| author | |
| committer | |
| log | 5f00c02e9903b23fca73277fcdd3b6aa4fe2ea5a |
| tree | ad7b80476af6f3a55a5f51bb631b5d4e43f0acfe |
| parent | 7b15af16ba1b2e7f785f9346b9f39159a79ae44b |
| signature | Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU |
Publish text partitions, child transfer, list clones, tags and title metadata in one revision. Retain original left identities and history; reject generated fields and unsupported run metadata before I/O.
Validated at every scalar boundary across twelve native cases, ordinary/checkpoint publication interruptions, 29,316 ASan executions, cold OneNote rendering and four subsequent native typing actions. The full public regression lane passes.
Assisted-by: gpt-6-astra87 files changed, 1889 insertions(+), 12 deletions(-)
corpus/paragraph-edit/README.md+10-2| ... | @@ -26,6 +26,14 @@ notebook before completing inspection. Cold-open the split notebook for the join | ... | @@ -26,6 +26,14 @@ notebook before completing inspection. Cold-open the split notebook for the join |
| 26 | pass. Captured COM IDs belong to their originating sessions; discover fresh IDs | 26 | pass. Captured COM IDs belong to their originating sessions; discover fresh IDs |
| 27 | when regenerating the corpus. | 27 | when regenerating the corpus. |
| 28 | 28 | ||
| 29 | `tools/test_paragraph_edit.py` verifies these native controls without a VM. They | 29 | `rust-split` retains twelve `ParagraphSplit` outputs, their cold native captures, |
| 30 | establish application behavior; they do not advertise a library split/join API. | 30 | and a second native session typing into four empty boundary paragraphs. The |
| 31 | hyperlink case stays unchanged because this operation rejects fields. The Rust | ||
| 32 | test `export_native_paragraph_splits` generates candidate notebooks; its output | ||
| 33 | directory comes from `ONESTORE_PARAGRAPH_OUTPUT`. Native character/style comparisons | ||
| 34 | use both the keyboard-generated controls and the Rust-written notebooks. Empty | ||
| 35 | typing checks extend the preexisting empty run in an independent expected model. | ||
| 36 | |||
| 37 | `tools/test_paragraph_edit.py` verifies these controls without a VM. The native | ||
| 38 | join captures establish behavior for subsequent join implementation. | ||
| 31 | Identical captured files link to one canonical copy within this corpus. | 39 | Identical captured files link to one canonical copy within this corpus. |
corpus/paragraph-edit/rust-split/candidate/synthetic.one created| Binary files /dev/null and b/corpus/paragraph-edit/rust-split/candidate/synthetic.one differ | |||
corpus/paragraph-edit/rust-split/manifest.json created+352| ... | @@ -0,0 +1,352 @@ | ||
| 1 | { | ||
| 2 | "cases": [ | ||
| 3 | { | ||
| 4 | "case": "Split middle", | ||
| 5 | "intent": { | ||
| 6 | "author": "Rust split author", | ||
| 7 | "created": 1473324660, | ||
| 8 | "guid": [ | ||
| 9 | 228, | ||
| 10 | 60, | ||
| 11 | 65, | ||
| 12 | 246, | ||
| 13 | 194, | ||
| 14 | 244, | ||
| 15 | 184, | ||
| 16 | 76, | ||
| 17 | 170, | ||
| 18 | 5, | ||
| 19 | 19, | ||
| 20 | 130, | ||
| 21 | 32, | ||
| 22 | 122, | ||
| 23 | 148, | ||
| 24 | 241 | ||
| 25 | ], | ||
| 26 | "offset": 2, | ||
| 27 | "text": "{DFE950EF-6BEB-0F5B-2403-7B74F1AE5002},44" | ||
| 28 | }, | ||
| 29 | "new_paragraph": "{F6413CE4-F4C2-4CB8-AA05-1382207A94F1},1", | ||
| 30 | "new_text": "{F6413CE4-F4C2-4CB8-AA05-1382207A94F1},2" | ||
| 31 | }, | ||
| 32 | { | ||
| 33 | "case": "Split style boundary", | ||
| 34 | "intent": { | ||
| 35 | "author": "Rust split author", | ||
| 36 | "created": 1473324660, | ||
| 37 | "guid": [ | ||
| 38 | 163, | ||
| 39 | 91, | ||
| 40 | 197, | ||
| 41 | 73, | ||
| 42 | 195, | ||
| 43 | 225, | ||
| 44 | 53, | ||
| 45 | 68, | ||
| 46 | 140, | ||
| 47 | 152, | ||
| 48 | 83, | ||
| 49 | 168, | ||
| 50 | 172, | ||
| 51 | 124, | ||
| 52 | 226, | ||
| 53 | 213 | ||
| 54 | ], | ||
| 55 | "offset": 4, | ||
| 56 | "text": "{5FB484E2-1E3E-0A9D-1989-271A3EBBEC42},44" | ||
| 57 | }, | ||
| 58 | "new_paragraph": "{49C55BA3-E1C3-4435-8C98-53A8AC7CE2D5},1", | ||
| 59 | "new_text": "{49C55BA3-E1C3-4435-8C98-53A8AC7CE2D5},2" | ||
| 60 | }, | ||
| 61 | { | ||
| 62 | "case": "Split start", | ||
| 63 | "intent": { | ||
| 64 | "author": "Rust split author", | ||
| 65 | "created": 1473324660, | ||
| 66 | "guid": [ | ||
| 67 | 135, | ||
| 68 | 16, | ||
| 69 | 214, | ||
| 70 | 248, | ||
| 71 | 73, | ||
| 72 | 35, | ||
| 73 | 2, | ||
| 74 | 69, | ||
| 75 | 148, | ||
| 76 | 213, | ||
| 77 | 125, | ||
| 78 | 28, | ||
| 79 | 43, | ||
| 80 | 124, | ||
| 81 | 81, | ||
| 82 | 35 | ||
| 83 | ], | ||
| 84 | "offset": 0, | ||
| 85 | "text": "{012ED94B-43B3-079A-3050-B1CBE25C1C09},44" | ||
| 86 | }, | ||
| 87 | "new_paragraph": "{F8D61087-2349-4502-94D5-7D1C2B7C5123},1", | ||
| 88 | "new_text": "{F8D61087-2349-4502-94D5-7D1C2B7C5123},2" | ||
| 89 | }, | ||
| 90 | { | ||
| 91 | "case": "Split end", | ||
| 92 | "intent": { | ||
| 93 | "author": "Rust split author", | ||
| 94 | "created": 1473324660, | ||
| 95 | "guid": [ | ||
| 96 | 37, | ||
| 97 | 220, | ||
| 98 | 149, | ||
| 99 | 138, | ||
| 100 | 85, | ||
| 101 | 3, | ||
| 102 | 106, | ||
| 103 | 69, | ||
| 104 | 168, | ||
| 105 | 172, | ||
| 106 | 49, | ||
| 107 | 82, | ||
| 108 | 247, | ||
| 109 | 99, | ||
| 110 | 160, | ||
| 111 | 139 | ||
| 112 | ], | ||
| 113 | "offset": 22, | ||
| 114 | "text": "{DAF723A3-C2A3-0798-2EAB-34613166A794},44" | ||
| 115 | }, | ||
| 116 | "new_paragraph": "{8A95DC25-0355-456A-A8AC-3152F763A08B},1", | ||
| 117 | "new_text": "{8A95DC25-0355-456A-A8AC-3152F763A08B},2" | ||
| 118 | }, | ||
| 119 | { | ||
| 120 | "case": "Split empty", | ||
| 121 | "intent": { | ||
| 122 | "author": "Rust split author", | ||
| 123 | "created": 1473324660, | ||
| 124 | "guid": [ | ||
| 125 | 232, | ||
| 126 | 204, | ||
| 127 | 91, | ||
| 128 | 132, | ||
| 129 | 180, | ||
| 130 | 27, | ||
| 131 | 239, | ||
| 132 | 79, | ||
| 133 | 158, | ||
| 134 | 115, | ||
| 135 | 213, | ||
| 136 | 165, | ||
| 137 | 40, | ||
| 138 | 35, | ||
| 139 | 189, | ||
| 140 | 93 | ||
| 141 | ], | ||
| 142 | "offset": 0, | ||
| 143 | "text": "{0B467F31-D287-08CD-09F4-A6FBB2F5418F},45" | ||
| 144 | }, | ||
| 145 | "new_paragraph": "{845BCCE8-1BB4-4FEF-9E73-D5A52823BD5D},1", | ||
| 146 | "new_text": "{845BCCE8-1BB4-4FEF-9E73-D5A52823BD5D},2" | ||
| 147 | }, | ||
| 148 | { | ||
| 149 | "case": "Split parent", | ||
| 150 | "intent": { | ||
| 151 | "author": "Rust split author", | ||
| 152 | "created": 1473324660, | ||
| 153 | "guid": [ | ||
| 154 | 54, | ||
| 155 | 186, | ||
| 156 | 114, | ||
| 157 | 171, | ||
| 158 | 44, | ||
| 159 | 189, | ||
| 160 | 95, | ||
| 161 | 71, | ||
| 162 | 135, | ||
| 163 | 190, | ||
| 164 | 71, | ||
| 165 | 95, | ||
| 166 | 23, | ||
| 167 | 246, | ||
| 168 | 37, | ||
| 169 | 157 | ||
| 170 | ], | ||
| 171 | "offset": 2, | ||
| 172 | "text": "{3860EA13-D444-0598-35D6-CF96769C6A21},44" | ||
| 173 | }, | ||
| 174 | "new_paragraph": "{AB72BA36-BD2C-475F-87BE-475F17F6259D},1", | ||
| 175 | "new_text": "{AB72BA36-BD2C-475F-87BE-475F17F6259D},2" | ||
| 176 | }, | ||
| 177 | { | ||
| 178 | "case": "Split child", | ||
| 179 | "intent": { | ||
| 180 | "author": "Rust split author", | ||
| 181 | "created": 1473324660, | ||
| 182 | "guid": [ | ||
| 183 | 160, | ||
| 184 | 247, | ||
| 185 | 235, | ||
| 186 | 152, | ||
| 187 | 30, | ||
| 188 | 98, | ||
| 189 | 166, | ||
| 190 | 77, | ||
| 191 | 157, | ||
| 192 | 204, | ||
| 193 | 141, | ||
| 194 | 45, | ||
| 195 | 114, | ||
| 196 | 151, | ||
| 197 | 225, | ||
| 198 | 195 | ||
| 199 | ], | ||
| 200 | "offset": 2, | ||
| 201 | "text": "{B587CBC6-0BCC-0A23-16F6-E1B0B3C5D061},49" | ||
| 202 | }, | ||
| 203 | "new_paragraph": "{98EBF7A0-621E-4DA6-9DCC-8D2D7297E1C3},1", | ||
| 204 | "new_text": "{98EBF7A0-621E-4DA6-9DCC-8D2D7297E1C3},2" | ||
| 205 | }, | ||
| 206 | { | ||
| 207 | "case": "Split bullet", | ||
| 208 | "intent": { | ||
| 209 | "author": "Rust split author", | ||
| 210 | "created": 1473324660, | ||
| 211 | "guid": [ | ||
| 212 | 53, | ||
| 213 | 245, | ||
| 214 | 214, | ||
| 215 | 76, | ||
| 216 | 159, | ||
| 217 | 56, | ||
| 218 | 134, | ||
| 219 | 76, | ||
| 220 | 178, | ||
| 221 | 90, | ||
| 222 | 131, | ||
| 223 | 182, | ||
| 224 | 74, | ||
| 225 | 114, | ||
| 226 | 31, | ||
| 227 | 24 | ||
| 228 | ], | ||
| 229 | "offset": 2, | ||
| 230 | "text": "{8C65E427-477C-02ED-1807-2F10E277019D},44" | ||
| 231 | }, | ||
| 232 | "new_paragraph": "{4CD6F535-389F-4C86-B25A-83B64A721F18},1", | ||
| 233 | "new_text": "{4CD6F535-389F-4C86-B25A-83B64A721F18},2" | ||
| 234 | }, | ||
| 235 | { | ||
| 236 | "case": "Split number", | ||
| 237 | "intent": { | ||
| 238 | "author": "Rust split author", | ||
| 239 | "created": 1473324661, | ||
| 240 | "guid": [ | ||
| 241 | 196, | ||
| 242 | 133, | ||
| 243 | 251, | ||
| 244 | 251, | ||
| 245 | 193, | ||
| 246 | 175, | ||
| 247 | 8, | ||
| 248 | 65, | ||
| 249 | 175, | ||
| 250 | 180, | ||
| 251 | 126, | ||
| 252 | 16, | ||
| 253 | 31, | ||
| 254 | 185, | ||
| 255 | 237, | ||
| 256 | 66 | ||
| 257 | ], | ||
| 258 | "offset": 2, | ||
| 259 | "text": "{D4ABBE4F-2165-0122-1F9F-ACE3FE92C703},44" | ||
| 260 | }, | ||
| 261 | "new_paragraph": "{FBFB85C4-AFC1-4108-AFB4-7E101FB9ED42},1", | ||
| 262 | "new_text": "{FBFB85C4-AFC1-4108-AFB4-7E101FB9ED42},2" | ||
| 263 | }, | ||
| 264 | { | ||
| 265 | "case": "Split tag", | ||
| 266 | "intent": { | ||
| 267 | "author": "Rust split author", | ||
| 268 | "created": 1473324661, | ||
| 269 | "guid": [ | ||
| 270 | 40, | ||
| 271 | 122, | ||
| 272 | 110, | ||
| 273 | 77, | ||
| 274 | 185, | ||
| 275 | 255, | ||
| 276 | 122, | ||
| 277 | 69, | ||
| 278 | 128, | ||
| 279 | 15, | ||
| 280 | 14, | ||
| 281 | 166, | ||
| 282 | 54, | ||
| 283 | 156, | ||
| 284 | 154, | ||
| 285 | 91 | ||
| 286 | ], | ||
| 287 | "offset": 2, | ||
| 288 | "text": "{37AA5877-2980-0227-169F-8B1E8EE0795A},44" | ||
| 289 | }, | ||
| 290 | "new_paragraph": "{4D6E7A28-FFB9-457A-800F-0EA6369C9A5B},1", | ||
| 291 | "new_text": "{4D6E7A28-FFB9-457A-800F-0EA6369C9A5B},2" | ||
| 292 | }, | ||
| 293 | { | ||
| 294 | "case": "Split cell", | ||
| 295 | "intent": { | ||
| 296 | "author": "Rust split author", | ||
| 297 | "created": 1473324661, | ||
| 298 | "guid": [ | ||
| 299 | 150, | ||
| 300 | 222, | ||
| 301 | 89, | ||
| 302 | 134, | ||
| 303 | 80, | ||
| 304 | 167, | ||
| 305 | 167, | ||
| 306 | 67, | ||
| 307 | 179, | ||
| 308 | 23, | ||
| 309 | 93, | ||
| 310 | 176, | ||
| 311 | 27, | ||
| 312 | 184, | ||
| 313 | 119, | ||
| 314 | 185 | ||
| 315 | ], | ||
| 316 | "offset": 2, | ||
| 317 | "text": "{F0832BC9-1578-0A96-08AF-99344644FFB8},50" | ||
| 318 | }, | ||
| 319 | "new_paragraph": "{8659DE96-A750-43A7-B317-5DB01BB877B9},1", | ||
| 320 | "new_text": "{8659DE96-A750-43A7-B317-5DB01BB877B9},2" | ||
| 321 | }, | ||
| 322 | { | ||
| 323 | "case": "Split soft break", | ||
| 324 | "intent": { | ||
| 325 | "author": "Rust split author", | ||
| 326 | "created": 1473324661, | ||
| 327 | "guid": [ | ||
| 328 | 199, | ||
| 329 | 62, | ||
| 330 | 94, | ||
| 331 | 81, | ||
| 332 | 29, | ||
| 333 | 157, | ||
| 334 | 236, | ||
| 335 | 77, | ||
| 336 | 159, | ||
| 337 | 34, | ||
| 338 | 22, | ||
| 339 | 137, | ||
| 340 | 163, | ||
| 341 | 57, | ||
| 342 | 215, | ||
| 343 | 79 | ||
| 344 | ], | ||
| 345 | "offset": 2, | ||
| 346 | "text": "{88189BA1-2F19-0282-05ED-A0B83153F143},44" | ||
| 347 | }, | ||
| 348 | "new_paragraph": "{515E3EC7-9D1D-4DEC-9F22-1689A339D74F},1", | ||
| 349 | "new_text": "{515E3EC7-9D1D-4DEC-9F22-1689A339D74F},2" | ||
| 350 | } | ||
| 351 | ] | ||
| 352 | } | ||
corpus/paragraph-edit/rust-split/native/notebook/Open Notebook.onetoc2 created| Binary files /dev/null and b/corpus/paragraph-edit/rust-split/native/notebook/Open Notebook.onetoc2 differ | |||
corpus/paragraph-edit/rust-split/native/notebook/synthetic.one created| Binary files /dev/null and b/corpus/paragraph-edit/rust-split/native/notebook/synthetic.one differ | |||
corpus/paragraph-edit/rust-split/native/read/environment.json created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | { | ||
| 2 | "powershell": "5.1.14409.1005", | ||
| 3 | "schema": "xs2010", | ||
| 4 | "hostname": "ONE-M6-AA441F91", | ||
| 5 | "cold": true, | ||
| 6 | "onenote": "14.0.4763.1000" | ||
| 7 | } | ||
corpus/paragraph-edit/rust-split/native/read/hierarchy.xml created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" name="notebook" nickname="notebook" ID="{A5E609F0-7B8E-4650-8008-F78195DDC594}{1}{B0}" path="C:\one-tests\runs\capture\notebook" lastModifiedTime="2026-09-08T08:52:39.000Z" color="#B49EDE"><one:Section name="synthetic" ID="{3FA69981-21D0-0FBE-12CF-2BD2FC0B5E0C}{1}{B0}" path="C:\one-tests\runs\capture\notebook\synthetic.one" lastModifiedTime="2026-09-08T08:52:39.000Z" color="#8AA8E4"><one:Page ID="{13EF6A07-A81B-4CAF-95A8-834300334213}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{89D51190-5315-422F-A5E6-92B8A673E329}{1}{B0}" name="Split middle" dateTime="2026-09-08T08:09:29.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{A923DEF6-EBB3-4703-A0FE-029F6B7EEA4E}{1}{B0}" name="Split style boundary" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{0EEEBDC0-EE0B-40C9-BFC7-A9AA93C7916F}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{E5887CFA-F13E-437F-9F25-6B1A4169BE2C}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{932F903F-B689-44C3-9E5D-CE04DE3437CB}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{0DC169BF-95C0-4AAF-A1A2-ED4A3D767051}{1}{B0}" name="Split parent" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{4B35902F-8318-47D8-87E8-3CE071853AC5}{1}{B0}" name="Split child" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{E3D9A117-19D3-4FF5-8B41-7F959E73BEB2}{1}{B0}" name="Split bullet" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{D359140C-3B82-4012-80C5-1C643EBAD29E}{1}{B0}" name="Split number" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{046AE778-A43B-4A6D-8EC1-45EE4AC75F37}{1}{B0}" name="Split tag" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{33C5B71F-B85D-4A15-899B-E21ED69D12E3}{1}{B0}" name="Split cell" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{AF160280-425C-4905-8189-7CDBD4C4E616}{1}{B0}" name="Split soft break" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/><one:Page ID="{05360577-7E8B-474B-8EF6-8D6059015DA8}{1}{B0}" name="Split before hyperlink" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1"/></one:Section></one:Notebook> | ||
corpus/paragraph-edit/rust-split/native/read/page-000.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{046AE778-A43B-4A6D-8EC1-45EE4AC75F37}{1}{B0}" name="Split tag" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Fixture task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{405D0C84-CF82-4236-BE0C-80A29906B055}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split tag]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{405D0C84-CF82-4236-BE0C-80A29906B055}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704788208008" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{405D0C84-CF82-4236-BE0C-80A29906B055}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{3A992EDB-19BB-056B-289C-051A217A5354}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{405D0C84-CF82-4236-BE0C-80A29906B055}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-001.xml created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{05360577-7E8B-474B-8EF6-8D6059015DA8}{1}{B0}" name="Split before hyperlink" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{23C44D14-BCC5-4A65-B879-325BBEAC1989}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split before hyperlink]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:09:37.000Z" objectID="{23C44D14-BCC5-4A65-B879-325BBEAC1989}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="130.6343231201172" height="26.85543441772461"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{23C44D14-BCC5-4A65-B879-325BBEAC1989}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Before <a | ||
| 3 | href="https://example.invalid/paragraph">Link label</a> tail]]></one:T></one:OE><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{23C44D14-BCC5-4A65-B879-325BBEAC1989}{47}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-002.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{0DC169BF-95C0-4AAF-A1A2-ED4A3D767051}{1}{B0}" name="Split parent" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{4F97BEE0-3246-4589-9D45-C42A617AA32E}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split parent]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{4F97BEE0-3246-4589-9D45-C42A617AA32E}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="135.3173980712891" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{4F97BEE0-3246-4589-9D45-C42A617AA32E}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{DC85EEC5-5B2E-074E-2F2D-4CE30010EC92}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T><one:OEChildren><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{4F97BEE0-3246-4589-9D45-C42A617AA32E}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved child]]></one:T></one:OE></one:OEChildren></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{4F97BEE0-3246-4589-9D45-C42A617AA32E}{53}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-003.xml created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{0EEEBDC0-EE0B-40C9-BFC7-A9AA93C7916F}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{76D98DB8-A5B1-478B-98C3-BA77F5BAD506}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split start]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{76D98DB8-A5B1-478B-98C3-BA77F5BAD506}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{76D98DB8-A5B1-478B-98C3-BA77F5BAD506}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{8F214474-C54B-0513-3C46-76A03C9A982C}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span | ||
| 4 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 5 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{76D98DB8-A5B1-478B-98C3-BA77F5BAD506}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-004.xml created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{13EF6A07-A81B-4CAF-95A8-834300334213}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Outline author="Rich author" lastModifiedBy="Rich author" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{7423C2BB-E36E-4F19-9A5A-0F98FFAFA772}{10}{B0}"><one:Position x="36.0" y="14.40000057220459" z="0"/><one:Size width="127.5136947631836" height="42.90299224853515"/><one:OEChildren><one:OE creationTime="2026-09-08T04:47:24.000Z" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{73466A4C-1013-0413-2A0E-CC9234C4D584}{1}{B0}" alignment="left"><one:T><![CDATA[<span style='font-weight:bold; | ||
| 3 | text-decoration:underline;font-family:Calibri;font-size:11.0pt'>Bold</span><span | ||
| 4 | style='font-family:Calibri;font-size:11.0pt'> </span><span style='font-family: | ||
| 5 | Arial;font-size:13.5pt'>&#129408;</span><span style='font-family:Calibri; | ||
| 6 | font-size:11.0pt'> </span><span style='font-style:italic;text-decoration:line-through; | ||
| 7 | font-family:Calibri;font-size:11.0pt'>italic</span><span style='font-family: | ||
| 8 | Calibri;font-size:11.0pt'> </span><span style='vertical-align:super;font-family: | ||
| 9 | Calibri;font-size:11.0pt'>é</span><span style='font-family:Calibri;font-size: | ||
| 10 | 11.0pt'> </span><span style='font-family:Calibri;font-size:11.0pt;color:#0C2238; | ||
| 11 | background:yellow;mso-highlight:yellow'>color</span><span style='font-family: | ||
| 12 | Calibri;font-size:11.0pt'> </span><span style='vertical-align:sub;font-family: | ||
| 13 | Calibri;font-size:11.0pt'>東京</span><span style='font-family:Calibri;font-size: | ||
| 14 | 11.0pt'><br> | ||
| 15 | End</span>]]></one:T></one:OE><one:OE author="snow" authorInitials="S" lastModifiedBy="snow" lastModifiedByInitials="S" creationTime="2026-09-05T05:06:55.000Z" lastModifiedTime="2026-09-05T05:06:56.000Z" objectID="{7423C2BB-E36E-4F19-9A5A-0F98FFAFA772}{11}{B0}" alignment="left" quickStyleIndex="0" style="font-size:11.0pt;color:#1F4E79"><one:T><![CDATA[<span | ||
| 16 | style='font-weight:bold;font-family:Calibri' lang=en-US>Fictitious: café, </span><span | ||
| 17 | style='font-weight:bold;font-family:SimSun' lang=en-US>東京</span><span | ||
| 18 | style='font-weight:bold;font-family:Calibri' lang=en-US>, </span><span | ||
| 19 | style='font-weight:bold;font-family:Arial;direction:rtl;unicode-bidi:embed' | ||
| 20 | lang=ar-SA>مرحبا</span>]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-005.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{33C5B71F-B85D-4A15-899B-E21ED69D12E3}{1}{B0}" name="Split cell" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split cell]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="254.9588165283203" height="48.80315780639648"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{40}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{41}{B0}"><one:Columns><one:Column index="0" width="180.0" isLocked="true"/><one:Column index="1" width="66.82881927490234"/></one:Columns><one:Row objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{42}{B0}" lastModifiedTime="2026-09-08T08:51:01.000Z"><one:Cell lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{43}{B0}"><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{46}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{F1AE8A65-4152-03B6-1B84-560C0C5EBEB6}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-08T08:09:37.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{54}{B0}" lastModifiedBy="virtual" lastModifiedByInitials="V"><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{57}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved cell]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{87747F3A-F37A-4A87-A03C-928851A236B7}{62}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-006.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{4B35902F-8318-47D8-87E8-3CE071853AC5}{1}{B0}" name="Split child" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{C2709F35-EDCE-4A32-BE65-EA0CA423196E}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split child]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C2709F35-EDCE-4A32-BE65-EA0CA423196E}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="131.8423614501953" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C2709F35-EDCE-4A32-BE65-EA0CA423196E}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved parent]]></one:T><one:OEChildren><one:OE lastModifiedBy="Rust split author" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C2709F35-EDCE-4A32-BE65-EA0CA423196E}{45}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" lastModifiedBy="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{EF1CA353-841C-0DB7-355F-8691657128CC}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{C2709F35-EDCE-4A32-BE65-EA0CA423196E}{53}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-007.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{89D51190-5315-422F-A5E6-92B8A673E329}{1}{B0}" name="Split middle" dateTime="2026-09-08T08:09:29.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{A81E041C-8DE9-4F4A-8C90-70C8E648990D}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split middle]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A81E041C-8DE9-4F4A-8C90-70C8E648990D}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:30.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A81E041C-8DE9-4F4A-8C90-70C8E648990D}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{81B66817-12C0-0CA9-0296-183E379C5DFE}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{A81E041C-8DE9-4F4A-8C90-70C8E648990D}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-008.xml created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{932F903F-B689-44C3-9E5D-CE04DE3437CB}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{7CB12BC2-3485-48DC-A167-AD47A5138880}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split empty]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{7CB12BC2-3485-48DC-A167-AD47A5138880}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{7CB12BC2-3485-48DC-A167-AD47A5138880}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{F3AC981B-FDB6-0FFE-36E0-DE193FC57452}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{7CB12BC2-3485-48DC-A167-AD47A5138880}{46}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-009.xml created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{A923DEF6-EBB3-4703-A0FE-029F6B7EEA4E}{1}{B0}" name="Split style boundary" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{2843D011-F83C-4A8C-B11A-2CA6295D254D}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split style boundary]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{2843D011-F83C-4A8C-B11A-2CA6295D254D}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{2843D011-F83C-4A8C-B11A-2CA6295D254D}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bold</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{3E320F50-07C1-0424-240B-5814BB9A2BDA}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | lang=en-US> </span><span style='font-style:italic' lang=en-US>italic</span><span | ||
| 5 | lang=en-US> &#129408; é </span><span style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{2843D011-F83C-4A8C-B11A-2CA6295D254D}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-010.xml created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{AF160280-425C-4905-8189-7CDBD4C4E616}{1}{B0}" name="Split soft break" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{FFEFCF52-C91B-4293-AD7E-AB0426B5384C}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split soft break]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{FFEFCF52-C91B-4293-AD7E-AB0426B5384C}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="468.0" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{FFEFCF52-C91B-4293-AD7E-AB0426B5384C}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Bo]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{26A96A34-7B1F-0DFD-37B1-1D35B4DF1E40}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[ld<br> | ||
| 3 | soft break]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{FFEFCF52-C91B-4293-AD7E-AB0426B5384C}{45}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-011.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{D359140C-3B82-4012-80C5-1C643EBAD29E}{1}{B0}" name="Split number" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{A35CEABC-C767-4133-B70C-A75FE9740E0C}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split number]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{A35CEABC-C767-4133-B70C-A75FE9740E0C}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{A35CEABC-C767-4133-B70C-A75FE9740E0C}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:List><one:Number numberSequence="1" numberFormat="##." restartNumberingAt="3" fontSize="11.0" font="Calibri" text="III."/></one:List><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C0CD137-49C3-0119-0727-75AC085F244D}{1}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="IV."/></one:List><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{A35CEABC-C767-4133-B70C-A75FE9740E0C}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-012.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{E3D9A117-19D3-4FF5-8B41-7F959E73BEB2}{1}{B0}" name="Split bullet" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{FB92B0D4-A17E-42FC-B094-24ACF591C892}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split bullet]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{FB92B0D4-A17E-42FC-B094-24ACF591C892}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="135.3173980712891" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{FB92B0D4-A17E-42FC-B094-24ACF591C892}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{3B21A1C6-DE9D-0C97-1AC9-880A5D94D617}{1}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T><one:OEChildren><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{FB92B0D4-A17E-42FC-B094-24ACF591C892}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved child]]></one:T></one:OE></one:OEChildren></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{FB92B0D4-A17E-42FC-B094-24ACF591C892}{54}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/page-013.xml created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{E5887CFA-F13E-437F-9F25-6B1A4169BE2C}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:52:39.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{AD007750-24A1-4789-8638-3FDD26806E9B}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split end]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{AD007750-24A1-4789-8638-3FDD26806E9B}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{AD007750-24A1-4789-8638-3FDD26806E9B}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span | ||
| 4 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 5 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{FD6288D6-E557-057B-003F-3AEEE0856984}{1}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt;color:#123456"><one:T><![CDATA[]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{AD007750-24A1-4789-8638-3FDD26806E9B}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/native/read/payloads.json created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../../../before/read/payloads.json | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/native/run.json created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | { | ||
| 2 | "notebook": "/Users/clo/dev/one/evidence/m10/paragraph-rust-split-01/candidate", | ||
| 3 | "expected_pages": 14, | ||
| 4 | "author": null, | ||
| 5 | "author_timeout_seconds": 600, | ||
| 6 | "inspect": false, | ||
| 7 | "collect_notebook": true, | ||
| 8 | "base": { | ||
| 9 | "file": "win7-office-base.qcow2", | ||
| 10 | "format": "qcow2", | ||
| 11 | "sha256": "a1a4f8fab782ee14885ff801ca2f6347c208fdcfc3513637096f314315c89346", | ||
| 12 | "virtual_size": 68719476736 | ||
| 13 | }, | ||
| 14 | "scripts": { | ||
| 15 | "cold.ps1": "c177fc72ae6c2634d186f5671a880de20b09f9716532c37c69cb13aa15c7e331", | ||
| 16 | "read.ps1": "04013bfcccee40a17e2a225f9b9e96f40a3a8daad9e350609654f8eda3ccbb41" | ||
| 17 | } | ||
| 18 | } | ||
corpus/paragraph-edit/rust-split/native/source.json created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | [ | ||
| 2 | { | ||
| 3 | "path": "synthetic.one", | ||
| 4 | "bytes": 110224, | ||
| 5 | "sha256": "c07cf1d31c658534b7cd3c6f77dd48dd52a1b9be4ef037b3d016b24336a4c3f4", | ||
| 6 | "mtime_ns": 1788857461138239881 | ||
| 7 | } | ||
| 8 | ] | ||
corpus/paragraph-edit/rust-split/native/teardown.json created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../../joined/teardown.json | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/before-read/environment.json created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | { | ||
| 2 | "powershell": "5.1.14409.1005", | ||
| 3 | "schema": "xs2010", | ||
| 4 | "hostname": "ONE-M6-02D586B5", | ||
| 5 | "cold": true, | ||
| 6 | "onenote": "14.0.4763.1000" | ||
| 7 | } | ||
corpus/paragraph-edit/rust-split/typed/before-read/hierarchy.xml created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" name="notebook" nickname="notebook" ID="{5F2547AA-6079-422C-929F-ACD159424C5F}{1}{B0}" path="C:\one-tests\runs\capture\notebook" lastModifiedTime="2026-09-08T08:57:31.000Z" color="#B49EDE"><one:Section name="synthetic" ID="{34C60088-AAFA-0664-3D80-161C07A5288F}{1}{B0}" path="C:\one-tests\runs\capture\notebook\synthetic.one" lastModifiedTime="2026-09-08T08:57:31.000Z" color="#8AA8E4"><one:Page ID="{188FF30E-2331-4575-BAE7-BE8DFB9D3490}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{82B58899-D83F-4BF5-8AA9-AF765DDD95AA}{1}{B0}" name="Split middle" dateTime="2026-09-08T08:09:29.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{A24347FF-6099-4ED9-8FB1-3F5190D09CCD}{1}{B0}" name="Split style boundary" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{06A1F0B6-1EEA-4375-8EED-D084C6D806D2}{1}{B0}" name="Split parent" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{40550926-0832-4E02-A8A7-012E8A2B4C46}{1}{B0}" name="Split child" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{E8B9381E-92F9-462F-A40E-425B65DDC831}{1}{B0}" name="Split bullet" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{D8398D05-B0A8-49C8-AF8A-21AAC514A41D}{1}{B0}" name="Split number" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{0F0A7E71-2F11-43B7-A18E-7820B16929B4}{1}{B0}" name="Split tag" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{38A52E16-3377-43CF-A6D4-DFD02D336460}{1}{B0}" name="Split cell" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{A4769B89-C976-40DF-AEC6-41152F6A9095}{1}{B0}" name="Split soft break" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{0E569C7E-F5A1-4E91-A1B9-B0AEA2AF2B2B}{1}{B0}" name="Split before hyperlink" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/></one:Section></one:Notebook> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-000.xml created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split start]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{8441DD7D-4E61-0CC9-1309-4B6EC734EEAF}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span | ||
| 4 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 5 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-001.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{06A1F0B6-1EEA-4375-8EED-D084C6D806D2}{1}{B0}" name="Split parent" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{44F727E9-B96C-4C53-B20A-F9E49AD4D5AD}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split parent]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{44F727E9-B96C-4C53-B20A-F9E49AD4D5AD}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="135.3173980712891" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{44F727E9-B96C-4C53-B20A-F9E49AD4D5AD}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{D7E577CC-D004-0E94-0062-712DFBBE9A11}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T><one:OEChildren><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{44F727E9-B96C-4C53-B20A-F9E49AD4D5AD}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved child]]></one:T></one:OE></one:OEChildren></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{44F727E9-B96C-4C53-B20A-F9E49AD4D5AD}{53}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-002.xml created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{0E569C7E-F5A1-4E91-A1B9-B0AEA2AF2B2B}{1}{B0}" name="Split before hyperlink" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{28A4D41D-37EF-43BF-9736-0F9545026F0A}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split before hyperlink]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:09:37.000Z" objectID="{28A4D41D-37EF-43BF-9736-0F9545026F0A}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="130.6343231201172" height="26.85543441772461"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{28A4D41D-37EF-43BF-9736-0F9545026F0A}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Before <a | ||
| 3 | href="https://example.invalid/paragraph">Link label</a> tail]]></one:T></one:OE><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{28A4D41D-37EF-43BF-9736-0F9545026F0A}{47}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-003.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{0F0A7E71-2F11-43B7-A18E-7820B16929B4}{1}{B0}" name="Split tag" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:TagDef index="0" type="0" symbol="3" fontColor="automatic" highlightColor="none" name="Fixture task"/><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{4B3D958D-44A8-4BEC-9143-BD6C62A8C6D6}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split tag]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{4B3D958D-44A8-4BEC-9143-BD6C62A8C6D6}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704788208008" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{4B3D958D-44A8-4BEC-9143-BD6C62A8C6D6}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:Tag index="0" completed="true" disabled="false" creationDate="2020-01-02T03:04:05.000Z" completionDate="2020-01-02T04:05:06.000Z"/><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{31F9B7D2-9291-0CB1-07D3-38D4DAD425D7}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{4B3D958D-44A8-4BEC-9143-BD6C62A8C6D6}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-004.xml created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{188FF30E-2331-4575-BAE7-BE8DFB9D3490}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Outline author="Rich author" lastModifiedBy="Rich author" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{7F435BB2-6844-46C3-B515-32560401D1F1}{10}{B0}"><one:Position x="36.0" y="14.40000057220459" z="0"/><one:Size width="127.5136947631836" height="42.90299224853515"/><one:OEChildren><one:OE creationTime="2026-09-08T04:47:24.000Z" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{7826F345-9B39-0DC9-0541-F15CCF6AA307}{1}{B0}" alignment="left"><one:T><![CDATA[<span style='font-weight:bold; | ||
| 3 | text-decoration:underline;font-family:Calibri;font-size:11.0pt'>Bold</span><span | ||
| 4 | style='font-family:Calibri;font-size:11.0pt'> </span><span style='font-family: | ||
| 5 | Arial;font-size:13.5pt'>&#129408;</span><span style='font-family:Calibri; | ||
| 6 | font-size:11.0pt'> </span><span style='font-style:italic;text-decoration:line-through; | ||
| 7 | font-family:Calibri;font-size:11.0pt'>italic</span><span style='font-family: | ||
| 8 | Calibri;font-size:11.0pt'> </span><span style='vertical-align:super;font-family: | ||
| 9 | Calibri;font-size:11.0pt'>é</span><span style='font-family:Calibri;font-size: | ||
| 10 | 11.0pt'> </span><span style='font-family:Calibri;font-size:11.0pt;color:#0C2238; | ||
| 11 | background:yellow;mso-highlight:yellow'>color</span><span style='font-family: | ||
| 12 | Calibri;font-size:11.0pt'> </span><span style='vertical-align:sub;font-family: | ||
| 13 | Calibri;font-size:11.0pt'>東京</span><span style='font-family:Calibri;font-size: | ||
| 14 | 11.0pt'><br> | ||
| 15 | End</span>]]></one:T></one:OE><one:OE author="snow" authorInitials="S" lastModifiedBy="snow" lastModifiedByInitials="S" creationTime="2026-09-05T05:06:55.000Z" lastModifiedTime="2026-09-05T05:06:56.000Z" objectID="{7F435BB2-6844-46C3-B515-32560401D1F1}{11}{B0}" alignment="left" quickStyleIndex="0" style="font-size:11.0pt;color:#1F4E79"><one:T><![CDATA[<span | ||
| 16 | style='font-weight:bold;font-family:Calibri' lang=en-US>Fictitious: café, </span><span | ||
| 17 | style='font-weight:bold;font-family:SimSun' lang=en-US>東京</span><span | ||
| 18 | style='font-weight:bold;font-family:Calibri' lang=en-US>, </span><span | ||
| 19 | style='font-weight:bold;font-family:Arial;direction:rtl;unicode-bidi:embed' | ||
| 20 | lang=ar-SA>مرحبا</span>]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-005.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{38A52E16-3377-43CF-A6D4-DFD02D336460}{1}{B0}" name="Split cell" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split cell]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="254.9588165283203" height="48.80315780639648"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{40}{B0}" alignment="left"><one:Table bordersVisible="true" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{41}{B0}"><one:Columns><one:Column index="0" width="180.0" isLocked="true"/><one:Column index="1" width="66.82881927490234"/></one:Columns><one:Row objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{42}{B0}" lastModifiedTime="2026-09-08T08:51:01.000Z"><one:Cell lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{43}{B0}"><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{46}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{FACE136C-CA78-0A6C-34CB-6BC2F7F0C835}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE></one:OEChildren></one:Cell><one:Cell lastModifiedTime="2026-09-08T08:09:37.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{54}{B0}" lastModifiedBy="virtual" lastModifiedByInitials="V"><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{57}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved cell]]></one:T></one:OE></one:OEChildren></one:Cell></one:Row></one:Table></one:OE><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{8C14E633-7850-435D-8F73-AF46AA0C4034}{62}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-006.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{40550926-0832-4E02-A8A7-012E8A2B4C46}{1}{B0}" name="Split child" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{C910063C-66E4-43E8-912A-D7C25F8D6FED}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split child]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C910063C-66E4-43E8-912A-D7C25F8D6FED}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="131.8423614501953" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C910063C-66E4-43E8-912A-D7C25F8D6FED}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved parent]]></one:T><one:OEChildren><one:OE lastModifiedBy="Rust split author" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{C910063C-66E4-43E8-912A-D7C25F8D6FED}{45}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" lastModifiedBy="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{E47C3A5A-0F36-046D-1A10-BB5F9EDF5E4F}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE></one:OEChildren></one:OE><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{C910063C-66E4-43E8-912A-D7C25F8D6FED}{53}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-007.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{82B58899-D83F-4BF5-8AA9-AF765DDD95AA}{1}{B0}" name="Split middle" dateTime="2026-09-08T08:09:29.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{A37E9D15-06C3-4690-A3DF-4D061DE6EF8E}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split middle]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A37E9D15-06C3-4690-A3DF-4D061DE6EF8E}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:30.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A37E9D15-06C3-4690-A3DF-4D061DE6EF8E}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{8AD6F11E-99EA-0573-2DD9-25F0CC322B7D}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{A37E9D15-06C3-4690-A3DF-4D061DE6EF8E}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-008.xml created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split empty]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{F8CC0112-769C-0624-19AF-E3D7C46B02D1}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{46}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-009.xml created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{A24347FF-6099-4ED9-8FB1-3F5190D09CCD}{1}{B0}" name="Split style boundary" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{23234918-7316-4356-9E55-1168D2F353CE}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split style boundary]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{23234918-7316-4356-9E55-1168D2F353CE}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{23234918-7316-4356-9E55-1168D2F353CE}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bold</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{35529659-8CEB-0DFE-0B44-65DA40345D59}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 4 | lang=en-US> </span><span style='font-style:italic' lang=en-US>italic</span><span | ||
| 5 | lang=en-US> &#129408; é </span><span style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:09:32.000Z" objectID="{23234918-7316-4356-9E55-1168D2F353CE}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-010.xml created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{A4769B89-C976-40DF-AEC6-41152F6A9095}{1}{B0}" name="Split soft break" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{F48F565B-4231-4B49-8231-96CADD1B4ECF}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split soft break]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{F48F565B-4231-4B49-8231-96CADD1B4ECF}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="468.0" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{F48F565B-4231-4B49-8231-96CADD1B4ECF}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Bo]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{2DC9F33D-F035-0427-18FE-20FB4F7168C3}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[ld<br> | ||
| 3 | soft break]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{F48F565B-4231-4B49-8231-96CADD1B4ECF}{45}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-011.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{D8398D05-B0A8-49C8-AF8A-21AAC514A41D}{1}{B0}" name="Split number" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{A83C73B5-4C4D-48E9-9843-9A9112DA788F}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split number]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{A83C73B5-4C4D-48E9-9843-9A9112DA788F}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{A83C73B5-4C4D-48E9-9843-9A9112DA788F}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:List><one:Number numberSequence="1" numberFormat="##." restartNumberingAt="3" fontSize="11.0" font="Calibri" text="III."/></one:List><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:01.000Z" lastModifiedTime="2026-09-08T08:51:01.000Z" objectID="{876C483E-C2E9-08C3-2868-4862F3F152CE}{1}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Number numberSequence="1" numberFormat="##." fontSize="11.0" font="Calibri" text="IV."/></one:List><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:09:34.000Z" objectID="{A83C73B5-4C4D-48E9-9843-9A9112DA788F}{49}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-012.xml created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{E8B9381E-92F9-462F-A40E-425B65DDC831}{1}{B0}" name="Split bullet" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{F0F229DD-2A54-4B26-9FDB-19620E3FBE11}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split bullet]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{F0F229DD-2A54-4B26-9FDB-19620E3FBE11}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="135.3173980712891" height="53.71086883544922"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{F0F229DD-2A54-4B26-9FDB-19620E3FBE11}{40}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold'>Bo</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{304138CF-55B7-054D-3586-B5C4A63AA094}{1}{B0}" alignment="left" quickStyleIndex="0"><one:List><one:Bullet bullet="3" fontSize="11.0"/></one:List><one:T><![CDATA[<span | ||
| 4 | style='font-weight:bold' lang=en-US>ld</span><span lang=en-US> </span><span | ||
| 5 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 6 | style='color:#123456' lang=x-none>tail</span>]]></one:T><one:OEChildren><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{F0F229DD-2A54-4B26-9FDB-19620E3FBE11}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved child]]></one:T></one:OE></one:OEChildren></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{F0F229DD-2A54-4B26-9FDB-19620E3FBE11}{54}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/page-013.xml created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split end]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span | ||
| 4 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 5 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:51:00.000Z" objectID="{F60211DF-6E7D-0CA1-2F70-07201B2B1F07}{1}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt;color:#123456"><one:T><![CDATA[]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:09:33.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/before-read/payloads.json created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../../../before/read/payloads.json | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/notebook/Open Notebook.onetoc2	 created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../../native/notebook/Open Notebook.onetoc2 | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/notebook/synthetic.one created| Binary files /dev/null and b/corpus/paragraph-edit/rust-split/typed/notebook/synthetic.one differ | |||
corpus/paragraph-edit/rust-split/typed/read/environment.json created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | { | ||
| 2 | "powershell": "5.1.14409.1005", | ||
| 3 | "schema": "xs2010", | ||
| 4 | "hostname": "ONE-M6-02D586B5", | ||
| 5 | "cold": false, | ||
| 6 | "onenote": "14.0.4763.1000" | ||
| 7 | } | ||
corpus/paragraph-edit/rust-split/typed/read/hierarchy.xml created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" name="notebook" nickname="notebook" ID="{5F2547AA-6079-422C-929F-ACD159424C5F}{1}{B0}" path="C:\one-tests\runs\capture\notebook" lastModifiedTime="2026-09-08T08:59:47.000Z" color="#B49EDE" isCurrentlyViewed="true"><one:Section name="synthetic" ID="{34C60088-AAFA-0664-3D80-161C07A5288F}{1}{B0}" path="C:\one-tests\runs\capture\notebook\synthetic.one" lastModifiedTime="2026-09-08T08:59:47.000Z" color="#8AA8E4" isCurrentlyViewed="true"><one:Page ID="{188FF30E-2331-4575-BAE7-BE8DFB9D3490}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{82B58899-D83F-4BF5-8AA9-AF765DDD95AA}{1}{B0}" name="Split middle" dateTime="2026-09-08T08:09:29.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{A24347FF-6099-4ED9-8FB1-3F5190D09CCD}{1}{B0}" name="Split style boundary" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:40.000Z" pageLevel="1"/><one:Page ID="{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:43.000Z" pageLevel="1"/><one:Page ID="{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:47.000Z" pageLevel="1" isCurrentlyViewed="true"/><one:Page ID="{06A1F0B6-1EEA-4375-8EED-D084C6D806D2}{1}{B0}" name="Split parent" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{40550926-0832-4E02-A8A7-012E8A2B4C46}{1}{B0}" name="Split child" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{E8B9381E-92F9-462F-A40E-425B65DDC831}{1}{B0}" name="Split bullet" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{D8398D05-B0A8-49C8-AF8A-21AAC514A41D}{1}{B0}" name="Split number" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{0F0A7E71-2F11-43B7-A18E-7820B16929B4}{1}{B0}" name="Split tag" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{38A52E16-3377-43CF-A6D4-DFD02D336460}{1}{B0}" name="Split cell" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{A4769B89-C976-40DF-AEC6-41152F6A9095}{1}{B0}" name="Split soft break" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/><one:Page ID="{0E569C7E-F5A1-4E91-A1B9-B0AEA2AF2B2B}{1}{B0}" name="Split before hyperlink" dateTime="2026-09-08T08:09:34.000Z" lastModifiedTime="2026-09-08T08:57:31.000Z" pageLevel="1"/></one:Section></one:Notebook> | ||
corpus/paragraph-edit/rust-split/typed/read/page-000.xml created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}" name="Split start" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:41.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:40.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split start]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:59:40.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:40.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Typed ]]></one:T></one:OE><one:OE author="Rust split author" lastModifiedBy="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:59:40.000Z" objectID="{8441DD7D-4E61-0CC9-1309-4B6EC734EEAF}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span | ||
| 4 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 5 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE creationTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:40.000Z" objectID="{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/read/page-001.xml created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../before-read/page-001.xml | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/read/page-002.xml created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../before-read/page-002.xml | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/read/page-003.xml created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../before-read/page-003.xml | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/read/page-004.xml created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{188FF30E-2331-4575-BAE7-BE8DFB9D3490}{1}{B0}" name="Bold 🦀 italic é color 東京" dateTime="2026-09-05T05:06:54.000Z" lastModifiedTime="2026-09-08T08:59:37.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Outline author="Rich author" lastModifiedBy="Rich author" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{7F435BB2-6844-46C3-B515-32560401D1F1}{10}{B0}"><one:Position x="36.0" y="14.40000057220459" z="0"/><one:Size width="523.125" height="42.90299224853515"/><one:OEChildren><one:OE creationTime="2026-09-08T04:47:24.000Z" lastModifiedTime="2026-09-08T04:47:24.000Z" objectID="{7826F345-9B39-0DC9-0541-F15CCF6AA307}{1}{B0}" alignment="left"><one:T><![CDATA[<span style='font-weight:bold; | ||
| 3 | text-decoration:underline;font-family:Calibri;font-size:11.0pt'>Bold</span><span | ||
| 4 | style='font-family:Calibri;font-size:11.0pt'> </span><span style='font-family: | ||
| 5 | Arial;font-size:13.5pt'>&#129408;</span><span style='font-family:Calibri; | ||
| 6 | font-size:11.0pt'> </span><span style='font-style:italic;text-decoration:line-through; | ||
| 7 | font-family:Calibri;font-size:11.0pt'>italic</span><span style='font-family: | ||
| 8 | Calibri;font-size:11.0pt'> </span><span style='vertical-align:super;font-family: | ||
| 9 | Calibri;font-size:11.0pt'>é</span><span style='font-family:Calibri;font-size: | ||
| 10 | 11.0pt'> </span><span style='font-family:Calibri;font-size:11.0pt;color:#0C2238; | ||
| 11 | background:yellow;mso-highlight:yellow'>color</span><span style='font-family: | ||
| 12 | Calibri;font-size:11.0pt'> </span><span style='vertical-align:sub;font-family: | ||
| 13 | Calibri;font-size:11.0pt'>東京</span><span style='font-family:Calibri;font-size: | ||
| 14 | 11.0pt'><br> | ||
| 15 | End</span>]]></one:T></one:OE><one:OE author="snow" authorInitials="S" lastModifiedBy="snow" lastModifiedByInitials="S" creationTime="2026-09-05T05:06:55.000Z" lastModifiedTime="2026-09-05T05:06:56.000Z" objectID="{7F435BB2-6844-46C3-B515-32560401D1F1}{11}{B0}" alignment="left" quickStyleIndex="0" style="font-size:11.0pt;color:#1F4E79"><one:T><![CDATA[<span | ||
| 16 | style='font-weight:bold;font-family:Calibri' lang=en-US>Fictitious: café, </span><span | ||
| 17 | style='font-weight:bold;font-family:SimSun' lang=en-US>東京</span><span | ||
| 18 | style='font-weight:bold;font-family:Calibri' lang=en-US>, </span><span | ||
| 19 | style='font-weight:bold;font-family:Arial;direction:rtl;unicode-bidi:embed' | ||
| 20 | lang=ar-SA>مرحبا</span>]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/read/page-005.xml created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../before-read/page-005.xml | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/read/page-006.xml created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../before-read/page-006.xml | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/read/page-007.xml created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../before-read/page-007.xml | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/read/page-008.xml created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}" name="Split empty" dateTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:47.000Z" pageLevel="1" isCurrentlyViewed="true" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:43.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split empty]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" lastModifiedTime="2026-09-08T08:59:46.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="115.6704635620117" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:44.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Typed ]]></one:T></one:OE><one:OE author="Rust split author" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:59:46.000Z" objectID="{F8CC0112-769C-0624-19AF-E3D7C46B02D1}{1}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Typed ]]></one:T></one:OE><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:43.000Z" objectID="{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{46}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/read/page-009.xml created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../before-read/page-009.xml | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/read/page-010.xml created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../before-read/page-010.xml | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/read/page-011.xml created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../before-read/page-011.xml | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/read/page-012.xml created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../before-read/page-012.xml | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/read/page-013.xml created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | <?xml version="1.0"?> | ||
| 2 | <one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote" ID="{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}" name="Split end" dateTime="2026-09-08T08:09:32.000Z" lastModifiedTime="2026-09-08T08:59:43.000Z" pageLevel="1" lang="en-US"><one:QuickStyleDef index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0"/><one:PageSettings RTL="false" color="automatic"><one:PageSize><one:Automatic/></one:PageSize><one:RuleLines visible="false"/></one:PageSettings><one:Title lang="en-US"><one:OE author="virtual" authorInitials="V" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:42.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{33}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:17.0pt"><one:T><![CDATA[Split end]]></one:T></one:OE></one:Title><one:Outline author="virtual" authorInitials="V" lastModifiedBy="Rust split author" lastModifiedTime="2026-09-08T08:59:42.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{39}{B0}"><one:Position x="72.0" y="108.0" z="0"/><one:Size width="116.921875" height="40.28315734863281"/><one:OEChildren><one:OE creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:42.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{40}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[<span | ||
| 3 | style='font-weight:bold' lang=en-US>Bold</span><span lang=en-US> </span><span | ||
| 4 | style='font-style:italic' lang=en-US>italic</span><span lang=en-US> &#129408; é </span><span | ||
| 5 | style='color:#123456' lang=x-none>tail</span>]]></one:T></one:OE><one:OE author="Rust split author" lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:51:00.000Z" lastModifiedTime="2026-09-08T08:59:42.000Z" objectID="{F60211DF-6E7D-0CA1-2F70-07201B2B1F07}{1}{B0}" alignment="left" quickStyleIndex="0" style="font-family:Calibri;font-size:11.0pt;color:#123456"><one:T><![CDATA[Typed ]]></one:T></one:OE><one:OE lastModifiedBy="virtual" lastModifiedByInitials="V" creationTime="2026-09-08T08:09:33.000Z" lastModifiedTime="2026-09-08T08:59:42.000Z" objectID="{A660EE59-AF8B-4E53-A977-0213DD2E1818}{48}{B0}" alignment="left" quickStyleIndex="0"><one:T><![CDATA[Preserved sibling]]></one:T></one:OE></one:OEChildren></one:Outline></one:Page> | ||
corpus/paragraph-edit/rust-split/typed/read/payloads.json created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../../../before/read/payloads.json | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/run.json created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | { | ||
| 2 | "notebook": "/Users/clo/dev/one/evidence/m10/paragraph-rust-split-01/native/notebook", | ||
| 3 | "expected_pages": 14, | ||
| 4 | "author": null, | ||
| 5 | "author_timeout_seconds": 600, | ||
| 6 | "inspect": true, | ||
| 7 | "collect_notebook": true, | ||
| 8 | "base": { | ||
| 9 | "file": "win7-office-base.qcow2", | ||
| 10 | "format": "qcow2", | ||
| 11 | "sha256": "a1a4f8fab782ee14885ff801ca2f6347c208fdcfc3513637096f314315c89346", | ||
| 12 | "virtual_size": 68719476736 | ||
| 13 | }, | ||
| 14 | "scripts": { | ||
| 15 | "cold.ps1": "c177fc72ae6c2634d186f5671a880de20b09f9716532c37c69cb13aa15c7e331", | ||
| 16 | "read.ps1": "04013bfcccee40a17e2a225f9b9e96f40a3a8daad9e350609654f8eda3ccbb41" | ||
| 17 | } | ||
| 18 | } | ||
corpus/paragraph-edit/rust-split/typed/source.json created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | [ | ||
| 2 | { | ||
| 3 | "path": "Open Notebook.onetoc2", | ||
| 4 | "bytes": 4800, | ||
| 5 | "sha256": "7c258d318aaa6089989a7beb427a820beb99ebd7833f2a76ecbbb3713df07dbb", | ||
| 6 | "mtime_ns": 1788857651415033964 | ||
| 7 | }, | ||
| 8 | { | ||
| 9 | "path": "synthetic.one", | ||
| 10 | "bytes": 110224, | ||
| 11 | "sha256": "29a64584c4d7ac72958595769854a3df199156cb89541df354d9e9f484450712", | ||
| 12 | "mtime_ns": 1788857651415524756 | ||
| 13 | } | ||
| 14 | ] | ||
corpus/paragraph-edit/rust-split/typed/teardown.json created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../../joined/teardown.json | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/ui/selections.json created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | [ | ||
| 2 | { | ||
| 3 | "case": "Split start", | ||
| 4 | "index": 0, | ||
| 5 | "page": "{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}", | ||
| 6 | "object": "{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{40}{B0}", | ||
| 7 | "text": "Typed " | ||
| 8 | }, | ||
| 9 | { | ||
| 10 | "case": "Split end", | ||
| 11 | "index": 1, | ||
| 12 | "page": "{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}", | ||
| 13 | "object": "{F60211DF-6E7D-0CA1-2F70-07201B2B1F07}{1}{B0}", | ||
| 14 | "text": "Typed " | ||
| 15 | }, | ||
| 16 | { | ||
| 17 | "case": "Split empty", | ||
| 18 | "index": 0, | ||
| 19 | "page": "{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}", | ||
| 20 | "object": "{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{40}{B0}", | ||
| 21 | "text": "Typed " | ||
| 22 | }, | ||
| 23 | { | ||
| 24 | "case": "Split empty", | ||
| 25 | "index": 1, | ||
| 26 | "page": "{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}", | ||
| 27 | "object": "{F8CC0112-769C-0624-19AF-E3D7C46B02D1}{1}{B0}", | ||
| 28 | "text": "Typed " | ||
| 29 | } | ||
| 30 | ] | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/ui/split-empty-0.ahk created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | #Requires AutoHotkey v2.0 | ||
| 2 | OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1))) | ||
| 3 | dm := Buffer(220, 0) | ||
| 4 | NumPut("UShort", 220, dm, 68) | ||
| 5 | if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm) | ||
| 6 | throw Error("Cannot inspect display mode") | ||
| 7 | NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72) | ||
| 8 | NumPut("UInt", 1280, dm, 172) | ||
| 9 | NumPut("UInt", 720, dm, 176) | ||
| 10 | if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0 | ||
| 11 | throw Error("Display mode rejected") | ||
| 12 | app := ComObject("OneNote.Application") | ||
| 13 | app.NavigateTo("{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}", "{77D1B2CB-BFAF-4106-8E28-90895EBDFE03}{40}{B0}", false) | ||
| 14 | hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10) | ||
| 15 | if !hwnd | ||
| 16 | throw Error("OneNote window did not appear") | ||
| 17 | WinMaximize(hwnd) | ||
| 18 | WinActivate(hwnd) | ||
| 19 | if !WinWaitActive(hwnd,, 10) | ||
| 20 | throw Error("OneNote window did not become active") | ||
| 21 | Sleep 300 | ||
| 22 | Send "{Left}" | ||
| 23 | SendText "Typed " | ||
corpus/paragraph-edit/rust-split/typed/ui/split-empty-0.json created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../../../joined/ui/split-empty.json | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/ui/split-empty-0.png created| Binary files /dev/null and b/corpus/paragraph-edit/rust-split/typed/ui/split-empty-0.png differ | |||
corpus/paragraph-edit/rust-split/typed/ui/split-empty-1.ahk created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | #Requires AutoHotkey v2.0 | ||
| 2 | OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1))) | ||
| 3 | dm := Buffer(220, 0) | ||
| 4 | NumPut("UShort", 220, dm, 68) | ||
| 5 | if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm) | ||
| 6 | throw Error("Cannot inspect display mode") | ||
| 7 | NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72) | ||
| 8 | NumPut("UInt", 1280, dm, 172) | ||
| 9 | NumPut("UInt", 720, dm, 176) | ||
| 10 | if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0 | ||
| 11 | throw Error("Display mode rejected") | ||
| 12 | app := ComObject("OneNote.Application") | ||
| 13 | app.NavigateTo("{984F0936-3DA3-4D19-B112-F3CA259A4148}{1}{B0}", "{F8CC0112-769C-0624-19AF-E3D7C46B02D1}{1}{B0}", false) | ||
| 14 | hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10) | ||
| 15 | if !hwnd | ||
| 16 | throw Error("OneNote window did not appear") | ||
| 17 | WinMaximize(hwnd) | ||
| 18 | WinActivate(hwnd) | ||
| 19 | if !WinWaitActive(hwnd,, 10) | ||
| 20 | throw Error("OneNote window did not become active") | ||
| 21 | Sleep 300 | ||
| 22 | Send "{Left}" | ||
| 23 | SendText "Typed " | ||
corpus/paragraph-edit/rust-split/typed/ui/split-empty-1.json created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../../../joined/ui/split-empty.json | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/ui/split-empty-1.png created| Binary files /dev/null and b/corpus/paragraph-edit/rust-split/typed/ui/split-empty-1.png differ | |||
corpus/paragraph-edit/rust-split/typed/ui/split-end-1.ahk created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | #Requires AutoHotkey v2.0 | ||
| 2 | OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1))) | ||
| 3 | dm := Buffer(220, 0) | ||
| 4 | NumPut("UShort", 220, dm, 68) | ||
| 5 | if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm) | ||
| 6 | throw Error("Cannot inspect display mode") | ||
| 7 | NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72) | ||
| 8 | NumPut("UInt", 1280, dm, 172) | ||
| 9 | NumPut("UInt", 720, dm, 176) | ||
| 10 | if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0 | ||
| 11 | throw Error("Display mode rejected") | ||
| 12 | app := ComObject("OneNote.Application") | ||
| 13 | app.NavigateTo("{EEE8E5F3-7A14-4AA5-B06A-56D4BAC7C8AF}{1}{B0}", "{F60211DF-6E7D-0CA1-2F70-07201B2B1F07}{1}{B0}", false) | ||
| 14 | hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10) | ||
| 15 | if !hwnd | ||
| 16 | throw Error("OneNote window did not appear") | ||
| 17 | WinMaximize(hwnd) | ||
| 18 | WinActivate(hwnd) | ||
| 19 | if !WinWaitActive(hwnd,, 10) | ||
| 20 | throw Error("OneNote window did not become active") | ||
| 21 | Sleep 300 | ||
| 22 | Send "{Left}" | ||
| 23 | SendText "Typed " | ||
corpus/paragraph-edit/rust-split/typed/ui/split-end-1.json created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../../../joined/ui/split-end.json | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/ui/split-end-1.png created| Binary files /dev/null and b/corpus/paragraph-edit/rust-split/typed/ui/split-end-1.png differ | |||
corpus/paragraph-edit/rust-split/typed/ui/split-start-0.ahk created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | #Requires AutoHotkey v2.0 | ||
| 2 | OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1))) | ||
| 3 | dm := Buffer(220, 0) | ||
| 4 | NumPut("UShort", 220, dm, 68) | ||
| 5 | if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm) | ||
| 6 | throw Error("Cannot inspect display mode") | ||
| 7 | NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72) | ||
| 8 | NumPut("UInt", 1280, dm, 172) | ||
| 9 | NumPut("UInt", 720, dm, 176) | ||
| 10 | if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0 | ||
| 11 | throw Error("Display mode rejected") | ||
| 12 | app := ComObject("OneNote.Application") | ||
| 13 | app.NavigateTo("{058E24C9-6521-4913-9088-94646869E7EC}{1}{B0}", "{7DB914B1-2E9B-4E51-B78C-87B90E14A385}{40}{B0}", false) | ||
| 14 | hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10) | ||
| 15 | if !hwnd | ||
| 16 | throw Error("OneNote window did not appear") | ||
| 17 | WinMaximize(hwnd) | ||
| 18 | WinActivate(hwnd) | ||
| 19 | if !WinWaitActive(hwnd,, 10) | ||
| 20 | throw Error("OneNote window did not become active") | ||
| 21 | Sleep 300 | ||
| 22 | Send "{Left}" | ||
| 23 | SendText "Typed " | ||
corpus/paragraph-edit/rust-split/typed/ui/split-start-0.json created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | ../../../joined/ui/split-start.json | ||
| \ No newline at end of file | |||
corpus/paragraph-edit/rust-split/typed/ui/split-start-0.png created| Binary files /dev/null and b/corpus/paragraph-edit/rust-split/typed/ui/split-start-0.png differ | |||
crates/onestore/README.md+9| ... | @@ -49,6 +49,7 @@ harness also accepts `--client-profile release`. | ... | @@ -49,6 +49,7 @@ harness also accepts `--client-profile release`. |
| 49 | | `replace_property_bytes` | Append one scalar-property revision; preserve prior revisions and unrelated property values and references | | 49 | | `replace_property_bytes` | Append one scalar-property revision; preserve prior revisions and unrelated property values and references | |
| 50 | | `replace_text`, `commit_text`, `commit_file_text` | Replace a UTF-16 range across ordinary text runs; publish text, run boundaries and modification time together | | 50 | | `replace_text`, `commit_text`, `commit_file_text` | Replace a UTF-16 range across ordinary text runs; publish text, run boundaries and modification time together | |
| 51 | | `Insertion`, `PreparedEdit::insert` | Insert paragraphs into editable containers or positioned outlines into a page, retaining intent identities across rebases | | 51 | | `Insertion`, `PreparedEdit::insert` | Insert paragraphs into editable containers or positioned outlines into a page, retaining intent identities across rebases | |
| 52 | | `ParagraphSplit`, `PreparedEdit::split` | Split ordinary text at a UTF-16 scalar boundary, retaining the original left identities and moving children to the right | | ||
| 52 | | `TextAttribute`, `PreparedEdit::format` | Change character formatting over a UTF-16 range while sharing immutable styles; preserve unselected runs | | 53 | | `TextAttribute`, `PreparedEdit::format` | Change character formatting over a UTF-16 range while sharing immutable styles; preserve unselected runs | |
| 53 | | `PreparedEdit::commit`, `PreparedEdit::commit_file` | Publish the exact prepared image under caller-held exclusion or the conservative filesystem adapter | | 54 | | `PreparedEdit::commit`, `PreparedEdit::commit_file` | Publish the exact prepared image under caller-held exclusion or the conservative filesystem adapter | |
| 54 | | `read_file` | Read a snapshot under whole-file exclusion | | 55 | | `read_file` | Read a snapshot under whole-file exclusion | |
| ... | @@ -77,6 +78,13 @@ accepts one `0..0` span for subsequent typing. Retain the `Insertion` value for | ... | @@ -77,6 +78,13 @@ accepts one `0..0` span for subsequent typing. Retain the `Insertion` value for |
| 77 | value creates different object identities. Duplicate insertion identities require | 78 | value creates different object identities. Duplicate insertion identities require |
| 78 | reconciliation. Formatting accepts explicit attributes, preserves inherited values, | 79 | reconciliation. Formatting accepts explicit attributes, preserves inherited values, |
| 79 | and gives retired immutable styles zero current references while retaining history. | 80 | and gives retired immutable styles zero current references while retaining history. |
| 81 | Paragraph splits preserve character formatting, retain tags on the left, and clone | ||
| 82 | mutable list objects without restarting numbering. The new right paragraph/text | ||
| 83 | identities belong to the retained `ParagraphSplit` intent. Its publication includes | ||
| 84 | the complete child graph and title metadata; repeating an existing identity requires | ||
| 85 | reconciliation. Title containers, generated fields, recording-linked text and | ||
| 86 | associated run metadata are rejected before I/O. Native split controls and subsequent | ||
| 87 | typing checks reside in [the paragraph corpus](../../corpus/paragraph-edit/README.md). | ||
| 80 | Generated fields, protected targets and unsupported run-data boundary changes are | 88 | Generated fields, protected targets and unsupported run-data boundary changes are |
| 81 | rejected before publication. Local caches expose text, insertion and formatting edits; | 89 | rejected before publication. Local caches expose text, insertion and formatting edits; |
| 82 | the [document-writer acceptance](../../evidence/MILESTONE9.md#document-writer-and-offline-acceptance) | 90 | the [document-writer acceptance](../../evidence/MILESTONE9.md#document-writer-and-offline-acceptance) |
| ... | @@ -215,6 +223,7 @@ subsets of unflushed bytes and is shared with the stateful commit fuzzer. | ... | @@ -215,6 +223,7 @@ subsets of unflushed bytes and is shared with the stateful commit fuzzer. |
| 215 | ```sh | 223 | ```sh |
| 216 | cargo +nightly fuzz run revisions -- -max_total_time=120 -max_len=262144 -rss_limit_mb=2048 | 224 | cargo +nightly fuzz run revisions -- -max_total_time=120 -max_len=262144 -rss_limit_mb=2048 |
| 217 | cargo +nightly fuzz run commit -- -max_total_time=300 -max_len=4096 -rss_limit_mb=2048 | 225 | cargo +nightly fuzz run commit -- -max_total_time=300 -max_len=4096 -rss_limit_mb=2048 |
| 226 | cargo +nightly fuzz run paragraph -- -max_total_time=120 -max_len=160 -rss_limit_mb=2048 | ||
| 218 | ``` | 227 | ``` |
| 219 | 228 | ||
| 220 | Fuzz targets cover storage, properties, revisions, scalar edits, creation, and | 229 | Fuzz targets cover storage, properties, revisions, scalar edits, creation, and |
crates/onestore/src/commit.rs+13| ... | @@ -183,6 +183,19 @@ pub struct PreparedEdit<'a> { | ... | @@ -183,6 +183,19 @@ pub struct PreparedEdit<'a> { |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | impl<'a> PreparedEdit<'a> { | 185 | impl<'a> PreparedEdit<'a> { |
| 186 | /// Splits a paragraph and updates its children, lists, tags and title metadata atomically. | ||
| 187 | /// Fields and associated run metadata are rejected before I/O. | ||
| 188 | pub fn split( | ||
| 189 | source: &'a [u8], | ||
| 190 | space: ExGuid, | ||
| 191 | split: &crate::ParagraphSplit, | ||
| 192 | ) -> Result<Self, crate::Error> { | ||
| 193 | Ok(Self { | ||
| 194 | source, | ||
| 195 | written: split.apply(source, space)?, | ||
| 196 | }) | ||
| 197 | } | ||
| 198 | |||
| 186 | /// Prepares an insertion and its dependent metadata in one revision, without I/O. | 199 | /// Prepares an insertion and its dependent metadata in one revision, without I/O. |
| 187 | pub fn insert( | 200 | pub fn insert( |
| 188 | source: &'a [u8], | 201 | source: &'a [u8], |
crates/onestore/src/lib.rs+2| ... | @@ -11,6 +11,7 @@ mod flush; | ... | @@ -11,6 +11,7 @@ mod flush; |
| 11 | mod formatting; | 11 | mod formatting; |
| 12 | mod insertion; | 12 | mod insertion; |
| 13 | mod objects; | 13 | mod objects; |
| 14 | mod paragraph; | ||
| 14 | mod properties; | 15 | mod properties; |
| 15 | #[cfg(feature = "protected")] | 16 | #[cfg(feature = "protected")] |
| 16 | pub mod protected; | 17 | pub mod protected; |
| ... | @@ -31,6 +32,7 @@ pub use files::FileDataReference; | ... | @@ -31,6 +32,7 @@ pub use files::FileDataReference; |
| 31 | pub use formatting::TextAttribute; | 32 | pub use formatting::TextAttribute; |
| 32 | pub use insertion::Insertion; | 33 | pub use insertion::Insertion; |
| 33 | pub use objects::{Object, ObjectData, ObjectReferences, ResolvedRevision}; | 34 | pub use objects::{Object, ObjectData, ObjectReferences, ResolvedRevision}; |
| 35 | pub use paragraph::ParagraphSplit; | ||
| 34 | pub use properties::{IdStream, Property, PropertySets, Value}; | 36 | pub use properties::{IdStream, Property, PropertySets, Value}; |
| 35 | pub use revisions::{ExGuid, ObjectSpace, Revision, RevisionIndex}; | 37 | pub use revisions::{ExGuid, ObjectSpace, Revision, RevisionIndex}; |
| 36 | pub use snapshot::{read_snapshot, read_storage_snapshot}; | 38 | pub use snapshot::{read_snapshot, read_storage_snapshot}; |
crates/onestore/src/paragraph.rs created+383| ... | @@ -0,0 +1,383 @@ | ||
| 1 | use crate::{ | ||
| 2 | Error, ExGuid, Object, ObjectData, PropertySets, RevisionIndex, Store, | ||
| 3 | create::{current_timestamps, properties, string}, | ||
| 4 | document::{Document, Element, Kind}, | ||
| 5 | edit::{editable_parents, page_title}, | ||
| 6 | write::{PropertyObject, fresh_guid, write_revision}, | ||
| 7 | }; | ||
| 8 | use serde::{Deserialize, Serialize}; | ||
| 9 | use std::{ | ||
| 10 | collections::{BTreeMap, BTreeSet}, | ||
| 11 | ops::Range, | ||
| 12 | sync::Arc, | ||
| 13 | }; | ||
| 14 | |||
| 15 | fn invalid(message: &'static str) -> Error { | ||
| 16 | Error { offset: 0, message } | ||
| 17 | } | ||
| 18 | |||
| 19 | /// Splits ordinary paragraph text while retaining the new objects' identities across retries. | ||
| 20 | /// The original paragraph/text remain on the left; nested children move to the right. | ||
| 21 | #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||
| 22 | #[serde(deny_unknown_fields)] | ||
| 23 | pub struct ParagraphSplit { | ||
| 24 | guid: [u8; 16], | ||
| 25 | text: ExGuid, | ||
| 26 | offset: u32, | ||
| 27 | author: String, | ||
| 28 | created: u32, | ||
| 29 | } | ||
| 30 | |||
| 31 | impl ParagraphSplit { | ||
| 32 | /// The offset is measured in UTF-16 code units and must lie between Unicode scalars. | ||
| 33 | pub fn new(text: ExGuid, offset: u32, author: &str) -> Result<Self, Error> { | ||
| 34 | if text.guid == [0; 16] || author.contains('\0') { | ||
| 35 | return Err(invalid( | ||
| 36 | "Choose paragraph text and an author name without NUL", | ||
| 37 | )); | ||
| 38 | } | ||
| 39 | Ok(Self { | ||
| 40 | guid: fresh_guid()?, | ||
| 41 | text, | ||
| 42 | offset, | ||
| 43 | author: author.to_owned(), | ||
| 44 | created: current_timestamps()?.0, | ||
| 45 | }) | ||
| 46 | } | ||
| 47 | |||
| 48 | /// Identity of the new right paragraph. | ||
| 49 | pub fn object(&self) -> ExGuid { | ||
| 50 | ExGuid { | ||
| 51 | guid: self.guid, | ||
| 52 | n: 1, | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | /// Identity of the new right paragraph's text. | ||
| 57 | pub fn text_object(&self) -> ExGuid { | ||
| 58 | ExGuid { | ||
| 59 | guid: self.guid, | ||
| 60 | n: 2, | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | pub(crate) fn apply(&self, source: &[u8], space: ExGuid) -> Result<Vec<u8>, Error> { | ||
| 65 | if self.guid == [0; 16] || self.text.guid == [0; 16] || self.author.contains('\0') { | ||
| 66 | return Err(invalid( | ||
| 67 | "Choose paragraph text and an author name without NUL", | ||
| 68 | )); | ||
| 69 | } | ||
| 70 | let store = Store::parse(source)?; | ||
| 71 | let index = RevisionIndex::parse(&store)?; | ||
| 72 | index.validate_current()?; | ||
| 73 | let mut document = Document::parse(&index)?; | ||
| 74 | let pages: Vec<_> = document | ||
| 75 | .pages()? | ||
| 76 | .into_iter() | ||
| 77 | .filter_map(|(sid, page)| (sid == space).then_some(page)) | ||
| 78 | .collect(); | ||
| 79 | let [page] = pages.as_slice() else { | ||
| 80 | return Err(invalid("Splitting requires a single active page")); | ||
| 81 | }; | ||
| 82 | let semantic = document | ||
| 83 | .spaces | ||
| 84 | .remove(&space) | ||
| 85 | .ok_or_else(|| invalid("The active page is unavailable"))?; | ||
| 86 | let rid = semantic.contexts[&ExGuid::default()]; | ||
| 87 | let mut view = semantic | ||
| 88 | .revisions | ||
| 89 | .into_iter() | ||
| 90 | .find_map(|(id, view)| (id == rid).then_some(view)) | ||
| 91 | .unwrap(); | ||
| 92 | let parents = editable_parents(&view, &pages, self.text)?; | ||
| 93 | let [paragraph] = parents | ||
| 94 | .get(&self.text) | ||
| 95 | .map(Vec::as_slice) | ||
| 96 | .unwrap_or_default() | ||
| 97 | else { | ||
| 98 | return Err(invalid("Select text belonging to one paragraph")); | ||
| 99 | }; | ||
| 100 | let [parent] = parents | ||
| 101 | .get(paragraph) | ||
| 102 | .map(Vec::as_slice) | ||
| 103 | .unwrap_or_default() | ||
| 104 | else { | ||
| 105 | return Err(invalid("Select a paragraph with one parent")); | ||
| 106 | }; | ||
| 107 | let left = &view.nodes[paragraph]; | ||
| 108 | let Kind::Paragraph { lists, .. } = &left.kind else { | ||
| 109 | return Err(invalid("Select ordinary paragraph text")); | ||
| 110 | }; | ||
| 111 | if left.content != [self.text] | ||
| 112 | || !matches!( | ||
| 113 | view.nodes[parent].kind, | ||
| 114 | Kind::Outline { .. } | ||
| 115 | | Kind::OutlineGroup | ||
| 116 | | Kind::Paragraph { .. } | ||
| 117 | | Kind::Cell { .. } | ||
| 118 | ) | ||
| 119 | { | ||
| 120 | return Err(invalid( | ||
| 121 | "Select ordinary paragraph text inside an outline or table cell", | ||
| 122 | )); | ||
| 123 | } | ||
| 124 | let mut ancestors = BTreeSet::new(); | ||
| 125 | let mut pending = vec![*paragraph]; | ||
| 126 | while let Some(id) = pending.pop() { | ||
| 127 | if !ancestors.insert(id) { | ||
| 128 | continue; | ||
| 129 | } | ||
| 130 | if matches!(view.nodes[&id].kind, Kind::Title) { | ||
| 131 | return Err(invalid( | ||
| 132 | "Title containers cannot be split into ordinary paragraphs", | ||
| 133 | )); | ||
| 134 | } | ||
| 135 | pending.extend(parents.get(&id).into_iter().flatten().copied()); | ||
| 136 | } | ||
| 137 | let node = &view.nodes[&self.text]; | ||
| 138 | let Kind::RichText { | ||
| 139 | text, | ||
| 140 | runs, | ||
| 141 | boilerplate, | ||
| 142 | .. | ||
| 143 | } = &node.kind | ||
| 144 | else { | ||
| 145 | return Err(invalid("Select ordinary paragraph text")); | ||
| 146 | }; | ||
| 147 | if *boilerplate || !node.media_ids.is_empty() || node.media_time_ms.is_some() { | ||
| 148 | return Err(invalid( | ||
| 149 | "Generated or recording-linked text cannot be split", | ||
| 150 | )); | ||
| 151 | } | ||
| 152 | for run in view.text_runs(self.text)? { | ||
| 153 | if [ | ||
| 154 | run.format.hidden, | ||
| 155 | run.format.hyperlink, | ||
| 156 | run.format.math, | ||
| 157 | run.format.embedded_object, | ||
| 158 | ] | ||
| 159 | .contains(&Some(true)) | ||
| 160 | || run.text.contains(['\u{fffc}', '\u{fddf}']) | ||
| 161 | { | ||
| 162 | return Err(invalid( | ||
| 163 | "This paragraph contains a field or embedded object that cannot be split", | ||
| 164 | )); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | let raw = index.resolve(space, rid)?; | ||
| 168 | let ObjectData::Properties(blob) = raw.objects[&self.text].data else { | ||
| 169 | unreachable!() | ||
| 170 | }; | ||
| 171 | if PropertySets::parse(blob)?.sets[0] | ||
| 172 | .iter() | ||
| 173 | .any(|p| matches!(p.id, 0x40003499 | 0x24003458)) | ||
| 174 | { | ||
| 175 | return Err(invalid( | ||
| 176 | "This paragraph contains run metadata that cannot be split", | ||
| 177 | )); | ||
| 178 | } | ||
| 179 | let length = u32::try_from(text.encode_utf16().count()) | ||
| 180 | .map_err(|_| invalid("Paragraph exceeds the UTF-16 offset range"))?; | ||
| 181 | if self.offset > length || lists.len() > 251 { | ||
| 182 | return Err(invalid( | ||
| 183 | "Choose a position within the paragraph and at most 251 list levels", | ||
| 184 | )); | ||
| 185 | } | ||
| 186 | let author_id = ExGuid { | ||
| 187 | guid: self.guid, | ||
| 188 | n: 3, | ||
| 189 | }; | ||
| 190 | let normal_id = ExGuid { | ||
| 191 | guid: self.guid, | ||
| 192 | n: 4, | ||
| 193 | }; | ||
| 194 | let typing = runs.last().and_then(|run| run.format).unwrap_or(normal_id); | ||
| 195 | let modified = current_timestamps()?.0.to_le_bytes(); | ||
| 196 | let mut changed = BTreeMap::new(); | ||
| 197 | if (self.offset == 0 && !text.is_empty()) || runs.iter().any(|run| run.format.is_none()) { | ||
| 198 | changed.insert( | ||
| 199 | normal_id, | ||
| 200 | PropertyObject { | ||
| 201 | jcid: 0x12004d, | ||
| 202 | bytes: properties(&[])?, | ||
| 203 | global_ids: Arc::new(BTreeMap::from([(0, self.guid)])), | ||
| 204 | }, | ||
| 205 | ); | ||
| 206 | } | ||
| 207 | let mut prefix = fragment( | ||
| 208 | &raw.objects[&self.text], | ||
| 209 | node, | ||
| 210 | 0..self.offset, | ||
| 211 | if text.is_empty() { typing } else { normal_id }, | ||
| 212 | )?; | ||
| 213 | let mut suffix = fragment(&raw.objects[&self.text], node, self.offset..length, typing)?; | ||
| 214 | prefix.set(&[(0x14001d7a, &modified)])?; | ||
| 215 | suffix.remove(&[0x40003489])?; | ||
| 216 | suffix.set(&[(0x14001d7a, &modified)])?; | ||
| 217 | suffix.reference(self.text_object())?; | ||
| 218 | changed.insert(self.text, prefix); | ||
| 219 | changed.insert(self.text_object(), suffix); | ||
| 220 | changed.insert( | ||
| 221 | author_id, | ||
| 222 | PropertyObject { | ||
| 223 | jcid: 0x120001, | ||
| 224 | bytes: properties(&[(0x1c001d75, string(&self.author))])?, | ||
| 225 | global_ids: Arc::new(BTreeMap::from([(0, self.guid)])), | ||
| 226 | }, | ||
| 227 | ); | ||
| 228 | let mut right = PropertyObject::from_object(&raw.objects[paragraph])?; | ||
| 229 | let content = right.reference(self.text_object())?; | ||
| 230 | let author = right.reference(author_id)?; | ||
| 231 | right.set(&[ | ||
| 232 | (0x24001c1f, &content), | ||
| 233 | (0x14001d09, &self.created.to_le_bytes()), | ||
| 234 | (0x20001d78, &author), | ||
| 235 | (0x20001d79, &author), | ||
| 236 | (0x14001d7a, &modified), | ||
| 237 | ])?; | ||
| 238 | if !lists.is_empty() { | ||
| 239 | let mut references = Vec::new(); | ||
| 240 | for (i, old) in lists.iter().enumerate() { | ||
| 241 | if !matches!(view.nodes[old].kind, Kind::List { .. }) { | ||
| 242 | return Err(invalid("The paragraph list is unavailable")); | ||
| 243 | } | ||
| 244 | let id = ExGuid { | ||
| 245 | guid: self.guid, | ||
| 246 | n: 5 + u32::try_from(i).unwrap(), | ||
| 247 | }; | ||
| 248 | let mut list = PropertyObject::from_object(&raw.objects[old])?; | ||
| 249 | list.remove(&[0x14001cb7])?; | ||
| 250 | list.reference(id)?; | ||
| 251 | references.extend_from_slice(&right.reference(id)?); | ||
| 252 | changed.insert(id, list); | ||
| 253 | } | ||
| 254 | right.set(&[(0x24001c26, &references)])?; | ||
| 255 | } | ||
| 256 | changed.insert(self.object(), right); | ||
| 257 | let mut original = PropertyObject::from_object(&raw.objects[paragraph])?; | ||
| 258 | original.remove(&[0x24001c20])?; | ||
| 259 | let author = original.reference(author_id)?; | ||
| 260 | original.set(&[(0x20001d79, &author), (0x14001d7a, &modified)])?; | ||
| 261 | changed.insert(*paragraph, original); | ||
| 262 | let mut parent_object = PropertyObject::from_object(&raw.objects[parent])?; | ||
| 263 | let mut children = Vec::new(); | ||
| 264 | for child in &view.nodes[parent].children { | ||
| 265 | children.extend_from_slice(&parent_object.reference(*child)?); | ||
| 266 | if child == paragraph { | ||
| 267 | children.extend_from_slice(&parent_object.reference(self.object())?); | ||
| 268 | } | ||
| 269 | } | ||
| 270 | parent_object.set(&[(0x24001c20, &children)])?; | ||
| 271 | changed.insert(*parent, parent_object); | ||
| 272 | if changed | ||
| 273 | .keys() | ||
| 274 | .any(|id| id.guid == self.guid && raw.objects.contains_key(id)) | ||
| 275 | { | ||
| 276 | return Err(invalid( | ||
| 277 | "A split identity already exists; reconcile the existing edit", | ||
| 278 | )); | ||
| 279 | } | ||
| 280 | for id in ancestors { | ||
| 281 | let object = match changed.entry(id) { | ||
| 282 | std::collections::btree_map::Entry::Occupied(entry) => entry.into_mut(), | ||
| 283 | std::collections::btree_map::Entry::Vacant(entry) => { | ||
| 284 | entry.insert(PropertyObject::from_object(&raw.objects[&id])?) | ||
| 285 | } | ||
| 286 | }; | ||
| 287 | object.set(&[(0x14001d7a, &modified)])?; | ||
| 288 | } | ||
| 289 | for (id, object) in &changed { | ||
| 290 | view.nodes.insert( | ||
| 291 | *id, | ||
| 292 | Element::parse( | ||
| 293 | &Object { | ||
| 294 | jcid: object.jcid, | ||
| 295 | reference_count: 0, | ||
| 296 | data: ObjectData::Properties(&object.bytes), | ||
| 297 | global_ids: Arc::clone(&object.global_ids), | ||
| 298 | }, | ||
| 299 | &store, | ||
| 300 | )?, | ||
| 301 | ); | ||
| 302 | } | ||
| 303 | let title = page_title(&view, &pages, None)?; | ||
| 304 | drop(view); | ||
| 305 | if let Some((_, automatic, title)) = title { | ||
| 306 | let metadata = raw | ||
| 307 | .roots | ||
| 308 | .get(&2) | ||
| 309 | .ok_or_else(|| invalid("Page title metadata is unavailable"))?; | ||
| 310 | if raw.objects[metadata].jcid != 0x20030 { | ||
| 311 | return Err(invalid("Page title metadata is unavailable")); | ||
| 312 | } | ||
| 313 | let title = string(&title); | ||
| 314 | let mut object = PropertyObject::from_object(&raw.objects[metadata])?; | ||
| 315 | object.set(&[(0x1c001cf3, &title)])?; | ||
| 316 | changed.insert(*metadata, object); | ||
| 317 | changed | ||
| 318 | .get_mut(page) | ||
| 319 | .unwrap() | ||
| 320 | .set(&[(0x1c001d3c, if automatic { &title } else { &[0, 0] })])?; | ||
| 321 | } | ||
| 322 | write_revision(source, space, |_| Ok(changed)) | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 326 | fn fragment( | ||
| 327 | raw: &Object<'_>, | ||
| 328 | node: &Element<'_>, | ||
| 329 | range: Range<u32>, | ||
| 330 | empty: ExGuid, | ||
| 331 | ) -> Result<PropertyObject, Error> { | ||
| 332 | let Kind::RichText { text, runs, .. } = &node.kind else { | ||
| 333 | return Err(invalid("Select ordinary paragraph text")); | ||
| 334 | }; | ||
| 335 | let units: Vec<_> = text.encode_utf16().collect(); | ||
| 336 | let start = usize::try_from(range.start) | ||
| 337 | .map_err(|_| invalid("Choose a position within the paragraph"))?; | ||
| 338 | let end = usize::try_from(range.end) | ||
| 339 | .map_err(|_| invalid("Choose a position within the paragraph"))?; | ||
| 340 | let slice = units | ||
| 341 | .get(start..end) | ||
| 342 | .ok_or_else(|| invalid("Choose a position within the paragraph"))?; | ||
| 343 | let text = String::from_utf16(slice) | ||
| 344 | .map_err(|_| invalid("Choose a position between Unicode scalars"))?; | ||
| 345 | let mut segments = Vec::new(); | ||
| 346 | for run in runs { | ||
| 347 | if run.start < range.end && range.start < run.end { | ||
| 348 | segments.push(( | ||
| 349 | run.end.min(range.end) - range.start, | ||
| 350 | run.format.unwrap_or(empty), | ||
| 351 | )); | ||
| 352 | } | ||
| 353 | } | ||
| 354 | if segments.is_empty() { | ||
| 355 | segments.push((0, empty)); | ||
| 356 | } | ||
| 357 | if !range.is_empty() && end == units.len() { | ||
| 358 | let last = runs.last().unwrap(); | ||
| 359 | if last.start == last.end { | ||
| 360 | segments.push((range.end - range.start, last.format.unwrap_or(empty))); | ||
| 361 | } | ||
| 362 | } | ||
| 363 | if segments[..segments.len() - 1] | ||
| 364 | .windows(2) | ||
| 365 | .any(|pair| pair[0].0 >= pair[1].0) | ||
| 366 | { | ||
| 367 | return Err(invalid("Text-run boundaries must be strictly increasing")); | ||
| 368 | } | ||
| 369 | let mut object = PropertyObject::from_object(raw)?; | ||
| 370 | let mut ends = Vec::new(); | ||
| 371 | let mut references = Vec::new(); | ||
| 372 | for (end, id) in segments { | ||
| 373 | ends.extend_from_slice(&end.to_le_bytes()); | ||
| 374 | references.extend_from_slice(&object.reference(id)?); | ||
| 375 | } | ||
| 376 | ends.truncate(ends.len() - 4); | ||
| 377 | object.set(&[ | ||
| 378 | (0x1c001c22, &string(&text)), | ||
| 379 | (0x1c001e12, &ends), | ||
| 380 | (0x24001e13, &references), | ||
| 381 | ])?; | ||
| 382 | Ok(object) | ||
| 383 | } | ||
crates/onestore/src/write.rs+83-9| ... | @@ -120,6 +120,15 @@ fn field_length(property: &crate::Property<'_>, set_lengths: &[usize]) -> usize | ... | @@ -120,6 +120,15 @@ fn field_length(property: &crate::Property<'_>, set_lengths: &[usize]) -> usize |
| 120 | } | 120 | } |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | fn property_set_lengths(properties: &PropertySets<'_>) -> Vec<usize> { | ||
| 124 | let mut lengths = vec![0; properties.sets.len()]; | ||
| 125 | for (i, set) in properties.sets.iter().enumerate().rev() { | ||
| 126 | lengths[i] = | ||
| 127 | 2 + set.len() * 4 + set.iter().map(|p| field_length(p, &lengths)).sum::<usize>(); | ||
| 128 | } | ||
| 129 | lengths | ||
| 130 | } | ||
| 131 | |||
| 123 | fn patch_properties( | 132 | fn patch_properties( |
| 124 | blob: &[u8], | 133 | blob: &[u8], |
| 125 | updates: &[(u32, &[u8])], | 134 | updates: &[(u32, &[u8])], |
| ... | @@ -130,15 +139,7 @@ fn patch_properties( | ... | @@ -130,15 +139,7 @@ fn patch_properties( |
| 130 | let ids = properties.root_ids.as_ptr().addr() - blob.as_ptr().addr(); | 139 | let ids = properties.root_ids.as_ptr().addr() - blob.as_ptr().addr(); |
| 131 | let ids_end = ids + properties.root_ids.len(); | 140 | let ids_end = ids + properties.root_ids.len(); |
| 132 | let body_end = blob.len() - properties.padding.len(); | 141 | let body_end = blob.len() - properties.padding.len(); |
| 133 | let mut set_lengths = vec![0; properties.sets.len()]; | 142 | let set_lengths = property_set_lengths(&properties); |
| 134 | for (i, set) in properties.sets.iter().enumerate().rev() { | ||
| 135 | set_lengths[i] = 2 | ||
| 136 | + set.len() * 4 | ||
| 137 | + set | ||
| 138 | .iter() | ||
| 139 | .map(|p| field_length(p, &set_lengths)) | ||
| 140 | .sum::<usize>(); | ||
| 141 | } | ||
| 142 | let mut offsets = Vec::with_capacity(root.len()); | 143 | let mut offsets = Vec::with_capacity(root.len()); |
| 143 | let mut offset = ids_end; | 144 | let mut offset = ids_end; |
| 144 | for property in root { | 145 | for property in root { |
| ... | @@ -379,6 +380,79 @@ impl PropertyObject { | ... | @@ -379,6 +380,79 @@ impl PropertyObject { |
| 379 | Ok(()) | 380 | Ok(()) |
| 380 | } | 381 | } |
| 381 | 382 | ||
| 383 | pub fn remove(&mut self, ids: &[u32]) -> Result<()> { | ||
| 384 | let properties = PropertySets::parse(&self.bytes)?; | ||
| 385 | let removed = |id: u32| { | ||
| 386 | ids.iter() | ||
| 387 | .any(|wanted| id & 0x7fffffff == wanted & 0x7fffffff) | ||
| 388 | }; | ||
| 389 | if !properties.sets[0].iter().any(|p| removed(p.id)) { | ||
| 390 | return Ok(()); | ||
| 391 | } | ||
| 392 | let lengths = property_set_lengths(&properties); | ||
| 393 | let mut offset = properties.root_ids.as_ptr().addr() - self.bytes.as_ptr().addr() | ||
| 394 | + properties.root_ids.len(); | ||
| 395 | let mut retained_ids = Vec::new(); | ||
| 396 | let mut fields = Vec::new(); | ||
| 397 | let mut references: [Vec<u8>; 3] = std::array::from_fn(|_| Vec::new()); | ||
| 398 | for property in &properties.sets[0] { | ||
| 399 | let end = offset + field_length(property, &lengths); | ||
| 400 | if !removed(property.id) { | ||
| 401 | retained_ids.extend_from_slice(&property.id.to_le_bytes()); | ||
| 402 | fields.extend_from_slice(&self.bytes[offset..end]); | ||
| 403 | let mut pending = vec![property]; | ||
| 404 | while let Some(field) = pending.pop() { | ||
| 405 | match &field.value { | ||
| 406 | Value::References { | ||
| 407 | stream, | ||
| 408 | compact_ids, | ||
| 409 | } => { | ||
| 410 | let index = match stream { | ||
| 411 | crate::IdStream::Objects => 0, | ||
| 412 | crate::IdStream::ObjectSpaces => 1, | ||
| 413 | crate::IdStream::Contexts => 2, | ||
| 414 | }; | ||
| 415 | references[index].extend_from_slice(compact_ids); | ||
| 416 | } | ||
| 417 | Value::Sets(children) => { | ||
| 418 | for child in children.clone().rev() { | ||
| 419 | pending.extend(properties.sets[child].iter().rev()); | ||
| 420 | } | ||
| 421 | } | ||
| 422 | _ => {} | ||
| 423 | } | ||
| 424 | } | ||
| 425 | } | ||
| 426 | offset = end; | ||
| 427 | } | ||
| 428 | let mut cursor = crate::bytes::Cursor { | ||
| 429 | bytes: &self.bytes, | ||
| 430 | offset: 0, | ||
| 431 | }; | ||
| 432 | let streams = crate::properties::reference_streams(&mut cursor)?; | ||
| 433 | let mut bytes = Vec::new(); | ||
| 434 | for (stream, retained) in streams.iter().zip(&references) { | ||
| 435 | if stream.offset == 0 { | ||
| 436 | continue; | ||
| 437 | } | ||
| 438 | let header = u32::from_le_bytes( | ||
| 439 | self.bytes[stream.offset - 4..stream.offset] | ||
| 440 | .try_into() | ||
| 441 | .unwrap(), | ||
| 442 | ); | ||
| 443 | let count = u32::try_from(retained.len() / 4).unwrap(); | ||
| 444 | bytes.extend_from_slice(&((header & 0xff000000) | count).to_le_bytes()); | ||
| 445 | bytes.extend_from_slice(retained); | ||
| 446 | } | ||
| 447 | bytes.extend_from_slice(&u16::try_from(retained_ids.len() / 4).unwrap().to_le_bytes()); | ||
| 448 | bytes.extend_from_slice(&retained_ids); | ||
| 449 | bytes.extend_from_slice(&fields); | ||
| 450 | bytes.resize(bytes.len().next_multiple_of(8), 0); | ||
| 451 | PropertySets::parse(&bytes)?; | ||
| 452 | self.bytes = bytes; | ||
| 453 | Ok(()) | ||
| 454 | } | ||
| 455 | |||
| 382 | pub fn reference(&mut self, id: ExGuid) -> Result<[u8; 4]> { | 456 | pub fn reference(&mut self, id: ExGuid) -> Result<[u8; 4]> { |
| 383 | if !self.global_ids.values().any(|guid| *guid == id.guid) { | 457 | if !self.global_ids.values().any(|guid| *guid == id.guid) { |
| 384 | let mut index = 0; | 458 | let mut index = 0; |
crates/onestore/src/write/tests.rs+54| ... | @@ -46,6 +46,8 @@ fn document_insertions_and_formatting_respect_readonly_ancestors() { | ... | @@ -46,6 +46,8 @@ fn document_insertions_and_formatting_respect_readonly_ancestors() { |
| 46 | .iter() | 46 | .iter() |
| 47 | .find_map(|(id, object)| (object.jcid == 0x6000e).then_some(*id)) | 47 | .find_map(|(id, object)| (object.jcid == 0x6000e).then_some(*id)) |
| 48 | .unwrap(); | 48 | .unwrap(); |
| 49 | let split = crate::ParagraphSplit::new(text, 1, "Author").unwrap(); | ||
| 50 | assert!(PreparedEdit::split(&protected, sid, &split).is_err()); | ||
| 49 | assert!( | 51 | assert!( |
| 50 | PreparedEdit::format( | 52 | PreparedEdit::format( |
| 51 | &protected, | 53 | &protected, |
| ... | @@ -531,6 +533,45 @@ fn nested_fields_and_other_reference_streams_remain_byte_exact() { | ... | @@ -531,6 +533,45 @@ fn nested_fields_and_other_reference_streams_remain_byte_exact() { |
| 531 | ); | 533 | ); |
| 532 | assert_eq!(&changed[20..36], &original[16..32]); | 534 | assert_eq!(&changed[20..36], &original[16..32]); |
| 533 | assert_eq!(parsed.sets[0][3].value, Value::Bytes(&[96, 97, 98, 99])); | 535 | assert_eq!(parsed.sets[0][3].value, Value::Bytes(&[96, 97, 98, 99])); |
| 536 | |||
| 537 | for removed in 0..16 { | ||
| 538 | let ids: Vec<_> = previous.sets[0] | ||
| 539 | .iter() | ||
| 540 | .enumerate() | ||
| 541 | .filter_map(|(i, property)| (removed & (1 << i) != 0).then_some(property.id)) | ||
| 542 | .collect(); | ||
| 543 | let mut object = super::PropertyObject { | ||
| 544 | jcid: 0x6000e, | ||
| 545 | bytes: original.clone(), | ||
| 546 | global_ids: Default::default(), | ||
| 547 | }; | ||
| 548 | object.remove(&ids).unwrap(); | ||
| 549 | let parsed = PropertySets::parse(&object.bytes).unwrap(); | ||
| 550 | assert!( | ||
| 551 | parsed.sets[0] | ||
| 552 | .iter() | ||
| 553 | .eq(previous.sets[0].iter().filter(|p| !ids.contains(&p.id))) | ||
| 554 | ); | ||
| 555 | if removed & 2 == 0 { | ||
| 556 | assert_eq!(parsed.sets[1], previous.sets[1]); | ||
| 557 | assert_eq!( | ||
| 558 | object | ||
| 559 | .bytes | ||
| 560 | .windows(nested.len()) | ||
| 561 | .filter(|bytes| *bytes == nested) | ||
| 562 | .count(), | ||
| 563 | 1 | ||
| 564 | ); | ||
| 565 | } else { | ||
| 566 | assert_eq!(parsed.sets.len(), 1); | ||
| 567 | } | ||
| 568 | if removed == 0 { | ||
| 569 | assert_eq!(object.bytes, original); | ||
| 570 | } | ||
| 571 | let before = object.bytes.clone(); | ||
| 572 | object.remove(&ids).unwrap(); | ||
| 573 | assert_eq!(object.bytes, before); | ||
| 574 | } | ||
| 534 | } | 575 | } |
| 535 | 576 | ||
| 536 | #[test] | 577 | #[test] |
| ... | @@ -549,6 +590,19 @@ fn deep_property_splices_do_not_use_the_call_stack() { | ... | @@ -549,6 +590,19 @@ fn deep_property_splices_do_not_use_the_call_stack() { |
| 549 | &changed[14..changed.len() - parsed.padding.len()], | 590 | &changed[14..changed.len() - parsed.padding.len()], |
| 550 | &bytes[10..] | 591 | &bytes[10..] |
| 551 | ); | 592 | ); |
| 593 | let mut object = super::PropertyObject { | ||
| 594 | jcid: 0x6000e, | ||
| 595 | bytes: changed, | ||
| 596 | global_ids: Default::default(), | ||
| 597 | }; | ||
| 598 | object.remove(&[0x08000002]).unwrap(); | ||
| 599 | let parsed = PropertySets::parse(&object.bytes).unwrap(); | ||
| 600 | assert_eq!(parsed.sets.len(), 100_001); | ||
| 601 | assert_eq!(&object.bytes[..bytes.len()], &bytes); | ||
| 602 | object.remove(&[0x44000001]).unwrap(); | ||
| 603 | let parsed = PropertySets::parse(&object.bytes).unwrap(); | ||
| 604 | assert_eq!(parsed.sets.len(), 1); | ||
| 605 | assert!(parsed.sets[0].is_empty()); | ||
| 552 | } | 606 | } |
| 553 | 607 | ||
| 554 | #[test] | 608 | #[test] |
crates/onestore/tests/paragraph.rs created+343| ... | @@ -0,0 +1,343 @@ | ||
| 1 | use onestore::{ | ||
| 2 | ExGuid, ParagraphSplit, PreparedEdit, RevisionIndex, Store, | ||
| 3 | document::{Document, Kind, Revision}, | ||
| 4 | }; | ||
| 5 | use serde_json::Value; | ||
| 6 | |||
| 7 | #[path = "support/checkpoint.rs"] | ||
| 8 | mod checkpoint; | ||
| 9 | #[path = "support/current.rs"] | ||
| 10 | mod current; | ||
| 11 | #[path = "support/disk.rs"] | ||
| 12 | mod disk; | ||
| 13 | |||
| 14 | const SOURCE: &[u8] = | ||
| 15 | include_bytes!("../../../corpus/paragraph-edit/before/notebook/synthetic.one"); | ||
| 16 | |||
| 17 | fn characters(view: &Revision<'_>, id: ExGuid) -> Vec<(char, Value)> { | ||
| 18 | view.text_runs(id) | ||
| 19 | .unwrap() | ||
| 20 | .into_iter() | ||
| 21 | .flat_map(|run| { | ||
| 22 | let format = serde_json::to_value(run.format).unwrap(); | ||
| 23 | run.text.chars().map(move |c| (c, format.clone())) | ||
| 24 | }) | ||
| 25 | .collect() | ||
| 26 | } | ||
| 27 | |||
| 28 | #[test] | ||
| 29 | fn splits_partition_native_paragraphs_at_every_scalar_boundary() { | ||
| 30 | let manifest: Value = | ||
| 31 | serde_json::from_str(include_str!("../../../corpus/paragraph-edit/manifest.json")).unwrap(); | ||
| 32 | let store = Store::parse(SOURCE).unwrap(); | ||
| 33 | let index = RevisionIndex::parse(&store).unwrap(); | ||
| 34 | let document = Document::parse(&index).unwrap(); | ||
| 35 | for case in manifest["cases"].as_array().unwrap() { | ||
| 36 | let text: ExGuid = serde_json::from_value(case["original_text"].clone()).unwrap(); | ||
| 37 | let paragraph: ExGuid = serde_json::from_value(case["original_paragraph"].clone()).unwrap(); | ||
| 38 | let (sid, space) = document | ||
| 39 | .spaces | ||
| 40 | .iter() | ||
| 41 | .find(|(_, space)| { | ||
| 42 | space.revisions[&space.contexts[&ExGuid::default()]] | ||
| 43 | .nodes | ||
| 44 | .contains_key(&text) | ||
| 45 | }) | ||
| 46 | .unwrap(); | ||
| 47 | let before = &space.revisions[&space.contexts[&ExGuid::default()]]; | ||
| 48 | let (parent, parent_node) = before | ||
| 49 | .nodes | ||
| 50 | .iter() | ||
| 51 | .find(|(_, node)| node.children.contains(&paragraph)) | ||
| 52 | .unwrap(); | ||
| 53 | let expected = characters(before, text); | ||
| 54 | let offsets: Vec<u32> = std::iter::once(0) | ||
| 55 | .chain(expected.iter().scan(0, |offset, (c, _)| { | ||
| 56 | *offset += u32::try_from(c.len_utf16()).unwrap(); | ||
| 57 | Some(*offset) | ||
| 58 | })) | ||
| 59 | .collect(); | ||
| 60 | for (position, offset) in offsets.iter().enumerate() { | ||
| 61 | let intent = ParagraphSplit::new(text, *offset, "Split author").unwrap(); | ||
| 62 | let restored = serde_json::from_value(serde_json::to_value(&intent).unwrap()).unwrap(); | ||
| 63 | assert_eq!(intent, restored); | ||
| 64 | let edited = PreparedEdit::split(SOURCE, *sid, &restored); | ||
| 65 | if case["case"] == "Split before hyperlink" { | ||
| 66 | assert!(edited.is_err()); | ||
| 67 | continue; | ||
| 68 | } | ||
| 69 | let edited = | ||
| 70 | edited.unwrap_or_else(|error| panic!("{} at {offset}: {error}", case["case"])); | ||
| 71 | let current_store = Store::parse(edited.as_bytes()).unwrap(); | ||
| 72 | assert_eq!( | ||
| 73 | current_store.header.transaction_count, | ||
| 74 | store.header.transaction_count + 1 | ||
| 75 | ); | ||
| 76 | let current_index = RevisionIndex::parse(&current_store).unwrap(); | ||
| 77 | current_index.validate_current().unwrap(); | ||
| 78 | let current_document = Document::parse(&current_index).unwrap(); | ||
| 79 | let current_space = &current_document.spaces[sid]; | ||
| 80 | let after = &current_space.revisions[&current_space.contexts[&ExGuid::default()]]; | ||
| 81 | let mut changed = std::collections::BTreeSet::from([text, before.roots[&2]]); | ||
| 82 | let mut pending = vec![paragraph]; | ||
| 83 | while let Some(id) = pending.pop() { | ||
| 84 | if !changed.insert(id) { | ||
| 85 | continue; | ||
| 86 | } | ||
| 87 | pending.extend(before.nodes.iter().filter_map(|(parent, node)| { | ||
| 88 | node.children | ||
| 89 | .iter() | ||
| 90 | .chain(&node.content) | ||
| 91 | .chain(&node.structure) | ||
| 92 | .any(|child| *child == id) | ||
| 93 | .then_some(*parent) | ||
| 94 | })); | ||
| 95 | } | ||
| 96 | let old_raw = index | ||
| 97 | .resolve(*sid, space.contexts[&ExGuid::default()]) | ||
| 98 | .unwrap(); | ||
| 99 | let new_raw = current_index | ||
| 100 | .resolve(*sid, current_space.contexts[&ExGuid::default()]) | ||
| 101 | .unwrap(); | ||
| 102 | for (id, object) in old_raw.objects { | ||
| 103 | if !changed.contains(&id) { | ||
| 104 | assert_eq!(object.data, new_raw.objects[&id].data, "untouched {id}"); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | assert_eq!( | ||
| 108 | characters(after, text), | ||
| 109 | expected[..position], | ||
| 110 | "{} prefix at {offset}", | ||
| 111 | case["case"] | ||
| 112 | ); | ||
| 113 | assert_eq!( | ||
| 114 | characters(after, intent.text_object()), | ||
| 115 | expected[position..], | ||
| 116 | "{} suffix at {offset}", | ||
| 117 | case["case"] | ||
| 118 | ); | ||
| 119 | let mut children = parent_node.children.clone(); | ||
| 120 | children.insert( | ||
| 121 | children.iter().position(|id| *id == paragraph).unwrap() + 1, | ||
| 122 | intent.object(), | ||
| 123 | ); | ||
| 124 | assert_eq!(after.nodes[parent].children, children); | ||
| 125 | assert_eq!(after.nodes[&paragraph].content, [text]); | ||
| 126 | assert!(after.nodes[&paragraph].children.is_empty()); | ||
| 127 | assert_eq!( | ||
| 128 | after.nodes[&intent.object()].content, | ||
| 129 | [intent.text_object()] | ||
| 130 | ); | ||
| 131 | assert_eq!( | ||
| 132 | after.nodes[&intent.object()].children, | ||
| 133 | before.nodes[&paragraph].children | ||
| 134 | ); | ||
| 135 | assert_eq!( | ||
| 136 | serde_json::to_value(&after.nodes[&text].tags).unwrap(), | ||
| 137 | serde_json::to_value(&before.nodes[&text].tags).unwrap() | ||
| 138 | ); | ||
| 139 | assert!(after.nodes[&intent.text_object()].tags.is_empty()); | ||
| 140 | let Kind::Paragraph { | ||
| 141 | lists: old_lists, .. | ||
| 142 | } = &before.nodes[&paragraph].kind | ||
| 143 | else { | ||
| 144 | panic!() | ||
| 145 | }; | ||
| 146 | let Kind::Paragraph { lists, .. } = &after.nodes[&intent.object()].kind else { | ||
| 147 | panic!() | ||
| 148 | }; | ||
| 149 | assert_eq!(old_lists.len(), lists.len()); | ||
| 150 | for (old, new) in old_lists.iter().zip(lists) { | ||
| 151 | assert_ne!(old, new); | ||
| 152 | let mut old = serde_json::to_value(&before.nodes[old]).unwrap(); | ||
| 153 | old["kind"]["restart"] = Value::Null; | ||
| 154 | assert_eq!(serde_json::to_value(&after.nodes[new]).unwrap(), old); | ||
| 155 | } | ||
| 156 | for (space_id, old_space) in &index.spaces { | ||
| 157 | for revision in old_space.revisions.keys() { | ||
| 158 | let old = index.resolve(*space_id, *revision).unwrap(); | ||
| 159 | let retained = current_index.resolve(*space_id, *revision).unwrap(); | ||
| 160 | assert_eq!(old.roots, retained.roots); | ||
| 161 | for (id, object) in old.objects { | ||
| 162 | assert_eq!(object.data, retained.objects[&id].data); | ||
| 163 | } | ||
| 164 | } | ||
| 165 | } | ||
| 166 | assert!(PreparedEdit::split(edited.as_bytes(), *sid, &intent).is_err()); | ||
| 167 | } | ||
| 168 | for offset in 0..=*offsets.last().unwrap() + 1 { | ||
| 169 | if offsets.contains(&offset) { | ||
| 170 | continue; | ||
| 171 | } | ||
| 172 | let intent = ParagraphSplit::new(text, offset, "Author").unwrap(); | ||
| 173 | assert!(PreparedEdit::split(SOURCE, *sid, &intent).is_err()); | ||
| 174 | } | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | #[test] | ||
| 179 | fn invalid_split_identities_and_title_targets_are_rejected() { | ||
| 180 | assert!(ParagraphSplit::new(ExGuid::default(), 0, "Author").is_err()); | ||
| 181 | let manifest: Value = | ||
| 182 | serde_json::from_str(include_str!("../../../corpus/paragraph-edit/manifest.json")).unwrap(); | ||
| 183 | let text: ExGuid = | ||
| 184 | serde_json::from_value(manifest["cases"][0]["original_text"].clone()).unwrap(); | ||
| 185 | assert!(ParagraphSplit::new(text, 0, "a\0b").is_err()); | ||
| 186 | let store = Store::parse(SOURCE).unwrap(); | ||
| 187 | let index = RevisionIndex::parse(&store).unwrap(); | ||
| 188 | let document = Document::parse(&index).unwrap(); | ||
| 189 | let sid = *document | ||
| 190 | .spaces | ||
| 191 | .iter() | ||
| 192 | .find(|(_, space)| { | ||
| 193 | space.revisions[&space.contexts[&ExGuid::default()]] | ||
| 194 | .nodes | ||
| 195 | .contains_key(&text) | ||
| 196 | }) | ||
| 197 | .unwrap() | ||
| 198 | .0; | ||
| 199 | let intent = ParagraphSplit::new(text, 1, "Author").unwrap(); | ||
| 200 | for (field, value) in [ | ||
| 201 | ("guid", serde_json::to_value([0_u8; 16]).unwrap()), | ||
| 202 | ("guid", serde_json::to_value(text.guid).unwrap()), | ||
| 203 | ("text", serde_json::to_value(ExGuid::default()).unwrap()), | ||
| 204 | ("author", serde_json::json!("a\0b")), | ||
| 205 | ("offset", serde_json::json!(u32::MAX)), | ||
| 206 | ] { | ||
| 207 | let mut encoded = serde_json::to_value(&intent).unwrap(); | ||
| 208 | encoded[field] = value; | ||
| 209 | let forged = serde_json::from_value(encoded).unwrap(); | ||
| 210 | assert!(PreparedEdit::split(SOURCE, sid, &forged).is_err()); | ||
| 211 | } | ||
| 212 | let mut titles = 0; | ||
| 213 | for (sid, _) in document.pages().unwrap() { | ||
| 214 | let space = &document.spaces[&sid]; | ||
| 215 | let view = &space.revisions[&space.contexts[&ExGuid::default()]]; | ||
| 216 | let mut pending: Vec<_> = view | ||
| 217 | .nodes | ||
| 218 | .iter() | ||
| 219 | .filter_map(|(id, n)| matches!(n.kind, Kind::Title).then_some(*id)) | ||
| 220 | .collect(); | ||
| 221 | let mut seen = std::collections::BTreeSet::new(); | ||
| 222 | while let Some(id) = pending.pop() { | ||
| 223 | if !seen.insert(id) { | ||
| 224 | continue; | ||
| 225 | } | ||
| 226 | let node = &view.nodes[&id]; | ||
| 227 | pending.extend(node.children.iter().chain(&node.content).copied()); | ||
| 228 | if matches!(node.kind, Kind::RichText { .. }) { | ||
| 229 | let intent = ParagraphSplit::new(id, 0, "Author").unwrap(); | ||
| 230 | assert!(PreparedEdit::split(SOURCE, sid, &intent).is_err()); | ||
| 231 | titles += 1; | ||
| 232 | } | ||
| 233 | } | ||
| 234 | } | ||
| 235 | assert!(titles >= 14); | ||
| 236 | } | ||
| 237 | |||
| 238 | #[test] | ||
| 239 | #[ignore = "exports paragraph splits for independent native validation"] | ||
| 240 | fn export_native_paragraph_splits() { | ||
| 241 | use std::{fs, path::PathBuf}; | ||
| 242 | let output = PathBuf::from(std::env::var_os("ONESTORE_PARAGRAPH_OUTPUT").unwrap()); | ||
| 243 | assert!(output.is_absolute()); | ||
| 244 | fs::create_dir(&output).unwrap(); | ||
| 245 | let manifest: Value = | ||
| 246 | serde_json::from_str(include_str!("../../../corpus/paragraph-edit/manifest.json")).unwrap(); | ||
| 247 | let mut source = SOURCE.to_vec(); | ||
| 248 | let mut written = Vec::new(); | ||
| 249 | for case in manifest["cases"].as_array().unwrap() { | ||
| 250 | if case["case"] == "Split before hyperlink" { | ||
| 251 | continue; | ||
| 252 | } | ||
| 253 | let text: ExGuid = serde_json::from_value(case["original_text"].clone()).unwrap(); | ||
| 254 | let store = Store::parse(&source).unwrap(); | ||
| 255 | let index = RevisionIndex::parse(&store).unwrap(); | ||
| 256 | let document = Document::parse(&index).unwrap(); | ||
| 257 | let sid = *document | ||
| 258 | .spaces | ||
| 259 | .iter() | ||
| 260 | .find(|(_, space)| { | ||
| 261 | space.revisions[&space.contexts[&ExGuid::default()]] | ||
| 262 | .nodes | ||
| 263 | .contains_key(&text) | ||
| 264 | }) | ||
| 265 | .unwrap() | ||
| 266 | .0; | ||
| 267 | let intent = ParagraphSplit::new( | ||
| 268 | text, | ||
| 269 | serde_json::from_value(case["offset_utf16"].clone()).unwrap(), | ||
| 270 | "Rust split author", | ||
| 271 | ) | ||
| 272 | .unwrap(); | ||
| 273 | let edited = PreparedEdit::split(&source, sid, &intent).unwrap(); | ||
| 274 | written.push(serde_json::json!({"case": case["case"], "intent": intent, | ||
| 275 | "new_paragraph": intent.object(), "new_text": intent.text_object()})); | ||
| 276 | source = edited.as_bytes().to_vec(); | ||
| 277 | } | ||
| 278 | let candidate = output.join("candidate"); | ||
| 279 | fs::create_dir(&candidate).unwrap(); | ||
| 280 | fs::write(candidate.join("synthetic.one"), source).unwrap(); | ||
| 281 | fs::write( | ||
| 282 | output.join("manifest.json"), | ||
| 283 | serde_json::to_vec_pretty(&serde_json::json!({"cases": written})).unwrap(), | ||
| 284 | ) | ||
| 285 | .unwrap(); | ||
| 286 | } | ||
| 287 | |||
| 288 | #[test] | ||
| 289 | fn interrupted_splits_publish_a_complete_graph_or_retain_the_original() { | ||
| 290 | let original = onestore::create_section("split.one", "Original", "Author").unwrap(); | ||
| 291 | let store = Store::parse(&original).unwrap(); | ||
| 292 | let index = RevisionIndex::parse(&store).unwrap(); | ||
| 293 | let document = Document::parse(&index).unwrap(); | ||
| 294 | let (sid, page) = document.pages().unwrap()[0]; | ||
| 295 | let space = &document.spaces[&sid]; | ||
| 296 | let view = &space.revisions[&space.contexts[&ExGuid::default()]]; | ||
| 297 | let outline = view.nodes[&page] | ||
| 298 | .children | ||
| 299 | .iter() | ||
| 300 | .find(|id| matches!(view.nodes[id].kind, Kind::Outline { .. })) | ||
| 301 | .unwrap(); | ||
| 302 | let paragraph = view.nodes[outline].children[0]; | ||
| 303 | let insertion = onestore::Insertion::paragraph(paragraph, None, "a🦀b", "Author") | ||
| 304 | .unwrap() | ||
| 305 | .with_formatting(1..3, &[onestore::TextAttribute::Bold(true)]) | ||
| 306 | .unwrap(); | ||
| 307 | let inserted = PreparedEdit::insert(&original, sid, &insertion).unwrap(); | ||
| 308 | let source = inserted.as_bytes(); | ||
| 309 | let checkpoint = checkpoint::pending(source, sid, insertion.text_object(), 0x14001d7a); | ||
| 310 | for source in [source, &checkpoint] { | ||
| 311 | let intent = ParagraphSplit::new(insertion.text_object(), 1, "Author").unwrap(); | ||
| 312 | let edit = PreparedEdit::split(source, sid, &intent).unwrap(); | ||
| 313 | let before = current::current(source); | ||
| 314 | let after = current::current(edit.as_bytes()); | ||
| 315 | for write_limit in [17, 4096] { | ||
| 316 | let disk = |fail_at| disk::Disk { | ||
| 317 | visible: source.to_vec(), | ||
| 318 | durable: source.to_vec(), | ||
| 319 | operation: 0, | ||
| 320 | fail_at, | ||
| 321 | write_limit, | ||
| 322 | random: 347, | ||
| 323 | }; | ||
| 324 | let mut successful = disk(None); | ||
| 325 | edit.commit(&mut successful).unwrap(); | ||
| 326 | assert_eq!(successful.durable, edit.as_bytes()); | ||
| 327 | for at in 1..=successful.operation { | ||
| 328 | let mut interrupted = disk(Some(at)); | ||
| 329 | let error = edit.commit(&mut interrupted).unwrap_err(); | ||
| 330 | let recovered = current::current(&interrupted.durable); | ||
| 331 | assert!( | ||
| 332 | recovered == before || recovered == after, | ||
| 333 | "interruption {at}" | ||
| 334 | ); | ||
| 335 | match error.state { | ||
| 336 | onestore::CommitState::NotCommitted => assert_eq!(recovered, before), | ||
| 337 | onestore::CommitState::Committed => assert_eq!(recovered, after), | ||
| 338 | onestore::CommitState::Unknown => {} | ||
| 339 | } | ||
| 340 | } | ||
| 341 | } | ||
| 342 | } | ||
| 343 | } | ||
fuzz/Cargo.toml+7| ... | @@ -84,3 +84,10 @@ path = "fuzz_targets/insert.rs" | ... | @@ -84,3 +84,10 @@ path = "fuzz_targets/insert.rs" |
| 84 | test = false | 84 | test = false |
| 85 | doc = false | 85 | doc = false |
| 86 | bench = false | 86 | bench = false |
| 87 | |||
| 88 | [[bin]] | ||
| 89 | name = "paragraph" | ||
| 90 | path = "fuzz_targets/paragraph.rs" | ||
| 91 | test = false | ||
| 92 | doc = false | ||
| 93 | bench = false |
fuzz/fuzz_targets/paragraph.rs created+144| ... | @@ -0,0 +1,144 @@ | ||
| 1 | #![no_main] | ||
| 2 | use libfuzzer_sys::fuzz_target; | ||
| 3 | use onestore::{ | ||
| 4 | CommitState, ExGuid, Insertion, ParagraphSplit, PreparedEdit, RevisionIndex, Store, | ||
| 5 | TextAttribute as A, | ||
| 6 | document::{Document, Kind}, | ||
| 7 | }; | ||
| 8 | use std::sync::LazyLock; | ||
| 9 | |||
| 10 | #[path = "../../crates/onestore/tests/support/current.rs"] | ||
| 11 | mod current; | ||
| 12 | #[path = "../../crates/onestore/tests/support/disk.rs"] | ||
| 13 | mod disk; | ||
| 14 | |||
| 15 | static SOURCE: LazyLock<(Vec<u8>, ExGuid, ExGuid)> = LazyLock::new(|| { | ||
| 16 | let source = onestore::create_section("paragraph.one", "Original", "Author").unwrap(); | ||
| 17 | let store = Store::parse(&source).unwrap(); | ||
| 18 | let index = RevisionIndex::parse(&store).unwrap(); | ||
| 19 | let document = Document::parse(&index).unwrap(); | ||
| 20 | let (sid, page) = document.pages().unwrap()[0]; | ||
| 21 | let space = &document.spaces[&sid]; | ||
| 22 | let view = &space.revisions[&space.contexts[&ExGuid::default()]]; | ||
| 23 | let outline = *view.nodes[&page] | ||
| 24 | .children | ||
| 25 | .iter() | ||
| 26 | .find(|id| matches!(view.nodes[id].kind, Kind::Outline { .. })) | ||
| 27 | .unwrap(); | ||
| 28 | let parent = view.nodes[&outline].children[0]; | ||
| 29 | let intent = Insertion::paragraph(parent, None, "a🦀 e\u{301} 東京\rEnd", "Author") | ||
| 30 | .unwrap() | ||
| 31 | .with_formatting(0..4, &[A::Bold(true)]) | ||
| 32 | .unwrap() | ||
| 33 | .with_formatting(4..7, &[A::Italic(true), A::Color(Some([12, 34, 56]))]) | ||
| 34 | .unwrap(); | ||
| 35 | let edited = PreparedEdit::insert(&source, sid, &intent).unwrap(); | ||
| 36 | (edited.as_bytes().to_vec(), sid, outline) | ||
| 37 | }); | ||
| 38 | |||
| 39 | fuzz_target!(|input: &[u8]| { | ||
| 40 | let (source, sid, outline) = &*SOURCE; | ||
| 41 | if let Ok(intent) = serde_json::from_slice::<ParagraphSplit>(input) | ||
| 42 | && let Ok(edit) = PreparedEdit::split(source, *sid, &intent) | ||
| 43 | { | ||
| 44 | current::current(edit.as_bytes()); | ||
| 45 | } | ||
| 46 | let mut persisted = source.clone(); | ||
| 47 | let mut caches = std::array::from_fn::<_, 12, _>(|_| source.clone()); | ||
| 48 | for step in input.chunks_exact(8).take(20) { | ||
| 49 | let actor = usize::from(step[0]) % caches.len(); | ||
| 50 | if step[1] % 3 == 0 { | ||
| 51 | caches[actor].clone_from(&persisted); | ||
| 52 | } | ||
| 53 | let source = &caches[actor]; | ||
| 54 | let store = Store::parse(source).unwrap(); | ||
| 55 | let index = RevisionIndex::parse(&store).unwrap(); | ||
| 56 | let document = Document::parse(&index).unwrap(); | ||
| 57 | let space = &document.spaces[sid]; | ||
| 58 | let view = &space.revisions[&space.contexts[&ExGuid::default()]]; | ||
| 59 | let mut pending = vec![*outline]; | ||
| 60 | let mut paragraphs = Vec::new(); | ||
| 61 | while let Some(id) = pending.pop() { | ||
| 62 | let node = &view.nodes[&id]; | ||
| 63 | pending.extend(node.children.iter().copied()); | ||
| 64 | if matches!(node.kind, Kind::Paragraph { .. }) { | ||
| 65 | paragraphs.push(id); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | let paragraph = paragraphs[usize::from(step[2]) % paragraphs.len()]; | ||
| 69 | let text = view.nodes[&paragraph].content[0]; | ||
| 70 | let characters: Vec<_> = view | ||
| 71 | .text_runs(text) | ||
| 72 | .unwrap() | ||
| 73 | .into_iter() | ||
| 74 | .flat_map(|run| { | ||
| 75 | let style = serde_json::to_value(run.format).unwrap(); | ||
| 76 | run.text.chars().map(move |c| (c, style.clone())) | ||
| 77 | }) | ||
| 78 | .collect(); | ||
| 79 | let offsets: Vec<u32> = std::iter::once(0) | ||
| 80 | .chain(characters.iter().scan(0, |n, (c, _)| { | ||
| 81 | *n += u32::try_from(c.len_utf16()).unwrap(); | ||
| 82 | Some(*n) | ||
| 83 | })) | ||
| 84 | .collect(); | ||
| 85 | let offset = u32::from(step[3]) % (offsets.last().unwrap() + 2); | ||
| 86 | let intent = ParagraphSplit::new(text, offset, "Paragraph fuzz").unwrap(); | ||
| 87 | let intent = serde_json::from_value(serde_json::to_value(intent).unwrap()).unwrap(); | ||
| 88 | let edit = PreparedEdit::split(source, *sid, &intent); | ||
| 89 | let Some(position) = offsets.iter().position(|n| *n == offset) else { | ||
| 90 | assert!(edit.is_err()); | ||
| 91 | continue; | ||
| 92 | }; | ||
| 93 | let edit = edit.unwrap(); | ||
| 94 | let after_store = Store::parse(edit.as_bytes()).unwrap(); | ||
| 95 | let after_index = RevisionIndex::parse(&after_store).unwrap(); | ||
| 96 | let after_document = Document::parse(&after_index).unwrap(); | ||
| 97 | let space = &after_document.spaces[sid]; | ||
| 98 | let after_view = &space.revisions[&space.contexts[&ExGuid::default()]]; | ||
| 99 | for (id, expected) in [ | ||
| 100 | (text, &characters[..position]), | ||
| 101 | (intent.text_object(), &characters[position..]), | ||
| 102 | ] { | ||
| 103 | let actual: Vec<_> = after_view | ||
| 104 | .text_runs(id) | ||
| 105 | .unwrap() | ||
| 106 | .into_iter() | ||
| 107 | .flat_map(|run| { | ||
| 108 | let style = serde_json::to_value(run.format).unwrap(); | ||
| 109 | run.text.chars().map(move |c| (c, style.clone())) | ||
| 110 | }) | ||
| 111 | .collect(); | ||
| 112 | assert_eq!(actual, expected); | ||
| 113 | } | ||
| 114 | assert!(after_view.nodes[&paragraph].children.is_empty()); | ||
| 115 | assert_eq!( | ||
| 116 | after_view.nodes[&intent.object()].children, | ||
| 117 | view.nodes[&paragraph].children | ||
| 118 | ); | ||
| 119 | let before = current::current(&persisted); | ||
| 120 | let after = current::current(edit.as_bytes()); | ||
| 121 | let mut disk = disk::Disk { | ||
| 122 | visible: persisted.clone(), | ||
| 123 | durable: persisted.clone(), | ||
| 124 | operation: 0, | ||
| 125 | fail_at: (step[4] != 0).then_some(usize::from(u16::from_le_bytes([step[4], step[5]]))), | ||
| 126 | write_limit: if step[6] & 1 == 0 { 17 } else { 4096 }, | ||
| 127 | random: u64::from(step[7]) + 1, | ||
| 128 | }; | ||
| 129 | let result = edit.commit(&mut disk); | ||
| 130 | let observed = current::current(&disk.durable); | ||
| 131 | match result { | ||
| 132 | Ok(()) => assert_eq!(observed, after), | ||
| 133 | Err(error) => { | ||
| 134 | assert!(observed == before || observed == after); | ||
| 135 | match error.state { | ||
| 136 | CommitState::NotCommitted => assert_eq!(observed, before), | ||
| 137 | CommitState::Committed => assert_eq!(observed, after), | ||
| 138 | CommitState::Unknown => {} | ||
| 139 | } | ||
| 140 | } | ||
| 141 | } | ||
| 142 | persisted = disk.durable; | ||
| 143 | } | ||
| 144 | }); | ||
tools/test_paragraph_edit.py+60-1| ... | @@ -8,7 +8,7 @@ import unittest | ... | @@ -8,7 +8,7 @@ import unittest |
| 8 | import xml.etree.ElementTree as ET | 8 | import xml.etree.ElementTree as ET |
| 9 | 9 | ||
| 10 | from document_model import EXPORTER, ordered_pages, walk | 10 | from document_model import EXPORTER, ordered_pages, walk |
| 11 | from native_format import native_characters | 11 | from native_format import compare_formats, native_characters |
| 12 | from native_xml import ns | 12 | from native_xml import ns |
| 13 | 13 | ||
| 14 | ROOT = Path(__file__).resolve().parent.parent | 14 | ROOT = Path(__file__).resolve().parent.parent |
| ... | @@ -17,6 +17,65 @@ compare = runpy.run_path(str(ROOT / 'tools/verify-document.py'))['compare'] | ... | @@ -17,6 +17,65 @@ compare = runpy.run_path(str(ROOT / 'tools/verify-document.py'))['compare'] |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | class ParagraphEditTest(unittest.TestCase): | 19 | class ParagraphEditTest(unittest.TestCase): |
| 20 | def test_rust_splits_match_native_controls_and_preserve_empty_typing_styles(self): | ||
| 21 | fixture = FIXTURE / 'rust-split' | ||
| 22 | manifest = json.loads((fixture / 'manifest.json').read_text()) | ||
| 23 | with TemporaryDirectory() as temporary: | ||
| 24 | for source, capture in [('candidate', 'native'), ('native/notebook', 'native'), | ||
| 25 | ('typed/notebook', 'typed')]: | ||
| 26 | native = Path(temporary) / source.replace('/', '-') / 'read' | ||
| 27 | shutil.copytree(fixture / capture / 'read', native) | ||
| 28 | compare(fixture / source, native) | ||
| 29 | subprocess.run([EXPORTER, fixture / 'candidate/synthetic.one', Path(temporary) / 'model'], check=True) | ||
| 30 | model = json.loads((Path(temporary) / 'model/document.json').read_text()) | ||
| 31 | subprocess.run([EXPORTER, fixture / 'native/notebook/synthetic.one', Path(temporary) / 'saved'], check=True) | ||
| 32 | saved = json.loads((Path(temporary) / 'saved/document.json').read_text()) | ||
| 33 | views = {r['nodes'][r['roots']['2']]['kind']['title']: (r, page) | ||
| 34 | for _, _, r, page in ordered_pages(model)} | ||
| 35 | saved_views = {r['nodes'][r['roots']['2']]['kind']['title']: (r, page) | ||
| 36 | for _, _, r, page in ordered_pages(saved)} | ||
| 37 | text_nodes = {} | ||
| 38 | for name, (revision, page) in views.items(): | ||
| 39 | current, current_page = saved_views[name] | ||
| 40 | self.assertEqual(page, current_page) | ||
| 41 | text_nodes[name] = [] | ||
| 42 | for outline in revision['nodes'][page]['children']: | ||
| 43 | if revision['nodes'][outline]['kind']['type'] != 'Outline': continue | ||
| 44 | for oid, node in walk(revision, outline): | ||
| 45 | self.assertEqual(current['nodes'][oid]['children'], node['children']) | ||
| 46 | self.assertEqual(current['nodes'][oid]['content'], node['content']) | ||
| 47 | if node['kind']['type'] == 'RichText': text_nodes[name].append(node) | ||
| 48 | captures = {} | ||
| 49 | for phase, folder in [('native', fixture / 'native/read'), ('typed', fixture / 'typed/read'), | ||
| 50 | ('control', FIXTURE / 'cold-split/read')]: | ||
| 51 | captures[phase] = {} | ||
| 52 | for path in folder.glob('page-*.xml'): | ||
| 53 | page = ET.parse(path).getroot() | ||
| 54 | captures[phase][page.get('name')] = native_characters(page, page.findall('one:Outline', ns)) | ||
| 55 | self.assertEqual(len(captures[phase]), 14) | ||
| 56 | cases = [c for c in manifest['cases'] if 'intent' in c] | ||
| 57 | self.assertEqual(len(cases), 12) | ||
| 58 | for case in cases: | ||
| 59 | name = case['case'] | ||
| 60 | with self.subTest(case=name): | ||
| 61 | for a, b in zip(captures['native'][name], captures['control'][name], strict=True): | ||
| 62 | for (c, left), (d, right) in zip(a, b, strict=True): | ||
| 63 | self.assertEqual(c, d) | ||
| 64 | for key in left.keys() | right.keys(): | ||
| 65 | default = 'automatic' if key in ('color', 'highlight') else False | ||
| 66 | self.assertEqual(left.get(key, default), right.get(key, default)) | ||
| 67 | selections = json.loads((fixture / 'typed/ui/selections.json').read_text()) | ||
| 68 | self.assertEqual(len(selections), 4) | ||
| 69 | for selection in selections: | ||
| 70 | node = text_nodes[selection['case']][selection['index']] | ||
| 71 | self.assertEqual(node['kind']['text'], '') | ||
| 72 | self.assertEqual(len(node['kind']['runs']), 1) | ||
| 73 | node['kind']['text'] = selection['text'] | ||
| 74 | node['kind']['runs'][0]['end'] = len(selection['text'].encode('utf-16-le')) // 2 | ||
| 75 | for name, (revision, page) in views.items(): | ||
| 76 | _, differences = compare_formats(revision, text_nodes[name], captures['typed'][name]) | ||
| 77 | self.assertEqual(differences, [], name) | ||
| 78 | |||
| 20 | def test_native_split_join_graphs_styles_and_identity_boundaries(self): | 79 | def test_native_split_join_graphs_styles_and_identity_boundaries(self): |
| 21 | manifest = json.loads((FIXTURE / 'manifest.json').read_text()) | 80 | manifest = json.loads((FIXTURE / 'manifest.json').read_text()) |
| 22 | models, native = {}, {} | 81 | models, native = {}, {} |