@aglyn/plugins-ai 1.0.0-beta.257 → 1.0.0-beta.258

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 (84) hide show
  1. package/package.json +17 -17
  2. package/src/lib/components/assist-panel.component.js +21 -8
  3. package/src/lib/components/assist-panel.component.js.map +1 -1
  4. package/src/lib/insights/ai-figure-readers.js +15 -8
  5. package/src/lib/insights/ai-figure-readers.js.map +1 -1
  6. package/src/lib/jobs/ai-job-build-step.d.ts +9 -0
  7. package/src/lib/jobs/ai-job-build-step.js +19 -3
  8. package/src/lib/jobs/ai-job-build-step.js.map +1 -1
  9. package/src/lib/jobs/ai-job-insight-step.js +1 -1
  10. package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
  11. package/src/lib/jobs/ai-job-page-language.d.ts +19 -0
  12. package/src/lib/jobs/ai-job-page-language.js +24 -4
  13. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  14. package/src/lib/jobs/ai-job-page-sections.js +12 -1
  15. package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
  16. package/src/lib/jobs/ai-job-page-step.d.ts +14 -0
  17. package/src/lib/jobs/ai-job-page-step.js +69 -20
  18. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  19. package/src/lib/jobs/ai-job-seo-step.js +3 -2
  20. package/src/lib/jobs/ai-job-seo-step.js.map +1 -1
  21. package/src/lib/jobs/ai-layout-stock-photos.d.ts +10 -5
  22. package/src/lib/jobs/ai-layout-stock-photos.js +89 -7
  23. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  24. package/src/lib/jobs/fixtures/ai-stock-photo-copper-kettle-recordings.d.ts +21 -0
  25. package/src/lib/jobs/fixtures/ai-stock-photo-copper-kettle-recordings.js +126 -0
  26. package/src/lib/jobs/fixtures/ai-stock-photo-copper-kettle-recordings.js.map +1 -0
  27. package/src/lib/layout-language/ai-layout-compiler.js +52 -52
  28. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  29. package/src/lib/layout-language/ai-layout-copy.d.ts +9 -5
  30. package/src/lib/layout-language/ai-layout-copy.js +22 -14
  31. package/src/lib/layout-language/ai-layout-copy.js.map +1 -1
  32. package/src/lib/layout-language/ai-layout-frame.js +4 -4
  33. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  34. package/src/lib/layout-language/ai-layout-pictures.d.ts +44 -15
  35. package/src/lib/layout-language/ai-layout-pictures.js +29 -8
  36. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
  37. package/src/lib/model/ai-build-job.js +14 -0
  38. package/src/lib/model/ai-build-job.js.map +1 -1
  39. package/src/lib/model/ai-host-publish-context.d.ts +6 -0
  40. package/src/lib/model/ai-host-publish-context.js +15 -2
  41. package/src/lib/model/ai-host-publish-context.js.map +1 -1
  42. package/src/lib/model/assist-follow-up.d.ts +35 -0
  43. package/src/lib/model/assist-follow-up.js +44 -4
  44. package/src/lib/model/assist-follow-up.js.map +1 -1
  45. package/src/lib/providers/anthropic.js +17 -4
  46. package/src/lib/providers/anthropic.js.map +1 -1
  47. package/src/lib/providers/cache-write-hour.d.ts +37 -0
  48. package/src/lib/providers/cache-write-hour.js +46 -0
  49. package/src/lib/providers/cache-write-hour.js.map +1 -0
  50. package/src/lib/providers/contract.d.ts +16 -3
  51. package/src/lib/providers/contract.js.map +1 -1
  52. package/src/lib/providers/routing.d.ts +13 -0
  53. package/src/lib/providers/routing.js +27 -11
  54. package/src/lib/providers/routing.js.map +1 -1
  55. package/src/lib/runtime/ai-dev-env.d.ts +13 -3
  56. package/src/lib/runtime/ai-dev-env.js +17 -3
  57. package/src/lib/runtime/ai-dev-env.js.map +1 -1
  58. package/src/lib/runtime/ai-dev-replay.js +4 -2
  59. package/src/lib/runtime/ai-dev-replay.js.map +1 -1
  60. package/src/lib/runtime/ai-doctrine-validators.d.ts +41 -1
  61. package/src/lib/runtime/ai-doctrine-validators.js +263 -2
  62. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  63. package/src/lib/runtime/ai-doctrine.js +7 -1
  64. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  65. package/src/lib/runtime/ai-eval-live.js +1 -1
  66. package/src/lib/runtime/ai-eval-live.js.map +1 -1
  67. package/src/lib/runtime/ai-eval.d.ts +1 -1
  68. package/src/lib/runtime/ai-eval.js +18 -1
  69. package/src/lib/runtime/ai-eval.js.map +1 -1
  70. package/src/lib/runtime/ai-placeholder-tokens.d.ts +70 -0
  71. package/src/lib/runtime/ai-placeholder-tokens.js +169 -0
  72. package/src/lib/runtime/ai-placeholder-tokens.js.map +1 -0
  73. package/src/lib/runtime/ai-repeated-items.js +5 -2
  74. package/src/lib/runtime/ai-repeated-items.js.map +1 -1
  75. package/src/lib/runtime/ai-runtime.js +2 -3
  76. package/src/lib/runtime/ai-runtime.js.map +1 -1
  77. package/src/lib/server/assist-chat.js +8 -3
  78. package/src/lib/server/assist-chat.js.map +1 -1
  79. package/src/lib/server/assist-view-context.d.ts +5 -1
  80. package/src/lib/server/assist-view-context.js +8 -3
  81. package/src/lib/server/assist-view-context.js.map +1 -1
  82. package/src/lib/usage/assist-usage.d.ts +2 -0
  83. package/src/lib/usage/assist-usage.js +8 -3
  84. package/src/lib/usage/assist-usage.js.map +1 -1
