apps/ios/Info.plist | 37 + apps/ios/Snowbound/App.swift | 64 ++ apps/ios/Snowbound/CanvasView.swift | 23 + apps/ios/Snowbound/FormatBar.swift | 21 + apps/ios/Snowbound/ICloud.swift | 15 +- apps/ios/Snowbound/Ink.swift | 8 +- apps/ios/Snowbound/Lists.swift | 35 +- apps/ios/Snowbound/Notebooks.swift | 45 +- apps/ios/Snowbound/PageViewController.swift | 72 ++ arc/canvas.md | 78 +- arc/sync.md | 14 +- arc/ui.md | 7 +- corpus/default-font/README.md | 21 + corpus/default-font/candidate/Open Notebook.onetoc2 | Bin 0 -> 1604 bytes corpus/default-font/candidate/fonts.one | Bin 0 -> 9824 bytes corpus/default-font/cold/page.png | Bin 0 -> 41961 bytes corpus/default-font/cold/page.xml | 2 + corpus/default-font/native/Color.one | Bin 0 -> 24576 bytes corpus/default-font/native/Lab.one | Bin 0 -> 25896 bytes corpus/default-font/native/color.png | Bin 0 -> 42379 bytes corpus/default-font/native/options-font-color.png | Bin 0 -> 42587 bytes corpus/object-tags/README.md | 27 + corpus/object-tags/candidate/Open Notebook.onetoc2 | Bin 0 -> 1604 bytes corpus/object-tags/candidate/files.one | Bin 0 -> 59048 bytes corpus/object-tags/cold/commands.jsonl | 3 + corpus/object-tags/cold/machine.json | 1 + corpus/object-tags/cold/notebook/Open Notebook.onetoc2 | Bin 0 -> 3764 bytes corpus/object-tags/cold/notebook/files.one | Bin 0 -> 59048 bytes corpus/object-tags/cold/read/32a01b6d0a94deebc53c688868b14b6fccc4e18b3b64ea052823e3856cf35b89.attachment | 1 + corpus/object-tags/cold/read/33fdf6e43c05ed910d335eda3fa269ccbd1415336c17a4a5357d009ee495b3a6.attachment | 1 + corpus/object-tags/cold/read/environment.json | 7 + corpus/object-tags/cold/read/hierarchy.xml | 2 + corpus/object-tags/cold/read/page-000.navigation.json | 13 + corpus/object-tags/cold/read/page-000.png | Bin 0 -> 48662 bytes corpus/object-tags/cold/read/page-000.xml | 194 ++++ corpus/object-tags/cold/read/page-001.navigation.json | 13 + corpus/object-tags/cold/read/page-001.png | Bin 0 -> 43406 bytes corpus/object-tags/cold/read/page-001.xml | 2 + corpus/object-tags/cold/read/page-002.navigation.json | 13 + corpus/object-tags/cold/read/page-002.png | Bin 0 -> 43531 bytes corpus/object-tags/cold/read/page-002.xml | 3 + corpus/object-tags/cold/read/page-003.navigation.json | 13 + corpus/object-tags/cold/read/page-003.png | Bin 0 -> 41909 bytes corpus/object-tags/cold/read/page-003.xml | 2 + corpus/object-tags/cold/read/payloads.json | 34 + corpus/object-tags/cold/run.json | 18 + corpus/object-tags/cold/scripts/cold.ps1 | 27 + corpus/object-tags/cold/scripts/read.ps1 | 144 +++ corpus/object-tags/cold/source.json | 14 + corpus/object-tags/cold/teardown.json | 1 + corpus/object-tags/native/commands.jsonl | 7 + corpus/object-tags/native/machine.json | 1 + corpus/object-tags/native/notebook/Open Notebook.onetoc2 | Bin 0 -> 4792 bytes corpus/object-tags/native/notebook/files.one | Bin 0 -> 56232 bytes corpus/object-tags/native/notebook/notes.txt | 1 + corpus/object-tags/native/notebook/ocr.png | Bin 0 -> 9598 bytes corpus/object-tags/native/notebook/photo.png | Bin 0 -> 659 bytes corpus/object-tags/native/read/32a01b6d0a94deebc53c688868b14b6fccc4e18b3b64ea052823e3856cf35b89.attachment | 1 + corpus/object-tags/native/read/33fdf6e43c05ed910d335eda3fa269ccbd1415336c17a4a5357d009ee495b3a6.attachment | 1 + corpus/object-tags/native/read/environment.json | 7 + corpus/object-tags/native/read/hierarchy.xml | 2 + corpus/object-tags/native/read/page-000.xml | 2 + corpus/object-tags/native/read/page-001.xml | 194 ++++ corpus/object-tags/native/read/page-002.xml | 3 + corpus/object-tags/native/read/page-003.xml | 2 + corpus/object-tags/native/read/payloads.json | 34 + corpus/object-tags/native/run.json | 19 + corpus/object-tags/native/scripts/author.ps1 | 37 + corpus/object-tags/native/scripts/cold.ps1 | 27 + corpus/object-tags/native/scripts/read.ps1 | 144 +++ corpus/object-tags/native/source.json | 26 + corpus/object-tags/native/teardown.json | 1 + corpus/object-tags/restored/candidate/Open Notebook.onetoc2 | Bin 0 -> 1604 bytes corpus/object-tags/restored/candidate/files.one | Bin 0 -> 67592 bytes corpus/object-tags/restored/cold/commands.jsonl | 3 + corpus/object-tags/restored/cold/machine.json | 1 + corpus/object-tags/restored/cold/notebook/Open Notebook.onetoc2 | Bin 0 -> 3764 bytes corpus/object-tags/restored/cold/notebook/files.one | Bin 0 -> 67592 bytes corpus/object-tags/restored/cold/read/32a01b6d0a94deebc53c688868b14b6fccc4e18b3b64ea052823e3856cf35b89.attachment | 1 + corpus/object-tags/restored/cold/read/33fdf6e43c05ed910d335eda3fa269ccbd1415336c17a4a5357d009ee495b3a6.attachment | 1 + corpus/object-tags/restored/cold/read/environment.json | 7 + corpus/object-tags/restored/cold/read/hierarchy.xml | 2 + corpus/object-tags/restored/cold/read/page-000.navigation.json | 13 + corpus/object-tags/restored/cold/read/page-000.png | Bin 0 -> 43521 bytes corpus/object-tags/restored/cold/read/page-000.xml | 3 + corpus/object-tags/restored/cold/read/page-001.navigation.json | 13 + corpus/object-tags/restored/cold/read/page-001.png | Bin 0 -> 41885 bytes corpus/object-tags/restored/cold/read/page-001.xml | 2 + corpus/object-tags/restored/cold/read/page-002.navigation.json | 13 + corpus/object-tags/restored/cold/read/page-002.png | Bin 0 -> 43374 bytes corpus/object-tags/restored/cold/read/page-002.xml | 2 + corpus/object-tags/restored/cold/read/page-003.navigation.json | 13 + corpus/object-tags/restored/cold/read/page-003.png | Bin 0 -> 48335 bytes corpus/object-tags/restored/cold/read/page-003.xml | 194 ++++ corpus/object-tags/restored/cold/read/payloads.json | 34 + corpus/object-tags/restored/cold/run.json | 18 + corpus/object-tags/restored/cold/scripts/cold.ps1 | 27 + corpus/object-tags/restored/cold/scripts/read.ps1 | 144 +++ corpus/object-tags/restored/cold/source.json | 14 + corpus/object-tags/restored/cold/teardown.json | 1 + corpus/picture-link/README.md | 15 + corpus/picture-link/candidate/Features.one | Bin 0 -> 123080 bytes corpus/picture-link/candidate/Open Notebook.onetoc2 | Bin 0 -> 1604 bytes corpus/picture-link/cold/commands.jsonl | 3 + corpus/picture-link/cold/machine.json | 1 + corpus/picture-link/cold/notebook/Features.one | Bin 0 -> 123080 bytes corpus/picture-link/cold/notebook/Open Notebook.onetoc2 | Bin 0 -> 3764 bytes corpus/picture-link/cold/read/4cff0039dbdf53a59f5f4e4592c29a5297ea3b7acce24415c0ae83c36c6bd7c2.attachment | Bin 0 -> 27 bytes corpus/picture-link/cold/read/56d4af65701c26df20bd4021eda95b6e830348ce3a746086079fe89285548dc9.attachment | Bin 0 -> 16044 bytes corpus/picture-link/cold/read/environment.json | 7 + corpus/picture-link/cold/read/hierarchy.xml | 2 + corpus/picture-link/cold/read/page-000.xml | 46 + corpus/picture-link/cold/read/page-001.xml | 6 + corpus/picture-link/cold/read/page-002.xml | 6 + corpus/picture-link/cold/read/page-003.xml | 9 + corpus/picture-link/cold/read/page-004.xml | 2 + corpus/picture-link/cold/read/page-005.xml | 6 + corpus/picture-link/cold/read/page-006.xml | 4 + corpus/picture-link/cold/read/page-007.xml | 6 + corpus/picture-link/cold/read/page-008.xml | 2 + corpus/picture-link/cold/read/page-009.xml | 2 + corpus/picture-link/cold/read/page-010.xml | 300 ++++++ corpus/picture-link/cold/read/page-011.xml | 21 + corpus/picture-link/cold/read/page-012.xml | 6 + corpus/picture-link/cold/read/payloads.json | 18 + corpus/picture-link/cold/run.json | 18 + corpus/picture-link/cold/scripts/cold.ps1 | 27 + corpus/picture-link/cold/scripts/read.ps1 | 144 +++ corpus/picture-link/cold/source.json | 14 + corpus/picture-link/cold/teardown.json | 1 + corpus/picture-link/lab/click-selects.png | Bin 0 -> 70567 bytes corpus/picture-link/lab/ctrl-click.png | Bin 0 -> 64059 bytes corpus/picture-link/lab/hover.png | Bin 0 -> 81083 bytes corpus/printout/README.md | 10 +- corpus/printout/candidate/Open Notebook.onetoc2 | Bin 1612 -> 1612 bytes corpus/printout/candidate/Printouts.one | Bin 268208 -> 443488 bytes corpus/printout/cold/commands.jsonl | 2 +- corpus/printout/cold/machine.json | 2 +- corpus/printout/cold/notebook/Open Notebook.onetoc2 | Bin 3780 -> 3780 bytes corpus/printout/cold/notebook/Printouts.one | Bin 268208 -> 443488 bytes corpus/printout/cold/read/environment.json | 2 +- corpus/printout/cold/read/hierarchy.xml | 2 +- corpus/printout/cold/read/page-000.navigation.json | 2 +- corpus/printout/cold/read/page-000.pdf | Bin 0 -> 180183 bytes corpus/printout/cold/read/page-000.png | Bin 44757 -> 47220 bytes corpus/printout/cold/read/page-000.xml | 598 ++++++++++-- corpus/printout/cold/read/page-001.navigation.json | 2 +- corpus/printout/cold/read/page-001.pdf | Bin 0 -> 89759 bytes corpus/printout/cold/read/page-001.png | Bin 47985 -> 44700 bytes corpus/printout/cold/read/page-001.xml | 598 ++---------- corpus/printout/cold/read/payloads.json | 4 +- corpus/printout/cold/run.json | 2 +- corpus/printout/cold/source.json | 10 +- corpus/recycle-purge/README.md | 19 + corpus/recycle-purge/candidate/New Section 1.one | Bin 0 -> 6024 bytes corpus/recycle-purge/candidate/OneNote_RecycleBin/OneNote_DeletedPages.one | Bin 0 -> 7344 bytes corpus/recycle-purge/candidate/OneNote_RecycleBin/Open Notebook.onetoc2 | Bin 0 -> 4216 bytes corpus/recycle-purge/candidate/Open Notebook.onetoc2 | Bin 0 -> 5280 bytes corpus/recycle-purge/cold/hierarchy.xml | 2 + corpus/recycle-purge/cold/recycle-bin.png | Bin 0 -> 69639 bytes corpus/section-color/README.md | 19 + corpus/section-color/candidate/Apple.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Blue Mist.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Blue.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Cyan.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Green.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Lemon.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Magenta.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/New Section 1.one | Bin 0 -> 6000 bytes corpus/section-color/candidate/None.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Open Notebook.onetoc2 | Bin 0 -> 14552 bytes corpus/section-color/candidate/Orange.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Purple Mist.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Purple.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Red Chalk.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Red.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Silver.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Tan.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Teal.one | Bin 0 -> 6352 bytes corpus/section-color/candidate/Yellow.one | Bin 0 -> 6352 bytes corpus/section-color/cold/commands.jsonl | 3 + corpus/section-color/cold/machine.json | 1 + corpus/section-color/cold/read/environment.json | 7 + corpus/section-color/cold/read/hierarchy.xml | 2 + corpus/section-color/cold/read/page-000.navigation.json | 13 + corpus/section-color/cold/read/page-000.png | Bin 0 -> 43028 bytes corpus/section-color/cold/read/page-000.xml | 2 + corpus/section-color/cold/read/page-001.navigation.json | 13 + corpus/section-color/cold/read/page-001.png | Bin 0 -> 42906 bytes corpus/section-color/cold/read/page-001.xml | 2 + corpus/section-color/cold/read/page-002.navigation.json | 13 + corpus/section-color/cold/read/page-002.png | Bin 0 -> 42875 bytes corpus/section-color/cold/read/page-002.xml | 2 + corpus/section-color/cold/read/page-003.navigation.json | 13 + corpus/section-color/cold/read/page-003.png | Bin 0 -> 43343 bytes corpus/section-color/cold/read/page-003.xml | 2 + corpus/section-color/cold/read/page-004.navigation.json | 13 + corpus/section-color/cold/read/page-004.png | Bin 0 -> 42947 bytes corpus/section-color/cold/read/page-004.xml | 2 + corpus/section-color/cold/read/page-005.navigation.json | 13 + corpus/section-color/cold/read/page-005.png | Bin 0 -> 42920 bytes corpus/section-color/cold/read/page-005.xml | 2 + corpus/section-color/cold/read/page-006.navigation.json | 13 + corpus/section-color/cold/read/page-006.png | Bin 0 -> 43039 bytes corpus/section-color/cold/read/page-006.xml | 2 + corpus/section-color/cold/read/page-007.navigation.json | 13 + corpus/section-color/cold/read/page-007.png | Bin 0 -> 42698 bytes corpus/section-color/cold/read/page-007.xml | 2 + corpus/section-color/cold/read/page-008.navigation.json | 13 + corpus/section-color/cold/read/page-008.png | Bin 0 -> 42635 bytes corpus/section-color/cold/read/page-008.xml | 2 + corpus/section-color/cold/read/page-009.navigation.json | 13 + corpus/section-color/cold/read/page-009.png | Bin 0 -> 43194 bytes corpus/section-color/cold/read/page-009.xml | 2 + corpus/section-color/cold/read/page-010.navigation.json | 13 + corpus/section-color/cold/read/page-010.png | Bin 0 -> 42983 bytes corpus/section-color/cold/read/page-010.xml | 2 + corpus/section-color/cold/read/page-011.navigation.json | 13 + corpus/section-color/cold/read/page-011.png | Bin 0 -> 42792 bytes corpus/section-color/cold/read/page-011.xml | 2 + corpus/section-color/cold/read/page-012.navigation.json | 13 + corpus/section-color/cold/read/page-012.png | Bin 0 -> 42225 bytes corpus/section-color/cold/read/page-012.xml | 2 + corpus/section-color/cold/read/page-013.navigation.json | 13 + corpus/section-color/cold/read/page-013.png | Bin 0 -> 42866 bytes corpus/section-color/cold/read/page-013.xml | 2 + corpus/section-color/cold/read/page-014.navigation.json | 13 + corpus/section-color/cold/read/page-014.png | Bin 0 -> 42685 bytes corpus/section-color/cold/read/page-014.xml | 2 + corpus/section-color/cold/read/page-015.navigation.json | 13 + corpus/section-color/cold/read/page-015.png | Bin 0 -> 42662 bytes corpus/section-color/cold/read/page-015.xml | 2 + corpus/section-color/cold/read/page-016.navigation.json | 13 + corpus/section-color/cold/read/page-016.png | Bin 0 -> 42847 bytes corpus/section-color/cold/read/page-016.xml | 2 + corpus/section-color/cold/read/page-017.navigation.json | 13 + corpus/section-color/cold/read/page-017.png | Bin 0 -> 42794 bytes corpus/section-color/cold/read/page-017.xml | 2 + corpus/section-color/cold/read/payloads.json | 3 + corpus/section-color/cold/run.json | 18 + corpus/section-color/cold/scripts/cold.ps1 | 27 + corpus/section-color/cold/scripts/read.ps1 | 144 +++ corpus/section-color/cold/source.json | 116 +++ corpus/section-color/cold/teardown.json | 1 + corpus/section-color/native/after.onetoc2 | Bin 0 -> 4952 bytes corpus/section-color/native/before.onetoc2 | Bin 0 -> 4912 bytes corpus/section-color/native/colors.txt | 17 + corpus/section-color/native/none.one | Bin 0 -> 16968 bytes corpus/section-color/native/notebook-colors.png | Bin 0 -> 49665 bytes corpus/section-color/native/notebook-menu.png | Bin 0 -> 49661 bytes corpus/section-color/native/notebook-properties.png | Bin 0 -> 49781 bytes corpus/section-color/native/section-color-menu.png | Bin 0 -> 50235 bytes corpus/section-color/native/section-menu.png | Bin 0 -> 50522 bytes corpus/section-color/native/teal.one | Bin 0 -> 12424 bytes corpus/styles/README.md | 27 + corpus/styles/candidate/.snowbound/themes.json | 33 + corpus/styles/candidate/Editorial.one | Bin 0 -> 12096 bytes corpus/styles/candidate/Manuscript.one | Bin 0 -> 12120 bytes corpus/styles/candidate/Modern.one | Bin 0 -> 12000 bytes corpus/styles/candidate/OneNote.one | Bin 0 -> 12072 bytes corpus/styles/candidate/Open Notebook.onetoc2 | Bin 0 -> 2036 bytes corpus/styles/cold/commands.jsonl | 4 + corpus/styles/cold/machine.json | 1 + corpus/styles/cold/notebook/Editorial.one | Bin 0 -> 12096 bytes corpus/styles/cold/notebook/Manuscript.one | Bin 0 -> 12120 bytes corpus/styles/cold/notebook/Modern.one | Bin 0 -> 12000 bytes corpus/styles/cold/notebook/OneNote.one | Bin 0 -> 12072 bytes corpus/styles/cold/notebook/Open Notebook.onetoc2 | Bin 0 -> 4476 bytes corpus/styles/cold/read/environment.json | 7 + corpus/styles/cold/read/hierarchy.xml | 2 + corpus/styles/cold/read/page-000.navigation.json | 13 + corpus/styles/cold/read/page-000.png | Bin 0 -> 53758 bytes corpus/styles/cold/read/page-000.xml | 7 + corpus/styles/cold/read/page-001.navigation.json | 13 + corpus/styles/cold/read/page-001.png | Bin 0 -> 48483 bytes corpus/styles/cold/read/page-001.xml | 8 + corpus/styles/cold/read/page-002.navigation.json | 13 + corpus/styles/cold/read/page-002.png | Bin 0 -> 50144 bytes corpus/styles/cold/read/page-002.xml | 8 + corpus/styles/cold/read/page-003.navigation.json | 13 + corpus/styles/cold/read/page-003.png | Bin 0 -> 49643 bytes corpus/styles/cold/read/page-003.xml | 10 + corpus/styles/cold/read/payloads.json | 3 + corpus/styles/cold/run.json | 19 + corpus/styles/cold/scripts/author.ps1 | 7 + corpus/styles/cold/scripts/cold.ps1 | 27 + corpus/styles/cold/scripts/read.ps1 | 144 +++ corpus/styles/cold/source.json | 38 + corpus/styles/cold/teardown.json | 1 + corpus/styles/onenote-edit/Manuscript.one | Bin 0 -> 22144 bytes corpus/styles/onenote-edit/Manuscript.png | Bin 0 -> 70113 bytes corpus/styles/onenote-edit/Manuscript.xml | 8 + corpus/styles/onenote/Styles.one | Bin 0 -> 38280 bytes corpus/styles/onenote/applied.xml | 16 + corpus/table-widths/README.md | 17 + corpus/table-widths/candidate/Open Notebook.onetoc2 | Bin 0 -> 1604 bytes corpus/table-widths/candidate/Tables.one | Bin 0 -> 35192 bytes corpus/table-widths/cold/commands.jsonl | 3 + corpus/table-widths/cold/machine.json | 1 + corpus/table-widths/cold/notebook/Open Notebook.onetoc2 | Bin 0 -> 3764 bytes corpus/table-widths/cold/notebook/Tables.one | Bin 0 -> 38080 bytes corpus/table-widths/cold/read/environment.json | 7 + corpus/table-widths/cold/read/hierarchy.xml | 2 + corpus/table-widths/cold/read/page-000.navigation.json | 13 + corpus/table-widths/cold/read/page-000.png | Bin 0 -> 46983 bytes corpus/table-widths/cold/read/page-000.xml | 2 + corpus/table-widths/cold/read/page-001.navigation.json | 13 + corpus/table-widths/cold/read/page-001.png | Bin 0 -> 44342 bytes corpus/table-widths/cold/read/page-001.xml | 2 + corpus/table-widths/cold/read/page-002.navigation.json | 13 + corpus/table-widths/cold/read/page-002.png | Bin 0 -> 46338 bytes corpus/table-widths/cold/read/page-002.xml | 2 + corpus/table-widths/cold/read/payloads.json | 3 + corpus/table-widths/cold/run.json | 18 + corpus/table-widths/cold/scripts/cold.ps1 | 27 + corpus/table-widths/cold/scripts/read.ps1 | 144 +++ corpus/table-widths/cold/source.json | 14 + corpus/table-widths/cold/teardown.json | 1 + crates/canvas/examples/print_pdf.rs | 12 +- crates/canvas/examples/scratch_eqref.rs | 667 ------------- crates/canvas/examples/scratch_files.rs | 15 - crates/canvas/examples/scratch_runs.rs | 23 - crates/canvas/examples/unsupported_inventory.rs | 19 + crates/canvas/src/editor.rs | 443 ++++++++- crates/canvas/src/editor/evidence.rs | 3 +- crates/canvas/src/editor/format.rs | 447 ++++++++- crates/canvas/src/editor/ops.rs | 23 + crates/canvas/src/editor/page.rs | 36 +- crates/canvas/src/editor/recording.rs | 3 +- crates/canvas/src/editor/table.rs | 527 ++++++++++- crates/canvas/src/gpu/page.rs | 122 ++- crates/canvas/src/gpu/page/background.rs | 10 + crates/canvas/src/gpu/profile.rs | 3 + crates/canvas/src/interaction/mod.rs | 251 ++++- crates/canvas/src/interaction/tests.rs | 189 ++++ crates/canvas/src/layout.rs | 2 + crates/canvas/src/outline.rs | 77 +- crates/canvas/src/print.rs | 184 +++- crates/canvas/src/search.rs | 40 +- crates/canvas/src/template.rs | 3 + crates/canvas/tests/attachment_insert.rs | 1 + crates/canvas/tests/default_font.rs | 122 +++ crates/canvas/tests/links_equations.rs | 16 +- crates/canvas/tests/ops_differential.rs | 204 +++- crates/canvas/tests/picture_paste.rs | 145 ++- crates/canvas/tests/pictures.rs | 463 +++++++++ crates/canvas/tests/printouts.rs | 58 +- crates/canvas/tests/recording.rs | 2 + crates/canvas/tests/table_widths.rs | 241 +++++ crates/draw/src/render.rs | 7 +- crates/draw/src/render/pdf.rs | 38 + crates/mobile/Cargo.toml | 2 +- crates/mobile/include/snowbound.h | 8 + crates/mobile/src/lib.rs | 135 ++- crates/mobile/src/library.rs | 131 ++- crates/mobile/src/tests.rs | 17 + crates/notebook/README.md | 33 +- crates/notebook/src/discover.rs | 38 +- crates/notebook/src/discover/source.rs | 18 + crates/notebook/src/lib.rs | 8 +- crates/notebook/src/merge.rs | 25 +- crates/notebook/src/queue.rs | 3 + crates/notebook/src/session.rs | 134 +++ crates/notebook/src/sidecar.rs | 2 + crates/notebook/src/sidecar/tests.rs | 45 +- crates/notebook/src/sidecar/themes.rs | 560 +++++++++++ crates/notebook/tests/discovery.rs | 40 + crates/notebook/tests/structure.rs | 52 + crates/notebook/tests/sync_outline.rs | 1 + crates/onestore/README.md | 1 + crates/onestore/examples/opts29_dump.rs | 29 - crates/onestore/src/document.rs | 4 + crates/onestore/src/formatting.rs | 27 +- crates/onestore/src/op/apply.rs | 117 ++- crates/onestore/src/op/content.rs | 63 +- crates/onestore/src/op/lower.rs | 101 +- crates/onestore/src/op/mod.rs | 52 + crates/onestore/src/op/model.rs | 161 +++- crates/onestore/src/op/properties.rs | 187 +++- crates/onestore/src/op/tests.rs | 200 +++- crates/onestore/src/page/mod.rs | 230 +++-- crates/onestore/src/pages.rs | 37 +- crates/onestore/src/write.rs | 9 +- crates/onestore/tests/page_attachments.rs | 3 + crates/onestore/tests/page_images.rs | 9 + crates/onestore/tests/protected.rs | 1 + crates/snowbound/Cargo.toml | 4 + crates/snowbound/assets/icons/styles.svg | 8 + crates/snowbound/linux/README.md | 5 +- crates/snowbound/linux/onenote.xml | 9 + crates/snowbound/linux/snowbound.desktop | 3 +- crates/snowbound/src/art.rs | 1 + crates/snowbound/src/attachment.rs | 13 +- crates/snowbound/src/commands.rs | 512 ++++++++-- crates/snowbound/src/conflict_render.rs | 2 +- crates/snowbound/src/desktop_linux.rs | 51 +- crates/snowbound/src/icloud_linux.rs | 7 +- crates/snowbound/src/icloud_macos.rs | 105 +- crates/snowbound/src/instance.rs | 247 +++++ crates/snowbound/src/keys.rs | 534 +++++++++++ crates/snowbound/src/library.rs | 343 ++++++- crates/snowbound/src/linux.rs | 7 +- crates/snowbound/src/macos.rs | 33 + crates/snowbound/src/main.rs | 667 +++++++++++-- crates/snowbound/src/manage.rs | 511 +++++++--- crates/snowbound/src/meeting.rs | 1 + crates/snowbound/src/menubar.rs | 41 +- crates/snowbound/src/menus.rs | 736 +++++++++++--- crates/snowbound/src/navigation.rs | 136 ++- crates/snowbound/src/options.rs | 880 +++++++++++++---- crates/snowbound/src/palette.rs | 322 +++++-- crates/snowbound/src/paste.rs | 614 +++++++++++- crates/snowbound/src/prefetch.rs | 376 ++++++++ crates/snowbound/src/print.rs | 407 +++++++- crates/snowbound/src/properties.rs | 196 ++++ crates/snowbound/src/recording.rs | 2 + crates/snowbound/src/rename.rs | 52 +- crates/snowbound/src/server.rs | 125 ++- crates/snowbound/src/settings.rs | 40 +- crates/snowbound/src/sidebar.rs | 138 ++- crates/snowbound/src/spell_windows.rs | 3 +- crates/snowbound/src/surface_windows.rs | 56 +- crates/snowbound/src/sync.rs | 1284 ++++++++++++++++++++----- crates/snowbound/src/themes.rs | 936 ++++++++++++++++++ crates/snowbound/src/undo.rs | 1630 ++++++++++++++++++++++++++++++++ crates/snowbound/src/windows.rs | 192 +++- crates/snowbound/tests/replay.rs | 130 +++ crates/ui/src/layout.rs | 63 +- crates/ui/src/lib.rs | 74 +- crates/ui/src/list.rs | 7 + crates/ui/src/popup.rs | 70 +- crates/ui/src/tests.rs | 303 +++++- crates/ui/src/text.rs | 25 +- tools/RELEASE.md | 2 +- tools/canvas/README.md | 4 +- tools/canvas/build_macos.py | 19 +- tools/native/styles.ps1 | 7 + tools/native_styles.py | 15 + tools/test_default_font.py | 37 + tools/test_object_tags.py | 56 ++ tools/test_picture_link.py | 27 + tools/test_printout.py | 4 +- tools/test_recycle_purge.py | 29 + tools/test_section_color.py | 30 + tools/test_styles.py | 59 ++ tools/test_table_widths.py | 48 + 446 files changed, 21304 insertions(+), 3056 deletions(-)