Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add native USB MIDI gadget support and kidlisp WASM updates

+16620 -143
+1
fedac/native/Makefile
··· 77 77 $(SRCDIR)/color.c \ 78 78 $(SRCDIR)/input.c \ 79 79 $(SRCDIR)/audio.c \ 80 + $(SRCDIR)/usb-midi.c \ 80 81 $(SRCDIR)/wifi.c \ 81 82 $(SRCDIR)/tts.c \ 82 83 $(SRCDIR)/ws-client.c \
+3 -1
fedac/native/docker-build.sh
··· 118 118 log "Step 2/4: Building initramfs..." 119 119 IROOT="$BUILD/initramfs-root" 120 120 rm -rf "$IROOT" 121 - mkdir -p "$IROOT"/{bin,lib64,lib/firmware/i915,dev,proc,sys,tmp,run,etc,etc/pki/tls/certs} 121 + mkdir -p "$IROOT"/{bin,lib64,lib/firmware/i915,dev,proc,sys,tmp,run,scripts,etc,etc/pki/tls/certs} 122 122 123 123 # ── 2a: Static busybox (no shared lib deps for shell) ── 124 124 BUSYBOX=$(command -v busybox) ··· 170 170 # ── 2b: Init script ── 171 171 cp "$NATIVE/initramfs/init" "$IROOT/init" 172 172 chmod +x "$IROOT/init" 173 + cp "$NATIVE/initramfs-scripts/"*.sh "$IROOT/scripts/" 2>/dev/null || true 174 + chmod +x "$IROOT/scripts/"*.sh 2>/dev/null || true 173 175 174 176 # ── 2c: ac-native binary ── 175 177 cp "$BUILD/ac-native" "$IROOT/ac-native"
+234
fedac/native/initramfs-scripts/usb-midi-gadget.sh
··· 1 + #!/bin/sh 2 + # usb-midi-gadget.sh — configure ac-native as a USB MIDI gadget 3 + 4 + STATE="/run/usb-midi.state" 5 + GADGET_ROOT="/sys/kernel/config/usb_gadget/ac-midi" 6 + CONFIG_NAME="c.1" 7 + FUNC_NAME="midi.usb0" 8 + LANG="0x409" 9 + VID="0x1d6b" 10 + PID="0x0104" 11 + 12 + serial_number() { 13 + if [ -f /mnt/.machine-id ]; then 14 + tr -d '\r\n' </mnt/.machine-id 15 + return 16 + fi 17 + echo "ac-midi" 18 + } 19 + 20 + first_typec_port() { 21 + for port_path in /sys/class/typec/port*; do 22 + [ -d "$port_path" ] || continue 23 + port="$(basename "$port_path")" 24 + case "$port" in 25 + *-*) continue ;; 26 + esac 27 + echo "$port" 28 + return 29 + done 30 + } 31 + 32 + current_role() { 33 + path="$1" 34 + primary="$2" 35 + secondary="$3" 36 + [ -r "$path" ] || return 37 + raw="$(cat "$path" 2>/dev/null)" 38 + case "$raw" in 39 + *"[$primary]"*) echo "$primary" ;; 40 + *"[$secondary]"*) echo "$secondary" ;; 41 + *) echo "$raw" | sed 's/[][]//g' ;; 42 + esac 43 + } 44 + 45 + try_device_role() { 46 + port="$1" 47 + [ -n "$port" ] || return 0 48 + pbase="/sys/class/typec/$port" 49 + 50 + if [ -w "$pbase/power_role" ] && grep -q "sink" "$pbase/power_role" 2>/dev/null; then 51 + printf "sink\n" >"$pbase/power_role" 2>/dev/null || true 52 + fi 53 + if [ -w "$pbase/data_role" ] && grep -q "device" "$pbase/data_role" 2>/dev/null; then 54 + printf "device\n" >"$pbase/data_role" 2>/dev/null || true 55 + fi 56 + } 57 + 58 + first_udc() { 59 + for udc_path in /sys/class/udc/*; do 60 + [ -e "$udc_path" ] || continue 61 + basename "$udc_path" 62 + return 63 + done 64 + } 65 + 66 + find_alsa_device() { 67 + [ -r /proc/asound/cards ] || return 68 + while IFS= read -r line; do 69 + case "$line" in 70 + *"MIDI Gadget"*|*"f_midi"*) 71 + card="$(echo "$line" | sed -n 's/^[[:space:]]*\([0-9][0-9]*\).*/\1/p')" 72 + [ -n "$card" ] && echo "hw:$card,0,0" 73 + return 74 + ;; 75 + esac 76 + done </proc/asound/cards 77 + } 78 + 79 + log_line() { 80 + ts="$(date -u '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null || date 2>/dev/null || echo now)" 81 + line="$ts [usb-midi] $*" 82 + echo "$line" >>/tmp/usb-midi-gadget.log 2>/dev/null || true 83 + if [ -d /mnt ]; then 84 + echo "$line" >>/mnt/ac-native.log 2>/dev/null || true 85 + echo "$line" >>/mnt/usb-midi.log 2>/dev/null || true 86 + fi 87 + } 88 + 89 + write_state() { 90 + enabled="$1" 91 + active="$2" 92 + reason="$3" 93 + udc="$4" 94 + port="$5" 95 + power_role="$6" 96 + data_role="$7" 97 + alsa_device="$8" 98 + serial="$9" 99 + 100 + mkdir -p /run 101 + { 102 + echo "enabled=$enabled" 103 + echo "active=$active" 104 + echo "reason=$reason" 105 + echo "udc=$udc" 106 + echo "port=$port" 107 + echo "power_role=$power_role" 108 + echo "data_role=$data_role" 109 + echo "alsa_device=$alsa_device" 110 + echo "serial=$serial" 111 + } >"$STATE" 112 + log_line "enabled=$enabled active=$active reason=$reason udc=$udc port=$port power=$power_role data=$data_role alsa=$alsa_device serial=$serial" 113 + } 114 + 115 + ensure_configfs() { 116 + mkdir -p /sys/kernel/config 117 + if ! grep -q " /sys/kernel/config " /proc/mounts 2>/dev/null; then 118 + mount -t configfs none /sys/kernel/config 2>/dev/null || true 119 + fi 120 + [ -d /sys/kernel/config/usb_gadget ] 121 + } 122 + 123 + cleanup_gadget() { 124 + if [ -e "$GADGET_ROOT/UDC" ]; then 125 + printf "\n" >"$GADGET_ROOT/UDC" 2>/dev/null || true 126 + fi 127 + rm -f "$GADGET_ROOT/configs/$CONFIG_NAME/$FUNC_NAME" 2>/dev/null || true 128 + rmdir "$GADGET_ROOT/functions/$FUNC_NAME" 2>/dev/null || true 129 + rmdir "$GADGET_ROOT/configs/$CONFIG_NAME/strings/$LANG" 2>/dev/null || true 130 + rmdir "$GADGET_ROOT/configs/$CONFIG_NAME" 2>/dev/null || true 131 + rmdir "$GADGET_ROOT/strings/$LANG" 2>/dev/null || true 132 + rmdir "$GADGET_ROOT" 2>/dev/null || true 133 + } 134 + 135 + bring_up() { 136 + serial="$(serial_number)" 137 + port="$(first_typec_port)" 138 + [ -n "$port" ] && try_device_role "$port" 139 + sleep 1 140 + 141 + power_role="" 142 + data_role="" 143 + if [ -n "$port" ]; then 144 + power_role="$(current_role "/sys/class/typec/$port/power_role" source sink)" 145 + data_role="$(current_role "/sys/class/typec/$port/data_role" host device)" 146 + fi 147 + 148 + if ! ensure_configfs; then 149 + write_state 1 0 no-configfs "" "$port" "$power_role" "$data_role" "" "$serial" 150 + return 1 151 + fi 152 + 153 + cleanup_gadget 154 + mkdir -p "$GADGET_ROOT" || { 155 + write_state 1 0 create-failed "" "$port" "$power_role" "$data_role" "" "$serial" 156 + return 1 157 + } 158 + 159 + printf "%s\n" "$VID" >"$GADGET_ROOT/idVendor" || true 160 + printf "%s\n" "$PID" >"$GADGET_ROOT/idProduct" || true 161 + printf "0x0200\n" >"$GADGET_ROOT/bcdUSB" || true 162 + printf "0x0100\n" >"$GADGET_ROOT/bcdDevice" || true 163 + 164 + mkdir -p "$GADGET_ROOT/strings/$LANG" 165 + printf "%s\n" "$serial" >"$GADGET_ROOT/strings/$LANG/serialnumber" 166 + printf "aesthetic.computer\n" >"$GADGET_ROOT/strings/$LANG/manufacturer" 167 + printf "ac native usb midi\n" >"$GADGET_ROOT/strings/$LANG/product" 168 + 169 + mkdir -p "$GADGET_ROOT/configs/$CONFIG_NAME/strings/$LANG" 170 + printf "usb midi\n" >"$GADGET_ROOT/configs/$CONFIG_NAME/strings/$LANG/configuration" 171 + printf "250\n" >"$GADGET_ROOT/configs/$CONFIG_NAME/MaxPower" || true 172 + 173 + if ! mkdir "$GADGET_ROOT/functions/$FUNC_NAME" 2>/dev/null; then 174 + write_state 1 0 no-midi-function "" "$port" "$power_role" "$data_role" "" "$serial" 175 + cleanup_gadget 176 + return 1 177 + fi 178 + 179 + printf "1\n" >"$GADGET_ROOT/functions/$FUNC_NAME/in_ports" || true 180 + printf "1\n" >"$GADGET_ROOT/functions/$FUNC_NAME/out_ports" || true 181 + printf "512\n" >"$GADGET_ROOT/functions/$FUNC_NAME/buflen" || true 182 + printf "32\n" >"$GADGET_ROOT/functions/$FUNC_NAME/qlen" || true 183 + printf "acnative\n" >"$GADGET_ROOT/functions/$FUNC_NAME/id" || true 184 + 185 + ln -s "$GADGET_ROOT/functions/$FUNC_NAME" "$GADGET_ROOT/configs/$CONFIG_NAME/$FUNC_NAME" 2>/dev/null || true 186 + 187 + udc="$(first_udc)" 188 + if [ -z "$udc" ]; then 189 + write_state 1 0 no-udc "" "$port" "$power_role" "$data_role" "" "$serial" 190 + return 1 191 + fi 192 + 193 + if ! printf "%s\n" "$udc" >"$GADGET_ROOT/UDC" 2>/dev/null; then 194 + write_state 1 0 bind-failed "$udc" "$port" "$power_role" "$data_role" "" "$serial" 195 + return 1 196 + fi 197 + 198 + alsa_device="" 199 + for _ in 1 2 3; do 200 + alsa_device="$(find_alsa_device)" 201 + [ -n "$alsa_device" ] && break 202 + sleep 1 203 + done 204 + 205 + write_state 1 1 ok "$udc" "$port" "$power_role" "$data_role" "$alsa_device" "$serial" 206 + return 0 207 + } 208 + 209 + bring_down() { 210 + port="$(first_typec_port)" 211 + power_role="" 212 + data_role="" 213 + [ -n "$port" ] && power_role="$(current_role "/sys/class/typec/$port/power_role" source sink)" 214 + [ -n "$port" ] && data_role="$(current_role "/sys/class/typec/$port/data_role" host device)" 215 + cleanup_gadget 216 + write_state 0 0 disabled "" "$port" "$power_role" "$data_role" "" "$(serial_number)" 217 + } 218 + 219 + case "${1:-up}" in 220 + up) 221 + bring_up 222 + ;; 223 + down) 224 + bring_down 225 + ;; 226 + refresh) 227 + bring_down 228 + bring_up 229 + ;; 230 + *) 231 + echo "usage: $0 [up|down|refresh]" >&2 232 + exit 1 233 + ;; 234 + esac
+9
fedac/native/initramfs/init
··· 88 88 sleep 1 89 89 done 90 90 91 + if [ -x /scripts/usb-midi-gadget.sh ]; then 92 + if [ "$USB_MOUNTED" = "1" ] && [ -f /mnt/config.json ] && 93 + grep -Eq '"usbMidi"[[:space:]]*:[[:space:]]*true' /mnt/config.json 2>/dev/null; then 94 + /scripts/usb-midi-gadget.sh up >/tmp/usb-midi-gadget.log 2>&1 || true 95 + else 96 + /scripts/usb-midi-gadget.sh down >/tmp/usb-midi-gadget.log 2>&1 || true 97 + fi 98 + fi 99 + 91 100 # Run ac-native in a loop — if it crashes, restart; if clean exit, shutdown 92 101 export LD_LIBRARY_PATH="/lib64:/usr/lib64:${LD_LIBRARY_PATH:-}" 93 102
+13 -5
fedac/native/kernel/config-minimal
··· 3172 3172 # 3173 3173 # CONFIG_USB_CDNS_SUPPORT is not set 3174 3174 # CONFIG_USB_MUSB_HDRC is not set 3175 - # CONFIG_USB_DWC3 is not set 3175 + CONFIG_USB_DWC3=y 3176 + CONFIG_USB_DWC3_DUAL_ROLE=y 3177 + CONFIG_USB_DWC3_PCI=y 3176 3178 # CONFIG_USB_DWC2 is not set 3177 3179 # CONFIG_USB_CHIPIDEA is not set 3178 3180 # CONFIG_USB_ISP1760 is not set ··· 3219 3221 # CONFIG_USB_ISP1301 is not set 3220 3222 # end of USB Physical Layer drivers 3221 3223 3222 - # CONFIG_USB_GADGET is not set 3223 - # CONFIG_TYPEC is not set 3224 - # CONFIG_USB_ROLE_SWITCH is not set 3224 + CONFIG_USB_GADGET=y 3225 + CONFIG_USB_LIBCOMPOSITE=y 3226 + CONFIG_USB_CONFIGFS=y 3227 + CONFIG_USB_CONFIGFS_F_MIDI=y 3228 + CONFIG_TYPEC=y 3229 + CONFIG_TYPEC_UCSI=y 3230 + CONFIG_UCSI_ACPI=y 3231 + CONFIG_USB_ROLE_SWITCH=y 3232 + CONFIG_USB_ROLES_INTEL_XHCI=y 3225 3233 # CONFIG_MMC is not set 3226 3234 # CONFIG_SCSI_UFSHCD is not set 3227 3235 # CONFIG_MEMSTICK is not set ··· 3705 3713 # CONFIG_TMPFS_QUOTA is not set 3706 3714 # CONFIG_HUGETLBFS is not set 3707 3715 CONFIG_ARCH_HAS_GIGANTIC_PAGE=y 3708 - # CONFIG_CONFIGFS_FS is not set 3716 + CONFIG_CONFIGFS_FS=y 3709 3717 CONFIG_EFIVAR_FS=y 3710 3718 # end of Pseudo filesystems 3711 3719
+1
fedac/native/pieces/list.mjs
··· 29 29 { name: "bye", desc: "log out" }, 30 30 { name: "version", desc: "OS hash" }, 31 31 { name: "ssh", desc: "SSH server" }, 32 + { name: "midi", desc: "usb midi gadget" }, 32 33 { name: "clear", desc: "clear history" }, 33 34 { name: "help", desc: "quick help" }, 34 35 ];
+130 -38
fedac/native/pieces/notepat.mjs
··· 103 103 104 104 // Cached sound API ref (for leave) 105 105 let soundAPI = null; 106 + let systemAPI = null; 106 107 107 108 // Tablet mode tracking 108 109 let lastTabletMode = null; 110 + let usbMidiRecent = []; 111 + let usbMidiNextRefreshFrame = 0; 112 + let usbMidiTypecSignature = ""; 109 113 110 114 111 115 // OS update panel state machine ··· 233 237 return 440 * Math.pow(2, (oct - 4) + (idx - 9) / 12); 234 238 } 235 239 240 + function noteToMidiNumber(note, oct) { 241 + const idx = CHROMATIC.indexOf(note); 242 + if (idx < 0) return 60; 243 + return Math.max(0, Math.min(127, (oct + 1) * 12 + idx)); 244 + } 245 + 246 + function velocityToMidi(velocity) { 247 + const v = Number.isFinite(velocity) ? velocity : 1; 248 + return Math.max(1, Math.min(127, Math.round(v * 127))); 249 + } 250 + 251 + function midiNoteLabel(note, oct) { 252 + return note.toUpperCase() + oct; 253 + } 254 + 255 + function pushUsbMidiRecent(prefix, note, oct) { 256 + usbMidiRecent.unshift({ text: prefix + midiNoteLabel(note, oct), until: frame + 180 }); 257 + if (usbMidiRecent.length > 6) usbMidiRecent.length = 6; 258 + } 259 + 260 + function readUsbMidiStatus(system) { 261 + try { 262 + return system?.usbMidi?.status?.() || system?.usbMidi || { enabled: false, active: false, reason: "uninitialized" }; 263 + } catch (_) { 264 + return system?.usbMidi || { enabled: false, active: false, reason: "uninitialized" }; 265 + } 266 + } 267 + 268 + function activeUsbMidiNotes() { 269 + return Object.values(sounds) 270 + .filter((entry) => entry?.midiNote !== undefined) 271 + .sort((a, b) => (a.midiNote || 0) - (b.midiNote || 0)) 272 + .map((entry) => midiNoteLabel(entry.note, entry.octave)); 273 + } 274 + 275 + function usbMidiStatusText(status) { 276 + const notes = activeUsbMidiNotes(); 277 + const recent = usbMidiRecent 278 + .filter((entry) => entry.until > frame) 279 + .map((entry) => entry.text); 280 + 281 + if (status?.active) { 282 + if (notes.length > 0) return "USB MIDI ON " + notes.slice(0, 3).join(","); 283 + if (recent.length > 0) return "USB MIDI ON " + recent.slice(0, 2).join(" "); 284 + return "USB MIDI ON"; 285 + } 286 + return "USB MIDI OFF"; 287 + } 288 + 289 + function rememberSound(key, entry, system, velocity = 1) { 290 + if (!entry) return; 291 + entry.midiNote = noteToMidiNumber(entry.note, entry.octave); 292 + entry.midiChannel = 0; 293 + sounds[key] = entry; 294 + system?.usbMidi?.noteOn?.(entry.midiNote, velocityToMidi(velocity), entry.midiChannel); 295 + pushUsbMidiRecent(">", entry.note, entry.octave); 296 + } 297 + 298 + function stopSoundKey(key, sound, system, fade = 0.08) { 299 + const entry = sounds[key]; 300 + if (!entry) return; 301 + if (entry.compositeVoices) { 302 + for (const voice of entry.compositeVoices) sound?.kill?.(voice, fade); 303 + } else { 304 + sound?.kill?.(entry.synth || entry, fade); 305 + } 306 + if (entry.midiNote !== undefined) { 307 + system?.usbMidi?.noteOff?.(entry.midiNote, 0, entry.midiChannel || 0); 308 + pushUsbMidiRecent("<", entry.note, entry.octave); 309 + } 310 + delete sounds[key]; 311 + } 312 + 313 + function stopAllSounds(sound, system, fade = 0.08) { 314 + for (const key of Object.keys(sounds)) stopSoundKey(key, sound, system, fade); 315 + touchNotes = {}; 316 + system?.usbMidi?.allNotesOff?.(0); 317 + sounds = {}; 318 + } 319 + 236 320 function noteColor(n) { return NOTE_COLORS[n] || [80, 80, 80]; } 237 321 238 322 // Hit-test a touch point against the note grid ··· 355 439 356 440 function boot({ wipe, system, sound }) { 357 441 wipe(0); 442 + soundAPI = sound; 443 + systemAPI = system; 358 444 const mic = sound?.microphone || null; 359 445 if (mic && (mic.sampleLength || 0) > 0) { 360 446 sampleLoaded = true; ··· 373 459 374 460 function act({ event: e, sound, wifi, system }) { 375 461 soundAPI = sound; 462 + systemAPI = system; 376 463 // Track shift state before any other handling 377 464 if (e.is("keyboard:down") && e.key?.toLowerCase() === "shift") shiftHeld = true; 378 465 if (e.is("keyboard:up") && e.key?.toLowerCase() === "shift") shiftHeld = false; ··· 433 520 const exitBeep = sound?.synth?.("square", { frequency: 880, duration: 0.12, volume: 0.2 }); 434 521 if (exitBeep) setTimeout(() => sound?.kill?.(exitBeep, 0.02), 120); 435 522 escCount = 0; 436 - for (const k of Object.keys(sounds)) { 437 - const s = sounds[k].synth || sounds[k]; 438 - sound?.kill(s, 0.05); 439 - } 440 - sounds = {}; 523 + stopAllSounds(sound, system, 0.05); 441 524 system?.jump?.("prompt"); 442 525 return; 443 526 } ··· 560 643 tone: playFreq, base: SAMPLE_BASE_FREQ, volume: vol, pan, loop: true, 561 644 }); 562 645 if (smp) { 563 - sounds[key] = { synth: smp, note: letter, octave: noteOctave, baseFreq: freq, isSample: true }; 646 + rememberSound(key, { synth: smp, note: letter, octave: noteOctave, baseFreq: freq, isSample: true }, system, velocity); 564 647 } else { 565 648 const synth = sound.synth({ 566 649 type: "sine", tone: playFreq, duration: Infinity, 567 650 volume: vol, attack: quickMode ? 0.002 : 0.005, decay: 0.1, pan, 568 651 }); 569 - sounds[key] = { synth, note: letter, octave: noteOctave, baseFreq: freq }; 652 + rememberSound(key, { synth, note: letter, octave: noteOctave, baseFreq: freq }, system, velocity); 570 653 } 571 654 } else { 572 655 const synth = sound.synth({ ··· 575 658 volume: vol, attack: quickMode ? 0.002 : 0.005, 576 659 decay: 0.1, pan: pan, 577 660 }); 578 - sounds[key] = { synth, note: letter, octave: noteOctave, baseFreq: freq }; 661 + rememberSound(key, { synth, note: letter, octave: noteOctave, baseFreq: freq }, system, velocity); 579 662 } 580 663 trail[key] = { note: letter, octave: noteOctave, brightness: velocity }; 581 664 } ··· 619 702 return; 620 703 } 621 704 if (sounds[key]) { 622 - const fade = quickMode ? 0.02 : 0.08; 623 - if (sounds[key].compositeVoices) { 624 - for (const v of sounds[key].compositeVoices) sound.kill(v, fade); 625 - } else { 626 - sound.kill(sounds[key].synth || sounds[key], fade); 627 - } 628 - delete sounds[key]; 705 + stopSoundKey(key, sound, system, quickMode ? 0.02 : 0.08); 629 706 } 630 707 } 631 708 ··· 806 883 }); 807 884 if (smp) { 808 885 synth = smp; 809 - sounds[hitNote.key] = { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq, isSample: true }; 886 + rememberSound(hitNote.key, { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq, isSample: true }, system, 1); 810 887 } 811 888 } else if (wave === "composite") { 812 889 // Rich layered pad: 5 detuned oscillators ··· 817 894 const d = sound.synth({ type: "triangle", tone: playFreq + 8 + detune(), duration: Infinity, volume: 0.016, attack: 0.999, decay: 0.9, pan }); 818 895 const e2 = sound.synth({ type: "square", tone: playFreq + detune(), duration: Infinity, volume: 0.008, attack: 0.05, decay: 0.9, pan }); 819 896 synth = a; // primary handle for kill 820 - sounds[hitNote.key] = { 897 + rememberSound(hitNote.key, { 821 898 synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq, 822 899 compositeVoices: [a, b, c, d, e2], 823 - }; 900 + }, system, 1); 824 901 } else { 825 902 synth = sound.synth({ 826 903 type: wave, tone: playFreq, duration: Infinity, 827 904 volume: 0.5, attack: 0.005, decay: 0.1, pan, 828 905 }); 829 - sounds[hitNote.key] = { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq }; 906 + rememberSound(hitNote.key, { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq }, system, 1); 830 907 } 831 908 if (!sounds[hitNote.key]) { 832 909 synth = sound.synth({ 833 910 type: "sine", tone: playFreq, duration: Infinity, 834 911 volume: 0.5, attack: 0.005, decay: 0.1, pan, 835 912 }); 836 - sounds[hitNote.key] = { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq }; 913 + rememberSound(hitNote.key, { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq }, system, 1); 837 914 } 838 915 trail[hitNote.key] = { note: hitNote.letter, octave: hitNote.octave, brightness: 1.0 }; 839 916 touchNotes[pid] = { key: hitNote.key }; ··· 893 970 if (hitNote && hitNote.key && hitNote.key !== touchNotes[pid]?.key) { 894 971 // Release current note 895 972 const oldKey = touchNotes[pid].key; 896 - if (sounds[oldKey]) { 897 - sound.kill(sounds[oldKey].synth || sounds[oldKey], 0.02); 898 - delete sounds[oldKey]; 899 - } 973 + stopSoundKey(oldKey, sound, system, 0.02); 900 974 // Trigger new note 901 975 if (!sounds[hitNote.key]) { 902 976 const freq = noteToFreq(hitNote.letter, hitNote.octave); ··· 910 984 }); 911 985 if (smp) { 912 986 synth = smp; 913 - sounds[hitNote.key] = { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq, isSample: true }; 987 + rememberSound(hitNote.key, { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq, isSample: true }, system, 1); 914 988 } 915 989 } else { 916 990 synth = sound.synth({ 917 991 type: wave, tone: playFreq, 918 992 duration: Infinity, volume: 0.5, attack: 0.005, decay: 0.1, pan, 919 993 }); 920 - sounds[hitNote.key] = { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq }; 994 + rememberSound(hitNote.key, { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq }, system, 1); 921 995 } 922 996 if (!sounds[hitNote.key]) { 923 997 synth = sound.synth({ 924 998 type: "sine", tone: playFreq, 925 999 duration: Infinity, volume: 0.5, attack: 0.005, decay: 0.1, pan, 926 1000 }); 927 - sounds[hitNote.key] = { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq }; 1001 + rememberSound(hitNote.key, { synth, note: hitNote.letter, octave: hitNote.octave, baseFreq: freq }, system, 1); 928 1002 } 929 1003 trail[hitNote.key] = { note: hitNote.letter, octave: hitNote.octave, brightness: 1.0 }; 930 1004 touchNotes[pid] = { key: hitNote.key }; ··· 946 1020 // Release touch-triggered note 947 1021 if (touchNotes[pid]) { 948 1022 const key = touchNotes[pid].key; 949 - if (sounds[key]) { 950 - const s = sounds[key].synth || sounds[key]; 951 - sound.kill(s, 0.08); 952 - delete sounds[key]; 953 - } 1023 + stopSoundKey(key, sound, system, 0.08); 954 1024 delete touchNotes[pid]; 955 1025 } 956 1026 } ··· 958 1028 959 1029 function paint({ wipe, ink, box, line, write, screen, sound, system, trackpad, pressures, wifi }) { 960 1030 frame++; 1031 + usbMidiRecent = usbMidiRecent.filter((entry) => entry.until > frame); 961 1032 // FPS tracking 962 1033 const now = performance.now(); 963 1034 if (fpsLastTime > 0) { ··· 975 1046 const h = screen.height; 976 1047 const CH = 6; // char width at size 1 (font_1 = 6x10) 977 1048 const mic = sound?.microphone || {}; 1049 + let usbMidiStatus = readUsbMidiStatus(system); 978 1050 sampleLoaded = (mic.sampleLength || 0) > 0; 979 1051 globalThis.__screenW = w; // expose for act() 980 1052 globalThis.__screenH = h; 1053 + 1054 + const typecSignature = (system?.typec || []) 1055 + .map((port) => port.port + ":" + port.powerRole + ":" + port.dataRole) 1056 + .join("|"); 1057 + const typecChanged = typecSignature !== usbMidiTypecSignature; 1058 + if (typecChanged) { 1059 + usbMidiTypecSignature = typecSignature; 1060 + } 1061 + 1062 + if (usbMidiStatus?.enabled && !usbMidiStatus?.active && frame >= usbMidiNextRefreshFrame) { 1063 + const typecDevice = (system?.typec || []).some((port) => port.dataRole === "device"); 1064 + if (typecChanged && typecDevice) { 1065 + usbMidiStatus = system?.usbMidi?.refresh?.() || usbMidiStatus; 1066 + usbMidiNextRefreshFrame = frame + 180; 1067 + } 1068 + } 981 1069 982 1070 // Trackpad FX: X = echo, Y = pitch shift (when enabled via \) 983 1071 if (trackpadFX && trackpad) { ··· 1167 1255 statusWrite(at, ap === 3 ? 100 : 255, ap === 3 ? 200 : 160, ap === 3 ? 255 : 60, 200); 1168 1256 } else if (autoUpdate.state === "ready") { 1169 1257 statusWrite("reboot?", 100, 220, 100, 220); 1258 + } 1259 + 1260 + const usbMidiText = usbMidiStatusText(usbMidiStatus); 1261 + if (usbMidiStatus?.active) { 1262 + statusWrite(usbMidiText, 100, 220, 140, 220); 1263 + } else if (usbMidiStatus?.enabled) { 1264 + statusWrite(usbMidiText, 255, 190, 80, 220); 1265 + } else { 1266 + statusWrite(usbMidiText, FG_DIM, FG_DIM, FG_DIM, 200); 1170 1267 } 1171 1268 1172 1269 // Metronome indicator (pendulum) in status bar — shown when enabled ··· 2490 2587 trackpadFX = false; 2491 2588 soundAPI?.room?.setMix?.(0); 2492 2589 soundAPI?.fx?.setMix?.(1); 2493 - // Stop all playing sounds 2494 - for (const key of Object.keys(sounds)) { 2495 - const s = sounds[key]; 2496 - if (s && s.synth) s.synth.stop?.(); 2497 - } 2498 - sounds = {}; 2590 + stopAllSounds(soundAPI, systemAPI, 0.02); 2499 2591 } 2500 2592 2501 2593 export { boot, act, paint, sim, leave };
+61 -1
fedac/native/pieces/prompt.mjs
··· 22 22 let PIECE_NAMES = []; 23 23 // Built-in non-piece commands 24 24 const BUILTIN_COMMANDS = [ 25 - "version", "reboot", "off", "clear", "help", "ssh", "hi", "bye", "ls", "papers", "login", 25 + "version", "reboot", "off", "clear", "help", "ssh", "hi", "bye", "ls", "papers", "login", "midi", 26 26 ]; 27 27 // All completable commands (built in boot) 28 28 let COMMANDS = []; ··· 56 56 "theme": "prompt theme", 57 57 "voice": "system voice", 58 58 "login": "switch identity", 59 + "midi": "usb midi gadget", 59 60 "dark": "dark mode", 60 61 "light": "light mode", 61 62 "auto": "auto dark/light", ··· 110 111 ink (? cyan yellow magenta) 8 111 112 circle w/2 h/2 (? 2 4 8)`, 112 113 }; 114 + 115 + function readUsbMidiStatus(system) { 116 + try { 117 + return system?.usbMidi?.status?.() || system?.usbMidi || null; 118 + } catch (_) { 119 + return system?.usbMidi || null; 120 + } 121 + } 122 + 123 + function formatUsbMidiStatus(status) { 124 + if (!status) return "usb midi unavailable"; 125 + if (status.active) { 126 + let msg = "usb midi active"; 127 + if (status.alsaDevice) msg += " " + status.alsaDevice; 128 + else if (status.udc) msg += " " + status.udc; 129 + if (status.port) msg += " via " + status.port; 130 + return msg; 131 + } 132 + if (status.enabled) { 133 + return status.reason && status.reason !== "ok" 134 + ? "usb midi enabled (" + status.reason + ")" 135 + : "usb midi enabled"; 136 + } 137 + if (status.reason && status.reason !== "disabled" && status.reason !== "uninitialized") { 138 + return "usb midi off (" + status.reason + ")"; 139 + } 140 + return "usb midi off"; 141 + } 113 142 114 143 function boot({ system }) { 115 144 message = ""; ··· 297 326 system?.startSSH?.(); 298 327 message = "starting ssh..."; 299 328 } 329 + messageFrame = 0; 330 + return; 331 + } 332 + if (baseWord === "midi") { 333 + const arg = spaceIdx >= 0 ? lower.slice(spaceIdx + 1).trim() : "status"; 334 + if (!arg || arg === "status") { 335 + message = formatUsbMidiStatus(readUsbMidiStatus(system)); 336 + messageFrame = 0; 337 + return; 338 + } 339 + if (arg === "on" || arg === "enable") { 340 + system?.saveConfig?.("usbMidi", "true"); 341 + const status = system?.usbMidi?.enable?.() || readUsbMidiStatus(system); 342 + message = formatUsbMidiStatus(status); 343 + messageFrame = 0; 344 + return; 345 + } 346 + if (arg === "off" || arg === "disable") { 347 + system?.saveConfig?.("usbMidi", "false"); 348 + const status = system?.usbMidi?.disable?.() || readUsbMidiStatus(system); 349 + message = formatUsbMidiStatus(status); 350 + messageFrame = 0; 351 + return; 352 + } 353 + if (arg === "refresh" || arg === "retry") { 354 + const status = system?.usbMidi?.refresh?.() || readUsbMidiStatus(system); 355 + message = formatUsbMidiStatus(status); 356 + messageFrame = 0; 357 + return; 358 + } 359 + message = "usage: midi [status|on|off|refresh]"; 300 360 messageFrame = 0; 301 361 return; 302 362 }
+109
fedac/native/src/js-bindings.c
··· 1 1 #define _GNU_SOURCE 2 2 #include "js-bindings.h" 3 + #include "usb-midi.h" 3 4 #include <pthread.h> 4 5 #include <stdio.h> 5 6 #include <stdlib.h> ··· 32 33 33 34 // Forward declaration (defined later in this file) 34 35 static int resolve_color_name(const char *name, ACColor *out); 36 + static JSValue js_usb_midi_note_on(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); 37 + static JSValue js_usb_midi_note_off(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); 38 + static JSValue js_usb_midi_all_notes_off(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); 35 39 36 40 // ============================================================ 37 41 // QuickJS Class IDs for 3D objects ··· 2054 2058 // midi (stub) 2055 2059 JSValue midi = JS_NewObject(ctx); 2056 2060 JS_SetPropertyStr(ctx, midi, "connect", JS_NewCFunction(ctx, js_noop, "connect", 0)); 2061 + JS_SetPropertyStr(ctx, midi, "noteOn", JS_NewCFunction(ctx, js_usb_midi_note_on, "noteOn", 3)); 2062 + JS_SetPropertyStr(ctx, midi, "noteOff", JS_NewCFunction(ctx, js_usb_midi_note_off, "noteOff", 3)); 2063 + JS_SetPropertyStr(ctx, midi, "allNotesOff", JS_NewCFunction(ctx, js_usb_midi_all_notes_off, "allNotesOff", 1)); 2057 2064 JS_SetPropertyStr(ctx, sound, "midi", midi); 2058 2065 2059 2066 // daw (stub) ··· 3267 3274 return JS_NewBool(ctx, ok); 3268 3275 } 3269 3276 3277 + static JSValue build_usb_midi_state_obj(JSContext *ctx) { 3278 + ACUsbMidiState state; 3279 + int has_state = usb_midi_read_state(&state); 3280 + if (!has_state) { 3281 + memset(&state, 0, sizeof(state)); 3282 + snprintf(state.reason, sizeof(state.reason), "uninitialized"); 3283 + } 3284 + 3285 + JSValue obj = JS_NewObject(ctx); 3286 + JS_SetPropertyStr(ctx, obj, "enabled", JS_NewBool(ctx, state.enabled)); 3287 + JS_SetPropertyStr(ctx, obj, "active", JS_NewBool(ctx, state.active)); 3288 + JS_SetPropertyStr(ctx, obj, "reason", JS_NewString(ctx, state.reason[0] ? state.reason : "unknown")); 3289 + JS_SetPropertyStr(ctx, obj, "udc", JS_NewString(ctx, state.udc)); 3290 + JS_SetPropertyStr(ctx, obj, "port", JS_NewString(ctx, state.port)); 3291 + JS_SetPropertyStr(ctx, obj, "powerRole", JS_NewString(ctx, state.power_role)); 3292 + JS_SetPropertyStr(ctx, obj, "dataRole", JS_NewString(ctx, state.data_role)); 3293 + JS_SetPropertyStr(ctx, obj, "alsaDevice", JS_NewString(ctx, state.alsa_device)); 3294 + JS_SetPropertyStr(ctx, obj, "serial", JS_NewString(ctx, state.serial)); 3295 + return obj; 3296 + } 3297 + 3298 + static JSValue js_usb_midi_status(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { 3299 + (void)this_val; (void)argc; (void)argv; 3300 + return build_usb_midi_state_obj(ctx); 3301 + } 3302 + 3303 + static JSValue js_usb_midi_control(JSContext *ctx, const char *action) { 3304 + usb_midi_close(); 3305 + if (access("/scripts/usb-midi-gadget.sh", X_OK) == 0) { 3306 + char cmd[256]; 3307 + snprintf(cmd, sizeof(cmd), "/scripts/usb-midi-gadget.sh %s >/tmp/usb-midi-gadget.log 2>&1", action); 3308 + int rc = system(cmd); 3309 + ac_log("[usb-midi] control %s rc=%d", action, rc); 3310 + } else { 3311 + FILE *fp = fopen("/run/usb-midi.state", "w"); 3312 + if (fp) { 3313 + fputs("enabled=0\nactive=0\nreason=missing-script\n", fp); 3314 + fclose(fp); 3315 + } 3316 + ac_log("[usb-midi] control %s failed: missing /scripts/usb-midi-gadget.sh", action); 3317 + } 3318 + usb_midi_close(); 3319 + return build_usb_midi_state_obj(ctx); 3320 + } 3321 + 3322 + static JSValue js_usb_midi_enable(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { 3323 + (void)this_val; (void)argc; (void)argv; 3324 + return js_usb_midi_control(ctx, "up"); 3325 + } 3326 + 3327 + static JSValue js_usb_midi_disable(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { 3328 + (void)this_val; (void)argc; (void)argv; 3329 + return js_usb_midi_control(ctx, "down"); 3330 + } 3331 + 3332 + static JSValue js_usb_midi_refresh(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { 3333 + (void)this_val; (void)argc; (void)argv; 3334 + return js_usb_midi_control(ctx, "refresh"); 3335 + } 3336 + 3337 + static JSValue js_usb_midi_note_on(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { 3338 + (void)this_val; 3339 + int32_t note = 60; 3340 + int32_t velocity = 100; 3341 + int32_t channel = 0; 3342 + if (argc < 1 || JS_ToInt32(ctx, &note, argv[0])) return JS_FALSE; 3343 + if (argc >= 2) JS_ToInt32(ctx, &velocity, argv[1]); 3344 + if (argc >= 3) JS_ToInt32(ctx, &channel, argv[2]); 3345 + return JS_NewBool(ctx, usb_midi_note_on(note, velocity, channel)); 3346 + } 3347 + 3348 + static JSValue js_usb_midi_note_off(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { 3349 + (void)this_val; 3350 + int32_t note = 60; 3351 + int32_t velocity = 0; 3352 + int32_t channel = 0; 3353 + if (argc < 1 || JS_ToInt32(ctx, &note, argv[0])) return JS_FALSE; 3354 + if (argc >= 2) JS_ToInt32(ctx, &velocity, argv[1]); 3355 + if (argc >= 3) JS_ToInt32(ctx, &channel, argv[2]); 3356 + return JS_NewBool(ctx, usb_midi_note_off(note, velocity, channel)); 3357 + } 3358 + 3359 + static JSValue js_usb_midi_all_notes_off(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { 3360 + (void)this_val; 3361 + int32_t channel = 0; 3362 + if (argc >= 1) JS_ToInt32(ctx, &channel, argv[0]); 3363 + return JS_NewBool(ctx, usb_midi_all_notes_off(channel)); 3364 + } 3365 + 3270 3366 // Hardened: triple sync with delays, pre-reboot EFI file size sanity check, 3271 3367 // perf flush, log flush before rebooting. 3272 3368 static JSValue js_reboot(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { ··· 4442 4538 // Remote reboot / poweroff — system.reboot() / system.poweroff() 4443 4539 JS_SetPropertyStr(ctx, sys, "reboot", JS_NewCFunction(ctx, js_reboot, "reboot", 0)); 4444 4540 JS_SetPropertyStr(ctx, sys, "poweroff", JS_NewCFunction(ctx, js_poweroff, "poweroff", 0)); 4541 + 4542 + // USB MIDI gadget status + control 4543 + { 4544 + JSValue usb_midi = build_usb_midi_state_obj(ctx); 4545 + JS_SetPropertyStr(ctx, usb_midi, "status", JS_NewCFunction(ctx, js_usb_midi_status, "status", 0)); 4546 + JS_SetPropertyStr(ctx, usb_midi, "enable", JS_NewCFunction(ctx, js_usb_midi_enable, "enable", 0)); 4547 + JS_SetPropertyStr(ctx, usb_midi, "disable", JS_NewCFunction(ctx, js_usb_midi_disable, "disable", 0)); 4548 + JS_SetPropertyStr(ctx, usb_midi, "refresh", JS_NewCFunction(ctx, js_usb_midi_refresh, "refresh", 0)); 4549 + JS_SetPropertyStr(ctx, usb_midi, "noteOn", JS_NewCFunction(ctx, js_usb_midi_note_on, "noteOn", 3)); 4550 + JS_SetPropertyStr(ctx, usb_midi, "noteOff", JS_NewCFunction(ctx, js_usb_midi_note_off, "noteOff", 3)); 4551 + JS_SetPropertyStr(ctx, usb_midi, "allNotesOff", JS_NewCFunction(ctx, js_usb_midi_all_notes_off, "allNotesOff", 1)); 4552 + JS_SetPropertyStr(ctx, sys, "usbMidi", usb_midi); 4553 + } 4445 4554 4446 4555 // File I/O — system.readFile(path) / system.writeFile(path, data) 4447 4556 JS_SetPropertyStr(ctx, sys, "readFile", JS_NewCFunction(ctx, js_read_file, "readFile", 1));
+211
fedac/native/src/usb-midi.c
··· 1 + #include "usb-midi.h" 2 + #include <alsa/asoundlib.h> 3 + #include <errno.h> 4 + #include <pthread.h> 5 + #include <stdio.h> 6 + #include <stdlib.h> 7 + #include <string.h> 8 + #include <time.h> 9 + #include <unistd.h> 10 + 11 + extern void ac_log(const char *fmt, ...); 12 + 13 + static pthread_mutex_t g_usb_midi_lock = PTHREAD_MUTEX_INITIALIZER; 14 + static snd_rawmidi_t *g_usb_midi_out = NULL; 15 + static char g_usb_midi_device[64] = {0}; 16 + static time_t g_usb_midi_next_retry = 0; 17 + 18 + static void usb_midi_state_init(ACUsbMidiState *state) { 19 + if (!state) return; 20 + memset(state, 0, sizeof(*state)); 21 + snprintf(state->reason, sizeof(state->reason), "unknown"); 22 + } 23 + 24 + int usb_midi_read_state(ACUsbMidiState *state) { 25 + usb_midi_state_init(state); 26 + if (!state) return 0; 27 + 28 + FILE *fp = fopen("/run/usb-midi.state", "r"); 29 + if (!fp) return 0; 30 + 31 + char line[256]; 32 + while (fgets(line, sizeof(line), fp)) { 33 + line[strcspn(line, "\r\n")] = 0; 34 + char *eq = strchr(line, '='); 35 + if (!eq) continue; 36 + *eq = 0; 37 + const char *key = line; 38 + const char *value = eq + 1; 39 + if (strcmp(key, "enabled") == 0) state->enabled = atoi(value) != 0; 40 + else if (strcmp(key, "active") == 0) state->active = atoi(value) != 0; 41 + else if (strcmp(key, "reason") == 0) snprintf(state->reason, sizeof(state->reason), "%s", value); 42 + else if (strcmp(key, "udc") == 0) snprintf(state->udc, sizeof(state->udc), "%s", value); 43 + else if (strcmp(key, "port") == 0) snprintf(state->port, sizeof(state->port), "%s", value); 44 + else if (strcmp(key, "power_role") == 0) snprintf(state->power_role, sizeof(state->power_role), "%s", value); 45 + else if (strcmp(key, "data_role") == 0) snprintf(state->data_role, sizeof(state->data_role), "%s", value); 46 + else if (strcmp(key, "alsa_device") == 0) snprintf(state->alsa_device, sizeof(state->alsa_device), "%s", value); 47 + else if (strcmp(key, "serial") == 0) snprintf(state->serial, sizeof(state->serial), "%s", value); 48 + } 49 + fclose(fp); 50 + return 1; 51 + } 52 + 53 + static int usb_midi_find_card_from_proc(void) { 54 + FILE *fp = fopen("/proc/asound/cards", "r"); 55 + if (!fp) return -1; 56 + 57 + int found = -1; 58 + char line[256]; 59 + while (fgets(line, sizeof(line), fp)) { 60 + int card = -1; 61 + if (sscanf(line, " %d [", &card) == 1) { 62 + if (strstr(line, "MIDI Gadget") || strstr(line, "f_midi")) { 63 + found = card; 64 + break; 65 + } 66 + } 67 + } 68 + fclose(fp); 69 + return found; 70 + } 71 + 72 + static int usb_midi_resolve_device(char *out, size_t out_sz) { 73 + if (!out || out_sz == 0) return 0; 74 + out[0] = 0; 75 + 76 + ACUsbMidiState state; 77 + if (usb_midi_read_state(&state) && state.alsa_device[0]) { 78 + snprintf(out, out_sz, "%s", state.alsa_device); 79 + return 1; 80 + } 81 + 82 + int card = usb_midi_find_card_from_proc(); 83 + if (card < 0) return 0; 84 + snprintf(out, out_sz, "hw:%d,0,0", card); 85 + return 1; 86 + } 87 + 88 + static int usb_midi_ensure_open_locked(void) { 89 + if (g_usb_midi_out) return 1; 90 + 91 + time_t now = time(NULL); 92 + if (g_usb_midi_next_retry && now < g_usb_midi_next_retry) return 0; 93 + 94 + char device[64]; 95 + if (!usb_midi_resolve_device(device, sizeof(device))) { 96 + g_usb_midi_next_retry = now + 1; 97 + return 0; 98 + } 99 + 100 + int rc = snd_rawmidi_open(NULL, &g_usb_midi_out, device, SND_RAWMIDI_NONBLOCK); 101 + if (rc < 0) { 102 + ac_log("[usb-midi] open %s failed: %s", device, snd_strerror(rc)); 103 + g_usb_midi_out = NULL; 104 + g_usb_midi_next_retry = now + 1; 105 + return 0; 106 + } 107 + 108 + snd_rawmidi_nonblock(g_usb_midi_out, 1); 109 + snprintf(g_usb_midi_device, sizeof(g_usb_midi_device), "%s", device); 110 + g_usb_midi_next_retry = 0; 111 + ac_log("[usb-midi] opened %s", g_usb_midi_device); 112 + return 1; 113 + } 114 + 115 + static int usb_midi_send_locked(const unsigned char *msg, size_t len) { 116 + if (!msg || len == 0) return 0; 117 + if (!usb_midi_ensure_open_locked()) return 0; 118 + 119 + size_t sent = 0; 120 + int attempts = 0; 121 + while (sent < len && attempts < 4) { 122 + ssize_t rc = snd_rawmidi_write(g_usb_midi_out, msg + sent, len - sent); 123 + if (rc > 0) { 124 + sent += (size_t)rc; 125 + continue; 126 + } 127 + if (rc == -EAGAIN || rc == 0) { 128 + attempts++; 129 + usleep(1000); 130 + continue; 131 + } 132 + ac_log("[usb-midi] write %s failed: %s", g_usb_midi_device[0] ? g_usb_midi_device : "(unknown)", snd_strerror((int)rc)); 133 + snd_rawmidi_close(g_usb_midi_out); 134 + g_usb_midi_out = NULL; 135 + g_usb_midi_device[0] = 0; 136 + g_usb_midi_next_retry = time(NULL) + 1; 137 + return 0; 138 + } 139 + 140 + return sent == len; 141 + } 142 + 143 + static int usb_midi_send_message(const unsigned char *msg, size_t len) { 144 + int ok; 145 + pthread_mutex_lock(&g_usb_midi_lock); 146 + ok = usb_midi_send_locked(msg, len); 147 + pthread_mutex_unlock(&g_usb_midi_lock); 148 + return ok; 149 + } 150 + 151 + void usb_midi_close(void) { 152 + pthread_mutex_lock(&g_usb_midi_lock); 153 + if (g_usb_midi_out) { 154 + snd_rawmidi_close(g_usb_midi_out); 155 + g_usb_midi_out = NULL; 156 + } 157 + g_usb_midi_device[0] = 0; 158 + g_usb_midi_next_retry = 0; 159 + pthread_mutex_unlock(&g_usb_midi_lock); 160 + } 161 + 162 + static int clamp_midi_u7(int value) { 163 + if (value < 0) return 0; 164 + if (value > 127) return 127; 165 + return value; 166 + } 167 + 168 + static int clamp_channel(int channel) { 169 + if (channel < 0) return 0; 170 + if (channel > 15) return 15; 171 + return channel; 172 + } 173 + 174 + int usb_midi_note_on(int note, int velocity, int channel) { 175 + unsigned char msg[3]; 176 + msg[0] = (unsigned char)(0x90 | clamp_channel(channel)); 177 + msg[1] = (unsigned char)clamp_midi_u7(note); 178 + msg[2] = (unsigned char)clamp_midi_u7(velocity); 179 + int ok = usb_midi_send_message(msg, sizeof(msg)); 180 + if (ok) ac_log("[usb-midi] note-on ch=%d note=%d vel=%d", clamp_channel(channel), clamp_midi_u7(note), clamp_midi_u7(velocity)); 181 + return ok; 182 + } 183 + 184 + int usb_midi_note_off(int note, int velocity, int channel) { 185 + unsigned char msg[3]; 186 + msg[0] = (unsigned char)(0x80 | clamp_channel(channel)); 187 + msg[1] = (unsigned char)clamp_midi_u7(note); 188 + msg[2] = (unsigned char)clamp_midi_u7(velocity); 189 + int ok = usb_midi_send_message(msg, sizeof(msg)); 190 + if (ok) ac_log("[usb-midi] note-off ch=%d note=%d vel=%d", clamp_channel(channel), clamp_midi_u7(note), clamp_midi_u7(velocity)); 191 + return ok; 192 + } 193 + 194 + int usb_midi_all_notes_off(int channel) { 195 + unsigned char all_notes_off[3]; 196 + unsigned char all_sound_off[3]; 197 + int ch = clamp_channel(channel); 198 + 199 + all_notes_off[0] = (unsigned char)(0xB0 | ch); 200 + all_notes_off[1] = 123; 201 + all_notes_off[2] = 0; 202 + 203 + all_sound_off[0] = (unsigned char)(0xB0 | ch); 204 + all_sound_off[1] = 120; 205 + all_sound_off[2] = 0; 206 + 207 + int ok = usb_midi_send_message(all_sound_off, sizeof(all_sound_off)) && 208 + usb_midi_send_message(all_notes_off, sizeof(all_notes_off)); 209 + if (ok) ac_log("[usb-midi] all-notes-off ch=%d", ch); 210 + return ok; 211 + }
+22
fedac/native/src/usb-midi.h
··· 1 + #ifndef AC_USB_MIDI_H 2 + #define AC_USB_MIDI_H 3 + 4 + typedef struct { 5 + int enabled; 6 + int active; 7 + char reason[64]; 8 + char udc[128]; 9 + char port[64]; 10 + char power_role[32]; 11 + char data_role[32]; 12 + char alsa_device[64]; 13 + char serial[64]; 14 + } ACUsbMidiState; 15 + 16 + int usb_midi_read_state(ACUsbMidiState *state); 17 + void usb_midi_close(void); 18 + int usb_midi_note_on(int note, int velocity, int channel); 19 + int usb_midi_note_off(int note, int velocity, int channel); 20 + int usb_midi_all_notes_off(int channel); 21 + 22 + #endif
+7
kidlisp-wasm/anim.lisp
··· 1 + wipe 10 5 25 2 + ink 255 100 50 3 + circle (+ w/2 (* 60 (cos (/ f 8)))) (+ h/2 (* 40 (sin (/ f 6)))) 20 4 + ink 50 200 255 5 + circle (+ w/2 (* 40 (cos (/ f 5)))) (+ h/2 (* 60 (sin (/ f 10)))) 15 6 + ink 255 255 100 7 + circle (+ w/2 (* 80 (sin (/ f 12)))) (+ h/2 (* 30 (cos (/ f 7)))) 10
+14894
kidlisp-wasm/anim.ppm
··· 1 + P6 2 + 128 128 3 + 255 4 + 5 +  6 +  7 +  8 +  9 +  10 +  11 +  12 +  13 +  14 +  15 +  16 +  17 +  18 +  19 +  20 +  21 +  22 +  23 +  24 +  25 +  26 +  27 +  28 +  29 +  30 +  31 +  32 +  33 +  34 +  35 +  36 +  37 +  38 +  39 +  40 +  41 +  42 +  43 +  44 +  45 +  46 +  47 +  48 +  49 +  50 +  51 +  52 +  53 +  54 +  55 +  56 +  57 +  58 +  59 +  60 +  61 +  62 +  63 +  64 +  65 +  66 +  67 +  68 +  69 +  70 +  71 +  72 +  73 +  74 +  75 +  76 +  77 +  78 +  79 +  80 +  81 +  82 +  83 +  84 +  85 +  86 +  87 +  88 +  89 +  90 +  91 +  92 +  93 +  94 +  95 +  96 +  97 +  98 +  99 +  100 +  101 +  102 +  103 +  104 +  105 +  106 +  107 +  108 +  109 +  110 +  111 +  112 +  113 +  114 +  115 +  116 +  117 +  118 +  119 +  120 +  121 +  122 +  123 +  124 +  125 +  126 +  127 +  128 +  129 +  130 +  131 +  132 +  133 +  134 +  135 +  136 +  137 +  138 +  139 +  140 +  141 +  142 +  143 +  144 +  145 +  146 +  147 +  148 +  149 +  150 +  151 +  152 +  153 +  154 +  155 +  156 +  157 +  158 +  159 +  160 +  161 +  162 +  163 +  164 +  165 +  166 +  167 +  168 +  169 +  170 +  171 +  172 +  173 +  174 +  175 +  176 +  177 +  178 +  179 +  180 +  181 +  182 +  183 +  184 +  185 +  186 +  187 +  188 +  189 +  190 +  191 +  192 +  193 +  194 +  195 +  196 +  197 +  198 +  199 +  200 +  201 +  202 +  203 +  204 +  205 +  206 +  207 +  208 +  209 +  210 +  211 +  212 +  213 +  214 +  215 +  216 +  217 +  218 +  219 +  220 +  221 +  222 +  223 +  224 +  225 +  226 +  227 +  228 +  229 +  230 +  231 +  232 +  233 +  234 +  235 +  236 +  237 +  238 +  239 +  240 +  241 +  242 +  243 +  244 +  245 +  246 +  247 +  248 +  249 +  250 +  251 +  252 +  253 +  254 +  255 +  256 +  257 +  258 +  259 +  260 +  261 +  262 +  263 +  264 +  265 +  266 +  267 +  268 +  269 +  270 +  271 +  272 +  273 +  274 +  275 +  276 +  277 +  278 +  279 +  280 +  281 +  282 +  283 +  284 +  285 +  286 +  287 +  288 +  289 +  290 +  291 +  292 +  293 +  294 +  295 +  296 +  297 +  298 +  299 +  300 +  301 +  302 +  303 +  304 +  305 +  306 +  307 +  308 +  309 +  310 +  311 +  312 +  313 +  314 +  315 +  316 +  317 +  318 +  319 +  320 +  321 +  322 +  323 +  324 +  325 +  326 +  327 +  328 +  329 +  330 +  331 +  332 +  333 +  334 +  335 +  336 +  337 +  338 +  339 +  340 +  341 +  342 +  343 +  344 +  345 +  346 +  347 +  348 +  349 +  350 +  351 +  352 +  353 +  354 +  355 +  356 +  357 +  358 +  359 +  360 +  361 +  362 +  363 +  364 +  365 +  366 +  367 +  368 +  369 +  370 +  371 +  372 +  373 +  374 +  375 +  376 +  377 +  378 +  379 +  380 +  381 +  382 +  383 +  384 +  385 +  386 +  387 +  388 +  389 +  390 +  391 +  392 +  393 +  394 +  395 +  396 +  397 +  398 +  399 +  400 +  401 +  402 +  403 +  404 +  405 +  406 +  407 +  408 +  409 +  410 +  411 +  412 +  413 +  414 +  415 +  416 +  417 +  418 +  419 +  420 +  421 +  422 +  423 +  424 +  425 +  426 +  427 +  428 +  429 +  430 +  431 +  432 +  433 +  434 +  435 +  436 +  437 +  438 +  439 +  440 +  441 +  442 +  443 +  444 +  445 +  446 +  447 +  448 +  449 +  450 +  451 +  452 +  453 +  454 +  455 +  456 +  457 +  458 +  459 +  460 +  461 +  462 +  463 +  464 +  465 +  466 +  467 +  468 +  469 +  470 +  471 +  472 +  473 +  474 +  475 +  476 +  477 +  478 +  479 +  480 +  481 +  482 +  483 +  484 +  485 +  486 +  487 +  488 +  489 +  490 +  491 +  492 +  493 +  494 +  495 +  496 +  497 +  498 +  499 +  500 +  501 +  502 +  503 +  504 +  505 +  506 +  507 +  508 +  509 +  510 +  511 +  512 +  513 +  514 +  515 +  516 +  517 +  518 +  519 +  520 +  521 +  522 +  523 +  524 +  525 +  526 +  527 +  528 +  529 +  530 +  531 +  532 +  533 +  534 +  535 +  536 +  537 +  538 +  539 +  540 +  541 +  542 +  543 +  544 +  545 +  546 +  547 +  548 +  549 +  550 +  551 +  552 +  553 +  554 +  555 +  556 +  557 +  558 +  559 +  560 +  561 +  562 +  563 +  564 +  565 +  566 +  567 +  568 +  569 +  570 +  571 +  572 +  573 +  574 +  575 +  576 +  577 +  578 +  579 +  580 +  581 +  582 +  583 +  584 +  585 +  586 +  587 +  588 +  589 +  590 +  591 +  592 +  593 +  594 +  595 +  596 +  597 +  598 +  599 +  600 +  601 +  602 +  603 +  604 +  605 +  606 +  607 +  608 +  609 +  610 +  611 +  612 +  613 +  614 +  615 +  616 +  617 +  618 +  619 +  620 +  621 +  622 +  623 +  624 +  625 +  626 +  627 +  628 +  629 +  630 +  631 +  632 +  633 +  634 +  635 +  636 +  637 +  638 +  639 +  640 +  641 +  642 +  643 +  644 +  645 +  646 +  647 +  648 +  649 +  650 +  651 +  652 +  653 +  654 +  655 +  656 +  657 +  658 +  659 +  660 +  661 +  662 +  663 +  664 +  665 +  666 +  667 +  668 +  669 +  670 +  671 +  672 +  673 +  674 +  675 +  676 +  677 +  678 +  679 +  680 +  681 +  682 +  683 +  684 +  685 +  686 +  687 +  688 +  689 +  690 +  691 +  692 +  693 +  694 +  695 +  696 +  697 +  698 +  699 +  700 +  701 +  702 +  703 +  704 +  705 +  706 +  707 +  708 +  709 +  710 +  711 +  712 +  713 +  714 +  715 +  716 +  717 +  718 +  719 +  720 +  721 +  722 +  723 +  724 +  725 +  726 +  727 +  728 +  729 +  730 +  731 +  732 +  733 +  734 +  735 +  736 +  737 +  738 +  739 +  740 +  741 +  742 +  743 +  744 +  745 +  746 +  747 +  748 +  749 +  750 +  751 +  752 +  753 +  754 +  755 +  756 +  757 +  758 +  759 +  760 +  761 +  762 +  763 +  764 +  765 +  766 +  767 +  768 +  769 +  770 +  771 +  772 +  773 +  774 +  775 +  776 +  777 +  778 +  779 +  780 +  781 +  782 +  783 +  784 +  785 +  786 +  787 +  788 +  789 +  790 +  791 +  792 +  793 +  794 +  795 +  796 +  797 +  798 +  799 +  800 +  801 +  802 +  803 +  804 +  805 +  806 +  807 +  808 +  809 +  810 +  811 +  812 +  813 +  814 +  815 +  816 +  817 +  818 +  819 +  820 +  821 +  822 +  823 +  824 +  825 +  826 +  827 +  828 +  829 +  830 +  831 +  832 +  833 +  834 +  835 +  836 +  837 +  838 +  839 +  840 +  841 +  842 +  843 +  844 +  845 +  846 +  847 +  848 +  849 +  850 +  851 +  852 +  853 +  854 +  855 +  856 +  857 +  858 +  859 +  860 +  861 +  862 +  863 +  864 +  865 +  866 +  867 +  868 +  869 +  870 +  871 +  872 +  873 +  874 +  875 +  876 +  877 +  878 +  879 +  880 +  881 +  882 +  883 +  884 +  885 +  886 +  887 +  888 +  889 +  890 +  891 +  892 +  893 +  894 +  895 +  896 +  897 +  898 +  899 +  900 +  901 +  902 +  903 +  904 +  905 +  906 +  907 +  908 +  909 +  910 +  911 +  912 +  913 +  914 +  915 +  916 +  917 +  918 +  919 +  920 +  921 +  922 +  923 +  924 +  925 +  926 +  927 +  928 +  929 +  930 +  931 +  932 +  933 +  934 +  935 +  936 +  937 +  938 +  939 +  940 +  941 +  942 +  943 +  944 +  945 +  946 +  947 +  948 +  949 +  950 +  951 +  952 +  953 +  954 +  955 +  956 +  957 +  958 +  959 +  960 +  961 +  962 +  963 +  964 +  965 +  966 +  967 +  968 +  969 +  970 +  971 +  972 +  973 +  974 +  975 +  976 +  977 +  978 +  979 +  980 +  981 +  982 +  983 +  984 +  985 +  986 +  987 +  988 +  989 +  990 +  991 +  992 +  993 +  994 +  995 +  996 +  997 +  998 +  999 +  1000 +  1001 +  1002 +  1003 +  1004 +  1005 +  1006 +  1007 +  1008 +  1009 +  1010 +  1011 +  1012 +  1013 +  1014 +  1015 +  1016 +  1017 +  1018 +  1019 +  1020 +  1021 +  1022 +  1023 +  1024 +  1025 +  1026 +  1027 +  1028 +  1029 +  1030 +  1031 +  1032 +  1033 +  1034 +  1035 +  1036 +  1037 +  1038 +  1039 +  1040 +  1041 +  1042 +  1043 +  1044 +  1045 +  1046 +  1047 +  1048 +  1049 +  1050 +  1051 +  1052 +  1053 +  1054 +  1055 +  1056 +  1057 +  1058 +  1059 +  1060 +  1061 +  1062 +  1063 +  1064 +  1065 +  1066 +  1067 +  1068 +  1069 +  1070 +  1071 +  1072 +  1073 +  1074 +  1075 +  1076 +  1077 +  1078 +  1079 +  1080 +  1081 +  1082 +  1083 +  1084 +  1085 +  1086 +  1087 +  1088 +  1089 +  1090 +  1091 +  1092 +  1093 +  1094 +  1095 +  1096 +  1097 +  1098 +  1099 +  1100 +  1101 +  1102 +  1103 +  1104 +  1105 +  1106 +  1107 +  1108 +  1109 +  1110 +  1111 +  1112 +  1113 +  1114 +  1115 +  1116 +  1117 +  1118 +  1119 +  1120 +  1121 +  1122 +  1123 +  1124 +  1125 +  1126 +  1127 +  1128 +  1129 +  1130 +  1131 +  1132 +  1133 +  1134 +  1135 +  1136 +  1137 +  1138 +  1139 +  1140 +  1141 +  1142 +  1143 +  1144 +  1145 +  1146 +  1147 +  1148 +  1149 +  1150 +  1151 +  1152 +  1153 +  1154 +  1155 +  1156 +  1157 +  1158 +  1159 +  1160 +  1161 +  1162 +  1163 +  1164 +  1165 +  1166 +  1167 +  1168 +  1169 +  1170 +  1171 +  1172 +  1173 +  1174 +  1175 +  1176 +  1177 +  1178 +  1179 +  1180 +  1181 +  1182 +  1183 +  1184 +  1185 +  1186 +  1187 +  1188 +  1189 +  1190 +  1191 +  1192 +  1193 +  1194 +  1195 +  1196 +  1197 +  1198 +  1199 +  1200 +  1201 +  1202 +  1203 +  1204 +  1205 +  1206 +  1207 +  1208 +  1209 +  1210 +  1211 +  1212 +  1213 +  1214 +  1215 +  1216 +  1217 +  1218 +  1219 +  1220 +  1221 +  1222 +  1223 +  1224 +  1225 +  1226 +  1227 +  1228 +  1229 +  1230 +  1231 +  1232 +  1233 +  1234 +  1235 +  1236 +  1237 +  1238 +  1239 +  1240 +  1241 +  1242 +  1243 +  1244 +  1245 +  1246 +  1247 +  1248 +  1249 +  1250 +  1251 +  1252 +  1253 +  1254 +  1255 +  1256 +  1257 +  1258 +  1259 +  1260 +  1261 +  1262 +  1263 +  1264 +  1265 +  1266 +  1267 +  1268 +  1269 +  1270 +  1271 +  1272 +  1273 +  1274 +  1275 +  1276 +  1277 +  1278 +  1279 +  1280 +  1281 +  1282 +  1283 +  1284 +  1285 +  1286 +  1287 +  1288 +  1289 +  1290 +  1291 +  1292 +  1293 +  1294 +  1295 +  1296 +  1297 +  1298 +  1299 +  1300 +  1301 +  1302 +  1303 +  1304 +  1305 +  1306 +  1307 +  1308 +  1309 +  1310 +  1311 +  1312 +  1313 +  1314 +  1315 +  1316 +  1317 +  1318 +  1319 +  1320 +  1321 +  1322 +  1323 +  1324 +  1325 +  1326 +  1327 +  1328 +  1329 +  1330 +  1331 +  1332 +  1333 +  1334 +  1335 +  1336 +  1337 +  1338 +  1339 +  1340 +  1341 +  1342 +  1343 +  1344 +  1345 +  1346 +  1347 +  1348 +  1349 +  1350 +  1351 +  1352 +  1353 +  1354 +  1355 +  1356 +  1357 +  1358 +  1359 +  1360 +  1361 +  1362 +  1363 +  1364 +  1365 +  1366 +  1367 +  1368 +  1369 +  1370 +  1371 +  1372 +  1373 +  1374 +  1375 +  1376 +  1377 +  1378 +  1379 +  1380 +  1381 +  1382 +  1383 +  1384 +  1385 +  1386 +  1387 +  1388 +  1389 +  1390 +  1391 +  1392 +  1393 +  1394 +  1395 +  1396 +  1397 +  1398 +  1399 +  1400 +  1401 +  1402 +  1403 +  1404 +  1405 +  1406 +  1407 +  1408 +  1409 +  1410 +  1411 +  1412 +  1413 +  1414 +  1415 +  1416 +  1417 +  1418 +  1419 +  1420 +  1421 +  1422 +  1423 +  1424 +  1425 +  1426 +  1427 +  1428 +  1429 +  1430 +  1431 +  1432 +  1433 +  1434 +  1435 +  1436 +  1437 +  1438 +  1439 +  1440 +  1441 +  1442 +  1443 +  1444 +  1445 +  1446 +  1447 +  1448 +  1449 +  1450 +  1451 +  1452 +  1453 +  1454 +  1455 +  1456 +  1457 +  1458 +  1459 +  1460 +  1461 +  1462 +  1463 +  1464 +  1465 +  1466 +  1467 +  1468 +  1469 +  1470 +  1471 +  1472 +  1473 +  1474 +  1475 +  1476 +  1477 +  1478 +  1479 +  1480 +  1481 +  1482 +  1483 +  1484 +  1485 +  1486 +  1487 +  1488 +  1489 +  1490 +  1491 +  1492 +  1493 +  1494 +  1495 +  1496 +  1497 +  1498 +  1499 +  1500 +  1501 +  1502 +  1503 +  1504 +  1505 +  1506 +  1507 +  1508 +  1509 +  1510 +  1511 +  1512 +  1513 +  1514 +  1515 +  1516 +  1517 +  1518 +  1519 +  1520 +  1521 +  1522 +  1523 +  1524 +  1525 +  1526 +  1527 +  1528 +  1529 +  1530 +  1531 +  1532 +  1533 +  1534 +  1535 +  1536 +  1537 +  1538 +  1539 +  1540 +  1541 +  1542 +  1543 +  1544 +  1545 +  1546 +  1547 +  1548 +  1549 +  1550 +  1551 +  1552 +  1553 +  1554 +  1555 +  1556 +  1557 +  1558 +  1559 +  1560 +  1561 +  1562 +  1563 +  1564 +  1565 +  1566 +  1567 +  1568 +  1569 +  1570 +  1571 +  1572 +  1573 +  1574 +  1575 +  1576 +  1577 +  1578 +  1579 +  1580 +  1581 +  1582 +  1583 +  1584 +  1585 +  1586 +  1587 +  1588 +  1589 +  1590 +  1591 +  1592 +  1593 +  1594 +  1595 +  1596 +  1597 +  1598 +  1599 +  1600 +  1601 +  1602 +  1603 +  1604 +  1605 +  1606 +  1607 +  1608 +  1609 +  1610 +  1611 +  1612 +  1613 +  1614 +  1615 +  1616 +  1617 +  1618 +  1619 +  1620 +  1621 +  1622 +  1623 +  1624 +  1625 +  1626 +  1627 +  1628 +  1629 +  1630 +  1631 +  1632 +  1633 +  1634 +  1635 +  1636 +  1637 +  1638 +  1639 +  1640 +  1641 +  1642 +  1643 +  1644 +  1645 +  1646 +  1647 +  1648 +  1649 +  1650 +  1651 +  1652 +  1653 +  1654 +  1655 +  1656 +  1657 +  1658 +  1659 +  1660 +  1661 +  1662 +  1663 +  1664 +  1665 +  1666 +  1667 +  1668 +  1669 +  1670 +  1671 +  1672 +  1673 +  1674 +  1675 +  1676 +  1677 +  1678 +  1679 +  1680 +  1681 +  1682 +  1683 +  1684 +  1685 +  1686 +  1687 +  1688 +  1689 +  1690 +  1691 +  1692 +  1693 +  1694 +  1695 +  1696 +  1697 +  1698 +  1699 +  1700 +  1701 +  1702 +  1703 +  1704 +  1705 +  1706 +  1707 +  1708 +  1709 +  1710 +  1711 +  1712 +  1713 +  1714 +  1715 +  1716 +  1717 +  1718 +  1719 +  1720 +  1721 +  1722 +  1723 +  1724 +  1725 +  1726 +  1727 +  1728 +  1729 +  1730 +  1731 +  1732 +  1733 +  1734 +  1735 +  1736 +  1737 +  1738 +  1739 +  1740 +  1741 +  1742 +  1743 +  1744 +  1745 +  1746 +  1747 +  1748 +  1749 +  1750 +  1751 +  1752 +  1753 +  1754 +  1755 +  1756 +  1757 +  1758 +  1759 +  1760 +  1761 +  1762 +  1763 +  1764 +  1765 +  1766 +  1767 +  1768 +  1769 +  1770 +  1771 +  1772 +  1773 +  1774 +  1775 +  1776 +  1777 +  1778 +  1779 +  1780 +  1781 +  1782 +  1783 +  1784 +  1785 +  1786 +  1787 +  1788 +  1789 +  1790 +  1791 +  1792 +  1793 +  1794 +  1795 +  1796 +  1797 +  1798 +  1799 +  1800 +  1801 +  1802 +  1803 +  1804 +  1805 +  1806 +  1807 +  1808 +  1809 +  1810 +  1811 +  1812 +  1813 +  1814 +  1815 +  1816 +  1817 +  1818 +  1819 +  1820 +  1821 +  1822 +  1823 +  1824 +  1825 +  1826 +  1827 +  1828 +  1829 +  1830 +  1831 +  1832 +  1833 +  1834 +  1835 +  1836 +  1837 +  1838 +  1839 +  1840 +  1841 +  1842 +  1843 +  1844 +  1845 +  1846 +  1847 +  1848 +  1849 +  1850 +  1851 +  1852 +  1853 +  1854 +  1855 +  1856 +  1857 +  1858 +  1859 +  1860 +  1861 +  1862 +  1863 +  1864 +  1865 +  1866 +  1867 +  1868 +  1869 +  1870 +  1871 +  1872 +  1873 +  1874 +  1875 +  1876 +  1877 +  1878 +  1879 +  1880 +  1881 +  1882 +  1883 +  1884 +  1885 +  1886 +  1887 +  1888 +  1889 +  1890 +  1891 +  1892 +  1893 +  1894 +  1895 +  1896 +  1897 +  1898 +  1899 +  1900 +  1901 +  1902 +  1903 +  1904 +  1905 +  1906 +  1907 +  1908 +  1909 +  1910 +  1911 +  1912 +  1913 +  1914 +  1915 +  1916 +  1917 +  1918 +  1919 +  1920 +  1921 +  1922 +  1923 +  1924 +  1925 +  1926 +  1927 +  1928 +  1929 +  1930 +  1931 +  1932 +  1933 +  1934 +  1935 +  1936 +  1937 +  1938 +  1939 +  1940 +  1941 +  1942 +  1943 +  1944 +  1945 +  1946 +  1947 +  1948 +  1949 +  1950 +  1951 +  1952 +  1953 +  1954 +  1955 +  1956 +  1957 +  1958 +  1959 +  1960 +  1961 +  1962 +  1963 +  1964 +  1965 +  1966 +  1967 +  1968 +  1969 +  1970 +  1971 +  1972 +  1973 +  1974 +  1975 +  1976 +  1977 +  1978 +  1979 +  1980 +  1981 +  1982 +  1983 +  1984 +  1985 +  1986 +  1987 +  1988 +  1989 +  1990 +  1991 +  1992 +  1993 +  1994 +  1995 +  1996 +  1997 +  1998 +  1999 +  2000 +  2001 +  2002 +  2003 +  2004 +  2005 +  2006 +  2007 +  2008 +  2009 +  2010 +  2011 +  2012 +  2013 +  2014 +  2015 +  2016 +  2017 +  2018 +  2019 +  2020 +  2021 +  2022 +  2023 +  2024 +  2025 +  2026 +  2027 +  2028 +  2029 +  2030 +  2031 +  2032 +  2033 +  2034 +  2035 +  2036 +  2037 +  2038 +  2039 +  2040 +  2041 +  2042 +  2043 +  2044 +  2045 +  2046 +  2047 +  2048 +  2049 +  2050 +  2051 +  2052 +  2053 +  2054 +  2055 +  2056 +  2057 +  2058 +  2059 +  2060 +  2061 +  2062 +  2063 +  2064 +  2065 +  2066 +  2067 +  2068 +  2069 +  2070 +  2071 +  2072 +  2073 +  2074 +  2075 +  2076 +  2077 +  2078 +  2079 +  2080 +  2081 +  2082 +  2083 +  2084 +  2085 +  2086 +  2087 +  2088 +  2089 +  2090 +  2091 +  2092 +  2093 +  2094 +  2095 +  2096 +  2097 +  2098 +  2099 +  2100 +  2101 +  2102 +  2103 +  2104 +  2105 +  2106 +  2107 +  2108 +  2109 +  2110 +  2111 +  2112 +  2113 +  2114 +  2115 +  2116 +  2117 +  2118 +  2119 +  2120 +  2121 +  2122 +  2123 +  2124 +  2125 +  2126 +  2127 +  2128 +  2129 +  2130 +  2131 +  2132 +  2133 +  2134 +  2135 +  2136 +  2137 +  2138 +  2139 +  2140 +  2141 +  2142 +  2143 +  2144 +  2145 +  2146 +  2147 +  2148 +  2149 +  2150 +  2151 +  2152 +  2153 +  2154 +  2155 +  2156 +  2157 +  2158 +  2159 +  2160 +  2161 +  2162 +  2163 +  2164 +  2165 +  2166 +  2167 +  2168 +  2169 +  2170 +  2171 +  2172 +  2173 +  2174 +  2175 +  2176 +  2177 +  2178 +  2179 +  2180 +  2181 +  2182 +  2183 +  2184 +  2185 +  2186 +  2187 +  2188 +  2189 +  2190 +  2191 +  2192 +  2193 +  2194 +  2195 +  2196 +  2197 +  2198 +  2199 +  2200 +  2201 +  2202 +  2203 +  2204 +  2205 +  2206 +  2207 +  2208 +  2209 +  2210 +  2211 +  2212 +  2213 +  2214 +  2215 +  2216 +  2217 +  2218 +  2219 +  2220 +  2221 +  2222 +  2223 +  2224 +  2225 +  2226 +  2227 +  2228 +  2229 +  2230 +  2231 +  2232 +  2233 +  2234 +  2235 +  2236 +  2237 +  2238 +  2239 +  2240 +  2241 +  2242 +  2243 +  2244 +  2245 +  2246 +  2247 +  2248 +  2249 +  2250 +  2251 +  2252 +  2253 +  2254 +  2255 +  2256 +  2257 +  2258 +  2259 +  2260 +  2261 +  2262 +  2263 +  2264 +  2265 +  2266 +  2267 +  2268 +  2269 +  2270 +  2271 +  2272 +  2273 +  2274 +  2275 +  2276 +  2277 +  2278 +  2279 +  2280 +  2281 +  2282 +  2283 +  2284 +  2285 +  2286 +  2287 +  2288 +  2289 +  2290 +  2291 +  2292 +  2293 +  2294 +  2295 +  2296 +  2297 +  2298 +  2299 +  2300 +  2301 +  2302 +  2303 +  2304 +  2305 +  2306 +  2307 +  2308 +  2309 +  2310 +  2311 +  2312 +  2313 +  2314 +  2315 +  2316 +  2317 +  2318 +  2319 +  2320 +  2321 +  2322 +  2323 +  2324 +  2325 +  2326 +  2327 +  2328 +  2329 +  2330 +  2331 +  2332 +  2333 +  2334 +  2335 +  2336 +  2337 +  2338 +  2339 +  2340 +  2341 +  2342 +  2343 +  2344 +  2345 +  2346 +  2347 +  2348 +  2349 +  2350 +  2351 +  2352 +  2353 +  2354 +  2355 +  2356 +  2357 +  2358 +  2359 +  2360 +  2361 +  2362 +  2363 +  2364 +  2365 +  2366 +  2367 +  2368 +  2369 +  2370 +  2371 +  2372 +  2373 +  2374 +  2375 +  2376 +  2377 +  2378 +  2379 +  2380 +  2381 +  2382 +  2383 +  2384 +  2385 +  2386 +  2387 +  2388 +  2389 +  2390 +  2391 +  2392 +  2393 +  2394 +  2395 +  2396 +  2397 +  2398 +  2399 +  2400 +  2401 +  2402 +  2403 +  2404 +  2405 +  2406 +  2407 +  2408 +  2409 +  2410 +  2411 +  2412 +  2413 +  2414 +  2415 +  2416 +  2417 +  2418 +  2419 +  2420 +  2421 +  2422 +  2423 +  2424 +  2425 +  2426 +  2427 +  2428 +  2429 +  2430 +  2431 +  2432 +  2433 +  2434 +  2435 +  2436 +  2437 +  2438 +  2439 +  2440 +  2441 +  2442 +  2443 +  2444 +  2445 +  2446 +  2447 +  2448 +  2449 +  2450 +  2451 +  2452 +  2453 +  2454 +  2455 +  2456 +  2457 +  2458 +  2459 +  2460 +  2461 +  2462 +  2463 +  2464 +  2465 +  2466 +  2467 +  2468 +  2469 +  2470 +  2471 +  2472 +  2473 +  2474 +  2475 +  2476 +  2477 +  2478 +  2479 +  2480 +  2481 +  2482 +  2483 +  2484 +  2485 +  2486 +  2487 +  2488 +  2489 +  2490 +  2491 +  2492 +  2493 +  2494 +  2495 +  2496 +  2497 +  2498 +  2499 +  2500 +  2501 +  2502 +  2503 +  2504 +  2505 +  2506 +  2507 +  2508 +  2509 +  2510 +  2511 +  2512 +  2513 +  2514 +  2515 +  2516 +  2517 +  2518 +  2519 +  2520 +  2521 +  2522 +  2523 +  2524 +  2525 +  2526 +  2527 +  2528 +  2529 +  2530 +  2531 +  2532 +  2533 +  2534 +  2535 +  2536 +  2537 +  2538 +  2539 +  2540 +  2541 +  2542 +  2543 +  2544 +  2545 +  2546 +  2547 +  2548 +  2549 +  2550 +  2551 +  2552 +  2553 +  2554 +  2555 +  2556 +  2557 +  2558 +  2559 +  2560 +  2561 +  2562 +  2563 +  2564 +  2565 +  2566 +  2567 +  2568 +  2569 +  2570 +  2571 +  2572 +  2573 +  2574 +  2575 +  2576 +  2577 +  2578 +  2579 +  2580 +  2581 +  2582 +  2583 +  2584 +  2585 +  2586 +  2587 +  2588 +  2589 +  2590 +  2591 +  2592 +  2593 +  2594 +  2595 +  2596 +  2597 +  2598 +  2599 +  2600 +  2601 +  2602 +  2603 +  2604 +  2605 +  2606 +  2607 +  2608 +  2609 +  2610 +  2611 +  2612 +  2613 +  2614 +  2615 +  2616 +  2617 +  2618 +  2619 +  2620 +  2621 +  2622 +  2623 +  2624 +  2625 +  2626 +  2627 +  2628 +  2629 +  2630 +  2631 +  2632 +  2633 +  2634 +  2635 +  2636 +  2637 +  2638 +  2639 +  2640 +  2641 +  2642 +  2643 +  2644 +  2645 +  2646 +  2647 +  2648 +  2649 +  2650 +  2651 +  2652 +  2653 +  2654 +  2655 +  2656 +  2657 +  2658 +  2659 +  2660 +  2661 +  2662 +  2663 +  2664 +  2665 +  2666 +  2667 +  2668 +  2669 +  2670 +  2671 +  2672 +  2673 +  2674 +  2675 +  2676 +  2677 +  2678 +  2679 +  2680 +  2681 +  2682 +  2683 +  2684 +  2685 +  2686 +  2687 +  2688 +  2689 +  2690 +  2691 +  2692 +  2693 +  2694 +  2695 +  2696 +  2697 +  2698 +  2699 +  2700 +  2701 +  2702 +  2703 +  2704 +  2705 +  2706 +  2707 +  2708 +  2709 +  2710 +  2711 +  2712 +  2713 +  2714 +  2715 +  2716 +  2717 +  2718 +  2719 +  2720 +  2721 +  2722 +  2723 +  2724 +  2725 +  2726 +  2727 +  2728 +  2729 +  2730 +  2731 +  2732 +  2733 +  2734 +  2735 +  2736 +  2737 +  2738 +  2739 +  2740 +  2741 +  2742 +  2743 +  2744 +  2745 +  2746 +  2747 +  2748 +  2749 +  2750 +  2751 +  2752 +  2753 +  2754 +  2755 +  2756 +  2757 +  2758 +  2759 +  2760 +  2761 +  2762 +  2763 +  2764 +  2765 +  2766 +  2767 +  2768 +  2769 +  2770 +  2771 +  2772 +  2773 +  2774 +  2775 +  2776 +  2777 +  2778 +  2779 +  2780 +  2781 +  2782 +  2783 +  2784 +  2785 +  2786 +  2787 +  2788 +  2789 +  2790 +  2791 +  2792 +  2793 +  2794 +  2795 +  2796 +  2797 +  2798 +  2799 +  2800 +  2801 +  2802 +  2803 +  2804 +  2805 +  2806 +  2807 +  2808 +  2809 +  2810 +  2811 +  2812 +  2813 +  2814 +  2815 +  2816 +  2817 +  2818 +  2819 +  2820 +  2821 +  2822 +  2823 +  2824 +  2825 +  2826 +  2827 +  2828 +  2829 +  2830 +  2831 +  2832 +  2833 +  2834 +  2835 +  2836 +  2837 +  2838 +  2839 +  2840 +  2841 +  2842 +  2843 +  2844 +  2845 +  2846 +  2847 +  2848 +  2849 +  2850 +  2851 +  2852 +  2853 +  2854 +  2855 +  2856 +  2857 +  2858 +  2859 +  2860 +  2861 +  2862 +  2863 +  2864 +  2865 +  2866 +  2867 +  2868 +  2869 +  2870 +  2871 +  2872 +  2873 +  2874 +  2875 +  2876 +  2877 +  2878 +  2879 +  2880 +  2881 +  2882 +  2883 +  2884 +  2885 +  2886 +  2887 +  2888 +  2889 +  2890 +  2891 +  2892 +  2893 +  2894 +  2895 +  2896 +  2897 +  2898 +  2899 +  2900 +  2901 +  2902 +  2903 +  2904 +  2905 +  2906 +  2907 +  2908 +  2909 +  2910 +  2911 +  2912 +  2913 +  2914 +  2915 +  2916 +  2917 +  2918 +  2919 +  2920 +  2921 +  2922 +  2923 +  2924 +  2925 +  2926 +  2927 +  2928 +  2929 +  2930 +  2931 +  2932 +  2933 +  2934 +  2935 +  2936 +  2937 +  2938 +  2939 +  2940 +  2941 +  2942 +  2943 +  2944 +  2945 +  2946 +  2947 +  2948 +  2949 +  2950 +  2951 +  2952 +  2953 +  2954 +  2955 +  2956 +  2957 +  2958 +  2959 +  2960 +  2961 +  2962 +  2963 +  2964 +  2965 +  2966 +  2967 +  2968 +  2969 +  2970 +  2971 +  2972 +  2973 +  2974 +  2975 +  2976 +  2977 +  2978 +  2979 +  2980 +  2981 +  2982 +  2983 +  2984 +  2985 +  2986 +  2987 +  2988 +  2989 +  2990 +  2991 +  2992 +  2993 +  2994 +  2995 +  2996 +  2997 +  2998 +  2999 +  3000 +  3001 +  3002 +  3003 +  3004 +  3005 +  3006 +  3007 +  3008 +  3009 +  3010 +  3011 +  3012 +  3013 +  3014 +  3015 +  3016 +  3017 +  3018 +  3019 +  3020 +  3021 +  3022 +  3023 +  3024 +  3025 +  3026 +  3027 +  3028 +  3029 +  3030 +  3031 +  3032 +  3033 +  3034 +  3035 +  3036 +  3037 +  3038 +  3039 +  3040 +  3041 +  3042 +  3043 +  3044 +  3045 +  3046 +  3047 +  3048 +  3049 +  3050 +  3051 +  3052 +  3053 +  3054 +  3055 +  3056 +  3057 +  3058 +  3059 +  3060 +  3061 +  3062 +  3063 +  3064 +  3065 +  3066 +  3067 +  3068 +  3069 +  3070 +  3071 +  3072 +  3073 +  3074 +  3075 +  3076 +  3077 +  3078 +  3079 +  3080 +  3081 +  3082 +  3083 +  3084 +  3085 +  3086 +  3087 +  3088 +  3089 +  3090 +  3091 +  3092 +  3093 +  3094 +  3095 +  3096 +  3097 +  3098 +  3099 +  3100 +  3101 +  3102 +  3103 +  3104 +  3105 +  3106 +  3107 +  3108 +  3109 +  3110 +  3111 +  3112 +  3113 +  3114 +  3115 +  3116 +  3117 +  3118 +  3119 +  3120 +  3121 +  3122 +  3123 +  3124 +  3125 +  3126 +  3127 +  3128 +  3129 +  3130 +  3131 +  3132 +  3133 +  3134 +  3135 +  3136 +  3137 +  3138 +  3139 +  3140 +  3141 +  3142 +  3143 +  3144 +  3145 +  3146 +  3147 +  3148 +  3149 +  3150 +  3151 +  3152 +  3153 +  3154 +  3155 +  3156 +  3157 +  3158 +  3159 +  3160 +  3161 +  3162 +  3163 +  3164 +  3165 +  3166 +  3167 +  3168 +  3169 +  3170 +  3171 +  3172 +  3173 +  3174 +  3175 +  3176 +  3177 +  3178 +  3179 +  3180 +  3181 +  3182 +  3183 +  3184 +  3185 +  3186 +  3187 +  3188 +  3189 +  3190 +  3191 +  3192 +  3193 +  3194 +  3195 +  3196 +  3197 +  3198 +  3199 +  3200 +  3201 +  3202 +  3203 +  3204 +  3205 +  3206 +  3207 +  3208 +  3209 +  3210 +  3211 +  3212 +  3213 +  3214 +  3215 +  3216 +  3217 +  3218 +  3219 +  3220 +  3221 +  3222 +  3223 +  3224 +  3225 +  3226 +  3227 +  3228 +  3229 +  3230 +  3231 +  3232 +  3233 +  3234 +  3235 +  3236 +  3237 +  3238 +  3239 +  3240 +  3241 +  3242 +  3243 +  3244 +  3245 +  3246 +  3247 +  3248 +  3249 +  3250 +  3251 +  3252 +  3253 +  3254 +  3255 +  3256 +  3257 +  3258 +  3259 +  3260 +  3261 +  3262 +  3263 +  3264 +  3265 +  3266 +  3267 +  3268 +  3269 +  3270 +  3271 +  3272 +  3273 +  3274 +  3275 +  3276 +  3277 +  3278 +  3279 +  3280 +  3281 +  3282 +  3283 +  3284 +  3285 +  3286 +  3287 +  3288 +  3289 +  3290 +  3291 +  3292 +  3293 +  3294 +  3295 +  3296 +  3297 +  3298 +  3299 +  3300 +  3301 +  3302 +  3303 +  3304 +  3305 +  3306 +  3307 +  3308 +  3309 +  3310 +  3311 +  3312 +  3313 +  3314 +  3315 +  3316 +  3317 +  3318 +  3319 +  3320 +  3321 +  3322 +  3323 +  3324 +  3325 +  3326 +  3327 +  3328 +  3329 +  3330 +  3331 +  3332 +  3333 +  3334 +  3335 +  3336 +  3337 +  3338 +  3339 +  3340 +  3341 +  3342 +  3343 +  3344 +  3345 +  3346 +  3347 +  3348 +  3349 +  3350 +  3351 +  3352 +  3353 +  3354 +  3355 +  3356 +  3357 +  3358 +  3359 +  3360 +  3361 +  3362 +  3363 +  3364 +  3365 +  3366 +  3367 +  3368 +  3369 +  3370 +  3371 +  3372 +  3373 +  3374 +  3375 +  3376 +  3377 +  3378 +  3379 +  3380 +  3381 +  3382 +  3383 +  3384 +  3385 +  3386 +  3387 +  3388 +  3389 +  3390 +  3391 +  3392 +  3393 +  3394 +  3395 +  3396 +  3397 +  3398 +  3399 +  3400 +  3401 +  3402 +  3403 +  3404 +  3405 +  3406 +  3407 +  3408 +  3409 +  3410 +  3411 +  3412 +  3413 +  3414 +  3415 +  3416 +  3417 +  3418 +  3419 +  3420 +  3421 +  3422 +  3423 +  3424 +  3425 +  3426 +  3427 +  3428 +  3429 +  3430 +  3431 +  3432 +  3433 +  3434 +  3435 +  3436 +  3437 +  3438 +  3439 +  3440 +  3441 +  3442 +  3443 +  3444 +  3445 +  3446 +  3447 +  3448 +  3449 +  3450 +  3451 +  3452 +  3453 +  3454 +  3455 +  3456 +  3457 +  3458 +  3459 +  3460 +  3461 +  3462 +  3463 +  3464 +  3465 +  3466 +  3467 +  3468 +  3469 +  3470 +  3471 +  3472 +  3473 +  3474 +  3475 +  3476 +  3477 +  3478 +  3479 +  3480 +  3481 +  3482 +  3483 +  3484 +  3485 +  3486 +  3487 +  3488 +  3489 +  3490 +  3491 +  3492 +  3493 +  3494 +  3495 +  3496 +  3497 +  3498 +  3499 +  3500 +  3501 +  3502 +  3503 +  3504 +  3505 +  3506 +  3507 +  3508 +  3509 +  3510 +  3511 +  3512 +  3513 +  3514 +  3515 +  3516 +  3517 +  3518 +  3519 +  3520 +  3521 +  3522 +  3523 +  3524 +  3525 +  3526 +  3527 +  3528 +  3529 +  3530 +  3531 +  3532 +  3533 +  3534 +  3535 +  3536 +  3537 +  3538 +  3539 +  3540 +  3541 +  3542 +  3543 +  3544 +  3545 +  3546 +  3547 +  3548 +  3549 +  3550 +  3551 +  3552 +  3553 +  3554 +  3555 +  3556 +  3557 +  3558 +  3559 +  3560 +  3561 +  3562 +  3563 +  3564 +  3565 +  3566 +  3567 +  3568 +  3569 +  3570 +  3571 +  3572 +  3573 +  3574 +  3575 +  3576 +  3577 +  3578 +  3579 +  3580 +  3581 +  3582 +  3583 +  3584 +  3585 +  3586 +  3587 +  3588 +  3589 +  3590 +  3591 +  3592 +  3593 +  3594 +  3595 +  3596 +  3597 +  3598 +  3599 +  3600 +  3601 +  3602 +  3603 +  3604 +  3605 +  3606 +  3607 +  3608 +  3609 +  3610 +  3611 +  3612 +  3613 +  3614 +  3615 +  3616 +  3617 +  3618 +  3619 +  3620 +  3621 +  3622 +  3623 +  3624 +  3625 +  3626 +  3627 +  3628 +  3629 +  3630 +  3631 +  3632 +  3633 +  3634 +  3635 +  3636 +  3637 +  3638 +  3639 +  3640 +  3641 +  3642 +  3643 +  3644 +  3645 +  3646 +  3647 +  3648 +  3649 +  3650 +  3651 +  3652 +  3653 +  3654 +  3655 +  3656 +  3657 +  3658 +  3659 +  3660 +  3661 +  3662 +  3663 +  3664 +  3665 +  3666 +  3667 +  3668 +  3669 +  3670 +  3671 +  3672 +  3673 +  3674 +  3675 +  3676 +  3677 +  3678 +  3679 +  3680 +  3681 +  3682 +  3683 +  3684 +  3685 +  3686 +  3687 +  3688 +  3689 +  3690 +  3691 +  3692 +  3693 +  3694 +  3695 +  3696 +  3697 +  3698 +  3699 +  3700 +  3701 +  3702 +  3703 +  3704 +  3705 +  3706 +  3707 +  3708 +  3709 +  3710 +  3711 +  3712 +  3713 +  3714 +  3715 +  3716 +  3717 +  3718 +  3719 +  3720 +  3721 +  3722 +  3723 +  3724 +  3725 +  3726 +  3727 +  3728 +  3729 +  3730 +  3731 +  3732 +  3733 +  3734 +  3735 +  3736 +  3737 +  3738 +  3739 +  3740 +  3741 +  3742 +  3743 +  3744 +  3745 +  3746 +  3747 +  3748 +  3749 +  3750 +  3751 +  3752 +  3753 +  3754 +  3755 +  3756 +  3757 +  3758 +  3759 +  3760 +  3761 +  3762 +  3763 +  3764 +  3765 +  3766 +  3767 +  3768 +  3769 +  3770 +  3771 +  3772 +  3773 +  3774 +  3775 +  3776 +  3777 +  3778 +  3779 +  3780 +  3781 +  3782 +  3783 +  3784 +  3785 +  3786 +  3787 +  3788 +  3789 +  3790 +  3791 +  3792 +  3793 +  3794 +  3795 +  3796 +  3797 +  3798 +  3799 +  3800 +  3801 +  3802 +  3803 +  3804 +  3805 +  3806 +  3807 +  3808 +  3809 +  3810 +  3811 +  3812 +  3813 +  3814 +  3815 +  3816 +  3817 +  3818 +  3819 +  3820 +  3821 +  3822 +  3823 +  3824 +  3825 +  3826 +  3827 +  3828 +  3829 +  3830 +  3831 +  3832 +  3833 +  3834 +  3835 +  3836 +  3837 +  3838 +  3839 +  3840 +  3841 +  3842 +  3843 +  3844 +  3845 +  3846 +  3847 +  3848 +  3849 +  3850 +  3851 +  3852 +  3853 +  3854 +  3855 +  3856 +  3857 +  3858 +  3859 +  3860 +  3861 +  3862 +  3863 +  3864 +  3865 +  3866 +  3867 +  3868 +  3869 +  3870 +  3871 +  3872 +  3873 +  3874 +  3875 +  3876 +  3877 +  3878 +  3879 +  3880 +  3881 +  3882 +  3883 +  3884 +  3885 +  3886 +  3887 +  3888 +  3889 +  3890 +  3891 +  3892 +  3893 +  3894 +  3895 +  3896 +  3897 +  3898 +  3899 +  3900 +  3901 +  3902 +  3903 +  3904 +  3905 +  3906 +  3907 +  3908 +  3909 +  3910 +  3911 +  3912 +  3913 +  3914 +  3915 +  3916 +  3917 +  3918 +  3919 +  3920 +  3921 +  3922 +  3923 +  3924 +  3925 +  3926 +  3927 +  3928 +  3929 +  3930 +  3931 +  3932 +  3933 +  3934 +  3935 +  3936 +  3937 +  3938 +  3939 +  3940 +  3941 +  3942 +  3943 +  3944 +  3945 +  3946 +  3947 +  3948 +  3949 +  3950 +  3951 +  3952 +  3953 +  3954 +  3955 +  3956 +  3957 +  3958 +  3959 +  3960 +  3961 +  3962 +  3963 +  3964 +  3965 +  3966 +  3967 +  3968 +  3969 +  3970 +  3971 +  3972 +  3973 +  3974 +  3975 +  3976 +  3977 +  3978 +  3979 +  3980 +  3981 +  3982 +  3983 +  3984 +  3985 +  3986 +  3987 +  3988 +  3989 +  3990 +  3991 +  3992 +  3993 +  3994 +  3995 +  3996 +  3997 +  3998 +  3999 +  4000 +  4001 +  4002 +  4003 +  4004 +  4005 +  4006 +  4007 +  4008 +  4009 +  4010 +  4011 +  4012 +  4013 +  4014 +  4015 +  4016 +  4017 +  4018 +  4019 +  4020 +  4021 +  4022 +  4023 +  4024 +  4025 +  4026 +  4027 +  4028 +  4029 +  4030 +  4031 +  4032 +  4033 +  4034 +  4035 +  4036 +  4037 +  4038 +  4039 +  4040 +  4041 +  4042 +  4043 +  4044 +  4045 +  4046 +  4047 +  4048 +  4049 +  4050 +  4051 +  4052 +  4053 +  4054 +  4055 +  4056 +  4057 +  4058 +  4059 +  4060 +  4061 +  4062 +  4063 +  4064 +  4065 +  4066 +  4067 +  4068 +  4069 +  4070 +  4071 +  4072 +  4073 +  4074 +  4075 +  4076 +  4077 +  4078 +  4079 +  4080 +  4081 +  4082 +  4083 +  4084 +  4085 +  4086 +  4087 +  4088 +  4089 +  4090 +  4091 +  4092 +  4093 +  4094 +  4095 +  4096 +  4097 +  4098 +  4099 +  4100 +  4101 +  4102 +  4103 +  4104 +  4105 +  4106 +  4107 +  4108 +  4109 +  4110 +  4111 +  4112 +  4113 +  4114 +  4115 +  4116 +  4117 +  4118 +  4119 +  4120 +  4121 +  4122 +  4123 +  4124 +  4125 +  4126 +  4127 +  4128 +  4129 +  4130 +  4131 +  4132 +  4133 +  4134 +  4135 +  4136 +  4137 +  4138 +  4139 +  4140 +  4141 +  4142 +  4143 +  4144 +  4145 +  4146 +  4147 +  4148 +  4149 +  4150 +  4151 +  4152 +  4153 +  4154 +  4155 +  4156 +  4157 +  4158 +  4159 +  4160 +  4161 +  4162 +  4163 +  4164 +  4165 +  4166 +  4167 +  4168 +  4169 +  4170 +  4171 +  4172 +  4173 +  4174 +  4175 +  4176 +  4177 +  4178 +  4179 +  4180 +  4181 +  4182 +  4183 +  4184 +  4185 +  4186 +  4187 +  4188 +  4189 +  4190 +  4191 +  4192 +  4193 +  4194 +  4195 +  4196 +  4197 +  4198 +  4199 +  4200 +  4201 +  4202 +  4203 +  4204 +  4205 +  4206 +  4207 +  4208 +  4209 +  4210 +  4211 +  4212 +  4213 +  4214 +  4215 +  4216 +  4217 +  4218 +  4219 +  4220 +  4221 +  4222 +  4223 +  4224 +  4225 +  4226 +  4227 +  4228 +  4229 +  4230 +  4231 +  4232 +  4233 +  4234 +  4235 +  4236 +  4237 +  4238 +  4239 +  4240 +  4241 +  4242 +  4243 +  4244 +  4245 +  4246 +  4247 +  4248 +  4249 +  4250 +  4251 +  4252 +  4253 +  4254 +  4255 +  4256 +  4257 +  4258 +  4259 +  4260 +  4261 +  4262 +  4263 +  4264 +  4265 +  4266 +  4267 +  4268 +  4269 +  4270 +  4271 +  4272 +  4273 +  4274 +  4275 +  4276 +  4277 +  4278 +  4279 +  4280 +  4281 +  4282 +  4283 +  4284 +  4285 +  4286 +  4287 +  4288 +  4289 +  4290 +  4291 +  4292 +  4293 +  4294 +  4295 +  4296 +  4297 +  4298 +  4299 +  4300 +  4301 +  4302 +  4303 +  4304 +  4305 +  4306 +  4307 +  4308 +  4309 +  4310 +  4311 +  4312 +  4313 +  4314 +  4315 +  4316 +  4317 +  4318 +  4319 +  4320 +  4321 +  4322 +  4323 +  4324 +  4325 +  4326 +  4327 +  4328 +  4329 +  4330 +  4331 +  4332 +  4333 +  4334 +  4335 +  4336 +  4337 +  4338 +  4339 +  4340 +  4341 +  4342 +  4343 +  4344 +  4345 +  4346 +  4347 +  4348 +  4349 +  4350 +  4351 +  4352 +  4353 +  4354 +  4355 +  4356 +  4357 +  4358 +  4359 +  4360 +  4361 +  4362 +  4363 +  4364 +  4365 +  4366 +  4367 +  4368 +  4369 +  4370 +  4371 +  4372 +  4373 +  4374 +  4375 +  4376 +  4377 +  4378 +  4379 +  4380 +  4381 +  4382 +  4383 +  4384 +  4385 +  4386 +  4387 +  4388 +  4389 +  4390 +  4391 +  4392 +  4393 +  4394 +  4395 +  4396 +  4397 +  4398 +  4399 +  4400 +  4401 +  4402 +  4403 +  4404 +  4405 +  4406 +  4407 +  4408 +  4409 +  4410 +  4411 +  4412 +  4413 +  4414 +  4415 +  4416 +  4417 +  4418 +  4419 +  4420 +  4421 +  4422 +  4423 +  4424 +  4425 +  4426 +  4427 +  4428 +  4429 +  4430 +  4431 +  4432 +  4433 +  4434 +  4435 +  4436 +  4437 +  4438 +  4439 +  4440 +  4441 +  4442 +  4443 +  4444 +  4445 +  4446 +  4447 +  4448 +  4449 +  4450 +  4451 +  4452 +  4453 +  4454 +  4455 +  4456 +  4457 +  4458 +  4459 +  4460 +  4461 +  4462 +  4463 +  4464 +  4465 +  4466 +  4467 +  4468 +  4469 +  4470 +  4471 +  4472 +  4473 +  4474 +  4475 +  4476 +  4477 +  4478 +  4479 +  4480 +  4481 +  4482 +  4483 +  4484 +  4485 +  4486 +  4487 +  4488 +  4489 +  4490 +  4491 +  4492 +  4493 +  4494 +  4495 +  4496 +  4497 +  4498 +  4499 +  4500 +  4501 +  4502 +  4503 +  4504 +  4505 +  4506 +  4507 +  4508 +  4509 +  4510 +  4511 +  4512 +  4513 +  4514 +  4515 +  4516 +  4517 +  4518 +  4519 +  4520 +  4521 +  4522 +  4523 +  4524 +  4525 +  4526 +  4527 +  4528 +  4529 +  4530 +  4531 +  4532 +  4533 +  4534 +  4535 +  4536 +  4537 +  4538 +  4539 +  4540 +  4541 +  4542 +  4543 +  4544 +  4545 +  4546 +  4547 +  4548 +  4549 +  4550 +  4551 +  4552 +  4553 +  4554 +  4555 +  4556 +  4557 +  4558 +  4559 +  4560 +  4561 +  4562 +  4563 +  4564 +  4565 +  4566 +  4567 +  4568 +  4569 +  4570 +  4571 +  4572 +  4573 +  4574 +  4575 +  4576 +  4577 +  4578 +  4579 +  4580 +  4581 +  4582 +  4583 +  4584 +  4585 +  4586 +  4587 +  4588 +  4589 +  4590 +  4591 +  4592 +  4593 +  4594 +  4595 +  4596 +  4597 +  4598 +  4599 +  4600 +  4601 +  4602 +  4603 +  4604 +  4605 +  4606 +  4607 +  4608 +  4609 +  4610 +  4611 +  4612 +  4613 +  4614 +  4615 +  4616 +  4617 +  4618 +  4619 +  4620 +  4621 +  4622 +  4623 +  4624 +  4625 +  4626 +  4627 +  4628 +  4629 +  4630 +  4631 +  4632 +  4633 +  4634 +  4635 +  4636 +  4637 +  4638 +  4639 +  4640 +  4641 +  4642 +  4643 +  4644 +  4645 +  4646 +  4647 +  4648 +  4649 +  4650 +  4651 +  4652 +  4653 +  4654 +  4655 +  4656 +  4657 +  4658 +  4659 +  4660 +  4661 +  4662 +  4663 +  4664 +  4665 +  4666 +  4667 +  4668 +  4669 +  4670 +  4671 +  4672 +  4673 +  4674 +  4675 +  4676 +  4677 +  4678 +  4679 +  4680 +  4681 +  4682 +  4683 +  4684 +  4685 +  4686 +  4687 +  4688 +  4689 +  4690 +  4691 +  4692 +  4693 +  4694 +  4695 +  4696 +  4697 +  4698 +  4699 +  4700 +  4701 +  4702 +  4703 +  4704 +  4705 +  4706 +  4707 +  4708 +  4709 +  4710 +  4711 +  4712 +  4713 +  4714 +  4715 +  4716 +  4717 +  4718 +  4719 +  4720 +  4721 +  4722 +  4723 +  4724 +  4725 +  4726 +  4727 +  4728 +  4729 +  4730 +  4731 +  4732 +  4733 +  4734 +  4735 +  4736 +  4737 +  4738 +  4739 +  4740 +  4741 +  4742 +  4743 +  4744 +  4745 +  4746 +  4747 +  4748 +  4749 +  4750 +  4751 +  4752 +  4753 +  4754 +  4755 +  4756 +  4757 +  4758 +  4759 +  4760 +  4761 +  4762 +  4763 +  4764 +  4765 +  4766 +  4767 +  4768 +  4769 +  4770 +  4771 +  4772 +  4773 +  4774 +  4775 +  4776 +  4777 +  4778 +  4779 +  4780 +  4781 +  4782 +  4783 +  4784 +  4785 +  4786 +  4787 +  4788 +  4789 +  4790 +  4791 +  4792 +  4793 +  4794 +  4795 +  4796 +  4797 +  4798 +  4799 +  4800 +  4801 +  4802 +  4803 +  4804 +  4805 +  4806 +  4807 +  4808 +  4809 +  4810 +  4811 +  4812 +  4813 +  4814 +  4815 +  4816 +  4817 +  4818 +  4819 +  4820 +  4821 +  4822 +  4823 +  4824 +  4825 +  4826 +  4827 +  4828 +  4829 +  4830 +  4831 +  4832 +  4833 +  4834 +  4835 +  4836 +  4837 +  4838 +  4839 +  4840 +  4841 +  4842 +  4843 +  4844 +  4845 +  4846 +  4847 +  4848 +  4849 +  4850 +  4851 +  4852 +  4853 +  4854 +  4855 +  4856 +  4857 +  4858 +  4859 +  4860 +  4861 +  4862 +  4863 +  4864 +  4865 +  4866 +  4867 +  4868 +  4869 +  4870 +  4871 +  4872 +  4873 +  4874 +  4875 +  4876 +  4877 +  4878 +  4879 +  4880 +  4881 +  4882 +  4883 +  4884 +  4885 +  4886 +  4887 +  4888 +  4889 +  4890 +  4891 +  4892 +  4893 +  4894 +  4895 +  4896 +  4897 +  4898 +  4899 +  4900 +  4901 +  4902 +  4903 +  4904 +  4905 +  4906 +  4907 +  4908 +  4909 +  4910 +  4911 +  4912 +  4913 +  4914 +  4915 +  4916 +  4917 +  4918 +  4919 +  4920 +  4921 +  4922 +  4923 +  4924 +  4925 +  4926 +  4927 +  4928 +  4929 +  4930 +  4931 +  4932 +  4933 +  4934 +  4935 +  4936 +  4937 +  4938 +  4939 +  4940 +  4941 +  4942 +  4943 +  4944 +  4945 +  4946 +  4947 +  4948 +  4949 +  4950 +  4951 +  4952 +  4953 +  4954 +  4955 +  4956 +  4957 +  4958 +  4959 +  4960 +  4961 +  4962 +  4963 +  4964 +  4965 +  4966 +  4967 +  4968 +  4969 +  4970 +  4971 +  4972 +  4973 +  4974 +  4975 +  4976 +  4977 +  4978 +  4979 +  4980 +  4981 +  4982 +  4983 +  4984 +  4985 +  4986 +  4987 +  4988 +  4989 +  4990 +  4991 +  4992 +  4993 +  4994 +  4995 +  4996 +  4997 +  4998 +  4999 +  5000 +  5001 +  5002 +  5003 +  5004 +  5005 +  5006 +  5007 +  5008 +  5009 +  5010 +  5011 +  5012 +  5013 +  5014 +  5015 +  5016 +  5017 +  5018 +  5019 +  5020 +  5021 +  5022 +  5023 +  5024 +  5025 +  5026 +  5027 +  5028 +  5029 +  5030 +  5031 +  5032 +  5033 +  5034 +  5035 +  5036 +  5037 +  5038 +  5039 +  5040 +  5041 +  5042 +  5043 +  5044 +  5045 +  5046 +  5047 +  5048 +  5049 +  5050 +  5051 +  5052 +  5053 +  5054 +  5055 +  5056 +  5057 +  5058 +  5059 +  5060 +  5061 +  5062 +  5063 +  5064 +  5065 +  5066 +  5067 +  5068 +  5069 +  5070 +  5071 +  5072 +  5073 +  5074 +  5075 +  5076 +  5077 +  5078 +  5079 +  5080 +  5081 +  5082 +  5083 +  5084 +  5085 +  5086 +  5087 +  5088 +  5089 +  5090 +  5091 +  5092 +  5093 +  5094 +  5095 +  5096 +  5097 +  5098 +  5099 +  5100 +  5101 +  5102 +  5103 +  5104 +  5105 +  5106 +  5107 +  5108 +  5109 +  5110 +  5111 +  5112 +  5113 +  5114 +  5115 +  5116 +  5117 +  5118 +  5119 +  5120 +  5121 +  5122 +  5123 +  5124 +  5125 +  5126 +  5127 +  5128 +  5129 +  5130 +  5131 +  5132 +  5133 +  5134 +  5135 +  5136 +  5137 +  5138 +  5139 +  5140 +  5141 +  5142 +  5143 +  5144 +  5145 +  5146 +  5147 +  5148 +  5149 +  5150 +  5151 +  5152 +  5153 +  5154 +  5155 +  5156 +  5157 +  5158 +  5159 +  5160 +  5161 +  5162 +  5163 +  5164 +  5165 +  5166 +  5167 +  5168 +  5169 +  5170 +  5171 +  5172 +  5173 +  5174 +  5175 +  5176 +  5177 +  5178 +  5179 +  5180 +  5181 +  5182 +  5183 +  5184 +  5185 +  5186 +  5187 +  5188 +  5189 +  5190 +  5191 +  5192 +  5193 +  5194 +  5195 +  5196 +  5197 +  5198 +  5199 +  5200 +  5201 +  5202 +  5203 +  5204 +  5205 +  5206 +  5207 +  5208 +  5209 +  5210 +  5211 +  5212 +  5213 +  5214 +  5215 +  5216 +  5217 +  5218 +  5219 +  5220 +  5221 +  5222 +  5223 +  5224 +  5225 +  5226 +  5227 +  5228 +  5229 +  5230 +  5231 +  5232 +  5233 +  5234 +  5235 +  5236 +  5237 +  5238 +  5239 +  5240 +  5241 +  5242 +  5243 +  5244 +  5245 +  5246 +  5247 +  5248 +  5249 +  5250 +  5251 +  5252 +  5253 +  5254 +  5255 +  5256 +  5257 +  5258 +  5259 +  5260 +  5261 +  5262 +  5263 +  5264 +  5265 +  5266 +  5267 +  5268 +  5269 +  5270 +  5271 +  5272 +  5273 +  5274 +  5275 +  5276 +  5277 +  5278 +  5279 +  5280 +  5281 +  5282 +  5283 +  5284 +  5285 +  5286 +  5287 +  5288 +  5289 +  5290 +  5291 +  5292 +  5293 +  5294 +  5295 +  5296 +  5297 +  5298 +  5299 +  5300 +  5301 +  5302 +  5303 +  5304 +  5305 +  5306 +  5307 +  5308 +  5309 +  5310 +  5311 +  5312 +  5313 +  5314 +  5315 +  5316 +  5317 +  5318 +  5319 +  5320 +  5321 +  5322 +  5323 +  5324 +  5325 +  5326 +  5327 +  5328 +  5329 +  5330 +  5331 +  5332 +  5333 +  5334 +  5335 +  5336 +  5337 +  5338 +  5339 +  5340 +  5341 +  5342 +  5343 +  5344 +  5345 +  5346 +  5347 +  5348 +  5349 +  5350 +  5351 +  5352 +  5353 +  5354 +  5355 +  5356 +  5357 +  5358 +  5359 +  5360 +  5361 +  5362 +  5363 +  5364 +  5365 +  5366 +  5367 +  5368 +  5369 +  5370 +  5371 +  5372 +  5373 +  5374 +  5375 +  5376 +  5377 +  5378 +  5379 +  5380 +  5381 +  5382 +  5383 +  5384 +  5385 +  5386 +  5387 +  5388 +  5389 +  5390 +  5391 +  5392 +  5393 +  5394 +  5395 +  5396 +  5397 +  5398 +  5399 +  5400 +  5401 +  5402 +  5403 +  5404 +  5405 +  5406 +  5407 +  5408 +  5409 +  5410 +  5411 +  5412 +  5413 +  5414 +  5415 +  5416 +  5417 +  5418 +  5419 +  5420 +  5421 +  5422 +  5423 +  5424 +  5425 +  5426 +  5427 +  5428 +  5429 +  5430 +  5431 +  5432 +  5433 +  5434 +  5435 +  5436 +  5437 +  5438 +  5439 +  5440 +  5441 +  5442 +  5443 +  5444 +  5445 +  5446 +  5447 +  5448 +  5449 +  5450 +  5451 +  5452 +  5453 +  5454 +  5455 +  5456 +  5457 +  5458 +  5459 +  5460 +  5461 +  5462 +  5463 +  5464 +  5465 +  5466 +  5467 +  5468 +  5469 +  5470 +  5471 +  5472 +  5473 +  5474 +  5475 +  5476 +  5477 +  5478 +  5479 +  5480 +  5481 +  5482 +  5483 +  5484 +  5485 +  5486 +  5487 +  5488 +  5489 +  5490 +  5491 +  5492 +  5493 +  5494 +  5495 +  5496 +  5497 +  5498 +  5499 +  5500 +  5501 +  5502 +  5503 +  5504 +  5505 +  5506 +  5507 +  5508 +  5509 +  5510 +  5511 +  5512 +  5513 +  5514 +  5515 +  5516 +  5517 +  5518 +  5519 +  5520 +  5521 +  5522 +  5523 +  5524 +  5525 +  5526 +  5527 +  5528 +  5529 +  5530 +  5531 +  5532 +  5533 +  5534 +  5535 +  5536 +  5537 +  5538 +  5539 +  5540 +  5541 +  5542 +  5543 +  5544 +  5545 +  5546 +  5547 +  5548 +  5549 +  5550 +  5551 +  5552 +  5553 +  5554 +  5555 +  5556 +  5557 +  5558 +  5559 +  5560 +  5561 +  5562 +  5563 +  5564 +  5565 +  5566 +  5567 +  5568 +  5569 +  5570 +  5571 +  5572 +  5573 +  5574 +  5575 +  5576 +  5577 +  5578 +  5579 +  5580 +  5581 +  5582 +  5583 +  5584 +  5585 +  5586 +  5587 +  5588 +  5589 +  5590 +  5591 +  5592 +  5593 +  5594 +  5595 +  5596 +  5597 +  5598 +  5599 +  5600 +  5601 +  5602 +  5603 +  5604 +  5605 +  5606 +  5607 +  5608 +  5609 +  5610 +  5611 +  5612 +  5613 +  5614 +  5615 +  5616 +  5617 +  5618 +  5619 +  5620 +  5621 +  5622 +  5623 +  5624 +  5625 +  5626 +  5627 +  5628 +  5629 +  5630 +  5631 +  5632 +  5633 +  5634 +  5635 +  5636 +  5637 +  5638 +  5639 +  5640 +  5641 +  5642 +  5643 +  5644 +  5645 +  5646 +  5647 +  5648 +  5649 +  5650 +  5651 +  5652 +  5653 +  5654 +  5655 +  5656 +  5657 +  5658 +  5659 +  5660 +  5661 +  5662 +  5663 +  5664 +  5665 +  5666 +  5667 +  5668 +  5669 +  5670 +  5671 +  5672 +  5673 +  5674 +  5675 +  5676 +  5677 +  5678 +  5679 +  5680 +  5681 +  5682 +  5683 +  5684 +  5685 +  5686 +  5687 +  5688 +  5689 +  5690 +  5691 +  5692 +  5693 +  5694 +  5695 +  5696 +  5697 +  5698 +  5699 +  5700 +  5701 +  5702 +  5703 +  5704 +  5705 +  5706 +  5707 +  5708 +  5709 +  5710 +  5711 +  5712 +  5713 +  5714 +  5715 +  5716 +  5717 +  5718 +  5719 +  5720 +  5721 +  5722 +  5723 +  5724 +  5725 +  5726 +  5727 +  5728 +  5729 +  5730 +  5731 +  5732 +  5733 +  5734 +  5735 +  5736 +  5737 +  5738 +  5739 +  5740 +  5741 +  5742 +  5743 +  5744 +  5745 +  5746 +  5747 +  5748 +  5749 +  5750 +  5751 +  5752 +  5753 +  5754 +  5755 +  5756 +  5757 +  5758 +  5759 +  5760 + �d2 5761 +  5762 +  5763 +  5764 +  5765 +  5766 +  5767 +  5768 +  5769 +  5770 +  5771 +  5772 +  5773 +  5774 +  5775 +  5776 +  5777 +  5778 +  5779 +  5780 +  5781 +  5782 +  5783 +  5784 +  5785 +  5786 +  5787 +  5788 +  5789 +  5790 +  5791 +  5792 +  5793 +  5794 +  5795 +  5796 +  5797 +  5798 +  5799 +  5800 +  5801 +  5802 +  5803 +  5804 +  5805 +  5806 +  5807 +  5808 +  5809 +  5810 +  5811 +  5812 +  5813 +  5814 +  5815 +  5816 +  5817 +  5818 +  5819 +  5820 +  5821 +  5822 +  5823 +  5824 +  5825 +  5826 +  5827 +  5828 +  5829 +  5830 +  5831 +  5832 +  5833 +  5834 +  5835 +  5836 +  5837 +  5838 +  5839 +  5840 +  5841 +  5842 +  5843 +  5844 +  5845 +  5846 +  5847 +  5848 +  5849 +  5850 +  5851 +  5852 +  5853 +  5854 +  5855 +  5856 +  5857 +  5858 +  5859 +  5860 +  5861 +  5862 +  5863 +  5864 +  5865 +  5866 +  5867 +  5868 +  5869 +  5870 +  5871 +  5872 +  5873 +  5874 +  5875 +  5876 +  5877 +  5878 +  5879 +  5880 +  5881 + �d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 5882 +  5883 +  5884 +  5885 +  5886 +  5887 +  5888 +  5889 +  5890 +  5891 +  5892 +  5893 +  5894 +  5895 +  5896 +  5897 +  5898 +  5899 +  5900 +  5901 +  5902 +  5903 +  5904 +  5905 +  5906 +  5907 +  5908 +  5909 +  5910 +  5911 +  5912 +  5913 +  5914 +  5915 +  5916 +  5917 +  5918 +  5919 +  5920 +  5921 +  5922 +  5923 +  5924 +  5925 +  5926 +  5927 +  5928 +  5929 +  5930 +  5931 +  5932 +  5933 +  5934 +  5935 +  5936 +  5937 +  5938 +  5939 +  5940 +  5941 +  5942 +  5943 +  5944 +  5945 +  5946 +  5947 +  5948 +  5949 +  5950 +  5951 +  5952 +  5953 +  5954 +  5955 +  5956 +  5957 +  5958 +  5959 +  5960 +  5961 +  5962 +  5963 +  5964 +  5965 +  5966 +  5967 +  5968 +  5969 +  5970 +  5971 +  5972 +  5973 +  5974 +  5975 +  5976 +  5977 +  5978 +  5979 +  5980 +  5981 +  5982 +  5983 +  5984 +  5985 +  5986 +  5987 +  5988 +  5989 +  5990 +  5991 +  5992 +  5993 +  5994 +  5995 +  5996 +  5997 + �d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 5998 +  5999 +  6000 +  6001 +  6002 +  6003 +  6004 +  6005 +  6006 +  6007 +  6008 +  6009 +  6010 +  6011 +  6012 +  6013 +  6014 +  6015 +  6016 +  6017 +  6018 +  6019 +  6020 +  6021 +  6022 +  6023 +  6024 +  6025 +  6026 +  6027 +  6028 +  6029 +  6030 +  6031 +  6032 +  6033 +  6034 +  6035 +  6036 +  6037 +  6038 +  6039 +  6040 +  6041 +  6042 +  6043 +  6044 +  6045 +  6046 +  6047 +  6048 +  6049 +  6050 +  6051 +  6052 +  6053 +  6054 +  6055 +  6056 +  6057 +  6058 +  6059 +  6060 +  6061 +  6062 +  6063 +  6064 +  6065 +  6066 +  6067 +  6068 +  6069 +  6070 +  6071 +  6072 +  6073 +  6074 +  6075 +  6076 +  6077 +  6078 +  6079 +  6080 +  6081 +  6082 +  6083 +  6084 +  6085 +  6086 +  6087 +  6088 +  6089 +  6090 +  6091 +  6092 +  6093 +  6094 +  6095 +  6096 +  6097 +  6098 +  6099 +  6100 +  6101 +  6102 +  6103 +  6104 +  6105 +  6106 +  6107 +  6108 +  6109 +  6110 +  6111 + �d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 6112 +  6113 +  6114 +  6115 +  6116 +  6117 +  6118 +  6119 +  6120 +  6121 +  6122 +  6123 +  6124 +  6125 +  6126 +  6127 +  6128 +  6129 +  6130 +  6131 +  6132 +  6133 +  6134 +  6135 +  6136 +  6137 +  6138 +  6139 +  6140 +  6141 +  6142 +  6143 +  6144 +  6145 +  6146 +  6147 +  6148 +  6149 +  6150 +  6151 +  6152 +  6153 +  6154 +  6155 +  6156 +  6157 +  6158 +  6159 +  6160 +  6161 +  6162 +  6163 +  6164 +  6165 +  6166 +  6167 +  6168 +  6169 +  6170 +  6171 +  6172 +  6173 +  6174 +  6175 +  6176 +  6177 +  6178 +  6179 +  6180 +  6181 +  6182 +  6183 +  6184 +  6185 +  6186 +  6187 +  6188 +  6189 +  6190 +  6191 +  6192 +  6193 +  6194 +  6195 +  6196 +  6197 +  6198 +  6199 +  6200 +  6201 +  6202 +  6203 +  6204 +  6205 +  6206 +  6207 +  6208 +  6209 +  6210 +  6211 +  6212 +  6213 +  6214 +  6215 +  6216 +  6217 +  6218 +  6219 +  6220 +  6221 +  6222 +  6223 + �d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 6224 +  6225 +  6226 +  6227 +  6228 +  6229 +  6230 +  6231 +  6232 +  6233 +  6234 +  6235 +  6236 +  6237 +  6238 +  6239 +  6240 +  6241 +  6242 +  6243 +  6244 +  6245 +  6246 +  6247 +  6248 +  6249 +  6250 +  6251 +  6252 +  6253 +  6254 +  6255 +  6256 +  6257 +  6258 +  6259 +  6260 +  6261 +  6262 +  6263 +  6264 +  6265 +  6266 +  6267 +  6268 +  6269 +  6270 +  6271 +  6272 +  6273 +  6274 +  6275 +  6276 +  6277 +  6278 +  6279 +  6280 +  6281 +  6282 +  6283 +  6284 +  6285 +  6286 +  6287 +  6288 +  6289 +  6290 +  6291 +  6292 +  6293 +  6294 +  6295 +  6296 +  6297 +  6298 +  6299 +  6300 +  6301 +  6302 +  6303 +  6304 +  6305 +  6306 +  6307 +  6308 +  6309 +  6310 +  6311 +  6312 +  6313 +  6314 +  6315 +  6316 +  6317 +  6318 +  6319 +  6320 +  6321 +  6322 +  6323 +  6324 +  6325 +  6326 +  6327 + 2�� 6328 +  6329 +  6330 +  6331 +  6332 +  6333 + �d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 6334 +  6335 +  6336 +  6337 +  6338 +  6339 +  6340 +  6341 +  6342 +  6343 +  6344 +  6345 +  6346 +  6347 +  6348 +  6349 +  6350 +  6351 +  6352 +  6353 +  6354 +  6355 +  6356 +  6357 +  6358 +  6359 +  6360 +  6361 +  6362 +  6363 +  6364 +  6365 +  6366 +  6367 +  6368 +  6369 +  6370 +  6371 +  6372 +  6373 +  6374 +  6375 +  6376 +  6377 +  6378 +  6379 +  6380 +  6381 +  6382 +  6383 +  6384 +  6385 +  6386 +  6387 +  6388 +  6389 +  6390 +  6391 +  6392 +  6393 +  6394 +  6395 +  6396 +  6397 +  6398 +  6399 +  6400 +  6401 +  6402 +  6403 +  6404 +  6405 +  6406 +  6407 +  6408 +  6409 +  6410 +  6411 +  6412 +  6413 +  6414 +  6415 +  6416 +  6417 +  6418 +  6419 +  6420 +  6421 +  6422 +  6423 +  6424 +  6425 +  6426 +  6427 +  6428 +  6429 +  6430 +  6431 +  6432 + 2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 6433 +  6434 +  6435 +  6436 +  6437 +  6438 +  6439 +  6440 +  6441 +  6442 +  6443 +  6444 +  6445 +  6446 +  6447 +  6448 +  6449 +  6450 +  6451 +  6452 +  6453 +  6454 +  6455 +  6456 +  6457 +  6458 +  6459 +  6460 +  6461 +  6462 +  6463 +  6464 +  6465 +  6466 +  6467 +  6468 +  6469 +  6470 +  6471 +  6472 +  6473 +  6474 +  6475 +  6476 +  6477 +  6478 +  6479 +  6480 +  6481 +  6482 +  6483 +  6484 +  6485 +  6486 +  6487 +  6488 +  6489 +  6490 +  6491 +  6492 +  6493 +  6494 +  6495 +  6496 +  6497 +  6498 +  6499 +  6500 +  6501 +  6502 +  6503 +  6504 +  6505 +  6506 +  6507 +  6508 +  6509 +  6510 +  6511 +  6512 +  6513 +  6514 +  6515 +  6516 +  6517 +  6518 +  6519 +  6520 +  6521 +  6522 +  6523 +  6524 +  6525 +  6526 +  6527 +  6528 +  6529 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 6530 +  6531 +  6532 +  6533 +  6534 +  6535 +  6536 +  6537 +  6538 +  6539 +  6540 +  6541 +  6542 +  6543 +  6544 +  6545 +  6546 +  6547 +  6548 +  6549 +  6550 +  6551 +  6552 +  6553 +  6554 +  6555 +  6556 +  6557 +  6558 +  6559 +  6560 +  6561 +  6562 +  6563 +  6564 +  6565 +  6566 +  6567 +  6568 +  6569 +  6570 +  6571 +  6572 +  6573 +  6574 +  6575 +  6576 +  6577 +  6578 +  6579 +  6580 +  6581 +  6582 +  6583 +  6584 +  6585 +  6586 +  6587 +  6588 +  6589 +  6590 +  6591 +  6592 +  6593 +  6594 +  6595 +  6596 +  6597 +  6598 +  6599 +  6600 +  6601 +  6602 +  6603 +  6604 +  6605 +  6606 +  6607 +  6608 +  6609 +  6610 +  6611 +  6612 +  6613 +  6614 +  6615 +  6616 +  6617 +  6618 +  6619 +  6620 +  6621 +  6622 +  6623 +  6624 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 6625 +  6626 +  6627 +  6628 +  6629 +  6630 +  6631 +  6632 +  6633 +  6634 +  6635 +  6636 +  6637 +  6638 +  6639 +  6640 +  6641 +  6642 +  6643 +  6644 +  6645 +  6646 +  6647 +  6648 +  6649 +  6650 +  6651 +  6652 +  6653 +  6654 +  6655 +  6656 +  6657 +  6658 +  6659 +  6660 +  6661 +  6662 +  6663 +  6664 +  6665 +  6666 +  6667 +  6668 +  6669 +  6670 +  6671 +  6672 +  6673 +  6674 +  6675 +  6676 +  6677 +  6678 +  6679 +  6680 +  6681 +  6682 +  6683 +  6684 +  6685 +  6686 +  6687 +  6688 +  6689 +  6690 +  6691 +  6692 +  6693 +  6694 +  6695 +  6696 +  6697 +  6698 +  6699 +  6700 +  6701 +  6702 +  6703 +  6704 +  6705 +  6706 +  6707 +  6708 +  6709 +  6710 +  6711 +  6712 +  6713 +  6714 +  6715 +  6716 +  6717 +  6718 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 6719 +  6720 +  6721 +  6722 +  6723 +  6724 +  6725 +  6726 +  6727 +  6728 +  6729 +  6730 +  6731 +  6732 +  6733 +  6734 +  6735 +  6736 +  6737 +  6738 +  6739 +  6740 +  6741 +  6742 +  6743 +  6744 +  6745 +  6746 +  6747 +  6748 +  6749 +  6750 +  6751 +  6752 +  6753 +  6754 +  6755 +  6756 +  6757 +  6758 +  6759 +  6760 +  6761 +  6762 +  6763 +  6764 +  6765 +  6766 +  6767 +  6768 +  6769 +  6770 +  6771 +  6772 +  6773 +  6774 +  6775 +  6776 +  6777 +  6778 +  6779 +  6780 +  6781 +  6782 +  6783 +  6784 +  6785 +  6786 +  6787 +  6788 +  6789 +  6790 +  6791 +  6792 +  6793 +  6794 +  6795 +  6796 +  6797 +  6798 +  6799 +  6800 +  6801 +  6802 +  6803 +  6804 +  6805 +  6806 +  6807 +  6808 +  6809 +  6810 +  6811 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 6812 +  6813 +  6814 +  6815 +  6816 +  6817 +  6818 +  6819 +  6820 +  6821 +  6822 +  6823 +  6824 +  6825 +  6826 +  6827 +  6828 +  6829 +  6830 +  6831 +  6832 +  6833 +  6834 +  6835 +  6836 +  6837 +  6838 +  6839 +  6840 +  6841 +  6842 +  6843 +  6844 +  6845 +  6846 +  6847 +  6848 +  6849 +  6850 +  6851 +  6852 +  6853 +  6854 +  6855 +  6856 +  6857 +  6858 +  6859 +  6860 +  6861 +  6862 +  6863 +  6864 +  6865 +  6866 +  6867 +  6868 +  6869 +  6870 +  6871 +  6872 +  6873 +  6874 +  6875 +  6876 +  6877 +  6878 +  6879 +  6880 +  6881 +  6882 +  6883 +  6884 +  6885 +  6886 +  6887 +  6888 +  6889 +  6890 +  6891 +  6892 +  6893 +  6894 +  6895 +  6896 +  6897 +  6898 +  6899 +  6900 +  6901 +  6902 +  6903 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 6904 +  6905 +  6906 +  6907 +  6908 +  6909 +  6910 +  6911 +  6912 +  6913 +  6914 +  6915 +  6916 +  6917 +  6918 +  6919 +  6920 +  6921 +  6922 +  6923 +  6924 +  6925 +  6926 +  6927 +  6928 +  6929 +  6930 +  6931 +  6932 +  6933 +  6934 +  6935 +  6936 +  6937 +  6938 +  6939 +  6940 +  6941 +  6942 +  6943 +  6944 +  6945 +  6946 +  6947 +  6948 +  6949 +  6950 +  6951 +  6952 +  6953 +  6954 +  6955 +  6956 +  6957 +  6958 +  6959 +  6960 +  6961 +  6962 +  6963 +  6964 +  6965 +  6966 +  6967 +  6968 +  6969 +  6970 +  6971 +  6972 +  6973 +  6974 +  6975 +  6976 +  6977 +  6978 +  6979 +  6980 +  6981 +  6982 +  6983 +  6984 +  6985 +  6986 +  6987 +  6988 +  6989 +  6990 +  6991 +  6992 +  6993 +  6994 +  6995 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 6996 +  6997 +  6998 +  6999 +  7000 +  7001 +  7002 +  7003 +  7004 +  7005 +  7006 +  7007 +  7008 +  7009 +  7010 +  7011 +  7012 +  7013 +  7014 +  7015 +  7016 +  7017 +  7018 +  7019 +  7020 +  7021 +  7022 +  7023 +  7024 +  7025 +  7026 +  7027 +  7028 +  7029 +  7030 +  7031 +  7032 +  7033 +  7034 +  7035 +  7036 +  7037 +  7038 +  7039 +  7040 +  7041 +  7042 +  7043 +  7044 +  7045 +  7046 +  7047 +  7048 +  7049 +  7050 +  7051 +  7052 +  7053 +  7054 +  7055 +  7056 +  7057 +  7058 +  7059 +  7060 +  7061 +  7062 +  7063 +  7064 +  7065 +  7066 +  7067 +  7068 +  7069 +  7070 +  7071 +  7072 +  7073 +  7074 +  7075 +  7076 +  7077 +  7078 +  7079 +  7080 +  7081 +  7082 +  7083 +  7084 +  7085 +  7086 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 7087 +  7088 +  7089 +  7090 +  7091 +  7092 +  7093 +  7094 +  7095 +  7096 +  7097 +  7098 +  7099 +  7100 +  7101 +  7102 +  7103 +  7104 +  7105 +  7106 +  7107 +  7108 +  7109 +  7110 +  7111 +  7112 +  7113 +  7114 +  7115 +  7116 +  7117 +  7118 +  7119 +  7120 +  7121 +  7122 +  7123 +  7124 +  7125 +  7126 +  7127 +  7128 +  7129 +  7130 +  7131 +  7132 +  7133 +  7134 +  7135 +  7136 +  7137 +  7138 +  7139 +  7140 +  7141 +  7142 +  7143 +  7144 +  7145 +  7146 +  7147 +  7148 +  7149 +  7150 +  7151 +  7152 +  7153 +  7154 +  7155 +  7156 +  7157 +  7158 +  7159 +  7160 +  7161 +  7162 +  7163 +  7164 +  7165 +  7166 +  7167 +  7168 +  7169 +  7170 +  7171 +  7172 +  7173 +  7174 +  7175 +  7176 +  7177 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 7178 +  7179 +  7180 +  7181 +  7182 +  7183 +  7184 +  7185 +  7186 +  7187 +  7188 +  7189 +  7190 +  7191 +  7192 +  7193 +  7194 +  7195 +  7196 +  7197 +  7198 +  7199 +  7200 +  7201 +  7202 +  7203 +  7204 +  7205 +  7206 +  7207 +  7208 +  7209 +  7210 +  7211 +  7212 +  7213 +  7214 +  7215 +  7216 +  7217 +  7218 +  7219 +  7220 +  7221 +  7222 +  7223 +  7224 +  7225 +  7226 +  7227 +  7228 +  7229 +  7230 +  7231 +  7232 +  7233 +  7234 +  7235 +  7236 +  7237 +  7238 +  7239 +  7240 +  7241 +  7242 +  7243 +  7244 +  7245 +  7246 +  7247 +  7248 +  7249 +  7250 +  7251 +  7252 +  7253 +  7254 +  7255 +  7256 +  7257 +  7258 +  7259 +  7260 +  7261 +  7262 +  7263 +  7264 +  7265 +  7266 +  7267 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2 7268 +  7269 +  7270 +  7271 +  7272 +  7273 +  7274 +  7275 +  7276 +  7277 +  7278 +  7279 +  7280 +  7281 +  7282 +  7283 +  7284 +  7285 +  7286 +  7287 +  7288 +  7289 +  7290 +  7291 +  7292 +  7293 +  7294 +  7295 +  7296 +  7297 +  7298 +  7299 +  7300 +  7301 +  7302 +  7303 +  7304 +  7305 +  7306 +  7307 +  7308 +  7309 +  7310 +  7311 +  7312 +  7313 +  7314 +  7315 +  7316 +  7317 +  7318 +  7319 +  7320 +  7321 +  7322 +  7323 +  7324 +  7325 +  7326 +  7327 +  7328 +  7329 +  7330 +  7331 +  7332 +  7333 +  7334 +  7335 +  7336 +  7337 +  7338 +  7339 +  7340 +  7341 +  7342 +  7343 +  7344 +  7345 +  7346 +  7347 +  7348 +  7349 +  7350 +  7351 +  7352 +  7353 +  7354 +  7355 +  7356 +  7357 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2 7358 +  7359 +  7360 +  7361 +  7362 +  7363 +  7364 +  7365 +  7366 +  7367 +  7368 +  7369 +  7370 +  7371 +  7372 +  7373 +  7374 +  7375 +  7376 +  7377 +  7378 +  7379 +  7380 +  7381 +  7382 +  7383 +  7384 +  7385 +  7386 +  7387 +  7388 +  7389 +  7390 +  7391 +  7392 +  7393 +  7394 +  7395 +  7396 +  7397 +  7398 +  7399 +  7400 +  7401 +  7402 +  7403 +  7404 +  7405 +  7406 +  7407 +  7408 +  7409 +  7410 +  7411 +  7412 +  7413 +  7414 +  7415 +  7416 +  7417 +  7418 +  7419 +  7420 +  7421 +  7422 +  7423 +  7424 +  7425 +  7426 +  7427 +  7428 +  7429 +  7430 +  7431 +  7432 +  7433 +  7434 +  7435 +  7436 +  7437 +  7438 +  7439 +  7440 +  7441 +  7442 +  7443 +  7444 +  7445 +  7446 +  7447 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2 7448 +  7449 +  7450 +  7451 +  7452 +  7453 +  7454 +  7455 +  7456 +  7457 +  7458 +  7459 +  7460 +  7461 +  7462 +  7463 +  7464 +  7465 +  7466 +  7467 +  7468 +  7469 +  7470 +  7471 +  7472 +  7473 +  7474 +  7475 +  7476 +  7477 +  7478 +  7479 +  7480 +  7481 +  7482 +  7483 +  7484 +  7485 +  7486 +  7487 +  7488 +  7489 +  7490 +  7491 +  7492 +  7493 +  7494 +  7495 +  7496 +  7497 +  7498 +  7499 +  7500 +  7501 +  7502 +  7503 +  7504 +  7505 +  7506 +  7507 +  7508 +  7509 +  7510 +  7511 +  7512 +  7513 +  7514 +  7515 +  7516 +  7517 +  7518 +  7519 +  7520 +  7521 +  7522 +  7523 +  7524 +  7525 +  7526 +  7527 +  7528 +  7529 +  7530 +  7531 +  7532 +  7533 +  7534 +  7535 +  7536 +  7537 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2 7538 +  7539 +  7540 +  7541 +  7542 +  7543 +  7544 +  7545 +  7546 +  7547 +  7548 +  7549 +  7550 +  7551 +  7552 +  7553 +  7554 +  7555 +  7556 +  7557 +  7558 +  7559 +  7560 +  7561 +  7562 +  7563 +  7564 +  7565 +  7566 +  7567 +  7568 +  7569 +  7570 +  7571 +  7572 +  7573 +  7574 +  7575 +  7576 +  7577 +  7578 +  7579 +  7580 +  7581 +  7582 +  7583 +  7584 +  7585 +  7586 +  7587 +  7588 +  7589 +  7590 +  7591 +  7592 +  7593 +  7594 +  7595 +  7596 +  7597 +  7598 +  7599 +  7600 +  7601 +  7602 +  7603 +  7604 +  7605 +  7606 +  7607 +  7608 +  7609 +  7610 +  7611 +  7612 +  7613 +  7614 +  7615 +  7616 +  7617 +  7618 +  7619 +  7620 +  7621 +  7622 +  7623 +  7624 +  7625 +  7626 +  7627 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2 7628 +  7629 +  7630 +  7631 +  7632 +  7633 +  7634 +  7635 +  7636 +  7637 +  7638 +  7639 +  7640 +  7641 +  7642 +  7643 +  7644 +  7645 +  7646 +  7647 +  7648 +  7649 +  7650 +  7651 +  7652 +  7653 +  7654 +  7655 +  7656 +  7657 +  7658 +  7659 +  7660 +  7661 +  7662 +  7663 +  7664 +  7665 +  7666 +  7667 +  7668 +  7669 +  7670 +  7671 +  7672 +  7673 +  7674 +  7675 +  7676 +  7677 +  7678 +  7679 +  7680 +  7681 +  7682 +  7683 +  7684 +  7685 +  7686 +  7687 +  7688 +  7689 +  7690 +  7691 +  7692 +  7693 +  7694 +  7695 +  7696 +  7697 +  7698 +  7699 +  7700 +  7701 +  7702 +  7703 +  7704 +  7705 +  7706 +  7707 +  7708 +  7709 +  7710 +  7711 +  7712 +  7713 +  7714 +  7715 +  7716 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2 7717 +  7718 +  7719 +  7720 +  7721 +  7722 +  7723 +  7724 +  7725 +  7726 +  7727 +  7728 +  7729 +  7730 +  7731 +  7732 +  7733 +  7734 +  7735 +  7736 +  7737 +  7738 +  7739 +  7740 +  7741 +  7742 +  7743 +  7744 +  7745 +  7746 +  7747 +  7748 +  7749 +  7750 +  7751 +  7752 +  7753 +  7754 +  7755 +  7756 +  7757 +  7758 +  7759 +  7760 +  7761 +  7762 +  7763 +  7764 +  7765 +  7766 +  7767 +  7768 +  7769 +  7770 +  7771 +  7772 +  7773 +  7774 +  7775 +  7776 +  7777 +  7778 +  7779 +  7780 +  7781 +  7782 +  7783 +  7784 +  7785 +  7786 +  7787 +  7788 +  7789 +  7790 +  7791 +  7792 +  7793 +  7794 +  7795 +  7796 +  7797 +  7798 +  7799 +  7800 +  7801 +  7802 +  7803 +  7804 +  7805 +  7806 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2 7807 +  7808 +  7809 +  7810 +  7811 +  7812 +  7813 +  7814 +  7815 +  7816 +  7817 +  7818 +  7819 +  7820 +  7821 +  7822 +  7823 +  7824 +  7825 +  7826 +  7827 +  7828 +  7829 +  7830 +  7831 +  7832 +  7833 +  7834 +  7835 +  7836 +  7837 +  7838 +  7839 +  7840 +  7841 +  7842 +  7843 +  7844 +  7845 +  7846 +  7847 +  7848 +  7849 +  7850 +  7851 +  7852 +  7853 +  7854 +  7855 +  7856 +  7857 +  7858 +  7859 +  7860 +  7861 +  7862 +  7863 +  7864 +  7865 +  7866 +  7867 +  7868 +  7869 +  7870 +  7871 +  7872 +  7873 +  7874 +  7875 +  7876 +  7877 +  7878 +  7879 +  7880 +  7881 +  7882 +  7883 +  7884 +  7885 +  7886 +  7887 +  7888 +  7889 +  7890 +  7891 +  7892 +  7893 +  7894 +  7895 +  7896 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2 7897 +  7898 +  7899 +  7900 +  7901 +  7902 +  7903 +  7904 +  7905 +  7906 +  7907 +  7908 +  7909 +  7910 +  7911 +  7912 +  7913 +  7914 +  7915 +  7916 +  7917 +  7918 +  7919 +  7920 +  7921 +  7922 +  7923 +  7924 +  7925 +  7926 +  7927 +  7928 +  7929 +  7930 +  7931 +  7932 +  7933 +  7934 +  7935 +  7936 +  7937 +  7938 +  7939 +  7940 +  7941 +  7942 +  7943 +  7944 +  7945 +  7946 +  7947 +  7948 +  7949 +  7950 +  7951 +  7952 +  7953 +  7954 +  7955 +  7956 +  7957 +  7958 +  7959 +  7960 +  7961 +  7962 +  7963 +  7964 +  7965 +  7966 +  7967 +  7968 +  7969 +  7970 +  7971 +  7972 +  7973 +  7974 +  7975 +  7976 +  7977 +  7978 +  7979 +  7980 +  7981 +  7982 +  7983 +  7984 +  7985 +  7986 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2 7987 +  7988 +  7989 +  7990 +  7991 +  7992 +  7993 +  7994 +  7995 +  7996 +  7997 +  7998 +  7999 +  8000 +  8001 +  8002 +  8003 +  8004 +  8005 +  8006 +  8007 +  8008 +  8009 +  8010 +  8011 +  8012 +  8013 +  8014 +  8015 +  8016 +  8017 +  8018 +  8019 +  8020 +  8021 +  8022 +  8023 +  8024 +  8025 +  8026 +  8027 +  8028 +  8029 +  8030 +  8031 +  8032 +  8033 +  8034 +  8035 +  8036 +  8037 +  8038 +  8039 +  8040 +  8041 +  8042 +  8043 +  8044 +  8045 +  8046 +  8047 +  8048 +  8049 +  8050 +  8051 +  8052 +  8053 +  8054 +  8055 +  8056 +  8057 +  8058 +  8059 +  8060 +  8061 +  8062 +  8063 +  8064 +  8065 +  8066 +  8067 +  8068 +  8069 +  8070 +  8071 +  8072 +  8073 +  8074 +  8075 +  8076 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2 8077 +  8078 +  8079 +  8080 +  8081 +  8082 +  8083 +  8084 +  8085 +  8086 +  8087 +  8088 +  8089 +  8090 +  8091 +  8092 +  8093 +  8094 +  8095 +  8096 +  8097 +  8098 +  8099 +  8100 +  8101 +  8102 +  8103 +  8104 +  8105 +  8106 +  8107 +  8108 +  8109 +  8110 +  8111 +  8112 +  8113 +  8114 +  8115 +  8116 +  8117 +  8118 +  8119 +  8120 +  8121 +  8122 +  8123 +  8124 +  8125 +  8126 +  8127 +  8128 +  8129 +  8130 +  8131 +  8132 +  8133 +  8134 +  8135 +  8136 +  8137 +  8138 +  8139 +  8140 +  8141 +  8142 +  8143 +  8144 +  8145 +  8146 +  8147 +  8148 +  8149 +  8150 +  8151 +  8152 +  8153 +  8154 +  8155 +  8156 +  8157 +  8158 +  8159 +  8160 +  8161 +  8162 +  8163 +  8164 +  8165 +  8166 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2 8167 +  8168 +  8169 +  8170 +  8171 +  8172 +  8173 +  8174 +  8175 +  8176 +  8177 +  8178 +  8179 +  8180 +  8181 +  8182 +  8183 +  8184 +  8185 +  8186 +  8187 +  8188 +  8189 +  8190 +  8191 +  8192 +  8193 +  8194 +  8195 +  8196 +  8197 +  8198 +  8199 +  8200 +  8201 +  8202 +  8203 +  8204 +  8205 +  8206 +  8207 +  8208 +  8209 +  8210 +  8211 +  8212 +  8213 +  8214 +  8215 +  8216 +  8217 +  8218 +  8219 +  8220 +  8221 +  8222 +  8223 +  8224 +  8225 +  8226 +  8227 +  8228 +  8229 +  8230 +  8231 +  8232 +  8233 +  8234 +  8235 +  8236 +  8237 +  8238 +  8239 +  8240 +  8241 +  8242 +  8243 +  8244 +  8245 +  8246 +  8247 +  8248 +  8249 +  8250 +  8251 +  8252 +  8253 +  8254 +  8255 +  8256 +  8257 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 8258 +  8259 +  8260 +  8261 +  8262 +  8263 +  8264 +  8265 +  8266 +  8267 +  8268 +  8269 +  8270 +  8271 +  8272 +  8273 +  8274 +  8275 +  8276 +  8277 +  8278 +  8279 +  8280 +  8281 +  8282 +  8283 +  8284 +  8285 +  8286 +  8287 +  8288 +  8289 +  8290 +  8291 +  8292 +  8293 +  8294 +  8295 +  8296 +  8297 +  8298 +  8299 +  8300 +  8301 +  8302 +  8303 +  8304 +  8305 +  8306 +  8307 +  8308 +  8309 +  8310 +  8311 +  8312 +  8313 +  8314 +  8315 +  8316 +  8317 +  8318 +  8319 +  8320 +  8321 +  8322 +  8323 +  8324 +  8325 +  8326 +  8327 +  8328 +  8329 +  8330 +  8331 +  8332 +  8333 +  8334 +  8335 +  8336 +  8337 +  8338 +  8339 +  8340 +  8341 +  8342 +  8343 +  8344 +  8345 +  8346 +  8347 +  8348 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 8349 +  8350 +  8351 +  8352 +  8353 +  8354 +  8355 +  8356 +  8357 +  8358 +  8359 +  8360 +  8361 +  8362 +  8363 +  8364 +  8365 +  8366 +  8367 +  8368 +  8369 +  8370 +  8371 +  8372 +  8373 +  8374 +  8375 +  8376 +  8377 +  8378 +  8379 +  8380 +  8381 +  8382 +  8383 +  8384 +  8385 +  8386 +  8387 +  8388 +  8389 +  8390 +  8391 +  8392 +  8393 +  8394 +  8395 +  8396 +  8397 +  8398 +  8399 +  8400 +  8401 +  8402 +  8403 +  8404 +  8405 +  8406 +  8407 +  8408 +  8409 +  8410 +  8411 +  8412 +  8413 +  8414 +  8415 +  8416 +  8417 +  8418 +  8419 +  8420 +  8421 +  8422 +  8423 +  8424 +  8425 +  8426 +  8427 +  8428 +  8429 +  8430 +  8431 +  8432 +  8433 +  8434 +  8435 +  8436 +  8437 +  8438 +  8439 +  8440 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 8441 +  8442 +  8443 +  8444 +  8445 +  8446 +  8447 +  8448 +  8449 +  8450 +  8451 +  8452 +  8453 +  8454 +  8455 +  8456 +  8457 +  8458 +  8459 +  8460 +  8461 +  8462 +  8463 +  8464 +  8465 +  8466 +  8467 +  8468 +  8469 +  8470 +  8471 +  8472 +  8473 +  8474 +  8475 +  8476 +  8477 +  8478 +  8479 +  8480 +  8481 +  8482 +  8483 +  8484 +  8485 +  8486 +  8487 +  8488 +  8489 +  8490 +  8491 +  8492 +  8493 +  8494 +  8495 +  8496 +  8497 +  8498 +  8499 +  8500 +  8501 +  8502 +  8503 +  8504 +  8505 +  8506 +  8507 +  8508 +  8509 +  8510 +  8511 +  8512 +  8513 +  8514 +  8515 +  8516 +  8517 +  8518 +  8519 +  8520 +  8521 +  8522 +  8523 +  8524 +  8525 +  8526 +  8527 +  8528 +  8529 +  8530 +  8531 +  8532 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 8533 +  8534 +  8535 +  8536 +  8537 +  8538 +  8539 +  8540 +  8541 +  8542 +  8543 +  8544 +  8545 +  8546 +  8547 +  8548 +  8549 +  8550 +  8551 +  8552 +  8553 +  8554 +  8555 +  8556 +  8557 +  8558 +  8559 +  8560 +  8561 +  8562 +  8563 +  8564 +  8565 +  8566 +  8567 +  8568 +  8569 +  8570 +  8571 +  8572 +  8573 +  8574 +  8575 +  8576 +  8577 +  8578 +  8579 +  8580 +  8581 +  8582 +  8583 +  8584 +  8585 +  8586 +  8587 +  8588 +  8589 +  8590 +  8591 +  8592 +  8593 +  8594 +  8595 +  8596 +  8597 +  8598 +  8599 +  8600 +  8601 +  8602 +  8603 +  8604 +  8605 +  8606 +  8607 +  8608 +  8609 +  8610 +  8611 +  8612 +  8613 +  8614 +  8615 +  8616 +  8617 +  8618 +  8619 +  8620 +  8621 +  8622 +  8623 +  8624 +  8625 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 8626 +  8627 +  8628 +  8629 +  8630 +  8631 +  8632 +  8633 +  8634 +  8635 +  8636 +  8637 +  8638 +  8639 +  8640 +  8641 +  8642 +  8643 +  8644 +  8645 +  8646 +  8647 +  8648 +  8649 +  8650 +  8651 +  8652 +  8653 +  8654 +  8655 +  8656 +  8657 +  8658 +  8659 +  8660 +  8661 +  8662 +  8663 +  8664 +  8665 +  8666 +  8667 +  8668 +  8669 +  8670 +  8671 +  8672 +  8673 +  8674 +  8675 +  8676 +  8677 +  8678 +  8679 +  8680 +  8681 +  8682 +  8683 +  8684 +  8685 +  8686 +  8687 +  8688 +  8689 +  8690 +  8691 +  8692 +  8693 +  8694 +  8695 +  8696 +  8697 +  8698 +  8699 +  8700 +  8701 +  8702 +  8703 +  8704 +  8705 +  8706 +  8707 +  8708 +  8709 +  8710 +  8711 +  8712 +  8713 +  8714 +  8715 +  8716 +  8717 +  8718 +  8719 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 8720 +  8721 +  8722 +  8723 +  8724 +  8725 +  8726 +  8727 +  8728 +  8729 +  8730 +  8731 +  8732 +  8733 +  8734 +  8735 +  8736 +  8737 +  8738 +  8739 +  8740 +  8741 +  8742 +  8743 +  8744 +  8745 +  8746 +  8747 +  8748 +  8749 +  8750 +  8751 +  8752 +  8753 +  8754 +  8755 +  8756 +  8757 +  8758 +  8759 +  8760 +  8761 +  8762 +  8763 +  8764 +  8765 +  8766 +  8767 +  8768 +  8769 +  8770 +  8771 +  8772 +  8773 +  8774 +  8775 +  8776 +  8777 +  8778 +  8779 +  8780 +  8781 +  8782 +  8783 +  8784 +  8785 +  8786 +  8787 +  8788 +  8789 +  8790 +  8791 +  8792 +  8793 +  8794 +  8795 +  8796 +  8797 +  8798 +  8799 +  8800 +  8801 +  8802 +  8803 +  8804 +  8805 +  8806 +  8807 +  8808 +  8809 +  8810 +  8811 +  8812 +  8813 +  8814 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 8815 +  8816 +  8817 +  8818 +  8819 +  8820 +  8821 +  8822 +  8823 +  8824 +  8825 +  8826 +  8827 +  8828 +  8829 +  8830 +  8831 +  8832 +  8833 +  8834 +  8835 +  8836 +  8837 +  8838 +  8839 +  8840 +  8841 +  8842 +  8843 +  8844 +  8845 +  8846 +  8847 +  8848 +  8849 +  8850 +  8851 +  8852 +  8853 +  8854 +  8855 +  8856 +  8857 +  8858 +  8859 +  8860 +  8861 +  8862 +  8863 +  8864 +  8865 +  8866 +  8867 +  8868 +  8869 +  8870 +  8871 +  8872 +  8873 +  8874 +  8875 +  8876 +  8877 +  8878 +  8879 +  8880 +  8881 +  8882 +  8883 +  8884 +  8885 +  8886 +  8887 +  8888 +  8889 +  8890 +  8891 +  8892 +  8893 +  8894 +  8895 +  8896 +  8897 +  8898 +  8899 +  8900 +  8901 +  8902 +  8903 +  8904 +  8905 +  8906 +  8907 +  8908 +  8909 +  8910 +  8911 + 2��2��2��2��2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 8912 +  8913 +  8914 +  8915 +  8916 +  8917 +  8918 +  8919 +  8920 +  8921 +  8922 +  8923 +  8924 +  8925 +  8926 +  8927 +  8928 +  8929 +  8930 +  8931 +  8932 +  8933 +  8934 +  8935 +  8936 +  8937 +  8938 +  8939 +  8940 +  8941 +  8942 +  8943 +  8944 +  8945 +  8946 +  8947 +  8948 +  8949 +  8950 +  8951 +  8952 +  8953 +  8954 +  8955 +  8956 +  8957 +  8958 +  8959 +  8960 +  8961 +  8962 +  8963 +  8964 +  8965 +  8966 +  8967 +  8968 +  8969 +  8970 +  8971 +  8972 +  8973 +  8974 +  8975 +  8976 +  8977 +  8978 +  8979 +  8980 +  8981 +  8982 +  8983 +  8984 +  8985 +  8986 +  8987 +  8988 +  8989 +  8990 +  8991 +  8992 +  8993 +  8994 +  8995 +  8996 +  8997 +  8998 +  8999 +  9000 +  9001 +  9002 +  9003 +  9004 +  9005 +  9006 +  9007 +  9008 +  9009 +  9010 + 2��2��2��2��2��2��2��2��2��2��2���d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 9011 +  9012 +  9013 +  9014 +  9015 +  9016 +  9017 +  9018 +  9019 +  9020 +  9021 +  9022 +  9023 +  9024 +  9025 +  9026 +  9027 +  9028 +  9029 +  9030 +  9031 +  9032 +  9033 +  9034 +  9035 +  9036 +  9037 +  9038 +  9039 +  9040 +  9041 +  9042 +  9043 +  9044 +  9045 +  9046 +  9047 +  9048 +  9049 +  9050 +  9051 +  9052 +  9053 +  9054 +  9055 +  9056 +  9057 +  9058 +  9059 +  9060 +  9061 +  9062 +  9063 +  9064 +  9065 +  9066 +  9067 +  9068 +  9069 +  9070 +  9071 +  9072 +  9073 +  9074 +  9075 +  9076 +  9077 +  9078 +  9079 +  9080 +  9081 +  9082 +  9083 +  9084 +  9085 +  9086 +  9087 +  9088 +  9089 +  9090 +  9091 +  9092 +  9093 +  9094 +  9095 +  9096 +  9097 +  9098 +  9099 +  9100 +  9101 +  9102 +  9103 +  9104 +  9105 +  9106 +  9107 +  9108 +  9109 +  9110 +  9111 +  9112 +  9113 +  9114 + 2�� 9115 +  9116 +  9117 +  9118 +  9119 +  9120 + �d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 9121 +  9122 +  9123 +  9124 +  9125 +  9126 +  9127 +  9128 +  9129 +  9130 +  9131 +  9132 +  9133 +  9134 +  9135 +  9136 +  9137 +  9138 +  9139 +  9140 +  9141 +  9142 +  9143 +  9144 +  9145 +  9146 +  9147 +  9148 +  9149 +  9150 +  9151 +  9152 +  9153 +  9154 +  9155 +  9156 +  9157 +  9158 +  9159 +  9160 +  9161 +  9162 +  9163 +  9164 +  9165 +  9166 +  9167 +  9168 +  9169 +  9170 +  9171 +  9172 +  9173 +  9174 +  9175 +  9176 +  9177 +  9178 +  9179 +  9180 +  9181 +  9182 +  9183 +  9184 +  9185 +  9186 +  9187 +  9188 +  9189 +  9190 +  9191 +  9192 +  9193 +  9194 +  9195 +  9196 +  9197 +  9198 +  9199 +  9200 +  9201 +  9202 +  9203 +  9204 +  9205 +  9206 +  9207 +  9208 +  9209 +  9210 +  9211 +  9212 +  9213 +  9214 +  9215 +  9216 +  9217 +  9218 +  9219 +  9220 +  9221 +  9222 +  9223 +  9224 +  9225 +  9226 +  9227 +  9228 +  9229 +  9230 +  9231 +  9232 + �d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 9233 +  9234 +  9235 +  9236 +  9237 +  9238 +  9239 +  9240 +  9241 +  9242 +  9243 +  9244 +  9245 +  9246 +  9247 +  9248 +  9249 +  9250 +  9251 +  9252 +  9253 +  9254 +  9255 +  9256 +  9257 +  9258 +  9259 +  9260 +  9261 +  9262 +  9263 +  9264 +  9265 +  9266 +  9267 +  9268 +  9269 +  9270 +  9271 +  9272 +  9273 +  9274 +  9275 +  9276 +  9277 +  9278 +  9279 +  9280 +  9281 +  9282 +  9283 +  9284 +  9285 +  9286 +  9287 +  9288 +  9289 +  9290 +  9291 +  9292 +  9293 +  9294 +  9295 +  9296 +  9297 +  9298 +  9299 +  9300 +  9301 +  9302 +  9303 +  9304 +  9305 +  9306 +  9307 +  9308 +  9309 +  9310 +  9311 +  9312 +  9313 +  9314 +  9315 +  9316 +  9317 +  9318 +  9319 +  9320 +  9321 +  9322 +  9323 +  9324 +  9325 +  9326 +  9327 +  9328 +  9329 +  9330 +  9331 +  9332 +  9333 +  9334 +  9335 +  9336 +  9337 +  9338 +  9339 +  9340 +  9341 +  9342 +  9343 +  9344 +  9345 +  9346 + �d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 9347 +  9348 +  9349 +  9350 +  9351 +  9352 +  9353 +  9354 +  9355 +  9356 +  9357 +  9358 +  9359 +  9360 +  9361 +  9362 +  9363 +  9364 +  9365 +  9366 +  9367 +  9368 +  9369 +  9370 +  9371 +  9372 +  9373 +  9374 +  9375 +  9376 +  9377 +  9378 +  9379 +  9380 +  9381 +  9382 +  9383 +  9384 +  9385 +  9386 +  9387 +  9388 +  9389 +  9390 +  9391 +  9392 +  9393 +  9394 +  9395 +  9396 +  9397 +  9398 +  9399 +  9400 +  9401 +  9402 +  9403 +  9404 +  9405 +  9406 +  9407 +  9408 +  9409 +  9410 +  9411 +  9412 +  9413 +  9414 +  9415 +  9416 +  9417 +  9418 +  9419 +  9420 +  9421 +  9422 +  9423 +  9424 +  9425 +  9426 +  9427 +  9428 +  9429 +  9430 +  9431 +  9432 +  9433 +  9434 +  9435 +  9436 +  9437 +  9438 +  9439 +  9440 +  9441 +  9442 +  9443 +  9444 +  9445 +  9446 +  9447 +  9448 +  9449 +  9450 +  9451 +  9452 +  9453 +  9454 +  9455 +  9456 +  9457 +  9458 +  9459 +  9460 +  9461 +  9462 + �d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 9463 +  9464 +  9465 +  9466 +  9467 +  9468 +  9469 +  9470 +  9471 +  9472 +  9473 +  9474 +  9475 +  9476 +  9477 +  9478 +  9479 +  9480 +  9481 +  9482 +  9483 +  9484 +  9485 +  9486 +  9487 +  9488 +  9489 +  9490 +  9491 +  9492 +  9493 +  9494 +  9495 +  9496 +  9497 +  9498 +  9499 +  9500 +  9501 +  9502 +  9503 +  9504 +  9505 +  9506 +  9507 +  9508 +  9509 +  9510 +  9511 +  9512 +  9513 +  9514 +  9515 +  9516 +  9517 +  9518 +  9519 +  9520 +  9521 +  9522 +  9523 +  9524 +  9525 +  9526 +  9527 +  9528 +  9529 +  9530 +  9531 +  9532 +  9533 +  9534 +  9535 +  9536 +  9537 +  9538 +  9539 +  9540 +  9541 +  9542 +  9543 +  9544 +  9545 +  9546 +  9547 +  9548 +  9549 +  9550 +  9551 +  9552 +  9553 +  9554 +  9555 +  9556 +  9557 +  9558 +  9559 +  9560 +  9561 +  9562 +  9563 +  9564 +  9565 +  9566 +  9567 +  9568 +  9569 +  9570 +  9571 +  9572 +  9573 +  9574 +  9575 +  9576 +  9577 +  9578 +  9579 +  9580 + �d2�d2�d2�d2�d2�d2�d2�d2�d2�d2 9581 +  9582 +  9583 +  9584 +  9585 +  9586 +  9587 +  9588 +  9589 +  9590 +  9591 +  9592 +  9593 +  9594 +  9595 +  9596 +  9597 +  9598 +  9599 +  9600 +  9601 +  9602 +  9603 +  9604 +  9605 +  9606 +  9607 +  9608 +  9609 +  9610 +  9611 +  9612 +  9613 +  9614 +  9615 +  9616 +  9617 +  9618 +  9619 +  9620 +  9621 +  9622 +  9623 +  9624 +  9625 +  9626 +  9627 +  9628 +  9629 +  9630 +  9631 +  9632 +  9633 +  9634 +  9635 +  9636 +  9637 +  9638 +  9639 +  9640 +  9641 +  9642 +  9643 +  9644 + ��d 9645 +  9646 +  9647 +  9648 +  9649 +  9650 +  9651 +  9652 +  9653 +  9654 +  9655 +  9656 +  9657 +  9658 +  9659 +  9660 +  9661 +  9662 +  9663 +  9664 +  9665 +  9666 +  9667 +  9668 +  9669 +  9670 +  9671 +  9672 +  9673 +  9674 +  9675 +  9676 +  9677 +  9678 +  9679 +  9680 +  9681 +  9682 +  9683 +  9684 +  9685 +  9686 +  9687 +  9688 +  9689 +  9690 +  9691 +  9692 +  9693 +  9694 +  9695 +  9696 +  9697 +  9698 +  9699 +  9700 +  9701 +  9702 +  9703 + �d2 9704 +  9705 +  9706 +  9707 +  9708 +  9709 +  9710 +  9711 +  9712 +  9713 +  9714 +  9715 +  9716 +  9717 +  9718 +  9719 +  9720 +  9721 +  9722 +  9723 +  9724 +  9725 +  9726 +  9727 +  9728 +  9729 +  9730 +  9731 +  9732 +  9733 +  9734 +  9735 +  9736 +  9737 +  9738 +  9739 +  9740 +  9741 +  9742 +  9743 +  9744 +  9745 +  9746 +  9747 +  9748 +  9749 +  9750 +  9751 +  9752 +  9753 +  9754 +  9755 +  9756 +  9757 +  9758 +  9759 +  9760 +  9761 +  9762 +  9763 +  9764 +  9765 +  9766 + ��d��d��d��d��d��d��d��d��d 9767 +  9768 +  9769 +  9770 +  9771 +  9772 +  9773 +  9774 +  9775 +  9776 +  9777 +  9778 +  9779 +  9780 +  9781 +  9782 +  9783 +  9784 +  9785 +  9786 +  9787 +  9788 +  9789 +  9790 +  9791 +  9792 +  9793 +  9794 +  9795 +  9796 +  9797 +  9798 +  9799 +  9800 +  9801 +  9802 +  9803 +  9804 +  9805 +  9806 +  9807 +  9808 +  9809 +  9810 +  9811 +  9812 +  9813 +  9814 +  9815 +  9816 +  9817 +  9818 +  9819 +  9820 +  9821 +  9822 +  9823 +  9824 +  9825 +  9826 +  9827 +  9828 +  9829 +  9830 +  9831 +  9832 +  9833 +  9834 +  9835 +  9836 +  9837 +  9838 +  9839 +  9840 +  9841 +  9842 +  9843 +  9844 +  9845 +  9846 +  9847 +  9848 +  9849 +  9850 +  9851 +  9852 +  9853 +  9854 +  9855 +  9856 +  9857 +  9858 +  9859 +  9860 +  9861 +  9862 +  9863 +  9864 +  9865 +  9866 +  9867 +  9868 +  9869 +  9870 +  9871 +  9872 +  9873 +  9874 +  9875 +  9876 +  9877 +  9878 +  9879 +  9880 +  9881 +  9882 +  9883 + ��d��d��d��d��d��d��d��d��d��d��d��d��d 9884 +  9885 +  9886 +  9887 +  9888 +  9889 +  9890 +  9891 +  9892 +  9893 +  9894 +  9895 +  9896 +  9897 +  9898 +  9899 +  9900 +  9901 +  9902 +  9903 +  9904 +  9905 +  9906 +  9907 +  9908 +  9909 +  9910 +  9911 +  9912 +  9913 +  9914 +  9915 +  9916 +  9917 +  9918 +  9919 +  9920 +  9921 +  9922 +  9923 +  9924 +  9925 +  9926 +  9927 +  9928 +  9929 +  9930 +  9931 +  9932 +  9933 +  9934 +  9935 +  9936 +  9937 +  9938 +  9939 +  9940 +  9941 +  9942 +  9943 +  9944 +  9945 +  9946 +  9947 +  9948 +  9949 +  9950 +  9951 +  9952 +  9953 +  9954 +  9955 +  9956 +  9957 +  9958 +  9959 +  9960 +  9961 +  9962 +  9963 +  9964 +  9965 +  9966 +  9967 +  9968 +  9969 +  9970 +  9971 +  9972 +  9973 +  9974 +  9975 +  9976 +  9977 +  9978 +  9979 +  9980 +  9981 +  9982 +  9983 +  9984 +  9985 +  9986 +  9987 +  9988 +  9989 +  9990 +  9991 +  9992 +  9993 +  9994 +  9995 +  9996 +  9997 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 9998 +  9999 +  10000 +  10001 +  10002 +  10003 +  10004 +  10005 +  10006 +  10007 +  10008 +  10009 +  10010 +  10011 +  10012 +  10013 +  10014 +  10015 +  10016 +  10017 +  10018 +  10019 +  10020 +  10021 +  10022 +  10023 +  10024 +  10025 +  10026 +  10027 +  10028 +  10029 +  10030 +  10031 +  10032 +  10033 +  10034 +  10035 +  10036 +  10037 +  10038 +  10039 +  10040 +  10041 +  10042 +  10043 +  10044 +  10045 +  10046 +  10047 +  10048 +  10049 +  10050 +  10051 +  10052 +  10053 +  10054 +  10055 +  10056 +  10057 +  10058 +  10059 +  10060 +  10061 +  10062 +  10063 +  10064 +  10065 +  10066 +  10067 +  10068 +  10069 +  10070 +  10071 +  10072 +  10073 +  10074 +  10075 +  10076 +  10077 +  10078 +  10079 +  10080 +  10081 +  10082 +  10083 +  10084 +  10085 +  10086 +  10087 +  10088 +  10089 +  10090 +  10091 +  10092 +  10093 +  10094 +  10095 +  10096 +  10097 +  10098 +  10099 +  10100 +  10101 +  10102 +  10103 +  10104 +  10105 +  10106 +  10107 +  10108 +  10109 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 10110 +  10111 +  10112 +  10113 +  10114 +  10115 +  10116 +  10117 +  10118 +  10119 +  10120 +  10121 +  10122 +  10123 +  10124 +  10125 +  10126 +  10127 +  10128 +  10129 +  10130 +  10131 +  10132 +  10133 +  10134 +  10135 +  10136 +  10137 +  10138 +  10139 +  10140 +  10141 +  10142 +  10143 +  10144 +  10145 +  10146 +  10147 +  10148 +  10149 +  10150 +  10151 +  10152 +  10153 +  10154 +  10155 +  10156 +  10157 +  10158 +  10159 +  10160 +  10161 +  10162 +  10163 +  10164 +  10165 +  10166 +  10167 +  10168 +  10169 +  10170 +  10171 +  10172 +  10173 +  10174 +  10175 +  10176 +  10177 +  10178 +  10179 +  10180 +  10181 +  10182 +  10183 +  10184 +  10185 +  10186 +  10187 +  10188 +  10189 +  10190 +  10191 +  10192 +  10193 +  10194 +  10195 +  10196 +  10197 +  10198 +  10199 +  10200 +  10201 +  10202 +  10203 +  10204 +  10205 +  10206 +  10207 +  10208 +  10209 +  10210 +  10211 +  10212 +  10213 +  10214 +  10215 +  10216 +  10217 +  10218 +  10219 +  10220 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 10221 +  10222 +  10223 +  10224 +  10225 +  10226 +  10227 +  10228 +  10229 +  10230 +  10231 +  10232 +  10233 +  10234 +  10235 +  10236 +  10237 +  10238 +  10239 +  10240 +  10241 +  10242 +  10243 +  10244 +  10245 +  10246 +  10247 +  10248 +  10249 +  10250 +  10251 +  10252 +  10253 +  10254 +  10255 +  10256 +  10257 +  10258 +  10259 +  10260 +  10261 +  10262 +  10263 +  10264 +  10265 +  10266 +  10267 +  10268 +  10269 +  10270 +  10271 +  10272 +  10273 +  10274 +  10275 +  10276 +  10277 +  10278 +  10279 +  10280 +  10281 +  10282 +  10283 +  10284 +  10285 +  10286 +  10287 +  10288 +  10289 +  10290 +  10291 +  10292 +  10293 +  10294 +  10295 +  10296 +  10297 +  10298 +  10299 +  10300 +  10301 +  10302 +  10303 +  10304 +  10305 +  10306 +  10307 +  10308 +  10309 +  10310 +  10311 +  10312 +  10313 +  10314 +  10315 +  10316 +  10317 +  10318 +  10319 +  10320 +  10321 +  10322 +  10323 +  10324 +  10325 +  10326 +  10327 +  10328 +  10329 +  10330 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 10331 +  10332 +  10333 +  10334 +  10335 +  10336 +  10337 +  10338 +  10339 +  10340 +  10341 +  10342 +  10343 +  10344 +  10345 +  10346 +  10347 +  10348 +  10349 +  10350 +  10351 +  10352 +  10353 +  10354 +  10355 +  10356 +  10357 +  10358 +  10359 +  10360 +  10361 +  10362 +  10363 +  10364 +  10365 +  10366 +  10367 +  10368 +  10369 +  10370 +  10371 +  10372 +  10373 +  10374 +  10375 +  10376 +  10377 +  10378 +  10379 +  10380 +  10381 +  10382 +  10383 +  10384 +  10385 +  10386 +  10387 +  10388 +  10389 +  10390 +  10391 +  10392 +  10393 +  10394 +  10395 +  10396 +  10397 +  10398 +  10399 +  10400 +  10401 +  10402 +  10403 +  10404 +  10405 +  10406 +  10407 +  10408 +  10409 +  10410 +  10411 +  10412 +  10413 +  10414 +  10415 +  10416 +  10417 +  10418 +  10419 +  10420 +  10421 +  10422 +  10423 +  10424 +  10425 +  10426 +  10427 +  10428 +  10429 +  10430 +  10431 +  10432 +  10433 +  10434 +  10435 +  10436 +  10437 +  10438 +  10439 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 10440 +  10441 +  10442 +  10443 +  10444 +  10445 +  10446 +  10447 +  10448 +  10449 +  10450 +  10451 +  10452 +  10453 +  10454 +  10455 +  10456 +  10457 +  10458 +  10459 +  10460 +  10461 +  10462 +  10463 +  10464 +  10465 +  10466 +  10467 +  10468 +  10469 +  10470 +  10471 +  10472 +  10473 +  10474 +  10475 +  10476 +  10477 +  10478 +  10479 +  10480 +  10481 +  10482 +  10483 +  10484 +  10485 +  10486 +  10487 +  10488 +  10489 +  10490 +  10491 +  10492 +  10493 +  10494 +  10495 +  10496 +  10497 +  10498 +  10499 +  10500 +  10501 +  10502 +  10503 +  10504 +  10505 +  10506 +  10507 +  10508 +  10509 +  10510 +  10511 +  10512 +  10513 +  10514 +  10515 +  10516 +  10517 +  10518 +  10519 +  10520 +  10521 +  10522 +  10523 +  10524 +  10525 +  10526 +  10527 +  10528 +  10529 +  10530 +  10531 +  10532 +  10533 +  10534 +  10535 +  10536 +  10537 +  10538 +  10539 +  10540 +  10541 +  10542 +  10543 +  10544 +  10545 +  10546 +  10547 +  10548 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 10549 +  10550 +  10551 +  10552 +  10553 +  10554 +  10555 +  10556 +  10557 +  10558 +  10559 +  10560 +  10561 +  10562 +  10563 +  10564 +  10565 +  10566 +  10567 +  10568 +  10569 +  10570 +  10571 +  10572 +  10573 +  10574 +  10575 +  10576 +  10577 +  10578 +  10579 +  10580 +  10581 +  10582 +  10583 +  10584 +  10585 +  10586 +  10587 +  10588 +  10589 +  10590 +  10591 +  10592 +  10593 +  10594 +  10595 +  10596 +  10597 +  10598 +  10599 +  10600 +  10601 +  10602 +  10603 +  10604 +  10605 +  10606 +  10607 +  10608 +  10609 +  10610 +  10611 +  10612 +  10613 +  10614 +  10615 +  10616 +  10617 +  10618 +  10619 +  10620 +  10621 +  10622 +  10623 +  10624 +  10625 +  10626 +  10627 +  10628 +  10629 +  10630 +  10631 +  10632 +  10633 +  10634 +  10635 +  10636 +  10637 +  10638 +  10639 +  10640 +  10641 +  10642 +  10643 +  10644 +  10645 +  10646 +  10647 +  10648 +  10649 +  10650 +  10651 +  10652 +  10653 +  10654 +  10655 +  10656 +  10657 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 10658 +  10659 +  10660 +  10661 +  10662 +  10663 +  10664 +  10665 +  10666 +  10667 +  10668 +  10669 +  10670 +  10671 +  10672 +  10673 +  10674 +  10675 +  10676 +  10677 +  10678 +  10679 +  10680 +  10681 +  10682 +  10683 +  10684 +  10685 +  10686 +  10687 +  10688 +  10689 +  10690 +  10691 +  10692 +  10693 +  10694 +  10695 +  10696 +  10697 +  10698 +  10699 +  10700 +  10701 +  10702 +  10703 +  10704 +  10705 +  10706 +  10707 +  10708 +  10709 +  10710 +  10711 +  10712 +  10713 +  10714 +  10715 +  10716 +  10717 +  10718 +  10719 +  10720 +  10721 +  10722 +  10723 +  10724 +  10725 +  10726 +  10727 +  10728 +  10729 +  10730 +  10731 +  10732 +  10733 +  10734 +  10735 +  10736 +  10737 +  10738 +  10739 +  10740 +  10741 +  10742 +  10743 +  10744 +  10745 +  10746 +  10747 +  10748 +  10749 +  10750 +  10751 +  10752 +  10753 +  10754 +  10755 +  10756 +  10757 +  10758 +  10759 +  10760 +  10761 +  10762 +  10763 +  10764 +  10765 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 10766 +  10767 +  10768 +  10769 +  10770 +  10771 +  10772 +  10773 +  10774 +  10775 +  10776 +  10777 +  10778 +  10779 +  10780 +  10781 +  10782 +  10783 +  10784 +  10785 +  10786 +  10787 +  10788 +  10789 +  10790 +  10791 +  10792 +  10793 +  10794 +  10795 +  10796 +  10797 +  10798 +  10799 +  10800 +  10801 +  10802 +  10803 +  10804 +  10805 +  10806 +  10807 +  10808 +  10809 +  10810 +  10811 +  10812 +  10813 +  10814 +  10815 +  10816 +  10817 +  10818 +  10819 +  10820 +  10821 +  10822 +  10823 +  10824 +  10825 +  10826 +  10827 +  10828 +  10829 +  10830 +  10831 +  10832 +  10833 +  10834 +  10835 +  10836 +  10837 +  10838 +  10839 +  10840 +  10841 +  10842 +  10843 +  10844 +  10845 +  10846 +  10847 +  10848 +  10849 +  10850 +  10851 +  10852 +  10853 +  10854 +  10855 +  10856 +  10857 +  10858 +  10859 +  10860 +  10861 +  10862 +  10863 +  10864 +  10865 +  10866 +  10867 +  10868 +  10869 +  10870 +  10871 +  10872 +  10873 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 10874 +  10875 +  10876 +  10877 +  10878 +  10879 +  10880 +  10881 +  10882 +  10883 +  10884 +  10885 +  10886 +  10887 +  10888 +  10889 +  10890 +  10891 +  10892 +  10893 +  10894 +  10895 +  10896 +  10897 +  10898 +  10899 +  10900 +  10901 +  10902 +  10903 +  10904 +  10905 +  10906 +  10907 +  10908 +  10909 +  10910 +  10911 +  10912 +  10913 +  10914 +  10915 +  10916 +  10917 +  10918 +  10919 +  10920 +  10921 +  10922 +  10923 +  10924 +  10925 +  10926 +  10927 +  10928 +  10929 +  10930 +  10931 +  10932 +  10933 +  10934 +  10935 +  10936 +  10937 +  10938 +  10939 +  10940 +  10941 +  10942 +  10943 +  10944 +  10945 +  10946 +  10947 +  10948 +  10949 +  10950 +  10951 +  10952 +  10953 +  10954 +  10955 +  10956 +  10957 +  10958 +  10959 +  10960 +  10961 +  10962 +  10963 +  10964 +  10965 +  10966 +  10967 +  10968 +  10969 +  10970 +  10971 +  10972 +  10973 +  10974 +  10975 +  10976 +  10977 +  10978 +  10979 +  10980 +  10981 +  10982 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 10983 +  10984 +  10985 +  10986 +  10987 +  10988 +  10989 +  10990 +  10991 +  10992 +  10993 +  10994 +  10995 +  10996 +  10997 +  10998 +  10999 +  11000 +  11001 +  11002 +  11003 +  11004 +  11005 +  11006 +  11007 +  11008 +  11009 +  11010 +  11011 +  11012 +  11013 +  11014 +  11015 +  11016 +  11017 +  11018 +  11019 +  11020 +  11021 +  11022 +  11023 +  11024 +  11025 +  11026 +  11027 +  11028 +  11029 +  11030 +  11031 +  11032 +  11033 +  11034 +  11035 +  11036 +  11037 +  11038 +  11039 +  11040 +  11041 +  11042 +  11043 +  11044 +  11045 +  11046 +  11047 +  11048 +  11049 +  11050 +  11051 +  11052 +  11053 +  11054 +  11055 +  11056 +  11057 +  11058 +  11059 +  11060 +  11061 +  11062 +  11063 +  11064 +  11065 +  11066 +  11067 +  11068 +  11069 +  11070 +  11071 +  11072 +  11073 +  11074 +  11075 +  11076 +  11077 +  11078 +  11079 +  11080 +  11081 +  11082 +  11083 +  11084 +  11085 +  11086 +  11087 +  11088 +  11089 +  11090 +  11091 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 11092 +  11093 +  11094 +  11095 +  11096 +  11097 +  11098 +  11099 +  11100 +  11101 +  11102 +  11103 +  11104 +  11105 +  11106 +  11107 +  11108 +  11109 +  11110 +  11111 +  11112 +  11113 +  11114 +  11115 +  11116 +  11117 +  11118 +  11119 +  11120 +  11121 +  11122 +  11123 +  11124 +  11125 +  11126 +  11127 +  11128 +  11129 +  11130 +  11131 +  11132 +  11133 +  11134 +  11135 +  11136 +  11137 +  11138 +  11139 +  11140 +  11141 +  11142 +  11143 +  11144 +  11145 +  11146 +  11147 +  11148 +  11149 +  11150 +  11151 +  11152 +  11153 +  11154 +  11155 +  11156 +  11157 +  11158 +  11159 +  11160 +  11161 +  11162 +  11163 +  11164 +  11165 +  11166 +  11167 +  11168 +  11169 +  11170 +  11171 +  11172 +  11173 +  11174 +  11175 +  11176 +  11177 +  11178 +  11179 +  11180 +  11181 +  11182 +  11183 +  11184 +  11185 +  11186 +  11187 +  11188 +  11189 +  11190 +  11191 +  11192 +  11193 +  11194 +  11195 +  11196 +  11197 +  11198 +  11199 +  11200 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 11201 +  11202 +  11203 +  11204 +  11205 +  11206 +  11207 +  11208 +  11209 +  11210 +  11211 +  11212 +  11213 +  11214 +  11215 +  11216 +  11217 +  11218 +  11219 +  11220 +  11221 +  11222 +  11223 +  11224 +  11225 +  11226 +  11227 +  11228 +  11229 +  11230 +  11231 +  11232 +  11233 +  11234 +  11235 +  11236 +  11237 +  11238 +  11239 +  11240 +  11241 +  11242 +  11243 +  11244 +  11245 +  11246 +  11247 +  11248 +  11249 +  11250 +  11251 +  11252 +  11253 +  11254 +  11255 +  11256 +  11257 +  11258 +  11259 +  11260 +  11261 +  11262 +  11263 +  11264 +  11265 +  11266 +  11267 +  11268 +  11269 +  11270 +  11271 +  11272 +  11273 +  11274 +  11275 +  11276 +  11277 +  11278 +  11279 +  11280 +  11281 +  11282 +  11283 +  11284 +  11285 +  11286 +  11287 +  11288 +  11289 +  11290 +  11291 +  11292 +  11293 +  11294 +  11295 +  11296 +  11297 +  11298 +  11299 +  11300 +  11301 +  11302 +  11303 +  11304 +  11305 +  11306 +  11307 +  11308 +  11309 +  11310 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 11311 +  11312 +  11313 +  11314 +  11315 +  11316 +  11317 +  11318 +  11319 +  11320 +  11321 +  11322 +  11323 +  11324 +  11325 +  11326 +  11327 +  11328 +  11329 +  11330 +  11331 +  11332 +  11333 +  11334 +  11335 +  11336 +  11337 +  11338 +  11339 +  11340 +  11341 +  11342 +  11343 +  11344 +  11345 +  11346 +  11347 +  11348 +  11349 +  11350 +  11351 +  11352 +  11353 +  11354 +  11355 +  11356 +  11357 +  11358 +  11359 +  11360 +  11361 +  11362 +  11363 +  11364 +  11365 +  11366 +  11367 +  11368 +  11369 +  11370 +  11371 +  11372 +  11373 +  11374 +  11375 +  11376 +  11377 +  11378 +  11379 +  11380 +  11381 +  11382 +  11383 +  11384 +  11385 +  11386 +  11387 +  11388 +  11389 +  11390 +  11391 +  11392 +  11393 +  11394 +  11395 +  11396 +  11397 +  11398 +  11399 +  11400 +  11401 +  11402 +  11403 +  11404 +  11405 +  11406 +  11407 +  11408 +  11409 +  11410 +  11411 +  11412 +  11413 +  11414 +  11415 +  11416 +  11417 +  11418 +  11419 +  11420 +  11421 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 11422 +  11423 +  11424 +  11425 +  11426 +  11427 +  11428 +  11429 +  11430 +  11431 +  11432 +  11433 +  11434 +  11435 +  11436 +  11437 +  11438 +  11439 +  11440 +  11441 +  11442 +  11443 +  11444 +  11445 +  11446 +  11447 +  11448 +  11449 +  11450 +  11451 +  11452 +  11453 +  11454 +  11455 +  11456 +  11457 +  11458 +  11459 +  11460 +  11461 +  11462 +  11463 +  11464 +  11465 +  11466 +  11467 +  11468 +  11469 +  11470 +  11471 +  11472 +  11473 +  11474 +  11475 +  11476 +  11477 +  11478 +  11479 +  11480 +  11481 +  11482 +  11483 +  11484 +  11485 +  11486 +  11487 +  11488 +  11489 +  11490 +  11491 +  11492 +  11493 +  11494 +  11495 +  11496 +  11497 +  11498 +  11499 +  11500 +  11501 +  11502 +  11503 +  11504 +  11505 +  11506 +  11507 +  11508 +  11509 +  11510 +  11511 +  11512 +  11513 +  11514 +  11515 +  11516 +  11517 +  11518 +  11519 +  11520 +  11521 +  11522 +  11523 +  11524 +  11525 +  11526 +  11527 +  11528 +  11529 +  11530 +  11531 +  11532 +  11533 + ��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d 11534 +  11535 +  11536 +  11537 +  11538 +  11539 +  11540 +  11541 +  11542 +  11543 +  11544 +  11545 +  11546 +  11547 +  11548 +  11549 +  11550 +  11551 +  11552 +  11553 +  11554 +  11555 +  11556 +  11557 +  11558 +  11559 +  11560 +  11561 +  11562 +  11563 +  11564 +  11565 +  11566 +  11567 +  11568 +  11569 +  11570 +  11571 +  11572 +  11573 +  11574 +  11575 +  11576 +  11577 +  11578 +  11579 +  11580 +  11581 +  11582 +  11583 +  11584 +  11585 +  11586 +  11587 +  11588 +  11589 +  11590 +  11591 +  11592 +  11593 +  11594 +  11595 +  11596 +  11597 +  11598 +  11599 +  11600 +  11601 +  11602 +  11603 +  11604 +  11605 +  11606 +  11607 +  11608 +  11609 +  11610 +  11611 +  11612 +  11613 +  11614 +  11615 +  11616 +  11617 +  11618 +  11619 +  11620 +  11621 +  11622 +  11623 +  11624 +  11625 +  11626 +  11627 +  11628 +  11629 +  11630 +  11631 +  11632 +  11633 +  11634 +  11635 +  11636 +  11637 +  11638 +  11639 +  11640 +  11641 +  11642 +  11643 +  11644 +  11645 +  11646 +  11647 + ��d��d��d��d��d��d��d��d��d��d��d��d��d 11648 +  11649 +  11650 +  11651 +  11652 +  11653 +  11654 +  11655 +  11656 +  11657 +  11658 +  11659 +  11660 +  11661 +  11662 +  11663 +  11664 +  11665 +  11666 +  11667 +  11668 +  11669 +  11670 +  11671 +  11672 +  11673 +  11674 +  11675 +  11676 +  11677 +  11678 +  11679 +  11680 +  11681 +  11682 +  11683 +  11684 +  11685 +  11686 +  11687 +  11688 +  11689 +  11690 +  11691 +  11692 +  11693 +  11694 +  11695 +  11696 +  11697 +  11698 +  11699 +  11700 +  11701 +  11702 +  11703 +  11704 +  11705 +  11706 +  11707 +  11708 +  11709 +  11710 +  11711 +  11712 +  11713 +  11714 +  11715 +  11716 +  11717 +  11718 +  11719 +  11720 +  11721 +  11722 +  11723 +  11724 +  11725 +  11726 +  11727 +  11728 +  11729 +  11730 +  11731 +  11732 +  11733 +  11734 +  11735 +  11736 +  11737 +  11738 +  11739 +  11740 +  11741 +  11742 +  11743 +  11744 +  11745 +  11746 +  11747 +  11748 +  11749 +  11750 +  11751 +  11752 +  11753 +  11754 +  11755 +  11756 +  11757 +  11758 +  11759 +  11760 +  11761 +  11762 +  11763 +  11764 + ��d��d��d��d��d��d��d��d��d 11765 +  11766 +  11767 +  11768 +  11769 +  11770 +  11771 +  11772 +  11773 +  11774 +  11775 +  11776 +  11777 +  11778 +  11779 +  11780 +  11781 +  11782 +  11783 +  11784 +  11785 +  11786 +  11787 +  11788 +  11789 +  11790 +  11791 +  11792 +  11793 +  11794 +  11795 +  11796 +  11797 +  11798 +  11799 +  11800 +  11801 +  11802 +  11803 +  11804 +  11805 +  11806 +  11807 +  11808 +  11809 +  11810 +  11811 +  11812 +  11813 +  11814 +  11815 +  11816 +  11817 +  11818 +  11819 +  11820 +  11821 +  11822 +  11823 +  11824 +  11825 +  11826 +  11827 +  11828 +  11829 +  11830 +  11831 +  11832 +  11833 +  11834 +  11835 +  11836 +  11837 +  11838 +  11839 +  11840 +  11841 +  11842 +  11843 +  11844 +  11845 +  11846 +  11847 +  11848 +  11849 +  11850 +  11851 +  11852 +  11853 +  11854 +  11855 +  11856 +  11857 +  11858 +  11859 +  11860 +  11861 +  11862 +  11863 +  11864 +  11865 +  11866 +  11867 +  11868 +  11869 +  11870 +  11871 +  11872 +  11873 +  11874 +  11875 +  11876 +  11877 +  11878 +  11879 +  11880 +  11881 +  11882 +  11883 +  11884 +  11885 +  11886 +  11887 + ��d 11888 +  11889 +  11890 +  11891 +  11892 +  11893 +  11894 +  11895 +  11896 +  11897 +  11898 +  11899 +  11900 +  11901 +  11902 +  11903 +  11904 +  11905 +  11906 +  11907 +  11908 +  11909 +  11910 +  11911 +  11912 +  11913 +  11914 +  11915 +  11916 +  11917 +  11918 +  11919 +  11920 +  11921 +  11922 +  11923 +  11924 +  11925 +  11926 +  11927 +  11928 +  11929 +  11930 +  11931 +  11932 +  11933 +  11934 +  11935 +  11936 +  11937 +  11938 +  11939 +  11940 +  11941 +  11942 +  11943 +  11944 +  11945 +  11946 +  11947 +  11948 +  11949 +  11950 +  11951 +  11952 +  11953 +  11954 +  11955 +  11956 +  11957 +  11958 +  11959 +  11960 +  11961 +  11962 +  11963 +  11964 +  11965 +  11966 +  11967 +  11968 +  11969 +  11970 +  11971 +  11972 +  11973 +  11974 +  11975 +  11976 +  11977 +  11978 +  11979 +  11980 +  11981 +  11982 +  11983 +  11984 +  11985 +  11986 +  11987 +  11988 +  11989 +  11990 +  11991 +  11992 +  11993 +  11994 +  11995 +  11996 +  11997 +  11998 +  11999 +  12000 +  12001 +  12002 +  12003 +  12004 +  12005 +  12006 +  12007 +  12008 +  12009 +  12010 +  12011 +  12012 +  12013 +  12014 +  12015 +  12016 +  12017 +  12018 +  12019 +  12020 +  12021 +  12022 +  12023 +  12024 +  12025 +  12026 +  12027 +  12028 +  12029 +  12030 +  12031 +  12032 +  12033 +  12034 +  12035 +  12036 +  12037 +  12038 +  12039 +  12040 +  12041 +  12042 +  12043 +  12044 +  12045 +  12046 +  12047 +  12048 +  12049 +  12050 +  12051 +  12052 +  12053 +  12054 +  12055 +  12056 +  12057 +  12058 +  12059 +  12060 +  12061 +  12062 +  12063 +  12064 +  12065 +  12066 +  12067 +  12068 +  12069 +  12070 +  12071 +  12072 +  12073 +  12074 +  12075 +  12076 +  12077 +  12078 +  12079 +  12080 +  12081 +  12082 +  12083 +  12084 +  12085 +  12086 +  12087 +  12088 +  12089 +  12090 +  12091 +  12092 +  12093 +  12094 +  12095 +  12096 +  12097 +  12098 +  12099 +  12100 +  12101 +  12102 +  12103 +  12104 +  12105 +  12106 +  12107 +  12108 +  12109 +  12110 +  12111 +  12112 +  12113 +  12114 +  12115 +  12116 +  12117 +  12118 +  12119 +  12120 +  12121 +  12122 +  12123 +  12124 +  12125 +  12126 +  12127 +  12128 +  12129 +  12130 +  12131 +  12132 +  12133 +  12134 +  12135 +  12136 +  12137 +  12138 +  12139 +  12140 +  12141 +  12142 +  12143 +  12144 +  12145 +  12146 +  12147 +  12148 +  12149 +  12150 +  12151 +  12152 +  12153 +  12154 +  12155 +  12156 +  12157 +  12158 +  12159 +  12160 +  12161 +  12162 +  12163 +  12164 +  12165 +  12166 +  12167 +  12168 +  12169 +  12170 +  12171 +  12172 +  12173 +  12174 +  12175 +  12176 +  12177 +  12178 +  12179 +  12180 +  12181 +  12182 +  12183 +  12184 +  12185 +  12186 +  12187 +  12188 +  12189 +  12190 +  12191 +  12192 +  12193 +  12194 +  12195 +  12196 +  12197 +  12198 +  12199 +  12200 +  12201 +  12202 +  12203 +  12204 +  12205 +  12206 +  12207 +  12208 +  12209 +  12210 +  12211 +  12212 +  12213 +  12214 +  12215 +  12216 +  12217 +  12218 +  12219 +  12220 +  12221 +  12222 +  12223 +  12224 +  12225 +  12226 +  12227 +  12228 +  12229 +  12230 +  12231 +  12232 +  12233 +  12234 +  12235 +  12236 +  12237 +  12238 +  12239 +  12240 +  12241 +  12242 +  12243 +  12244 +  12245 +  12246 +  12247 +  12248 +  12249 +  12250 +  12251 +  12252 +  12253 +  12254 +  12255 +  12256 +  12257 +  12258 +  12259 +  12260 +  12261 +  12262 +  12263 +  12264 +  12265 +  12266 +  12267 +  12268 +  12269 +  12270 +  12271 +  12272 +  12273 +  12274 +  12275 +  12276 +  12277 +  12278 +  12279 +  12280 +  12281 +  12282 +  12283 +  12284 +  12285 +  12286 +  12287 +  12288 +  12289 +  12290 +  12291 +  12292 +  12293 +  12294 +  12295 +  12296 +  12297 +  12298 +  12299 +  12300 +  12301 +  12302 +  12303 +  12304 +  12305 +  12306 +  12307 +  12308 +  12309 +  12310 +  12311 +  12312 +  12313 +  12314 +  12315 +  12316 +  12317 +  12318 +  12319 +  12320 +  12321 +  12322 +  12323 +  12324 +  12325 +  12326 +  12327 +  12328 +  12329 +  12330 +  12331 +  12332 +  12333 +  12334 +  12335 +  12336 +  12337 +  12338 +  12339 +  12340 +  12341 +  12342 +  12343 +  12344 +  12345 +  12346 +  12347 +  12348 +  12349 +  12350 +  12351 +  12352 +  12353 +  12354 +  12355 +  12356 +  12357 +  12358 +  12359 +  12360 +  12361 +  12362 +  12363 +  12364 +  12365 +  12366 +  12367 +  12368 +  12369 +  12370 +  12371 +  12372 +  12373 +  12374 +  12375 +  12376 +  12377 +  12378 +  12379 +  12380 +  12381 +  12382 +  12383 +  12384 +  12385 +  12386 +  12387 +  12388 +  12389 +  12390 +  12391 +  12392 +  12393 +  12394 +  12395 +  12396 +  12397 +  12398 +  12399 +  12400 +  12401 +  12402 +  12403 +  12404 +  12405 +  12406 +  12407 +  12408 +  12409 +  12410 +  12411 +  12412 +  12413 +  12414 +  12415 +  12416 +  12417 +  12418 +  12419 +  12420 +  12421 +  12422 +  12423 +  12424 +  12425 +  12426 +  12427 +  12428 +  12429 +  12430 +  12431 +  12432 +  12433 +  12434 +  12435 +  12436 +  12437 +  12438 +  12439 +  12440 +  12441 +  12442 +  12443 +  12444 +  12445 +  12446 +  12447 +  12448 +  12449 +  12450 +  12451 +  12452 +  12453 +  12454 +  12455 +  12456 +  12457 +  12458 +  12459 +  12460 +  12461 +  12462 +  12463 +  12464 +  12465 +  12466 +  12467 +  12468 +  12469 +  12470 +  12471 +  12472 +  12473 +  12474 +  12475 +  12476 +  12477 +  12478 +  12479 +  12480 +  12481 +  12482 +  12483 +  12484 +  12485 +  12486 +  12487 +  12488 +  12489 +  12490 +  12491 +  12492 +  12493 +  12494 +  12495 +  12496 +  12497 +  12498 +  12499 +  12500 +  12501 +  12502 +  12503 +  12504 +  12505 +  12506 +  12507 +  12508 +  12509 +  12510 +  12511 +  12512 +  12513 +  12514 +  12515 +  12516 +  12517 +  12518 +  12519 +  12520 +  12521 +  12522 +  12523 +  12524 +  12525 +  12526 +  12527 +  12528 +  12529 +  12530 +  12531 +  12532 +  12533 +  12534 +  12535 +  12536 +  12537 +  12538 +  12539 +  12540 +  12541 +  12542 +  12543 +  12544 +  12545 +  12546 +  12547 +  12548 +  12549 +  12550 +  12551 +  12552 +  12553 +  12554 +  12555 +  12556 +  12557 +  12558 +  12559 +  12560 +  12561 +  12562 +  12563 +  12564 +  12565 +  12566 +  12567 +  12568 +  12569 +  12570 +  12571 +  12572 +  12573 +  12574 +  12575 +  12576 +  12577 +  12578 +  12579 +  12580 +  12581 +  12582 +  12583 +  12584 +  12585 +  12586 +  12587 +  12588 +  12589 +  12590 +  12591 +  12592 +  12593 +  12594 +  12595 +  12596 +  12597 +  12598 +  12599 +  12600 +  12601 +  12602 +  12603 +  12604 +  12605 +  12606 +  12607 +  12608 +  12609 +  12610 +  12611 +  12612 +  12613 +  12614 +  12615 +  12616 +  12617 +  12618 +  12619 +  12620 +  12621 +  12622 +  12623 +  12624 +  12625 +  12626 +  12627 +  12628 +  12629 +  12630 +  12631 +  12632 +  12633 +  12634 +  12635 +  12636 +  12637 +  12638 +  12639 +  12640 +  12641 +  12642 +  12643 +  12644 +  12645 +  12646 +  12647 +  12648 +  12649 +  12650 +  12651 +  12652 +  12653 +  12654 +  12655 +  12656 +  12657 +  12658 +  12659 +  12660 +  12661 +  12662 +  12663 +  12664 +  12665 +  12666 +  12667 +  12668 +  12669 +  12670 +  12671 +  12672 +  12673 +  12674 +  12675 +  12676 +  12677 +  12678 +  12679 +  12680 +  12681 +  12682 +  12683 +  12684 +  12685 +  12686 +  12687 +  12688 +  12689 +  12690 +  12691 +  12692 +  12693 +  12694 +  12695 +  12696 +  12697 +  12698 +  12699 +  12700 +  12701 +  12702 +  12703 +  12704 +  12705 +  12706 +  12707 +  12708 +  12709 +  12710 +  12711 +  12712 +  12713 +  12714 +  12715 +  12716 +  12717 +  12718 +  12719 +  12720 +  12721 +  12722 +  12723 +  12724 +  12725 +  12726 +  12727 +  12728 +  12729 +  12730 +  12731 +  12732 +  12733 +  12734 +  12735 +  12736 +  12737 +  12738 +  12739 +  12740 +  12741 +  12742 +  12743 +  12744 +  12745 +  12746 +  12747 +  12748 +  12749 +  12750 +  12751 +  12752 +  12753 +  12754 +  12755 +  12756 +  12757 +  12758 +  12759 +  12760 +  12761 +  12762 +  12763 +  12764 +  12765 +  12766 +  12767 +  12768 +  12769 +  12770 +  12771 +  12772 +  12773 +  12774 +  12775 +  12776 +  12777 +  12778 +  12779 +  12780 +  12781 +  12782 +  12783 +  12784 +  12785 +  12786 +  12787 +  12788 +  12789 +  12790 +  12791 +  12792 +  12793 +  12794 +  12795 +  12796 +  12797 +  12798 +  12799 +  12800 +  12801 +  12802 +  12803 +  12804 +  12805 +  12806 +  12807 +  12808 +  12809 +  12810 +  12811 +  12812 +  12813 +  12814 +  12815 +  12816 +  12817 +  12818 +  12819 +  12820 +  12821 +  12822 +  12823 +  12824 +  12825 +  12826 +  12827 +  12828 +  12829 +  12830 +  12831 +  12832 +  12833 +  12834 +  12835 +  12836 +  12837 +  12838 +  12839 +  12840 +  12841 +  12842 +  12843 +  12844 +  12845 +  12846 +  12847 +  12848 +  12849 +  12850 +  12851 +  12852 +  12853 +  12854 +  12855 +  12856 +  12857 +  12858 +  12859 +  12860 +  12861 +  12862 +  12863 +  12864 +  12865 +  12866 +  12867 +  12868 +  12869 +  12870 +  12871 +  12872 +  12873 +  12874 +  12875 +  12876 +  12877 +  12878 +  12879 +  12880 +  12881 +  12882 +  12883 +  12884 +  12885 +  12886 +  12887 +  12888 +  12889 +  12890 +  12891 +  12892 +  12893 +  12894 +  12895 +  12896 +  12897 +  12898 +  12899 +  12900 +  12901 +  12902 +  12903 +  12904 +  12905 +  12906 +  12907 +  12908 +  12909 +  12910 +  12911 +  12912 +  12913 +  12914 +  12915 +  12916 +  12917 +  12918 +  12919 +  12920 +  12921 +  12922 +  12923 +  12924 +  12925 +  12926 +  12927 +  12928 +  12929 +  12930 +  12931 +  12932 +  12933 +  12934 +  12935 +  12936 +  12937 +  12938 +  12939 +  12940 +  12941 +  12942 +  12943 +  12944 +  12945 +  12946 +  12947 +  12948 +  12949 +  12950 +  12951 +  12952 +  12953 +  12954 +  12955 +  12956 +  12957 +  12958 +  12959 +  12960 +  12961 +  12962 +  12963 +  12964 +  12965 +  12966 +  12967 +  12968 +  12969 +  12970 +  12971 +  12972 +  12973 +  12974 +  12975 +  12976 +  12977 +  12978 +  12979 +  12980 +  12981 +  12982 +  12983 +  12984 +  12985 +  12986 +  12987 +  12988 +  12989 +  12990 +  12991 +  12992 +  12993 +  12994 +  12995 +  12996 +  12997 +  12998 +  12999 +  13000 +  13001 +  13002 +  13003 +  13004 +  13005 +  13006 +  13007 +  13008 +  13009 +  13010 +  13011 +  13012 +  13013 +  13014 +  13015 +  13016 +  13017 +  13018 +  13019 +  13020 +  13021 +  13022 +  13023 +  13024 +  13025 +  13026 +  13027 +  13028 +  13029 +  13030 +  13031 +  13032 +  13033 +  13034 +  13035 +  13036 +  13037 +  13038 +  13039 +  13040 +  13041 +  13042 +  13043 +  13044 +  13045 +  13046 +  13047 +  13048 +  13049 +  13050 +  13051 +  13052 +  13053 +  13054 +  13055 +  13056 +  13057 +  13058 +  13059 +  13060 +  13061 +  13062 +  13063 +  13064 +  13065 +  13066 +  13067 +  13068 +  13069 +  13070 +  13071 +  13072 +  13073 +  13074 +  13075 +  13076 +  13077 +  13078 +  13079 +  13080 +  13081 +  13082 +  13083 +  13084 +  13085 +  13086 +  13087 +  13088 +  13089 +  13090 +  13091 +  13092 +  13093 +  13094 +  13095 +  13096 +  13097 +  13098 +  13099 +  13100 +  13101 +  13102 +  13103 +  13104 +  13105 +  13106 +  13107 +  13108 +  13109 +  13110 +  13111 +  13112 +  13113 +  13114 +  13115 +  13116 +  13117 +  13118 +  13119 +  13120 +  13121 +  13122 +  13123 +  13124 +  13125 +  13126 +  13127 +  13128 +  13129 +  13130 +  13131 +  13132 +  13133 +  13134 +  13135 +  13136 +  13137 +  13138 +  13139 +  13140 +  13141 +  13142 +  13143 +  13144 +  13145 +  13146 +  13147 +  13148 +  13149 +  13150 +  13151 +  13152 +  13153 +  13154 +  13155 +  13156 +  13157 +  13158 +  13159 +  13160 +  13161 +  13162 +  13163 +  13164 +  13165 +  13166 +  13167 +  13168 +  13169 +  13170 +  13171 +  13172 +  13173 +  13174 +  13175 +  13176 +  13177 +  13178 +  13179 +  13180 +  13181 +  13182 +  13183 +  13184 +  13185 +  13186 +  13187 +  13188 +  13189 +  13190 +  13191 +  13192 +  13193 +  13194 +  13195 +  13196 +  13197 +  13198 +  13199 +  13200 +  13201 +  13202 +  13203 +  13204 +  13205 +  13206 +  13207 +  13208 +  13209 +  13210 +  13211 +  13212 +  13213 +  13214 +  13215 +  13216 +  13217 +  13218 +  13219 +  13220 +  13221 +  13222 +  13223 +  13224 +  13225 +  13226 +  13227 +  13228 +  13229 +  13230 +  13231 +  13232 +  13233 +  13234 +  13235 +  13236 +  13237 +  13238 +  13239 +  13240 +  13241 +  13242 +  13243 +  13244 +  13245 +  13246 +  13247 +  13248 +  13249 +  13250 +  13251 +  13252 +  13253 +  13254 +  13255 +  13256 +  13257 +  13258 +  13259 +  13260 +  13261 +  13262 +  13263 +  13264 +  13265 +  13266 +  13267 +  13268 +  13269 +  13270 +  13271 +  13272 +  13273 +  13274 +  13275 +  13276 +  13277 +  13278 +  13279 +  13280 +  13281 +  13282 +  13283 +  13284 +  13285 +  13286 +  13287 +  13288 +  13289 +  13290 +  13291 +  13292 +  13293 +  13294 +  13295 +  13296 +  13297 +  13298 +  13299 +  13300 +  13301 +  13302 +  13303 +  13304 +  13305 +  13306 +  13307 +  13308 +  13309 +  13310 +  13311 +  13312 +  13313 +  13314 +  13315 +  13316 +  13317 +  13318 +  13319 +  13320 +  13321 +  13322 +  13323 +  13324 +  13325 +  13326 +  13327 +  13328 +  13329 +  13330 +  13331 +  13332 +  13333 +  13334 +  13335 +  13336 +  13337 +  13338 +  13339 +  13340 +  13341 +  13342 +  13343 +  13344 +  13345 +  13346 +  13347 +  13348 +  13349 +  13350 +  13351 +  13352 +  13353 +  13354 +  13355 +  13356 +  13357 +  13358 +  13359 +  13360 +  13361 +  13362 +  13363 +  13364 +  13365 +  13366 +  13367 +  13368 +  13369 +  13370 +  13371 +  13372 +  13373 +  13374 +  13375 +  13376 +  13377 +  13378 +  13379 +  13380 +  13381 +  13382 +  13383 +  13384 +  13385 +  13386 +  13387 +  13388 +  13389 +  13390 +  13391 +  13392 +  13393 +  13394 +  13395 +  13396 +  13397 +  13398 +  13399 +  13400 +  13401 +  13402 +  13403 +  13404 +  13405 +  13406 +  13407 +  13408 +  13409 +  13410 +  13411 +  13412 +  13413 +  13414 +  13415 +  13416 +  13417 +  13418 +  13419 +  13420 +  13421 +  13422 +  13423 +  13424 +  13425 +  13426 +  13427 +  13428 +  13429 +  13430 +  13431 +  13432 +  13433 +  13434 +  13435 +  13436 +  13437 +  13438 +  13439 +  13440 +  13441 +  13442 +  13443 +  13444 +  13445 +  13446 +  13447 +  13448 +  13449 +  13450 +  13451 +  13452 +  13453 +  13454 +  13455 +  13456 +  13457 +  13458 +  13459 +  13460 +  13461 +  13462 +  13463 +  13464 +  13465 +  13466 +  13467 +  13468 +  13469 +  13470 +  13471 +  13472 +  13473 +  13474 +  13475 +  13476 +  13477 +  13478 +  13479 +  13480 +  13481 +  13482 +  13483 +  13484 +  13485 +  13486 +  13487 +  13488 +  13489 +  13490 +  13491 +  13492 +  13493 +  13494 +  13495 +  13496 +  13497 +  13498 +  13499 +  13500 +  13501 +  13502 +  13503 +  13504 +  13505 +  13506 +  13507 +  13508 +  13509 +  13510 +  13511 +  13512 +  13513 +  13514 +  13515 +  13516 +  13517 +  13518 +  13519 +  13520 +  13521 +  13522 +  13523 +  13524 +  13525 +  13526 +  13527 +  13528 +  13529 +  13530 +  13531 +  13532 +  13533 +  13534 +  13535 +  13536 +  13537 +  13538 +  13539 +  13540 +  13541 +  13542 +  13543 +  13544 +  13545 +  13546 +  13547 +  13548 +  13549 +  13550 +  13551 +  13552 +  13553 +  13554 +  13555 +  13556 +  13557 +  13558 +  13559 +  13560 +  13561 +  13562 +  13563 +  13564 +  13565 +  13566 +  13567 +  13568 +  13569 +  13570 +  13571 +  13572 +  13573 +  13574 +  13575 +  13576 +  13577 +  13578 +  13579 +  13580 +  13581 +  13582 +  13583 +  13584 +  13585 +  13586 +  13587 +  13588 +  13589 +  13590 +  13591 +  13592 +  13593 +  13594 +  13595 +  13596 +  13597 +  13598 +  13599 +  13600 +  13601 +  13602 +  13603 +  13604 +  13605 +  13606 +  13607 +  13608 +  13609 +  13610 +  13611 +  13612 +  13613 +  13614 +  13615 +  13616 +  13617 +  13618 +  13619 +  13620 +  13621 +  13622 +  13623 +  13624 +  13625 +  13626 +  13627 +  13628 +  13629 +  13630 +  13631 +  13632 +  13633 +  13634 +  13635 +  13636 +  13637 +  13638 +  13639 +  13640 +  13641 +  13642 +  13643 +  13644 +  13645 +  13646 +  13647 +  13648 +  13649 +  13650 +  13651 +  13652 +  13653 +  13654 +  13655 +  13656 +  13657 +  13658 +  13659 +  13660 +  13661 +  13662 +  13663 +  13664 +  13665 +  13666 +  13667 +  13668 +  13669 +  13670 +  13671 +  13672 +  13673 +  13674 +  13675 +  13676 +  13677 +  13678 +  13679 +  13680 +  13681 +  13682 +  13683 +  13684 +  13685 +  13686 +  13687 +  13688 +  13689 +  13690 +  13691 +  13692 +  13693 +  13694 +  13695 +  13696 +  13697 +  13698 +  13699 +  13700 +  13701 +  13702 +  13703 +  13704 +  13705 +  13706 +  13707 +  13708 +  13709 +  13710 +  13711 +  13712 +  13713 +  13714 +  13715 +  13716 +  13717 +  13718 +  13719 +  13720 +  13721 +  13722 +  13723 +  13724 +  13725 +  13726 +  13727 +  13728 +  13729 +  13730 +  13731 +  13732 +  13733 +  13734 +  13735 +  13736 +  13737 +  13738 +  13739 +  13740 +  13741 +  13742 +  13743 +  13744 +  13745 +  13746 +  13747 +  13748 +  13749 +  13750 +  13751 +  13752 +  13753 +  13754 +  13755 +  13756 +  13757 +  13758 +  13759 +  13760 +  13761 +  13762 +  13763 +  13764 +  13765 +  13766 +  13767 +  13768 +  13769 +  13770 +  13771 +  13772 +  13773 +  13774 +  13775 +  13776 +  13777 +  13778 +  13779 +  13780 +  13781 +  13782 +  13783 +  13784 +  13785 +  13786 +  13787 +  13788 +  13789 +  13790 +  13791 +  13792 +  13793 +  13794 +  13795 +  13796 +  13797 +  13798 +  13799 +  13800 +  13801 +  13802 +  13803 +  13804 +  13805 +  13806 +  13807 +  13808 +  13809 +  13810 +  13811 +  13812 +  13813 +  13814 +  13815 +  13816 +  13817 +  13818 +  13819 +  13820 +  13821 +  13822 +  13823 +  13824 +  13825 +  13826 +  13827 +  13828 +  13829 +  13830 +  13831 +  13832 +  13833 +  13834 +  13835 +  13836 +  13837 +  13838 +  13839 +  13840 +  13841 +  13842 +  13843 +  13844 +  13845 +  13846 +  13847 +  13848 +  13849 +  13850 +  13851 +  13852 +  13853 +  13854 +  13855 +  13856 +  13857 +  13858 +  13859 +  13860 +  13861 +  13862 +  13863 +  13864 +  13865 +  13866 +  13867 +  13868 +  13869 +  13870 +  13871 +  13872 +  13873 +  13874 +  13875 +  13876 +  13877 +  13878 +  13879 +  13880 +  13881 +  13882 +  13883 +  13884 +  13885 +  13886 +  13887 +  13888 +  13889 +  13890 +  13891 +  13892 +  13893 +  13894 +  13895 +  13896 +  13897 +  13898 +  13899 +  13900 +  13901 +  13902 +  13903 +  13904 +  13905 +  13906 +  13907 +  13908 +  13909 +  13910 +  13911 +  13912 +  13913 +  13914 +  13915 +  13916 +  13917 +  13918 +  13919 +  13920 +  13921 +  13922 +  13923 +  13924 +  13925 +  13926 +  13927 +  13928 +  13929 +  13930 +  13931 +  13932 +  13933 +  13934 +  13935 +  13936 +  13937 +  13938 +  13939 +  13940 +  13941 +  13942 +  13943 +  13944 +  13945 +  13946 +  13947 +  13948 +  13949 +  13950 +  13951 +  13952 +  13953 +  13954 +  13955 +  13956 +  13957 +  13958 +  13959 +  13960 +  13961 +  13962 +  13963 +  13964 +  13965 +  13966 +  13967 +  13968 +  13969 +  13970 +  13971 +  13972 +  13973 +  13974 +  13975 +  13976 +  13977 +  13978 +  13979 +  13980 +  13981 +  13982 +  13983 +  13984 +  13985 +  13986 +  13987 +  13988 +  13989 +  13990 +  13991 +  13992 +  13993 +  13994 +  13995 +  13996 +  13997 +  13998 +  13999 +  14000 +  14001 +  14002 +  14003 +  14004 +  14005 +  14006 +  14007 +  14008 +  14009 +  14010 +  14011 +  14012 +  14013 +  14014 +  14015 +  14016 +  14017 +  14018 +  14019 +  14020 +  14021 +  14022 +  14023 +  14024 +  14025 +  14026 +  14027 +  14028 +  14029 +  14030 +  14031 +  14032 +  14033 +  14034 +  14035 +  14036 +  14037 +  14038 +  14039 +  14040 +  14041 +  14042 +  14043 +  14044 +  14045 +  14046 +  14047 +  14048 +  14049 +  14050 +  14051 +  14052 +  14053 +  14054 +  14055 +  14056 +  14057 +  14058 +  14059 +  14060 +  14061 +  14062 +  14063 +  14064 +  14065 +  14066 +  14067 +  14068 +  14069 +  14070 +  14071 +  14072 +  14073 +  14074 +  14075 +  14076 +  14077 +  14078 +  14079 +  14080 +  14081 +  14082 +  14083 +  14084 +  14085 +  14086 +  14087 +  14088 +  14089 +  14090 +  14091 +  14092 +  14093 +  14094 +  14095 +  14096 +  14097 +  14098 +  14099 +  14100 +  14101 +  14102 +  14103 +  14104 +  14105 +  14106 +  14107 +  14108 +  14109 +  14110 +  14111 +  14112 +  14113 +  14114 +  14115 +  14116 +  14117 +  14118 +  14119 +  14120 +  14121 +  14122 +  14123 +  14124 +  14125 +  14126 +  14127 +  14128 +  14129 +  14130 +  14131 +  14132 +  14133 +  14134 +  14135 +  14136 +  14137 +  14138 +  14139 +  14140 +  14141 +  14142 +  14143 +  14144 +  14145 +  14146 +  14147 +  14148 +  14149 +  14150 +  14151 +  14152 +  14153 +  14154 +  14155 +  14156 +  14157 +  14158 +  14159 +  14160 +  14161 +  14162 +  14163 +  14164 +  14165 +  14166 +  14167 +  14168 +  14169 +  14170 +  14171 +  14172 +  14173 +  14174 +  14175 +  14176 +  14177 +  14178 +  14179 +  14180 +  14181 +  14182 +  14183 +  14184 +  14185 +  14186 +  14187 +  14188 +  14189 +  14190 +  14191 +  14192 +  14193 +  14194 +  14195 +  14196 +  14197 +  14198 +  14199 +  14200 +  14201 +  14202 +  14203 +  14204 +  14205 +  14206 +  14207 +  14208 +  14209 +  14210 +  14211 +  14212 +  14213 +  14214 +  14215 +  14216 +  14217 +  14218 +  14219 +  14220 +  14221 +  14222 +  14223 +  14224 +  14225 +  14226 +  14227 +  14228 +  14229 +  14230 +  14231 +  14232 +  14233 +  14234 +  14235 +  14236 +  14237 +  14238 +  14239 +  14240 +  14241 +  14242 +  14243 +  14244 +  14245 +  14246 +  14247 +  14248 +  14249 +  14250 +  14251 +  14252 +  14253 +  14254 +  14255 +  14256 +  14257 +  14258 +  14259 +  14260 +  14261 +  14262 +  14263 +  14264 +  14265 +  14266 +  14267 +  14268 +  14269 +  14270 +  14271 +  14272 +  14273 +  14274 +  14275 +  14276 +  14277 +  14278 +  14279 +  14280 +  14281 +  14282 +  14283 +  14284 +  14285 +  14286 +  14287 +  14288 +  14289 +  14290 +  14291 +  14292 +  14293 +  14294 +  14295 +  14296 +  14297 +  14298 +  14299 +  14300 +  14301 +  14302 +  14303 +  14304 +  14305 +  14306 +  14307 +  14308 +  14309 +  14310 +  14311 +  14312 +  14313 +  14314 +  14315 +  14316 +  14317 +  14318 +  14319 +  14320 +  14321 +  14322 +  14323 +  14324 +  14325 +  14326 +  14327 +  14328 +  14329 +  14330 +  14331 +  14332 +  14333 +  14334 +  14335 +  14336 +  14337 +  14338 +  14339 +  14340 +  14341 +  14342 +  14343 +  14344 +  14345 +  14346 +  14347 +  14348 +  14349 +  14350 +  14351 +  14352 +  14353 +  14354 +  14355 +  14356 +  14357 +  14358 +  14359 +  14360 +  14361 +  14362 +  14363 +  14364 +  14365 +  14366 +  14367 +  14368 +  14369 +  14370 +  14371 +  14372 +  14373 +  14374 +  14375 +  14376 +  14377 +  14378 +  14379 +  14380 +  14381 +  14382 +  14383 +  14384 +  14385 +  14386 +  14387 +  14388 +  14389 +  14390 +  14391 +  14392 +  14393 +  14394 +  14395 +  14396 +  14397 +  14398 +  14399 +  14400 +  14401 +  14402 +  14403 +  14404 +  14405 +  14406 +  14407 +  14408 +  14409 +  14410 +  14411 +  14412 +  14413 +  14414 +  14415 +  14416 +  14417 +  14418 +  14419 +  14420 +  14421 +  14422 +  14423 +  14424 +  14425 +  14426 +  14427 +  14428 +  14429 +  14430 +  14431 +  14432 +  14433 +  14434 +  14435 +  14436 +  14437 +  14438 +  14439 +  14440 +  14441 +  14442 +  14443 +  14444 +  14445 +  14446 +  14447 +  14448 +  14449 +  14450 +  14451 +  14452 +  14453 +  14454 +  14455 +  14456 +  14457 +  14458 +  14459 +  14460 +  14461 +  14462 +  14463 +  14464 +  14465 +  14466 +  14467 +  14468 +  14469 +  14470 +  14471 +  14472 +  14473 +  14474 +  14475 +  14476 +  14477 +  14478 +  14479 +  14480 +  14481 +  14482 +  14483 +  14484 +  14485 +  14486 +  14487 +  14488 +  14489 +  14490 +  14491 +  14492 +  14493 +  14494 +  14495 +  14496 +  14497 +  14498 +  14499 +  14500 +  14501 +  14502 +  14503 +  14504 +  14505 +  14506 +  14507 +  14508 +  14509 +  14510 +  14511 +  14512 +  14513 +  14514 +  14515 +  14516 +  14517 +  14518 +  14519 +  14520 +  14521 +  14522 +  14523 +  14524 +  14525 +  14526 +  14527 +  14528 +  14529 +  14530 +  14531 +  14532 +  14533 +  14534 +  14535 +  14536 +  14537 +  14538 +  14539 +  14540 +  14541 +  14542 +  14543 +  14544 +  14545 +  14546 +  14547 +  14548 +  14549 +  14550 +  14551 +  14552 +  14553 +  14554 +  14555 +  14556 +  14557 +  14558 +  14559 +  14560 +  14561 +  14562 +  14563 +  14564 +  14565 +  14566 +  14567 +  14568 +  14569 +  14570 +  14571 +  14572 +  14573 +  14574 +  14575 +  14576 +  14577 +  14578 +  14579 +  14580 +  14581 +  14582 +  14583 +  14584 +  14585 +  14586 +  14587 +  14588 +  14589 +  14590 +  14591 +  14592 +  14593 +  14594 +  14595 +  14596 +  14597 +  14598 +  14599 +  14600 +  14601 +  14602 +  14603 +  14604 +  14605 +  14606 +  14607 +  14608 +  14609 +  14610 +  14611 +  14612 +  14613 +  14614 +  14615 +  14616 +  14617 +  14618 +  14619 +  14620 +  14621 +  14622 +  14623 +  14624 +  14625 +  14626 +  14627 +  14628 +  14629 +  14630 +  14631 +  14632 +  14633 +  14634 +  14635 +  14636 +  14637 +  14638 +  14639 +  14640 +  14641 +  14642 +  14643 +  14644 +  14645 +  14646 +  14647 +  14648 +  14649 +  14650 +  14651 +  14652 +  14653 +  14654 +  14655 +  14656 +  14657 +  14658 +  14659 +  14660 +  14661 +  14662 +  14663 +  14664 +  14665 +  14666 +  14667 +  14668 +  14669 +  14670 +  14671 +  14672 +  14673 +  14674 +  14675 +  14676 +  14677 +  14678 +  14679 +  14680 +  14681 +  14682 +  14683 +  14684 +  14685 +  14686 +  14687 +  14688 +  14689 +  14690 +  14691 +  14692 +  14693 +  14694 +  14695 +  14696 +  14697 +  14698 +  14699 +  14700 +  14701 +  14702 +  14703 +  14704 +  14705 +  14706 +  14707 +  14708 +  14709 +  14710 +  14711 +  14712 +  14713 +  14714 +  14715 +  14716 +  14717 +  14718 +  14719 +  14720 +  14721 +  14722 +  14723 +  14724 +  14725 +  14726 +  14727 +  14728 +  14729 +  14730 +  14731 +  14732 +  14733 +  14734 +  14735 +  14736 +  14737 +  14738 +  14739 +  14740 +  14741 +  14742 +  14743 +  14744 +  14745 +  14746 +  14747 +  14748 +  14749 +  14750 +  14751 +  14752 +  14753 +  14754 +  14755 +  14756 +  14757 +  14758 +  14759 +  14760 +  14761 +  14762 +  14763 +  14764 +  14765 +  14766 +  14767 +  14768 +  14769 +  14770 +  14771 +  14772 +  14773 +  14774 +  14775 +  14776 +  14777 +  14778 +  14779 +  14780 +  14781 +  14782 +  14783 +  14784 +  14785 +  14786 +  14787 +  14788 +  14789 +  14790 +  14791 +  14792 +  14793 +  14794 +  14795 +  14796 +  14797 +  14798 +  14799 +  14800 +  14801 +  14802 +  14803 +  14804 +  14805 +  14806 +  14807 +  14808 +  14809 +  14810 +  14811 +  14812 +  14813 +  14814 +  14815 +  14816 +  14817 +  14818 +  14819 +  14820 +  14821 +  14822 +  14823 +  14824 +  14825 +  14826 +  14827 +  14828 +  14829 +  14830 +  14831 +  14832 +  14833 +  14834 +  14835 +  14836 +  14837 +  14838 +  14839 +  14840 +  14841 +  14842 +  14843 +  14844 +  14845 +  14846 +  14847 +  14848 +  14849 +  14850 +  14851 +  14852 +  14853 +  14854 +  14855 +  14856 +  14857 +  14858 +  14859 +  14860 +  14861 +  14862 +  14863 +  14864 +  14865 +  14866 +  14867 +  14868 +  14869 +  14870 +  14871 +  14872 +  14873 +  14874 +  14875 +  14876 +  14877 +  14878 +  14879 +  14880 +  14881 +  14882 +  14883 +  14884 +  14885 +  14886 +  14887 +  14888 +  14889 +  14890 +  14891 +  14892 +  14893 +  14894 + 
+87
kidlisp-wasm/animate.mjs
··· 1 + #!/usr/bin/env node 2 + // Render animated KidLisp pieces to WebP via self-contained WASM. 3 + // Usage: node animate.mjs <piece.lisp> [frames] [fps] [size] 4 + 5 + import { readFileSync, mkdirSync } from "fs"; 6 + import { basename } from "path"; 7 + import sharp from "sharp"; 8 + import { Compiler } from "./compiler.mjs"; 9 + 10 + const OUT_DIR = new URL("./output/", import.meta.url).pathname; 11 + mkdirSync(OUT_DIR, { recursive: true }); 12 + 13 + const input = process.argv[2] || "anim.lisp"; 14 + const FRAMES = parseInt(process.argv[3]) || 120; 15 + const FPS = parseInt(process.argv[4]) || 30; 16 + const SIZE = parseInt(process.argv[5]) || 256; 17 + 18 + const path = new URL(input, import.meta.url).pathname; 19 + const source = readFileSync(path, "utf-8"); 20 + const name = basename(input, ".lisp"); 21 + 22 + console.log(`Compiling ${input}...`); 23 + const compiler = new Compiler(); 24 + const wasmBytes = compiler.compile(source); 25 + const mathImports = { 26 + math: { 27 + sin: (x) => Math.fround(Math.sin(x)), 28 + cos: (x) => Math.fround(Math.cos(x)), 29 + random: () => Math.fround(Math.random()), 30 + }, 31 + }; 32 + const { instance } = await WebAssembly.instantiate(wasmBytes, mathImports); 33 + console.log(`WASM: ${wasmBytes.length} bytes | ${FRAMES} frames @ ${FPS}fps | ${SIZE}x${SIZE}`); 34 + 35 + // Render all frames 36 + const delay = Math.round(1000 / FPS); 37 + const framePngs = []; 38 + 39 + for (let f = 0; f < FRAMES; f++) { 40 + instance.exports.paint(SIZE, SIZE, f); 41 + 42 + const mem = new Uint8Array(instance.exports.memory.buffer); 43 + const pixels = Buffer.from(mem.slice(0, SIZE * SIZE * 4)); 44 + 45 + const png = await sharp(pixels, { 46 + raw: { width: SIZE, height: SIZE, channels: 4 }, 47 + }).png().toBuffer(); 48 + 49 + framePngs.push(png); 50 + 51 + if ((f + 1) % 30 === 0 || f === FRAMES - 1) { 52 + process.stdout.write(`\r Rendered ${f + 1}/${FRAMES} frames`); 53 + } 54 + } 55 + console.log(); 56 + 57 + // Encode animated WebP 58 + console.log("Encoding animated WebP..."); 59 + const outPath = `${OUT_DIR}${name}.webp`; 60 + 61 + await sharp(framePngs[0], { animated: true }) 62 + .webp({ quality: 80 }) 63 + .toFile(outPath + ".tmp"); 64 + 65 + // sharp doesn't do animated WebP natively from frames, 66 + // so use ffmpeg which is available 67 + import { execSync } from "child_process"; 68 + 69 + // Write frames to temp dir 70 + const tmpDir = `${OUT_DIR}.frames-${name}`; 71 + mkdirSync(tmpDir, { recursive: true }); 72 + 73 + for (let f = 0; f < framePngs.length; f++) { 74 + const framePath = `${tmpDir}/frame-${String(f).padStart(5, "0")}.png`; 75 + await sharp(framePngs[f]).toFile(framePath); 76 + } 77 + 78 + execSync( 79 + `ffmpeg -y -framerate ${FPS} -i "${tmpDir}/frame-%05d.png" -loop 0 -lossless 1 "${outPath}" 2>/dev/null`, 80 + ); 81 + 82 + // Clean up 83 + execSync(`rm -rf "${tmpDir}" "${outPath}.tmp"`); 84 + 85 + const { statSync } = await import("fs"); 86 + const size = statSync(outPath).size; 87 + console.log(`${name}.webp (${SIZE}x${SIZE}, ${FRAMES} frames, ${(size / 1024).toFixed(1)}KB)`);
+3
kidlisp-wasm/bels.lisp
··· 1 + brown 2 + line 0 0 100 100 3 + scroll -2 1
+712 -95
kidlisp-wasm/compiler.mjs
··· 99 99 fneg() { this.b.push(0x8c); return this; } 100 100 fsqrt(){ this.b.push(0x91); return this; } 101 101 ffloor(){this.b.push(0x8e); return this; } 102 + fmin() { this.b.push(0x96); return this; } 103 + fmax() { this.b.push(0x97); return this; } 104 + fceil(){ this.b.push(0x8d); return this; } 102 105 // f32 comparison 103 - flt() { this.b.push(0x5b); return this; } 104 - fgt() { this.b.push(0x5d); return this; } 106 + feq() { this.b.push(0x5b); return this; } 107 + fne() { this.b.push(0x5c); return this; } 108 + flt() { this.b.push(0x5d); return this; } 109 + fgt() { this.b.push(0x5e); return this; } 105 110 fle() { this.b.push(0x5f); return this; } 106 - fge() { this.b.push(0x5e); return this; } 111 + fge() { this.b.push(0x60); return this; } 107 112 // Conversion 108 113 i2f() { this.b.push(0xb2); return this; } // i32 → f32 109 114 f2i() { this.b.push(0xa8); return this; } // f32 → i32 (trunc) ··· 133 138 yellow: [255, 255, 0], cyan: [0, 255, 255], magenta: [255, 0, 255], 134 139 orange: [255, 165, 0], purple: [128, 0, 128], 135 140 pink: [255, 192, 203], gray: [128, 128, 128], grey: [128, 128, 128], 136 - lime: [0, 255, 0], 141 + lime: [0, 255, 0], brown: [139, 69, 19], beige: [245, 245, 220], 142 + indigo: [75, 0, 130], violet: [238, 130, 238], 143 + orange2: [255, 200, 0], // alias for ink 255 200 0 137 144 }; 138 145 139 146 // ─── Parser ───────────────────────────────────────────────────────── ··· 211 218 212 219 // ─── Globals ──────────────────────────────────────────────────────── 213 220 214 - const G_W = 0, G_H = 1, G_IR = 2, G_IG = 3, G_IB = 4; 221 + const G_W = 0, G_H = 1, G_IR = 2, G_IG = 3, G_IB = 4, G_IA = 5; 222 + const G_SAX = 6, G_SAY = 7; // scroll accumulators (f32) 215 223 const I32 = 0x7f, F32 = 0x7d; 216 224 217 - // ─── Function Indices ─────────────────────────────────────────────── 218 - // No imports — all functions are internal. 225 + // ─── Constants ────────────────────────────────────────────────────── 226 + const FPS = 30; // frames per second for time-based calculations 219 227 220 - const F_SET_PIXEL = 0; // (i32, i32) → () 221 - const F_WIPE = 1; // (f32, f32, f32) → () 222 - const F_INK = 2; // (f32, f32, f32) → () 223 - const F_PLOT = 3; // (f32, f32) → () 224 - const F_LINE = 4; // (f32, f32, f32, f32) → () 225 - const F_BOX = 5; // (f32, f32, f32, f32) → () 226 - const F_CIRCLE = 6; // (f32, f32, f32) → () 227 - const F_TRI = 7; // (f32, f32, f32, f32, f32, f32) → () 228 - const F_PAINT = 8; // (f32, f32, f32) → () 228 + // ─── Function Indices ─────────────────────────────────────────────── 229 + // Imports come first in WASM function index space. 230 + const NUM_IMPORTS = 3; 231 + const F_SIN = 0; // imported: (f32) → f32 232 + const F_COS = 1; // imported: (f32) → f32 233 + const F_RANDOM = 2; // imported: () → f32 [returns 0..1) 234 + // Internal functions (offset by NUM_IMPORTS) 235 + const F_SET_PIXEL = 3; // (i32, i32) → () 236 + const F_WIPE = 4; // (f32, f32, f32) → () 237 + const F_INK = 5; // (f32, f32, f32) → () 238 + const F_PLOT = 6; // (f32, f32) → () 239 + const F_LINE = 7; // (f32, f32, f32, f32) → () 240 + const F_BOX = 8; // (f32, f32, f32, f32) → () 241 + const F_CIRCLE = 9; // (f32, f32, f32) → () 242 + const F_TRI = 10; // (f32, f32, f32, f32, f32, f32) → () 243 + const F_SCROLL = 11; // (f32, f32) → () 244 + const F_SPIN = 12; // (f32) → () 245 + const F_ZOOM = 13; // (f32) → () 246 + const F_CONTRAST = 14; // (f32) → () 247 + const F_PAINT = 15; // (f32, f32, f32) → () 229 248 230 249 // ─── Runtime Function Emitters ────────────────────────────────────── 231 250 232 251 // $set_pixel(x: i32, y: i32) 233 - // Writes a pixel at (x,y) using current ink color. 252 + // Writes a pixel at (x,y) using current ink color, alpha-blended via G_IA. 234 253 function emitSetPixel() { 235 254 const e = new E(); 236 - // params: 0=x, 1=y | locals: 2=offset 255 + // params: 0=x, 1=y | locals: 2=offset, 3=alpha, 4=invAlpha, 5=old 237 256 // Bounds check 238 257 e.lg(0).i32c(0).ilt().if_().ret().end(); 239 258 e.lg(0).gg(G_W).ige().if_().ret().end(); ··· 241 260 e.lg(1).gg(G_H).ige().if_().ret().end(); 242 261 // offset = (y * width + x) * 4 243 262 e.lg(1).gg(G_W).imul().lg(0).iadd().i32c(4).imul().ls(2); 244 - // store RGBA 245 - e.lg(2).gg(G_IR).st8(); 246 - e.lg(2).i32c(1).iadd().gg(G_IG).st8(); 247 - e.lg(2).i32c(2).iadd().gg(G_IB).st8(); 248 - e.lg(2).i32c(3).iadd().i32c(255).st8(); 263 + 264 + // alpha = G_IA 265 + e.gg(G_IA).ls(3); 266 + // Skip if alpha == 0 267 + e.lg(3).ieqz().if_().ret().end(); 268 + 269 + // Fast path: alpha == 255 → direct write 270 + e.lg(3).i32c(255).ieq().if_(); 271 + e.lg(2).gg(G_IR).st8(); 272 + e.lg(2).i32c(1).iadd().gg(G_IG).st8(); 273 + e.lg(2).i32c(2).iadd().gg(G_IB).st8(); 274 + e.lg(2).i32c(3).iadd().i32c(255).st8(); 275 + e.else_(); 276 + // Alpha blend: new = (old * (255 - alpha) + ink * alpha) / 255 277 + e.i32c(255).lg(3).isub().ls(4); // invAlpha = 255 - alpha 278 + // R 279 + e.lg(2).ld8u().ls(5); 280 + e.lg(2); e.lg(5).lg(4).imul().gg(G_IR).lg(3).imul().iadd().i32c(255).idiv(); e.st8(); 281 + // G 282 + e.lg(2).i32c(1).iadd().ld8u().ls(5); 283 + e.lg(2).i32c(1).iadd(); e.lg(5).lg(4).imul().gg(G_IG).lg(3).imul().iadd().i32c(255).idiv(); e.st8(); 284 + // B 285 + e.lg(2).i32c(2).iadd().ld8u().ls(5); 286 + e.lg(2).i32c(2).iadd(); e.lg(5).lg(4).imul().gg(G_IB).lg(3).imul().iadd().i32c(255).idiv(); e.st8(); 287 + // A stays 255 288 + e.lg(2).i32c(3).iadd().i32c(255).st8(); 289 + e.end(); 290 + 249 291 e.end(); 250 - return { locals: [[1, I32]], code: e.bytes() }; // 1 i32 local (offset) 292 + return { locals: [[4, I32]], code: e.bytes() }; 251 293 } 252 294 253 295 // $wipe(r: f32, g: f32, b: f32) ··· 536 578 return { locals: [[13, I32]], code: e.bytes() }; 537 579 } 538 580 581 + // $scroll(dx: f32, dy: f32) — shift pixels with wrapping + fractional accumulation 582 + function emitScroll() { 583 + const e = new E(); 584 + // params: 0=dx, 1=dy 585 + // locals: 2=idx, 3=idy, 4=total, 5=i, 6=src, 7=sx, 8=sy, 9=x, 10=y, 11=tmpOff 586 + 587 + // Accumulate fractional scroll: G_SAX += dx, G_SAY += dy 588 + e.gg(G_SAX).lg(0).fadd().gs(G_SAX); 589 + e.gg(G_SAY).lg(1).fadd().gs(G_SAY); 590 + // Extract integer parts (trunc toward zero) 591 + e.gg(G_SAX).f2i().ls(2); // idx 592 + e.gg(G_SAY).f2i().ls(3); // idy 593 + // Keep fractional remainders 594 + e.gg(G_SAX).lg(2).i2f().fsub().gs(G_SAX); 595 + e.gg(G_SAY).lg(3).i2f().fsub().gs(G_SAY); 596 + // Skip if no integer scroll 597 + e.lg(2).ieqz().lg(3).ieqz().iand().if_().ret().end(); 598 + e.gg(G_W).gg(G_H).imul().ls(4); // total pixels 599 + // Copy current buffer to temp area (at offset total*4) 600 + e.i32c(0).ls(5); // i = 0 601 + e.gg(G_W).gg(G_H).imul().i32c(4).imul().ls(11); // tmpOff = total * 4 602 + e.block().loop(); 603 + e.lg(5).lg(11).ige().brif(1); 604 + // mem[tmpOff + i] = mem[i] 605 + e.lg(5).lg(11).iadd(); 606 + e.lg(5).ld8u(); 607 + e.st8(); 608 + e.lg(5).i32c(1).iadd().ls(5); 609 + e.br(0); 610 + e.end().end(); 611 + 612 + // For each pixel (x,y), read from (x-dx, y-dy) in temp buffer with wrapping 613 + e.i32c(0).ls(10); // y = 0 614 + e.block().loop(); 615 + e.lg(10).gg(G_H).ige().brif(1); 616 + e.i32c(0).ls(9); // x = 0 617 + e.block().loop(); 618 + e.lg(9).gg(G_W).ige().brif(1); 619 + 620 + // sx = ((x - idx) % w + w) % w 621 + e.lg(9).lg(2).isub().gg(G_W).irem().gg(G_W).iadd().gg(G_W).irem().ls(7); 622 + // sy = ((y - idy) % h + h) % h 623 + e.lg(10).lg(3).isub().gg(G_H).irem().gg(G_H).iadd().gg(G_H).irem().ls(8); 624 + 625 + // src = tmpOff + (sy * w + sx) * 4 626 + e.lg(11).lg(8).gg(G_W).imul().lg(7).iadd().i32c(4).imul().iadd().ls(6); 627 + // dst = (y * w + x) * 4 628 + e.lg(10).gg(G_W).imul().lg(9).iadd().i32c(4).imul().ls(5); 629 + // copy 4 bytes 630 + e.lg(5).lg(6).ld8u().st8(); 631 + e.lg(5).i32c(1).iadd().lg(6).i32c(1).iadd().ld8u().st8(); 632 + e.lg(5).i32c(2).iadd().lg(6).i32c(2).iadd().ld8u().st8(); 633 + e.lg(5).i32c(3).iadd().lg(6).i32c(3).iadd().ld8u().st8(); 634 + 635 + e.lg(9).i32c(1).iadd().ls(9); 636 + e.br(0); 637 + e.end().end(); // x loop 638 + e.lg(10).i32c(1).iadd().ls(10); 639 + e.br(0); 640 + e.end().end(); // y loop 641 + e.end(); 642 + return { locals: [[10, I32]], code: e.bytes() }; 643 + } 644 + 645 + // ─── Rainbow Colors ───────────────────────────────────────────────── 646 + 647 + const RAINBOW = [ 648 + [255, 0, 0], // red 649 + [255, 165, 0], // orange 650 + [255, 255, 0], // yellow 651 + [0, 128, 0], // green 652 + [0, 0, 255], // blue 653 + [75, 0, 130], // indigo 654 + [238, 130, 238], // violet 655 + ]; 656 + 657 + // $spin(steps: f32) — vortex/swirl: angleChange = steps/distance from center 658 + // Pixels near center rotate more, creating a spiral effect. 659 + function emitSpin() { 660 + const e = new E(); 661 + // param: 0=steps (f32) 662 + // f32 locals: 1=dx, 2=dy, 3=distSq, 4=dist, 5=angleChange, 6=sinA, 7=cosA, 8=fsx, 9=fsy, 10=fcx, 11=fcy 663 + // i32 locals: 12=total, 13=tmpOff, 14=x, 15=y, 664 + // 16=sx, 17=sy, 18=srcOff, 19=dstOff, 20=i 665 + 666 + // fcx = (w - 1) / 2.0, fcy = (h - 1) / 2.0 667 + e.gg(G_W).i2f().f32c(1).fsub().f32c(2).fdiv().ls(10); 668 + e.gg(G_H).i2f().f32c(1).fsub().f32c(2).fdiv().ls(11); 669 + 670 + // total = w * h, tmpOff = total * 4 671 + e.gg(G_W).gg(G_H).imul().ls(12); 672 + e.lg(12).i32c(4).imul().ls(13); 673 + 674 + // Copy buffer to temp 675 + e.i32c(0).ls(20); 676 + e.block().loop(); 677 + e.lg(20).lg(13).ige().brif(1); 678 + e.lg(20).lg(13).iadd().lg(20).ld8u().st8(); 679 + e.lg(20).i32c(1).iadd().ls(20); 680 + e.br(0); 681 + e.end().end(); 682 + 683 + // For each (x, y) 684 + e.i32c(0).ls(15); // y = 0 685 + e.block().loop(); 686 + e.lg(15).gg(G_H).ige().brif(1); 687 + 688 + e.i32c(0).ls(14); // x = 0 689 + e.block().loop(); 690 + e.lg(14).gg(G_W).ige().brif(1); 691 + 692 + // dx = x - fcx, dy = y - fcy (all f32) 693 + e.lg(14).i2f().lg(10).fsub().ls(1); 694 + e.lg(15).i2f().lg(11).fsub().ls(2); 695 + 696 + // distSq = dx*dx + dy*dy 697 + e.lg(1).lg(1).fmul().lg(2).lg(2).fmul().fadd().ls(3); 698 + 699 + // dstOff = (y * w + x) * 4 700 + e.lg(15).gg(G_W).imul().lg(14).iadd().i32c(4).imul().ls(19); 701 + 702 + // if distSq < 1.0: copy directly (center pixel) 703 + e.lg(3).f32c(1).flt().if_(); 704 + // srcOff in temp = tmpOff + dstOff 705 + e.lg(19).lg(13).iadd().ls(18); 706 + e.lg(19).lg(18).ld8u().st8(); 707 + e.lg(19).i32c(1).iadd().lg(18).i32c(1).iadd().ld8u().st8(); 708 + e.lg(19).i32c(2).iadd().lg(18).i32c(2).iadd().ld8u().st8(); 709 + e.lg(19).i32c(3).iadd().lg(18).i32c(3).iadd().ld8u().st8(); 710 + e.else_(); 711 + // Vortex: angleChange = steps / distance 712 + e.lg(3).fsqrt().ls(4); 713 + e.lg(0).lg(4).fdiv().ls(5); 714 + 715 + // sinA = sin(angleChange), cosA = cos(angleChange) 716 + e.lg(5).call(F_SIN).ls(6); 717 + e.lg(5).call(F_COS).ls(7); 718 + 719 + // Rotate (dx, dy) by -angleChange using rotation matrix: 720 + // fsx = fcx + dx*cosA + dy*sinA 721 + e.lg(10).lg(1).lg(7).fmul().fadd().lg(2).lg(6).fmul().fadd().ls(8); 722 + // fsy = fcy - dx*sinA + dy*cosA 723 + e.lg(11).lg(1).lg(6).fmul().fsub().lg(2).lg(7).fmul().fadd().ls(9); 724 + 725 + // Nearest neighbor + wrap 726 + // Round to nearest (floor(x + 0.5)) for symmetric sampling 727 + e.lg(8).f32c(0.5).fadd().ffloor().f2i().ls(16); 728 + e.lg(9).f32c(0.5).fadd().ffloor().f2i().ls(17); 729 + e.lg(16).gg(G_W).irem().gg(G_W).iadd().gg(G_W).irem().ls(16); 730 + e.lg(17).gg(G_H).irem().gg(G_H).iadd().gg(G_H).irem().ls(17); 731 + 732 + // srcOff = tmpOff + (sy * w + sx) * 4 733 + e.lg(13).lg(17).gg(G_W).imul().lg(16).iadd().i32c(4).imul().iadd().ls(18); 734 + 735 + // Copy 4 bytes 736 + e.lg(19).lg(18).ld8u().st8(); 737 + e.lg(19).i32c(1).iadd().lg(18).i32c(1).iadd().ld8u().st8(); 738 + e.lg(19).i32c(2).iadd().lg(18).i32c(2).iadd().ld8u().st8(); 739 + e.lg(19).i32c(3).iadd().lg(18).i32c(3).iadd().ld8u().st8(); 740 + e.end(); 741 + 742 + e.lg(14).i32c(1).iadd().ls(14); 743 + e.br(0); 744 + e.end().end(); // x loop 745 + e.lg(15).i32c(1).iadd().ls(15); 746 + e.br(0); 747 + e.end().end(); // y loop 748 + e.end(); 749 + return { locals: [[11, F32], [9, I32]], code: e.bytes() }; 750 + } 751 + 752 + // $zoom(factor: f32) — scale pixel buffer from center (nearest-neighbor) 753 + function emitZoom() { 754 + const e = new E(); 755 + // param: 0=factor (f32) 756 + // f32 locals: 1=inv, 2=fcx, 3=fcy, 4=fsx, 5=fsy 757 + // i32 locals: 6=total, 7=tmpOff, 8=x, 9=y, 10=sx, 11=sy, 758 + // 12=srcOff, 13=dstOff, 14=i 759 + 760 + e.f32c(1).lg(0).fdiv().ls(1); 761 + e.gg(G_W).i2f().f32c(1).fsub().f32c(2).fdiv().ls(2); 762 + e.gg(G_H).i2f().f32c(1).fsub().f32c(2).fdiv().ls(3); 763 + 764 + e.gg(G_W).gg(G_H).imul().ls(6); 765 + e.lg(6).i32c(4).imul().ls(7); 766 + 767 + // Copy buffer to temp 768 + e.i32c(0).ls(14); 769 + e.block().loop(); 770 + e.lg(14).lg(7).ige().brif(1); 771 + e.lg(14).lg(7).iadd().lg(14).ld8u().st8(); 772 + e.lg(14).i32c(1).iadd().ls(14); 773 + e.br(0); 774 + e.end().end(); 775 + 776 + e.i32c(0).ls(9); // y = 0 777 + e.block().loop(); 778 + e.lg(9).gg(G_H).ige().brif(1); 779 + 780 + e.i32c(0).ls(8); // x = 0 781 + e.block().loop(); 782 + e.lg(8).gg(G_W).ige().brif(1); 783 + 784 + // fsx = fcx + (x - fcx) * inv 785 + e.lg(2).lg(8).i2f().lg(2).fsub().lg(1).fmul().fadd().ls(4); 786 + // fsy = fcy + (y - fcy) * inv 787 + e.lg(3).lg(9).i2f().lg(3).fsub().lg(1).fmul().fadd().ls(5); 788 + 789 + // Round to nearest for symmetric centering, then wrap 790 + e.lg(4).f32c(0.5).fadd().ffloor().f2i().ls(10); 791 + e.lg(5).f32c(0.5).fadd().ffloor().f2i().ls(11); 792 + e.lg(10).gg(G_W).irem().gg(G_W).iadd().gg(G_W).irem().ls(10); 793 + e.lg(11).gg(G_H).irem().gg(G_H).iadd().gg(G_H).irem().ls(11); 794 + 795 + // srcOff = tmpOff + (sy * w + sx) * 4 796 + e.lg(7).lg(11).gg(G_W).imul().lg(10).iadd().i32c(4).imul().iadd().ls(12); 797 + // dstOff = (y * w + x) * 4 798 + e.lg(9).gg(G_W).imul().lg(8).iadd().i32c(4).imul().ls(13); 799 + 800 + // Copy 4 bytes 801 + e.lg(13).lg(12).ld8u().st8(); 802 + e.lg(13).i32c(1).iadd().lg(12).i32c(1).iadd().ld8u().st8(); 803 + e.lg(13).i32c(2).iadd().lg(12).i32c(2).iadd().ld8u().st8(); 804 + e.lg(13).i32c(3).iadd().lg(12).i32c(3).iadd().ld8u().st8(); 805 + 806 + e.lg(8).i32c(1).iadd().ls(8); 807 + e.br(0); 808 + e.end().end(); // x loop 809 + e.lg(9).i32c(1).iadd().ls(9); 810 + e.br(0); 811 + e.end().end(); // y loop 812 + e.end(); 813 + return { locals: [[5, F32], [9, I32]], code: e.bytes() }; 814 + } 815 + 816 + // $contrast(factor: f32) — adjust pixel contrast around midpoint 128 817 + function emitContrast() { 818 + const e = new E(); 819 + // param: 0=factor (f32) 820 + // i32 locals: 1=total, 2=i, 3=off, 4=v 821 + // f32 locals: 5=result 822 + 823 + e.gg(G_W).gg(G_H).imul().i32c(4).imul().ls(1); // total bytes 824 + e.i32c(0).ls(2); // i = 0 825 + 826 + e.block().loop(); 827 + e.lg(2).lg(1).ige().brif(1); 828 + 829 + // Process R, G, B (skip A at offset +3) 830 + // For each channel c in {0,1,2}: 831 + // val = mem[i+c] 832 + // result = 128 + (val - 128) * factor 833 + // clamp to 0..255 834 + // mem[i+c] = result 835 + for (let c = 0; c < 3; c++) { 836 + e.lg(2).i32c(c).iadd().ls(3); // off = i + c 837 + e.lg(3).ld8u().ls(4); // v = mem[off] 838 + 839 + // result = 128 + (v - 128) * factor 840 + e.f32c(128).lg(4).i2f().f32c(128).fsub().lg(0).fmul().fadd().ls(5); 841 + 842 + // clamp: result = max(0, min(255, result)) 843 + e.lg(5).f32c(0).fmax().f32c(255).fmin().ls(5); 844 + 845 + // store 846 + e.lg(3).lg(5).f2i().st8(); 847 + } 848 + 849 + e.lg(2).i32c(4).iadd().ls(2); // i += 4 850 + e.br(0); 851 + e.end().end(); 852 + e.end(); 853 + return { locals: [[4, I32], [1, F32]], code: e.bytes() }; 854 + } 855 + 539 856 // ─── Compiler ─────────────────────────────────────────────────────── 540 857 541 858 export class Compiler { 542 859 constructor() { 543 - this.code = new E(); // bytecode for paint body 860 + this.code = new E(); 861 + this.nextLocal = 3; // params: 0=w, 1=h, 2=frame 862 + this.paintLocals = []; // [[count, type], ...] 544 863 } 545 864 546 - // Emit piece expression 865 + // Allocate a local in the paint function, returns its index 866 + allocLocal(type = F32) { 867 + const idx = this.nextLocal++; 868 + const last = this.paintLocals[this.paintLocals.length - 1]; 869 + if (last && last[1] === type) last[0]++; 870 + else this.paintLocals.push([1, type]); 871 + return idx; 872 + } 873 + 874 + // How many f32 values does this expression push? 875 + exprArity(node) { 876 + if (node.t === "num") return 1; 877 + if (node.t === "sym") { 878 + if (COLORS[node.v] || node.v === "rainbow") return 3; 879 + return 1; 880 + } 881 + if (node.t === "list") { 882 + const head = node.items[0]; 883 + if (head.t === "sym") { 884 + if (head.v === "?") return node.items.length > 1 ? this.exprArity(node.items[1]) : 1; 885 + if (head.v.match(/^\d+\.?\d*s\.\.\.$/)) return 1; 886 + } 887 + } 888 + return 1; 889 + } 890 + 547 891 compileExpr(node) { 548 - if (node.t === "num") { 549 - this.code.f32c(node.v); 550 - } else if (node.t === "sym") { 551 - this.compileSym(node.v); 552 - } else if (node.t === "list") { 553 - this.compileCall(node); 554 - } 892 + if (node.t === "num") { this.code.f32c(node.v); } 893 + else if (node.t === "sym") { this.compileSym(node.v); } 894 + else if (node.t === "list") { this.compileCall(node); } 555 895 } 556 896 557 897 compileSym(name) { ··· 559 899 if (name === "h") { this.code.lg(1); return; } 560 900 if (name === "frame" || name === "f") { this.code.lg(2); return; } 561 901 902 + // Rainbow → frame-dependent ROYGBIV color 903 + if (name === "rainbow") { this.compileRainbow(); return; } 904 + 562 905 // Division shorthand: w/2, h/3, etc. 563 906 const dm = name.match(/^(\w+)\/(\d+(?:\.\d+)?)$/); 564 - if (dm) { 565 - this.compileSym(dm[1]); 566 - this.code.f32c(parseFloat(dm[2])); 567 - this.code.fdiv(); 568 - return; 569 - } 907 + if (dm) { this.compileSym(dm[1]); this.code.f32c(parseFloat(dm[2])).fdiv(); return; } 570 908 571 909 // Multiplication shorthand: w*2, h*3, etc. 572 910 const mm = name.match(/^(\w+)\*(\d+(?:\.\d+)?)$/); 573 - if (mm) { 574 - this.compileSym(mm[1]); 575 - this.code.f32c(parseFloat(mm[2])); 576 - this.code.fmul(); 577 - return; 578 - } 911 + if (mm) { this.compileSym(mm[1]); this.code.f32c(parseFloat(mm[2])).fmul(); return; } 579 912 580 913 // Color name → 3 f32 values 581 914 if (COLORS[name]) { ··· 587 920 throw new Error(`Unknown symbol: ${name}`); 588 921 } 589 922 923 + // rainbow → frame % 7 selects from ROYGBIV, pushes 3 f32s 924 + compileRainbow() { 925 + const idxL = this.allocLocal(I32); 926 + const rL = this.allocLocal(F32); 927 + const gL = this.allocLocal(F32); 928 + const bL = this.allocLocal(F32); 929 + 930 + this.code.lg(2).f2i().i32c(7).irem().ls(idxL); 931 + 932 + // Default to first color 933 + this.code.f32c(RAINBOW[0][0]).ls(rL); 934 + this.code.f32c(RAINBOW[0][1]).ls(gL); 935 + this.code.f32c(RAINBOW[0][2]).ls(bL); 936 + 937 + for (let i = 1; i < RAINBOW.length; i++) { 938 + this.code.lg(idxL).i32c(i).ieq().if_(); 939 + this.code.f32c(RAINBOW[i][0]).ls(rL); 940 + this.code.f32c(RAINBOW[i][1]).ls(gL); 941 + this.code.f32c(RAINBOW[i][2]).ls(bL); 942 + this.code.end(); 943 + } 944 + 945 + this.code.lg(rL).lg(gL).lg(bL); 946 + } 947 + 948 + // (? a b c) → random choice, pushes 1 or 3 f32s depending on arg type 949 + compileRandom(args) { 950 + const n = args.length; 951 + if (n === 0) { this.code.f32c(0); return; } 952 + if (n === 1) { this.compileExpr(args[0]); return; } 953 + 954 + const arity = this.exprArity(args[0]); 955 + const idxL = this.allocLocal(I32); 956 + 957 + // idx = floor(random() * n) 958 + this.code.call(F_RANDOM).f32c(n).fmul().ffloor().f2i().ls(idxL); 959 + 960 + if (arity === 3) { 961 + // Color mode 962 + const rL = this.allocLocal(F32); 963 + const gL = this.allocLocal(F32); 964 + const bL = this.allocLocal(F32); 965 + 966 + this.compileColorValue(args[0]); 967 + this.code.ls(bL).ls(gL).ls(rL); 968 + 969 + for (let i = 1; i < n; i++) { 970 + this.code.lg(idxL).i32c(i).ieq().if_(); 971 + this.compileColorValue(args[i]); 972 + this.code.ls(bL).ls(gL).ls(rL); 973 + this.code.end(); 974 + } 975 + this.code.lg(rL).lg(gL).lg(bL); 976 + } else { 977 + // Scalar mode 978 + const vL = this.allocLocal(F32); 979 + 980 + this.compileExpr(args[0]); 981 + this.code.ls(vL); 982 + 983 + for (let i = 1; i < n; i++) { 984 + this.code.lg(idxL).i32c(i).ieq().if_(); 985 + this.compileExpr(args[i]); 986 + this.code.ls(vL); 987 + this.code.end(); 988 + } 989 + this.code.lg(vL); 990 + } 991 + } 992 + 993 + // Emit 3 f32s (r, g, b) for a color-producing node 994 + compileColorValue(node) { 995 + if (node.t === "sym") { 996 + if (node.v === "rainbow") { this.compileRainbow(); return; } 997 + if (COLORS[node.v]) { 998 + const [r, g, b] = COLORS[node.v]; 999 + this.code.f32c(r).f32c(g).f32c(b); 1000 + return; 1001 + } 1002 + } 1003 + if (node.t === "num") { 1004 + // Treat number as grayscale 1005 + this.code.f32c(node.v).f32c(node.v).f32c(node.v); 1006 + return; 1007 + } 1008 + if (node.t === "list") { 1009 + this.compileCall(node); 1010 + return; 1011 + } 1012 + } 1013 + 1014 + // (Ns... a b) → smooth cosine oscillation between a and b over N seconds 1015 + compileTimeInterp(periodStr, args) { 1016 + const period = parseFloat(periodStr); 1017 + const frames = Math.max(2, Math.round(period * FPS)); 1018 + 1019 + if (args.length >= 2) { 1020 + const aL = this.allocLocal(F32); 1021 + this.compileExpr(args[0]); 1022 + this.code.ls(aL); 1023 + 1024 + // result = a + (b - a) * 0.5 * (1 - cos(2π * frame / frames)) 1025 + this.compileExpr(args[1]); 1026 + this.code.lg(aL).fsub(); // b - a 1027 + this.code.f32c(0.5).fmul(); // (b-a)/2 1028 + 1029 + this.code.f32c(1); // 1.0 1030 + this.code.lg(2); // frame (f32) 1031 + this.code.f32c(2 * Math.PI / frames).fmul(); // angle 1032 + this.code.call(F_COS); // cos(angle) 1033 + this.code.fsub(); // 1 - cos(angle) 1034 + 1035 + this.code.fmul(); // (b-a)/2 * (1 - cos) 1036 + this.code.lg(aL).fadd(); // a + ... 1037 + } else if (args.length === 1) { 1038 + this.compileExpr(args[0]); 1039 + } 1040 + } 1041 + 1042 + // Inline fade: gradient fill (horizontal, compile-time color stops) 1043 + compileFadeInline(colorNames, isFirstLine) { 1044 + const names = colorNames.split("-"); 1045 + const colors = names.map(n => { 1046 + const c = COLORS[n.trim()]; 1047 + if (!c) throw new Error(`Unknown fade color: ${n}`); 1048 + return c; 1049 + }); 1050 + const numStops = colors.length; 1051 + 1052 + const yL = this.allocLocal(I32); 1053 + const xL = this.allocLocal(I32); 1054 + const tL = this.allocLocal(F32); 1055 + const segL = this.allocLocal(F32); 1056 + const idxL = this.allocLocal(I32); 1057 + const fracL = this.allocLocal(F32); 1058 + const rL = this.allocLocal(F32); 1059 + const gL = this.allocLocal(F32); 1060 + const bL = this.allocLocal(F32); 1061 + const offL = this.allocLocal(I32); 1062 + 1063 + if (isFirstLine) this.code.lg(2).f32c(0).fle().if_(); 1064 + 1065 + // for y = 0..h 1066 + this.code.i32c(0).ls(yL); 1067 + this.code.block().loop(); 1068 + this.code.lg(yL).gg(G_H).ige().brif(1); 1069 + 1070 + // for x = 0..w 1071 + this.code.i32c(0).ls(xL); 1072 + this.code.block().loop(); 1073 + this.code.lg(xL).gg(G_W).ige().brif(1); 1074 + 1075 + // t = x / max(w - 1, 1) 1076 + this.code.gg(G_W).i32c(1).isub().ls(offL); 1077 + this.code.lg(offL).ieqz().if_(); 1078 + this.code.f32c(0).ls(tL); 1079 + this.code.else_(); 1080 + this.code.lg(xL).i2f().lg(offL).i2f().fdiv().ls(tL); 1081 + this.code.end(); 1082 + 1083 + // segment = t * (numStops - 1), idx = floor, frac = segment - idx 1084 + this.code.lg(tL).f32c(numStops - 1).fmul().ls(segL); 1085 + this.code.lg(segL).ffloor().f2i().ls(idxL); 1086 + this.code.lg(segL).lg(idxL).i2f().fsub().ls(fracL); 1087 + // Clamp idx 1088 + this.code.lg(idxL).i32c(numStops - 2).igt().if_(); 1089 + this.code.i32c(numStops - 2).ls(idxL); 1090 + this.code.f32c(1).ls(fracL); 1091 + this.code.end(); 1092 + 1093 + // Branch on idx for color lerp 1094 + this.code.f32c(colors[0][0]).ls(rL); 1095 + this.code.f32c(colors[0][1]).ls(gL); 1096 + this.code.f32c(colors[0][2]).ls(bL); 1097 + 1098 + for (let i = 0; i < numStops - 1; i++) { 1099 + const c0 = colors[i], c1 = colors[i + 1]; 1100 + this.code.lg(idxL).i32c(i).ieq().if_(); 1101 + this.code.f32c(c0[0]).f32c(c1[0]).f32c(c0[0]).fsub().lg(fracL).fmul().fadd().ls(rL); 1102 + this.code.f32c(c0[1]).f32c(c1[1]).f32c(c0[1]).fsub().lg(fracL).fmul().fadd().ls(gL); 1103 + this.code.f32c(c0[2]).f32c(c1[2]).f32c(c0[2]).fsub().lg(fracL).fmul().fadd().ls(bL); 1104 + this.code.end(); 1105 + } 1106 + 1107 + // Write pixel 1108 + this.code.lg(yL).gg(G_W).imul().lg(xL).iadd().i32c(4).imul().ls(offL); 1109 + this.code.lg(offL).lg(rL).f2i().st8(); 1110 + this.code.lg(offL).i32c(1).iadd().lg(gL).f2i().st8(); 1111 + this.code.lg(offL).i32c(2).iadd().lg(bL).f2i().st8(); 1112 + this.code.lg(offL).i32c(3).iadd().i32c(255).st8(); 1113 + 1114 + this.code.lg(xL).i32c(1).iadd().ls(xL); 1115 + this.code.br(0); 1116 + this.code.end().end(); // x loop 1117 + this.code.lg(yL).i32c(1).iadd().ls(yL); 1118 + this.code.br(0); 1119 + this.code.end().end(); // y loop 1120 + 1121 + if (isFirstLine) this.code.end(); 1122 + } 1123 + 590 1124 compileCall(node) { 591 1125 if (node.items.length === 0) return; 592 1126 const head = node.items[0]; ··· 595 1129 const name = head.v; 596 1130 const args = node.items.slice(1); 597 1131 1132 + // Random choice: (? a b c) 1133 + if (name === "?") { this.compileRandom(args); return; } 1134 + 1135 + // Time interpolation: (2s... a b) → lerp 1136 + const interpMatch = name.match(/^(\d+\.?\d*)s\.\.\.$/); 1137 + if (interpMatch) { this.compileTimeInterp(interpMatch[1], args); return; } 1138 + 1139 + // Periodic execution: (0.5s expr) → run every N seconds 1140 + const periodicMatch = name.match(/^(\d+\.?\d*)s$/); 1141 + if (periodicMatch) { 1142 + const frames = Math.max(1, Math.round(parseFloat(periodicMatch[1]) * FPS)); 1143 + this.code.lg(2).f2i().i32c(frames).irem().ieqz().if_(); 1144 + for (const arg of args) { 1145 + if (arg.t === "list") this.compileCall(arg); 1146 + else this.compileExpr(arg); 1147 + } 1148 + this.code.end(); 1149 + return; 1150 + } 1151 + 598 1152 // Arithmetic 599 1153 const arith = { "+": "fadd", "-": "fsub", "*": "fmul", "/": "fdiv" }; 600 1154 if (arith[name]) { ··· 609 1163 if (name === "abs") { this.compileExpr(args[0]); this.code.fabs(); return; } 610 1164 if (name === "neg") { this.compileExpr(args[0]); this.code.fneg(); return; } 611 1165 if (name === "floor"){ this.compileExpr(args[0]); this.code.ffloor(); return; } 1166 + if (name === "sin") { this.compileExpr(args[0]); this.code.call(F_SIN); return; } 1167 + if (name === "cos") { this.compileExpr(args[0]); this.code.call(F_COS); return; } 612 1168 613 - // Drawing functions → internal function calls 1169 + // ink — special: color expressions can push 3 values + optional alpha 1170 + if (name === "ink") { 1171 + let totalArity = 0; 1172 + for (const arg of args) { 1173 + const a = this.exprArity(arg); 1174 + this.compileExpr(arg); 1175 + totalArity += a; 1176 + } 1177 + if (totalArity >= 4) { 1178 + // Stack: [r, g, b, alpha, ...extras]. Drop extras, pop alpha → G_IA 1179 + while (totalArity > 4) { this.code.drop(); totalArity--; } 1180 + this.code.f2i().gs(G_IA); 1181 + } else { 1182 + while (totalArity > 3) { this.code.drop(); totalArity--; } 1183 + this.code.i32c(255).gs(G_IA); // no alpha → fully opaque 1184 + } 1185 + this.code.call(F_INK); 1186 + return; 1187 + } 1188 + 1189 + // Drawing + transform functions 614 1190 const funcMap = { 615 - wipe: F_WIPE, ink: F_INK, plot: F_PLOT, 1191 + wipe: F_WIPE, plot: F_PLOT, 616 1192 line: F_LINE, box: F_BOX, circle: F_CIRCLE, tri: F_TRI, 1193 + scroll: F_SCROLL, spin: F_SPIN, zoom: F_ZOOM, contrast: F_CONTRAST, 617 1194 }; 618 1195 if (funcMap[name] !== undefined) { 619 1196 for (const arg of args) this.compileExpr(arg); ··· 627 1204 compile(source) { 628 1205 const ast = parse(tokenize(source)); 629 1206 630 - // Compile piece code into paint body 631 - // Paint starts by setting globals from params 632 - this.code.lg(0).f2i().gs(G_W); // width = param 0 633 - this.code.lg(1).f2i().gs(G_H); // height = param 1 1207 + // Paint params: 0=w, 1=h, 2=frame 1208 + this.code.lg(0).f2i().gs(G_W); 1209 + this.code.lg(1).f2i().gs(G_H); 634 1210 635 - for (const node of ast) { 1211 + for (let i = 0; i < ast.length; i++) { 1212 + const node = ast[i]; 1213 + const isFirstLine = i === 0; 1214 + 1215 + // fade: directive 1216 + if (node.t === "sym" && node.v.startsWith("fade:")) { 1217 + const parts = node.v.slice(5).split(":"); 1218 + this.compileFadeInline(parts[0], isFirstLine); 1219 + continue; 1220 + } 1221 + 1222 + // Bare color name → wipe 1223 + if (node.t === "sym" && COLORS[node.v]) { 1224 + const [r, g, b] = COLORS[node.v]; 1225 + if (isFirstLine) { 1226 + this.code.lg(2).f32c(0).fle().if_(); 1227 + this.code.f32c(r).f32c(g).f32c(b).call(F_WIPE); 1228 + this.code.end(); 1229 + } else { 1230 + this.code.f32c(r).f32c(g).f32c(b).call(F_WIPE); 1231 + } 1232 + continue; 1233 + } 1234 + 636 1235 if (node.t === "list") { 637 1236 this.compileCall(node); 638 - } else if (node.t === "sym" && COLORS[node.v]) { 639 - // Bare color name → wipe 640 - const [r, g, b] = COLORS[node.v]; 641 - this.code.f32c(r).f32c(g).f32c(b).call(F_WIPE); 642 1237 } 643 1238 } 644 1239 ··· 647 1242 648 1243 buildModule() { 649 1244 const out = []; 650 - 651 - // Magic + version 652 1245 out.push(0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00); 653 1246 654 1247 // ── Types ── 1248 + const T_I32_I32 = 0; // (i32,i32)→() 1249 + const T_F32_F32_F32 = 1; // (f32,f32,f32)→() 1250 + const T_F32_F32 = 2; // (f32,f32)→() 1251 + const T_F32x4 = 3; // (f32,f32,f32,f32)→() 1252 + const T_F32x6 = 4; // (f32,f32,f32,f32,f32,f32)→() 1253 + const T_F32_RET = 5; // (f32)→f32 [sin, cos] 1254 + const T_VOID_F32 = 6; // ()→f32 [random] 1255 + const T_F32_VOID = 7; // (f32)→() [spin, zoom, contrast] 1256 + 655 1257 const types = [ 656 - [0x60, 2, I32, I32, 0], // 0: (i32,i32)→() 657 - [0x60, 3, F32, F32, F32, 0], // 1: (f32,f32,f32)→() 658 - [0x60, 2, F32, F32, 0], // 2: (f32,f32)→() 659 - [0x60, 4, F32, F32, F32, F32, 0], // 3: (f32,f32,f32,f32)→() 660 - [0x60, 6, F32, F32, F32, F32, F32, F32, 0], // 4: (f32,f32,f32,f32,f32,f32)→() 1258 + [0x60, 2, I32, I32, 0], 1259 + [0x60, 3, F32, F32, F32, 0], 1260 + [0x60, 2, F32, F32, 0], 1261 + [0x60, 4, F32, F32, F32, F32, 0], 1262 + [0x60, 6, F32, F32, F32, F32, F32, F32, 0], 1263 + [0x60, 1, F32, 1, F32], 1264 + [0x60, 0, 1, F32], 1265 + [0x60, 1, F32, 0], 661 1266 ]; 662 - // Format: 0x60 paramcount paramtypes... resultcount resulttypes... 663 1267 const typeEntries = types.map(t => { 664 1268 const tag = t[0]; 665 1269 const paramCount = t[1]; ··· 670 1274 }); 671 1275 out.push(...section(1, vecOf(typeEntries))); 672 1276 673 - // ── Functions (no imports!) ── 674 - // Map each function to its type index 1277 + // ── Imports ── 1278 + const importEntries = [ 1279 + [...encodeString("math"), ...encodeString("sin"), 0x00, ...uleb128(T_F32_RET)], 1280 + [...encodeString("math"), ...encodeString("cos"), 0x00, ...uleb128(T_F32_RET)], 1281 + [...encodeString("math"), ...encodeString("random"), 0x00, ...uleb128(T_VOID_F32)], 1282 + ]; 1283 + out.push(...section(2, vecOf(importEntries))); 1284 + 1285 + // ── Functions ── 675 1286 const funcTypes = [ 676 - 0, // set_pixel: (i32,i32)→() 677 - 1, // wipe: (f32,f32,f32)→() 678 - 1, // ink: (f32,f32,f32)→() 679 - 2, // plot: (f32,f32)→() 680 - 3, // line: (f32,f32,f32,f32)→() 681 - 3, // box: (f32,f32,f32,f32)→() 682 - 1, // circle: (f32,f32,f32)→() 683 - 4, // tri: (f32,f32,f32,f32,f32,f32)→() 684 - 1, // paint: (f32,f32,f32)→() 1287 + T_I32_I32, // set_pixel 1288 + T_F32_F32_F32, // wipe 1289 + T_F32_F32_F32, // ink 1290 + T_F32_F32, // plot 1291 + T_F32x4, // line 1292 + T_F32x4, // box 1293 + T_F32_F32_F32, // circle 1294 + T_F32x6, // tri 1295 + T_F32_F32, // scroll 1296 + T_F32_VOID, // spin 1297 + T_F32_VOID, // zoom 1298 + T_F32_VOID, // contrast 1299 + T_F32_F32_F32, // paint 685 1300 ]; 686 1301 out.push(...section(3, vecOf(funcTypes.map(t => [...uleb128(t)])))); 687 1302 688 1303 // ── Memory ── 689 - // 16 pages = 1MB, enough for 512x512 RGBA 690 - out.push(...section(5, vecOf([[0x00, ...uleb128(16)]]))); 1304 + out.push(...section(5, vecOf([[0x00, ...uleb128(32)]]))); 691 1305 692 1306 // ── Globals ── 693 1307 const globals = [ 694 - [I32, 0x01, 0x41, ...sleb128(0), 0x0b], // width: i32 mut = 0 695 - [I32, 0x01, 0x41, ...sleb128(0), 0x0b], // height: i32 mut = 0 696 - [I32, 0x01, 0x41, ...sleb128(255), 0x0b], // ink_r: i32 mut = 255 697 - [I32, 0x01, 0x41, ...sleb128(255), 0x0b], // ink_g: i32 mut = 255 698 - [I32, 0x01, 0x41, ...sleb128(255), 0x0b], // ink_b: i32 mut = 255 1308 + [I32, 0x01, 0x41, ...sleb128(0), 0x0b], // G_W: width 1309 + [I32, 0x01, 0x41, ...sleb128(0), 0x0b], // G_H: height 1310 + [I32, 0x01, 0x41, ...sleb128(255), 0x0b], // G_IR: ink red 1311 + [I32, 0x01, 0x41, ...sleb128(255), 0x0b], // G_IG: ink green 1312 + [I32, 0x01, 0x41, ...sleb128(255), 0x0b], // G_IB: ink blue 1313 + [I32, 0x01, 0x41, ...sleb128(255), 0x0b], // G_IA: ink alpha 1314 + [F32, 0x01, 0x43, ...f32Bytes(0), 0x0b], // G_SAX: scroll accum X 1315 + [F32, 0x01, 0x43, ...f32Bytes(0), 0x0b], // G_SAY: scroll accum Y 699 1316 ]; 700 1317 out.push(...section(6, vecOf(globals))); 701 1318 ··· 708 1325 709 1326 // ── Code ── 710 1327 const runtimeFuncs = [ 711 - emitSetPixel(), // 0 712 - emitWipe(), // 1 713 - emitInk(), // 2 714 - emitPlot(), // 3 715 - emitLine(), // 4 716 - emitBox(), // 5 717 - emitCircle(), // 6 718 - emitTri(), // 7 1328 + emitSetPixel(), 1329 + emitWipe(), 1330 + emitInk(), 1331 + emitPlot(), 1332 + emitLine(), 1333 + emitBox(), 1334 + emitCircle(), 1335 + emitTri(), 1336 + emitScroll(), 1337 + emitSpin(), 1338 + emitZoom(), 1339 + emitContrast(), 719 1340 ]; 720 1341 721 - // Paint function body 722 - const paintBody = { locals: [], code: [...this.code.bytes(), 0x0b] }; 723 - 1342 + const paintBody = { locals: this.paintLocals, code: [...this.code.bytes(), 0x0b] }; 724 1343 const allFuncs = [...runtimeFuncs, paintBody]; 725 1344 726 1345 const codeBodies = allFuncs.map(fn => { 727 - // Local declarations: groups of (count, type) 728 1346 const localDecl = fn.locals.length > 0 729 1347 ? [...uleb128(fn.locals.length), ...fn.locals.flatMap(([count, type]) => [...uleb128(count), type])] 730 1348 : [0x00]; ··· 733 1351 }); 734 1352 735 1353 out.push(...section(10, vecOf(codeBodies))); 736 - 737 1354 return new Uint8Array(out); 738 1355 } 739 1356 }
+15
kidlisp-wasm/orbit.lisp
··· 1 + wipe 5 5 15 2 + ; trailing circles orbit center 3 + ink 255 60 60 4 + circle (+ w/2 (* 80 (cos (/ f 10)))) (+ h/2 (* 80 (sin (/ f 10)))) 12 5 + ink 60 200 255 6 + circle (+ w/2 (* 60 (cos (/ f 7)))) (+ h/2 (* 60 (sin (/ f 7)))) 10 7 + ink 100 255 100 8 + circle (+ w/2 (* 40 (cos (/ f 5)))) (+ h/2 (* 40 (sin (/ f 5)))) 8 9 + ; center dot 10 + ink 255 255 200 11 + circle w/2 h/2 5 12 + ; crosshairs 13 + ink 40 40 60 14 + line 0 h/2 w h/2 15 + line w/2 0 w/2 h
+7
kidlisp-wasm/pulse.lisp
··· 1 + wipe 0 0 0 2 + ink 200 50 255 3 + circle w/2 h/2 (+ 30 (* 25 (sin (/ f 6)))) 4 + ink 50 200 255 5 + circle w/2 h/2 (+ 20 (* 15 (sin (/ f 4)))) 6 + ink 255 255 255 7 + circle w/2 h/2 (+ 5 (* 5 (sin (/ f 3))))
+8 -1
kidlisp-wasm/render.mjs
··· 22 22 23 23 const compiler = new Compiler(); 24 24 const wasmBytes = compiler.compile(source); 25 - const { instance } = await WebAssembly.instantiate(wasmBytes, {}); 25 + const mathImports = { 26 + math: { 27 + sin: (x) => Math.fround(Math.sin(x)), 28 + cos: (x) => Math.fround(Math.cos(x)), 29 + random: () => Math.fround(Math.random()), 30 + }, 31 + }; 32 + const { instance } = await WebAssembly.instantiate(wasmBytes, mathImports); 26 33 instance.exports.paint(WIDTH, HEIGHT, 0); 27 34 28 35 const mem = new Uint8Array(instance.exports.memory.buffer);
+8
kidlisp-wasm/roz.lisp
··· 1 + fade:red-blue-black-blue-red 2 + ink (? rainbow white 0) (1s... 24 64) 3 + line w/2 0 w/2 h 4 + (spin (2s... -1.125 1.125)) (zoom 1.1) 5 + (0.5s (contrast 1.05)) 6 + (scroll (? -0.1 0 0.1) (? -0.1 0 0.1)) 7 + ink (? cyan yellow magenta) 8 8 + circle w/2 h/2 (? 2 4 8)
kidlisp-wasm/roz.ppm