@@ -0,0 +1,169 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /**
17
+ * Template placeholders in copy (AGL-3827): a slot a template or a model's
18
+ * own scaffolding left where words belong, which a visitor would read exactly
19
+ * as written. A live About page shipped two testimonials whose quote and name
20
+ * were `{{1}}` and `{{2}}`, the repeated-item slots of a section written once.
21
+ *
22
+ * What counts as a placeholder, and what does not:
23
+ *
24
+ * - `{{1}}`, `{{ 2 }}`: a repeated item's slot (`ai-repeated-items.ts`). No
25
+ * binding token is a number, so one left in copy filled nothing.
26
+ * - `{{name}}`, `{{Customer name}}`, `{{客户}}`: anything in double braces
27
+ * that is not a binding the platform fills. A scoped binding, such as
28
+ * `{{item.title}}`, `{{entry.url}}`, `{{prop.heading}}` or
29
+ * `{{contact.firstName}}`, and an id token, `{{var:…}}` or `{{fn:…(…)}}`,
30
+ * are the platform's own and are left to the checks that own them. A bare
31
+ * `{{name}}` would bind a site variable of that name, and a generator is
32
+ * shown none, so in a generated page it is a slot; an email's step owns
33
+ * its merge tokens, bare spellings included (`ai-job-email-step.ts`).
34
+ * - `[[Customer name]]`, `${name}`: a template's slot in another syntax.
35
+ * - `<Your business name>`, `<placeholder>`: words in angle brackets that are
36
+ * no HTML tag. Several words whose first is not a tag name, or one word a
37
+ * slot is named by. `Press <Enter>`, `x < y`, `<3` and markup are copy.
38
+ *
39
+ * NOT a placeholder: a fact the brief never gave, in single square brackets,
40
+ * such as `[Office phone number]`. That is the honest marker rule 14 asks for
41
+ * instead of an invented fact, and each draft's note lists them for the
42
+ * member to fill (AGL-3056). Nor `[sic]`, a Markdown link, a price, or Lorem
43
+ * ipsum, which rule 14's filler check already refuses.
44
+ *
45
+ * Pure text in, tokens out: no tree, no palette, so any check may read it.
46
+ */ /** Anything in double braces, on one line. */ const MUSTACHE = /\{\{\s*([^{}\n]{0,80}?)\s*\}\}/g;
47
+ const REPEAT_SLOT = /^\d+$/;
48
+ /** `{{var:id}}` and `{{fn:name(args)}}`, the binding grammar's id tokens (`binding-tokens.ts`). */ const ID_TOKEN = /^(?:var|fn):/;
49
+ /** A scoped binding: `item.title`, `entry.cover.url`, `contact.firstName`. */ const SCOPED_TOKEN = /^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)+$/;
50
+ /** A legacy `{{name}}` token's name (`NAME_TOKEN_PATTERN`). */ const BARE_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,39}$/;
51
+ const DOUBLE_BRACKET = /\[\[\s*[^[\]\n]{1,80}?\s*\]\]/g;
52
+ const TEMPLATE_LITERAL = /\$\{\s*[A-Za-z_][\w.]{0,40}\s*\}/g;
53
+ /** Words in angle brackets: a letter first, no attribute, path or quote inside. */ const ANGLE = RegExp("<([\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376-\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E-\\u066F\\u0671-\\u06D3\\u06D5\\u06E5-\\u06E6\\u06EE-\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4-\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088F\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC-\\u09DD\\u09DF-\\u09E1\\u09F0-\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32-\\u0A33\\u0A35-\\u0A36\\u0A38-\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0-\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C-\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5C-\\u0C5D\\u0C60-\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDC-\\u0CDE\\u0CE0-\\u0CE1\\u0CF1-\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32-\\u0E33\\u0E40-\\u0E46\\u0E81-\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2-\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065-\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE-\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C8A\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5-\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183-\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3006\\u3031-\\u3035\\u303B-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A-\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7DC\\uA7F1-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD-\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5-\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40-\\uFB41\\uFB43-\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC\\u{10000}-\\u{1000B}\\u{1000D}-\\u{10026}\\u{10028}-\\u{1003A}\\u{1003C}-\\u{1003D}\\u{1003F}-\\u{1004D}\\u{10050}-\\u{1005D}\\u{10080}-\\u{100FA}\\u{10280}-\\u{1029C}\\u{102A0}-\\u{102D0}\\u{10300}-\\u{1031F}\\u{1032D}-\\u{10340}\\u{10342}-\\u{10349}\\u{10350}-\\u{10375}\\u{10380}-\\u{1039D}\\u{103A0}-\\u{103C3}\\u{103C8}-\\u{103CF}\\u{10400}-\\u{1049D}\\u{104B0}-\\u{104D3}\\u{104D8}-\\u{104FB}\\u{10500}-\\u{10527}\\u{10530}-\\u{10563}\\u{10570}-\\u{1057A}\\u{1057C}-\\u{1058A}\\u{1058C}-\\u{10592}\\u{10594}-\\u{10595}\\u{10597}-\\u{105A1}\\u{105A3}-\\u{105B1}\\u{105B3}-\\u{105B9}\\u{105BB}-\\u{105BC}\\u{105C0}-\\u{105F3}\\u{10600}-\\u{10736}\\u{10740}-\\u{10755}\\u{10760}-\\u{10767}\\u{10780}-\\u{10785}\\u{10787}-\\u{107B0}\\u{107B2}-\\u{107BA}\\u{10800}-\\u{10805}\\u{10808}\\u{1080A}-\\u{10835}\\u{10837}-\\u{10838}\\u{1083C}\\u{1083F}-\\u{10855}\\u{10860}-\\u{10876}\\u{10880}-\\u{1089E}\\u{108E0}-\\u{108F2}\\u{108F4}-\\u{108F5}\\u{10900}-\\u{10915}\\u{10920}-\\u{10939}\\u{10940}-\\u{10959}\\u{10980}-\\u{109B7}\\u{109BE}-\\u{109BF}\\u{10A00}\\u{10A10}-\\u{10A13}\\u{10A15}-\\u{10A17}\\u{10A19}-\\u{10A35}\\u{10A60}-\\u{10A7C}\\u{10A80}-\\u{10A9C}\\u{10AC0}-\\u{10AC7}\\u{10AC9}-\\u{10AE4}\\u{10B00}-\\u{10B35}\\u{10B40}-\\u{10B55}\\u{10B60}-\\u{10B72}\\u{10B80}-\\u{10B91}\\u{10C00}-\\u{10C48}\\u{10C80}-\\u{10CB2}\\u{10CC0}-\\u{10CF2}\\u{10D00}-\\u{10D23}\\u{10D4A}-\\u{10D65}\\u{10D6F}-\\u{10D85}\\u{10E80}-\\u{10EA9}\\u{10EB0}-\\u{10EB1}\\u{10EC2}-\\u{10EC7}\\u{10F00}-\\u{10F1C}\\u{10F27}\\u{10F30}-\\u{10F45}\\u{10F70}-\\u{10F81}\\u{10FB0}-\\u{10FC4}\\u{10FE0}-\\u{10FF6}\\u{11003}-\\u{11037}\\u{11071}-\\u{11072}\\u{11075}\\u{11083}-\\u{110AF}\\u{110D0}-\\u{110E8}\\u{11103}-\\u{11126}\\u{11144}\\u{11147}\\u{11150}-\\u{11172}\\u{11176}\\u{11183}-\\u{111B2}\\u{111C1}-\\u{111C4}\\u{111DA}\\u{111DC}\\u{11200}-\\u{11211}\\u{11213}-\\u{1122B}\\u{1123F}-\\u{11240}\\u{11280}-\\u{11286}\\u{11288}\\u{1128A}-\\u{1128D}\\u{1128F}-\\u{1129D}\\u{1129F}-\\u{112A8}\\u{112B0}-\\u{112DE}\\u{11305}-\\u{1130C}\\u{1130F}-\\u{11310}\\u{11313}-\\u{11328}\\u{1132A}-\\u{11330}\\u{11332}-\\u{11333}\\u{11335}-\\u{11339}\\u{1133D}\\u{11350}\\u{1135D}-\\u{11361}\\u{11380}-\\u{11389}\\u{1138B}\\u{1138E}\\u{11390}-\\u{113B5}\\u{113B7}\\u{113D1}\\u{113D3}\\u{11400}-\\u{11434}\\u{11447}-\\u{1144A}\\u{1145F}-\\u{11461}\\u{11480}-\\u{114AF}\\u{114C4}-\\u{114C5}\\u{114C7}\\u{11580}-\\u{115AE}\\u{115D8}-\\u{115DB}\\u{11600}-\\u{1162F}\\u{11644}\\u{11680}-\\u{116AA}\\u{116B8}\\u{11700}-\\u{1171A}\\u{11740}-\\u{11746}\\u{11800}-\\u{1182B}\\u{118A0}-\\u{118DF}\\u{118FF}-\\u{11906}\\u{11909}\\u{1190C}-\\u{11913}\\u{11915}-\\u{11916}\\u{11918}-\\u{1192F}\\u{1193F}\\u{11941}\\u{119A0}-\\u{119A7}\\u{119AA}-\\u{119D0}\\u{119E1}\\u{119E3}\\u{11A00}\\u{11A0B}-\\u{11A32}\\u{11A3A}\\u{11A50}\\u{11A5C}-\\u{11A89}\\u{11A9D}\\u{11AB0}-\\u{11AF8}\\u{11BC0}-\\u{11BE0}\\u{11C00}-\\u{11C08}\\u{11C0A}-\\u{11C2E}\\u{11C40}\\u{11C72}-\\u{11C8F}\\u{11D00}-\\u{11D06}\\u{11D08}-\\u{11D09}\\u{11D0B}-\\u{11D30}\\u{11D46}\\u{11D60}-\\u{11D65}\\u{11D67}-\\u{11D68}\\u{11D6A}-\\u{11D89}\\u{11D98}\\u{11DB0}-\\u{11DDB}\\u{11EE0}-\\u{11EF2}\\u{11F02}\\u{11F04}-\\u{11F10}\\u{11F12}-\\u{11F33}\\u{11FB0}\\u{12000}-\\u{12399}\\u{12480}-\\u{12543}\\u{12F90}-\\u{12FF0}\\u{13000}-\\u{1342F}\\u{13441}-\\u{13446}\\u{13460}-\\u{143FA}\\u{14400}-\\u{14646}\\u{16100}-\\u{1611D}\\u{16800}-\\u{16A38}\\u{16A40}-\\u{16A5E}\\u{16A70}-\\u{16ABE}\\u{16AD0}-\\u{16AED}\\u{16B00}-\\u{16B2F}\\u{16B40}-\\u{16B43}\\u{16B63}-\\u{16B77}\\u{16B7D}-\\u{16B8F}\\u{16D40}-\\u{16D6C}\\u{16E40}-\\u{16E7F}\\u{16EA0}-\\u{16EB8}\\u{16EBB}-\\u{16ED3}\\u{16F00}-\\u{16F4A}\\u{16F50}\\u{16F93}-\\u{16F9F}\\u{16FE0}-\\u{16FE1}\\u{16FE3}\\u{16FF2}-\\u{16FF3}\\u{17000}-\\u{18CD5}\\u{18CFF}-\\u{18D1E}\\u{18D80}-\\u{18DF2}\\u{1AFF0}-\\u{1AFF3}\\u{1AFF5}-\\u{1AFFB}\\u{1AFFD}-\\u{1AFFE}\\u{1B000}-\\u{1B122}\\u{1B132}\\u{1B150}-\\u{1B152}\\u{1B155}\\u{1B164}-\\u{1B167}\\u{1B170}-\\u{1B2FB}\\u{1BC00}-\\u{1BC6A}\\u{1BC70}-\\u{1BC7C}\\u{1BC80}-\\u{1BC88}\\u{1BC90}-\\u{1BC99}\\u{1D400}-\\u{1D454}\\u{1D456}-\\u{1D49C}\\u{1D49E}-\\u{1D49F}\\u{1D4A2}\\u{1D4A5}-\\u{1D4A6}\\u{1D4A9}-\\u{1D4AC}\\u{1D4AE}-\\u{1D4B9}\\u{1D4BB}\\u{1D4BD}-\\u{1D4C3}\\u{1D4C5}-\\u{1D505}\\u{1D507}-\\u{1D50A}\\u{1D50D}-\\u{1D514}\\u{1D516}-\\u{1D51C}\\u{1D51E}-\\u{1D539}\\u{1D53B}-\\u{1D53E}\\u{1D540}-\\u{1D544}\\u{1D546}\\u{1D54A}-\\u{1D550}\\u{1D552}-\\u{1D6A5}\\u{1D6A8}-\\u{1D6C0}\\u{1D6C2}-\\u{1D6DA}\\u{1D6DC}-\\u{1D6FA}\\u{1D6FC}-\\u{1D714}\\u{1D716}-\\u{1D734}\\u{1D736}-\\u{1D74E}\\u{1D750}-\\u{1D76E}\\u{1D770}-\\u{1D788}\\u{1D78A}-\\u{1D7A8}\\u{1D7AA}-\\u{1D7C2}\\u{1D7C4}-\\u{1D7CB}\\u{1DF00}-\\u{1DF1E}\\u{1DF25}-\\u{1DF2A}\\u{1E030}-\\u{1E06D}\\u{1E100}-\\u{1E12C}\\u{1E137}-\\u{1E13D}\\u{1E14E}\\u{1E290}-\\u{1E2AD}\\u{1E2C0}-\\u{1E2EB}\\u{1E4D0}-\\u{1E4EB}\\u{1E5D0}-\\u{1E5ED}\\u{1E5F0}\\u{1E6C0}-\\u{1E6DE}\\u{1E6E0}-\\u{1E6E2}\\u{1E6E4}-\\u{1E6E5}\\u{1E6E7}-\\u{1E6ED}\\u{1E6F0}-\\u{1E6F4}\\u{1E6FE}-\\u{1E6FF}\\u{1E7E0}-\\u{1E7E6}\\u{1E7E8}-\\u{1E7EB}\\u{1E7ED}-\\u{1E7EE}\\u{1E7F0}-\\u{1E7FE}\\u{1E800}-\\u{1E8C4}\\u{1E900}-\\u{1E943}\\u{1E94B}\\u{1EE00}-\\u{1EE03}\\u{1EE05}-\\u{1EE1F}\\u{1EE21}-\\u{1EE22}\\u{1EE24}\\u{1EE27}\\u{1EE29}-\\u{1EE32}\\u{1EE34}-\\u{1EE37}\\u{1EE39}\\u{1EE3B}\\u{1EE42}\\u{1EE47}\\u{1EE49}\\u{1EE4B}\\u{1EE4D}-\\u{1EE4F}\\u{1EE51}-\\u{1EE52}\\u{1EE54}\\u{1EE57}\\u{1EE59}\\u{1EE5B}\\u{1EE5D}\\u{1EE5F}\\u{1EE61}-\\u{1EE62}\\u{1EE64}\\u{1EE67}-\\u{1EE6A}\\u{1EE6C}-\\u{1EE72}\\u{1EE74}-\\u{1EE77}\\u{1EE79}-\\u{1EE7C}\\u{1EE7E}\\u{1EE80}-\\u{1EE89}\\u{1EE8B}-\\u{1EE9B}\\u{1EEA1}-\\u{1EEA3}\\u{1EEA5}-\\u{1EEA9}\\u{1EEAB}-\\u{1EEBB}\\u{20000}-\\u{2A6DF}\\u{2A700}-\\u{2B81D}\\u{2B820}-\\u{2CEAD}\\u{2CEB0}-\\u{2EBE0}\\u{2EBF0}-\\u{2EE5D}\\u{2F800}-\\u{2FA1D}\\u{30000}-\\u{3134A}\\u{31350}-\\u{33479}][^<>{}[\\]=/\"':;@\\n]{0,60}?)>", "gu");
54
+ /** Elements copy may carry inline, whose tag an angle slot never starts with. */ const HTML_TAGS = new Set([
55
+ 'a',
56
+ 'abbr',
57
+ 'b',
58
+ 'br',
59
+ 'cite',
60
+ 'code',
61
+ 'del',
62
+ 'div',
63
+ 'em',
64
+ 'h1',
65
+ 'h2',
66
+ 'h3',
67
+ 'h4',
68
+ 'h5',
69
+ 'h6',
70
+ 'hr',
71
+ 'i',
72
+ 'img',
73
+ 'ins',
74
+ 'kbd',
75
+ 'li',
76
+ 'mark',
77
+ 'ol',
78
+ 'p',
79
+ 'q',
80
+ 's',
81
+ 'small',
82
+ 'span',
83
+ 'strong',
84
+ 'sub',
85
+ 'sup',
86
+ 'u',
87
+ 'ul'
88
+ ]);
89
+ /** One word in angle brackets that names a slot rather than a key or a tag. */ const SLOT_WORD = RegExp("^(?:placeholder|insert|tbd|todo|name|title|text|copy|value|company|business|city|phone|email|address|date|price|quote|author|your[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376-\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E-\\u066F\\u0671-\\u06D3\\u06D5\\u06E5-\\u06E6\\u06EE-\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4-\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088F\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC-\\u09DD\\u09DF-\\u09E1\\u09F0-\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32-\\u0A33\\u0A35-\\u0A36\\u0A38-\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0-\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C-\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5C-\\u0C5D\\u0C60-\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDC-\\u0CDE\\u0CE0-\\u0CE1\\u0CF1-\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32-\\u0E33\\u0E40-\\u0E46\\u0E81-\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2-\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065-\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE-\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C8A\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5-\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183-\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3006\\u3031-\\u3035\\u303B-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A-\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7DC\\uA7F1-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD-\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5-\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40-\\uFB41\\uFB43-\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC\\u{10000}-\\u{1000B}\\u{1000D}-\\u{10026}\\u{10028}-\\u{1003A}\\u{1003C}-\\u{1003D}\\u{1003F}-\\u{1004D}\\u{10050}-\\u{1005D}\\u{10080}-\\u{100FA}\\u{10280}-\\u{1029C}\\u{102A0}-\\u{102D0}\\u{10300}-\\u{1031F}\\u{1032D}-\\u{10340}\\u{10342}-\\u{10349}\\u{10350}-\\u{10375}\\u{10380}-\\u{1039D}\\u{103A0}-\\u{103C3}\\u{103C8}-\\u{103CF}\\u{10400}-\\u{1049D}\\u{104B0}-\\u{104D3}\\u{104D8}-\\u{104FB}\\u{10500}-\\u{10527}\\u{10530}-\\u{10563}\\u{10570}-\\u{1057A}\\u{1057C}-\\u{1058A}\\u{1058C}-\\u{10592}\\u{10594}-\\u{10595}\\u{10597}-\\u{105A1}\\u{105A3}-\\u{105B1}\\u{105B3}-\\u{105B9}\\u{105BB}-\\u{105BC}\\u{105C0}-\\u{105F3}\\u{10600}-\\u{10736}\\u{10740}-\\u{10755}\\u{10760}-\\u{10767}\\u{10780}-\\u{10785}\\u{10787}-\\u{107B0}\\u{107B2}-\\u{107BA}\\u{10800}-\\u{10805}\\u{10808}\\u{1080A}-\\u{10835}\\u{10837}-\\u{10838}\\u{1083C}\\u{1083F}-\\u{10855}\\u{10860}-\\u{10876}\\u{10880}-\\u{1089E}\\u{108E0}-\\u{108F2}\\u{108F4}-\\u{108F5}\\u{10900}-\\u{10915}\\u{10920}-\\u{10939}\\u{10940}-\\u{10959}\\u{10980}-\\u{109B7}\\u{109BE}-\\u{109BF}\\u{10A00}\\u{10A10}-\\u{10A13}\\u{10A15}-\\u{10A17}\\u{10A19}-\\u{10A35}\\u{10A60}-\\u{10A7C}\\u{10A80}-\\u{10A9C}\\u{10AC0}-\\u{10AC7}\\u{10AC9}-\\u{10AE4}\\u{10B00}-\\u{10B35}\\u{10B40}-\\u{10B55}\\u{10B60}-\\u{10B72}\\u{10B80}-\\u{10B91}\\u{10C00}-\\u{10C48}\\u{10C80}-\\u{10CB2}\\u{10CC0}-\\u{10CF2}\\u{10D00}-\\u{10D23}\\u{10D4A}-\\u{10D65}\\u{10D6F}-\\u{10D85}\\u{10E80}-\\u{10EA9}\\u{10EB0}-\\u{10EB1}\\u{10EC2}-\\u{10EC7}\\u{10F00}-\\u{10F1C}\\u{10F27}\\u{10F30}-\\u{10F45}\\u{10F70}-\\u{10F81}\\u{10FB0}-\\u{10FC4}\\u{10FE0}-\\u{10FF6}\\u{11003}-\\u{11037}\\u{11071}-\\u{11072}\\u{11075}\\u{11083}-\\u{110AF}\\u{110D0}-\\u{110E8}\\u{11103}-\\u{11126}\\u{11144}\\u{11147}\\u{11150}-\\u{11172}\\u{11176}\\u{11183}-\\u{111B2}\\u{111C1}-\\u{111C4}\\u{111DA}\\u{111DC}\\u{11200}-\\u{11211}\\u{11213}-\\u{1122B}\\u{1123F}-\\u{11240}\\u{11280}-\\u{11286}\\u{11288}\\u{1128A}-\\u{1128D}\\u{1128F}-\\u{1129D}\\u{1129F}-\\u{112A8}\\u{112B0}-\\u{112DE}\\u{11305}-\\u{1130C}\\u{1130F}-\\u{11310}\\u{11313}-\\u{11328}\\u{1132A}-\\u{11330}\\u{11332}-\\u{11333}\\u{11335}-\\u{11339}\\u{1133D}\\u{11350}\\u{1135D}-\\u{11361}\\u{11380}-\\u{11389}\\u{1138B}\\u{1138E}\\u{11390}-\\u{113B5}\\u{113B7}\\u{113D1}\\u{113D3}\\u{11400}-\\u{11434}\\u{11447}-\\u{1144A}\\u{1145F}-\\u{11461}\\u{11480}-\\u{114AF}\\u{114C4}-\\u{114C5}\\u{114C7}\\u{11580}-\\u{115AE}\\u{115D8}-\\u{115DB}\\u{11600}-\\u{1162F}\\u{11644}\\u{11680}-\\u{116AA}\\u{116B8}\\u{11700}-\\u{1171A}\\u{11740}-\\u{11746}\\u{11800}-\\u{1182B}\\u{118A0}-\\u{118DF}\\u{118FF}-\\u{11906}\\u{11909}\\u{1190C}-\\u{11913}\\u{11915}-\\u{11916}\\u{11918}-\\u{1192F}\\u{1193F}\\u{11941}\\u{119A0}-\\u{119A7}\\u{119AA}-\\u{119D0}\\u{119E1}\\u{119E3}\\u{11A00}\\u{11A0B}-\\u{11A32}\\u{11A3A}\\u{11A50}\\u{11A5C}-\\u{11A89}\\u{11A9D}\\u{11AB0}-\\u{11AF8}\\u{11BC0}-\\u{11BE0}\\u{11C00}-\\u{11C08}\\u{11C0A}-\\u{11C2E}\\u{11C40}\\u{11C72}-\\u{11C8F}\\u{11D00}-\\u{11D06}\\u{11D08}-\\u{11D09}\\u{11D0B}-\\u{11D30}\\u{11D46}\\u{11D60}-\\u{11D65}\\u{11D67}-\\u{11D68}\\u{11D6A}-\\u{11D89}\\u{11D98}\\u{11DB0}-\\u{11DDB}\\u{11EE0}-\\u{11EF2}\\u{11F02}\\u{11F04}-\\u{11F10}\\u{11F12}-\\u{11F33}\\u{11FB0}\\u{12000}-\\u{12399}\\u{12480}-\\u{12543}\\u{12F90}-\\u{12FF0}\\u{13000}-\\u{1342F}\\u{13441}-\\u{13446}\\u{13460}-\\u{143FA}\\u{14400}-\\u{14646}\\u{16100}-\\u{1611D}\\u{16800}-\\u{16A38}\\u{16A40}-\\u{16A5E}\\u{16A70}-\\u{16ABE}\\u{16AD0}-\\u{16AED}\\u{16B00}-\\u{16B2F}\\u{16B40}-\\u{16B43}\\u{16B63}-\\u{16B77}\\u{16B7D}-\\u{16B8F}\\u{16D40}-\\u{16D6C}\\u{16E40}-\\u{16E7F}\\u{16EA0}-\\u{16EB8}\\u{16EBB}-\\u{16ED3}\\u{16F00}-\\u{16F4A}\\u{16F50}\\u{16F93}-\\u{16F9F}\\u{16FE0}-\\u{16FE1}\\u{16FE3}\\u{16FF2}-\\u{16FF3}\\u{17000}-\\u{18CD5}\\u{18CFF}-\\u{18D1E}\\u{18D80}-\\u{18DF2}\\u{1AFF0}-\\u{1AFF3}\\u{1AFF5}-\\u{1AFFB}\\u{1AFFD}-\\u{1AFFE}\\u{1B000}-\\u{1B122}\\u{1B132}\\u{1B150}-\\u{1B152}\\u{1B155}\\u{1B164}-\\u{1B167}\\u{1B170}-\\u{1B2FB}\\u{1BC00}-\\u{1BC6A}\\u{1BC70}-\\u{1BC7C}\\u{1BC80}-\\u{1BC88}\\u{1BC90}-\\u{1BC99}\\u{1D400}-\\u{1D454}\\u{1D456}-\\u{1D49C}\\u{1D49E}-\\u{1D49F}\\u{1D4A2}\\u{1D4A5}-\\u{1D4A6}\\u{1D4A9}-\\u{1D4AC}\\u{1D4AE}-\\u{1D4B9}\\u{1D4BB}\\u{1D4BD}-\\u{1D4C3}\\u{1D4C5}-\\u{1D505}\\u{1D507}-\\u{1D50A}\\u{1D50D}-\\u{1D514}\\u{1D516}-\\u{1D51C}\\u{1D51E}-\\u{1D539}\\u{1D53B}-\\u{1D53E}\\u{1D540}-\\u{1D544}\\u{1D546}\\u{1D54A}-\\u{1D550}\\u{1D552}-\\u{1D6A5}\\u{1D6A8}-\\u{1D6C0}\\u{1D6C2}-\\u{1D6DA}\\u{1D6DC}-\\u{1D6FA}\\u{1D6FC}-\\u{1D714}\\u{1D716}-\\u{1D734}\\u{1D736}-\\u{1D74E}\\u{1D750}-\\u{1D76E}\\u{1D770}-\\u{1D788}\\u{1D78A}-\\u{1D7A8}\\u{1D7AA}-\\u{1D7C2}\\u{1D7C4}-\\u{1D7CB}\\u{1DF00}-\\u{1DF1E}\\u{1DF25}-\\u{1DF2A}\\u{1E030}-\\u{1E06D}\\u{1E100}-\\u{1E12C}\\u{1E137}-\\u{1E13D}\\u{1E14E}\\u{1E290}-\\u{1E2AD}\\u{1E2C0}-\\u{1E2EB}\\u{1E4D0}-\\u{1E4EB}\\u{1E5D0}-\\u{1E5ED}\\u{1E5F0}\\u{1E6C0}-\\u{1E6DE}\\u{1E6E0}-\\u{1E6E2}\\u{1E6E4}-\\u{1E6E5}\\u{1E6E7}-\\u{1E6ED}\\u{1E6F0}-\\u{1E6F4}\\u{1E6FE}-\\u{1E6FF}\\u{1E7E0}-\\u{1E7E6}\\u{1E7E8}-\\u{1E7EB}\\u{1E7ED}-\\u{1E7EE}\\u{1E7F0}-\\u{1E7FE}\\u{1E800}-\\u{1E8C4}\\u{1E900}-\\u{1E943}\\u{1E94B}\\u{1EE00}-\\u{1EE03}\\u{1EE05}-\\u{1EE1F}\\u{1EE21}-\\u{1EE22}\\u{1EE24}\\u{1EE27}\\u{1EE29}-\\u{1EE32}\\u{1EE34}-\\u{1EE37}\\u{1EE39}\\u{1EE3B}\\u{1EE42}\\u{1EE47}\\u{1EE49}\\u{1EE4B}\\u{1EE4D}-\\u{1EE4F}\\u{1EE51}-\\u{1EE52}\\u{1EE54}\\u{1EE57}\\u{1EE59}\\u{1EE5B}\\u{1EE5D}\\u{1EE5F}\\u{1EE61}-\\u{1EE62}\\u{1EE64}\\u{1EE67}-\\u{1EE6A}\\u{1EE6C}-\\u{1EE72}\\u{1EE74}-\\u{1EE77}\\u{1EE79}-\\u{1EE7C}\\u{1EE7E}\\u{1EE80}-\\u{1EE89}\\u{1EE8B}-\\u{1EE9B}\\u{1EEA1}-\\u{1EEA3}\\u{1EEA5}-\\u{1EEA9}\\u{1EEAB}-\\u{1EEBB}\\u{20000}-\\u{2A6DF}\\u{2A700}-\\u{2B81D}\\u{2B820}-\\u{2CEAD}\\u{2CEB0}-\\u{2EBE0}\\u{2EBF0}-\\u{2EE5D}\\u{2F800}-\\u{2FA1D}\\u{30000}-\\u{3134A}\\u{31350}-\\u{33479}_-]*)$", "iu");
90
+ /** The placeholders a piece of copy holds, in the order they appear. */ export function aiPlaceholderTokens(text, options = {}) {
91
+ if (!text) return [];
92
+ const found = [];
93
+ if (text.includes('{{')) {
94
+ for (const match of text.matchAll(MUSTACHE)){
95
+ var _match_index;
96
+ const inner = match[1].trim();
97
+ if (REPEAT_SLOT.test(inner)) {
98
+ var _match_index1;
99
+ found.push({
100
+ kind: 'repeat-slot',
101
+ token: match[0],
102
+ at: (_match_index1 = match.index) != null ? _match_index1 : 0
103
+ });
104
+ continue;
105
+ }
106
+ if (ID_TOKEN.test(inner) || SCOPED_TOKEN.test(inner)) continue;
107
+ if (options.mergeTokens && BARE_NAME.test(inner)) continue;
108
+ found.push({
109
+ kind: 'template-token',
110
+ token: match[0],
111
+ at: (_match_index = match.index) != null ? _match_index : 0
112
+ });
113
+ }
114
+ }
115
+ if (text.includes('[[')) {
116
+ for (const match of text.matchAll(DOUBLE_BRACKET)){
117
+ var _match_index2;
118
+ found.push({
119
+ kind: 'double-bracket',
120
+ token: match[0],
121
+ at: (_match_index2 = match.index) != null ? _match_index2 : 0
122
+ });
123
+ }
124
+ }
125
+ if (text.includes('${')) {
126
+ for (const match of text.matchAll(TEMPLATE_LITERAL)){
127
+ var _match_index3;
128
+ found.push({
129
+ kind: 'template-literal',
130
+ token: match[0],
131
+ at: (_match_index3 = match.index) != null ? _match_index3 : 0
132
+ });
133
+ }
134
+ }
135
+ if (!options.markup && text.includes('<')) {
136
+ for (const match of text.matchAll(ANGLE)){
137
+ var _match_index4;
138
+ const inner = match[1].trim();
139
+ const words = inner.split(/\s+/);
140
+ const slot = words.length > 1 ? !HTML_TAGS.has(words[0].toLowerCase()) : SLOT_WORD.test(inner);
141
+ if (slot) found.push({
142
+ kind: 'angle-slot',
143
+ token: match[0],
144
+ at: (_match_index4 = match.index) != null ? _match_index4 : 0
145
+ });
146
+ }
147
+ }
148
+ return found.sort((a, b)=>a.at - b.at).map(({ kind, token })=>({
149
+ kind,
150
+ token
151
+ }));
152
+ }
153
+ /** Whether copy holds a placeholder at all. */ export function aiHasPlaceholderToken(text, options = {}) {
154
+ return aiPlaceholderTokens(text, options).length > 0;
155
+ }
156
+ /**
157
+ * Whether copy is ONLY placeholders: with every token taken out, not one
158
+ * letter or digit is left, as in `{{1}}` or `“{{1}}” — {{2}}`. Such copy says
159
+ * nothing a reader could keep, which is what lets an item that shows only it
160
+ * be taken out without losing a word (`aiSettlePlaceholderItems`).
161
+ */ export function aiIsOnlyPlaceholders(text, options = {}) {
162
+ const tokens = aiPlaceholderTokens(text, options);
163
+ if (!tokens.length) return false;
164
+ let rest = text;
165
+ for (const { token } of tokens)rest = rest.replace(token, ' ');
166
+ return !RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376-\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E-\\u066F\\u0671-\\u06D3\\u06D5\\u06E5-\\u06E6\\u06EE-\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4-\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u0870-\\u0887\\u0889-\\u088F\\u08A0-\\u08C9\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC-\\u09DD\\u09DF-\\u09E1\\u09F0-\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32-\\u0A33\\u0A35-\\u0A36\\u0A38-\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0-\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C-\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C5C-\\u0C5D\\u0C60-\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDC-\\u0CDE\\u0CE0-\\u0CE1\\u0CF1-\\u0CF2\\u0D04-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32-\\u0E33\\u0E40-\\u0E46\\u0E81-\\u0E82\\u0E84\\u0E86-\\u0E8A\\u0E8C-\\u0EA3\\u0EA5\\u0EA7-\\u0EB0\\u0EB2-\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065-\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u1711\\u171F-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4C\\u1B83-\\u1BA0\\u1BAE-\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C8A\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF3\\u1CF5-\\u1CF6\\u1CFA\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183-\\u2184\\u2C00-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3006\\u3031-\\u3035\\u303B-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BF\\u31F0-\\u31FF\\u3400-\\u4DBF\\u4E00-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A-\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7DC\\uA7F1-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD-\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5-\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB69\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40-\\uFB41\\uFB43-\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC\\u{10000}-\\u{1000B}\\u{1000D}-\\u{10026}\\u{10028}-\\u{1003A}\\u{1003C}-\\u{1003D}\\u{1003F}-\\u{1004D}\\u{10050}-\\u{1005D}\\u{10080}-\\u{100FA}\\u{10280}-\\u{1029C}\\u{102A0}-\\u{102D0}\\u{10300}-\\u{1031F}\\u{1032D}-\\u{10340}\\u{10342}-\\u{10349}\\u{10350}-\\u{10375}\\u{10380}-\\u{1039D}\\u{103A0}-\\u{103C3}\\u{103C8}-\\u{103CF}\\u{10400}-\\u{1049D}\\u{104B0}-\\u{104D3}\\u{104D8}-\\u{104FB}\\u{10500}-\\u{10527}\\u{10530}-\\u{10563}\\u{10570}-\\u{1057A}\\u{1057C}-\\u{1058A}\\u{1058C}-\\u{10592}\\u{10594}-\\u{10595}\\u{10597}-\\u{105A1}\\u{105A3}-\\u{105B1}\\u{105B3}-\\u{105B9}\\u{105BB}-\\u{105BC}\\u{105C0}-\\u{105F3}\\u{10600}-\\u{10736}\\u{10740}-\\u{10755}\\u{10760}-\\u{10767}\\u{10780}-\\u{10785}\\u{10787}-\\u{107B0}\\u{107B2}-\\u{107BA}\\u{10800}-\\u{10805}\\u{10808}\\u{1080A}-\\u{10835}\\u{10837}-\\u{10838}\\u{1083C}\\u{1083F}-\\u{10855}\\u{10860}-\\u{10876}\\u{10880}-\\u{1089E}\\u{108E0}-\\u{108F2}\\u{108F4}-\\u{108F5}\\u{10900}-\\u{10915}\\u{10920}-\\u{10939}\\u{10940}-\\u{10959}\\u{10980}-\\u{109B7}\\u{109BE}-\\u{109BF}\\u{10A00}\\u{10A10}-\\u{10A13}\\u{10A15}-\\u{10A17}\\u{10A19}-\\u{10A35}\\u{10A60}-\\u{10A7C}\\u{10A80}-\\u{10A9C}\\u{10AC0}-\\u{10AC7}\\u{10AC9}-\\u{10AE4}\\u{10B00}-\\u{10B35}\\u{10B40}-\\u{10B55}\\u{10B60}-\\u{10B72}\\u{10B80}-\\u{10B91}\\u{10C00}-\\u{10C48}\\u{10C80}-\\u{10CB2}\\u{10CC0}-\\u{10CF2}\\u{10D00}-\\u{10D23}\\u{10D4A}-\\u{10D65}\\u{10D6F}-\\u{10D85}\\u{10E80}-\\u{10EA9}\\u{10EB0}-\\u{10EB1}\\u{10EC2}-\\u{10EC7}\\u{10F00}-\\u{10F1C}\\u{10F27}\\u{10F30}-\\u{10F45}\\u{10F70}-\\u{10F81}\\u{10FB0}-\\u{10FC4}\\u{10FE0}-\\u{10FF6}\\u{11003}-\\u{11037}\\u{11071}-\\u{11072}\\u{11075}\\u{11083}-\\u{110AF}\\u{110D0}-\\u{110E8}\\u{11103}-\\u{11126}\\u{11144}\\u{11147}\\u{11150}-\\u{11172}\\u{11176}\\u{11183}-\\u{111B2}\\u{111C1}-\\u{111C4}\\u{111DA}\\u{111DC}\\u{11200}-\\u{11211}\\u{11213}-\\u{1122B}\\u{1123F}-\\u{11240}\\u{11280}-\\u{11286}\\u{11288}\\u{1128A}-\\u{1128D}\\u{1128F}-\\u{1129D}\\u{1129F}-\\u{112A8}\\u{112B0}-\\u{112DE}\\u{11305}-\\u{1130C}\\u{1130F}-\\u{11310}\\u{11313}-\\u{11328}\\u{1132A}-\\u{11330}\\u{11332}-\\u{11333}\\u{11335}-\\u{11339}\\u{1133D}\\u{11350}\\u{1135D}-\\u{11361}\\u{11380}-\\u{11389}\\u{1138B}\\u{1138E}\\u{11390}-\\u{113B5}\\u{113B7}\\u{113D1}\\u{113D3}\\u{11400}-\\u{11434}\\u{11447}-\\u{1144A}\\u{1145F}-\\u{11461}\\u{11480}-\\u{114AF}\\u{114C4}-\\u{114C5}\\u{114C7}\\u{11580}-\\u{115AE}\\u{115D8}-\\u{115DB}\\u{11600}-\\u{1162F}\\u{11644}\\u{11680}-\\u{116AA}\\u{116B8}\\u{11700}-\\u{1171A}\\u{11740}-\\u{11746}\\u{11800}-\\u{1182B}\\u{118A0}-\\u{118DF}\\u{118FF}-\\u{11906}\\u{11909}\\u{1190C}-\\u{11913}\\u{11915}-\\u{11916}\\u{11918}-\\u{1192F}\\u{1193F}\\u{11941}\\u{119A0}-\\u{119A7}\\u{119AA}-\\u{119D0}\\u{119E1}\\u{119E3}\\u{11A00}\\u{11A0B}-\\u{11A32}\\u{11A3A}\\u{11A50}\\u{11A5C}-\\u{11A89}\\u{11A9D}\\u{11AB0}-\\u{11AF8}\\u{11BC0}-\\u{11BE0}\\u{11C00}-\\u{11C08}\\u{11C0A}-\\u{11C2E}\\u{11C40}\\u{11C72}-\\u{11C8F}\\u{11D00}-\\u{11D06}\\u{11D08}-\\u{11D09}\\u{11D0B}-\\u{11D30}\\u{11D46}\\u{11D60}-\\u{11D65}\\u{11D67}-\\u{11D68}\\u{11D6A}-\\u{11D89}\\u{11D98}\\u{11DB0}-\\u{11DDB}\\u{11EE0}-\\u{11EF2}\\u{11F02}\\u{11F04}-\\u{11F10}\\u{11F12}-\\u{11F33}\\u{11FB0}\\u{12000}-\\u{12399}\\u{12480}-\\u{12543}\\u{12F90}-\\u{12FF0}\\u{13000}-\\u{1342F}\\u{13441}-\\u{13446}\\u{13460}-\\u{143FA}\\u{14400}-\\u{14646}\\u{16100}-\\u{1611D}\\u{16800}-\\u{16A38}\\u{16A40}-\\u{16A5E}\\u{16A70}-\\u{16ABE}\\u{16AD0}-\\u{16AED}\\u{16B00}-\\u{16B2F}\\u{16B40}-\\u{16B43}\\u{16B63}-\\u{16B77}\\u{16B7D}-\\u{16B8F}\\u{16D40}-\\u{16D6C}\\u{16E40}-\\u{16E7F}\\u{16EA0}-\\u{16EB8}\\u{16EBB}-\\u{16ED3}\\u{16F00}-\\u{16F4A}\\u{16F50}\\u{16F93}-\\u{16F9F}\\u{16FE0}-\\u{16FE1}\\u{16FE3}\\u{16FF2}-\\u{16FF3}\\u{17000}-\\u{18CD5}\\u{18CFF}-\\u{18D1E}\\u{18D80}-\\u{18DF2}\\u{1AFF0}-\\u{1AFF3}\\u{1AFF5}-\\u{1AFFB}\\u{1AFFD}-\\u{1AFFE}\\u{1B000}-\\u{1B122}\\u{1B132}\\u{1B150}-\\u{1B152}\\u{1B155}\\u{1B164}-\\u{1B167}\\u{1B170}-\\u{1B2FB}\\u{1BC00}-\\u{1BC6A}\\u{1BC70}-\\u{1BC7C}\\u{1BC80}-\\u{1BC88}\\u{1BC90}-\\u{1BC99}\\u{1D400}-\\u{1D454}\\u{1D456}-\\u{1D49C}\\u{1D49E}-\\u{1D49F}\\u{1D4A2}\\u{1D4A5}-\\u{1D4A6}\\u{1D4A9}-\\u{1D4AC}\\u{1D4AE}-\\u{1D4B9}\\u{1D4BB}\\u{1D4BD}-\\u{1D4C3}\\u{1D4C5}-\\u{1D505}\\u{1D507}-\\u{1D50A}\\u{1D50D}-\\u{1D514}\\u{1D516}-\\u{1D51C}\\u{1D51E}-\\u{1D539}\\u{1D53B}-\\u{1D53E}\\u{1D540}-\\u{1D544}\\u{1D546}\\u{1D54A}-\\u{1D550}\\u{1D552}-\\u{1D6A5}\\u{1D6A8}-\\u{1D6C0}\\u{1D6C2}-\\u{1D6DA}\\u{1D6DC}-\\u{1D6FA}\\u{1D6FC}-\\u{1D714}\\u{1D716}-\\u{1D734}\\u{1D736}-\\u{1D74E}\\u{1D750}-\\u{1D76E}\\u{1D770}-\\u{1D788}\\u{1D78A}-\\u{1D7A8}\\u{1D7AA}-\\u{1D7C2}\\u{1D7C4}-\\u{1D7CB}\\u{1DF00}-\\u{1DF1E}\\u{1DF25}-\\u{1DF2A}\\u{1E030}-\\u{1E06D}\\u{1E100}-\\u{1E12C}\\u{1E137}-\\u{1E13D}\\u{1E14E}\\u{1E290}-\\u{1E2AD}\\u{1E2C0}-\\u{1E2EB}\\u{1E4D0}-\\u{1E4EB}\\u{1E5D0}-\\u{1E5ED}\\u{1E5F0}\\u{1E6C0}-\\u{1E6DE}\\u{1E6E0}-\\u{1E6E2}\\u{1E6E4}-\\u{1E6E5}\\u{1E6E7}-\\u{1E6ED}\\u{1E6F0}-\\u{1E6F4}\\u{1E6FE}-\\u{1E6FF}\\u{1E7E0}-\\u{1E7E6}\\u{1E7E8}-\\u{1E7EB}\\u{1E7ED}-\\u{1E7EE}\\u{1E7F0}-\\u{1E7FE}\\u{1E800}-\\u{1E8C4}\\u{1E900}-\\u{1E943}\\u{1E94B}\\u{1EE00}-\\u{1EE03}\\u{1EE05}-\\u{1EE1F}\\u{1EE21}-\\u{1EE22}\\u{1EE24}\\u{1EE27}\\u{1EE29}-\\u{1EE32}\\u{1EE34}-\\u{1EE37}\\u{1EE39}\\u{1EE3B}\\u{1EE42}\\u{1EE47}\\u{1EE49}\\u{1EE4B}\\u{1EE4D}-\\u{1EE4F}\\u{1EE51}-\\u{1EE52}\\u{1EE54}\\u{1EE57}\\u{1EE59}\\u{1EE5B}\\u{1EE5D}\\u{1EE5F}\\u{1EE61}-\\u{1EE62}\\u{1EE64}\\u{1EE67}-\\u{1EE6A}\\u{1EE6C}-\\u{1EE72}\\u{1EE74}-\\u{1EE77}\\u{1EE79}-\\u{1EE7C}\\u{1EE7E}\\u{1EE80}-\\u{1EE89}\\u{1EE8B}-\\u{1EE9B}\\u{1EEA1}-\\u{1EEA3}\\u{1EEA5}-\\u{1EEA9}\\u{1EEAB}-\\u{1EEBB}\\u{20000}-\\u{2A6DF}\\u{2A700}-\\u{2B81D}\\u{2B820}-\\u{2CEAD}\\u{2CEB0}-\\u{2EBE0}\\u{2EBF0}-\\u{2EE5D}\\u{2F800}-\\u{2FA1D}\\u{30000}-\\u{3134A}\\u{31350}-\\u{33479}\\u0030-\\u0039\\u00B2-\\u00B3\\u00B9\\u00BC-\\u00BE\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u09F4-\\u09F9\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0B72-\\u0B77\\u0BE6-\\u0BF2\\u0C66-\\u0C6F\\u0C78-\\u0C7E\\u0CE6-\\u0CEF\\u0D58-\\u0D5E\\u0D66-\\u0D78\\u0DE6-\\u0DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F33\\u1040-\\u1049\\u1090-\\u1099\\u1369-\\u137C\\u16EE-\\u16F0\\u17E0-\\u17E9\\u17F0-\\u17F9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19DA\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\u2070\\u2074-\\u2079\\u2080-\\u2089\\u2150-\\u2182\\u2185-\\u2189\\u2460-\\u249B\\u24EA-\\u24FF\\u2776-\\u2793\\u2CFD\\u3007\\u3021-\\u3029\\u3038-\\u303A\\u3192-\\u3195\\u3220-\\u3229\\u3248-\\u324F\\u3251-\\u325F\\u3280-\\u3289\\u32B1-\\u32BF\\uA620-\\uA629\\uA6E6-\\uA6EF\\uA830-\\uA835\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19\\u{10107}-\\u{10133}\\u{10140}-\\u{10178}\\u{1018A}-\\u{1018B}\\u{102E1}-\\u{102FB}\\u{10320}-\\u{10323}\\u{10341}\\u{1034A}\\u{103D1}-\\u{103D5}\\u{104A0}-\\u{104A9}\\u{10858}-\\u{1085F}\\u{10879}-\\u{1087F}\\u{108A7}-\\u{108AF}\\u{108FB}-\\u{108FF}\\u{10916}-\\u{1091B}\\u{109BC}-\\u{109BD}\\u{109C0}-\\u{109CF}\\u{109D2}-\\u{109FF}\\u{10A40}-\\u{10A48}\\u{10A7D}-\\u{10A7E}\\u{10A9D}-\\u{10A9F}\\u{10AEB}-\\u{10AEF}\\u{10B58}-\\u{10B5F}\\u{10B78}-\\u{10B7F}\\u{10BA9}-\\u{10BAF}\\u{10CFA}-\\u{10CFF}\\u{10D30}-\\u{10D39}\\u{10D40}-\\u{10D49}\\u{10E60}-\\u{10E7E}\\u{10F1D}-\\u{10F26}\\u{10F51}-\\u{10F54}\\u{10FC5}-\\u{10FCB}\\u{11052}-\\u{1106F}\\u{110F0}-\\u{110F9}\\u{11136}-\\u{1113F}\\u{111D0}-\\u{111D9}\\u{111E1}-\\u{111F4}\\u{112F0}-\\u{112F9}\\u{11450}-\\u{11459}\\u{114D0}-\\u{114D9}\\u{11650}-\\u{11659}\\u{116C0}-\\u{116C9}\\u{116D0}-\\u{116E3}\\u{11730}-\\u{1173B}\\u{118E0}-\\u{118F2}\\u{11950}-\\u{11959}\\u{11BF0}-\\u{11BF9}\\u{11C50}-\\u{11C6C}\\u{11D50}-\\u{11D59}\\u{11DA0}-\\u{11DA9}\\u{11DE0}-\\u{11DE9}\\u{11F50}-\\u{11F59}\\u{11FC0}-\\u{11FD4}\\u{12400}-\\u{1246E}\\u{16130}-\\u{16139}\\u{16A60}-\\u{16A69}\\u{16AC0}-\\u{16AC9}\\u{16B50}-\\u{16B59}\\u{16B5B}-\\u{16B61}\\u{16D70}-\\u{16D79}\\u{16E80}-\\u{16E96}\\u{16FF4}-\\u{16FF6}\\u{1CCF0}-\\u{1CCF9}\\u{1D2C0}-\\u{1D2D3}\\u{1D2E0}-\\u{1D2F3}\\u{1D360}-\\u{1D378}\\u{1D7CE}-\\u{1D7FF}\\u{1E140}-\\u{1E149}\\u{1E2F0}-\\u{1E2F9}\\u{1E4F0}-\\u{1E4F9}\\u{1E5F1}-\\u{1E5FA}\\u{1E8C7}-\\u{1E8CF}\\u{1E950}-\\u{1E959}\\u{1EC71}-\\u{1ECAB}\\u{1ECAD}-\\u{1ECAF}\\u{1ECB1}-\\u{1ECB4}\\u{1ED01}-\\u{1ED2D}\\u{1ED2F}-\\u{1ED3D}\\u{1F100}-\\u{1F10C}\\u{1FBF0}-\\u{1FBF9}]", "u").test(rest);
167
+ }
168
+
169
+ //# sourceMappingURL=ai-placeholder-tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-placeholder-tokens.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Template placeholders in copy (AGL-3827): a slot a template or a model's\n * own scaffolding left where words belong, which a visitor would read exactly\n * as written. A live About page shipped two testimonials whose quote and name\n * were `{{1}}` and `{{2}}`, the repeated-item slots of a section written once.\n *\n * What counts as a placeholder, and what does not:\n *\n * - `{{1}}`, `{{ 2 }}`: a repeated item's slot (`ai-repeated-items.ts`). No\n * binding token is a number, so one left in copy filled nothing.\n * - `{{name}}`, `{{Customer name}}`, `{{客户}}`: anything in double braces\n * that is not a binding the platform fills. A scoped binding, such as\n * `{{item.title}}`, `{{entry.url}}`, `{{prop.heading}}` or\n * `{{contact.firstName}}`, and an id token, `{{var:…}}` or `{{fn:…(…)}}`,\n * are the platform's own and are left to the checks that own them. A bare\n * `{{name}}` would bind a site variable of that name, and a generator is\n * shown none, so in a generated page it is a slot; an email's step owns\n * its merge tokens, bare spellings included (`ai-job-email-step.ts`).\n * - `[[Customer name]]`, `${name}`: a template's slot in another syntax.\n * - `<Your business name>`, `<placeholder>`: words in angle brackets that are\n * no HTML tag. Several words whose first is not a tag name, or one word a\n * slot is named by. `Press <Enter>`, `x < y`, `<3` and markup are copy.\n *\n * NOT a placeholder: a fact the brief never gave, in single square brackets,\n * such as `[Office phone number]`. That is the honest marker rule 14 asks for\n * instead of an invented fact, and each draft's note lists them for the\n * member to fill (AGL-3056). Nor `[sic]`, a Markdown link, a price, or Lorem\n * ipsum, which rule 14's filler check already refuses.\n *\n * Pure text in, tokens out: no tree, no palette, so any check may read it.\n */\n\nexport type AiPlaceholderKind = 'repeat-slot' | 'template-token' | 'double-bracket' | 'template-literal' | 'angle-slot'\n\nexport interface AiPlaceholderToken {\n kind: AiPlaceholderKind\n /** The token as the copy spells it. */\n token: string\n}\n\nexport interface AiPlaceholderOptions {\n /** The text is markup (an HTML or CSS field), where angle brackets are syntax. */\n markup?: boolean\n /** The output's own step owns its bare merge tokens, as an email's does. */\n mergeTokens?: boolean\n}\n\n/** Anything in double braces, on one line. */\nconst MUSTACHE = /\\{\\{\\s*([^{}\\n]{0,80}?)\\s*\\}\\}/g\nconst REPEAT_SLOT = /^\\d+$/\n/** `{{var:id}}` and `{{fn:name(args)}}`, the binding grammar's id tokens (`binding-tokens.ts`). */\nconst ID_TOKEN = /^(?:var|fn):/\n/** A scoped binding: `item.title`, `entry.cover.url`, `contact.firstName`. */\nconst SCOPED_TOKEN = /^[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)+$/\n/** A legacy `{{name}}` token's name (`NAME_TOKEN_PATTERN`). */\nconst BARE_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,39}$/\nconst DOUBLE_BRACKET = /\\[\\[\\s*[^[\\]\\n]{1,80}?\\s*\\]\\]/g\nconst TEMPLATE_LITERAL = /\\$\\{\\s*[A-Za-z_][\\w.]{0,40}\\s*\\}/g\n/** Words in angle brackets: a letter first, no attribute, path or quote inside. */\nconst ANGLE = /<(\\p{L}[^<>{}[\\]=/\"':;@\\n]{0,60}?)>/gu\n/** Elements copy may carry inline, whose tag an angle slot never starts with. */\nconst HTML_TAGS = new Set([\n 'a', 'abbr', 'b', 'br', 'cite', 'code', 'del', 'div', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'hr', 'i', 'img', 'ins', 'kbd', 'li', 'mark', 'ol', 'p', 'q', 's', 'small', 'span', 'strong',\n 'sub', 'sup', 'u', 'ul',\n])\n/** One word in angle brackets that names a slot rather than a key or a tag. */\nconst SLOT_WORD =\n /^(?:placeholder|insert|tbd|todo|name|title|text|copy|value|company|business|city|phone|email|address|date|price|quote|author|your[\\p{L}_-]*)$/iu\n\n/** The placeholders a piece of copy holds, in the order they appear. */\nexport function aiPlaceholderTokens(text: string, options: AiPlaceholderOptions = {}): AiPlaceholderToken[] {\n if (!text) return []\n const found: Array<AiPlaceholderToken & { at: number }> = []\n if (text.includes('{{')) {\n for (const match of text.matchAll(MUSTACHE)) {\n const inner = match[1].trim()\n if (REPEAT_SLOT.test(inner)) {\n found.push({ kind: 'repeat-slot', token: match[0], at: match.index ?? 0 })\n continue\n }\n if (ID_TOKEN.test(inner) || SCOPED_TOKEN.test(inner)) continue\n if (options.mergeTokens && BARE_NAME.test(inner)) continue\n found.push({ kind: 'template-token', token: match[0], at: match.index ?? 0 })\n }\n }\n if (text.includes('[[')) {\n for (const match of text.matchAll(DOUBLE_BRACKET)) {\n found.push({ kind: 'double-bracket', token: match[0], at: match.index ?? 0 })\n }\n }\n if (text.includes('${')) {\n for (const match of text.matchAll(TEMPLATE_LITERAL)) {\n found.push({ kind: 'template-literal', token: match[0], at: match.index ?? 0 })\n }\n }\n if (!options.markup && text.includes('<')) {\n for (const match of text.matchAll(ANGLE)) {\n const inner = match[1].trim()\n const words = inner.split(/\\s+/)\n const slot = words.length > 1 ? !HTML_TAGS.has(words[0].toLowerCase()) : SLOT_WORD.test(inner)\n if (slot) found.push({ kind: 'angle-slot', token: match[0], at: match.index ?? 0 })\n }\n }\n return found.sort((a, b) => a.at - b.at).map(({ kind, token }) => ({ kind, token }))\n}\n\n/** Whether copy holds a placeholder at all. */\nexport function aiHasPlaceholderToken(text: string, options: AiPlaceholderOptions = {}): boolean {\n return aiPlaceholderTokens(text, options).length > 0\n}\n\n/**\n * Whether copy is ONLY placeholders: with every token taken out, not one\n * letter or digit is left, as in `{{1}}` or `“{{1}}” — {{2}}`. Such copy says\n * nothing a reader could keep, which is what lets an item that shows only it\n * be taken out without losing a word (`aiSettlePlaceholderItems`).\n */\nexport function aiIsOnlyPlaceholders(text: string, options: AiPlaceholderOptions = {}): boolean {\n const tokens = aiPlaceholderTokens(text, options)\n if (!tokens.length) return false\n let rest = text\n for (const { token } of tokens) rest = rest.replace(token, ' ')\n return !/[\\p{L}\\p{N}]/u.test(rest)\n}\n"],"names":["MUSTACHE","REPEAT_SLOT","ID_TOKEN","SCOPED_TOKEN","BARE_NAME","DOUBLE_BRACKET","TEMPLATE_LITERAL","ANGLE","HTML_TAGS","Set","SLOT_WORD","aiPlaceholderTokens","text","options","found","includes","match","matchAll","inner","trim","test","push","kind","token","at","index","mergeTokens","markup","words","split","slot","length","has","toLowerCase","sort","a","b","map","aiHasPlaceholderToken","aiIsOnlyPlaceholders","tokens","rest","replace"],"mappings":"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"}
@@ -226,7 +226,6 @@ function childIds(node) {
226
226
  ]
