diff --git a/corpus/paragraph-edit/README.md b/corpus/paragraph-edit/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..14333fa67ce761a4c93017134f400497e767249c
--- /dev/null
+++ b/corpus/paragraph-edit/README.md
@@ -0,0 +1,31 @@
+# Native paragraph editing
+
+OneNote 2010 authored 13 cases, split each through keyboard input, reopened the
+result in a fresh disposable VM, and joined each pair through keyboard input.
+The four phases retain notebook bytes and independent native XML: `before`,
+`split`, `cold-split`, and `joined`. A fourteenth control page remains unchanged.
+
+Cases cover mixed formatting, style/start/end/empty boundaries, nested children,
+bullets, numbering, completed tags, table cells, soft breaks, and splitting plain
+text before a hyperlink. The manifest records storage identities and split
+positions. Captured UI scripts and screenshots retain the actual native actions;
+`joined/first-backspace` records the intermediate list/indentation changes.
+
+The original paragraph stays on the left and children transfer to the new right
+paragraph. Completed tags remain on the left rich-text object. Joining an empty
+left paragraph retains its paragraph identity but adopts the right text object.
+Bullet, numbered, and nested cases require two Backspaces because the first
+changes list or indentation state. The native application also added flag
+`0x880034dd` and changed timestamps on some unrelated text objects; the manifest
+records those observations without assigning undocumented meaning to the flag.
+
+`tools/native/paragraphs.ps1` authors the cases. Use `tools/native_runner.py` with
+that author, `--expected-pages 14 --inspect --collect-notebook`, then navigate to
+each current page/object ID and send its recorded keys. Preserve the authored
+notebook before completing inspection. Cold-open the split notebook for the join
+pass. Captured COM IDs belong to their originating sessions; discover fresh IDs
+when regenerating the corpus.
+
+`tools/test_paragraph_edit.py` verifies these native controls without a VM. They
+establish application behavior; they do not advertise a library split/join API.
+Identical captured files link to one canonical copy within this corpus.
diff --git a/corpus/paragraph-edit/before/notebook/Open Notebook.onetoc2 b/corpus/paragraph-edit/before/notebook/Open Notebook.onetoc2
new file mode 100644
index 0000000000000000000000000000000000000000..c6759f2d5c5014f4ee7aa5cf331bc86d53a7f2c6
Binary files /dev/null and b/corpus/paragraph-edit/before/notebook/Open Notebook.onetoc2 differ
diff --git a/corpus/paragraph-edit/before/notebook/synthetic.one b/corpus/paragraph-edit/before/notebook/synthetic.one
new file mode 100644
index 0000000000000000000000000000000000000000..79e1782196f8f41b265887c45fd17f4cbf609ded
Binary files /dev/null and b/corpus/paragraph-edit/before/notebook/synthetic.one differ
diff --git a/corpus/paragraph-edit/before/read/environment.json b/corpus/paragraph-edit/before/read/environment.json
new file mode 100644
index 0000000000000000000000000000000000000000..c385db9765c91099ea72c6e5592960c61f26ad7c
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/environment.json
@@ -0,0 +1,7 @@
+{
+ "powershell": "5.1.14409.1005",
+ "schema": "xs2010",
+ "hostname": "ONE-M6-FAE892C2",
+ "cold": false,
+ "onenote": "14.0.4763.1000"
+}
diff --git a/corpus/paragraph-edit/before/read/hierarchy.xml b/corpus/paragraph-edit/before/read/hierarchy.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3096a94f9f2c6becc1350122ac021f5f1aed6914
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/hierarchy.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/corpus/paragraph-edit/before/read/page-000.xml b/corpus/paragraph-edit/before/read/page-000.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b54a01eff28da010cb3e6ee8c03acae07e3633d8
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-000.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-001.xml b/corpus/paragraph-edit/before/read/page-001.xml
new file mode 100644
index 0000000000000000000000000000000000000000..239cd8121764dc73f00afd0c0fa3de733c92c4e4
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-001.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-002.xml b/corpus/paragraph-edit/before/read/page-002.xml
new file mode 100644
index 0000000000000000000000000000000000000000..73e8745815055166d503f1eca0ceff94e1ed6f39
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-002.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-003.xml b/corpus/paragraph-edit/before/read/page-003.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eae2c00fb58e2266ae3730438a22e95b7a331f8a
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-003.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-004.xml b/corpus/paragraph-edit/before/read/page-004.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e894ea69fe7a97ce449e03710590641949cbcb58
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-004.xml
@@ -0,0 +1,3 @@
+
+Link label tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-005.xml b/corpus/paragraph-edit/before/read/page-005.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8e9deb6bf6025d5a6013cc5bb25bfab42be5b76a
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-005.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-006.xml b/corpus/paragraph-edit/before/read/page-006.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d7b2a5d77894c3cd32111e46361a53b39a1c2eb8
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-006.xml
@@ -0,0 +1,20 @@
+
+Bold 🦀 italic é color 東京
+End]]>Fictitious: café, 東京, مرحبا]]>
diff --git a/corpus/paragraph-edit/before/read/page-007.xml b/corpus/paragraph-edit/before/read/page-007.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f97b0e3dd7fe1b9cc759b69f07edd0d121d192bf
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-007.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-008.xml b/corpus/paragraph-edit/before/read/page-008.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f40ff26cac5b9ce5a123eca4049a3faff199e940
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-008.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-009.xml b/corpus/paragraph-edit/before/read/page-009.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f2c0715aaac3d0495826eb4bdcc559bd33a686d7
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-009.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-010.xml b/corpus/paragraph-edit/before/read/page-010.xml
new file mode 100644
index 0000000000000000000000000000000000000000..33770852cc66c64799cc6fdb01a1b219677647c9
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-010.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-011.xml b/corpus/paragraph-edit/before/read/page-011.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e0afeda5652c651623b71c70d30fb008381b33a2
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-011.xml
@@ -0,0 +1,3 @@
+
+
+soft break]]>
diff --git a/corpus/paragraph-edit/before/read/page-012.xml b/corpus/paragraph-edit/before/read/page-012.xml
new file mode 100644
index 0000000000000000000000000000000000000000..875f1639a34c4669c6e3e4d085da6c171d1a724b
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-012.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/before/read/page-013.xml b/corpus/paragraph-edit/before/read/page-013.xml
new file mode 100644
index 0000000000000000000000000000000000000000..29f08e7b65bb9733c9edd87e53c3c429494b9a13
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/page-013.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/corpus/paragraph-edit/before/read/payloads.json b/corpus/paragraph-edit/before/read/payloads.json
new file mode 100644
index 0000000000000000000000000000000000000000..1ce91a413d6fff4d58765187b76756f0e97ae843
--- /dev/null
+++ b/corpus/paragraph-edit/before/read/payloads.json
@@ -0,0 +1,3 @@
+[
+
+]
\ No newline at end of file
diff --git a/corpus/paragraph-edit/cold-split/notebook/Open Notebook.onetoc2 b/corpus/paragraph-edit/cold-split/notebook/Open Notebook.onetoc2
new file mode 120000
index 0000000000000000000000000000000000000000..a6c7d197861f52dda5ecaf4da2ab7e471f409518
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/notebook/Open Notebook.onetoc2
@@ -0,0 +1 @@
+../../before/notebook/Open Notebook.onetoc2
\ No newline at end of file
diff --git a/corpus/paragraph-edit/cold-split/notebook/synthetic.one b/corpus/paragraph-edit/cold-split/notebook/synthetic.one
new file mode 100644
index 0000000000000000000000000000000000000000..17a12021a235afca288596231b20b34ce3b88438
Binary files /dev/null and b/corpus/paragraph-edit/cold-split/notebook/synthetic.one differ
diff --git a/corpus/paragraph-edit/cold-split/read/environment.json b/corpus/paragraph-edit/cold-split/read/environment.json
new file mode 100644
index 0000000000000000000000000000000000000000..ca89644d60e2c61179149a5cbf5e28bab9570731
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/environment.json
@@ -0,0 +1,7 @@
+{
+ "powershell": "5.1.14409.1005",
+ "schema": "xs2010",
+ "hostname": "ONE-M6-8D10767D",
+ "cold": true,
+ "onenote": "14.0.4763.1000"
+}
diff --git a/corpus/paragraph-edit/cold-split/read/hierarchy.xml b/corpus/paragraph-edit/cold-split/read/hierarchy.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f88266f92db6e79663ec9acc28167fc7ae647da6
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/hierarchy.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/corpus/paragraph-edit/cold-split/read/page-000.xml b/corpus/paragraph-edit/cold-split/read/page-000.xml
new file mode 100644
index 0000000000000000000000000000000000000000..347e508cebb9d032041b4677e60cb4add901497d
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-000.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-001.xml b/corpus/paragraph-edit/cold-split/read/page-001.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ae955a8a8605a4ff1ce7243994110c1e81a144c7
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-001.xml
@@ -0,0 +1,20 @@
+
+Bold 🦀 italic é color 東京
+End]]>Fictitious: café, 東京, مرحبا]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-002.xml b/corpus/paragraph-edit/cold-split/read/page-002.xml
new file mode 100644
index 0000000000000000000000000000000000000000..88cb10ea6dfab1f5b4bbcf825e2a64794ac96315
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-002.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-003.xml b/corpus/paragraph-edit/cold-split/read/page-003.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e5fae9952bb24e3b5f83a7c32a7b29953bfa38db
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-003.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-004.xml b/corpus/paragraph-edit/cold-split/read/page-004.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cf9f48dddf129bfb047525c29a423a5ef2a1a7f3
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-004.xml
@@ -0,0 +1,3 @@
+
+Link label tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-005.xml b/corpus/paragraph-edit/cold-split/read/page-005.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eca16897930bafe8272990b334516b0eda1201a4
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-005.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-006.xml b/corpus/paragraph-edit/cold-split/read/page-006.xml
new file mode 100644
index 0000000000000000000000000000000000000000..33506bb8e473b5a0949ee5a9f4257e2ace4fb802
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-006.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-007.xml b/corpus/paragraph-edit/cold-split/read/page-007.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0fd04445529ff89b7e29ac5a95bbb585b73fd271
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-007.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-008.xml b/corpus/paragraph-edit/cold-split/read/page-008.xml
new file mode 100644
index 0000000000000000000000000000000000000000..77b41e6f3db09ebe4d4270d61fb9f13d05c6c4e3
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-008.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-009.xml b/corpus/paragraph-edit/cold-split/read/page-009.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9b3d74d5aeeea48903e9b67e8e7b402d20f01b5a
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-009.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-010.xml b/corpus/paragraph-edit/cold-split/read/page-010.xml
new file mode 100644
index 0000000000000000000000000000000000000000..75aed24e94fad7c97aa0b86474d4e8f150ec7984
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-010.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/corpus/paragraph-edit/cold-split/read/page-011.xml b/corpus/paragraph-edit/cold-split/read/page-011.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1a8527083f4a076dd91122b60e393e58220da690
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-011.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-012.xml b/corpus/paragraph-edit/cold-split/read/page-012.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2492bf01b2b32029aae4b6ffbd889f349370c947
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-012.xml
@@ -0,0 +1,5 @@
+
+Bold]]> italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/cold-split/read/page-013.xml b/corpus/paragraph-edit/cold-split/read/page-013.xml
new file mode 100644
index 0000000000000000000000000000000000000000..577b45ff30558421f1336b1036d3f2a2b61ed8e8
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/page-013.xml
@@ -0,0 +1,3 @@
+
+
+soft break]]>
diff --git a/corpus/paragraph-edit/cold-split/read/payloads.json b/corpus/paragraph-edit/cold-split/read/payloads.json
new file mode 120000
index 0000000000000000000000000000000000000000..4a72bfff3e4007f7e1da7b55da52ca9286ab5b86
--- /dev/null
+++ b/corpus/paragraph-edit/cold-split/read/payloads.json
@@ -0,0 +1 @@
+../../before/read/payloads.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-000.xml b/corpus/paragraph-edit/joined/first-backspace/page-000.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e57b73d3aa9689d1e2b48b7427c5226314b44660
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-000.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-001.xml b/corpus/paragraph-edit/joined/first-backspace/page-001.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0f266a1324bb81af7e1c44343c5d7727ff265273
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-001.xml
@@ -0,0 +1,20 @@
+
+Bold 🦀 italic é color 東京
+End]]>Fictitious: café, 東京, مرحبا]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-002.xml b/corpus/paragraph-edit/joined/first-backspace/page-002.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a351651c8d8f00eb17371d1abc5562289e868505
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-002.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-003.xml b/corpus/paragraph-edit/joined/first-backspace/page-003.xml
new file mode 100644
index 0000000000000000000000000000000000000000..517a6e47001c671625ec8e2d3c81ef596e694557
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-003.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-004.xml b/corpus/paragraph-edit/joined/first-backspace/page-004.xml
new file mode 100644
index 0000000000000000000000000000000000000000..938a4b3cf86e08e924511eb8fe96b1c7dff69a9f
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-004.xml
@@ -0,0 +1,3 @@
+
+Link label tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-005.xml b/corpus/paragraph-edit/joined/first-backspace/page-005.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d8162c7f67be743088540782d7e089061aee1c6a
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-005.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-006.xml b/corpus/paragraph-edit/joined/first-backspace/page-006.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1ddcf067077c8eb6eb298778175d589200862053
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-006.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-007.xml b/corpus/paragraph-edit/joined/first-backspace/page-007.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b386ef5177ac49ec68d1345bbac758d2d64e1298
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-007.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-008.xml b/corpus/paragraph-edit/joined/first-backspace/page-008.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4bfb20d5101f347c6699a748407188aa0c4b57c4
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-008.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-009.xml b/corpus/paragraph-edit/joined/first-backspace/page-009.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1ac476e2a3a1116e2919e661992f642cb9e90f98
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-009.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-010.xml b/corpus/paragraph-edit/joined/first-backspace/page-010.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fb2a9042f0086ce7cf003238010f8606f219de07
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-010.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-011.xml b/corpus/paragraph-edit/joined/first-backspace/page-011.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e5963403bb328488d65f4fded60f6cafba222b39
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-011.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-012.xml b/corpus/paragraph-edit/joined/first-backspace/page-012.xml
new file mode 100644
index 0000000000000000000000000000000000000000..69178a4fd9ba9d1d3ad3b8b91deb6aa517ba7306
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-012.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/first-backspace/page-013.xml b/corpus/paragraph-edit/joined/first-backspace/page-013.xml
new file mode 100644
index 0000000000000000000000000000000000000000..68e09626e339fbdcc375a50ea3a291929dbecbbe
--- /dev/null
+++ b/corpus/paragraph-edit/joined/first-backspace/page-013.xml
@@ -0,0 +1,3 @@
+
+
+soft break]]>
diff --git a/corpus/paragraph-edit/joined/notebook/Open Notebook.onetoc2 b/corpus/paragraph-edit/joined/notebook/Open Notebook.onetoc2
new file mode 120000
index 0000000000000000000000000000000000000000..a6c7d197861f52dda5ecaf4da2ab7e471f409518
--- /dev/null
+++ b/corpus/paragraph-edit/joined/notebook/Open Notebook.onetoc2
@@ -0,0 +1 @@
+../../before/notebook/Open Notebook.onetoc2
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/notebook/synthetic.one b/corpus/paragraph-edit/joined/notebook/synthetic.one
new file mode 100644
index 0000000000000000000000000000000000000000..cc00e159ea992436bdcc065e8e6a2ae8dc7a438b
Binary files /dev/null and b/corpus/paragraph-edit/joined/notebook/synthetic.one differ
diff --git a/corpus/paragraph-edit/joined/read/environment.json b/corpus/paragraph-edit/joined/read/environment.json
new file mode 100644
index 0000000000000000000000000000000000000000..8af10bbbcec840cf075049e56114048556c57c66
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/environment.json
@@ -0,0 +1,7 @@
+{
+ "powershell": "5.1.14409.1005",
+ "schema": "xs2010",
+ "hostname": "ONE-M6-8D10767D",
+ "cold": false,
+ "onenote": "14.0.4763.1000"
+}
diff --git a/corpus/paragraph-edit/joined/read/hierarchy.xml b/corpus/paragraph-edit/joined/read/hierarchy.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1ef41a703bfb9493d6a81b5dc77fe04f81e72636
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/hierarchy.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/corpus/paragraph-edit/joined/read/page-000.xml b/corpus/paragraph-edit/joined/read/page-000.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ad81e70a671d93904fc17271498363e3e001732d
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-000.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/read/page-001.xml b/corpus/paragraph-edit/joined/read/page-001.xml
new file mode 120000
index 0000000000000000000000000000000000000000..0ac1857901861a92ebc942f64f652fa8b68360cf
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-001.xml
@@ -0,0 +1 @@
+../first-backspace/page-001.xml
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/read/page-002.xml b/corpus/paragraph-edit/joined/read/page-002.xml
new file mode 120000
index 0000000000000000000000000000000000000000..9ec46da096f316383e27d344ea318cd64d296c76
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-002.xml
@@ -0,0 +1 @@
+../first-backspace/page-002.xml
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/read/page-003.xml b/corpus/paragraph-edit/joined/read/page-003.xml
new file mode 120000
index 0000000000000000000000000000000000000000..4d14281451f9299f6bd6fab480fb430cdec3ad0a
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-003.xml
@@ -0,0 +1 @@
+../first-backspace/page-003.xml
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/read/page-004.xml b/corpus/paragraph-edit/joined/read/page-004.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ff859c9c866734c09e43b947d35e5e17b3e8db32
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-004.xml
@@ -0,0 +1,3 @@
+
+Link label tail]]>
diff --git a/corpus/paragraph-edit/joined/read/page-005.xml b/corpus/paragraph-edit/joined/read/page-005.xml
new file mode 120000
index 0000000000000000000000000000000000000000..a843faa11fbd9702dcfe560dd5621fdce80785a4
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-005.xml
@@ -0,0 +1 @@
+../first-backspace/page-005.xml
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/read/page-006.xml b/corpus/paragraph-edit/joined/read/page-006.xml
new file mode 120000
index 0000000000000000000000000000000000000000..f5464c7f79f5c498f519ae434d371b42c18e31be
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-006.xml
@@ -0,0 +1 @@
+../first-backspace/page-006.xml
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/read/page-007.xml b/corpus/paragraph-edit/joined/read/page-007.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8857fda6f1a5a8a9789bef4d8c3a615d4f048375
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-007.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/read/page-008.xml b/corpus/paragraph-edit/joined/read/page-008.xml
new file mode 100644
index 0000000000000000000000000000000000000000..514dd32fa6e776ebbaf87509ac3484b67f873c7b
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-008.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/joined/read/page-009.xml b/corpus/paragraph-edit/joined/read/page-009.xml
new file mode 120000
index 0000000000000000000000000000000000000000..6a08061c645d13b437677d84ca549eb64bb1bd45
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-009.xml
@@ -0,0 +1 @@
+../first-backspace/page-009.xml
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/read/page-010.xml b/corpus/paragraph-edit/joined/read/page-010.xml
new file mode 120000
index 0000000000000000000000000000000000000000..f04c8b17e5a22a45d231e9802db6039de8da6a1a
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-010.xml
@@ -0,0 +1 @@
+../first-backspace/page-010.xml
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/read/page-011.xml b/corpus/paragraph-edit/joined/read/page-011.xml
new file mode 120000
index 0000000000000000000000000000000000000000..b7b2740f37fac425f20230a9612a925d77571dc6
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-011.xml
@@ -0,0 +1 @@
+../first-backspace/page-011.xml
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/read/page-012.xml b/corpus/paragraph-edit/joined/read/page-012.xml
new file mode 120000
index 0000000000000000000000000000000000000000..651c39040531fc1ca870d18b857049980b354493
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-012.xml
@@ -0,0 +1 @@
+../first-backspace/page-012.xml
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/read/page-013.xml b/corpus/paragraph-edit/joined/read/page-013.xml
new file mode 120000
index 0000000000000000000000000000000000000000..62442ea63f11bdbeeea95a0358fbce1806a4aa98
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/page-013.xml
@@ -0,0 +1 @@
+../first-backspace/page-013.xml
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/read/payloads.json b/corpus/paragraph-edit/joined/read/payloads.json
new file mode 120000
index 0000000000000000000000000000000000000000..4a72bfff3e4007f7e1da7b55da52ca9286ab5b86
--- /dev/null
+++ b/corpus/paragraph-edit/joined/read/payloads.json
@@ -0,0 +1 @@
+../../before/read/payloads.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/run.json b/corpus/paragraph-edit/joined/run.json
new file mode 100644
index 0000000000000000000000000000000000000000..0e1d54cacce93d9cc87f5558f33d4e52563b1a0a
--- /dev/null
+++ b/corpus/paragraph-edit/joined/run.json
@@ -0,0 +1,18 @@
+{
+ "notebook": "/Users/clo/dev/one/evidence/m10/paragraph-native-matrix-02/notebook",
+ "expected_pages": 14,
+ "author": null,
+ "author_timeout_seconds": 600,
+ "inspect": true,
+ "collect_notebook": true,
+ "base": {
+ "file": "win7-office-base.qcow2",
+ "format": "qcow2",
+ "sha256": "a1a4f8fab782ee14885ff801ca2f6347c208fdcfc3513637096f314315c89346",
+ "virtual_size": 68719476736
+ },
+ "scripts": {
+ "cold.ps1": "c177fc72ae6c2634d186f5671a880de20b09f9716532c37c69cb13aa15c7e331",
+ "read.ps1": "04013bfcccee40a17e2a225f9b9e96f40a3a8daad9e350609654f8eda3ccbb41"
+ }
+}
diff --git a/corpus/paragraph-edit/joined/source.json b/corpus/paragraph-edit/joined/source.json
new file mode 100644
index 0000000000000000000000000000000000000000..7c676c6ed8f3fca121c3b05767eacfbcd4378898
--- /dev/null
+++ b/corpus/paragraph-edit/joined/source.json
@@ -0,0 +1,14 @@
+[
+ {
+ "path": "Open Notebook.onetoc2",
+ "bytes": 4800,
+ "sha256": "d5ad0479c7301028f97744151d87968ab877b3e21ab76e336dff522bfb6e977b",
+ "mtime_ns": 1788855157213410685
+ },
+ {
+ "path": "synthetic.one",
+ "bytes": 117336,
+ "sha256": "d563065b5c8da6d76f56cca06896ccad8f85d781d8392ad8092c6ab86b7d4343",
+ "mtime_ns": 1788855157213628018
+ }
+]
diff --git a/corpus/paragraph-edit/joined/teardown.json b/corpus/paragraph-edit/joined/teardown.json
new file mode 100644
index 0000000000000000000000000000000000000000..05a47793de40f322e745c4c4183727e3590ecf70
--- /dev/null
+++ b/corpus/paragraph-edit/joined/teardown.json
@@ -0,0 +1 @@
+{"absent": true}
diff --git a/corpus/paragraph-edit/joined/ui/capture-first.json b/corpus/paragraph-edit/joined/ui/capture-first.json
new file mode 100644
index 0000000000000000000000000000000000000000..0ba66787f8c38fde2c70f82af2ec71c8756ba5a0
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/capture-first.json
@@ -0,0 +1,6 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "error": null
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/capture-first.ps1 b/corpus/paragraph-edit/joined/ui/capture-first.ps1
new file mode 100644
index 0000000000000000000000000000000000000000..1f609d68ca0f5d80181f59bd0c8c2833a1b7f802
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/capture-first.ps1
@@ -0,0 +1,14 @@
+Set-StrictMode -Version Latest
+$ErrorActionPreference = 'Stop'
+$app = New-Object -ComObject OneNote.Application
+$out = 'C:\one-tests\runs\capture\join-first'
+New-Item -ItemType Directory -Path $out | Out-Null
+$pages = @('{10598CD2-0723-42D7-BF23-B94ACAD9FE98}{1}{B0}','{488376FA-2C20-49A0-AD63-06E9BB6F864E}{1}{B0}','{5582A13D-6A30-45C6-870C-2C00289B5532}{1}{B0}','{56AD7542-11FB-4FA0-9969-68E0862AB40C}{1}{B0}','{5E5A198A-FAB0-4244-B63D-08CAE25D99F5}{1}{B0}','{5F06FB85-2000-4F62-B60A-C044F19B9B6A}{1}{B0}','{68A9ABE2-3C66-4F1A-B150-67B46DC1D6BE}{1}{B0}','{883508F1-BFB9-451D-B80E-99CE85E616C3}{1}{B0}','{B8B5BDEA-9DE8-4AFA-B38A-FA3F252F7AEF}{1}{B0}','{BEE46007-7505-4670-A7EE-EEB0FA357A71}{1}{B0}','{C8438CC2-32B2-41CC-A696-4BAE6568F396}{1}{B0}','{D2B90D6D-D72E-4720-9D2D-17121D2F2774}{1}{B0}','{F24FC20B-6F88-420C-9835-8735D0222E13}{1}{B0}','{F47A1E7D-C667-4C0A-B942-F9716F98224B}{1}{B0}')
+$i = 0
+foreach ($id in $pages) {
+ $xml = ''
+ $app.GetPageContent($id, [ref]$xml, 1, 1)
+ [IO.File]::WriteAllText((Join-Path $out ('page-{0:d3}.xml' -f $i)), $xml, [Text.Encoding]::UTF8)
+ $i++
+}
+[void][Runtime.InteropServices.Marshal]::FinalReleaseComObject($app)
diff --git a/corpus/paragraph-edit/joined/ui/selections.json b/corpus/paragraph-edit/joined/ui/selections.json
new file mode 100644
index 0000000000000000000000000000000000000000..03d56b3373262f167a5eeb06758b41a71b5d1dbd
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/selections.json
@@ -0,0 +1,80 @@
+[
+ {
+ "name": "Split middle",
+ "page": "{D2B90D6D-D72E-4720-9D2D-17121D2F2774}{1}{B0}",
+ "object": "{27380AFB-64A9-4D62-B4A6-00F074A62D13}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split style boundary",
+ "page": "{F24FC20B-6F88-420C-9835-8735D0222E13}{1}{B0}",
+ "object": "{298089D0-38DF-481A-9CB7-1313598683FC}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split start",
+ "page": "{5582A13D-6A30-45C6-870C-2C00289B5532}{1}{B0}",
+ "object": "{9EABED1E-F611-49F9-8BD1-F2BFDC42FB24}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split end",
+ "page": "{BEE46007-7505-4670-A7EE-EEB0FA357A71}{1}{B0}",
+ "object": "{4C86E604-486A-4936-A02F-91FE50086290}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split empty",
+ "page": "{C8438CC2-32B2-41CC-A696-4BAE6568F396}{1}{B0}",
+ "object": "{C6500222-467D-4F01-938E-E60ED395BE17}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split parent",
+ "page": "{56AD7542-11FB-4FA0-9969-68E0862AB40C}{1}{B0}",
+ "object": "{E4D7EDD5-0391-4A85-AFC9-58F66BFF3BA5}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split child",
+ "page": "{10598CD2-0723-42D7-BF23-B94ACAD9FE98}{1}{B0}",
+ "object": "{F0BF446D-9EB7-4779-9AA5-2B26CE785A50}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split bullet",
+ "page": "{B8B5BDEA-9DE8-4AFA-B38A-FA3F252F7AEF}{1}{B0}",
+ "object": "{0468BDE2-84BE-47D4-BCA5-692CB4F18A0D}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split number",
+ "page": "{883508F1-BFB9-451D-B80E-99CE85E616C3}{1}{B0}",
+ "object": "{F1A4E8E9-779F-44DA-8B2F-7649DB21C69A}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split tag",
+ "page": "{5F06FB85-2000-4F62-B60A-C044F19B9B6A}{1}{B0}",
+ "object": "{381B0A74-8BD4-41F2-9451-884502ABF22A}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split cell",
+ "page": "{68A9ABE2-3C66-4F1A-B150-67B46DC1D6BE}{1}{B0}",
+ "object": "{32AE7C99-3E1F-4147-AC54-809B85578108}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split soft break",
+ "page": "{F47A1E7D-C667-4C0A-B942-F9716F98224B}{1}{B0}",
+ "object": "{EDCDC68C-6206-4475-9442-4426E2A05C6A}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ },
+ {
+ "name": "Split before hyperlink",
+ "page": "{5E5A198A-FAB0-4244-B63D-08CAE25D99F5}{1}{B0}",
+ "object": "{022941A3-2EC7-492C-B428-FE0881641F72}{11}{B0}",
+ "keys": "{Left}{Backspace}"
+ }
+]
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-before-hyperlink.ahk b/corpus/paragraph-edit/joined/ui/split-before-hyperlink.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..f0fbce1e7a5185dba8ed30e61dc4cd0510b824c7
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-before-hyperlink.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{5E5A198A-FAB0-4244-B63D-08CAE25D99F5}{1}{B0}", "{022941A3-2EC7-492C-B428-FE0881641F72}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-before-hyperlink.json b/corpus/paragraph-edit/joined/ui/split-before-hyperlink.json
new file mode 100644
index 0000000000000000000000000000000000000000..160b5b3947358fbe4a11025b2edadab365f38d7a
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-before-hyperlink.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split before hyperlink - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-before-hyperlink.png b/corpus/paragraph-edit/joined/ui/split-before-hyperlink.png
new file mode 100644
index 0000000000000000000000000000000000000000..d4e33c2df4a0327885553bb8570cf59d2e2e3b7d
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-before-hyperlink.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-bullet-second.ahk b/corpus/paragraph-edit/joined/ui/split-bullet-second.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..3ad0d40f57e106d89a015028ece40907690d4563
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-bullet-second.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{B8B5BDEA-9DE8-4AFA-B38A-FA3F252F7AEF}{1}{B0}", "{0468BDE2-84BE-47D4-BCA5-692CB4F18A0D}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-bullet-second.json b/corpus/paragraph-edit/joined/ui/split-bullet-second.json
new file mode 100644
index 0000000000000000000000000000000000000000..b07a4a1e59e449a59a3234586cee2e1f44bc2b54
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-bullet-second.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split bullet - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-bullet-second.png b/corpus/paragraph-edit/joined/ui/split-bullet-second.png
new file mode 100644
index 0000000000000000000000000000000000000000..faaa4176919345b07c49ae341e2954bfc5cbe879
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-bullet-second.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-bullet.ahk b/corpus/paragraph-edit/joined/ui/split-bullet.ahk
new file mode 120000
index 0000000000000000000000000000000000000000..798bfc8b780d9806b17a7cc2b6dd87ac5961c850
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-bullet.ahk
@@ -0,0 +1 @@
+split-bullet-second.ahk
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-bullet.json b/corpus/paragraph-edit/joined/ui/split-bullet.json
new file mode 120000
index 0000000000000000000000000000000000000000..c8259ec32698dc36f0b78fd2a7f72bfd5d9e4ae2
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-bullet.json
@@ -0,0 +1 @@
+split-bullet-second.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-bullet.png b/corpus/paragraph-edit/joined/ui/split-bullet.png
new file mode 100644
index 0000000000000000000000000000000000000000..ca57c3ae5b9605a65b4e094a2131776797559765
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-bullet.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-cell.ahk b/corpus/paragraph-edit/joined/ui/split-cell.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..6cb4464aac06ada20ac980bf815070b1f56d544a
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-cell.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{68A9ABE2-3C66-4F1A-B150-67B46DC1D6BE}{1}{B0}", "{32AE7C99-3E1F-4147-AC54-809B85578108}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-cell.json b/corpus/paragraph-edit/joined/ui/split-cell.json
new file mode 100644
index 0000000000000000000000000000000000000000..cf5796db966e8245fc67e39e8eb44bddc9a7030c
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-cell.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split cell - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-cell.png b/corpus/paragraph-edit/joined/ui/split-cell.png
new file mode 100644
index 0000000000000000000000000000000000000000..518a4eb9c2163ef037bbb1f04ecddbd8d3da0f4d
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-cell.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-child-second.ahk b/corpus/paragraph-edit/joined/ui/split-child-second.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..b87b5c1df5bf230fcf16d680558120f2d317c03a
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-child-second.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{10598CD2-0723-42D7-BF23-B94ACAD9FE98}{1}{B0}", "{F0BF446D-9EB7-4779-9AA5-2B26CE785A50}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-child-second.json b/corpus/paragraph-edit/joined/ui/split-child-second.json
new file mode 100644
index 0000000000000000000000000000000000000000..b31fd369f638dfd9a6bedc28e3d18ca25801d519
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-child-second.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split child - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-child-second.png b/corpus/paragraph-edit/joined/ui/split-child-second.png
new file mode 100644
index 0000000000000000000000000000000000000000..307a8db84fcf6ef6543c8c6817c42cf01795987b
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-child-second.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-child.ahk b/corpus/paragraph-edit/joined/ui/split-child.ahk
new file mode 120000
index 0000000000000000000000000000000000000000..1890420ad594825903ad54059f3209f698df37c2
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-child.ahk
@@ -0,0 +1 @@
+split-child-second.ahk
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-child.json b/corpus/paragraph-edit/joined/ui/split-child.json
new file mode 120000
index 0000000000000000000000000000000000000000..dd5633580a3976680ae3cf13aca7d233b803e472
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-child.json
@@ -0,0 +1 @@
+split-child-second.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-child.png b/corpus/paragraph-edit/joined/ui/split-child.png
new file mode 100644
index 0000000000000000000000000000000000000000..d472c28ede3373e782646f4b33090b2ef1b1b386
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-child.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-empty.ahk b/corpus/paragraph-edit/joined/ui/split-empty.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..9fc2d0d23950ac54eade1248deddf4c4207eec16
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-empty.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{C8438CC2-32B2-41CC-A696-4BAE6568F396}{1}{B0}", "{C6500222-467D-4F01-938E-E60ED395BE17}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-empty.json b/corpus/paragraph-edit/joined/ui/split-empty.json
new file mode 100644
index 0000000000000000000000000000000000000000..c564fedbf8698c3edeeb72b34a6ff2f8f3e96947
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-empty.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split empty - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-empty.png b/corpus/paragraph-edit/joined/ui/split-empty.png
new file mode 100644
index 0000000000000000000000000000000000000000..43cba18530714ed2381f182a1e7ca104ecb27189
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-empty.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-end.ahk b/corpus/paragraph-edit/joined/ui/split-end.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..f94eabf464c97a88dd474bdacd45326b37fe2ce5
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-end.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{BEE46007-7505-4670-A7EE-EEB0FA357A71}{1}{B0}", "{4C86E604-486A-4936-A02F-91FE50086290}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-end.json b/corpus/paragraph-edit/joined/ui/split-end.json
new file mode 100644
index 0000000000000000000000000000000000000000..8cbff82a2cd888fbdab74fb9a9b625e73945bbb4
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-end.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split end - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-end.png b/corpus/paragraph-edit/joined/ui/split-end.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f5e159d02900db9f710099343d4c9933dd263c7
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-end.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-middle.ahk b/corpus/paragraph-edit/joined/ui/split-middle.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..fa362e66ca5ae286c47ee90ef7e18be47b3b0278
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-middle.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{D2B90D6D-D72E-4720-9D2D-17121D2F2774}{1}{B0}", "{27380AFB-64A9-4D62-B4A6-00F074A62D13}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-middle.json b/corpus/paragraph-edit/joined/ui/split-middle.json
new file mode 100644
index 0000000000000000000000000000000000000000..0792a13cf3a0387631c505894ffacf21f4c149e2
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-middle.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split middle - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-middle.png b/corpus/paragraph-edit/joined/ui/split-middle.png
new file mode 100644
index 0000000000000000000000000000000000000000..0439f939b6927603847b5def7aa2f31161fcab0f
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-middle.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-number-second.ahk b/corpus/paragraph-edit/joined/ui/split-number-second.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..954a036b0a564e2a21bc7df425b0540bcc33899b
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-number-second.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{883508F1-BFB9-451D-B80E-99CE85E616C3}{1}{B0}", "{F1A4E8E9-779F-44DA-8B2F-7649DB21C69A}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-number-second.json b/corpus/paragraph-edit/joined/ui/split-number-second.json
new file mode 100644
index 0000000000000000000000000000000000000000..a6c68149aee23c0d9655419c3a8689ecb48f31e4
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-number-second.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split number - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-number-second.png b/corpus/paragraph-edit/joined/ui/split-number-second.png
new file mode 100644
index 0000000000000000000000000000000000000000..68a733b2e5abc593470003ce9c234f08a0820ad7
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-number-second.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-number.ahk b/corpus/paragraph-edit/joined/ui/split-number.ahk
new file mode 120000
index 0000000000000000000000000000000000000000..65e4c477a0f8bea2a323e6baf6cf15463a23b3cd
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-number.ahk
@@ -0,0 +1 @@
+split-number-second.ahk
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-number.json b/corpus/paragraph-edit/joined/ui/split-number.json
new file mode 120000
index 0000000000000000000000000000000000000000..6b9d25f2e5ce02f7baaea1214590eb660249d194
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-number.json
@@ -0,0 +1 @@
+split-number-second.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-number.png b/corpus/paragraph-edit/joined/ui/split-number.png
new file mode 100644
index 0000000000000000000000000000000000000000..2cc0f043010b2815801c76d5a34ea574bfe5cf7e
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-number.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-parent.ahk b/corpus/paragraph-edit/joined/ui/split-parent.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..a6c893733a6bd7847d70322068b53acbe6778183
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-parent.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{56AD7542-11FB-4FA0-9969-68E0862AB40C}{1}{B0}", "{E4D7EDD5-0391-4A85-AFC9-58F66BFF3BA5}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-parent.json b/corpus/paragraph-edit/joined/ui/split-parent.json
new file mode 100644
index 0000000000000000000000000000000000000000..be4881fe6deb5c2bd80babf81c64127d4d01f446
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-parent.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split parent - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-parent.png b/corpus/paragraph-edit/joined/ui/split-parent.png
new file mode 100644
index 0000000000000000000000000000000000000000..fea871932118f21be919e457d1a2ab0bcdf2f918
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-parent.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-soft-break.ahk b/corpus/paragraph-edit/joined/ui/split-soft-break.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..b0e10b341666173109ec97de6c3bdb439f4c7304
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-soft-break.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{F47A1E7D-C667-4C0A-B942-F9716F98224B}{1}{B0}", "{EDCDC68C-6206-4475-9442-4426E2A05C6A}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-soft-break.json b/corpus/paragraph-edit/joined/ui/split-soft-break.json
new file mode 100644
index 0000000000000000000000000000000000000000..f073f081f16c07cf00cebac9661ba71e646f00b1
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-soft-break.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split soft break - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-soft-break.png b/corpus/paragraph-edit/joined/ui/split-soft-break.png
new file mode 100644
index 0000000000000000000000000000000000000000..b12084f326089637c70895a24f638d7d039880aa
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-soft-break.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-start.ahk b/corpus/paragraph-edit/joined/ui/split-start.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..e4a506948dc96e63dc2193abb668b1f4d9c58dbd
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-start.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{5582A13D-6A30-45C6-870C-2C00289B5532}{1}{B0}", "{9EABED1E-F611-49F9-8BD1-F2BFDC42FB24}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-start.json b/corpus/paragraph-edit/joined/ui/split-start.json
new file mode 100644
index 0000000000000000000000000000000000000000..ce6d5480076539787bc1b0aad66135f9effa3498
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-start.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split start - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-start.png b/corpus/paragraph-edit/joined/ui/split-start.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b5ce17c684cf4215cf8bdb20a6a9db80dfdbbb8
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-start.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-style-boundary.ahk b/corpus/paragraph-edit/joined/ui/split-style-boundary.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..f5ae6d1082c72245dd36f9cbce381b25c856b9b1
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-style-boundary.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{F24FC20B-6F88-420C-9835-8735D0222E13}{1}{B0}", "{298089D0-38DF-481A-9CB7-1313598683FC}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-style-boundary.json b/corpus/paragraph-edit/joined/ui/split-style-boundary.json
new file mode 100644
index 0000000000000000000000000000000000000000..a2a97c99108abeef0e8f94d9fc61547fa6f40542
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-style-boundary.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split style boundary - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-style-boundary.png b/corpus/paragraph-edit/joined/ui/split-style-boundary.png
new file mode 100644
index 0000000000000000000000000000000000000000..07417a5d3b57d13d054369c0e255f7c9a6250d6d
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-style-boundary.png differ
diff --git a/corpus/paragraph-edit/joined/ui/split-tag.ahk b/corpus/paragraph-edit/joined/ui/split-tag.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..898f963ef3c477f76cafba2b8b6ab7fa9d244046
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-tag.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{5F06FB85-2000-4F62-B60A-C044F19B9B6A}{1}{B0}", "{381B0A74-8BD4-41F2-9451-884502ABF22A}{11}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Backspace}"
diff --git a/corpus/paragraph-edit/joined/ui/split-tag.json b/corpus/paragraph-edit/joined/ui/split-tag.json
new file mode 100644
index 0000000000000000000000000000000000000000..7742a6ab31d3062373373524036f7b94d5d9a1a6
--- /dev/null
+++ b/corpus/paragraph-edit/joined/ui/split-tag.json
@@ -0,0 +1,13 @@
+{
+ "exit": 0,
+ "stdout": "",
+ "stderr": "",
+ "w": 1280,
+ "h": 720,
+ "error": null,
+ "win": {
+ "title": "Split tag - Microsoft OneNote",
+ "class": "Framework::CFrame",
+ "dialog": false
+ }
+}
\ No newline at end of file
diff --git a/corpus/paragraph-edit/joined/ui/split-tag.png b/corpus/paragraph-edit/joined/ui/split-tag.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1044b6c4e2e5e1211c5287568b5a120d2c6bba4
Binary files /dev/null and b/corpus/paragraph-edit/joined/ui/split-tag.png differ
diff --git a/corpus/paragraph-edit/manifest.json b/corpus/paragraph-edit/manifest.json
new file mode 100644
index 0000000000000000000000000000000000000000..6dfc99ff2a8106445fb1ce934cc470e0ed250996
--- /dev/null
+++ b/corpus/paragraph-edit/manifest.json
@@ -0,0 +1,1115 @@
+{
+ "cases": [
+ {
+ "case": "Split middle",
+ "offset_utf16": 2,
+ "original_paragraph": "{DFE950EF-6BEB-0F5B-2403-7B74F1AE5002},40",
+ "original_text": "{DFE950EF-6BEB-0F5B-2403-7B74F1AE5002},44",
+ "new_paragraph": "{0BA342F5-0690-087C-24FE-8EE6D81C2041},11",
+ "new_text": "{0BA342F5-0690-087C-24FE-8EE6D81C2041},12",
+ "native_metadata_changes": {}
+ },
+ {
+ "case": "Split style boundary",
+ "offset_utf16": 4,
+ "original_paragraph": "{5FB484E2-1E3E-0A9D-1989-271A3EBBEC42},40",
+ "original_text": "{5FB484E2-1E3E-0A9D-1989-271A3EBBEC42},44",
+ "new_paragraph": "{051BC1DE-5AE6-0D04-0CEF-9D05F53C8EAE},11",
+ "new_text": "{051BC1DE-5AE6-0D04-0CEF-9D05F53C8EAE},12",
+ "native_metadata_changes": {
+ "{5FB484E2-1E3E-0A9D-1989-271A3EBBEC42},52": {
+ "modified": [
+ 1473322172,
+ 1473322306
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split start",
+ "offset_utf16": 0,
+ "original_paragraph": "{012ED94B-43B3-079A-3050-B1CBE25C1C09},40",
+ "original_text": "{012ED94B-43B3-079A-3050-B1CBE25C1C09},44",
+ "new_paragraph": "{B230A510-9428-0CE7-1B89-7CA970F8F676},11",
+ "new_text": "{B230A510-9428-0CE7-1B89-7CA970F8F676},12",
+ "native_metadata_changes": {
+ "{012ED94B-43B3-079A-3050-B1CBE25C1C09},52": {
+ "modified": [
+ 1473322172,
+ 1473322308
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split end",
+ "offset_utf16": 22,
+ "original_paragraph": "{DAF723A3-C2A3-0798-2EAB-34613166A794},40",
+ "original_text": "{DAF723A3-C2A3-0798-2EAB-34613166A794},44",
+ "new_paragraph": "{601DAE0A-2A53-0C28-3077-1FE8FCB26FC2},11",
+ "new_text": "{601DAE0A-2A53-0C28-3077-1FE8FCB26FC2},12",
+ "native_metadata_changes": {
+ "{DAF723A3-C2A3-0798-2EAB-34613166A794},52": {
+ "modified": [
+ 1473322173,
+ 1473322310
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split empty",
+ "offset_utf16": 0,
+ "original_paragraph": "{0B467F31-D287-08CD-09F4-A6FBB2F5418F},40",
+ "original_text": "{0B467F31-D287-08CD-09F4-A6FBB2F5418F},45",
+ "new_paragraph": "{EACB4A2C-2444-0A1F-03D6-68187F2FB345},11",
+ "new_text": "{EACB4A2C-2444-0A1F-03D6-68187F2FB345},12",
+ "native_metadata_changes": {
+ "{0B467F31-D287-08CD-09F4-A6FBB2F5418F},50": {
+ "modified": [
+ 1473322173,
+ 1473322312
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split parent",
+ "offset_utf16": 2,
+ "original_paragraph": "{3860EA13-D444-0598-35D6-CF96769C6A21},40",
+ "original_text": "{3860EA13-D444-0598-35D6-CF96769C6A21},44",
+ "new_paragraph": "{C84CA5DB-61A8-0F9B-3F91-D6E0C74536F7},11",
+ "new_text": "{C84CA5DB-61A8-0F9B-3F91-D6E0C74536F7},12",
+ "native_metadata_changes": {
+ "{3860EA13-D444-0598-35D6-CF96769C6A21},52": {
+ "modified": [
+ 1473322173,
+ 1473322314
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ },
+ "{3860EA13-D444-0598-35D6-CF96769C6A21},57": {
+ "modified": [
+ 1473322173,
+ 1473322314
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split child",
+ "offset_utf16": 2,
+ "original_paragraph": "{B587CBC6-0BCC-0A23-16F6-E1B0B3C5D061},45",
+ "original_text": "{B587CBC6-0BCC-0A23-16F6-E1B0B3C5D061},49",
+ "new_paragraph": "{DC240C63-FC8E-0267-0AFD-A53062C25702},11",
+ "new_text": "{DC240C63-FC8E-0267-0AFD-A53062C25702},12",
+ "native_metadata_changes": {
+ "{B587CBC6-0BCC-0A23-16F6-E1B0B3C5D061},44": {
+ "modified": [
+ 1473322173,
+ 1473322316
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ },
+ "{B587CBC6-0BCC-0A23-16F6-E1B0B3C5D061},57": {
+ "modified": [
+ 1473322173,
+ 1473322316
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split bullet",
+ "offset_utf16": 2,
+ "original_paragraph": "{8C65E427-477C-02ED-1807-2F10E277019D},40",
+ "original_text": "{8C65E427-477C-02ED-1807-2F10E277019D},44",
+ "new_paragraph": "{28F3F5EC-E687-02CA-2CFD-E73A184B875F},11",
+ "new_text": "{28F3F5EC-E687-02CA-2CFD-E73A184B875F},12",
+ "native_metadata_changes": {
+ "{8C65E427-477C-02ED-1807-2F10E277019D},52": {
+ "modified": [
+ 1473322173,
+ 1473322318
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ },
+ "{8C65E427-477C-02ED-1807-2F10E277019D},58": {
+ "modified": [
+ 1473322173,
+ 1473322318
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split number",
+ "offset_utf16": 2,
+ "original_paragraph": "{D4ABBE4F-2165-0122-1F9F-ACE3FE92C703},40",
+ "original_text": "{D4ABBE4F-2165-0122-1F9F-ACE3FE92C703},44",
+ "new_paragraph": "{DD3FA0E7-15A6-01C4-1B77-F85F779BCBC8},11",
+ "new_text": "{DD3FA0E7-15A6-01C4-1B77-F85F779BCBC8},12",
+ "native_metadata_changes": {
+ "{D4ABBE4F-2165-0122-1F9F-ACE3FE92C703},53": {
+ "modified": [
+ 1473322174,
+ 1473322320
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split tag",
+ "offset_utf16": 2,
+ "original_paragraph": "{37AA5877-2980-0227-169F-8B1E8EE0795A},40",
+ "original_text": "{37AA5877-2980-0227-169F-8B1E8EE0795A},44",
+ "new_paragraph": "{1480427A-E9ED-04EC-0409-0653AE11FF78},11",
+ "new_text": "{1480427A-E9ED-04EC-0409-0653AE11FF78},12",
+ "native_metadata_changes": {
+ "{37AA5877-2980-0227-169F-8B1E8EE0795A},53": {
+ "modified": [
+ 1473322174,
+ 1473322322
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split cell",
+ "offset_utf16": 2,
+ "original_paragraph": "{F0832BC9-1578-0A96-08AF-99344644FFB8},46",
+ "original_text": "{F0832BC9-1578-0A96-08AF-99344644FFB8},50",
+ "new_paragraph": "{1E353497-5C26-0459-3C0C-0E8D29ED8C5A},11",
+ "new_text": "{1E353497-5C26-0459-3C0C-0E8D29ED8C5A},12",
+ "native_metadata_changes": {
+ "{F0832BC9-1578-0A96-08AF-99344644FFB8},61": {
+ "modified": [
+ 1473322174,
+ 1473322324
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ },
+ "{F0832BC9-1578-0A96-08AF-99344644FFB8},66": {
+ "modified": [
+ 1473322174,
+ 1473322324
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split soft break",
+ "offset_utf16": 2,
+ "original_paragraph": "{88189BA1-2F19-0282-05ED-A0B83153F143},40",
+ "original_text": "{88189BA1-2F19-0282-05ED-A0B83153F143},44",
+ "new_paragraph": "{C1568E82-003F-016B-041A-CA304E1A5138},11",
+ "new_text": "{C1568E82-003F-016B-041A-CA304E1A5138},12",
+ "native_metadata_changes": {
+ "{88189BA1-2F19-0282-05ED-A0B83153F143},49": {
+ "modified": [
+ 1473322174,
+ 1473322326
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "case": "Split before hyperlink",
+ "offset_utf16": 2,
+ "original_paragraph": "{543319E7-5AC7-0A74-10EA-39E7A94AD086},40",
+ "original_text": "{543319E7-5AC7-0A74-10EA-39E7A94AD086},44",
+ "new_paragraph": "{2EB209AD-4CFE-0C32-2470-701E2DDE1220},11",
+ "new_text": "{2EB209AD-4CFE-0C32-2470-701E2DDE1220},12",
+ "native_metadata_changes": {
+ "{543319E7-5AC7-0A74-10EA-39E7A94AD086},51": {
+ "modified": [
+ 1473322174,
+ 1473322328
+ ],
+ "extra": [
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "id": 268442878,
+ "value": {
+ "Bytes": "0904"
+ }
+ },
+ {
+ "id": 335551550,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 335551620,
+ "value": {
+ "Bytes": "01000000"
+ }
+ },
+ {
+ "id": 2281714909,
+ "value": "NoData"
+ }
+ ]
+ ]
+ ]
+ }
+ }
+ }
+ ],
+ "phases": {
+ "before": {
+ "notebook/Open Notebook.onetoc2": "d5ad0479c7301028f97744151d87968ab877b3e21ab76e336dff522bfb6e977b",
+ "notebook/synthetic.one": "12972a49eddfac350f8e6d31e13385cbed460612e5db7bc9e398d08df29cdfc9",
+ "read/environment.json": "e3728ee7f5ae9aee232175cb8f363ce5008ac1168fc845cbcd40d56e4b2fdc19",
+ "read/hierarchy.xml": "b73b4b0b3ef4971a14b57ed58cf5e6acd733dc48e91b879c22b1b4e19424a6df",
+ "read/page-000.xml": "71bcd04f4323a9e7ac279bdb08611767cf240bab475b825799dfe29e2d8950e7",
+ "read/page-001.xml": "84ddce8b60dc2665441de6f8488746366f38d210f96dd82b965b863279c83145",
+ "read/page-002.xml": "2a0801879f4fb86790f32b5b34b15dd05c808b9586208ef9b407130e5decb180",
+ "read/page-003.xml": "59fffc0a750156cb9388b256eef96832c71b3e3b5a093535cad3fd037159f37f",
+ "read/page-004.xml": "c3e2a038150db3796089a13efe21c7ce869eeaa088e83ab1b8817002f087c8b8",
+ "read/page-005.xml": "e1f416eb3de6469db520f144b1dd2d65556d744def5d54c017cd584e5a2df81d",
+ "read/page-006.xml": "6ec787ea1bc6d9a3fa051ed1553f59bf024c2a42d44992bc4feef63fb4cd54af",
+ "read/page-007.xml": "f3897d47a95b102c3c7ca9ac0dd28ffea8bae661a4649c6cd08ea2d63ba16339",
+ "read/page-008.xml": "4b250cf90e842c3229c4e6d36ea69ab8812357534d13769880b2b7c45550f0ed",
+ "read/page-009.xml": "5d4f29f58ce278f1a29189b2fd287c2eb923d0153a9e0d560bf818cff371013c",
+ "read/page-010.xml": "b82a90e94ef26597a71576073f4c3aa869ba3bb9d86d353af5a89ecc9892ecb9",
+ "read/page-011.xml": "567f3cddc70069016b4ab54ac38bf34c37073260f4ffb5c2832ee7364d97b906",
+ "read/page-012.xml": "36c3cd0a6e61489e160c22ec44f1a58aeda4358faacc63314ea6df7192b3037b",
+ "read/page-013.xml": "cb380bb80f73507c28bb7c5dfc73b04b6f59ea0522ce48a8c49700b8e7c7a553",
+ "read/payloads.json": "f1d4ed4a75237e4878028e6b6010c6bbef26a0046c58de51825558342883b19f"
+ },
+ "split": {
+ "notebook/Open Notebook.onetoc2": "d5ad0479c7301028f97744151d87968ab877b3e21ab76e336dff522bfb6e977b",
+ "notebook/synthetic.one": "d563065b5c8da6d76f56cca06896ccad8f85d781d8392ad8092c6ab86b7d4343",
+ "read/environment.json": "e3728ee7f5ae9aee232175cb8f363ce5008ac1168fc845cbcd40d56e4b2fdc19",
+ "read/hierarchy.xml": "d2dfc3749f7f284cba67732c7a07e4edb66e3e779edd0586e40365237175c155",
+ "read/page-000.xml": "5afdf38d9a83a0ad90f1447052b283c1a8abd514c70b2d47fb178929612ca76c",
+ "read/page-001.xml": "000bc51ae65d4e1905940329280c14d83f56d349b14e51191bc26a13451c8576",
+ "read/page-002.xml": "23c9da531f38248b29dcb4a107690f94e9f185c9d9f9479819272aaa92e1d1f4",
+ "read/page-003.xml": "afc4102efc77db37f8ec1db2cb5099aba2c76289ecdb5ae35aa49fdc8edad57a",
+ "read/page-004.xml": "e4e8d25ddb5292a404c7198c44550ed96a67fdd9e501b3580e6532dbe683ccaf",
+ "read/page-005.xml": "dbce8d8ea44200f2b5d07c58af31e1866648870235aa42f3999e0c536310bc12",
+ "read/page-006.xml": "bfab647d1afd522d99267f8c73a825849137bf90ceef49330b48948f3d0068ca",
+ "read/page-007.xml": "bca13722dec588f3b33a3775d53b09f8dff2bb41a513c43d8afc87c8f4ac703b",
+ "read/page-008.xml": "405dd5f4de4c14e735099f057087a95e3811f96b9a42d21be1d700c20db93f69",
+ "read/page-009.xml": "bfe78c69b4b3f6f125a2d14caf27624b8ffa3afd840311286a02dc6d29e460e7",
+ "read/page-010.xml": "4427d3e1c92d8169d6c0805191c19abb99e346b1ae34ecc3dadf01083ae3df27",
+ "read/page-011.xml": "4f20ea26c5527835112215c23294025ba911e52b5bb3ac4df00418ff53ebb028",
+ "read/page-012.xml": "281aa5fbe3ef3e9b5d1a41be1315e1af3b74256755db3351e5e7df598fd055d2",
+ "read/page-013.xml": "bcafdfeea985d066862c86e831ca24118730784ce5aea9a8db8b8f1b849ebdd9",
+ "read/payloads.json": "f1d4ed4a75237e4878028e6b6010c6bbef26a0046c58de51825558342883b19f"
+ },
+ "cold-split": {
+ "notebook/Open Notebook.onetoc2": "d5ad0479c7301028f97744151d87968ab877b3e21ab76e336dff522bfb6e977b",
+ "notebook/synthetic.one": "d563065b5c8da6d76f56cca06896ccad8f85d781d8392ad8092c6ab86b7d4343",
+ "read/environment.json": "ba935a421886f7967f702be9d283e179ae18bc8306de3f2adbcf734764d0caf6",
+ "read/hierarchy.xml": "67a6f1120926d543fbad79671d628222461cdd2fbf68984e9a6e0ba48ab27cd4",
+ "read/page-000.xml": "e048b9108922df6196f789d9754059a46ead75d0fe4c30d4fef03571bbf84c7b",
+ "read/page-001.xml": "f8b9cff38e277fb4501a26161a5f455f849ac743c611e6799c3ffeededab3a70",
+ "read/page-002.xml": "91519a91d6f4e4307e0381d1569a8b7de47395d54f2a90b7a47f88998aec1f30",
+ "read/page-003.xml": "f9eaa54cd29816b832ebf4ab758407c63879f6facb3707e56b85781ed5db6b4d",
+ "read/page-004.xml": "00909485e9273f6043ac231f62c845be1b90af192e7e40e962d7b387e43dd901",
+ "read/page-005.xml": "2b0ff3747966d93b16f39f5b1ef47a091bdd705bbc065d472af7525367762452",
+ "read/page-006.xml": "66992fcfdf762fa3d04672722bd597be4041e759d1c3c0d1756f2fee4cd37132",
+ "read/page-007.xml": "e6e260a8b80c6f34de27c8b277118253d02b2bb2db3a12f7a9974c9a147d7a05",
+ "read/page-008.xml": "145edbb6f8fb9fd4b92bc17ec63535064fd82ecaf92601455bd67695ab29403f",
+ "read/page-009.xml": "457cfc9cd762563c3781713f30f1fe59514e6baee59de1741c02bd7196077c01",
+ "read/page-010.xml": "9ef81540f09227c92807e355fb71b12b96d0d53072be54e88b76028ba24ef977",
+ "read/page-011.xml": "ab69c7e0c0af67a0e15fbe66f6783b81acd209ccf59057600023f4709a3475d0",
+ "read/page-012.xml": "d42a25416b7a7e8c773ffc2b4860a8bb5a507fe6bc62eb6d2311e9d3e36a4b65",
+ "read/page-013.xml": "cf783f78e3499750a1a402c94ee2bb5475e0a5e2ae256419601a63562637b529",
+ "read/payloads.json": "f1d4ed4a75237e4878028e6b6010c6bbef26a0046c58de51825558342883b19f"
+ },
+ "joined": {
+ "notebook/Open Notebook.onetoc2": "d5ad0479c7301028f97744151d87968ab877b3e21ab76e336dff522bfb6e977b",
+ "notebook/synthetic.one": "01b524c7b5f5584d0bfc9bf39e862648dbfc247831b39e939d8a876bb3791f53",
+ "read/environment.json": "cb13373bb2d302e72f84db1562a10f9b7a6b9d487db2b9492359f9f11f1a03e6",
+ "read/hierarchy.xml": "22008bc66eca4e9e81ee71797ecec0b0ab9a9573536c283bdf3068d5c1249d16",
+ "read/page-000.xml": "6085c08ed830334c5dda5767cbca5e9cb7f44228063a5a48d1375b43f7757e9e",
+ "read/page-001.xml": "c47a27712e91ac43cf67150079675753b8d9acbfc989d061409076680b210c3d",
+ "read/page-002.xml": "e0689e5d1870f1ddb9f325306e6e31f73aea714f04627e225b0c416eec618c9e",
+ "read/page-003.xml": "0693cb23f11251903f3a77d597bc6d6fb2e866e3689551054a0eede1fc902b3b",
+ "read/page-004.xml": "5a6a5bcf5002159ee02ae27e207624887ef274f4d66c07c94e9dccca50739ccf",
+ "read/page-005.xml": "8790b6054791eef5336c2e169c272283cce41a6befd500366e9dc3376e0c2ca4",
+ "read/page-006.xml": "b82fe4c8b25950978de1a393b822c9ff5036acbb044f9ffff05177fe468bcbee",
+ "read/page-007.xml": "3836c858fb76f6d203b59546bd254b8f471c35b7e0eda41f5983c788d6e04411",
+ "read/page-008.xml": "dbc4c51290cc10a83c0ea3589d474c602851ab5a00b484e7cfbeea4650b9b8ee",
+ "read/page-009.xml": "c295b21213365683761822088b25c9c497b5c5fa727b1e1a060b54fd71b74057",
+ "read/page-010.xml": "f360d463c2469795d7995a15bcacfb935743ffbbd1e8a8e88493e913b6b32e3f",
+ "read/page-011.xml": "5e870a6968914a9c4a46fe0b1490bc28e4fe194141c230d469287e7174b93f87",
+ "read/page-012.xml": "1d6aacea82748afc294e86c6420e08b61bba5b1950444aaecfaf25450f3883e1",
+ "read/page-013.xml": "5de946ec79fe9bf1c62518fa835cef03b0d0eadfddea58b25c75d90525d40482",
+ "read/payloads.json": "f1d4ed4a75237e4878028e6b6010c6bbef26a0046c58de51825558342883b19f"
+ }
+ }
+}
diff --git a/corpus/paragraph-edit/split/notebook/Open Notebook.onetoc2 b/corpus/paragraph-edit/split/notebook/Open Notebook.onetoc2
new file mode 120000
index 0000000000000000000000000000000000000000..a6c7d197861f52dda5ecaf4da2ab7e471f409518
--- /dev/null
+++ b/corpus/paragraph-edit/split/notebook/Open Notebook.onetoc2
@@ -0,0 +1 @@
+../../before/notebook/Open Notebook.onetoc2
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/notebook/synthetic.one b/corpus/paragraph-edit/split/notebook/synthetic.one
new file mode 120000
index 0000000000000000000000000000000000000000..0def68dab8bd396ec442a62cce7b4dd0598eaaba
--- /dev/null
+++ b/corpus/paragraph-edit/split/notebook/synthetic.one
@@ -0,0 +1 @@
+../../cold-split/notebook/synthetic.one
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/read/environment.json b/corpus/paragraph-edit/split/read/environment.json
new file mode 120000
index 0000000000000000000000000000000000000000..032ba3b41dd4114f7b416f0781d9c5fb61796d7f
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/environment.json
@@ -0,0 +1 @@
+../../before/read/environment.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/read/hierarchy.xml b/corpus/paragraph-edit/split/read/hierarchy.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cd75c5d1dcc1b175bb83dbf9ed561aab117674f4
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/hierarchy.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/corpus/paragraph-edit/split/read/page-000.xml b/corpus/paragraph-edit/split/read/page-000.xml
new file mode 100644
index 0000000000000000000000000000000000000000..59c611837b0acd12d3ba5ba8166a2f76bb6b66a0
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-000.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-001.xml b/corpus/paragraph-edit/split/read/page-001.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8da1ab6975c4845b659eaba27c43a15b8e406814
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-001.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-002.xml b/corpus/paragraph-edit/split/read/page-002.xml
new file mode 100644
index 0000000000000000000000000000000000000000..341ef1007dcc02e6e5b61a15e1e1d08402c47d84
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-002.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-003.xml b/corpus/paragraph-edit/split/read/page-003.xml
new file mode 100644
index 0000000000000000000000000000000000000000..546158c8f42fb295c42c64de22402dc693487bc4
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-003.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-004.xml b/corpus/paragraph-edit/split/read/page-004.xml
new file mode 100644
index 0000000000000000000000000000000000000000..39d5d4764bff04dd33c735ff0d78aa373c8f07e0
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-004.xml
@@ -0,0 +1,3 @@
+
+Link label tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-005.xml b/corpus/paragraph-edit/split/read/page-005.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5c352b855bbc145546937611932006167cf1a905
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-005.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-006.xml b/corpus/paragraph-edit/split/read/page-006.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7250ef9fd9263d735fd183b5632265b14a7178c1
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-006.xml
@@ -0,0 +1,20 @@
+
+Bold 🦀 italic é color 東京
+End]]>Fictitious: café, 東京, مرحبا]]>
diff --git a/corpus/paragraph-edit/split/read/page-007.xml b/corpus/paragraph-edit/split/read/page-007.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9d5bede589a43b893bbc03f8d9fb8aac0ab13d50
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-007.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-008.xml b/corpus/paragraph-edit/split/read/page-008.xml
new file mode 100644
index 0000000000000000000000000000000000000000..84b6f40bb4a6628cb20b0dc92c1de41558653ceb
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-008.xml
@@ -0,0 +1,5 @@
+
+Bold italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-009.xml b/corpus/paragraph-edit/split/read/page-009.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a2776717e075ed88b9498db566935d9b973535a2
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-009.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-010.xml b/corpus/paragraph-edit/split/read/page-010.xml
new file mode 100644
index 0000000000000000000000000000000000000000..039b53c4cf625b7adc551185579dd0470026f5d5
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-010.xml
@@ -0,0 +1,5 @@
+
+Bold]]> italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-011.xml b/corpus/paragraph-edit/split/read/page-011.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4772e3e40af43a7b1f12e59f3efa24f17638c671
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-011.xml
@@ -0,0 +1,3 @@
+
+
+soft break]]>
diff --git a/corpus/paragraph-edit/split/read/page-012.xml b/corpus/paragraph-edit/split/read/page-012.xml
new file mode 100644
index 0000000000000000000000000000000000000000..54dd21835c8d6beee7d5ef6305757c9b05c408f1
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-012.xml
@@ -0,0 +1,6 @@
+
+Bo]]>ld italic 🦀 é tail]]>
diff --git a/corpus/paragraph-edit/split/read/page-013.xml b/corpus/paragraph-edit/split/read/page-013.xml
new file mode 100644
index 0000000000000000000000000000000000000000..26baedbb75927eff5d3cec77b8991835da706121
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/page-013.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/corpus/paragraph-edit/split/read/payloads.json b/corpus/paragraph-edit/split/read/payloads.json
new file mode 120000
index 0000000000000000000000000000000000000000..4a72bfff3e4007f7e1da7b55da52ca9286ab5b86
--- /dev/null
+++ b/corpus/paragraph-edit/split/read/payloads.json
@@ -0,0 +1 @@
+../../before/read/payloads.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/run.json b/corpus/paragraph-edit/split/run.json
new file mode 100644
index 0000000000000000000000000000000000000000..0b075e3d9110c309d1d07c3137b06e37027141ef
--- /dev/null
+++ b/corpus/paragraph-edit/split/run.json
@@ -0,0 +1,19 @@
+{
+ "notebook": "/Users/clo/dev/one/corpus/formatted-insertion/native-paragraph/candidate",
+ "expected_pages": 14,
+ "author": "tools/native/paragraphs.ps1",
+ "author_timeout_seconds": 600,
+ "inspect": true,
+ "collect_notebook": true,
+ "base": {
+ "file": "win7-office-base.qcow2",
+ "format": "qcow2",
+ "sha256": "a1a4f8fab782ee14885ff801ca2f6347c208fdcfc3513637096f314315c89346",
+ "virtual_size": 68719476736
+ },
+ "scripts": {
+ "author.ps1": "ad9833269f61cc031fc897fedae7cf433f4ab7b188dc2fa30ab6e2c657cb212c",
+ "cold.ps1": "c177fc72ae6c2634d186f5671a880de20b09f9716532c37c69cb13aa15c7e331",
+ "read.ps1": "04013bfcccee40a17e2a225f9b9e96f40a3a8daad9e350609654f8eda3ccbb41"
+ }
+}
diff --git a/corpus/paragraph-edit/split/source.json b/corpus/paragraph-edit/split/source.json
new file mode 100644
index 0000000000000000000000000000000000000000..5a6046f72de12f78e8a6c2943e9f8e066db32e98
--- /dev/null
+++ b/corpus/paragraph-edit/split/source.json
@@ -0,0 +1,8 @@
+[
+ {
+ "path": "synthetic.one",
+ "bytes": 18672,
+ "sha256": "202823512283be980b6a139adcf5f4f369d15f17d60ed7b23f9f2289513aa4e9",
+ "mtime_ns": 1788844254904000129
+ }
+]
diff --git a/corpus/paragraph-edit/split/teardown.json b/corpus/paragraph-edit/split/teardown.json
new file mode 120000
index 0000000000000000000000000000000000000000..8b4fa29c76b0c84be8e3815d693a242cc55fbf90
--- /dev/null
+++ b/corpus/paragraph-edit/split/teardown.json
@@ -0,0 +1 @@
+../joined/teardown.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/selections.json b/corpus/paragraph-edit/split/ui/selections.json
new file mode 100644
index 0000000000000000000000000000000000000000..88955ebbed283a12de35b1ac11b0cdec1b2ecd5c
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/selections.json
@@ -0,0 +1,80 @@
+[
+ {
+ "name": "Split middle",
+ "page": "{E2D69849-42AD-4FA3-BBEA-AA04A24E2B85}{1}{B0}",
+ "object": "{C31D8DC5-9C51-42C6-929C-4874E27551A1}{40}{B0}",
+ "keys": "{Left}{Right 2}{Enter}"
+ },
+ {
+ "name": "Split style boundary",
+ "page": "{C220572F-FA0B-4A8F-BEF2-3A236F4322E2}{1}{B0}",
+ "object": "{434059C8-E984-4700-AF16-141A2D60EDE1}{40}{B0}",
+ "keys": "{Left}{Right 4}{Enter}"
+ },
+ {
+ "name": "Split start",
+ "page": "{65ED3419-FFB3-4D45-A1CB-911697FA59C3}{1}{B0}",
+ "object": "{1DDA0461-B409-4A07-86CF-82CBF1871DAA}{40}{B0}",
+ "keys": "{Left}{Enter}"
+ },
+ {
+ "name": "Split end",
+ "page": "{8E8BF523-E086-4EF3-8129-53A645547680}{1}{B0}",
+ "object": "{C603FE89-3519-4A05-9834-076122BDA637}{40}{B0}",
+ "keys": "{Right}{Enter}"
+ },
+ {
+ "name": "Split empty",
+ "page": "{F82C19E6-A731-494F-8051-F6B8DA09FF67}{1}{B0}",
+ "object": "{17B2A21B-253D-4550-BF6B-95FBA12E402C}{40}{B0}",
+ "keys": "{Left}{Enter}"
+ },
+ {
+ "name": "Split parent",
+ "page": "{66C2E066-8478-4723-BFAE-D5F6394BB8FD}{1}{B0}",
+ "object": "{24943739-23FE-4805-8349-FC9665476B82}{40}{B0}",
+ "keys": "{Left}{Right 2}{Enter}"
+ },
+ {
+ "name": "Split child",
+ "page": "{203619F6-92A0-4A54-99E4-045C75B8F269}{1}{B0}",
+ "object": "{A97316EC-FC76-47BE-A069-D2B0A01ED1C2}{45}{B0}",
+ "keys": "{Left}{Right 2}{Enter}"
+ },
+ {
+ "name": "Split bullet",
+ "page": "{88DA28CE-086B-4279-954D-47299A4E761E}{1}{B0}",
+ "object": "{9091390D-B0C6-4F70-AE98-1C10F1AC003E}{40}{B0}",
+ "keys": "{Left}{Right 2}{Enter}"
+ },
+ {
+ "name": "Split number",
+ "page": "{B85A9DD5-2A3A-4D9E-9EC9-24D83A871A32}{1}{B0}",
+ "object": "{C85F6365-D6DF-4CBF-A900-9FE3ED49C6A0}{40}{B0}",
+ "keys": "{Left}{Right 2}{Enter}"
+ },
+ {
+ "name": "Split tag",
+ "page": "{6F696EA1-B583-47E1-90CD-7D524EFA979B}{1}{B0}",
+ "object": "{2B5E855D-DE3A-4FBA-A000-B81E9D3B78F9}{40}{B0}",
+ "keys": "{Left}{Right 2}{Enter}"
+ },
+ {
+ "name": "Split cell",
+ "page": "{58C63EC6-A9E5-4799-9797-DAA2D2A0DA4F}{1}{B0}",
+ "object": "{EC77F6E3-E2C2-470B-BE30-AA34559FFE1B}{46}{B0}",
+ "keys": "{Left}{Right 2}{Enter}"
+ },
+ {
+ "name": "Split soft break",
+ "page": "{C4158B59-53E4-4489-9F85-4467D0F92EBA}{1}{B0}",
+ "object": "{94EC468B-D8A3-4F1F-B372-93B82288F0E0}{40}{B0}",
+ "keys": "{Left}{Right 2}{Enter}"
+ },
+ {
+ "name": "Split before hyperlink",
+ "page": "{6E358CAE-6F33-4AC7-90FA-B5DC5D3C9504}{1}{B0}",
+ "object": "{48C7C4CD-AD7D-47E9-A675-0AE7BA91D125}{40}{B0}",
+ "keys": "{Left}{Right 2}{Enter}"
+ }
+]
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-before-hyperlink.ahk b/corpus/paragraph-edit/split/ui/split-before-hyperlink.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..c3acbae7d7bfcfc764e6c29d9936e95b740f9c23
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-before-hyperlink.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{6E358CAE-6F33-4AC7-90FA-B5DC5D3C9504}{1}{B0}", "{48C7C4CD-AD7D-47E9-A675-0AE7BA91D125}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Right 2}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-before-hyperlink.json b/corpus/paragraph-edit/split/ui/split-before-hyperlink.json
new file mode 120000
index 0000000000000000000000000000000000000000..2a37a81b99436e6c0e1de7a586fe05a523a65538
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-before-hyperlink.json
@@ -0,0 +1 @@
+../../joined/ui/split-before-hyperlink.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-before-hyperlink.png b/corpus/paragraph-edit/split/ui/split-before-hyperlink.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec7c4de0d4e9b8001bba0a82b6650453665e7ed2
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-before-hyperlink.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-bullet.ahk b/corpus/paragraph-edit/split/ui/split-bullet.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..ada9454be06f9c1ba7447b8edbf5dcac8ce30908
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-bullet.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{88DA28CE-086B-4279-954D-47299A4E761E}{1}{B0}", "{9091390D-B0C6-4F70-AE98-1C10F1AC003E}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Right 2}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-bullet.json b/corpus/paragraph-edit/split/ui/split-bullet.json
new file mode 120000
index 0000000000000000000000000000000000000000..5a09435161a6cb8b9036e98077108cf462c8a3db
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-bullet.json
@@ -0,0 +1 @@
+../../joined/ui/split-bullet-second.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-bullet.png b/corpus/paragraph-edit/split/ui/split-bullet.png
new file mode 100644
index 0000000000000000000000000000000000000000..eeacfc608a902fd56d61e3b8f31245c5890cce60
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-bullet.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-cell.ahk b/corpus/paragraph-edit/split/ui/split-cell.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..7f5f71ae1aaf5372117640fba57f0587c11e7673
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-cell.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{58C63EC6-A9E5-4799-9797-DAA2D2A0DA4F}{1}{B0}", "{EC77F6E3-E2C2-470B-BE30-AA34559FFE1B}{46}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Right 2}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-cell.json b/corpus/paragraph-edit/split/ui/split-cell.json
new file mode 120000
index 0000000000000000000000000000000000000000..b2b5e8d725464e26442edf4e0532294c07a601ee
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-cell.json
@@ -0,0 +1 @@
+../../joined/ui/split-cell.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-cell.png b/corpus/paragraph-edit/split/ui/split-cell.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c69398eac8358e0e99d256a3e27cad463040256
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-cell.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-child.ahk b/corpus/paragraph-edit/split/ui/split-child.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..36ee9a09d4a9588568467a8464e78241b2a28b5a
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-child.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{203619F6-92A0-4A54-99E4-045C75B8F269}{1}{B0}", "{A97316EC-FC76-47BE-A069-D2B0A01ED1C2}{45}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Right 2}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-child.json b/corpus/paragraph-edit/split/ui/split-child.json
new file mode 120000
index 0000000000000000000000000000000000000000..e153c49f5461ccefeac2d0c5ac2bb623bfbea116
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-child.json
@@ -0,0 +1 @@
+../../joined/ui/split-child-second.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-child.png b/corpus/paragraph-edit/split/ui/split-child.png
new file mode 100644
index 0000000000000000000000000000000000000000..922a231ba15af32e56e8e9a8f3fc15b34ddf70fc
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-child.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-empty.ahk b/corpus/paragraph-edit/split/ui/split-empty.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..d6290a9568a7cfe3f3a826ac4eb7a1a51e152660
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-empty.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{F82C19E6-A731-494F-8051-F6B8DA09FF67}{1}{B0}", "{17B2A21B-253D-4550-BF6B-95FBA12E402C}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-empty.json b/corpus/paragraph-edit/split/ui/split-empty.json
new file mode 120000
index 0000000000000000000000000000000000000000..93394abe38ea508fbd81f3db649404ed32abdc31
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-empty.json
@@ -0,0 +1 @@
+../../joined/ui/split-empty.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-empty.png b/corpus/paragraph-edit/split/ui/split-empty.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8954197ab3cf8a268b8cec7f1df4d59cee5b23c
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-empty.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-end.ahk b/corpus/paragraph-edit/split/ui/split-end.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..63440449b351134046bad8bcb47ae33a036e2751
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-end.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{8E8BF523-E086-4EF3-8129-53A645547680}{1}{B0}", "{C603FE89-3519-4A05-9834-076122BDA637}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Right}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-end.json b/corpus/paragraph-edit/split/ui/split-end.json
new file mode 120000
index 0000000000000000000000000000000000000000..39b6f769d1a3891ca78c2d5caf722217e262c201
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-end.json
@@ -0,0 +1 @@
+../../joined/ui/split-end.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-end.png b/corpus/paragraph-edit/split/ui/split-end.png
new file mode 100644
index 0000000000000000000000000000000000000000..00f2b566c3a44835d79f182b1dd33091153a53ef
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-end.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-middle.ahk b/corpus/paragraph-edit/split/ui/split-middle.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..5212378691b5d48c80e1e177ef450f367181a0d2
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-middle.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{E2D69849-42AD-4FA3-BBEA-AA04A24E2B85}{1}{B0}", "{C31D8DC5-9C51-42C6-929C-4874E27551A1}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Right 2}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-middle.json b/corpus/paragraph-edit/split/ui/split-middle.json
new file mode 120000
index 0000000000000000000000000000000000000000..3a3492158778b8eed082297b2d8d67d949b3e876
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-middle.json
@@ -0,0 +1 @@
+../../joined/ui/split-middle.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-middle.png b/corpus/paragraph-edit/split/ui/split-middle.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ea6aa5ba6eeb424e46f1cc66734e42b8aa52b50
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-middle.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-number.ahk b/corpus/paragraph-edit/split/ui/split-number.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..07bb1d062b5c1f9b0711aa090c97c4ea1ffe8bdc
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-number.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{B85A9DD5-2A3A-4D9E-9EC9-24D83A871A32}{1}{B0}", "{C85F6365-D6DF-4CBF-A900-9FE3ED49C6A0}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Right 2}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-number.json b/corpus/paragraph-edit/split/ui/split-number.json
new file mode 120000
index 0000000000000000000000000000000000000000..21070c724ce3c279d8ec10c9777c6e14de2d6a02
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-number.json
@@ -0,0 +1 @@
+../../joined/ui/split-number-second.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-number.png b/corpus/paragraph-edit/split/ui/split-number.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd0c1cfd301ba571bfea868faccf7582ba9fb328
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-number.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-parent.ahk b/corpus/paragraph-edit/split/ui/split-parent.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..8cf3b5389331a835f96f64517c3e8ae7b98d95de
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-parent.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{66C2E066-8478-4723-BFAE-D5F6394BB8FD}{1}{B0}", "{24943739-23FE-4805-8349-FC9665476B82}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Right 2}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-parent.json b/corpus/paragraph-edit/split/ui/split-parent.json
new file mode 120000
index 0000000000000000000000000000000000000000..f37a04976ca9192a997ce3d31a6ab146c55db6ef
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-parent.json
@@ -0,0 +1 @@
+../../joined/ui/split-parent.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-parent.png b/corpus/paragraph-edit/split/ui/split-parent.png
new file mode 100644
index 0000000000000000000000000000000000000000..70444a1c074642b9cdd2f88758e77ba83402144b
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-parent.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-soft-break.ahk b/corpus/paragraph-edit/split/ui/split-soft-break.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..4877080c6eea362d3927d48b0c0c6cd67d084b6e
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-soft-break.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{C4158B59-53E4-4489-9F85-4467D0F92EBA}{1}{B0}", "{94EC468B-D8A3-4F1F-B372-93B82288F0E0}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Right 2}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-soft-break.json b/corpus/paragraph-edit/split/ui/split-soft-break.json
new file mode 120000
index 0000000000000000000000000000000000000000..3fe8b24611e7219c8980d43c26bc14a3189321db
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-soft-break.json
@@ -0,0 +1 @@
+../../joined/ui/split-soft-break.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-soft-break.png b/corpus/paragraph-edit/split/ui/split-soft-break.png
new file mode 100644
index 0000000000000000000000000000000000000000..7c021075ba4e3b1c909ba6bec470d69b7c177683
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-soft-break.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-start.ahk b/corpus/paragraph-edit/split/ui/split-start.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..011a6a13bdf795e4a1d3c850b6c8fd781887cc6b
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-start.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{65ED3419-FFB3-4D45-A1CB-911697FA59C3}{1}{B0}", "{1DDA0461-B409-4A07-86CF-82CBF1871DAA}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-start.json b/corpus/paragraph-edit/split/ui/split-start.json
new file mode 120000
index 0000000000000000000000000000000000000000..a4f63d32d90e6d48d2fb3bd9e782f7e4b764429f
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-start.json
@@ -0,0 +1 @@
+../../joined/ui/split-start.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-start.png b/corpus/paragraph-edit/split/ui/split-start.png
new file mode 100644
index 0000000000000000000000000000000000000000..24893a3681d8a80549b08d47e85b93eaa8403581
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-start.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-style-boundary.ahk b/corpus/paragraph-edit/split/ui/split-style-boundary.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..b328d7d4d10609b246cac475cf779e7f8fd51afa
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-style-boundary.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{C220572F-FA0B-4A8F-BEF2-3A236F4322E2}{1}{B0}", "{434059C8-E984-4700-AF16-141A2D60EDE1}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Right 4}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-style-boundary.json b/corpus/paragraph-edit/split/ui/split-style-boundary.json
new file mode 120000
index 0000000000000000000000000000000000000000..c85882b409994ca7a72513fb70b39f66e21bf13d
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-style-boundary.json
@@ -0,0 +1 @@
+../../joined/ui/split-style-boundary.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-style-boundary.png b/corpus/paragraph-edit/split/ui/split-style-boundary.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ee34c89ae80d7e33160af1f2415019258c32de3
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-style-boundary.png differ
diff --git a/corpus/paragraph-edit/split/ui/split-tag.ahk b/corpus/paragraph-edit/split/ui/split-tag.ahk
new file mode 100644
index 0000000000000000000000000000000000000000..825b9407d0062011097f73ab864193ced3d0fec5
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-tag.ahk
@@ -0,0 +1,22 @@
+#Requires AutoHotkey v2.0
+OnError((exception, mode) => (FileAppend(exception.Message, "**"), ExitApp(1)))
+dm := Buffer(220, 0)
+NumPut("UShort", 220, dm, 68)
+if !DllCall("EnumDisplaySettingsW", "Ptr", 0, "UInt", 0xFFFFFFFF, "Ptr", dm)
+ throw Error("Cannot inspect display mode")
+NumPut("UInt", NumGet(dm, 72, "UInt") | 0x180000, dm, 72)
+NumPut("UInt", 1280, dm, 172)
+NumPut("UInt", 720, dm, 176)
+if DllCall("ChangeDisplaySettingsW", "Ptr", dm, "UInt", 0, "Int") != 0
+ throw Error("Display mode rejected")
+app := ComObject("OneNote.Application")
+app.NavigateTo("{6F696EA1-B583-47E1-90CD-7D524EFA979B}{1}{B0}", "{2B5E855D-DE3A-4FBA-A000-B81E9D3B78F9}{40}{B0}", false)
+hwnd := WinWait("ahk_class Framework::CFrame ahk_exe ONENOTE.EXE",, 10)
+if !hwnd
+ throw Error("OneNote window did not appear")
+WinMaximize(hwnd)
+WinActivate(hwnd)
+if !WinWaitActive(hwnd,, 10)
+ throw Error("OneNote window did not become active")
+Sleep 300
+Send "{Left}{Right 2}{Enter}"
diff --git a/corpus/paragraph-edit/split/ui/split-tag.json b/corpus/paragraph-edit/split/ui/split-tag.json
new file mode 120000
index 0000000000000000000000000000000000000000..0b68c60f3c88d4e54391ac1b5978807aaef0598b
--- /dev/null
+++ b/corpus/paragraph-edit/split/ui/split-tag.json
@@ -0,0 +1 @@
+../../joined/ui/split-tag.json
\ No newline at end of file
diff --git a/corpus/paragraph-edit/split/ui/split-tag.png b/corpus/paragraph-edit/split/ui/split-tag.png
new file mode 100644
index 0000000000000000000000000000000000000000..8d78ef23c17e3b4e0fa3755eb4abfddcaf9a41d7
Binary files /dev/null and b/corpus/paragraph-edit/split/ui/split-tag.png differ
diff --git a/tools/native/paragraphs.ps1 b/tools/native/paragraphs.ps1
new file mode 100644
index 0000000000000000000000000000000000000000..89dc9cc6d648d8bc6ec4c7e4003a2c1acfec6877
--- /dev/null
+++ b/tools/native/paragraphs.ps1
@@ -0,0 +1,47 @@
+param([Parameter(Mandatory=$true)][string]$Root, [Parameter(Mandatory=$true)][string]$CloneHost)
+Set-StrictMode -Version Latest
+$ErrorActionPreference = 'Stop'
+& "$PSScriptRoot\cold-current.ps1" -Root $Root -CloneHost $CloneHost
+$app = New-Object -ComObject OneNote.Application
+$notebook = ''
+try {
+ $app.OpenHierarchy((Join-Path $Root 'notebook'), '', [ref]$notebook, 0)
+ $section = ''
+ $app.OpenHierarchy('synthetic.one', $notebook, [ref]$section, 0)
+ $mixed = 'Bold italic ' + [char]::ConvertFromUtf32(0x1F980) + ' e' + [char]0x0301 + ' tail'
+ $text = ''
+ $child = 'Preserved child'
+ $cases = @(
+ @{ name = 'Split middle'; keys = '{Left}{Right 2}{Enter}'; body = '' + $text + '' },
+ @{ name = 'Split style boundary'; keys = '{Left}{Right 4}{Enter}'; body = '' + $text + '' },
+ @{ name = 'Split start'; keys = '{Left}{Enter}'; body = '' + $text + '' },
+ @{ name = 'Split end'; keys = '{Right}{Enter}'; body = '' + $text + '' },
+ @{ name = 'Split empty'; keys = '{Left}{Enter}'; body = '' },
+ @{ name = 'Split parent'; keys = '{Left}{Right 2}{Enter}'; body = '' + $text + $child + '' },
+ @{ name = 'Split child'; keys = '{Left}{Right 2}{Enter}'; nested = $true; body = 'Preserved parent' + $text + '' },
+ @{ name = 'Split bullet'; keys = '{Left}{Right 2}{Enter}'; body = '' + $text + $child + '' },
+ @{ name = 'Split number'; keys = '{Left}{Right 2}{Enter}'; body = '' + $text + '' },
+ @{ name = 'Split tag'; keys = '{Left}{Right 2}{Enter}'; body = '' + $text + '' },
+ @{ name = 'Split cell'; keys = '{Left}{Right 2}{Enter}'; body = '' + $text + 'Preserved cell' },
+ @{ name = 'Split soft break'; keys = '{Left}{Right 2}{Enter}'; body = '' + "`n" + 'soft break]]>' },
+ @{ name = 'Split before hyperlink'; keys = '{Left}{Right 2}{Enter}'; body = 'Link label tail]]>' }
+ )
+ $inputs = Join-Path $Root 'inputs'
+ New-Item -ItemType Directory -Path $inputs | Out-Null
+ foreach ($case in $cases) {
+ $page = ''
+ $app.CreateNewPage($section, [ref]$page, 0)
+ $xml = '' + $case.name + '' + $case.body + 'Preserved sibling'
+ [IO.File]::WriteAllText((Join-Path $inputs ($case.name + '.xml')), $xml, [Text.Encoding]::UTF8)
+ $app.UpdatePageContent($xml, [DateTime]::MinValue, 1, $true)
+ $case.page = $page
+ }
+ $cases | ConvertTo-Json -Depth 6 | Set-Content (Join-Path $Root 'cases.json') -Encoding UTF8
+ $app.SyncHierarchy($notebook)
+} finally {
+ if ($notebook) { $app.CloseNotebook($notebook, $false) }
+ [void][Runtime.InteropServices.Marshal]::FinalReleaseComObject($app)
+ $app = $null
+ [GC]::Collect()
+ [GC]::WaitForPendingFinalizers()
+}
diff --git a/tools/test_paragraph_edit.py b/tools/test_paragraph_edit.py
new file mode 100644
index 0000000000000000000000000000000000000000..04e36e9ca80be005699aa8ec842c10225bf4f286
--- /dev/null
+++ b/tools/test_paragraph_edit.py
@@ -0,0 +1,86 @@
+import json
+from pathlib import Path
+import runpy
+import shutil
+import subprocess
+from tempfile import TemporaryDirectory
+import unittest
+import xml.etree.ElementTree as ET
+
+from document_model import EXPORTER, ordered_pages, walk
+from native_format import native_characters
+from native_xml import ns
+
+ROOT = Path(__file__).resolve().parent.parent
+FIXTURE = ROOT / 'corpus/paragraph-edit'
+compare = runpy.run_path(str(ROOT / 'tools/verify-document.py'))['compare']
+
+
+class ParagraphEditTest(unittest.TestCase):
+ def test_native_split_join_graphs_styles_and_identity_boundaries(self):
+ manifest = json.loads((FIXTURE / 'manifest.json').read_text())
+ models, native = {}, {}
+ with TemporaryDirectory() as temporary:
+ for phase in manifest['phases']:
+ folder = Path(temporary) / phase
+ read = folder / 'read'
+ shutil.copytree(FIXTURE / phase / 'read', read)
+ compare(FIXTURE / phase / 'notebook', read)
+ subprocess.run([EXPORTER, FIXTURE / phase / 'notebook/synthetic.one', folder / 'model'], check=True)
+ model = json.loads((folder / 'model/document.json').read_text())
+ models[phase] = {r['nodes'][r['roots']['2']]['kind'].get('title'): (r, page)
+ for _, _, r, page in ordered_pages(model)}
+ self.assertEqual(len(models[phase]), 14)
+ native[phase] = {}
+ for file in read.glob('page-*.xml'):
+ page = ET.parse(file).getroot()
+ native[phase][page.get('name')] = native_characters(page, page.findall('one:Outline', ns))
+ self.assertEqual(len(manifest['cases']), 13)
+ for case in manifest['cases']:
+ name = case['case']
+ with self.subTest(case=name):
+ old, page = models['before'][name]
+ text, paragraph, suffix, suffix_text = (case[key] for key in
+ ('original_text', 'original_paragraph', 'new_paragraph', 'new_text'))
+ parent, = [oid for oid, node in old['nodes'].items() if paragraph in node['children']]
+ position = old['nodes'][parent]['children'].index(paragraph)
+ expected_children = old['nodes'][parent]['children'].copy()
+ expected_children.insert(position + 1, suffix)
+ encoded = old['nodes'][text]['kind']['text'].encode('utf-16-le')
+ at = case['offset_utf16'] * 2
+ for phase in ('split', 'cold-split'):
+ current, _ = models[phase][name]
+ self.assertEqual(current['nodes'][parent]['children'], expected_children)
+ self.assertEqual(current['nodes'][paragraph]['content'], [text])
+ self.assertEqual(current['nodes'][paragraph]['children'], [])
+ self.assertEqual(current['nodes'][suffix]['content'], [suffix_text])
+ self.assertEqual(current['nodes'][suffix]['children'], old['nodes'][paragraph]['children'])
+ self.assertEqual(current['nodes'][text]['kind']['text'], encoded[:at].decode('utf-16-le'))
+ self.assertEqual(current['nodes'][suffix_text]['kind']['text'], encoded[at:].decode('utf-16-le'))
+ self.assertEqual(current['nodes'][text]['tags'], old['nodes'][text]['tags'])
+ self.assertEqual(current['nodes'][suffix_text]['tags'], [])
+ joined, joined_page = models['joined'][name]
+ adopted = name in ('Split start', 'Split empty')
+ self.assertEqual(joined['nodes'][page]['children'], old['nodes'][page]['children'])
+ self.assertEqual(page, joined_page)
+ for outline in old['nodes'][page]['children']:
+ if old['nodes'][outline]['kind']['type'] != 'Outline': continue
+ for oid, node in walk(old, outline):
+ if adopted and oid == text: continue
+ self.assertEqual(joined['nodes'][oid]['children'], node['children'])
+ content = [suffix_text] if adopted and oid == paragraph else node['content']
+ self.assertEqual(joined['nodes'][oid]['content'], content)
+ if node['kind']['type'] == 'RichText':
+ self.assertEqual(joined['nodes'][oid]['kind']['text'], node['kind']['text'])
+ self.assertEqual(joined['nodes'][oid]['tags'], node['tags'])
+ self.assertEqual(joined['nodes'][suffix_text if adopted else text]['kind']['text'], encoded.decode('utf-16-le'))
+ for left, right in zip(native['before'][name], native['joined'][name], strict=True):
+ for (a, old_style), (b, new_style) in zip(left, right, strict=True):
+ self.assertEqual(a, b)
+ for key in old_style.keys() | new_style.keys():
+ default = 'automatic' if key in ('color', 'highlight') else False
+ self.assertEqual(old_style.get(key, default), new_style.get(key, default))
+
+
+if __name__ == '__main__':
+ unittest.main()