This is a binary file and will not be displayed.

+8 -2
kidlisp-wasm/run.mjs
··· 18 18 const wasmBytes = compiler.compile(source); 19 19 console.log(`WASM binary: ${wasmBytes.length} bytes (self-contained renderer)`); 20 20 21 - // Instantiate — NO imports. The module has everything. 22 - const { instance } = await WebAssembly.instantiate(wasmBytes, {}); 21 + // Instantiate — math imports only, rendering is self-contained. 22 + const { instance } = await WebAssembly.instantiate(wasmBytes, { 23 + math: { 24 + sin: (x) => Math.fround(Math.sin(x)), 25 + cos: (x) => Math.fround(Math.cos(x)), 26 + random: () => Math.fround(Math.random()), 27 + }, 28 + }); 23 29 24 30 console.log(`Running paint(${WIDTH}, ${HEIGHT}, 0)...`); 25 31 instance.exports.paint(WIDTH, HEIGHT, 0);
+58
kidlisp-wasm/runtime.mjs
··· 1 + import { readFileSync } from "fs"; 2 + import { basename } from "path"; 3 + import { Compiler } from "./compiler.mjs"; 4 + 5 + export function hashString(text) { 6 + let hash = 0x811c9dc5; 7 + for (let i = 0; i < text.length; i += 1) { 8 + hash ^= text.charCodeAt(i); 9 + hash = Math.imul(hash, 0x01000193); 10 + } 11 + return hash >>> 0; 12 + } 13 + 14 + export function createSeededRandom(seed) { 15 + let state = (seed >>> 0) || 1; 16 + return () => { 17 + state ^= state << 13; 18 + state ^= state >>> 17; 19 + state ^= state << 5; 20 + return (state >>> 0) / 0x100000000; 21 + }; 22 + } 23 + 24 + export function createMathImports(random = Math.random) { 25 + return { 26 + math: { 27 + sin: (x) => Math.fround(Math.sin(x)), 28 + cos: (x) => Math.fround(Math.cos(x)), 29 + random: () => Math.fround(random()), 30 + }, 31 + }; 32 + } 33 + 34 + export function loadPiece(input) { 35 + const path = new URL(input, import.meta.url).pathname; 36 + const source = readFileSync(path, "utf-8"); 37 + return { 38 + input, 39 + path, 40 + source, 41 + name: basename(input, ".lisp"), 42 + }; 43 + } 44 + 45 + export async function instantiatePiece(source, options = {}) { 46 + const compiler = new Compiler(); 47 + const wasmBytes = compiler.compile(source); 48 + const seed = options.seed ?? hashString(source); 49 + const random = options.random ?? createSeededRandom(seed); 50 + const { instance } = await WebAssembly.instantiate(wasmBytes, createMathImports(random)); 51 + return { instance, wasmBytes, seed }; 52 + } 53 + 54 + export function renderFrame(instance, width, height, frame) { 55 + instance.exports.paint(width, height, frame); 56 + const byteLength = width * height * 4; 57 + return new Uint8Array(instance.exports.memory.buffer, 0, byteLength).slice(); 58 + }
+8
kidlisp-wasm/trail.lisp
··· 1 + black 2 + ink 255 60 60 3 + circle (+ w/2 (* 80 (cos (/ f 10)))) (+ h/2 (* 80 (sin (/ f 10)))) 6 4 + ink 60 200 255 5 + circle (+ w/2 (* 60 (cos (/ f 7)))) (+ h/2 (* 60 (sin (/ f 7)))) 5 6 + ink 100 255 100 7 + circle (+ w/2 (* 40 (cos (/ f 5)))) (+ h/2 (* 40 (sin (/ f 5)))) 4 8 + scroll 1 0
+11
kidlisp-wasm/wave.lisp
··· 1 + wipe 15 15 35 2 + ink 80 180 255 3 + box 0 (+ h/2 (* 30 (sin (/ f 8)))) w 4 4 + box 0 (+ h/2 (* 30 (sin (+ 1 (/ f 8))))) w 4 5 + box 0 (+ h/2 (* 30 (sin (+ 2 (/ f 8))))) w 4 6 + ink 255 120 80 7 + box 0 (+ h/2 (* 20 (cos (/ f 6)))) w 3 8 + box 0 (+ h/2 (* 20 (cos (+ 1.5 (/ f 6))))) w 3 9 + ink 100 255 150 10 + box 0 (+ h/2 (* 40 (sin (/ f 12)))) w 2 11 + box 0 (+ h/2 (* 40 (sin (+ 3 (/ f 12))))) w 2