227
227
  };
228
228
  }
229
- if (!marked.length) return unchanged;
230
229
  }
231
230
  const ancestorsOf = (id)=>{
232
231
  const out = [];
@@ -361,7 +360,11 @@ function childIds(node) {
361
360
  copies
362
361
  });
363
362
  }
364
- // A placeholder in no repeated item has no copy to take a value from.
363
+ // A placeholder in no repeated item has no copy to take a value from, on
364
+ // every workspace: one that keeps reusable components is told the same
365
+ // placeholders for an item of instances (AGL-3024), and a live About page
366
+ // whose testimonials kept them and no "repeat" showed `{{1}}` and `{{2}}`
367
+ // to its visitors (AGL-3827).
365
368
  for (const id of order){
366
369
  if (inItem.has(id)) continue;
367
370
  const positions = nodePositions(nodeOf(id));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-repeated-items.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { REUSABLE_INSTANCE_COMPONENT_ID } from '@aglyn/aglyn/app-utils/reusable-component-keys'\nimport { AI_TYPED_LIST_MIN_ITEMS, type AiDoctrineViolation } from './ai-doctrine-validators'\n\n/**\n * A repeated item written once (AGL-3053).\n *\n * A workspace that keeps no reusable components can place no instance, so a\n * row of cards is drawn card by card. Written out in a model's answer, every\n * card repeats its whole subtree — the Card, its body, its heading and its\n * text, each node's JSON escaped inside the tool call — and four practice\n * areas with real copy run past a section pass's answer ceiling. So on such a\n * workspace an answer writes the item ONCE and lists what differs between its\n * copies, and this module draws the copies before any check reads the answer:\n *\n * ```json\n * \"card\": { \"componentId\": \"muiCard\", \"nodes\": [\"body\"],\n * \"repeat\": [[\"Estate planning\", \"Wills and trusts…\"],\n * [\"Real estate\", \"Closings and title…\"]] },\n * \"title\": { \"componentId\": \"muiTypography\", \"props\": { \"children\": \"{{1}}\" } },\n * \"text\": { \"componentId\": \"muiTypography\", \"props\": { \"children\": \"{{2}}\" } }\n * ```\n *\n * `repeat` holds one list of values a copy, and `{{n}}` stands for a copy's\n * n-th value wherever it appears in the item's props or styles.\n *\n * A workspace that DOES keep reusable components writes the same shape around\n * an instance (AGL-3024): one `reusableInstance` inside the repeated item,\n * `{{n}}` through the values it fills, and one list of values a copy. Six\n * cards written out as six instances spend their structure six times and run\n * past the ceiling a pass answers within; written once they spend it once, and\n * the section stays ONE section with one heading, which is what a page's\n * outline and its search ranking are built on. The item still places the\n * component — rule 1 is untouched — and an item that places none is refused\n * here exactly as before.\n *\n * - **Positional, because it is the smallest list a copy can be.** Each value\n * costs its quotes and a comma. A named value repeats its name on every\n * copy, and a list of columns keeps a copy's values apart from each other.\n * - **Numbered, because no binding token is a number.** A site variable's\n * `{{name}}` starts with a letter, and a component's `{{prop.name}}`, a\n * template's `{{entry.field}}` and a function's `{{fn:…}}` carry a dot or a\n * colon (`binding-tokens.ts`), so copy that binds one keeps its token, and\n * nothing a placeholder leaves behind can bind.\n *\n * The copies are the item cloned in order, in its place under its parent. The\n * first keeps the ids the model wrote, and copy `n` takes `<id>~<n>` on every\n * node of the subtree, so one answer always draws one tree and every id a copy\n * took leads back to the node the model wrote (`sourceIds`). The drawn tree is\n * what every check reads and what a page stores: nothing downstream sees\n * `repeat` or a placeholder.\n *\n * Refused, each with a sentence a re-ask can act on and the model's own nodes\n * named: `repeat` on an item that places no instance where the workspace keeps\n * reusable components (rule 1: place a component's instances), on the document\n * wrapper or what it holds\n * directly, or inside another repeated item; a list that is not one list of\n * values a copy; fewer than 2 copies or more than `AI_REPEAT_MAX_COPIES`; a\n * placeholder a copy gives no value for, or one outside every repeated item; a\n * value no placeholder uses; and a copy's id that the answer already gives\n * another node. Pure: no provider and no Firestore.\n */\n\n/** The key a repeated item's node lists its copies' values under. */\nexport const AI_REPEAT_KEY = 'repeat'\n\n/**\n * The most copies one item may list: a list of `AI_TYPED_LIST_MIN_ITEMS` or\n * more typed into a page is data (rule 8), which a plan binds or shortens.\n */\nexport const AI_REPEAT_MAX_COPIES = AI_TYPED_LIST_MIN_ITEMS - 1\n\n/** A copy's `n`-th value, by its 1-based position. */\nconst PLACEHOLDER = /\\{\\{\\s*(\\d+)\\s*\\}\\}/g\n\n/** A string that is one placeholder and nothing else, whose value keeps its own type. */\nconst WHOLE_PLACEHOLDER = /^\\s*\\{\\{\\s*(\\d+)\\s*\\}\\}\\s*$/\n\n/** What a list of copies looks like, in every sentence that asks for one. */\nconst EXAMPLE = '[[\"Title 1\", \"Text 1\"], [\"Title 2\", \"Text 2\"]]'\n\nexport interface AiRepeatedItemsOptions {\n /** The workspace keeps no reusable components: the one place an item is written once. */\n inline: boolean\n /** What the answer is, as a person reads a refusal: `section`, `page`. */\n noun: string\n}\n\nexport type AiRepeatedItemsResult =\n | {\n ok: true\n /** The answer with every repeated item drawn into its copies; the answer itself when none is. */\n tree: unknown\n /** Each id a copy took → the id the model wrote for that node. */\n sourceIds: Record<string, string>\n /** How many items were written once. */\n items: number\n }\n | { ok: false; violations: AiDoctrineViolation[] }\n\ntype RawNode = Record<string, unknown>\ntype Scalar = string | number | boolean\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isScalar(value: unknown): value is Scalar {\n return (\n typeof value === 'string' || typeof value === 'boolean' || (typeof value === 'number' && Number.isFinite(value))\n )\n}\n\nfunction childIds(node: RawNode | undefined): string[] {\n const children = node?.['nodes']\n return Array.isArray(children) ? children.filter((id): id is string => typeof id === 'string') : []\n}\n\n/** Every placeholder position a value uses, however deep in props or styles. */\nfunction positionsIn(value: unknown, into: Set<number>): Set<number> {\n if (typeof value === 'string') {\n for (const match of value.matchAll(PLACEHOLDER)) into.add(Number(match[1]))\n } else if (Array.isArray(value)) {\n for (const inner of value) positionsIn(inner, into)\n } else if (isRecord(value)) {\n for (const inner of Object.values(value)) positionsIn(inner, into)\n }\n return into\n}\n\n/** The positions one node's props and styles use. */\nfunction nodePositions(node: RawNode): Set<number> {\n return positionsIn(node['sx'], positionsIn(node['props'], new Set()))\n}\n\n/** A value with every placeholder filled from one copy's values. */\nfunction fill(value: unknown, values: readonly Scalar[]): unknown {\n if (typeof value === 'string') {\n const whole = WHOLE_PLACEHOLDER.exec(value)\n if (whole) return values[Number(whole[1]) - 1]\n return value.replace(PLACEHOLDER, (_token, position: string) => String(values[Number(position) - 1]))\n }\n if (Array.isArray(value)) return value.map((inner) => fill(inner, values))\n if (isRecord(value)) {\n return Object.fromEntries(Object.entries(value).map(([key, inner]) => [key, fill(inner, values)]))\n }\n return value\n}\n\n/** 1 → first, 2 → second, 12 → 12th. */\nfunction ordinal(position: number): string {\n const word = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh'][position - 1]\n if (word) return word\n const tens = position % 100\n const suffix = tens >= 11 && tens <= 13 ? 'th' : (['th', 'st', 'nd', 'rd'][position % 10] ?? 'th')\n return `${position}${suffix}`\n}\n\n/** `{{1}}`, `{{1}} and {{2}}`, `{{1}}, {{2}} and {{3}}`. */\nfunction placeholders(positions: Iterable<number>): string {\n const list = [...positions].sort((a, b) => a - b).map((position) => `{{${position}}}`)\n return list.length <= 1 ? list.join('') : `${list.slice(0, -1).join(', ')} and ${list[list.length - 1]}`\n}\n\n/**\n * The answer with every repeated item drawn into its copies, or the reasons it\n * cannot be. An answer that is not a node map, or that writes nothing once, is\n * handed back as it came, for the palette validator to read as it always has.\n */\nexport function expandAiRepeatedItems(input: unknown, options: AiRepeatedItemsOptions): AiRepeatedItemsResult {\n const unchanged: AiRepeatedItemsResult = { ok: true, tree: input, sourceIds: {}, items: 0 }\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return unchanged\n const rootId = input['rootId']\n const nodes = input['nodes'] as Record<string, unknown>\n const nodeOf = (id: string): RawNode | undefined => {\n const node = nodes[id]\n return isRecord(node) ? node : undefined\n }\n\n // The walk the palette validator makes: breadth first from the root, each\n // node under the first parent that lists it.\n const parentOf = new Map<string, string | null>([[rootId, null]])\n const order: string[] = []\n const queue = [rootId]\n for (let index = 0; index < queue.length; index += 1) {\n const id = queue[index]\n if (!nodeOf(id)) continue\n order.push(id)\n for (const child of childIds(nodeOf(id))) {\n if (parentOf.has(child)) continue\n parentOf.set(child, id)\n queue.push(child)\n }\n }\n const marked = order.filter((id) => Object.prototype.hasOwnProperty.call(nodeOf(id), AI_REPEAT_KEY))\n\n /** A node and everything under it, each node once. */\n const subtreeOf = (id: string): string[] => {\n const seen = new Set<string>()\n const stack = [id]\n const out: string[] = []\n while (stack.length) {\n const next = stack.pop() as string\n if (seen.has(next) || !nodeOf(next)) continue\n seen.add(next)\n out.push(next)\n stack.push(...childIds(nodeOf(next)).reverse())\n }\n return out\n }\n\n // Where the workspace keeps reusable components, writing an item once is how\n // an answer places MANY instances inside one ceiling (AGL-3024), not a way\n // around placing them: an item that places an instance is drawn into its\n // copies exactly as a Free one is, and one that places none is still drawing\n // by hand a component the site has, which rule 1 refuses as it always did.\n if (!options.inline) {\n const byHand = marked.filter(\n (id) => !subtreeOf(id).some((node) => nodeOf(node)?.['componentId'] === REUSABLE_INSTANCE_COMPONENT_ID),\n )\n if (byHand.length) {\n return {\n ok: false,\n violations: [\n {\n rule: 1,\n code: 'repeat-not-inline',\n message: 'This draws a repeated item to be copied, instead of placing it as instances of a component.',\n detail: `Put one instance of a component the site has (componentId \"reusableInstance\") inside the repeated item, or remove \"${AI_REPEAT_KEY}\" and place each copy as an instance.`,\n nodeIds: byHand,\n },\n ],\n }\n }\n if (!marked.length) return unchanged\n }\n const ancestorsOf = (id: string): string[] => {\n const out: string[] = []\n for (let parent = parentOf.get(id); parent; parent = parentOf.get(parent)) out.push(parent)\n return out\n }\n\n const violations: AiDoctrineViolation[] = []\n const refuse = (code: string, detail: string, nodeIds: string[]) => {\n violations.push({\n rule: null,\n code,\n message: `The answer could not be used as a ${options.noun}.`,\n detail,\n nodeIds: [...new Set(nodeIds)],\n })\n }\n const inItem = new Set(marked.flatMap(subtreeOf))\n const topLevel = new Set([rootId, ...childIds(nodeOf(rootId))])\n const taken = new Set(Object.keys(nodes))\n const items: Array<{ id: string; parent: string; subtree: string[]; copies: Scalar[][] }> = []\n\n for (const id of marked) {\n const outer = ancestorsOf(id).find((ancestor) => marked.includes(ancestor))\n if (outer) {\n refuse(\n 'repeat-nested',\n `\"${id}\" has \"${AI_REPEAT_KEY}\" inside \"${outer}\", which repeats already: keep \"${AI_REPEAT_KEY}\" on \"${outer}\" alone, and write what repeats inside it out in full.`,\n [id, outer],\n )\n continue\n }\n if (topLevel.has(id)) {\n refuse(\n 'repeat-on-section',\n `\"${id}\" is the document wrapper or what it holds directly, and never repeats: put \"${AI_REPEAT_KEY}\" on the item that repeats inside the ${options.noun}.`,\n [id],\n )\n continue\n }\n const list = nodeOf(id)?.[AI_REPEAT_KEY]\n if (!Array.isArray(list)) {\n refuse(\n 'repeat-shape',\n `\"${AI_REPEAT_KEY}\" on \"${id}\" is not a list of copies: give it one list of values for each copy, such as ${EXAMPLE}.`,\n [id],\n )\n continue\n }\n // A copy of one value may be the value itself.\n const listed = list.map((copy: unknown) => (isScalar(copy) ? [copy] : copy))\n const malformed = listed.findIndex((copy) => !Array.isArray(copy) || !copy.every(isScalar))\n if (malformed !== -1) {\n refuse(\n 'repeat-shape',\n `The ${ordinal(malformed + 1)} copy of \"${id}\" is not a list of text values: give each copy one list, such as ${EXAMPLE}.`,\n [id],\n )\n continue\n }\n const copies = listed as Scalar[][]\n if (copies.length < 2 || copies.length > AI_REPEAT_MAX_COPIES) {\n refuse(\n 'repeat-count',\n `\"${AI_REPEAT_KEY}\" on \"${id}\" lists ${copies.length} ${copies.length === 1 ? 'copy' : 'copies'}: list from 2 to ${AI_REPEAT_MAX_COPIES}, and write an item that appears once without \"${AI_REPEAT_KEY}\".`,\n [id],\n )\n continue\n }\n const subtree = subtreeOf(id)\n const users = new Map<number, string[]>()\n for (const node of subtree) {\n for (const position of nodePositions(nodeOf(node) as RawNode)) {\n users.set(position, [...(users.get(position) ?? []), node])\n }\n }\n const used = [...users.keys()].sort((a, b) => a - b)\n const highest = used.length ? used[used.length - 1] : 0\n if (users.has(0)) {\n refuse(\n 'repeat-placeholder-without-value',\n `\"${(users.get(0) as string[])[0]}\" uses {{0}}, and a copy's values count from {{1}}: write {{1}} for each copy's first value.`,\n [id, ...(users.get(0) as string[])],\n )\n continue\n }\n const gap = used.findIndex((position, index) => position !== index + 1) + 1\n if (gap > 0) {\n refuse(\n 'repeat-value-without-placeholder',\n `\"${id}\" uses ${placeholders(used)} and no {{${gap}}}, so each copy's ${ordinal(gap)} value fills nothing: number the placeholders from {{1}} with no gap.`,\n [id],\n )\n continue\n }\n const short = copies.findIndex((copy) => copy.length < highest)\n if (short !== -1) {\n const unfilled = used.filter((position) => position > copies[short].length)\n refuse(\n 'repeat-placeholder-without-value',\n `The ${ordinal(short + 1)} copy of \"${id}\" gives ${copies[short].length} ${copies[short].length === 1 ? 'value' : 'values'}, and the item uses ${placeholders(used)}: give every copy one value for each placeholder, in order.`,\n [id, ...unfilled.flatMap((position) => users.get(position) ?? [])],\n )\n continue\n }\n const long = copies.findIndex((copy) => copy.length > highest)\n if (long !== -1) {\n refuse(\n 'repeat-value-without-placeholder',\n highest\n ? `The ${ordinal(long + 1)} copy of \"${id}\" gives ${copies[long].length} values, and the item uses only ${placeholders(used)}: give every copy one value for each placeholder, in order.`\n : `\"${id}\" lists values and uses no placeholder for them: write {{1}}, {{2}} and on where its copies differ, each copy's values in that order.`,\n [id],\n )\n continue\n }\n const collision = subtree\n .flatMap((node) => copies.slice(1).map((_values, index) => ({ node, copy: index + 2 })))\n .find(({ node, copy }) => taken.has(`${node}~${copy}`))\n if (collision) {\n const clash = `${collision.node}~${collision.copy}`\n refuse(\n 'repeat-id-collision',\n `The ${ordinal(collision.copy)} copy of \"${collision.node}\" takes the id \"${clash}\", which the answer already gives another node: rename \"${clash}\".`,\n [id, clash],\n )\n continue\n }\n for (const node of subtree) copies.slice(1).forEach((_values, index) => taken.add(`${node}~${index + 2}`))\n items.push({ id, parent: parentOf.get(id) as string, subtree, copies })\n }\n\n // A placeholder in no repeated item has no copy to take a value from.\n for (const id of order) {\n if (inItem.has(id)) continue\n const positions = nodePositions(nodeOf(id) as RawNode)\n if (!positions.size) continue\n refuse(\n 'repeat-placeholder-without-value',\n `\"${id}\" uses ${placeholders(positions)} and sits in no item with \"${AI_REPEAT_KEY}\": write its text out, or put \"${AI_REPEAT_KEY}\" on the item it repeats in.`,\n [id],\n )\n }\n\n if (violations.length) return { ok: false, violations }\n if (!items.length) return unchanged\n\n const drawn: Record<string, unknown> = { ...nodes }\n const sourceIds: Record<string, string> = {}\n for (const item of items) {\n const members = new Set(item.subtree)\n const idIn = (node: string, copy: number) => (copy === 1 || !members.has(node) ? node : `${node}~${copy}`)\n item.copies.forEach((values, index) => {\n const copy = index + 1\n for (const node of item.subtree) {\n const source = nodeOf(node) as RawNode\n const clone: RawNode = { ...source }\n delete clone[AI_REPEAT_KEY]\n if (source['props'] !== undefined) clone['props'] = fill(source['props'], values)\n if (source['sx'] !== undefined) clone['sx'] = fill(source['sx'], values)\n if (Array.isArray(source['nodes'])) {\n clone['nodes'] = source['nodes'].map((child: unknown) => (typeof child === 'string' ? idIn(child, copy) : child))\n }\n if (node !== item.id && typeof source['parentId'] === 'string') clone['parentId'] = idIn(source['parentId'], copy)\n const id = idIn(node, copy)\n drawn[id] = clone\n if (copy > 1) sourceIds[id] = node\n }\n })\n // Every copy in the item's place, in order: the parent as drawn so far,\n // which an item beside this one may already have drawn into.\n const parent = drawn[item.parent] as RawNode\n const siblings = Array.isArray(parent['nodes']) ? [...parent['nodes']] : []\n siblings.splice(siblings.indexOf(item.id), 1, ...item.copies.map((_values, index) => idIn(item.id, index + 1)))\n drawn[item.parent] = { ...parent, nodes: siblings }\n }\n return { ok: true, tree: { ...input, nodes: drawn }, sourceIds, items: items.length }\n}\n"],"names":["REUSABLE_INSTANCE_COMPONENT_ID","AI_TYPED_LIST_MIN_ITEMS","AI_REPEAT_KEY","AI_REPEAT_MAX_COPIES","PLACEHOLDER","WHOLE_PLACEHOLDER","EXAMPLE","isRecord","value","Array","isArray","isScalar","Number","isFinite","childIds","node","children","filter","id","positionsIn","into","match","matchAll","add","inner","Object","values","nodePositions","Set","fill","whole","exec","replace","_token","position","String","map","fromEntries","entries","key","ordinal","word","tens","suffix","placeholders","positions","list","sort","a","b","length","join","slice","expandAiRepeatedItems","input","options","unchanged","ok","tree","sourceIds","items","rootId","nodes","nodeOf","undefined","parentOf","Map","order","queue","index","push","child","has","set","marked","prototype","hasOwnProperty","call","subtreeOf","seen","stack","out","next","pop","reverse","inline","byHand","some","violations","rule","code","message","detail","nodeIds","ancestorsOf","parent","get","refuse","noun","inItem","flatMap","topLevel","taken","keys","outer","find","ancestor","includes","listed","copy","malformed","findIndex","every","copies","subtree","users","used","highest","gap","short","unfilled","long","collision","_values","clash","forEach","size","drawn","item","members","idIn","source","clone","siblings","splice","indexOf"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-repeated-items.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { REUSABLE_INSTANCE_COMPONENT_ID } from '@aglyn/aglyn/app-utils/reusable-component-keys'\nimport { AI_TYPED_LIST_MIN_ITEMS, type AiDoctrineViolation } from './ai-doctrine-validators'\n\n/**\n * A repeated item written once (AGL-3053).\n *\n * A workspace that keeps no reusable components can place no instance, so a\n * row of cards is drawn card by card. Written out in a model's answer, every\n * card repeats its whole subtree — the Card, its body, its heading and its\n * text, each node's JSON escaped inside the tool call — and four practice\n * areas with real copy run past a section pass's answer ceiling. So on such a\n * workspace an answer writes the item ONCE and lists what differs between its\n * copies, and this module draws the copies before any check reads the answer:\n *\n * ```json\n * \"card\": { \"componentId\": \"muiCard\", \"nodes\": [\"body\"],\n * \"repeat\": [[\"Estate planning\", \"Wills and trusts…\"],\n * [\"Real estate\", \"Closings and title…\"]] },\n * \"title\": { \"componentId\": \"muiTypography\", \"props\": { \"children\": \"{{1}}\" } },\n * \"text\": { \"componentId\": \"muiTypography\", \"props\": { \"children\": \"{{2}}\" } }\n * ```\n *\n * `repeat` holds one list of values a copy, and `{{n}}` stands for a copy's\n * n-th value wherever it appears in the item's props or styles.\n *\n * A workspace that DOES keep reusable components writes the same shape around\n * an instance (AGL-3024): one `reusableInstance` inside the repeated item,\n * `{{n}}` through the values it fills, and one list of values a copy. Six\n * cards written out as six instances spend their structure six times and run\n * past the ceiling a pass answers within; written once they spend it once, and\n * the section stays ONE section with one heading, which is what a page's\n * outline and its search ranking are built on. The item still places the\n * component — rule 1 is untouched — and an item that places none is refused\n * here exactly as before.\n *\n * - **Positional, because it is the smallest list a copy can be.** Each value\n * costs its quotes and a comma. A named value repeats its name on every\n * copy, and a list of columns keeps a copy's values apart from each other.\n * - **Numbered, because no binding token is a number.** A site variable's\n * `{{name}}` starts with a letter, and a component's `{{prop.name}}`, a\n * template's `{{entry.field}}` and a function's `{{fn:…}}` carry a dot or a\n * colon (`binding-tokens.ts`), so copy that binds one keeps its token, and\n * nothing a placeholder leaves behind can bind.\n *\n * The copies are the item cloned in order, in its place under its parent. The\n * first keeps the ids the model wrote, and copy `n` takes `<id>~<n>` on every\n * node of the subtree, so one answer always draws one tree and every id a copy\n * took leads back to the node the model wrote (`sourceIds`). The drawn tree is\n * what every check reads and what a page stores: nothing downstream sees\n * `repeat` or a placeholder.\n *\n * Refused, each with a sentence a re-ask can act on and the model's own nodes\n * named: `repeat` on an item that places no instance where the workspace keeps\n * reusable components (rule 1: place a component's instances), on the document\n * wrapper or what it holds\n * directly, or inside another repeated item; a list that is not one list of\n * values a copy; fewer than 2 copies or more than `AI_REPEAT_MAX_COPIES`; a\n * placeholder a copy gives no value for, or one outside every repeated item; a\n * value no placeholder uses; and a copy's id that the answer already gives\n * another node. Pure: no provider and no Firestore.\n */\n\n/** The key a repeated item's node lists its copies' values under. */\nexport const AI_REPEAT_KEY = 'repeat'\n\n/**\n * The most copies one item may list: a list of `AI_TYPED_LIST_MIN_ITEMS` or\n * more typed into a page is data (rule 8), which a plan binds or shortens.\n */\nexport const AI_REPEAT_MAX_COPIES = AI_TYPED_LIST_MIN_ITEMS - 1\n\n/** A copy's `n`-th value, by its 1-based position. */\nconst PLACEHOLDER = /\\{\\{\\s*(\\d+)\\s*\\}\\}/g\n\n/** A string that is one placeholder and nothing else, whose value keeps its own type. */\nconst WHOLE_PLACEHOLDER = /^\\s*\\{\\{\\s*(\\d+)\\s*\\}\\}\\s*$/\n\n/** What a list of copies looks like, in every sentence that asks for one. */\nconst EXAMPLE = '[[\"Title 1\", \"Text 1\"], [\"Title 2\", \"Text 2\"]]'\n\nexport interface AiRepeatedItemsOptions {\n /** The workspace keeps no reusable components: the one place an item is written once. */\n inline: boolean\n /** What the answer is, as a person reads a refusal: `section`, `page`. */\n noun: string\n}\n\nexport type AiRepeatedItemsResult =\n | {\n ok: true\n /** The answer with every repeated item drawn into its copies; the answer itself when none is. */\n tree: unknown\n /** Each id a copy took → the id the model wrote for that node. */\n sourceIds: Record<string, string>\n /** How many items were written once. */\n items: number\n }\n | { ok: false; violations: AiDoctrineViolation[] }\n\ntype RawNode = Record<string, unknown>\ntype Scalar = string | number | boolean\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isScalar(value: unknown): value is Scalar {\n return (\n typeof value === 'string' || typeof value === 'boolean' || (typeof value === 'number' && Number.isFinite(value))\n )\n}\n\nfunction childIds(node: RawNode | undefined): string[] {\n const children = node?.['nodes']\n return Array.isArray(children) ? children.filter((id): id is string => typeof id === 'string') : []\n}\n\n/** Every placeholder position a value uses, however deep in props or styles. */\nfunction positionsIn(value: unknown, into: Set<number>): Set<number> {\n if (typeof value === 'string') {\n for (const match of value.matchAll(PLACEHOLDER)) into.add(Number(match[1]))\n } else if (Array.isArray(value)) {\n for (const inner of value) positionsIn(inner, into)\n } else if (isRecord(value)) {\n for (const inner of Object.values(value)) positionsIn(inner, into)\n }\n return into\n}\n\n/** The positions one node's props and styles use. */\nfunction nodePositions(node: RawNode): Set<number> {\n return positionsIn(node['sx'], positionsIn(node['props'], new Set()))\n}\n\n/** A value with every placeholder filled from one copy's values. */\nfunction fill(value: unknown, values: readonly Scalar[]): unknown {\n if (typeof value === 'string') {\n const whole = WHOLE_PLACEHOLDER.exec(value)\n if (whole) return values[Number(whole[1]) - 1]\n return value.replace(PLACEHOLDER, (_token, position: string) => String(values[Number(position) - 1]))\n }\n if (Array.isArray(value)) return value.map((inner) => fill(inner, values))\n if (isRecord(value)) {\n return Object.fromEntries(Object.entries(value).map(([key, inner]) => [key, fill(inner, values)]))\n }\n return value\n}\n\n/** 1 → first, 2 → second, 12 → 12th. */\nfunction ordinal(position: number): string {\n const word = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh'][position - 1]\n if (word) return word\n const tens = position % 100\n const suffix = tens >= 11 && tens <= 13 ? 'th' : (['th', 'st', 'nd', 'rd'][position % 10] ?? 'th')\n return `${position}${suffix}`\n}\n\n/** `{{1}}`, `{{1}} and {{2}}`, `{{1}}, {{2}} and {{3}}`. */\nfunction placeholders(positions: Iterable<number>): string {\n const list = [...positions].sort((a, b) => a - b).map((position) => `{{${position}}}`)\n return list.length <= 1 ? list.join('') : `${list.slice(0, -1).join(', ')} and ${list[list.length - 1]}`\n}\n\n/**\n * The answer with every repeated item drawn into its copies, or the reasons it\n * cannot be. An answer that is not a node map, or that writes nothing once, is\n * handed back as it came, for the palette validator to read as it always has.\n */\nexport function expandAiRepeatedItems(input: unknown, options: AiRepeatedItemsOptions): AiRepeatedItemsResult {\n const unchanged: AiRepeatedItemsResult = { ok: true, tree: input, sourceIds: {}, items: 0 }\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return unchanged\n const rootId = input['rootId']\n const nodes = input['nodes'] as Record<string, unknown>\n const nodeOf = (id: string): RawNode | undefined => {\n const node = nodes[id]\n return isRecord(node) ? node : undefined\n }\n\n // The walk the palette validator makes: breadth first from the root, each\n // node under the first parent that lists it.\n const parentOf = new Map<string, string | null>([[rootId, null]])\n const order: string[] = []\n const queue = [rootId]\n for (let index = 0; index < queue.length; index += 1) {\n const id = queue[index]\n if (!nodeOf(id)) continue\n order.push(id)\n for (const child of childIds(nodeOf(id))) {\n if (parentOf.has(child)) continue\n parentOf.set(child, id)\n queue.push(child)\n }\n }\n const marked = order.filter((id) => Object.prototype.hasOwnProperty.call(nodeOf(id), AI_REPEAT_KEY))\n\n /** A node and everything under it, each node once. */\n const subtreeOf = (id: string): string[] => {\n const seen = new Set<string>()\n const stack = [id]\n const out: string[] = []\n while (stack.length) {\n const next = stack.pop() as string\n if (seen.has(next) || !nodeOf(next)) continue\n seen.add(next)\n out.push(next)\n stack.push(...childIds(nodeOf(next)).reverse())\n }\n return out\n }\n\n // Where the workspace keeps reusable components, writing an item once is how\n // an answer places MANY instances inside one ceiling (AGL-3024), not a way\n // around placing them: an item that places an instance is drawn into its\n // copies exactly as a Free one is, and one that places none is still drawing\n // by hand a component the site has, which rule 1 refuses as it always did.\n if (!options.inline) {\n const byHand = marked.filter(\n (id) => !subtreeOf(id).some((node) => nodeOf(node)?.['componentId'] === REUSABLE_INSTANCE_COMPONENT_ID),\n )\n if (byHand.length) {\n return {\n ok: false,\n violations: [\n {\n rule: 1,\n code: 'repeat-not-inline',\n message: 'This draws a repeated item to be copied, instead of placing it as instances of a component.',\n detail: `Put one instance of a component the site has (componentId \"reusableInstance\") inside the repeated item, or remove \"${AI_REPEAT_KEY}\" and place each copy as an instance.`,\n nodeIds: byHand,\n },\n ],\n }\n }\n }\n const ancestorsOf = (id: string): string[] => {\n const out: string[] = []\n for (let parent = parentOf.get(id); parent; parent = parentOf.get(parent)) out.push(parent)\n return out\n }\n\n const violations: AiDoctrineViolation[] = []\n const refuse = (code: string, detail: string, nodeIds: string[]) => {\n violations.push({\n rule: null,\n code,\n message: `The answer could not be used as a ${options.noun}.`,\n detail,\n nodeIds: [...new Set(nodeIds)],\n })\n }\n const inItem = new Set(marked.flatMap(subtreeOf))\n const topLevel = new Set([rootId, ...childIds(nodeOf(rootId))])\n const taken = new Set(Object.keys(nodes))\n const items: Array<{ id: string; parent: string; subtree: string[]; copies: Scalar[][] }> = []\n\n for (const id of marked) {\n const outer = ancestorsOf(id).find((ancestor) => marked.includes(ancestor))\n if (outer) {\n refuse(\n 'repeat-nested',\n `\"${id}\" has \"${AI_REPEAT_KEY}\" inside \"${outer}\", which repeats already: keep \"${AI_REPEAT_KEY}\" on \"${outer}\" alone, and write what repeats inside it out in full.`,\n [id, outer],\n )\n continue\n }\n if (topLevel.has(id)) {\n refuse(\n 'repeat-on-section',\n `\"${id}\" is the document wrapper or what it holds directly, and never repeats: put \"${AI_REPEAT_KEY}\" on the item that repeats inside the ${options.noun}.`,\n [id],\n )\n continue\n }\n const list = nodeOf(id)?.[AI_REPEAT_KEY]\n if (!Array.isArray(list)) {\n refuse(\n 'repeat-shape',\n `\"${AI_REPEAT_KEY}\" on \"${id}\" is not a list of copies: give it one list of values for each copy, such as ${EXAMPLE}.`,\n [id],\n )\n continue\n }\n // A copy of one value may be the value itself.\n const listed = list.map((copy: unknown) => (isScalar(copy) ? [copy] : copy))\n const malformed = listed.findIndex((copy) => !Array.isArray(copy) || !copy.every(isScalar))\n if (malformed !== -1) {\n refuse(\n 'repeat-shape',\n `The ${ordinal(malformed + 1)} copy of \"${id}\" is not a list of text values: give each copy one list, such as ${EXAMPLE}.`,\n [id],\n )\n continue\n }\n const copies = listed as Scalar[][]\n if (copies.length < 2 || copies.length > AI_REPEAT_MAX_COPIES) {\n refuse(\n 'repeat-count',\n `\"${AI_REPEAT_KEY}\" on \"${id}\" lists ${copies.length} ${copies.length === 1 ? 'copy' : 'copies'}: list from 2 to ${AI_REPEAT_MAX_COPIES}, and write an item that appears once without \"${AI_REPEAT_KEY}\".`,\n [id],\n )\n continue\n }\n const subtree = subtreeOf(id)\n const users = new Map<number, string[]>()\n for (const node of subtree) {\n for (const position of nodePositions(nodeOf(node) as RawNode)) {\n users.set(position, [...(users.get(position) ?? []), node])\n }\n }\n const used = [...users.keys()].sort((a, b) => a - b)\n const highest = used.length ? used[used.length - 1] : 0\n if (users.has(0)) {\n refuse(\n 'repeat-placeholder-without-value',\n `\"${(users.get(0) as string[])[0]}\" uses {{0}}, and a copy's values count from {{1}}: write {{1}} for each copy's first value.`,\n [id, ...(users.get(0) as string[])],\n )\n continue\n }\n const gap = used.findIndex((position, index) => position !== index + 1) + 1\n if (gap > 0) {\n refuse(\n 'repeat-value-without-placeholder',\n `\"${id}\" uses ${placeholders(used)} and no {{${gap}}}, so each copy's ${ordinal(gap)} value fills nothing: number the placeholders from {{1}} with no gap.`,\n [id],\n )\n continue\n }\n const short = copies.findIndex((copy) => copy.length < highest)\n if (short !== -1) {\n const unfilled = used.filter((position) => position > copies[short].length)\n refuse(\n 'repeat-placeholder-without-value',\n `The ${ordinal(short + 1)} copy of \"${id}\" gives ${copies[short].length} ${copies[short].length === 1 ? 'value' : 'values'}, and the item uses ${placeholders(used)}: give every copy one value for each placeholder, in order.`,\n [id, ...unfilled.flatMap((position) => users.get(position) ?? [])],\n )\n continue\n }\n const long = copies.findIndex((copy) => copy.length > highest)\n if (long !== -1) {\n refuse(\n 'repeat-value-without-placeholder',\n highest\n ? `The ${ordinal(long + 1)} copy of \"${id}\" gives ${copies[long].length} values, and the item uses only ${placeholders(used)}: give every copy one value for each placeholder, in order.`\n : `\"${id}\" lists values and uses no placeholder for them: write {{1}}, {{2}} and on where its copies differ, each copy's values in that order.`,\n [id],\n )\n continue\n }\n const collision = subtree\n .flatMap((node) => copies.slice(1).map((_values, index) => ({ node, copy: index + 2 })))\n .find(({ node, copy }) => taken.has(`${node}~${copy}`))\n if (collision) {\n const clash = `${collision.node}~${collision.copy}`\n refuse(\n 'repeat-id-collision',\n `The ${ordinal(collision.copy)} copy of \"${collision.node}\" takes the id \"${clash}\", which the answer already gives another node: rename \"${clash}\".`,\n [id, clash],\n )\n continue\n }\n for (const node of subtree) copies.slice(1).forEach((_values, index) => taken.add(`${node}~${index + 2}`))\n items.push({ id, parent: parentOf.get(id) as string, subtree, copies })\n }\n\n // A placeholder in no repeated item has no copy to take a value from, on\n // every workspace: one that keeps reusable components is told the same\n // placeholders for an item of instances (AGL-3024), and a live About page\n // whose testimonials kept them and no \"repeat\" showed `{{1}}` and `{{2}}`\n // to its visitors (AGL-3827).\n for (const id of order) {\n if (inItem.has(id)) continue\n const positions = nodePositions(nodeOf(id) as RawNode)\n if (!positions.size) continue\n refuse(\n 'repeat-placeholder-without-value',\n `\"${id}\" uses ${placeholders(positions)} and sits in no item with \"${AI_REPEAT_KEY}\": write its text out, or put \"${AI_REPEAT_KEY}\" on the item it repeats in.`,\n [id],\n )\n }\n\n if (violations.length) return { ok: false, violations }\n if (!items.length) return unchanged\n\n const drawn: Record<string, unknown> = { ...nodes }\n const sourceIds: Record<string, string> = {}\n for (const item of items) {\n const members = new Set(item.subtree)\n const idIn = (node: string, copy: number) => (copy === 1 || !members.has(node) ? node : `${node}~${copy}`)\n item.copies.forEach((values, index) => {\n const copy = index + 1\n for (const node of item.subtree) {\n const source = nodeOf(node) as RawNode\n const clone: RawNode = { ...source }\n delete clone[AI_REPEAT_KEY]\n if (source['props'] !== undefined) clone['props'] = fill(source['props'], values)\n if (source['sx'] !== undefined) clone['sx'] = fill(source['sx'], values)\n if (Array.isArray(source['nodes'])) {\n clone['nodes'] = source['nodes'].map((child: unknown) => (typeof child === 'string' ? idIn(child, copy) : child))\n }\n if (node !== item.id && typeof source['parentId'] === 'string') clone['parentId'] = idIn(source['parentId'], copy)\n const id = idIn(node, copy)\n drawn[id] = clone\n if (copy > 1) sourceIds[id] = node\n }\n })\n // Every copy in the item's place, in order: the parent as drawn so far,\n // which an item beside this one may already have drawn into.\n const parent = drawn[item.parent] as RawNode\n const siblings = Array.isArray(parent['nodes']) ? [...parent['nodes']] : []\n siblings.splice(siblings.indexOf(item.id), 1, ...item.copies.map((_values, index) => idIn(item.id, index + 1)))\n drawn[item.parent] = { ...parent, nodes: siblings }\n }\n return { ok: true, tree: { ...input, nodes: drawn }, sourceIds, items: items.length }\n}\n"],"names":["REUSABLE_INSTANCE_COMPONENT_ID","AI_TYPED_LIST_MIN_ITEMS","AI_REPEAT_KEY","AI_REPEAT_MAX_COPIES","PLACEHOLDER","WHOLE_PLACEHOLDER","EXAMPLE","isRecord","value","Array","isArray","isScalar","Number","isFinite","childIds","node","children","filter","id","positionsIn","into","match","matchAll","add","inner","Object","values","nodePositions","Set","fill","whole","exec","replace","_token","position","String","map","fromEntries","entries","key","ordinal","word","tens","suffix","placeholders","positions","list","sort","a","b","length","join","slice","expandAiRepeatedItems","input","options","unchanged","ok","tree","sourceIds","items","rootId","nodes","nodeOf","undefined","parentOf","Map","order","queue","index","push","child","has","set","marked","prototype","hasOwnProperty","call","subtreeOf","seen","stack","out","next","pop","reverse","inline","byHand","some","violations","rule","code","message","detail","nodeIds","ancestorsOf","parent","get","refuse","noun","inItem","flatMap","topLevel","taken","keys","outer","find","ancestor","includes","listed","copy","malformed","findIndex","every","copies","subtree","users","used","highest","gap","short","unfilled","long","collision","_values","clash","forEach","size","drawn","item","members","idIn","source","clone","siblings","splice","indexOf"],"mappings":"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"}
@@ -18,7 +18,7 @@ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_wi
18
18
  */ import { aiCatalogEntry, aiModelCacheMinTokens } from "../providers/catalog.js";
19
19
  import { AI_IMAGE_MAX_BYTES, AI_IMAGE_MEDIA_TYPES, AI_REQUEST_MAX_IMAGES, AiRequestShapeError, AiUpstreamError, aiBase64Bytes, aiMessageImages } from "../providers/contract.js";
20
20
  import { resolveAiProvider } from "../providers/routing.js";
21
- import { aiDevCacheTtl, aiDevReplayMode, aiIsDeployedRuntime, aiLiveBatchWanted, aiUnderLiveRun, aiWarnIfReplayAskedInDeployment } from "./ai-dev-env.js";
21
+ import { aiRequestCacheTtl, aiDevReplayMode, aiIsDeployedRuntime, aiLiveBatchWanted, aiUnderLiveRun, aiWarnIfReplayAskedInDeployment } from "./ai-dev-env.js";
22
22
  import { aiAnsweredOutsideBatch, aiCompleteInBatch } from "./ai-live-batch.js";
23
23
  export { AI_UPSTREAM_FAILURE_COPY, AiRequestShapeError, AiUpstreamError } from "../providers/contract.js";
24
24
  /**
@@ -236,7 +236,6 @@ function providerFor(input) {
236
236
  };
237
237
  }
238
238
  export async function runAiRequest(input) {
239
- var _request_cacheTtl;
240
239
  validateAiSystemBlocks(input.system);
241
240
  if (input.cacheConversation && !aiConversationCacheFits(input.system)) {
242
241
  throw new AiRequestShapeError(`the conversation's breakpoint would be the ${AI_MAX_CACHE_BREAKPOINTS + 1}th; at most ${AI_MAX_CACHE_BREAKPOINTS} are cached`);
@@ -250,7 +249,7 @@ export async function runAiRequest(input) {
250
249
  "provider"
251
250
  ]);
252
251
  aiWarnIfReplayAskedInDeployment();
253
- const cacheTtl = (_request_cacheTtl = request.cacheTtl) != null ? _request_cacheTtl : aiDevCacheTtl();
252
+ const cacheTtl = aiRequestCacheTtl(request.cacheTtl);
254
253
  const providerRequest = _extends({}, request, cacheTtl ? {
255
254
  cacheTtl
256
255
  } : {}, {