@aiquants/spreadsheet 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +1103 -0
  2. package/LICENSE.md +155 -0
  3. package/README.md +817 -0
  4. package/dist/index.cjs +21 -0
  5. package/dist/index.d.cts +1960 -0
  6. package/dist/index.d.ts +1960 -0
  7. package/dist/index.js +7711 -0
  8. package/dist/styles/spreadsheet.css +2 -0
  9. package/dist/styles/spreadsheet.standalone.css +3 -0
  10. package/package.json +94 -0
  11. package/src/Spreadsheet.tsx +2313 -0
  12. package/src/clipboard/clipPayload.ts +1242 -0
  13. package/src/clipboard/fixtures/excel.fixture.ts +301 -0
  14. package/src/clipboard/fixtures/html.fixture.ts +90 -0
  15. package/src/clipboard/fixtures/sheets.fixture.ts +83 -0
  16. package/src/clipboard/htmlInterop.ts +1694 -0
  17. package/src/clipboard/numberFormatCodec.ts +870 -0
  18. package/src/clipboard/pasteSpecial.ts +608 -0
  19. package/src/clipboard/tiling.ts +370 -0
  20. package/src/clipboard/tsv.ts +186 -0
  21. package/src/clipboard/useClipboard.ts +1154 -0
  22. package/src/commands/selfCalc.ts +279 -0
  23. package/src/commands/useCommands.ts +946 -0
  24. package/src/editor/useCellEditor.ts +708 -0
  25. package/src/grid/CellView.tsx +51 -0
  26. package/src/grid/GridBody.tsx +489 -0
  27. package/src/header/ColumnHeader.tsx +167 -0
  28. package/src/header/RowHeader.tsx +144 -0
  29. package/src/header/columnName.ts +31 -0
  30. package/src/header/resizeGates.ts +146 -0
  31. package/src/header/resizeStrips.ts +79 -0
  32. package/src/header/useHeaderResize.ts +598 -0
  33. package/src/header/useHeaderSelection.ts +454 -0
  34. package/src/index.ts +122 -0
  35. package/src/keyboard/compositionGuard.ts +53 -0
  36. package/src/keyboard/ensureCellVisible.ts +77 -0
  37. package/src/keyboard/shortcuts.ts +718 -0
  38. package/src/keyboard/useGridKeyboard.ts +940 -0
  39. package/src/model/axisModel.ts +186 -0
  40. package/src/model/cellAnnotations.ts +92 -0
  41. package/src/model/cellCoord.ts +114 -0
  42. package/src/model/cellFormat.ts +562 -0
  43. package/src/model/cellPaint.ts +537 -0
  44. package/src/model/conditionalFormat.ts +805 -0
  45. package/src/model/dataAdapter.ts +478 -0
  46. package/src/model/dataValidation.ts +542 -0
  47. package/src/model/formulaRefs.ts +984 -0
  48. package/src/model/frozenPartition.ts +100 -0
  49. package/src/model/labels.ts +228 -0
  50. package/src/model/viewStore.ts +124 -0
  51. package/src/overlay/SelectionOverlay.tsx +1425 -0
  52. package/src/overlay/useFillHandle.ts +432 -0
  53. package/src/popover/CommentPopover.tsx +109 -0
  54. package/src/popover/LinkPopover.tsx +108 -0
  55. package/src/popover/ListPopover.tsx +161 -0
  56. package/src/popover/MessagePopover.tsx +36 -0
  57. package/src/popover/NotePopover.tsx +106 -0
  58. package/src/popover/NoteTip.tsx +26 -0
  59. package/src/popover/PopoverLayer.tsx +210 -0
  60. package/src/popover/placement.ts +138 -0
  61. package/src/popover/usePopovers.ts +642 -0
  62. package/src/selection/selectionState.ts +239 -0
  63. package/src/selection/useAutoScroller.ts +226 -0
  64. package/src/selection/usePointDrag.ts +273 -0
  65. package/src/selection/useSelectionEngine.ts +687 -0
  66. package/src/styles/components.entry.css +10 -0
  67. package/src/styles/spreadsheet.css +1029 -0
  68. package/src/styles/standalone.entry.css +9 -0
