apps/ios/Snowbound/Notebooks.swift | 85 +++- arc/canvas.md | 27 ++ arc/file-format.md | 13 +- arc/sync.md | 54 ++- corpus/ink-tools/README.md | 55 +++ corpus/ink-tools/drawn/candidate/Open Notebook.onetoc2 | Bin 0 -> 1596 bytes corpus/ink-tools/drawn/candidate/ink.one | Bin 0 -> 11656 bytes corpus/ink-tools/drawn/cold/commands.jsonl | 3 + corpus/ink-tools/drawn/cold/machine.json | 1 + corpus/ink-tools/drawn/cold/notebook/Open Notebook.onetoc2 | Bin 0 -> 3748 bytes corpus/ink-tools/drawn/cold/notebook/ink.one | Bin 0 -> 11656 bytes corpus/ink-tools/drawn/cold/read/environment.json | 7 + corpus/ink-tools/drawn/cold/read/hierarchy.xml | 2 + corpus/ink-tools/drawn/cold/read/page-000.navigation.json | 13 + corpus/ink-tools/drawn/cold/read/page-000.png | Bin 0 -> 44020 bytes corpus/ink-tools/drawn/cold/read/page-000.xml | 19 + corpus/ink-tools/drawn/cold/read/payloads.json | 3 + corpus/ink-tools/drawn/cold/run.json | 18 + corpus/ink-tools/drawn/cold/scripts/cold.ps1 | 27 ++ corpus/ink-tools/drawn/cold/scripts/read.ps1 | 144 ++++++ corpus/ink-tools/drawn/cold/source.json | 14 + corpus/ink-tools/drawn/cold/teardown.json | 1 + corpus/ink-tools/edited/candidate/Open Notebook.onetoc2 | Bin 0 -> 1596 bytes corpus/ink-tools/edited/candidate/ink.one | Bin 0 -> 86952 bytes corpus/ink-tools/edited/cold/commands.jsonl | 3 + corpus/ink-tools/edited/cold/machine.json | 1 + corpus/ink-tools/edited/cold/notebook/Open Notebook.onetoc2 | Bin 0 -> 3748 bytes corpus/ink-tools/edited/cold/notebook/ink.one | Bin 0 -> 86952 bytes corpus/ink-tools/edited/cold/read/environment.json | 7 + corpus/ink-tools/edited/cold/read/hierarchy.xml | 2 + corpus/ink-tools/edited/cold/read/page-000.navigation.json | 13 + corpus/ink-tools/edited/cold/read/page-000.png | Bin 0 -> 46557 bytes corpus/ink-tools/edited/cold/read/page-000.xml | 24 + corpus/ink-tools/edited/cold/read/page-001.navigation.json | 13 + corpus/ink-tools/edited/cold/read/page-001.png | Bin 0 -> 42240 bytes corpus/ink-tools/edited/cold/read/page-001.xml | 7 + corpus/ink-tools/edited/cold/read/page-002.navigation.json | 13 + corpus/ink-tools/edited/cold/read/page-002.png | Bin 0 -> 42399 bytes corpus/ink-tools/edited/cold/read/page-002.xml | 15 + corpus/ink-tools/edited/cold/read/page-003.navigation.json | 13 + corpus/ink-tools/edited/cold/read/page-003.png | Bin 0 -> 42584 bytes corpus/ink-tools/edited/cold/read/page-003.xml | 75 +++ corpus/ink-tools/edited/cold/read/page-004.navigation.json | 13 + corpus/ink-tools/edited/cold/read/page-004.png | Bin 0 -> 45358 bytes corpus/ink-tools/edited/cold/read/page-004.xml | 46 ++ corpus/ink-tools/edited/cold/read/payloads.json | 3 + corpus/ink-tools/edited/cold/run.json | 18 + corpus/ink-tools/edited/cold/scripts/cold.ps1 | 27 ++ corpus/ink-tools/edited/cold/scripts/read.ps1 | 144 ++++++ corpus/ink-tools/edited/cold/source.json | 14 + corpus/ink-tools/edited/cold/teardown.json | 1 + corpus/ink-tools/native-ui/commands.jsonl | 3 + corpus/ink-tools/native-ui/machine.json | 1 + corpus/ink-tools/native-ui/read/environment.json | 7 + corpus/ink-tools/native-ui/read/hierarchy.xml | 2 + corpus/ink-tools/native-ui/read/page-000.navigation.json | 13 + corpus/ink-tools/native-ui/read/page-000.png | Bin 0 -> 46536 bytes corpus/ink-tools/native-ui/read/page-000.xml | 24 + corpus/ink-tools/native-ui/read/page-001.navigation.json | 13 + corpus/ink-tools/native-ui/read/page-001.png | Bin 0 -> 42379 bytes corpus/ink-tools/native-ui/read/page-001.xml | 15 + corpus/ink-tools/native-ui/read/page-002.navigation.json | 13 + corpus/ink-tools/native-ui/read/page-002.png | Bin 0 -> 42221 bytes corpus/ink-tools/native-ui/read/page-002.xml | 7 + corpus/ink-tools/native-ui/read/page-003.navigation.json | 13 + corpus/ink-tools/native-ui/read/page-003.png | Bin 0 -> 42564 bytes corpus/ink-tools/native-ui/read/page-003.xml | 75 +++ corpus/ink-tools/native-ui/read/page-004.navigation.json | 13 + corpus/ink-tools/native-ui/read/page-004.png | Bin 0 -> 45175 bytes corpus/ink-tools/native-ui/read/page-004.xml | 39 ++ corpus/ink-tools/native-ui/read/payloads.json | 3 + corpus/ink-tools/native-ui/run.json | 18 + corpus/ink-tools/native-ui/scripts/cold.ps1 | 27 ++ corpus/ink-tools/native-ui/scripts/read.ps1 | 144 ++++++ corpus/ink-tools/native-ui/source.json | 14 + corpus/ink-tools/native-ui/teardown.json | 1 + corpus/media-edit/README.md | 3 +- corpus/recording/README.md | 65 +++ corpus/recording/candidate/Open Notebook.onetoc2 | Bin 0 -> 1604 bytes corpus/recording/candidate/Recorded.one | Bin 0 -> 26848 bytes corpus/recording/cold/commands.jsonl | 3 + corpus/recording/cold/machine.json | 1 + corpus/recording/cold/notebook/Open Notebook.onetoc2 | Bin 0 -> 3764 bytes corpus/recording/cold/notebook/Recorded.one | Bin 0 -> 28344 bytes corpus/recording/cold/read/36b0ffb210410ba1e1afffb66c6817f76261c422c4a083ab7f721cb94b186087.attachment | Bin 0 -> 16444 bytes corpus/recording/cold/read/environment.json | 7 + corpus/recording/cold/read/hierarchy.xml | 2 + corpus/recording/cold/read/page-000.navigation.json | 13 + corpus/recording/cold/read/page-000.png | Bin 0 -> 45564 bytes corpus/recording/cold/read/page-000.xml | 2 + corpus/recording/cold/read/payloads.json | 10 + corpus/recording/cold/run.json | 18 + corpus/recording/cold/scripts/cold.ps1 | 27 ++ corpus/recording/cold/scripts/read.ps1 | 144 ++++++ corpus/recording/cold/source.json | 14 + corpus/recording/cold/teardown.json | 1 + corpus/recording/edit/candidate/Open Notebook.onetoc2 | Bin 0 -> 3764 bytes corpus/recording/edit/candidate/files.one | Bin 0 -> 82304 bytes corpus/recording/edit/cold/commands.jsonl | 3 + corpus/recording/edit/cold/machine.json | 1 + corpus/recording/edit/cold/notebook/Open Notebook.onetoc2 | Bin 0 -> 3764 bytes corpus/recording/edit/cold/notebook/files.one | Bin 0 -> 82304 bytes corpus/recording/edit/cold/read/b20a14e044e33eac39b4665e7d79813b8a3672dbbd27ed9d2e4ac866c13ec4b6.attachment | 1 + corpus/recording/edit/cold/read/c41bd6bd61277bdc4bf3557b5572be5c08451ba5b4665aba662ac1280d907ca3.attachment | Bin 0 -> 24827 bytes corpus/recording/edit/cold/read/environment.json | 7 + corpus/recording/edit/cold/read/hierarchy.xml | 2 + corpus/recording/edit/cold/read/page-000.navigation.json | 13 + corpus/recording/edit/cold/read/page-000.png | Bin 0 -> 47800 bytes corpus/recording/edit/cold/read/page-000.xml | 2 + corpus/recording/edit/cold/read/page-001.navigation.json | 13 + corpus/recording/edit/cold/read/page-001.png | Bin 0 -> 41400 bytes corpus/recording/edit/cold/read/page-001.xml | 2 + corpus/recording/edit/cold/read/payloads.json | 18 + corpus/recording/edit/cold/run.json | 18 + corpus/recording/edit/cold/scripts/cold.ps1 | 27 ++ corpus/recording/edit/cold/scripts/read.ps1 | 144 ++++++ corpus/recording/edit/cold/source.json | 14 + corpus/recording/edit/cold/teardown.json | 1 + corpus/recording/native/attached/files.one | Bin 0 -> 78616 bytes corpus/recording/native/deleted/files.one | Bin 0 -> 57960 bytes corpus/recording/native/notebook/Open Notebook.onetoc2 | Bin 0 -> 3764 bytes corpus/recording/native/notebook/files.one | Bin 0 -> 51208 bytes corpus/recording/native/read/onenote-linked-notes.png | Bin 0 -> 49251 bytes corpus/recording/native/read/onenote-plays-ima-adpcm.png | Bin 0 -> 58361 bytes corpus/recording/native/read/onenote-recording-tab.png | Bin 0 -> 55895 bytes corpus/recording/native/read/page-recorded.xml | 3 + corpus/recording/played-from-note.png | Bin 0 -> 56750 bytes crates/canvas/src/editor.rs | 50 +- crates/canvas/src/editor/ink.rs | 450 +++++++++++++++++ crates/canvas/src/editor/recording.rs | 284 +++++++++++ crates/canvas/src/gpu/page.rs | 97 ++-- crates/canvas/src/interaction/ink.rs | 326 +++++++++++++ crates/canvas/src/interaction/mod.rs | 107 ++++- crates/canvas/src/outline.rs | 2 + crates/canvas/tests/ink_tools.rs | 287 +++++++++++ crates/canvas/tests/ops_differential.rs | 153 +++++- crates/canvas/tests/recording.rs | 187 ++++++++ crates/draw/src/render.rs | 24 + crates/draw/src/render/gl.rs | 4 + crates/draw/src/render/webgpu.rs | 17 + crates/mobile/include/snowbound.h | 6 +- crates/mobile/src/lib.rs | 88 +++- crates/mobile/src/library.rs | 40 +- crates/mobile/src/tests.rs | 129 ++++- crates/notebook/README.md | 46 +- crates/notebook/examples/launch_probe.rs | 228 --------- crates/notebook/src/background.rs | 827 ++++++++++++++++++++++++++------ crates/notebook/src/discover.rs | 377 ++++++++++----- crates/notebook/src/discover/source.rs | 40 +- crates/notebook/src/lib.rs | 34 +- crates/notebook/src/session.rs | 131 +++-- crates/notebook/src/smb/directory.rs | 10 +- crates/notebook/src/smb/mod.rs | 5 + crates/notebook/src/worker.rs | 23 +- crates/notebook/tests/discovery.rs | 81 +++- crates/notebook/tests/session.rs | 124 ++++- crates/onestore/README.md | 4 +- crates/onestore/examples/ink_lab.rs | 25 - crates/onestore/examples/scratch_dump.rs | 29 -- crates/onestore/src/op/apply.rs | 11 +- crates/onestore/src/op/content.rs | 20 +- crates/onestore/src/page/ink.rs | 12 +- crates/onestore/src/page/text.rs | 5 + crates/onestore/tests/page_ink.rs | 44 +- crates/onestore/tests/page_media.rs | 114 ++++- crates/snowbound/assets/icons/eraser.svg | 11 + crates/snowbound/assets/icons/lasso.svg | 4 + crates/snowbound/assets/icons/pen.svg | 11 + crates/snowbound/assets/icons/select.svg | 5 + crates/snowbound/assets/icons/shape-arrow.svg | 3 + crates/snowbound/assets/icons/shape-line.svg | 3 + crates/snowbound/assets/icons/shape-oval.svg | 3 + crates/snowbound/assets/icons/shape-rectangle.svg | 3 + crates/snowbound/assets/icons/shapes.svg | 8 + crates/snowbound/src/art.rs | 10 + crates/snowbound/src/attachment.rs | 34 +- crates/snowbound/src/commands.rs | 93 +++- crates/snowbound/src/library.rs | 54 ++- crates/snowbound/src/main.rs | 185 ++++++- crates/snowbound/src/media_linux.rs | 270 +++++++++++ crates/snowbound/src/media_macos.rs | 182 +++++++ crates/snowbound/src/pane.rs | 4 +- crates/snowbound/src/recording.rs | 687 ++++++++++++++++++++++++++ crates/snowbound/src/search.rs | 54 ++- crates/snowbound/src/settings.rs | 4 + crates/snowbound/src/watch.rs | 121 +++-- tools/canvas/build_macos.py | 1 + tools/test_ink_tools.py | 82 ++++ tools/test_recording.py | 88 ++++ tools/verify-document.py | 3 + 190 files changed, 7478 insertions(+), 848 deletions(-)