@@ -0,0 +1,301 @@
1
+ /**
2
+ * @fileoverview Microsoft Excel clipboard `text/html` fixtures for htmlInterop.spec.ts (v0.8 §5.1 /
3
+ * §5.3). Real Excel captures are queued for a human (§5.3); every export here is a HAND-WRITTEN
4
+ * reconstruction that follows the research map's verified skeleton (Excel 15 desktop: `<style>`
5
+ * block outside the fragment, `.xl##` classes, `mso-number-format` escaping with `\0022`,
6
+ * `mso-ignore:colspan`, `mso-spacerun`, `<col width span>`, `<tr height style='height:Npt'>`;
7
+ * Excel 2002: `x:num` / `x:str` / `x:bool` / `x:err` / `x:fmla`; Excel for the web: the
8
+ * `ccp_infra` wrapper and Chrome's double fragment). Indentation uses spaces (the workspace bans
9
+ * tab characters) and line ends are LF; the CRLF form is derived in the spec. `String.raw` keeps
10
+ * every CSS backslash verbatim. Test-only: no package source imports this directory.
11
+ *
12
+ * Microsoft Excel のクリップボード `text/html` フィクスチャ (htmlInterop.spec.ts 用、v0.8 §5.1 /
13
+ * §5.3)。実 Excel キャプチャは人手キュー (§5.3) のため、全 export は研究マップの検証済み骨格
14
+ * (Excel 15 デスクトップ / Excel 2002 の `x:*` / Excel for the web) に従う手書き再構成。字下げは
15
+ * 空白 (タブ禁止)、行末は LF (CRLF 形は spec 側で派生)。`String.raw` で CSS の逆斜線を保つ。
16
+ */
17
+
18
+ /**
19
+ * Excel 15 (Microsoft 365 desktop) skeleton, composed per research map §2 / §10 (verified
20
+ * fragments from public dumps: Qiita 2019, Froala #2028, CKEditor 4 `Table_excel/office365`).
21
+ * 4 rows × 5 columns: header row with `.xl65` (white bold centred, all-round thin borders, fill +
22
+ * `mso-pattern`), a `colspan=2` spill flagged `mso-ignore:colspan`, an `&nbsp;` empty cell; a
23
+ * user-sized row (`36.5pt` → 49 px) with a `rowspan=2` anchor, the shared-border form
24
+ * (`border-top:none;border-left:none` inline), `mso-number-format` classes `"\#\,\#\#0"`,
25
+ * `"0\.0%"` + italic, the accounting pattern with `\0022` and `\;` inside the CSS string plus an
26
+ * `mso-spacerun` span; a row with `"Short Date"`, a hyperlink class, a `<br>` + CRLF-style
27
+ * indentation cell with wrap / top / Times New Roman 9pt / line-through / `1.0pt dashed red`,
28
+ * a `"\@"` text cell with a `hairline` border; and a HIDDEN row (`display:none`) with an escaped
29
+ * date pattern `"yyyy\\-mm\\-dd"`, a whole-cell `<font class=font6>` run, a partial run, a
30
+ * `<ruby><rt>` phonetic guide and an unknown class. Reconstruction 2026-09-05, licence n/a.
31
+ * Excel 15 (Microsoft 365 デスクトップ) の骨格 (研究マップ §2 / §10 の検証済み断片に基づく再構成)。
32
+ * 4 行 × 5 列: `.xl65` 見出し (白太字中央・全周 thin・塗り + mso-pattern)、`mso-ignore:colspan`
33
+ * の溢れ、`&nbsp;` 空セル、ユーザー行高 (36.5pt → 49px) の `rowspan=2`、共有罫線形、数値書式
34
+ * クラス 3 種 (`\0022` / `\;` 入り会計形 + spacerun)、Short Date、リンク、`<br>` + 字下げ、
35
+ * `"\@"` + hairline、非表示行 (エスケープ日付・全体 `<font>` run・部分 run・ruby・未知クラス)。
36
+ */
37
+ export const EXCEL_DESKTOP_15 = String.raw`<html xmlns:v="urn:schemas-microsoft-com:vml"
38
+ xmlns:o="urn:schemas-microsoft-com:office:office"
39
+ xmlns:x="urn:schemas-microsoft-com:office:excel"
40
+ xmlns="http://www.w3.org/TR/REC-html40">
41
+
42
+ <head>
43
+ <meta http-equiv=Content-Type content="text/html; charset=utf-8">
44
+ <meta name=ProgId content=Excel.Sheet>
45
+ <meta name=Generator content="Microsoft Excel 15">
46
+ <link id=Main-File rel=Main-File
47
+ href="file:///C:/Users/XXXXX/AppData/Local/Temp/msohtmlclip1/01/clip.htm">
48
+ <link rel=File-List
49
+ href="file:///C:/Users/XXXXX/AppData/Local/Temp/msohtmlclip1/01/clip_filelist.xml">
50
+ <style>
51
+ <!--table
52
+ {mso-displayed-decimal-separator:"\.";
53
+ mso-displayed-thousand-separator:"\,";}
54
+ @page
55
+ {margin:.75in .7in .75in .7in;
56
+ mso-header-margin:.3in;
57
+ mso-footer-margin:.3in;}
58
+ tr
59
+ {mso-height-source:auto;}
60
+ col
61
+ {mso-width-source:auto;}
62
+ br
63
+ {mso-data-placement:same-cell;}
64
+ td
65
+ {padding-top:1px;
66
+ padding-right:1px;
67
+ padding-left:1px;
68
+ mso-ignore:padding;
69
+ color:black;
70
+ font-size:11.0pt;
71
+ font-weight:400;
72
+ font-style:normal;
73
+ text-decoration:none;
74
+ font-family:Calibri, sans-serif;
75
+ mso-font-charset:0;
76
+ mso-number-format:General;
77
+ text-align:general;
78
+ vertical-align:bottom;
79
+ border:none;
80
+ mso-background-source:auto;
81
+ mso-pattern:auto;
82
+ mso-protection:locked visible;
83
+ white-space:nowrap;
84
+ mso-rotate:0;}
85
+ .xl65
86
+ {color:white;
87
+ font-weight:700;
88
+ text-align:center;
89
+ border:.5pt solid windowtext;
90
+ background:#C6E0B4;
91
+ mso-pattern:black none;}
92
+ .xl66
93
+ {border:.5pt solid windowtext;}
94
+ .xl67
95
+ {text-align:right;
96
+ border-top:none;
97
+ border-right:.5pt solid windowtext;
98
+ border-bottom:1.5pt solid windowtext;
99
+ border-left:none;}
100
+ .xl68
101
+ {mso-number-format:"\#\,\#\#0";}
102
+ .xl69
103
+ {mso-number-format:"0\.0%";
104
+ font-style:italic;}
105
+ .xl70
106
+ {mso-number-format:"_-* \#\,\#\#0_-\;\\-* \#\,\#\#0_-\;_-* \0022-\0022??_-\;_-\@_-";}
107
+ .xl71
108
+ {mso-number-format:"Short Date";
109
+ text-align:right;}
110
+ .xl72
111
+ {color:#0563C1;
112
+ text-decoration:underline;
113
+ text-underline-style:single;}
114
+ .xl73
115
+ {white-space:normal;
116
+ vertical-align:top;
117
+ font-family:"Times New Roman", serif;
118
+ font-size:9.0pt;
119
+ text-decoration:line-through;
120
+ border:1.0pt dashed red;}
121
+ .xl74
122
+ {mso-number-format:"\@";
123
+ border-bottom:.5pt hairline windowtext;}
124
+ .xl75
125
+ {mso-number-format:"yyyy\\-mm\\-dd";
126
+ text-align:center;}
127
+ .font6
128
+ {color:red;
129
+ font-size:9.0pt;
130
+ font-weight:700;}
131
+ -->
132
+ </style>
133
+ </head>
134
+
135
+ <body link="#0563C1" vlink="#954F72">
136
+
137
+ <table border=0 cellpadding=0 cellspacing=0 width=320 style='border-collapse:
138
+ collapse;width:240pt'>
139
+ <!--StartFragment-->
140
+ <col width=64 span=2 style='width:48pt'>
141
+ <col width=93 style='mso-width-source:userset;mso-width-alt:3234;width:70pt'>
142
+ <col width=64 style='width:48pt' span=2>
143
+ <tr height=20 style='height:15.0pt'>
144
+ <td height=20 class=xl65 width=64 style='height:15.0pt;width:48pt'>Qty</td>
145
+ <td class=xl65 width=64 style='width:48pt'>Double</td>
146
+ <td colspan=2 class=xl65 style='mso-ignore:colspan'>Spill</td>
147
+ <td class=xl65 width=64 style='width:48pt'>&nbsp;</td>
148
+ </tr>
149
+ <tr height=49 style='mso-height-source:userset;height:36.5pt'>
150
+ <td rowspan=2 height=98 class=xl66 width=64 align=right style='height:73.0pt;width:48pt'>4000</td>
151
+ <td class=xl67 style='border-top:none;border-left:none'>8000</td>
152
+ <td class=xl68 align=right>2,728,548</td>
153
+ <td class=xl69 align=right>20.5%</td>
154
+ <td class=xl70><span style='mso-spacerun:yes'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>2,728,548 </td>
155
+ </tr>
156
+ <tr height=20 style='height:15.0pt'>
157
+ <td height=20 class=xl71 style='height:15.0pt'>2026/09/04</td>
158
+ <td class=xl72><a href="https://example.com/">link</a></td>
159
+ <td class=xl73>first<br>
160
+ second</td>
161
+ <td class=xl74>0123</td>
162
+ </tr>
163
+ <tr height=20 style='display:none;height:15.0pt'>
164
+ <td height=20 class=xl75 style='height:15.0pt'>2026-09-04</td>
165
+ <td><font class="font6">Alarm</font></td>
166
+ <td><font class="font6">Al</font>arm</td>
167
+ <td><ruby>漢<rt>かん</rt></ruby>字</td>
168
+ <td class=xl62></td>
169
+ </tr>
170
+ <!--EndFragment-->
171
+ </table>
172
+
173
+ </body>
174
+
175
+ </html>`
176
+
177
+ /**
178
+ * Excel 2002-era typed attributes (research map §5, [doc] Office HTML reference — modern Excel no
179
+ * longer WRITES them but still READS them): `x:num` bare and valued (17-digit E notation), `x:str`
180
+ * on a numeric-looking string, `x:bool`, `x:err` + `x:fmla`, `x:num` + `x:fmla`, a date serial
181
+ * under `"Short Date"` (inline `mso-number-format`), a non-numeric `x:num` and an `x:fmla` that
182
+ * does not start with `=` (both must be ignored). The `<table x:str>` global default is present.
183
+ * Reconstruction 2026-09-05, licence n/a.
184
+ * Excel 2002 世代の型付き属性 (研究マップ §5、Office HTML リファレンス [doc] — 現行 Excel は書かないが
185
+ * 読む): 裸 / 値付き `x:num` (17 桁 E 表記)、数値風文字列の `x:str`、`x:bool`、`x:err` + `x:fmla`、
186
+ * `x:num` + `x:fmla`、Short Date 下の日付シリアル、非数値 `x:num` と `=` 無し `x:fmla` (無視対象)。
187
+ */
188
+ export const EXCEL_2002_TYPED = String.raw`<html xmlns:x="urn:schemas-microsoft-com:office:excel">
189
+ <head>
190
+ <meta name=Generator content="Microsoft Excel 10">
191
+ <style>
192
+ <!--table
193
+ {mso-displayed-decimal-separator:"\.";
194
+ mso-displayed-thousand-separator:"\,";}
195
+ .xl24
196
+ {mso-number-format:"0\.00";}
197
+ -->
198
+ </style>
199
+ </head>
200
+ <body>
201
+ <table x:str border=0 cellpadding=0 cellspacing=0>
202
+ <tr>
203
+ <td align=right x:num>12345</td>
204
+ <td align=right x:num="12344.6789" class=xl24>12,344.68</td>
205
+ <td align=right x:num="4.6000000000000001E-4">0.00046</td>
206
+ <td align=right x:str>12345</td>
207
+ <td align=center x:bool="TRUE">TRUE</td>
208
+ </tr>
209
+ <tr>
210
+ <td align=center x:err="#DIV/0!" x:fmla="=AVERAGE(D3:D10)">#DIV/0!</td>
211
+ <td align=right x:num x:fmla="=SUM(B2:B5)">10</td>
212
+ <td align=right x:num="46269" style='mso-number-format:"Short Date"'>2026/09/04</td>
213
+ <td x:num="abc">text</td>
214
+ <td x:fmla="SUM(1)">1</td>
215
+ </tr>
216
+ </table>
217
+ </body>
218
+ </html>`
219
+
220
+ /**
221
+ * Excel for the web (research map §8, [verified] Bugzilla 1641019 / roosterjs / CKEditor 5 forms):
222
+ * Chrome's own `<html><body><!--StartFragment-->` wrapper around Office's `<div ccp_infra_…>`
223
+ * wrapper around a second `<html>` document with the LEAN td block (no `mso-number-format:General`,
224
+ * no `mso-pattern:auto`), `<table width=209 style='…'>` without border attributes, `<col width=64
225
+ * style='width:48pt' span=2>`, `<td width=64 height=20 style='width:48pt;height:15.0pt'>`, the
226
+ * `background:white;mso-pattern:black none` fill, `.5pt solid windowtext` borders and a hyperlink
227
+ * class with `white-space:normal`. Reconstruction 2026-09-05, licence n/a.
228
+ * Excel for the web (研究マップ §8): Chrome の二重フラグメント + Office の `ccp_infra` div + 内側の
229
+ * 第 2 `<html>` 文書 (lean td ブロック)、属性なし `<table>`、`<col span>`、td の幅 / 高さ、白塗り +
230
+ * mso-pattern、`.5pt solid windowtext`、`white-space:normal` 付きリンククラス。
231
+ */
232
+ export const EXCEL_WEB_15 = String.raw`<html>
233
+ <body>
234
+ <!--StartFragment--><div ccp_infra_version='3' ccp_infra_timestamp='1693000000000' ccp_infra_user_hash='1234567890' ccp_infra_copy_id='00000000-0000-0000-0000-000000000000' data-ccp-timestamp='1693000000000'><html><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=ProgId content=Excel.Sheet><meta name=Generator content="Microsoft Excel 15"><style>
235
+ <!--table
236
+ {mso-displayed-decimal-separator:"\.";
237
+ mso-displayed-thousand-separator:"\,";}
238
+ tr
239
+ {mso-height-source:auto;}
240
+ col
241
+ {mso-width-source:auto;}
242
+ td
243
+ {padding-top:1px;
244
+ padding-right:1px;
245
+ padding-left:1px;
246
+ mso-ignore:padding;
247
+ color:black;
248
+ font-size:11.0pt;
249
+ font-weight:400;
250
+ font-style:normal;
251
+ text-decoration:none;
252
+ font-family:Calibri, sans-serif;
253
+ mso-font-charset:0;
254
+ text-align:general;
255
+ vertical-align:bottom;
256
+ border:none;
257
+ white-space:nowrap;
258
+ mso-rotate:0;}
259
+ .xl33
260
+ {background:white;
261
+ mso-pattern:black none;
262
+ border:.5pt solid windowtext;}
263
+ .xl34
264
+ {color:#0563C1;
265
+ text-decoration:underline;
266
+ text-underline-style:single;
267
+ white-space:normal;}
268
+ -->
269
+ </style></head><body link="#0563C1" vlink="#954F72"><table width=209 style='border-collapse:collapse;width:157pt'><!--StartFragment--><col width=64 style='width:48pt' span=2><col width=81 style='width:61pt'><tr height=20 style='height:15.0pt'><td width=64 height=20 style='width:48pt;height:15.0pt'>Plain</td><td class=xl33 width=64 style='width:48pt'>1</td><td class=xl34 width=81 style='width:61pt'><a href="https://example.com/web">web</a></td></tr><!--EndFragment--></table></body></html></div><!--EndFragment-->
270
+ </body>
271
+ </html>`
272
+
273
+ /**
274
+ * A European-locale Excel 15 copy (research map §2: "a European dump had `\,` and `\.` swapped"):
275
+ * the table rule declares the DECIMAL separator `,` and the THOUSAND separator `.`, so the
276
+ * displayed `2.728.548,5` under `mso-number-format:"\#\,\#\#0\.0"` (patterns stay locale-neutral)
277
+ * recovers as `2728548.5`, and a `General` cell keeps its text. Reconstruction 2026-09-05.
278
+ * 欧州ロケールの Excel 15 コピー (研究マップ §2: 区切りの入替え): table 規則が小数 `,` / 桁区切り
279
+ * `.` を宣言し、`2.728.548,5` (パターンは locale 非依存の `#,##0.0`) が `2728548.5` に復元される。
280
+ */
281
+ export const EXCEL_EUROPEAN_SEPARATORS = String.raw`<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">
282
+ <head>
283
+ <meta name=Generator content="Microsoft Excel 15">
284
+ <style>
285
+ <!--table
286
+ {mso-displayed-decimal-separator:"\,";
287
+ mso-displayed-thousand-separator:"\.";}
288
+ .xl66
289
+ {mso-number-format:"\#\,\#\#0\.0";}
290
+ -->
291
+ </style>
292
+ </head>
293
+ <body>
294
+ <table border=0 cellpadding=0 cellspacing=0>
295
+ <tr height=20 style='height:15.0pt'>
296
+ <td class=xl66 align=right>2.728.548,5</td>
297
+ <td>1.234</td>
298
+ </tr>
299
+ </table>
300
+ </body>
301
+ </html>`
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @fileoverview Generic (non-spreadsheet) HTML table fixtures for htmlInterop.spec.ts (v0.8 §5.1):
3
+ * hand-written documents exercising the HTML table model and text semantics the `html` kind must
4
+ * honour — pretty-printed whitespace, entities, `thead` / `tfoot` / `tbody` ordering, `th`,
5
+ * `rowspan` / `colspan` interplay, nested tables, semantic run tags, `<font>` attributes,
6
+ * `bgcolor`, `white-space` modes, `<script>` / comments / `<img>` noise (no `mso-*` property —
7
+ * that would be an Excel marker), and a second table that must be ignored. Written 2026-09-05, licence n/a. Test-only.
8
+ * 汎用 HTML 表のフィクスチャ (htmlInterop.spec.ts 用、v0.8 §5.1): `html` kind が守るべき HTML 表
9
+ * モデルと文字列意味論 (整形済み空白・実体・thead / tfoot / tbody 順・th・rowspan / colspan の
10
+ * 干渉・入れ子表・意味タグ run・`<font>` 属性・bgcolor・white-space 各モード・script / コメント /
11
+ * img のノイズ (`mso-*` は Excel マーカーになるので含めない)・無視すべき第 2 表) を手書きで網羅。テスト専用。
12
+ */
13
+
14
+ /**
15
+ * A pretty-printed page: a `<title>` and a paragraph mentioning `<table>` before the table, a
16
+ * `<caption>`, `thead` (a `th` with `colspan=2`), `tfoot` placed BEFORE `tbody` in source order
17
+ * (the HTML `rows` order puts it last), class rules in `<style>` (`.hot`, `td.money`), a
18
+ * `rowspan=2` anchor holding a whole-cell `<b>`, `bgcolor`, a `white-space: pre` cell with a
19
+ * `&#9;` tab, partial `<i>` / `<u>` runs, indentation + `<br>` inside a cell, a whole-cell `<a>`
20
+ * with a nested partial `<em>`, a nested table, a whole-cell `<font color face>`, a `<script>` and
21
+ * a comment inside a cell, a `white-space: pre-line` cell, an `<img>` and `&nbsp;` — then a
22
+ * second table that must not be read.
23
+ * 整形済みページ: 表の前の `<title>` / 段落、caption、thead (`colspan=2` の th)、tbody より前に
24
+ * 置かれた tfoot (HTML の rows 順では末尾)、`<style>` のクラス規則、`<b>` 全体 run の rowspan
25
+ * anchor、bgcolor、`&#9;` 入り pre セル、部分 `<i>` / `<u>`、字下げ + `<br>`、部分 `<em>` を含む
26
+ * 全体 `<a>`、入れ子表、全体 `<font>`、script + コメント、pre-line、img + `&nbsp;`、
27
+ * 読んではならない第 2 表。
28
+ */
29
+ export const HTML_PRETTY_PAGE = `<!DOCTYPE html>
30
+ <html>
31
+ <head>
32
+ <title>Not a table</title>
33
+ <style>
34
+ .hot { color: #ff0000; font-weight: bold; }
35
+ td.money { text-align: right; }
36
+ </style>
37
+ </head>
38
+ <body>
39
+ <p>Intro paragraph with a &lt;table&gt; mention.</p>
40
+ <table border="1">
41
+ <caption>Prices</caption>
42
+ <thead>
43
+ <tr>
44
+ <th>Item</th>
45
+ <th colspan="2">Amount &amp; unit</th>
46
+ </tr>
47
+ </thead>
48
+ <tfoot>
49
+ <tr><td>Total</td><td class="money" colspan="2">3</td></tr>
50
+ </tfoot>
51
+ <tbody>
52
+ <tr>
53
+ <td rowspan="2"><b>Apple</b></td>
54
+ <td class="hot money" bgcolor="#FFFF00">1</td>
55
+ <td style="white-space: pre">a&#9;b</td>
56
+ </tr>
57
+ <tr>
58
+ <td><i>two</i> <u>words</u></td>
59
+ <td>
60
+ multi
61
+ line text
62
+ <br>
63
+ after break
64
+ </td>
65
+ </tr>
66
+ <tr>
67
+ <td><a href="https://example.com/a">Link <em>text</em></a></td>
68
+ <td><table><tr><td>n1</td><td>n2</td></tr><tr><td>n3</td></tr></table></td>
69
+ <td><font color="#00ff00" face="Verdana, Geneva">Green</font></td>
70
+ </tr>
71
+ <tr>
72
+ <td><script>alert(1)</script>Safe<!-- comment --></td>
73
+ <td style="white-space: pre-line"> x
74
+ y </td>
75
+ <td><img src="x.png" alt="pic">Only text &nbsp;here</td>
76
+ </tr>
77
+ </tbody>
78
+ </table>
79
+ <table><tr><td>second table</td></tr></table>
80
+ </body>
81
+ </html>`
82
+
83
+ /**
84
+ * A table whose second row spans THREE columns although its first row declares only two
85
+ * (`rowspan` carry + two own cells): the HTML model widens the table beyond the per-row Σcolspan the
86
+ * estimator sees — the case the reader documents as needing a post-parse re-gate.
87
+ * 1 行目が 2 列しか宣言しないのに 2 行目が 3 列に広がる表 (rowspan の持ち越し + 自セル 2 つ):
88
+ * HTML モデルは見積もりの行毎 Σcolspan を超えて広がる — reader が事後再ゲートを求める事例。
89
+ */
90
+ export const HTML_ROWSPAN_WIDENING = `<table><tr><td rowspan="2">a</td><td>b</td></tr><tr><td>c</td><td>d</td></tr></table>`
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @fileoverview Google Sheets clipboard `text/html` fixtures for htmlInterop.spec.ts (v0.8 §5.1 /
3
+ * §5.3). Every export is a template literal (no backslash occurs in Sheets markup, so `String.raw`
4
+ * is not needed) whose docstring states its provenance (source, capture date, tool, licence). The MARKUP — wrapper, `<style>` block, table / col / tr / td
5
+ * attributes and every inline style — is byte-verbatim from the cited capture; the cell TEXTS and
6
+ * URLs are replaced by neutral words / `example.com` so that no third-party body text is embedded
7
+ * (harness rule §5.3). Fixtures are test-only: no package source imports this directory.
8
+ *
9
+ * Google Sheets のクリップボード `text/html` フィクスチャ (htmlInterop.spec.ts 用、v0.8 §5.1 /
10
+ * §5.3)。各 export はテンプレートリテラル (Sheets のマークアップに逆斜線は無く `String.raw` は不要)
11
+ * で、docstring に由来 (source / capture date / tool / licence) を記す。マークアップ (ラッパー・`<style>`・table / col / tr / td の属性・全インライン
12
+ * style) は引用元キャプチャのバイト通り、セル本文と URL は中立語 / `example.com` へ置換 (第三者
13
+ * 本文を埋め込まない — §5.3)。テスト専用でパッケージ本体からは import しない。
14
+ */
15
+
16
+ /**
17
+ * Own live capture of a 3 × 6 range copied from Google's public "Example Spreadsheet" (anonymous
18
+ * viewer): the raw `paste`-event `text/html` — `<google-sheets-html-origin>` wrapper, the grid-line
19
+ * `<style>`, `data-sheets-root="1"` + `data-sheets-baot="1"`, `<colgroup>` pixel widths, `<tr>`
20
+ * pixel heights, the base td style with `vertical-align:middle;font-weight:bold;` on the header
21
+ * row and `vertical-align:bottom;` elsewhere, and NO `data-sheets-value` on any cell (the 2026
22
+ * anonymous form). Source: Google Sheets (docs.google.com), capture date 2026-09-04, tool:
23
+ * headless Chrome 140 via Playwright (`sweep.mjs`, paste-event sink), licence: own capture
24
+ * (markup verbatim, texts replaced).
25
+ * Google 公開「Example Spreadsheet」の 3 × 6 範囲を匿名閲覧で自前キャプチャした生の `text/html`
26
+ * (2026-09-04、headless Chrome 140 + Playwright)。ラッパー・罫線 `<style>`・root / baot 属性・
27
+ * px 列幅 / 行高・見出し行の `vertical-align:middle;font-weight:bold;`・他行の
28
+ * `vertical-align:bottom;`・全セルに `data-sheets-value` 無し (2026 年匿名形)。本文は置換済み。
29
+ */
30
+ export const SHEETS_LIVE_2026 = `<google-sheets-html-origin><style type="text/css"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" dir="ltr" border="1" style="table-layout:fixed;font-size:10pt;font-family:arial,sans,sans-serif;width:0px;border-collapse:collapse;border:none" data-sheets-root="1" data-sheets-baot="1"><colgroup><col width="120"/><col width="120"/><col width="120"/><col width="120"/><col width="120"/><col width="120"/></colgroup><tbody><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:middle;font-weight:bold;">Name</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:middle;font-weight:bold;">Group</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:middle;font-weight:bold;">Level</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:middle;font-weight:bold;">Region</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:middle;font-weight:bold;">Field</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:middle;font-weight:bold;">Activity</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">Alice</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">F</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">4. Fourth</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">North</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">Text</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">Theatre</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">Ben</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">M</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">1. First</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">South</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">Numbers</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;">Rowing</td></tr></tbody></table>`
31
+
32
+ /**
33
+ * The SAME copy as SHEETS_LIVE_2026 read back through `navigator.clipboard.read()` WITHOUT
34
+ * `unsanitized` — Chromium's sanitised re-serialisation: the `<style>` block is gone and its
35
+ * grid-line rule is inlined on every td as `border: 1px solid rgb(204, 204, 204)`, `padding`
36
+ * collapses to `2px 3px`, every declaration gains a space after the colon, `<col>` loses its
37
+ * XHTML slash, and the wrapper element carries a computed-style dump. `data-*` attributes survive
38
+ * in this capture (Chromium keeps them on the table). Source / date / tool / licence as above.
39
+ * SHEETS_LIVE_2026 と同じコピーを `unsanitized` 無しの `navigator.clipboard.read()` で読み戻した
40
+ * Chromium のサニタイズ再直列化形: `<style>` は消え罫線規則が全 td に
41
+ * `border: 1px solid rgb(204, 204, 204)` としてインライン化、`padding` は `2px 3px` に畳まれ、
42
+ * 宣言はコロン後に空白、`<col>` の XHTML スラッシュ消失、ラッパーに計算スタイルの羅列。
43
+ */
44
+ export const SHEETS_LIVE_2026_SANITISED = `<google-sheets-html-origin style="color: rgb(0, 0, 0); font-size: medium; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" dir="ltr" border="1" data-sheets-root="1" data-sheets-baot="1" style="table-layout: fixed; font-size: 10pt; font-family: arial, sans, sans-serif; width: 0px; border-collapse: collapse; border-width: medium; border-style: none; border-color: currentcolor; border-image: none;"><colgroup><col width="120"><col width="120"><col width="120"><col width="120"><col width="120"><col width="120"></colgroup><tbody><tr style="height: 21px;"><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: middle; font-weight: bold;">Name</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: middle; font-weight: bold;">Group</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: middle; font-weight: bold;">Level</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: middle; font-weight: bold;">Region</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: middle; font-weight: bold;">Field</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: middle; font-weight: bold;">Activity</td></tr><tr style="height: 21px;"><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Alice</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">F</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">4. Fourth</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">North</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Text</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Theatre</td></tr><tr style="height: 21px;"><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Ben</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">M</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">1. First</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">South</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Numbers</td><td style="border: 1px solid rgb(204, 204, 204); overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Rowing</td></tr></tbody></table></google-sheets-html-origin>`
45
+
46
+ /**
47
+ * A 4 × 4 table COMPOSED from cells of the 2026-09-04 sweep captures (23 public sheets, same tool
48
+ * and date as SHEETS_LIVE_2026): every `<td>` open tag and its inline style is verbatim from a
49
+ * captured cell; texts / URLs replaced. Families: merge anchor with `rowspan` + `colspan`, borders
50
+ * 1 / 2 px solid, `1px dashed`, the `1px solid transparent` overflow marker, `background-color`,
51
+ * `font-family` / `font-size:NNpt`, `font-weight:bold|normal`, `text-decoration:underline` /
52
+ * `line-through`, `color`, `text-align`, `vertical-align:top|middle|bottom`,
53
+ * `wrap-strategy:4;white-space:normal;word-wrap:break-word;` (wrap), `white-space:clip` (clip),
54
+ * `white-space:nowrap` (overflow), `<br/>`, `<a class="in-cell-link">`, the `<span><div
55
+ * style="max-height:…">` merged-wrapped wrapper, the overflow `<div><div style="float:left;">`
56
+ * wrapper and rich-text `<span style>` runs (a whole-cell run and a partial one).
57
+ * 2026-09-04 のスイープキャプチャ (公開シート 23 件) のセルを合成した 4 × 4 表: 各 `<td>` 開始タグと
58
+ * インライン style はキャプチャ通り、本文 / URL は置換。結合 anchor (rowspan + colspan)、罫線
59
+ * 1 / 2 px solid・1px dashed・透明 (overflow 印)、背景色、フォント族 / サイズ、太字 / normal、
60
+ * 下線 / 取消線、文字色、水平 / 垂直揃え、wrap / clip / nowrap、`<br/>`、in-cell-link、結合折返し
61
+ * ラッパー、overflow ラッパー、リッチテキスト `<span>` (全体 run と部分 run)。
62
+ */
63
+ export const SHEETS_RICH_2026 = `<google-sheets-html-origin><style type="text/css"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" dir="ltr" border="1" style="table-layout:fixed;font-size:10pt;font-family:Arial;width:0px;border-collapse:collapse;border:none" data-sheets-root="1" data-sheets-baot="1"><colgroup><col width="100"/><col width="100"/><col width="61"/><col width="300"/></colgroup><tbody><tr style="height:21px;"><td style="border-right:2px solid #000000;border-bottom:2px solid #000000;border-left:2px solid #000000;overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;background-color:#ffffff;font-family:Comfortaa;font-size:9pt;font-weight:bold;text-decoration:underline;color:#0000ff;text-align:center;" rowspan="2" colspan="2"><a class="in-cell-link" href="https://example.com/list" target="_blank">Title</a></td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:top;font-weight:bold;wrap-strategy:0;white-space:nowrap;">Plan</td><td style="border-right:1px solid transparent;overflow:visible;padding:2px 0px 2px 0px;vertical-align:bottom;color:#0000ff;"><div style="white-space:nowrap;overflow:hidden;position:relative;width:303px;left:3px;"><div style="float:left;">spill text</div></div></td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:middle;wrap-strategy:4;white-space:normal;word-wrap:break-word;">Wrapped &amp; long</td><td style="border-right:1px solid transparent;overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;"></td></tr><tr style="height:42px;"><td style="border-right:1px dashed #999999;border-bottom:1px solid #ffffff;overflow:hidden;padding:2px 3px 2px 3px;vertical-align:middle;background-color:#ffffff;font-family:Nunito;font-size:16pt;font-weight:normal;wrap-strategy:4;white-space:normal;word-wrap:break-word;color:#999999;text-align:center;"><span style="font-size:16pt;font-family:Nunito,Arial;font-weight:normal;font-style:normal;color:#999999;">TYPE HERE</span></td><td style="border-right:1px solid #ffffff;border-bottom:1px solid #f8f9fa;border-left:1px solid #284e3f;overflow:hidden;padding:2px 8px 2px 8px;vertical-align:middle;background-color:#ffffff;font-family:Roboto;font-weight:normal;text-decoration:line-through;wrap-strategy:3;white-space:clip;color:#434343;">done</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;background-color:#cfe2f3;">line one:<br/>line two</td><td style="border-bottom:1px dashed #000000;overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;font-weight:bold;wrap-strategy:4;white-space:normal;word-wrap:break-word;text-align:right;">6.7</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:middle;wrap-strategy:4;white-space:normal;word-wrap:break-word;" rowspan="1" colspan="3"><span><div style="max-height:42px">Notes<br/><br/>:: a field<br/>-&gt; a reference</div></span></td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;background-color:#f9fafb;font-size:9pt;wrap-strategy:4;white-space:normal;word-wrap:break-word;color:#374151;text-align:right;"><span style="font-size:9pt;font-family:Arial;font-style:normal;color:#374151;">w/ </span><span style="font-size:9pt;font-family:Arial;font-style:normal;text-decoration:underline;color:#374151;">it&#39;s</span></td></tr></tbody></table></google-sheets-html-origin>`
64
+
65
+ /**
66
+ * HAND-WRITTEN reconstruction of an editor-side (logged-in) Sheets copy carrying the typed
67
+ * `data-sheets-*` attributes, following the grammar documented in the research map (§3) and the
68
+ * open-source fixtures it cites: iter.ca 2022 (`data-sheets-value` type 3 + `data-sheets-formula`
69
+ * R1C1), Univer `constant.ts` (Apache-2.0; `data-sheets-numberformat` `{"1":5,"2":"yyyy/m/d","3":1}`
70
+ * with serial 45607 = 2024/11/11, `rowspan` / `colspan`), Lexical (MIT; `data-sheets-textstyleruns`),
71
+ * jsvine 2015 (positional array `[null,2,"…"]`). Cells: number, formula, `=` literal forced to a
72
+ * string, boolean, error `#DIV/0!`, DATE serial, PERCENT, NUMBER, TEXT, legacy array form,
73
+ * `data-sheets-hyperlink` beside a different `<a href>`, `data-sheets-note` with `&#10;`,
74
+ * `data-sheets-userformat` + partial bold run, DATE_TIME serial with a fraction, malformed JSON,
75
+ * a FALSE with the automatic format `{"1":0}`, and a formula / hyperlink pair that must be dropped
76
+ * (no `=` / `javascript:`). Not a capture: reconstruction, 2026-09-05, licence n/a.
77
+ * 編集者側 (ログイン済) の Sheets コピーが持つ型付き `data-sheets-*` 属性を、研究マップ §3 と引用
78
+ * OSS フィクスチャ (iter.ca 2022 / Univer Apache-2.0 / Lexical MIT / jsvine 2015) の文法に従い
79
+ * 手書き再構成。数値・数式・`=` リテラル・真偽値・エラー・DATE シリアル・PERCENT・NUMBER・TEXT・
80
+ * 旧配列形・別 `<a>` と並ぶ hyperlink 属性・`&#10;` 入り note・userformat + 部分 bold run・
81
+ * 小数付き DATE_TIME・不正 JSON・自動書式の FALSE・落とすべき数式 / hyperlink。キャプチャではない。
82
+ */
83
+ export const SHEETS_TYPED_RECONSTRUCTION = `<google-sheets-html-origin><style type="text/css"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" dir="ltr" border="1" style="table-layout:fixed;font-size:10pt;font-family:Arial;width:0px;border-collapse:collapse;border:none" data-sheets-root="1"><colgroup><col width="100"/><col width="100"/><col width="100"/><col width="100"/></colgroup><tbody><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:3}">3</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:6}" data-sheets-formula="=2*R[0]C[-1]">6</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;=not a formula&quot;}">=not a formula</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:center;" data-sheets-value="{&quot;1&quot;:4,&quot;4&quot;:1}">TRUE</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:center;" data-sheets-value="{&quot;1&quot;:5,&quot;5&quot;:{&quot;1&quot;:2}}" data-sheets-formula="=1/0">#DIV/0!</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:45607}" data-sheets-numberformat="{&quot;1&quot;:5,&quot;2&quot;:&quot;yyyy/m/d&quot;,&quot;3&quot;:1}">2024/11/11</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:0.2}" data-sheets-numberformat="{&quot;1&quot;:3,&quot;2&quot;:&quot;0.00%&quot;,&quot;3&quot;:1}">20.00%</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:1234.5}" data-sheets-numberformat="{&quot;1&quot;:2,&quot;2&quot;:&quot;#,##0.00&quot;,&quot;3&quot;:1}">1,234.50</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;0123&quot;}" data-sheets-numberformat="{&quot;1&quot;:1}">0123</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="[null,2,&quot;Legacy&quot;]">Legacy</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-decoration:underline;color:#1155cc;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Docs&quot;}" data-sheets-hyperlink="https://example.com/docs"><a class="in-cell-link" href="https://example.com/other" target="_blank">Docs</a></td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Noted&quot;}" data-sheets-note="A note&#10;second line" data-sheets-userformat="{&quot;2&quot;:513,&quot;3&quot;:{&quot;1&quot;:0},&quot;12&quot;:0}" data-sheets-textstyleruns="{&quot;1&quot;:0}{&quot;1&quot;:2,&quot;2&quot;:{&quot;5&quot;:1}}">No<span style="font-weight:bold;">ted</span></td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:45607.5}" data-sheets-numberformat="{&quot;1&quot;:7,&quot;2&quot;:&quot;yyyy-mm-dd hh:mm:ss&quot;}">2024-11-11 12:00:00</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{not json">shown</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-align:center;" data-sheets-value="{&quot;1&quot;:4,&quot;4&quot;:0}" data-sheets-numberformat="{&quot;1&quot;:0}">FALSE</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-formula="R[0]C[-1]" data-sheets-hyperlink="javascript:alert(1)">bad</td></tr></tbody></table></google-sheets-html-origin>`