@nodaro/prompts 1.38.0 → 1.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/chunk-2EW5B7ZV.cjs +86 -0
  2. package/dist/chunk-2EW5B7ZV.cjs.map +1 -0
  3. package/dist/chunk-2P26SZX5.cjs +414 -0
  4. package/dist/chunk-2P26SZX5.cjs.map +1 -0
  5. package/dist/{chunk-7XKHDXCL.cjs → chunk-3U7X6JZN.cjs} +13 -12
  6. package/dist/chunk-3U7X6JZN.cjs.map +1 -0
  7. package/dist/chunk-4GKTOVFM.cjs +8 -0
  8. package/dist/chunk-4GKTOVFM.cjs.map +1 -0
  9. package/dist/{chunk-HRBBNODV.js → chunk-6GVFJLDL.js} +4 -3
  10. package/dist/chunk-6GVFJLDL.js.map +1 -0
  11. package/dist/{chunk-LVSH7K7R.cjs → chunk-C3NHNECH.cjs} +165 -88
  12. package/dist/chunk-C3NHNECH.cjs.map +1 -0
  13. package/dist/{chunk-CEPVQQVO.js → chunk-C46256GZ.js} +43 -5
  14. package/dist/chunk-C46256GZ.js.map +1 -0
  15. package/dist/{chunk-JKCR6WRZ.cjs → chunk-DQFQJECU.cjs} +43 -5
  16. package/dist/chunk-DQFQJECU.cjs.map +1 -0
  17. package/dist/{chunk-QDEWBBUR.js → chunk-DUXX6CBX.js} +12 -143
  18. package/dist/chunk-DUXX6CBX.js.map +1 -0
  19. package/dist/chunk-EAYEZXWT.js +388 -0
  20. package/dist/chunk-EAYEZXWT.js.map +1 -0
  21. package/dist/chunk-GILUVQQJ.js +6 -0
  22. package/dist/chunk-GILUVQQJ.js.map +1 -0
  23. package/dist/{chunk-KIYNOOPJ.js → chunk-GTDKDD7Y.js} +12 -6
  24. package/dist/chunk-GTDKDD7Y.js.map +1 -0
  25. package/dist/{chunk-QBEZMR2F.js → chunk-HQTHDTHN.js} +137 -62
  26. package/dist/chunk-HQTHDTHN.js.map +1 -0
  27. package/dist/{chunk-TLVX5PXD.cjs → chunk-IUCNJAHW.cjs} +13 -7
  28. package/dist/chunk-IUCNJAHW.cjs.map +1 -0
  29. package/dist/{chunk-ZFIXQRBZ.cjs → chunk-LXPKTI2K.cjs} +12 -83
  30. package/dist/chunk-LXPKTI2K.cjs.map +1 -0
  31. package/dist/{chunk-CVPB2N3Z.cjs → chunk-LZ53F5BN.cjs} +103 -5
  32. package/dist/chunk-LZ53F5BN.cjs.map +1 -0
  33. package/dist/{chunk-4FDNVNJE.js → chunk-N6VMPG5S.js} +12 -79
  34. package/dist/chunk-N6VMPG5S.js.map +1 -0
  35. package/dist/{chunk-LK2CZK5U.cjs → chunk-PWWM7Q3T.cjs} +7 -7
  36. package/dist/{chunk-LK2CZK5U.cjs.map → chunk-PWWM7Q3T.cjs.map} +1 -1
  37. package/dist/{chunk-N7TOWXDJ.js → chunk-QDUTMOF4.js} +3 -3
  38. package/dist/{chunk-N7TOWXDJ.js.map → chunk-QDUTMOF4.js.map} +1 -1
  39. package/dist/{chunk-NO6XHX4R.js → chunk-RB2F5JQF.js} +100 -7
  40. package/dist/chunk-RB2F5JQF.js.map +1 -0
  41. package/dist/{chunk-MENBHEAY.cjs → chunk-WRM52ZBN.cjs} +19 -161
  42. package/dist/chunk-WRM52ZBN.cjs.map +1 -0
  43. package/dist/chunk-YS6HOWMW.js +80 -0
  44. package/dist/chunk-YS6HOWMW.js.map +1 -0
  45. package/dist/entries/assembly.cjs +34 -25
  46. package/dist/entries/assembly.d.cts +121 -37
  47. package/dist/entries/assembly.d.ts +121 -37
  48. package/dist/entries/assembly.js +5 -4
  49. package/dist/entries/doctrine.cjs +46 -46
  50. package/dist/entries/doctrine.d.cts +3 -3
  51. package/dist/entries/doctrine.d.ts +3 -3
  52. package/dist/entries/doctrine.js +1 -1
  53. package/dist/entries/picker-catalogs.cjs +42 -42
  54. package/dist/entries/picker-catalogs.js +3 -3
  55. package/dist/entries/presets.cjs +49 -26
  56. package/dist/entries/presets.d.cts +53 -1
  57. package/dist/entries/presets.d.ts +53 -1
  58. package/dist/entries/presets.js +4 -1
  59. package/dist/entries/prompt-builder.cjs +135 -98
  60. package/dist/entries/prompt-builder.d.cts +22 -11
  61. package/dist/entries/prompt-builder.d.ts +22 -11
  62. package/dist/entries/prompt-builder.js +4 -3
  63. package/dist/entries/prompt-fields.cjs +41 -40
  64. package/dist/entries/prompt-fields.d.cts +2 -1
  65. package/dist/entries/prompt-fields.d.ts +2 -1
  66. package/dist/entries/prompt-fields.js +2 -1
  67. package/dist/index.cjs +339 -273
  68. package/dist/index.d.cts +4 -4
  69. package/dist/index.d.ts +4 -4
  70. package/dist/index.js +11 -9
  71. package/dist/{subject-registry-BUswuEVD.d.cts → subject-registry-CQi_CZfJ.d.cts} +78 -9
  72. package/dist/{subject-registry-D7V8PEG-.d.ts → subject-registry-DFiGx49v.d.ts} +78 -9
  73. package/package.json +2 -2
  74. package/src/__tests__/assemble-image-input-style-references.test.ts +173 -0
  75. package/src/__tests__/catalog-id-guard.test.ts +30 -0
  76. package/src/__tests__/factory-preset-previews.test.ts +123 -0
  77. package/src/__tests__/factory-preset-references.test.ts +222 -0
  78. package/src/__tests__/factory-presets-prototype-keys.test.ts +43 -0
  79. package/src/__tests__/frame-reference-slots.test.ts +43 -0
  80. package/src/__tests__/gemini-omni-inputs.test.ts +12 -10
  81. package/src/__tests__/provider-prompt-doctrine.test.ts +14 -0
  82. package/src/__tests__/user-direction-refs.test.ts +180 -0
  83. package/src/__tests__/veo-i2v-inputs.test.ts +16 -11
  84. package/src/assemble-image-input.ts +114 -13
  85. package/src/catalog-id-guard.ts +18 -2
  86. package/src/color-names.ts +192 -0
  87. package/src/direction-registry.ts +66 -5
  88. package/src/entries/assembly.ts +1 -0
  89. package/src/entries/prompt-builder.ts +2 -0
  90. package/src/factory-presets/generate-image.ts +29 -0
  91. package/src/factory-presets/index.ts +6 -1
  92. package/src/factory-presets/preview-files.generated.ts +4 -0
  93. package/src/factory-presets/previews.ts +40 -0
  94. package/src/factory-presets/references.ts +81 -0
  95. package/src/factory-presets/shared-image.ts +4 -0
  96. package/src/factory-presets/types.ts +8 -0
  97. package/src/frame-reference-slots.ts +92 -0
  98. package/src/gemini-omni-inputs.ts +23 -22
  99. package/src/image-reference-doctrine.ts +3 -3
  100. package/src/image-token-pattern.ts +13 -0
  101. package/src/node-prompt-fields.ts +5 -3
  102. package/src/own-entry.ts +11 -0
  103. package/src/prompt-builder.ts +4 -5
  104. package/src/prompt-style-section.ts +3 -3
  105. package/src/prompt-wizard-categories.ts +2 -0
  106. package/src/provider-prompt-doctrine.ts +45 -3
  107. package/src/ref-binding.ts +28 -3
  108. package/src/resolve-prompt.ts +2 -1
  109. package/src/seedance-2-inputs.ts +15 -40
  110. package/src/user-direction-refs.ts +110 -0
  111. package/src/veo-i2v-inputs.ts +24 -17
  112. package/src/video-reference-resolver.ts +1 -1
  113. package/dist/chunk-4FDNVNJE.js.map +0 -1
  114. package/dist/chunk-7XKHDXCL.cjs.map +0 -1
  115. package/dist/chunk-CEPVQQVO.js.map +0 -1
  116. package/dist/chunk-CVPB2N3Z.cjs.map +0 -1
  117. package/dist/chunk-HRBBNODV.js.map +0 -1
  118. package/dist/chunk-JKCR6WRZ.cjs.map +0 -1
  119. package/dist/chunk-KIYNOOPJ.js.map +0 -1
  120. package/dist/chunk-LVSH7K7R.cjs.map +0 -1
  121. package/dist/chunk-MENBHEAY.cjs.map +0 -1
  122. package/dist/chunk-NO6XHX4R.js.map +0 -1
  123. package/dist/chunk-QBEZMR2F.js.map +0 -1
  124. package/dist/chunk-QDEWBBUR.js.map +0 -1
  125. package/dist/chunk-TLVX5PXD.cjs.map +0 -1
  126. package/dist/chunk-UJKFHPZ7.js +0 -37
  127. package/dist/chunk-UJKFHPZ7.js.map +0 -1
  128. package/dist/chunk-W5SCZIOB.cjs +0 -43
  129. package/dist/chunk-W5SCZIOB.cjs.map +0 -1
  130. package/dist/chunk-ZFIXQRBZ.cjs.map +0 -1
@@ -3,6 +3,12 @@ import { resolveNodeRefs } from '@nodaro/shared/workflow';
3
3
  import { readPromptAffixes } from '@nodaro/shared/nodes';
4
4
  import { SOCIAL_POST_NODE_TYPES } from '@nodaro/shared/social';
5
5
 
6
+ // src/own-entry.ts
7
+ function ownEntry(record, key) {
8
+ return key !== void 0 && Object.prototype.hasOwnProperty.call(record, key) ? record[key] : void 0;
9
+ }
10
+
11
+ // src/resolve-prompt.ts
6
12
  var present = (s) => typeof s === "string" && s.trim().length > 0;
7
13
  var rr = (s, m) => m.size > 0 ? resolveNodeRefs(s, m) : s;
8
14
  var GLUE_PUNCTUATION = /* @__PURE__ */ new Set([",", ".", ";", ":", "!", "?", ")"]);
@@ -74,7 +80,7 @@ function computeNodePrompt(nodeType, data, { override, wired, refMap, appendWire
74
80
  if (nodeType === "text-to-speech") {
75
81
  typed = data.textSource === "direct" || !present(wired) ? [data.directText] : [];
76
82
  } else {
77
- const fields = NODE_PROMPT_CANDIDATE_FIELDS[nodeType] ?? ["prompt"];
83
+ const fields = ownEntry(NODE_PROMPT_CANDIDATE_FIELDS, nodeType) ?? ["prompt"];
78
84
  typed = fields.map((f) => data[f]);
79
85
  }
80
86
  return resolvePrompt({ override, typed, wired, refMap, appendWired, affixes: readPromptAffixes(data) });
@@ -90,28 +96,6 @@ function computeScriptTopic(data, { override, wired, refMap }) {
90
96
  return applyPromptAffixes(core === void 0 ? "" : rr(core, refMap), readPromptAffixes(data), refMap);
91
97
  }
92
98
 
93
- // src/audio-tags.ts
94
- function removeBracketTags(text) {
95
- let out = "";
96
- let from = 0;
97
- let open = text.indexOf("[");
98
- while (open !== -1) {
99
- const close = text.indexOf("]", open + 1);
100
- if (close === -1) break;
101
- if (close === open + 1) {
102
- open = text.indexOf("[", open + 1);
103
- continue;
104
- }
105
- out += text.slice(from, open);
106
- from = close + 1;
107
- open = text.indexOf("[", from);
108
- }
109
- return out + text.slice(from);
110
- }
111
- function stripAudioTags(text) {
112
- return removeBracketTags(text).replace(/\s{2,}/g, " ").trim();
113
- }
114
-
115
99
  // src/node-prompt-fields.ts
116
100
  var NODE_PROMPT_FIELDS = {
117
101
  // ── Image ──
@@ -186,7 +170,7 @@ var NODE_PROMPT_FIELDS = {
186
170
  "edit-plan": { prompt: "instructions", promptLabel: "Editing instructions", media: "video", inline: false }
187
171
  };
188
172
  function getPromptFields(nodeType) {
189
- return nodeType ? NODE_PROMPT_FIELDS[nodeType] : void 0;
173
+ return nodeType ? ownEntry(NODE_PROMPT_FIELDS, nodeType) : void 0;
190
174
  }
191
175
  function nodeHasPromptField(nodeType) {
192
176
  return getPromptFields(nodeType) !== void 0;
@@ -210,63 +194,12 @@ function promptFieldCarriesAffixes(nodeType, promptField) {
210
194
  const core = promptAffixCoreField(nodeType);
211
195
  if (core === void 0) return false;
212
196
  if (promptField === void 0) return getPromptFields(nodeType).prompt === core;
213
- return promptField === core || (NODE_PROMPT_CANDIDATE_FIELDS[nodeType] ?? []).includes(promptField);
197
+ return promptField === core || (ownEntry(NODE_PROMPT_CANDIDATE_FIELDS, nodeType) ?? []).includes(promptField);
214
198
  }
215
199
  var PROMPT_AFFIX_NODE_TYPES = new Set(
216
200
  Object.entries(NODE_PROMPT_FIELDS).filter(([, s]) => s.affixes !== false).map(([t]) => t)
217
201
  );
218
- var WIRED_OUTPUT_NODE_TYPES = /* @__PURE__ */ new Set(["webhook-output", ...SOCIAL_POST_NODE_TYPES]);
219
- var TEXT_REQUIRED_NODE_TYPES = /* @__PURE__ */ new Set([
220
- "llm-chat",
221
- "ai-writer",
222
- "generate-script",
223
- "text-to-speech",
224
- "generate-music",
225
- "text-to-audio",
226
- // Save to Collection refuses an empty record ("nothing to save"): a feed
227
- // with nothing new wired straight into it must skip it, not fail the run.
228
- "collection-write",
229
- // Generate Image: an empty prompt is a legal request in general (references
230
- // alone), but when the text it was WIRED produced nothing this run — the skip
231
- // rule's precondition — an empty prompt is a paid picture of nothing.
232
- "generate-image"
233
- ]);
234
- var withoutAffixes = (data) => ({ ...data, promptPrefix: void 0, promptSuffix: void 0 });
235
- var present2 = (s) => typeof s === "string" && s.trim().length > 0;
236
- function computeAiWriterInput(data, { override, wired }) {
237
- return [override, wired, data.userInput, data.prompt].find(present2) ?? "";
238
- }
239
- function computeNodeSendText(nodeType, data, args) {
240
- const bare = withoutAffixes(data);
241
- switch (nodeType) {
242
- case "llm-chat":
243
- return computeLlmChatFields(bare, {
244
- override: args.override,
245
- wiredUserInput: args.wired,
246
- wiredSystemPrompt: args.wiredSystemPrompt,
247
- refMap: args.refMap
248
- }).userInput;
249
- case "ai-writer":
250
- return computeAiWriterInput(bare, args);
251
- case "generate-script":
252
- return computeScriptTopic(bare, { override: args.override, wired: args.wired, refMap: args.refMap });
253
- case "generate-music": {
254
- const prompt = computeNodePrompt(nodeType, bare, { override: args.override, wired: args.wired, refMap: args.refMap });
255
- return present2(prompt) ? prompt : present2(data.lyrics) ? data.lyrics : "";
256
- }
257
- case "text-to-speech":
258
- case "text-to-audio":
259
- case "generate-image":
260
- return computeNodePrompt(nodeType, bare, { override: args.override, wired: args.wired, refMap: args.refMap });
261
- case "collection-write": {
262
- const typed = [data.title, data.text, data.link].map((v) => typeof v === "string" ? resolveNodeRefs(v, args.refMap) : v).find((v) => present2(v));
263
- return [args.override, args.wired, typed].find(present2) ?? "";
264
- }
265
- default:
266
- return void 0;
267
- }
268
- }
269
202
 
270
- export { NODE_PROMPT_CANDIDATE_FIELDS, NODE_PROMPT_FIELDS, PROMPT_AFFIX_CORE_FIELD_OVERRIDES, PROMPT_AFFIX_NODE_TYPES, TEXT_REQUIRED_NODE_TYPES, WIRED_OUTPUT_NODE_TYPES, applyPromptAffixes, composeNegative, computeAiWriterInput, computeLlmChatFields, computeNodePrompt, computeNodeSendText, computeScriptTopic, getPromptFields, getSnippetMedia, joinPromptParts, nodeHasInlinePrompt, nodeHasPromptField, nodeSupportsPromptAffixes, promptAffixCoreField, promptFieldCarriesAffixes, promptPartSeparator, resolvePrompt, stripAudioTags };
271
- //# sourceMappingURL=chunk-4FDNVNJE.js.map
272
- //# sourceMappingURL=chunk-4FDNVNJE.js.map
203
+ export { NODE_PROMPT_CANDIDATE_FIELDS, NODE_PROMPT_FIELDS, PROMPT_AFFIX_CORE_FIELD_OVERRIDES, PROMPT_AFFIX_NODE_TYPES, applyPromptAffixes, composeNegative, computeLlmChatFields, computeNodePrompt, computeScriptTopic, getPromptFields, getSnippetMedia, joinPromptParts, nodeHasInlinePrompt, nodeHasPromptField, nodeSupportsPromptAffixes, ownEntry, promptAffixCoreField, promptFieldCarriesAffixes, promptPartSeparator, resolvePrompt };
204
+ //# sourceMappingURL=chunk-N6VMPG5S.js.map
205
+ //# sourceMappingURL=chunk-N6VMPG5S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/own-entry.ts","../src/resolve-prompt.ts","../src/node-prompt-fields.ts"],"names":[],"mappings":"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","file":"chunk-N6VMPG5S.js","sourcesContent":["/**\n * A registry keyed by node type is a plain object, and the key is\n * caller-supplied (`?nodeType=` on a public route, a preset row's `node_type`,\n * workflow JSON). A plain `record[key] ?? fallback` reads an Object.prototype\n * member for `\"constructor\"`, `\"toString\"` or `\"__proto__\"` — a function or\n * the prototype itself, which the caller then maps or iterates and throws on.\n * This reads an OWN entry only, so such a name is \"no such type\".\n */\nexport function ownEntry<T>(record: Readonly<Record<string, T>>, key: string | undefined): T | undefined {\n return key !== undefined && Object.prototype.hasOwnProperty.call(record, key) ? record[key] : undefined\n}\n","import { resolveNodeRefs } from \"@nodaro/shared/workflow\"\nimport { readPromptAffixes, type PromptAffixes } from \"@nodaro/shared/nodes\"\nimport { SOCIAL_POST_NODE_TYPES } from \"@nodaro/shared/social\"\nimport { joinSentences } from \"./hint-join.js\"\nimport { ownEntry } from \"./own-entry.js\"\n\nexport interface ResolvePromptArgs {\n override?: string\n typed?: ReadonlyArray<string | undefined>\n wired?: string\n refMap: ReadonlyMap<string, string>\n /** Opt-in (generate-image / generate-video only): APPEND the wired\n * (connected-prompt) value to the TYPED base instead of treating wired as a\n * fallback, so a connected prompt auto-injects alongside the typed prompt. An\n * `override` (list fan-out item) still fully replaces — no wired append.\n * Off/undefined = exact legacy precedence (override > typed > wired) for every\n * other node type. */\n appendWired?: boolean\n /** Pre/post text wrapped around WHICHEVER core precedence produced (override,\n * typed, wired, or the appendWired combination). Applied last. */\n affixes?: PromptAffixes\n}\nconst present = (s?: string): s is string => typeof s === \"string\" && s.trim().length > 0\nconst rr = (s: string, m: ReadonlyMap<string, string>) => (m.size > 0 ? resolveNodeRefs(s, m) : s)\n\n// ---------------------------------------------------------------------------\n// Prompt affixes (pre/post text) — see docs/prompt-pre-post-text.md (join rule, empty-core, no-op guarantee)\n// ---------------------------------------------------------------------------\n\nconst GLUE_PUNCTUATION = new Set([\",\", \".\", \";\", \":\", \"!\", \"?\", \")\"])\n\n/** The ONE join rule between two non-blank prompt parts: a single space unless\n * the boundary already has whitespace on either side or the right part opens\n * with sentence punctuation. Shared by `joinPromptParts` and the editor's\n * Final-view segment builder so preview and run agree byte-for-byte. */\nexport function promptPartSeparator(left: string, right: string): \"\" | \" \" {\n if (left.length === 0 || right.length === 0) return \"\"\n if (/\\s$/.test(left) || /^\\s/.test(right)) return \"\"\n if (GLUE_PUNCTUATION.has(right[0])) return \"\"\n return \" \"\n}\n\n/** Join prompt parts with `promptPartSeparator`; blank parts are dropped,\n * non-blank parts are used verbatim (no trimming). */\nexport function joinPromptParts(parts: ReadonlyArray<string | undefined>): string {\n let out = \"\"\n for (const part of parts) {\n if (!present(part)) continue\n out = out.length === 0 ? part : out + promptPartSeparator(out, part) + part\n }\n return out\n}\n\n/**\n * Wrap `core` with the node's pre/post text. `{Label}` refs are resolved in the\n * AFFIXES only — the core arrives exactly as the caller's precedence produced it.\n * NO-OP GUARANTEE: with no non-blank affix the core is returned unchanged (same\n * reference) — every existing workflow stays byte-identical.\n * EMPTY CORE: a blank core with affixes yields the joined affixes alone.\n */\nexport function applyPromptAffixes(core: string, affixes: PromptAffixes | undefined, refMap: ReadonlyMap<string, string>): string\nexport function applyPromptAffixes(core: string | undefined, affixes: PromptAffixes | undefined, refMap: ReadonlyMap<string, string>): string | undefined\nexport function applyPromptAffixes(\n core: string | undefined,\n affixes: PromptAffixes | undefined,\n refMap: ReadonlyMap<string, string>,\n): string | undefined {\n const prefix = present(affixes?.prefix) ? rr(affixes!.prefix!, refMap) : undefined\n const suffix = present(affixes?.suffix) ? rr(affixes!.suffix!, refMap) : undefined\n if (prefix === undefined && suffix === undefined) return core\n return joinPromptParts([prefix, core, suffix])\n}\n\n/** SINGLE SOURCE OF TRUTH for prompt precedence across both DAG engines:\n * override (list fan-out) > first present typed candidate > wired > \"\".\n * \"present\" = non-empty after trim. {Label} refs are resolved on the chosen\n * branch via the shared resolveNodeRefs. With `appendWired`, the chosen base\n * AND the wired value are both emitted, joined as sentences (`joinSentences`:\n * \". \", or a space after one that already ends). Affixes wrap the result. */\nexport function resolvePrompt({ override, typed = [], wired, refMap, appendWired, affixes }: ResolvePromptArgs): string {\n return applyPromptAffixes(resolveCore({ override, typed, wired, refMap, appendWired }), affixes, refMap)\n}\n\nfunction resolveCore({ override, typed = [], wired, refMap, appendWired }: Omit<ResolvePromptArgs, \"affixes\">): string {\n // appendWired: a connected prompt APPENDS to the TYPED base. An `override`\n // (list fan-out item) still fully REPLACES — it never receives a wired append,\n // so per-item fan-out prompts are unchanged.\n if (appendWired && !present(override)) {\n const base = typed.find(present)\n return joinSentences([base, wired].filter(present).map((s) => rr(s, refMap)))\n }\n if (present(override)) return rr(override, refMap)\n for (const t of typed) if (present(t)) return rr(t, refMap)\n if (present(wired)) return rr(wired, refMap)\n return \"\"\n}\n\n/** Compose a final NEGATIVE prompt from a TYPED base + a WIRED (connected\n * negative-handle) value: both are emitted, joined as sentences (`joinSentences`, mirrors `appendWired`\n * for the positive prompt). Pure join — the caller resolves `{label}` refs on\n * the typed value first, and the wired value is already a resolved output that\n * the input-resolver has filtered (referenced / Inject-Negative-off dropped).\n * Generate-image / generate-video only; empty parts are dropped. */\nexport function composeNegative(typed?: string, wired?: string): string {\n return joinSentences([typed, wired])\n}\n\n/** Ordered typed-candidate fields per node type — the precedence source of\n * truth (NOT NODE_MAPPABLE_FIELDS, which is field-mapping eligibility, omits\n * video-retake, and orders llm-chat wrong). */\nexport const NODE_PROMPT_CANDIDATE_FIELDS: Readonly<Record<string, readonly string[]>> = {\n \"generate-image\": [\"prompt\"],\n // motionPrompt is here so generate-video re-typed to text-to-video keeps a\n // prompt stored in data.motionPrompt (the inline picker's legacy field). Safe\n // for a standalone text-to-video node — it never carries data.motionPrompt.\n \"text-to-video\": [\"prompt\", \"motionPrompt\"],\n \"video-to-video\": [\"prompt\"],\n \"generate-music\": [\"prompt\"],\n \"speech-to-video\": [\"prompt\"],\n \"cinematic-avatar\": [\"prompt\"],\n \"extend-video\": [\"prompt\"],\n \"video-retake\": [\"prompt\"],\n \"suno-replace-section\": [\"prompt\"],\n \"image-to-video\": [\"prompt\", \"motionPrompt\"],\n \"generate-video\": [\"prompt\", \"motionPrompt\"],\n \"text-to-audio\": [\"prompt\", \"text\"],\n // Social posts: the orchestrator + frontend executor match per-platform node\n // types (node.type is \"instagram-post\", \"telegram-post\", …), NOT a unified\n // \"social-publish\" type — so every platform needs its own [\"caption\"] entry.\n // Derived from the shared SOCIAL_POST_NODE_TYPES single source of truth so a\n // new platform can't drift out of the precedence map.\n ...Object.fromEntries(\n [...SOCIAL_POST_NODE_TYPES].map((t) => [t, [\"caption\"] as readonly string[]]),\n ),\n // Kept for any caller that passes the aggregate type instead of a platform.\n \"social-publish\": [\"caption\"],\n}\n\nexport interface ComputeNodePromptArgs {\n override?: string\n wired?: string\n refMap: ReadonlyMap<string, string>\n /** See ResolvePromptArgs.appendWired — generate-image / generate-video only. */\n appendWired?: boolean\n}\n/** Resolve a single-prompt node's final prompt (typed-primary). Both engines\n * call this so field-selection + precedence are structurally identical. */\nexport function computeNodePrompt(\n nodeType: string,\n data: Record<string, unknown>,\n { override, wired, refMap, appendWired }: ComputeNodePromptArgs,\n): string {\n let typed: ReadonlyArray<string | undefined>\n if (nodeType === \"text-to-speech\") {\n // data.text is a phantom field on TTS; only directText (gated) is real.\n //\n // The gate is a PREFERENCE, not a lock: when textSource is \"connected\" we\n // still fall back to typed text if nothing is wired. Writers flip the gate\n // (PromptFieldSpec.promptGate), but data reaches nodes from places no\n // writer touches — workflows saved before that fix, JSON imports, MCP\n // writes, templates — and there the text sat visible in the node while the\n // run failed with \"no text found\" (founder, 2026-08-14). Coerce rather\n // than reject, same principle as normalizeModelInput.\n typed =\n data.textSource === \"direct\" || !present(wired)\n ? [data.directText as string | undefined]\n : []\n } else {\n const fields = ownEntry(NODE_PROMPT_CANDIDATE_FIELDS, nodeType) ?? [\"prompt\"]\n typed = fields.map((f) => data[f] as string | undefined)\n }\n return resolvePrompt({ override, typed, wired, refMap, appendWired, affixes: readPromptAffixes(data) })\n}\n\nexport interface LlmChatFieldArgs {\n override?: string\n wiredUserInput?: string\n wiredSystemPrompt?: string\n refMap: ReadonlyMap<string, string>\n}\n/** llm-chat resolves TWO independent fields. override applies to userInput only. */\nexport function computeLlmChatFields(\n data: Record<string, unknown>,\n { override, wiredUserInput, wiredSystemPrompt, refMap }: LlmChatFieldArgs,\n): { userInput: string; systemPrompt: string } {\n return {\n userInput: resolvePrompt({ override, typed: [data.userInput as string | undefined], wired: wiredUserInput, refMap, affixes: readPromptAffixes(data) }),\n systemPrompt: resolvePrompt({ typed: [data.systemPrompt as string | undefined], wired: wiredSystemPrompt, refMap }),\n }\n}\n\n/** generate-script's topic. Both engines call this, so a wired Text node reads\n * the same on a single-node run and a server run.\n *\n * Precedence is override (a list fan-out item) > wired > `data.prompt`. Wired\n * comes BEFORE the typed field, the reverse of `computeNodePrompt`, because\n * `data.prompt` has no editor: the panel's text field is the style guide. A\n * value there was written by the old connect-time `{Label}` auto-fill or by an\n * agent, and it is kept only as the fallback that saved workflows rely on. */\nexport function computeScriptTopic(\n data: Record<string, unknown>,\n { override, wired, refMap }: Omit<ComputeNodePromptArgs, \"appendWired\">,\n): string {\n const core = [override, wired, data.prompt as string | undefined].find(present)\n return applyPromptAffixes(core === undefined ? \"\" : rr(core, refMap), readPromptAffixes(data), refMap)\n}\n","/**\n * Single source of truth: which data field(s) hold a node's user-editable\n * prompt text. Drives the quick-edit Prompt modal so it can work generically\n * across every AI node without each call site hardcoding a field name.\n *\n * The registry LIVES HERE (`@nodaro/prompts`) so the backend orchestrator, the\n * `/v1/nodes` registry, the prompt-affix totality tests and the docs tooling\n * read the SAME list the editor does. `frontend/src/lib/prompt-fields.ts` is a\n * pure re-export of this module — frontend code keeps importing\n * `@/lib/prompt-fields` unchanged.\n *\n * Most nodes store the prompt in `data.prompt`, but several don't\n * (`text-prompt` → `text`, `image-to-text` → `customPrompt`, …) — this map is\n * where that knowledge lives, once.\n *\n * INVARIANT: every node that exposes a user-editable prompt MUST have an entry\n * here, or the quick-edit modal silently does nothing for it. A guard test\n * (`prompt-fields.test.ts`) keeps this in sync with the node set.\n *\n * This module is intentionally pure data (no React/lucide imports) so it can be\n * pulled into the app-runtime bundle and any test without dragging in the icon\n * library. The string `icon` kind is mapped to a concrete lucide component in\n * `prompt-edit-button.tsx` (`getPromptIcon`), the only place that renders it.\n */\n\nimport type { SnippetMedia } from \"./factory-snippets/types.js\"\nimport { NODE_PROMPT_CANDIDATE_FIELDS } from \"./resolve-prompt.js\"\nimport { ownEntry } from \"./own-entry.js\"\n\n/** Which lucide glyph a node's prompt affordance uses. Kept as a string so this\n * module stays icon-library-free; mapped to a component in the strip button. */\nexport type PromptIconKind = \"pencil\" | \"paintbrush\"\n\nexport interface PromptFieldSpec {\n /** Data key holding the primary prompt (e.g. \"prompt\", \"text\", \"customPrompt\"). */\n readonly prompt: string\n /** Data key holding the negative prompt, when the node supports one. */\n readonly negative?: string\n /** Label override for the primary field (defaults to \"Prompt\"). */\n readonly promptLabel?: string\n /** Icon for the prompt affordance (strip button + modal title). Defaults to a\n * pencil; image-editing nodes use a paintbrush to read as \"edit\". */\n readonly icon?: PromptIconKind\n /** Node modality for prompt-snippet scoping — drives which snippet pool the\n * \"/\" menu and Snippets button show for this node's prompt fields. REQUIRED\n * so a new node cannot forget to declare it (compile error). */\n readonly media: SnippetMedia\n /** True when this node renders a media-result preview body and therefore\n * participates in inline-prompt mode (the `InlineNodePrompt` editor on the\n * node face, centralized in `BaseNode`). REQUIRED (like `media`) so a new\n * prompt node must consciously choose — compile error if omitted. The set of\n * `inline: true` types is guarded in `prompt-fields.test.ts`. */\n readonly inline: boolean\n /** Some nodes only READ their prompt field when a sibling discriminator\n * selects it — TTS keeps `directText` but resolves it only while\n * `textSource === \"direct\"`, defaulting to `\"connected\"`. Writing the text\n * without flipping the discriminator saved the value and then failed with\n * \"no text found\" (founder hit it live, 2026-08-14). Declare the pair here\n * and every writer flips it automatically. */\n readonly promptGate?: { readonly field: string; readonly value: string }\n /** Prompt pre/post text (`promptPrefix` / `promptSuffix`) support. Defaults to\n * ON for every prompt node; set `false` ONLY for a node whose \"prompt\" is not\n * a model prompt (the plain Text input node). Read via `nodeSupportsPromptAffixes`. */\n readonly affixes?: false\n}\n\nexport const NODE_PROMPT_FIELDS: Readonly<Record<string, PromptFieldSpec>> = {\n // ── Image ──\n // (`edit-image` / `image-to-image` are legacy types consolidated into\n // `modify-image`; they're not in the creatable node set, so a node of that\n // type never mounts and needs no entry here. The guard test enforces that.)\n \"generate-image\": { prompt: \"prompt\", negative: \"negativePrompt\", media: \"image\", inline: true },\n \"modify-image\": { prompt: \"prompt\", negative: \"negativePrompt\", icon: \"paintbrush\", media: \"image\", inline: true },\n \"generate-mask\": { prompt: \"prompt\", promptLabel: \"What to mask\", media: \"image\", inline: true },\n // ── Video ──\n \"generate-video\": { prompt: \"prompt\", negative: \"negativePrompt\", media: \"video\", inline: true },\n // Trimmed multi-segment stitch sibling of generate-video — no negativePrompt field.\n \"generate-video-pro\": { prompt: \"prompt\", media: \"video\", inline: true },\n // Span-replace sibling of generate-video-pro — no negativePrompt field.\n \"edit-video-pro\": { prompt: \"prompt\", media: \"video\", inline: true },\n \"text-to-video\": { prompt: \"prompt\", negative: \"negativePrompt\", media: \"video\", inline: true },\n \"image-to-video\": { prompt: \"prompt\", negative: \"negativePrompt\", promptLabel: \"Motion prompt\", media: \"video\", inline: true },\n \"video-to-video\": { prompt: \"prompt\", negative: \"negativePrompt\", media: \"video\", inline: true },\n \"switchx\": { prompt: \"prompt\", promptLabel: \"Look prompt\", media: \"video\", inline: true },\n \"extend-video\": { prompt: \"prompt\", negative: \"negativePrompt\", media: \"video\", inline: true },\n \"speech-to-video\": { prompt: \"prompt\", negative: \"negativePrompt\", media: \"video\", inline: true },\n \"motion-transfer\": { prompt: \"prompt\", negative: \"negativePrompt\", media: \"video\", inline: true },\n // Cinematic Avatar (HeyGen) — generative prompt (NOT a verbatim script),\n // so it participates in the quick-edit Prompt modal like other AI video nodes.\n \"cinematic-avatar\": { prompt: \"prompt\", media: \"video\", inline: true },\n \"video-sfx\": { prompt: \"prompt\", negative: \"negativePrompt\", promptLabel: \"Sound prompt\", media: \"audio\", inline: true },\n \"video-retake\": { prompt: \"prompt\", promptLabel: \"Retake prompt\", media: \"video\", inline: true },\n // Video Mask (SAM 3) — the subject to track, like Generate Mask's \"what to mask\".\n \"video-mask\": { prompt: \"prompt\", promptLabel: \"What to mask\", media: \"video\", inline: true },\n // ── Audio / music ──\n \"generate-music\": { prompt: \"prompt\", media: \"audio\", inline: true },\n \"suno-generate\": { prompt: \"prompt\", media: \"audio\", inline: true },\n \"text-to-audio\": { prompt: \"prompt\", media: \"audio\", inline: true },\n // ── Text / LLM (no media-result preview body → no inline editor) ──\n \"text-prompt\": { prompt: \"text\", promptLabel: \"Text\", media: \"text\", inline: false, affixes: false },\n \"image-to-text\": { prompt: \"customPrompt\", promptLabel: \"Question\", media: \"text\", inline: false },\n \"llm-chat\": { prompt: \"userInput\", promptLabel: \"Prompt\", media: \"text\", inline: false },\n // ── Speech / voice ──\n \"text-to-speech\": { prompt: \"directText\", promptLabel: \"Text\", media: \"audio\", inline: true, promptGate: { field: \"textSource\", value: \"direct\" } },\n \"voice-design\": { prompt: \"voiceDescription\", promptLabel: \"Voice description\", media: \"audio\", inline: true },\n \"voice-remix\": { prompt: \"voiceDescription\", promptLabel: \"Voice description\", media: \"audio\", inline: true },\n \"lip-sync\": { prompt: \"prompt\", media: \"audio\", inline: true },\n // ── Suno (music) ──\n \"suno-cover\": { prompt: \"prompt\", media: \"audio\", inline: true },\n \"suno-extend\": { prompt: \"prompt\", media: \"audio\", inline: true },\n \"suno-replace-section\": { prompt: \"prompt\", media: \"audio\", inline: true },\n \"suno-upload-extend\": { prompt: \"prompt\", media: \"audio\", inline: true },\n // NOTE: `suno-add-vocals` is intentionally absent — its node has no\n // user-editable prompt (SunoAddVocalsData declares only `model`; the config\n // panel + backend route take taskId/audioId/model, never a prompt). A stale\n // entry here rendered a phantom Prompt editor in the quick-edit modal that\n // wrote to a `data.prompt` key nothing ever reads (the dead-field class the\n // guard test now catches via defaultData ownership).\n \"suno-lyrics\": { prompt: \"prompt\", media: \"audio\", inline: false },\n \"suno-style-boost\": { prompt: \"content\", promptLabel: \"Style\", media: \"audio\", inline: false },\n // ── Composition / FX (compact, no media-result preview → no inline editor) ──\n \"image-critic\": { prompt: \"prompt\", promptLabel: \"Criteria\", media: \"image\", inline: false },\n \"motion-graphics\": { prompt: \"motionPrompt\", promptLabel: \"Motion prompt\", media: \"video\", inline: false },\n \"pro-3d-render\": { prompt: \"scenePrompt\", promptLabel: \"Scene\", media: \"text\", inline: false },\n \"generate-3d-scene\": { prompt: \"scenePrompt\", promptLabel: \"Scene\", media: \"text\", inline: false },\n \"edit-3d-scene\": { prompt: \"editPrompt\", promptLabel: \"Edit instruction\", media: \"text\", inline: false },\n \"3d-title\": { prompt: \"titlePrompt\", promptLabel: \"Title\", media: \"text\", inline: false },\n // ── Script / alignment (their primary text field) ──\n \"generate-script\": { prompt: \"styleGuide\", promptLabel: \"Style guide\", media: \"text\", inline: false },\n \"forced-alignment\": { prompt: \"transcript\", promptLabel: \"Transcript\", media: \"audio\", inline: false },\n // Video Analysis — its focus hint is the editable prompt (renders a JSON scene\n // table, not a media preview → no inline editor).\n \"video-analysis\": { prompt: \"analysisFocus\", promptLabel: \"Analysis focus\", media: \"video\", inline: false },\n // Edit Plan (podcast editing) — its free-text editing instructions are the\n // editable prompt; the affixes wrap them. Emits an EDL (JSON), not a media\n // preview, so no inline editor.\n \"edit-plan\": { prompt: \"instructions\", promptLabel: \"Editing instructions\", media: \"video\", inline: false },\n}\n\n/** The prompt-field spec for a node type, or undefined if it has none (an\n * Object.prototype member name such as `constructor` has none). */\nexport function getPromptFields(nodeType: string | undefined): PromptFieldSpec | undefined {\n return nodeType ? ownEntry(NODE_PROMPT_FIELDS, nodeType) : undefined\n}\n\n/** True when this node type has a registered, quick-editable prompt field. */\nexport function nodeHasPromptField(nodeType: string | undefined): boolean {\n return getPromptFields(nodeType) !== undefined\n}\n\n/** Snippet modality for a node type (drives the snippet pool), or undefined\n * when the node has no prompt field. */\nexport function getSnippetMedia(nodeType: string | undefined): SnippetMedia | undefined {\n return getPromptFields(nodeType)?.media\n}\n\n/** True when this node type renders the inline on-node prompt editor — the\n * media-preview nodes (image/video/audio result body). Single source for\n * BaseNode's centralized `InlineNodePrompt` rendering and the gold nodes'\n * `showInline` derivation (`useInlinePromptActive`). */\nexport function nodeHasInlinePrompt(nodeType: string | undefined): boolean {\n return getPromptFields(nodeType)?.inline === true\n}\n\n/** True when the node type carries `promptPrefix` / `promptSuffix` — every\n * registered prompt node except explicit opt-outs (`affixes: false`). The single\n * predicate the config panel, Final view, `/v1/nodes` registry, totality tests\n * and docs tooling all gate on. */\nexport function nodeSupportsPromptAffixes(nodeType: string | undefined): boolean {\n const spec = getPromptFields(nodeType)\n return spec !== undefined && spec.affixes !== false\n}\n\n/**\n * Where the RUN-TIME prompt lives when it differs from the editor's prompt\n * field (spec §7). `generate-script`'s editable prompt is its `styleGuide`, but\n * the run wraps the topic `prompt` with the affixes — so previewing the style\n * guide must NOT show them.\n */\nexport const PROMPT_AFFIX_CORE_FIELD_OVERRIDES: Readonly<Record<string, string>> = { \"generate-script\": \"prompt\" }\n\n/** The data key whose value the run wraps with promptPrefix/promptSuffix, or\n * undefined when the node has no affixes. */\nexport function promptAffixCoreField(nodeType: string | undefined): string | undefined {\n if (!nodeSupportsPromptAffixes(nodeType)) return undefined\n return PROMPT_AFFIX_CORE_FIELD_OVERRIDES[nodeType!] ?? getPromptFields(nodeType)!.prompt\n}\n\n/**\n * True when a preview of `promptField` on this node must show the affixes —\n * i.e. that key is what the run actually wraps. THE gate for the editor's Final\n * view, so a sibling field (llm-chat's `systemPrompt`, generate-script's\n * `styleGuide`) never renders a wrap the run doesn't perform.\n *\n * Two ways a key qualifies:\n * - it IS the core field ({@link promptAffixCoreField}), or\n * - it is a run-time FALLBACK candidate for the type\n * ({@link NODE_PROMPT_CANDIDATE_FIELDS}) — `computeNodePrompt` picks the\n * first present candidate and wraps THAT, so i2v's legacy `motionPrompt`\n * genuinely receives the affixes when `data.prompt` is empty.\n *\n * The two rules never collide: no override type declares candidates (guarded in\n * `node-prompt-fields.test.ts`).\n *\n * `undefined` means \"the node's primary prompt field\" — the common call.\n */\nexport function promptFieldCarriesAffixes(nodeType: string | undefined, promptField: string | undefined): boolean {\n const core = promptAffixCoreField(nodeType)\n if (core === undefined) return false\n if (promptField === undefined) return getPromptFields(nodeType)!.prompt === core\n return promptField === core || (ownEntry(NODE_PROMPT_CANDIDATE_FIELDS, nodeType) ?? []).includes(promptField)\n}\n\n/** The affix-capable node types, derived from the registry (never hand-listed). */\nexport const PROMPT_AFFIX_NODE_TYPES: ReadonlySet<string> = new Set(\n Object.entries(NODE_PROMPT_FIELDS).filter(([, s]) => s.affixes !== false).map(([t]) => t),\n)\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkW5SCZIOB_cjs = require('./chunk-W5SCZIOB.cjs');
3
+ var chunk2P26SZX5_cjs = require('./chunk-2P26SZX5.cjs');
4
4
  var chunkMQEXFCNU_cjs = require('./chunk-MQEXFCNU.cjs');
5
5
  var chunk3UEA3UHQ_cjs = require('./chunk-3UEA3UHQ.cjs');
6
6
  var chunkK6NT635Z_cjs = require('./chunk-K6NT635Z.cjs');
@@ -359,17 +359,17 @@ function resolveBaseHint(type, data, mode = "full") {
359
359
  // them goes through (the subject fold uses it too). Each returns "" on a
360
360
  // miss, so the entry lookup is the module's job, not this switch's.
361
361
  case "animal":
362
- return withCustomText(data, byMode(mode, chunkW5SCZIOB_cjs.curatedAnimalPromptHint, chunkW5SCZIOB_cjs.curatedAnimalTerm)(asStr(data.animal)));
362
+ return withCustomText(data, byMode(mode, chunk2P26SZX5_cjs.curatedAnimalPromptHint, chunk2P26SZX5_cjs.curatedAnimalTerm)(asStr(data.animal)));
363
363
  case "vehicle": {
364
- const t = chunkW5SCZIOB_cjs.curatedVehicleText(asStr(data.vehicle));
364
+ const t = chunk2P26SZX5_cjs.curatedVehicleText(asStr(data.vehicle));
365
365
  return withCustomText(data, byMode(mode, t.hint, t.term));
366
366
  }
367
367
  case "weapon": {
368
- const t = chunkW5SCZIOB_cjs.curatedWeaponText(asStr(data.weapon));
368
+ const t = chunk2P26SZX5_cjs.curatedWeaponText(asStr(data.weapon));
369
369
  return withCustomText(data, byMode(mode, t.hint, t.term));
370
370
  }
371
371
  case "furniture": {
372
- const t = chunkW5SCZIOB_cjs.curatedFurnitureText(asStr(data.furniture));
372
+ const t = chunk2P26SZX5_cjs.curatedFurnitureText(asStr(data.furniture));
373
373
  return withCustomText(data, byMode(mode, t.hint, t.term));
374
374
  }
375
375
  case "photo-genre":
@@ -425,5 +425,5 @@ exports.getAdultOnlyIds = getAdultOnlyIds;
425
425
  exports.getCharacterMotionBindings = getCharacterMotionBindings;
426
426
  exports.getMinorAgeHintStrings = getMinorAgeHintStrings;
427
427
  exports.getParameterPromptHint = getParameterPromptHint;
428
- //# sourceMappingURL=chunk-LK2CZK5U.cjs.map
429
- //# sourceMappingURL=chunk-LK2CZK5U.cjs.map
428
+ //# sourceMappingURL=chunk-PWWM7Q3T.cjs.map
429
+ //# sourceMappingURL=chunk-PWWM7Q3T.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/age-floor.ts","../src/parameter-prompt-hint.ts"],"names":["getRegisteredPickerCatalogs","getRegisteredPeople","ADULT_AGE_IDS","MINOR_IMPLYING_TYPE_IDS","isMinorAge","joinHintFragments","composeCameraMotionHintFromConnections","readTransitionOptionValues","composeTransitionHintFromConnections","composeCharacterFxHintFromConnections","composeCharacterMotionHintFromConnections","getPickerCatalog","resolveTerm","buildFramingHints","buildLightingHints","getLensPromptHint","getLensTerm","getCameraFormatPromptHint","getCameraFormatTerm","getColorLookPromptHint","getColorLookTerm","buildMusicGenreHints","buildMusicMoodHints","buildInstrumentationHints","buildVoiceCharacterHints","buildVoiceDeliveryHints","buildPersonHints","buildMoodHints","buildPoseHints","buildStylingHints","buildAtmosphereHints","buildActionFxHints","getStylePromptHint","getStyleTerm","getSettingPromptHint","getSettingTerm","getLoopSubjectPromptHint","getLoopSubjectTerm","buildMaterialHints","curatedAnimalPromptHint","curatedAnimalTerm","curatedVehicleText","curatedWeaponText","curatedFurnitureText","getPhotoGenrePromptHint","getPhotoGenreTerm","getBackdropPromptHint","getBackdropTerm","buildHeldPropHints","buildPhotographerHints","buildAestheticHints","getEraPromptHint","getEraTerm","buildTemporalHints","buildExposureHints","getRenderQualityPromptHint","getRenderQualityTerm","getCompositionEffectPromptHint","getCompositionEffectTerm","buildPostProcessHints"],"mappings":";;;;;;;;;AAoCO,IAAM,0BAA0B,CAAC,SAAA,EAAW,MAAA,EAAQ,MAAA,EAAQ,eAAe,kBAAkB;AAGpG,IAAM,0BAAA,GAAkD,IAAI,GAAA,CAAI,uBAAuB,CAAA;AAMvF,SAAS,UAAU,OAAA,EAAqD;AACtE,EAAA,IAAI,QAAQ,IAAA,KAAS,QAAA,EAAU,OAAO,OAAA,CAAQ,WAAW,EAAC;AAC1D,EAAA,OAAA,CAAQ,OAAA,CAAQ,cAAc,EAAC,EAAG,QAAQ,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AAC5D;AAMO,SAAS,mBAAA,GAAqD;AACnE,EAAA,MAAM,cAAA,GAAiBA,6CAAA,EAA4B,CAChD,MAAA,CAAO,CAAC,CAAA,KAAM,0BAAA,CAA2B,GAAA,CAAI,CAAA,CAAE,SAAS,CAAC,CAAA,CACzD,QAAQ,SAAS,CAAA;AACpB,EAAA,MAAM,MAAqC,CAAC,GAAGC,qCAAA,EAAoB,EAAG,GAAG,cAAc,CAAA;AACvF,EAAA,OAAO,IAAI,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,cAAc,IAAI,CAAA;AAC/C;AAGO,SAAS,eAAA,GAAuC;AACrD,EAAA,OAAO,IAAI,IAAI,mBAAA,EAAoB,CAAE,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AACvD;AA0BO,IAAM,+BAAA,GAAyD;AAAA;AAAA,EAEpE,gBAAA;AAAA;AAAA,EAEA,sBAAA;AAAA;AAAA,EAEA,eAAA;AAAA;AAAA,EAEA,sCAAA;AAAA;AAAA,EAEA,iDAAA;AAAA;AAAA,EAEA,gCAAA;AAAA;AAAA,EAEA,oCAAA;AAAA;AAAA,EAEA,uDAAA;AAAA;AAAA,EAEA,6HAAA;AAAA;AAAA,EAEA,wFAAA;AAAA;AAAA,EAEA,oEAAA;AAAA;AAAA,EAEA,kDAAA;AAAA;AAAA,EAEA,0EAAA;AAAA;AAAA,EAEA,iFAAA;AAAA;AAAA,EAEA,uDAAA;AAAA;AAAA;AAAA;AAAA,EAIA;AACF;AAmBO,SAAS,uBAAA,GAAiD;AAC/D,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAY,+BAA+B,CAAA;AAC3D,EAAA,KAAA,MAAW,CAAA,IAAK,qBAAoB,EAAG;AACrC,IAAA,IAAI,EAAE,UAAA,EAAY,GAAA,CAAI,IAAI,CAAA,CAAE,UAAA,CAAW,aAAa,CAAA;AAAA,EACtD;AACA,EAAA,OAAO,CAAC,GAAG,GAAG,EAAE,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,MAAA,IAAU,CAAC,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,MAAA,GAAS,EAAE,MAAM,CAAA;AACjF;AA4BA,IAAI,gBAAA,GAAiD,IAAA;AACrD,IAAI,0BAAA,GAA6B,EAAA;AAC1B,SAAS,sBAAA,GAAgD;AAC9D,EAAA,MAAM,SAASA,qCAAA,EAAoB;AACnC,EAAA,IAAI,gBAAA,IAAoB,0BAAA,KAA+B,MAAA,CAAO,MAAA,EAAQ,OAAO,gBAAA;AAC7E,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAY;AAC5B,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,MAAM,QAAA,GAAW,EAAE,SAAA,KAAc,KAAA,IAAS,CAACC,+BAAA,CAAc,GAAA,CAAI,EAAE,EAAE,CAAA;AACjE,IAAA,MAAM,YAAY,CAAA,CAAE,SAAA,KAAc,UAAUC,yCAAA,CAAwB,GAAA,CAAI,EAAE,EAAE,CAAA;AAC5E,IAAA,IAAI,CAAC,QAAA,IAAY,CAAC,SAAA,EAAW;AAC7B,IAAA,IAAI,EAAE,UAAA,EAAY,GAAA,CAAI,IAAI,CAAA,CAAE,UAAA,CAAW,aAAa,CAAA;AAAA,EACtD;AACA,EAAA,0BAAA,GAA6B,MAAA,CAAO,MAAA;AACpC,EAAA,gBAAA,GAAmB,CAAC,GAAG,GAAG,EAAE,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,MAAA,IAAU,CAAC,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,MAAA,GAAS,EAAE,MAAM,CAAA;AAC3F,EAAA,OAAO,gBAAA;AACT;AAEA,SAAS,eAAe,CAAA,EAAmB;AACzC,EAAA,OAAO,CAAA,CAAE,OAAA,CAAQ,qBAAA,EAAuB,MAAM,CAAA;AAChD;AAKA,SAAS,kBAAkB,MAAA,EAAwB;AACjD,EAAA,OAAO,OACJ,IAAA,EAAK,CACL,KAAA,CAAM,QAAQ,EACd,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAC,CAAA,CAC1B,IAAI,cAAc,CAAA,CAClB,KAAK,SAAS,CAAA;AACnB;AA0BO,SAAS,6BAA6B,OAAA,EAA+C;AAC1F,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,iBAAiB,CAAA,CAAE,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA;AACtE,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAC9B,EAAA,OAAO,CAAA,cAAA,EAAiB,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA,WAAA,CAAA;AACxC;AAOA,IAAI,mBAAA,GAAqC,IAAA;AACzC,IAAI,sBAAA,GAAyB,EAAA;AAC7B,SAAS,gBAAA,GAAkC;AACzC,EAAA,MAAM,UAAU,sBAAA,EAAuB;AACvC,EAAA,IAAI,mBAAA,IAAuB,sBAAA,KAA2B,OAAA,CAAQ,MAAA,EAAQ,OAAO,mBAAA;AAC7E,EAAA,sBAAA,GAAyB,OAAA,CAAQ,MAAA;AACjC,EAAA,MAAM,GAAA,GAAM,6BAA6B,OAAO,CAAA;AAChD,EAAA,mBAAA,GAAsB,QAAQ,IAAA,GAAO,IAAA,GAAO,IAAI,MAAA,CAAO,KAAK,GAAG,CAAA;AAC/D,EAAA,OAAO,mBAAA;AACT;AAiBA,IAAM,cAAA,GACJ,uIAAA;AAQF,IAAM,eAAA,GAAkB,kDAAA;AAIxB,IAAM,gBAAA,GAA0C,CAAC,cAAA,EAAgB,eAAe,CAAA;AAMhF,IAAM,iBAAA,GAAoB,8CAAA;AAiBnB,SAAS,qBAAqB,IAAA,EAA0C;AAC7E,EAAA,IAAI,OAAO,SAAS,QAAA,IAAY,IAAA,CAAK,MAAK,CAAE,MAAA,KAAW,GAAG,OAAO,KAAA;AACjE,EAAA,MAAM,KAAK,gBAAA,EAAiB;AAC5B,EAAA,IAAI,EAAA,IAAM,EAAA,CAAG,IAAA,CAAK,IAAI,GAAG,OAAO,IAAA;AAChC,EAAA,KAAA,MAAW,QAAQ,gBAAA,EAAkB;AACnC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG;AACnC,MAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AACrB,MAAA,IAAI,OAAO,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,GAAI,IAAI,OAAO,IAAA;AAAA,IAC3C;AAAA,EACF;AACA,EAAA,OAAO,iBAAA,CAAkB,KAAK,IAAI,CAAA;AACpC;AAQO,IAAM,mBAAA,GAAsB,CAAC,QAAA,EAAU,GAAG,uBAAuB;AAExE,SAAS,QAAA,CAAS,KAA8B,IAAA,EAAoD;AAClG,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AACxC,IAAA,IAAI,OAAO,MAAM,QAAA,EAAU;AACzB,MAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IAC7B,CAAA,MAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG;AAC3B,MAAA,MAAM,IAAA,GAAO,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA,KAAM,QAAA,IAAY,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,CAAE,CAAA;AACpE,MAAA,IAAI,IAAA,CAAK,MAAA,GAAS,CAAA,EAAG,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA;AAAA,IAChC,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAKO,SAAS,iCAAoE,MAAA,EAAc;AAChG,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,IAAI,CAAC,UAAU,OAAO,MAAA,KAAW,YAAY,CAACC,4BAAA,CAAW,MAA6D,CAAA,EAAG,OAAO,MAAA;AAChI,EAAA,MAAM,OAAO,eAAA,EAAgB;AAC7B,EAAA,MAAM,GAAA,GAA+B,EAAE,GAAG,MAAA,EAAO;AACjD,EAAA,KAAA,MAAW,OAAO,mBAAA,EAAqB;AACrC,IAAA,MAAM,CAAA,GAAI,IAAI,GAAG,CAAA;AACjB,IAAA,IAAI,CAAA,IAAK,OAAO,CAAA,KAAM,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG,GAAA,CAAI,GAAG,CAAA,GAAI,QAAA,CAAS,GAA8B,IAAI,CAAA;AAAA,EAC7G;AACA,EAAA,OAAO,GAAA;AACT;;;ACvSA,SAAS,MAAM,CAAA,EAAoB;AACjC,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,GAAI,EAAA;AACrC;AAGA,SAAS,wBAAwB,IAAA,EAAwC;AACvE,EAAA,MAAM,CAAA,GAAK,IAAA,CAAK,IAAA,IAAQ,EAAC;AACzB,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,CAAE,aAAA,EAAe,EAAE,QAAA,EAAU,CAAA,CAAE,UAAA,EAAY,CAAA,CAAE,YAAY,CAAA;AAC7E,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,IAAA,GAAO,MAAA,GAAS,CAAA,EAAG,OAAO,CAAA,CAAE,IAAA,EAAK;AAAA,EAClE;AACA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,8BAA8B,IAAA,EAAwC;AAC7E,EAAA,MAAM,IAAA,GAAO,wBAAwB,IAAI,CAAA;AACzC,EAAA,IAAI,MAAM,OAAO,IAAA;AACjB,EAAA,MAAM,YAAA,GAAe,OAAQ,IAAA,CAAK,IAAA,IAAQ,EAAC,EAA+B,YAAY,EAAE,IAAA,EAAK;AAC7F,EAAA,OAAO,YAAA,CAAa,MAAA,GAAS,CAAA,GAAI,YAAA,GAAe,MAAA;AAClD;AAIA,IAAM,sBAAA,GAAyB,CAAC,aAAA,EAAe,YAAA,EAAc,sBAAsB,CAAA;AAMnF,SAAS,yBAAyB,IAAA,EAA6B;AAC7D,EAAA,MAAM,CAAA,GAAK,IAAA,CAAK,IAAA,IAAQ,EAAC;AACzB,EAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,EAAA,IAAI,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,IAAKA,4BAAA,CAAW,MAA0C,CAAA,EAAG;AAC5H,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,sBAAA,CAAuB,IAAA,CAAK,CAAC,KAAA,KAAU,oBAAA,CAAqB,MAAM,CAAA,CAAE,KAAK,CAAC,CAAC,CAAC,CAAA;AACrF;AAGO,SAAS,0BAAA,CAA2B,MAAoB,GAAA,EAAwB;AACrF,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAY;AAClC,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AACnC,EAAA,IAAI,YAAA,GAAe,KAAA;AACnB,EAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,EAAK,KAAA,IAAS,EAAC,EAAG;AACnC,IAAA,IAAI,IAAA,CAAK,WAAW,IAAA,CAAK,EAAA,IAAO,KAAK,YAAA,KAAiB,QAAA,IAAY,IAAA,CAAK,YAAA,KAAiB,SAAA,EAAY;AACpG,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,CAAM,IAAA,CAAK,OAAK,CAAA,CAAE,EAAA,KAAO,KAAK,MAAM,CAAA;AACrD,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,IAAI,KAAK,YAAA,KAAiB,QAAA,EAAU,SAAA,CAAU,GAAA,CAAI,IAAI,EAAE,CAAA;AAAA,SACnD,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAC1B,IAAA,IAAI,wBAAA,CAAyB,GAAG,CAAA,EAAG,YAAA,GAAe,IAAA;AAClD,IAAA,MAAM,IAAA,GAAO,8BAA8B,GAAG,CAAA;AAC9C,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,YAAA,KAAiB,QAAA,GAAW,WAAA,GAAc,YAAA;AAC7D,IAAA,IAAI,CAAC,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA,EAAG,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EAC5C;AACA,EAAA,OAAO,EAAE,WAAA,EAAa,YAAA,EAAc,YAAA,EAAc,aAAa,CAAC,GAAG,SAAS,CAAA,CAAE,KAAK,CAAA,EAAA,KAAM,UAAA,CAAW,GAAA,CAAI,EAAE,CAAC,CAAA,EAAE;AAC/G;AAOA,SAAS,cAAA,CAAe,MAA+B,QAAA,EAA0B;AAC/E,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,MAAM,GAAA,GAAM,OAAO,IAAA,CAAK,OAAA,KAAY,WAAW,IAAA,CAAK,OAAA,CAAQ,MAAK,GAAI,EAAA;AACrE,EAAA,IAAI,GAAA,EAAK,SAAA,CAAU,IAAA,CAAK,GAAG,CAAA;AAC3B,EAAA,IAAI,QAAA,EAAU,SAAA,CAAU,IAAA,CAAK,QAAQ,CAAA;AACrC,EAAA,MAAM,IAAA,GAAO,OAAO,IAAA,CAAK,QAAA,KAAa,WAAW,IAAA,CAAK,QAAA,CAAS,MAAK,GAAI,EAAA;AACxE,EAAA,IAAI,IAAA,EAAM,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAC7B,EAAA,OAAOC,oCAAkB,SAAS,CAAA;AACpC;AAWA,SAAS,aAAa,IAAA,EAA2D;AAC/E,EAAA,MAAM,MAAM,IAAA,CAAK,QAAA;AACjB,EAAA,OAAO,GAAA,KAAQ,SAAA,IAAa,GAAA,KAAQ,MAAA,GAAS,GAAA,GAAM,MAAA;AACrD;AAGA,SAAS,MAAA,CAAU,IAAA,EAAsB,IAAA,EAAS,OAAA,EAAe;AAC/D,EAAA,OAAO,IAAA,KAAS,YAAY,OAAA,GAAU,IAAA;AACxC;AAIA,IAAM,sBAAA,GAAwG;AAAA,EAC5G,MAAA,EAAQ,EAAE,IAAA,EAAM,mDAAA,EAAqD,SAAS,eAAA,EAAgB;AAAA,EAC9F,QAAA,EAAU,EAAE,IAAA,EAAM,0CAAA,EAA4C,SAAS,iBAAA,EAAkB;AAAA,EACzF,OAAA,EAAS,EAAE,IAAA,EAAM,0DAAA,EAA4D,SAAS,gBAAA;AACxF,CAAA;AAgBO,SAAS,sBAAA,CACd,MACA,GAAA,EACQ;AACR,EAAA,OAAO,oBAAA,CAAqB,MAAM,GAAG,CAAA;AACvC;AASA,SAAS,oBAAA,CACP,IAAA,EACA,GAAA,EACA,SAAA,EACQ;AACR,EAAA,IAAI,CAAC,IAAA,EAAM,IAAA,EAAM,OAAO,EAAA;AACxB,EAAA,MAAM,IAAA,GAAQ,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC5B,EAAA,MAAM,IAAA,GAAuB,YAAA,CAAa,IAAI,CAAA,IAAK,SAAA,IAAa,MAAA;AAEhE,EAAA,IAAI,IAAA,CAAK,SAAS,eAAA,EAAiB;AACjC,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,IAAA,CAAK,YAAY,CAAA,IAAK,MAAA;AAC7C,IAAA,IAAI,CAAC,GAAA,EAAK,OAAO,cAAA,CAAe,IAAA,EAAMC,wDAAA,CAAuC,QAAA,EAAU,EAAC,EAAG,EAAC,EAAG,IAAI,CAAC,CAAA;AACpG,IAAA,MAAM,aAAuB,EAAC;AAC9B,IAAA,MAAM,WAAqB,EAAC;AAC5B,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAI,KAAA,EAAO;AAC5B,MAAA,IAAI,IAAA,CAAK,MAAA,KAAW,IAAA,CAAK,EAAA,EAAI;AAC7B,MAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,IAAA,CAAK,MAAM,CAAA;AACtD,MAAA,IAAI,CAAC,GAAA,EAAK;AAKV,MAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,GAAA,EAAK,MAAA,EAAW,IAAI,CAAA;AACtD,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,IAAI,IAAA,CAAK,YAAA,KAAiB,YAAA,EAAc,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,WAAA,IACnD,IAAA,CAAK,YAAA,KAAiB,UAAA,EAAY,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,IAC/D;AACA,IAAA,OAAO,eAAe,IAAA,EAAMA,wDAAA,CAAuC,UAAU,UAAA,EAAY,QAAA,EAAU,IAAI,CAAC,CAAA;AAAA,EAC1G;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,YAAA,EAAc;AAC9B,IAAA,MAAM,MAAM,IAAA,CAAK,UAAA;AACjB,IAAA,MAAM,eACJ,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GACb,GAAA,CAAI,OAAO,CAAC,CAAA,KAAmB,OAAO,CAAA,KAAM,YAAY,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA,GACnE,KAAA,CAAM,GAAG,CAAA,IAAK,MAAA;AACrB,IAAA,MAAM,MAAA,GAA2B;AAAA,MAC/B,QAAA,EAAW,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AAAA,MAC9B,QAAA,EAAW,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AAAA,MAC9B,SAAA,EAAW,KAAA,CAAM,IAAA,CAAK,SAAS;AAAA,KACjC;AAEA,IAAA,MAAM,YAAA,GAAeC,6CAA2B,IAAI,CAAA;AACpD,IAAA,MAAM,WAAA,GAAc,YAAA,GAAe,EAAE,YAAA,EAAa,GAAI,MAAA;AACtD,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,cAAA,CAAe,IAAA,EAAMC,sDAAA,CAAqC,YAAA,EAAc,EAAC,EAAG,EAAC,EAAG,MAAA,EAAQ,IAAA,EAAM,WAAW,CAAC,CAAA;AAAA,IACnH;AACA,IAAA,MAAM,aAAuB,EAAC;AAC9B,IAAA,MAAM,WAAqB,EAAC;AAC5B,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAI,KAAA,EAAO;AAC5B,MAAA,IAAI,IAAA,CAAK,MAAA,KAAW,IAAA,CAAK,EAAA,EAAI;AAC7B,MAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,IAAA,CAAK,MAAM,CAAA;AACtD,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,GAAA,EAAK,MAAA,EAAW,IAAI,CAAA;AACtD,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,IAAS,IAAA,CAAK,YAAA,KAAiB,YAAA,EAAc,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,WAAA,IACxD,IAAA,CAAK,YAAA,KAAiB,UAAA,EAAc,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,IACjE;AACA,IAAA,OAAO,cAAA,CAAe,MAAMA,sDAAA,CAAqC,YAAA,EAAc,YAAY,QAAA,EAAU,MAAA,EAAQ,IAAA,EAAM,WAAW,CAAC,CAAA;AAAA,EACjI;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,cAAA,EAAgB;AAChC,IAAA,MAAM,MAAM,IAAA,CAAK,WAAA;AACjB,IAAA,MAAM,WACJ,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GACb,GAAA,CAAI,OAAO,CAAC,CAAA,KAAmB,OAAO,CAAA,KAAM,YAAY,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA,GACnE,KAAA,CAAM,GAAG,CAAA,IAAK,MAAA;AACrB,IAAA,MAAM,MAAA,GAA4B;AAAA,MAChC,QAAA,EAAW,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AAAA,MAC9B,QAAA,EAAW,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AAAA,MAC9B,SAAA,EAAW,KAAA,CAAM,IAAA,CAAK,SAAS;AAAA,KACjC;AACA,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,cAAA,CAAe,MAAMC,uDAAA,CAAsC,QAAA,EAAU,EAAC,EAAG,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,IAC/F;AACA,IAAA,MAAM,cAAwB,EAAC;AAC/B,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAI,KAAA,EAAO;AAC5B,MAAA,IAAI,IAAA,CAAK,MAAA,KAAW,IAAA,CAAK,EAAA,EAAI;AAC7B,MAAA,IAAI,IAAA,CAAK,iBAAiB,QAAA,EAAU;AACpC,MAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,IAAA,CAAK,MAAM,CAAA;AACtD,MAAA,IAAI,CAAC,GAAA,EAAK;AACV,MAAA,MAAM,IAAA,GAAO,wBAAwB,GAAG,CAAA;AACxC,MAAA,IAAI,IAAA,EAAM,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA;AAAA,IACjC;AACA,IAAA,OAAO,eAAe,IAAA,EAAMA,uDAAA,CAAsC,UAAU,WAAA,EAAa,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,EACxG;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,kBAAA,EAAoB;AACpC,IAAA,MAAM,MAAM,IAAA,CAAK,eAAA;AACjB,IAAA,MAAM,WACJ,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GACb,GAAA,CAAI,OAAO,CAAC,CAAA,KAAmB,OAAO,CAAA,KAAM,YAAY,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA,GACnE,KAAA,CAAM,GAAG,CAAA,IAAK,MAAA;AACrB,IAAA,MAAM,MAAA,GAAgC;AAAA,MACpC,QAAA,EAAU,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AAAA,MAC7B,IAAA,EAAU,KAAA,CAAM,IAAA,CAAK,IAAI;AAAA,KAC3B;AACA,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,OAAO,cAAA,CAAe,IAAA,EAAMC,2DAAA,CAA0C,QAAA,EAAU,IAAI,EAAC,EAAG,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,IACvG;AACA,IAAA,MAAM,EAAE,WAAA,EAAa,YAAA,EAAc,cAAa,GAAI,0BAAA,CAA2B,MAAM,GAAG,CAAA;AACxF,IAAA,OAAO,cAAA;AAAA,MACL,IAAA;AAAA,MACAA,2DAAA,CAA0C,UAAU,WAAA,EAAa,YAAA,EAAc,QAAQ,IAAA,EAAM,EAAE,cAAc;AAAA,KAC/G;AAAA,EACF;AAEA,EAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,IAAA,CAAK,IAAA,EAAM,MAAM,IAAI,CAAA;AAClD,EAAA,IAAI,MAAM,OAAO,IAAA;AAOjB,EAAA,MAAM,GAAA,GAAMC,kCAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AACtC,EAAA,IAAI,GAAA,EAAK,IAAA,KAAS,QAAA,IAAY,GAAA,CAAI,UAAA,EAAY;AAC5C,IAAA,MAAM,EAAA,GAAK,OAAO,IAAA,CAAK,GAAA,CAAI,UAAU,MAAM,QAAA,GAAY,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA,GAAe,EAAA;AACzF,IAAA,MAAM,GAAA,GAAM,IAAI,OAAA,EAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AAChD,IAAA,IAAI,GAAA,SAAY,MAAA,CAAO,IAAA,EAAM,IAAI,UAAA,EAAYC,6BAAA,CAAY,GAAG,CAAC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,IAAA;AACT;AAaA,SAAS,eAAA,CACP,IAAA,EACA,IAAA,EACA,IAAA,GAAuB,MAAA,EACf;AACR,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,SAAA;AACH,MAAA,OAAO,cAAA,CAAe,MAAMC,mCAAA,CAAkB,IAAA,EAAM,OAAO,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IAC7E,KAAK,UAAA;AACH,MAAA,OAAO,cAAA,CAAe,MAAMC,oCAAA,CAAmB,IAAA,EAAM,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IACvE,KAAK,MAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,mCAAA,EAAmBC,6BAAW,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAC,CAAA;AAAA,IAC5F,KAAK,eAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,2CAAA,EAA2BC,qCAAmB,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,YAAY,CAAC,CAAC,CAAA;AAAA,IACpH,KAAK,YAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,wCAAA,EAAwBC,kCAAgB,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,SAAS,CAAC,CAAC,CAAA;AAAA;AAAA;AAAA;AAAA,IAK3G,KAAK,aAAA;AACH,MAAA,OAAOC,sCAAA,CAAsB,IAAA,IAAQ,EAAC,EAAkD,IAAI,CAAA;AAAA,IAC9F,KAAK,YAAA;AACH,MAAA,OAAOC,qCAAA,CAAqB,IAAA,IAAQ,EAAC,EAAiD,IAAI,CAAA;AAAA,IAC5F,KAAK,iBAAA;AACH,MAAA,OAAOC,2CAAA,CAA2B,IAAA,IAAQ,EAAC,EAAuD,IAAI,CAAA;AAAA,IACxG,KAAK,iBAAA;AACH,MAAA,OAAOC,0CAAA,CAA0B,IAAA,IAAQ,EAAC,EAAsD,IAAI,CAAA;AAAA,IACtG,KAAK,gBAAA;AACH,MAAA,OAAOC,yCAAA,CAAyB,IAAA,IAAQ,EAAC,EAAqD,IAAI,CAAA;AAAA,IACpG,KAAK,QAAA;AACH,MAAA,OAAOC,kCAAA,CAAiB,IAAA,EAAM,IAAI,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,IAC/C,KAAK,MAAA;AACH,MAAA,OAAOC,gCAAA,CAAe,IAAA,EAAM,IAAI,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,IAC7C,KAAK,MAAA;AACH,MAAA,OAAOC,gCAAA,CAAe,IAAA,EAAM,IAAI,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,IAC7C,KAAK,SAAA;AACH,MAAA,OAAOC,mCAAA,CAAkB,IAAA,EAAM,IAAI,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,IAEhD,KAAK,YAAA;AACH,MAAA,OAAO,cAAA,CAAe,MAAMC,sCAAA,CAAqB,IAAA,CAAK,YAAY,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IACpF,KAAK,WAAA;AACH,MAAA,OAAO,cAAA,CAAe,MAAMC,oCAAA,CAAmB,IAAA,CAAK,UAAU,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IAChF,KAAK,OAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,oCAAA,EAAoBC,8BAAY,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,KAAK,CAAC,CAAC,CAAA;AAAA,IAC/F,KAAK,SAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,sCAAA,EAAsBC,gCAAc,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,OAAO,CAAC,CAAC,CAAA;AAAA,IACrG,KAAK,cAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,0CAAA,EAA0BC,oCAAkB,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,WAAW,CAAC,CAAC,CAAA;AAAA,IACjH,KAAK,UAAA;AACH,MAAA,OAAO,eAAe,IAAA,EAAMC,oCAAA,CAAmB,IAAA,CAAK,QAAA,EAAU,IAAI,CAAC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKrE,KAAK,QAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,yCAAA,EAAyBC,mCAAiB,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,MAAM,CAAC,CAAC,CAAA;AAAA,IAC1G,KAAK,SAAA,EAAW;AACd,MAAA,MAAM,CAAA,GAAIC,oCAAA,CAAmB,KAAA,CAAM,IAAA,CAAK,OAAO,CAAC,CAAA;AAChD,MAAA,OAAO,cAAA,CAAe,MAAM,MAAA,CAAO,IAAA,EAAM,EAAE,IAAA,EAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,IAC1D;AAAA,IACA,KAAK,QAAA,EAAU;AACb,MAAA,MAAM,CAAA,GAAIC,mCAAA,CAAkB,KAAA,CAAM,IAAA,CAAK,MAAM,CAAC,CAAA;AAC9C,MAAA,OAAO,cAAA,CAAe,MAAM,MAAA,CAAO,IAAA,EAAM,EAAE,IAAA,EAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,IAC1D;AAAA,IACA,KAAK,WAAA,EAAa;AAChB,MAAA,MAAM,CAAA,GAAIC,sCAAA,CAAqB,KAAA,CAAM,IAAA,CAAK,SAAS,CAAC,CAAA;AACpD,MAAA,OAAO,cAAA,CAAe,MAAM,MAAA,CAAO,IAAA,EAAM,EAAE,IAAA,EAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,IAC1D;AAAA,IACA,KAAK,aAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,yCAAA,EAAyBC,mCAAiB,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,UAAU,CAAC,CAAC,CAAA;AAAA,IAC9G,KAAK,UAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,uCAAA,EAAuBC,iCAAe,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAC,CAAC,CAAA;AAAA,IACxG,KAAK,WAAA;AACH,MAAA,OAAO,cAAA,CAAe,MAAMC,oCAAA,CAAmB,IAAA,CAAK,UAAU,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IAChF,KAAK,cAAA;AACH,MAAA,OAAO,eAAe,IAAA,EAAMC,wCAAA,CAAuB,IAAA,CAAK,YAAA,EAAc,IAAI,CAAC,CAAA;AAAA,IAC7E,KAAK,WAAA;AACH,MAAA,OAAO,eAAe,IAAA,EAAMC,qCAAA,CAAoB,IAAA,CAAK,SAAA,EAAW,IAAI,CAAC,CAAA;AAAA,IACvE,KAAK,KAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,kCAAA,EAAkBC,4BAAU,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA;AAAA,IACzF,KAAK,UAAA;AACH,MAAA,OAAO,cAAA,CAAe,MAAMC,oCAAA,CAAmB,IAAA,EAAM,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IACvE,KAAK,mBAAA;AACH,MAAA,OAAO,cAAA,CAAe,MAAMC,oCAAA,CAAmB,IAAA,EAAM,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IACvE,KAAK,gBAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,4CAAA,EAA4BC,sCAAoB,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,aAAa,CAAC,CAAC,CAAA;AAAA,IACvH,KAAK,qBAAA;AACH,MAAA,OAAO,cAAA,CAAe,IAAA,EAAM,MAAA,CAAO,IAAA,EAAMC,gDAAA,EAAgCC,0CAAwB,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,iBAAiB,CAAC,CAAC,CAAA;AAAA,IACnI,KAAK,sBAAA;AACH,MAAA,OAAO,cAAA,CAAe,MAAMC,uCAAA,CAAsB,IAAA,CAAK,aAAa,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA;AAAA;AAAA,IAGtF,KAAK,QAAA,EAAU;AACb,MAAA,MAAM,IAAA,GAAO,sBAAA,CAAuB,KAAA,CAAM,IAAA,CAAK,MAAM,CAAC,CAAA;AACtD,MAAA,OAAO,OAAO,MAAA,CAAO,IAAA,EAAM,KAAK,IAAA,EAAM,IAAA,CAAK,OAAO,CAAA,GAAI,EAAA;AAAA,IACxD;AAAA;AAAA;AAAA,IAIA,KAAK,MAAA;AACH,MAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,CAAE,IAAA,EAAK;AAAA,IAC/B,KAAK,aAAA;AAKH,MAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,CAAE,IAAA,EAAK;AAAA,IAC/B,KAAK,aAAA;AACH,MAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,CAAE,IAAA,EAAK;AAAA,IAC/B;AACE,MAAA,OAAO,EAAA;AAAA;AAEb","file":"chunk-LK2CZK5U.cjs","sourcesContent":["/**\n * The minor-age floor — Layer 1 of spec 2026-09-01-app-reports-triage-design.md\n * §3.3 (W1-a). Content-free: this module decides WHICH catalog entries a minor\n * subject may not carry; the clause a deployment appends lives in its\n * registered PromptPolicy (backend/src/lib/prompt-policies/), never here.\n *\n * `ADULT_ONLY_FLAG`, `ADULT_AGE_IDS`, `MINOR_IMPLYING_TYPE_IDS` and\n * `isMinorAge` live in the import-free leaf `age-signal.ts` and are\n * re-exported here unchanged — this module's own catalog-funnel imports\n * (`person-packs.js`, `picker-catalogs.js`) are exactly what `person.ts` /\n * `styling.ts` must NOT reach through, on pain of reopening the\n * person → age-floor → picker-catalogs load-time cycle (see `age-signal.ts`'s\n * header). `person.ts` / `styling.ts` import `isMinorAge` from\n * `age-signal.ts` directly instead of from here.\n */\n\nimport { getRegisteredPeople } from \"./person-packs.js\"\nimport { getRegisteredPickerCatalogs, type PickerCatalog, type PickerOption } from \"./picker-catalogs.js\"\nimport { isMinorAge, ADULT_AGE_IDS, MINOR_IMPLYING_TYPE_IDS } from \"./age-signal.js\"\n\nexport { ADULT_ONLY_FLAG, ADULT_AGE_IDS, MINOR_IMPLYING_TYPE_IDS, isMinorAge } from \"./age-signal.js\"\n\n/** Shape shared by every catalog entry the floor reads. */\nexport interface AdultOnlyEntry {\n readonly id: string\n readonly promptHint: string\n readonly term?: string\n readonly adultOnly?: true\n}\n\n/** The picker catalogs (by `catalogId`) this floor sweeps beside person.\n * Exported because it is the SINGLE source of truth for two things that used\n * to be maintained by hand and drifted: which catalogs `getAdultOnlyEntries`\n * sweeps for the flag, and which analyzer keys `FLOORED_PICKER_KEYS` strips\n * flagged ids out of (a `photo-genre` swept for the flag but absent from the\n * strip list let `glamour-portrait` survive on a minor). */\nexport const ADULT_SWEPT_CATALOG_IDS = [\"styling\", \"mood\", \"pose\", \"photo-genre\", \"character-motion\"] as const\n\n/** Membership form of the list above (the sweep does one lookup per catalog). */\nconst ADULT_SWEPT_CATALOG_ID_SET: ReadonlySet<string> = new Set(ADULT_SWEPT_CATALOG_IDS)\n\n/** Flatten a catalog's options regardless of shape: single-dim catalogs carry\n * `options` directly, multi-dim ones carry `dimensions[].options` (mirrors\n * `applyDeny` in catalog-packs.ts, the other consumer that has to handle\n * both shapes). */\nfunction optionsOf(catalog: PickerCatalog): ReadonlyArray<PickerOption> {\n if (catalog.kind === \"single\") return catalog.options ?? []\n return (catalog.dimensions ?? []).flatMap((d) => d.options)\n}\n\n/** Every entry, across the swept catalogs, that carries the flag. Reads every\n * catalog through the pack-composed funnel — `getRegisteredPeople()` for\n * person, `getRegisteredPickerCatalogs()` for styling/mood/pose/photo-genre —\n * so a pack-added or pack-replaced entry is included. */\nexport function getAdultOnlyEntries(): ReadonlyArray<AdultOnlyEntry> {\n const catalogEntries = getRegisteredPickerCatalogs()\n .filter((c) => ADULT_SWEPT_CATALOG_ID_SET.has(c.catalogId))\n .flatMap(optionsOf)\n const all: ReadonlyArray<AdultOnlyEntry> = [...getRegisteredPeople(), ...catalogEntries]\n return all.filter((e) => e.adultOnly === true)\n}\n\n/** The set of flagged ids (fast membership for the collectors). */\nexport function getAdultOnlyIds(): ReadonlySet<string> {\n return new Set(getAdultOnlyEntries().map((e) => e.id))\n}\n\n/**\n * The pre-rework `promptHint` of every `adultOnly` entry the spec\n * (2026-09-01-app-reports-triage-design §3.3) listed for rewording — including\n * `eye-state-half-lidded` and `feature-collarbone-visible`, which the W1-b\n * harness initially left byte-identical (0/10 and 0/22 render rate under\n * either wording) and a 2026-09-03 replay then found renderable wordings for\n * — plus the hard-coded midriff+navel fold clause. These strings are permanently part of the strip\n * set: a consumer that has not bumped `@nodaro/prompts` still emits them, and\n * the client-assembled `seedPrompt` path is exactly how the 2026-07-30\n * minor-age prompts reached a provider. Retiring can only ever cause an EXTRA\n * strip, and only for a subject `isMinorAge` has already judged a minor — so\n * the list only grows, never shrinks.\n *\n * `promptHint` ONLY, for the same reason `getAdultOnlyHintStrings` gives:\n * `term` is short display vocabulary and the composed-catalog projection\n * back-fills a derived `term` for every option, so terms collide with benign\n * everyday text. Assembled prompts and client seedPrompts are built from\n * hints, never from terms. The three W1-b entries that are NOT flagged —\n * `texture-dewy`, `texture-baby-soft`, `eye-state-staring-camera` (spec\n * §3.3's \"deliberately not flagged\" list) — are absent: their old wording\n * never belonged to the floor.\n *\n * 15 flagged hints + the fold literal = 16.\n */\nexport const RETIRED_ADULT_ONLY_HINT_STRINGS: ReadonlyArray<string> = [\n // bust-very-full\n \"very full bust\",\n // silhouette-hourglass\n \"hourglass silhouette\",\n // waist-defined\n \"defined waist\",\n // lip-state-glossy\n \"with high-shine glossy wet-look lips\",\n // lip-state-parted\n \"with lips slightly parted, taking a soft breath\",\n // lip-state-bitten\n \"playfully biting the lower lip\",\n // eye-state-half-lidded\n \"with heavy half-lidded sleepy eyes\",\n // texture-glistening\n \"with glistening skin, sweat or oil catching the light\",\n // texture-shower-fresh-wet\n \"with just-out-of-the-shower wet skin, water beading on the surface and rolling in slow droplets down the curves of the body\",\n // feature-bare-shoulders\n \"with bare shoulders exposed, the line of the collarbone and shoulder muscles uncovered\",\n // feature-collarbone-visible\n \"with a prominent collarbone clearly defined and catching the light\",\n // feature-midriff-visible\n \"wearing a cropped style with the midriff visible\",\n // state-fitted — the 2026-07-30 incident clause\n \"the clothing fitted and form-conscious, hugging the contours of the body\",\n // state-wet\n \"the clothing soaked and wet, the fabric clinging to the body and dripping water\",\n // pose `biting-lip` (the lip-state-bitten twin)\n \"biting the lower lip with a subtle playful expression\",\n // the hard-coded midriff+navel fold in emitIndependentFragments — not any\n // entry's hint, so retiring it ADDS a needle for a clause that really is\n // emitted verbatim.\n \"wearing a cropped style, midriff and navel visible\",\n]\n\n/** Every full prompt-hint string a flagged entry can inject, lower-cased,\n * longest first — the backend policy strips text that contains any of them\n * (Layer 2), which is how flagged wording arriving inside free text (a\n * client-assembled seedPrompt) is caught. Seeded with\n * `RETIRED_ADULT_ONLY_HINT_STRINGS` so a catalog rewording can never narrow\n * the strip set for a consumer still shipping the pre-rephrase wording.\n *\n * `promptHint` ONLY, deliberately — `term` is analyzer/UI vocabulary\n * (compact-mode display), and `picker-catalogs.ts`'s composed-catalog\n * projection back-fills a `term` for EVERY option via `deriveTerm(label)`\n * when no explicit term was authored (e.g. \"lounging\", \"cropped top\",\n * \"school uniform\", \"lying down\"). Those short, generic derived terms are\n * exactly the kind of everyday word that collides with unrelated, benign\n * text and over-strips it. Assembled prompts and client seedPrompts are\n * built from HINTS, never from terms, so hints are the only strings that\n * can actually arrive verbatim in free text — terms don't need to be (and\n * must not be) swept here. */\nexport function getAdultOnlyHintStrings(): ReadonlyArray<string> {\n const out = new Set<string>(RETIRED_ADULT_ONLY_HINT_STRINGS)\n for (const e of getAdultOnlyEntries()) {\n if (e.promptHint) out.add(e.promptHint.toLowerCase())\n }\n return [...out].filter((s) => s.length >= 8).sort((a, b) => b.length - a.length)\n}\n\n/**\n * Every full prompt-hint string that DESCRIBES A MINOR — the mirror of\n * `getAdultOnlyHintStrings`, and the needle list for the TEXT signal below.\n *\n * Why a text signal exists at all: `isMinorAge` reads the structured picker\n * value, and the P0 arrival path does not have one. A thin client can create a\n * character row carrying only `{nodeId, name, projectId}` and send the picker\n * selection as an already-assembled `seedPrompt`, so `row.person === null`\n * while the prompt itself says \"a young child around 5 years old\". That client\n * assembles the text FROM THESE HINTS, which is exactly why the catalog is the\n * drift-proof needle list: a new minor age entry is swept the day it is added,\n * with no second list to remember.\n *\n * Selection is DERIVED, never hand-listed: an `age` entry is a minor unless its\n * id is in the `ADULT_AGE_IDS` allow-list (so a new age id is inside the floor\n * by default — same ratchet as `isMinorAge`), plus every `type` entry named by\n * `MINOR_IMPLYING_TYPE_IDS`. Read through the pack-composed funnel\n * (`getRegisteredPeople()`), so a deployment pack's entries are swept too.\n *\n * `promptHint` ONLY — never `term` and never `label`, for the same reason\n * `getAdultOnlyHintStrings` gives: `term` is short display vocabulary\n * (\"in their teens\" as a compact chip) and the composed-catalog projection\n * back-fills a derived `term` for every option, so terms collide with benign\n * text. The `>= 8` filter drops `age-custom`'s empty hint (`\"\"`), which would\n * otherwise match every string ever written.\n */\nlet cachedMinorHints: ReadonlyArray<string> | null = null\nlet cachedMinorHintSourceCount = -1\nexport function getMinorAgeHintStrings(): ReadonlyArray<string> {\n const people = getRegisteredPeople()\n if (cachedMinorHints && cachedMinorHintSourceCount === people.length) return cachedMinorHints\n const out = new Set<string>()\n for (const e of people) {\n const minorAge = e.dimension === \"age\" && !ADULT_AGE_IDS.has(e.id)\n const minorType = e.dimension === \"type\" && MINOR_IMPLYING_TYPE_IDS.has(e.id)\n if (!minorAge && !minorType) continue\n if (e.promptHint) out.add(e.promptHint.toLowerCase())\n }\n cachedMinorHintSourceCount = people.length\n cachedMinorHints = [...out].filter((s) => s.length >= 8).sort((a, b) => b.length - a.length)\n return cachedMinorHints\n}\n\nfunction escapeReSource(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n}\n\n/** One needle's regex source: the phrase's tokens — split on whitespace AND\n * hyphens — escaped and rejoined by `[\\s-]+`, so it matches however the text\n * that carries it happened to be spaced or hyphenated. */\nfunction needleTokenSource(needle: string): string {\n return needle\n .trim()\n .split(/[\\s-]+/)\n .filter((t) => t.length > 0)\n .map(escapeReSource)\n .join(\"[\\\\s-]+\")\n}\n\n/**\n * The word-bounded alternation SOURCE for a needle list — the one place both\n * layers of the floor build their matcher, so they can never disagree about\n * what \"the same phrase\" means.\n *\n * Two properties, both load-bearing:\n * - **Separator tolerance.** A catalog hint is authored with single spaces\n * (\"very full bust\"), but the free text that carries it is written by a\n * human or an LLM and arrives as \"very-full bust\" or \"very full bust\".\n * A literal alternation misses those, and a miss is a flagged phrase\n * reaching the provider on a minor's prompt. Each needle's tokens are\n * joined by `[\\s-]+`, which requires AT LEAST one separator — so\n * \"very fullbust\" (no separator at all) is still not a match, and the\n * phrase can't silently widen into a substring rule.\n * - **Word boundaries.** `(?<![\\w-])` / `(?![\\w-])` keep a needle from\n * gluing onto an adjacent word's characters (\"mesh tops\" must survive a\n * \"mesh top\" needle).\n *\n * Ordering is the CALLER's: pass needles longest-first so the alternation\n * consumes the longest match at a given position instead of leaving debris.\n * Returns `null` when there is nothing to match (an empty list would otherwise\n * compile to `(?:)`, which matches everywhere). Flags are the caller's too —\n * `\"i\"` for a `.test()` instance, `\"gi\"` for one used with `String.replace`.\n */\nexport function buildNeedleAlternationSource(needles: ReadonlyArray<string>): string | null {\n const alts = needles.map(needleTokenSource).filter((s) => s.length > 0)\n if (alts.length === 0) return null\n return `(?<![\\\\w-])(?:${alts.join(\"|\")})(?![\\\\w-])`\n}\n\n/** Needle alternation over `getMinorAgeHintStrings()`, word-bounded on both\n * sides so a hint can only match a whole phrase. Deliberately NOT global:\n * this instance is only ever `.test()`ed, and a `/g` regex would carry\n * `lastIndex` across calls. Cached by needle count (packs are registered\n * before the first prompt is assembled). */\nlet cachedMinorNeedleRe: RegExp | null = null\nlet cachedMinorNeedleCount = -1\nfunction minorNeedleRegex(): RegExp | null {\n const needles = getMinorAgeHintStrings()\n if (cachedMinorNeedleRe && cachedMinorNeedleCount === needles.length) return cachedMinorNeedleRe\n cachedMinorNeedleCount = needles.length\n const src = buildNeedleAlternationSource(needles)\n cachedMinorNeedleRe = src === null ? null : new RegExp(src, \"i\")\n return cachedMinorNeedleRe\n}\n\n/**\n * NUMBER-FIRST age shapes: the ones `buildAgeFragment` (person.ts) emits for a\n * CUSTOM age (\"N years old\", \"N year old\", \"N-year-old\") and the catalog's own\n * \"2-3 years old\" range (the FIRST number decides), plus the colloquial tails a\n * human or an LLM writes instead — \"12yo\", \"12 yo\", \"12 y.o.\", \"12 y/o\",\n * \"12 yr old\", \"12-yr-old\", \"12yrs old\", \"12 years of age\". The cut is `< 20`,\n * the same boundary `isMinorAge` uses for `customAge` and the same one\n * `buildAgeFragment` switches to \"in their teens\" at.\n *\n * Both boundaries are load-bearing. The LEADING one stops a match inside a\n * larger token; the TRAILING one is what makes \"a 5 year older sibling\" a\n * non-hit (\"old\" may not glue onto \"older\") and what stops \"yo\" from firing\n * inside \"12 young\" or \"12 yoga\". Used via `matchAll`, which clones the regex\n * rather than advancing this instance's `lastIndex`.\n */\nconst NUMERIC_AGE_RE =\n /(?<![\\w-])(\\d{1,3})(?:\\s*-\\s*\\d{1,3})?\\s*-?\\s*(?:years?\\s*-?\\s*old|yrs?\\s*-?\\s*old|y(?:\\.\\s*o\\.?|\\/o|o)|years?\\s+of\\s+age)(?![\\w-])/gi\n\n/**\n * AGE-FIRST shapes, where the number trails the word instead of leading it:\n * \"age 12\", \"aged 12\", \"at the age of 12\". The leading boundary is what keeps\n * \"image 12\" / \"page 12\" out (the `age` there is glued to a preceding word\n * character), and the trailing one keeps \"aged 12th\" out.\n */\nconst PREFIXED_AGE_RE = /(?<![\\w-])aged?\\s+(?:of\\s+)?(\\d{1,3})(?![\\w-])/gi\n\n/** Every rule that reads a NUMBER out of the text, each capturing the age in\n * group 1. Iterated together below so a new shape is one array entry. */\nconst AGE_NUMBER_RULES: ReadonlyArray<RegExp> = [NUMERIC_AGE_RE, PREFIXED_AGE_RE]\n\n/** The one NON-numeric shape `buildAgeFragment` emits below 20 (`${n} years\n * old, in their teens`). Kept as its own rule rather than as a catalog term.\n * Separator-tolerant on the same terms as the needle alternation, so\n * \"in their teens\" and \"in-their-teens\" are the same phrase. */\nconst IN_THEIR_TEENS_RE = /(?<![\\w-])in[\\s-]+their[\\s-]+teens(?![\\w-])/i\n\n/**\n * True when free text describes a MINOR subject. Three rules, in order:\n * 1. any minor-age / minor-implying-type prompt hint, word-bounded;\n * 2. a numeric age below 20 in any shape `buildAgeFragment` emits;\n * 3. the literal \"in their teens\".\n *\n * Deliberately NOT a bare-word check: \"child\", \"teen\", \"kid\" alone must never\n * fire, or an adult prompt that merely MENTIONS a child (\"a mother holding her\n * child\") would be floored — the spec's \"adults are byte-identical\" is a hard\n * requirement, so every rule here is a full phrase or a bounded number.\n *\n * Pairs with `isMinorAge`, never replaces it: the structured picker value is\n * the primary signal; this catches the same subject when only the assembled\n * text survives.\n */\nexport function containsMinorAgeHint(text: string | null | undefined): boolean {\n if (typeof text !== \"string\" || text.trim().length === 0) return false\n const re = minorNeedleRegex()\n if (re && re.test(text)) return true\n for (const rule of AGE_NUMBER_RULES) {\n for (const m of text.matchAll(rule)) {\n const n = Number(m[1])\n if (Number.isFinite(n) && n < 20) return true\n }\n }\n return IN_THEIR_TEENS_RE.test(text)\n}\n\n/** The analyzer/import value keys the floor strips flagged ids out of:\n * `person` plus EVERY catalog the flag sweep reads. DERIVED, never\n * hand-listed — the hand-written version omitted `photo-genre` while the\n * sweep included it, so a minor kept `glamour-portrait`. The analyzer JSON is\n * keyed by picker type id (`describe-to-picker.ts`), which is the same string\n * as the catalog id, so this list IS the set of keys to visit. */\nexport const FLOORED_PICKER_KEYS = [\"person\", ...ADULT_SWEPT_CATALOG_IDS] as const\n\nfunction stripIds(obj: Record<string, unknown>, drop: ReadonlySet<string>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n if (typeof v === \"string\") {\n if (!drop.has(v)) out[k] = v\n } else if (Array.isArray(v)) {\n const kept = v.filter((x) => !(typeof x === \"string\" && drop.has(x)))\n if (kept.length > 0) out[k] = kept\n } else {\n out[k] = v\n }\n }\n return out\n}\n\n/** Analyzer / import post-filter: when the person value describes a minor,\n * remove every flagged id from the person, styling, pose and mood values.\n * Identity (same reference) for an adult. */\nexport function applyMinorAgeFloorToPickerValues<T extends Record<string, unknown>>(values: T): T {\n const person = values.person\n if (!person || typeof person !== \"object\" || !isMinorAge(person as { age?: string; customAge?: number; type?: string })) return values\n const drop = getAdultOnlyIds()\n const out: Record<string, unknown> = { ...values }\n for (const key of FLOORED_PICKER_KEYS) {\n const v = out[key]\n if (v && typeof v === \"object\" && !Array.isArray(v)) out[key] = stripIds(v as Record<string, unknown>, drop)\n }\n return out as T\n}\n","import type { HintNodeLike, HintEdgeLike, HintGraphContext } from \"@nodaro/shared/types\"\nexport type { HintNodeLike, HintEdgeLike, HintGraphContext }\n/**\n * Single source of truth for parameter-node prompt-hint text.\n *\n * Every parameter node (framing, lens, camera-format, lighting, color-look,\n * atmosphere, style, setting, person, mood, pose, styling, temporal, tone,\n * text-prompt, camera-motion) dispatches through `getParameterPromptHint` to\n * produce the descriptive clause it contributes to a consumer's prompt.\n *\n * The frontend DAG executor and backend workflow orchestrator both call this,\n * so the text injected via the `cinematography` handle is identical to the\n * text injected when the node is wired directly into a Text Prompt / LLM Chat\n * / Combine Text input.\n *\n * Camera-motion is graph-aware: when `ctx` is provided the function walks the\n * node's `startState`/`endState` incoming edges and composes a fully formed\n * sentence via `composeCameraMotionHintFromConnections`. Without `ctx` only\n * the bare motion description is returned.\n */\n\nimport { buildFramingHints } from \"./framing.js\"\nimport { buildLightingHints } from \"./lighting.js\"\nimport { getLensPromptHint, getLensTerm } from \"./lens.js\"\nimport { getCameraFormatPromptHint, getCameraFormatTerm } from \"./camera-format.js\"\nimport { getColorLookPromptHint, getColorLookTerm } from \"./color-look.js\"\nimport { buildAtmosphereHints } from \"./atmosphere.js\"\nimport { buildActionFxHints } from \"./action-fx.js\"\nimport { getStylePromptHint, getStyleTerm } from \"./style.js\"\nimport { getSettingPromptHint, getSettingTerm } from \"./setting.js\"\nimport { getLoopSubjectPromptHint, getLoopSubjectTerm } from \"./loop-subject.js\"\nimport { buildPersonHints } from \"./person.js\"\nimport { buildMoodHints } from \"./mood.js\"\nimport { buildPoseHints } from \"./pose.js\"\nimport { buildStylingHints } from \"./styling.js\"\nimport { buildTemporalHints } from \"./temporal.js\"\nimport { composeCameraMotionHintFromConnections } from \"./camera-motions.js\"\nimport { joinHintFragments } from \"./hint-join.js\"\nimport { composeTransitionHintFromConnections, readTransitionOptionValues, type TransitionDuration, type TransitionIntensity, type TransitionPosition, type TransitionTiming } from \"./transitions.js\"\nimport { composeCharacterFxHintFromConnections, type CharacterFxDuration, type CharacterFxIntensity, type CharacterFxPosition, type CharacterFxTiming } from \"./character-fx.js\"\nimport { composeCharacterMotionHintFromConnections, type CharacterMotionPace, type CharacterMotionPosition, type CharacterMotionTiming } from \"./character-motion.js\"\nimport { containsMinorAgeHint, isMinorAge } from \"./age-floor.js\"\nimport { buildMaterialHints } from \"./materials.js\"\nimport { curatedAnimalPromptHint, curatedAnimalTerm, curatedVehicleText, curatedWeaponText, curatedFurnitureText } from \"./shared-catalog-overlay.js\"\nimport { getPhotoGenrePromptHint, getPhotoGenreTerm } from \"./photo-genre.js\"\nimport { getBackdropPromptHint, getBackdropTerm } from \"./backdrop.js\"\nimport { buildHeldPropHints } from \"./held-prop.js\"\nimport { buildPhotographerHints } from \"./photographer.js\"\nimport { buildAestheticHints } from \"./aesthetic.js\"\nimport { getEraPromptHint, getEraTerm } from \"./era.js\"\nimport { buildExposureHints } from \"./exposure-settings.js\"\nimport { getRenderQualityPromptHint, getRenderQualityTerm } from \"./render-quality.js\"\nimport { getCompositionEffectPromptHint, getCompositionEffectTerm } from \"./composition-effects.js\"\nimport { buildPostProcessHints } from \"./post-process-effects.js\"\nimport { buildMusicGenreHints } from \"./music-genre.js\"\nimport { buildMusicMoodHints } from \"./music-mood.js\"\nimport { buildInstrumentationHints } from \"./instrumentation.js\"\nimport { buildVoiceCharacterHints } from \"./voice-character.js\"\nimport { buildVoiceDeliveryHints } from \"./voice-delivery.js\"\nimport { getPickerCatalog } from \"./picker-catalogs.js\"\nimport { resolveTerm, type PickerHintMode } from \"./term.js\"\n\n\nfunction asStr(v: unknown): string {\n return typeof v === \"string\" ? v : \"\"\n}\n\n/** Extract the display name from a character / face / object / location ref node. */\nfunction extractCharacterRefName(node: HintNodeLike): string | undefined {\n const d = (node.data ?? {}) as Record<string, unknown>\n const candidates = [d.characterName, d.faceName, d.objectName, d.locationName]\n for (const v of candidates) {\n if (typeof v === \"string\" && v.trim().length > 0) return v.trim()\n }\n return undefined\n}\n\n/** Character Motion's name read: the shared character / face / object / location\n * read, then a creature's `creatureName`. Local to Character Motion so the\n * Character FX prompt, which shares `extractCharacterRefName`, stays unchanged. */\nfunction extractCharacterMotionRefName(node: HintNodeLike): string | undefined {\n const name = extractCharacterRefName(node)\n if (name) return name\n const creatureName = asStr(((node.data ?? {}) as Record<string, unknown>).creatureName).trim()\n return creatureName.length > 0 ? creatureName : undefined\n}\n\n/** Free-text fields a character / face / object / location ref node describes its subject in.\n * A creature ref uses the same `description` / `canonicalDescription` names. */\nconst REF_DESCRIPTION_FIELDS = [\"description\", \"seedPrompt\", \"canonicalDescription\"] as const\n\n/** True when a character / face / object / location ref node describes a minor:\n * its structured `person` age (the primary signal) or an age phrase in its\n * free-text description. Feeds the Character Motion floor (adult-only moves\n * dropped) — errs toward flooring, never toward letting an adult-only move through. */\nfunction extractCharacterRefMinor(node: HintNodeLike): boolean {\n const d = (node.data ?? {}) as Record<string, unknown>\n const person = d.person\n if (person && typeof person === \"object\" && !Array.isArray(person) && isMinorAge(person as Parameters<typeof isMinorAge>[0])) {\n return true\n }\n return REF_DESCRIPTION_FIELDS.some((field) => containsMinorAgeHint(asStr(d[field])))\n}\n\n/** The preview, diagnostics and execution use identical graph bindings. */\nexport function getCharacterMotionBindings(node: HintNodeLike, ctx?: HintGraphContext) {\n const targetNames: string[] = []\n const partnerNames: string[] = []\n const targetIds = new Set<string>()\n const partnerIds = new Set<string>()\n let subjectMinor = false\n for (const edge of ctx?.edges ?? []) {\n if (edge.target !== node.id || (edge.targetHandle !== \"target\" && edge.targetHandle !== \"partner\")) continue\n const src = ctx?.nodes.find(n => n.id === edge.source)\n if (!src) continue\n if (edge.targetHandle === \"target\") targetIds.add(src.id)\n else partnerIds.add(src.id)\n if (extractCharacterRefMinor(src)) subjectMinor = true\n const name = extractCharacterMotionRefName(src)\n if (!name) continue\n const names = edge.targetHandle === \"target\" ? targetNames : partnerNames\n if (!names.includes(name)) names.push(name)\n }\n return { targetNames, partnerNames, subjectMinor, selfPairing: [...targetIds].some(id => partnerIds.has(id)) }\n}\n\n/** Compose `[preText, mainHint, postText]` into a comma-joined string,\n * honoring the user's free-text fragments around the structured hint.\n * Helpers like `getStylePromptHint` that already include preText/postText\n * composition (build*Hints in mood/person/etc.) bypass this — they\n * return the fully-composed string directly. */\nfunction withCustomText(data: Record<string, unknown>, mainHint: string): string {\n const fragments: string[] = []\n const pre = typeof data.preText === \"string\" ? data.preText.trim() : \"\"\n if (pre) fragments.push(pre)\n if (mainHint) fragments.push(mainHint)\n const post = typeof data.postText === \"string\" ? data.postText.trim() : \"\"\n if (post) fragments.push(post)\n return joinHintFragments(fragments)\n}\n\n/**\n * The node-level hint mode a picker declares via `data.hintMode`.\n *\n * Only the two documented values count; anything else (a stale value, a typo,\n * a non-string) is treated as UNDECLARED and falls back — to the inherited\n * mode when the node is resolved as an upstream input, and to `\"full\"`\n * otherwise. Compact is opt-in, so an unrecognized value can never silently\n * shorten a prompt.\n */\nfunction readHintMode(data: Record<string, unknown>): PickerHintMode | undefined {\n const raw = data.hintMode\n return raw === \"compact\" || raw === \"full\" ? raw : undefined\n}\n\n/** Pick the full-hint or the compact-term getter for the active mode. */\nfunction byMode<T>(mode: PickerHintMode, full: T, compact: T): T {\n return mode === \"compact\" ? compact : full\n}\n\n/** How much a shot moves (the Motion node's three steps), as the clause it\n * adds to a video prompt; the compact form is the bare term. */\nconst MOTION_INTENSITY_HINTS: Readonly<Record<string, { readonly full: string; readonly compact: string }>> = {\n subtle: { full: \"subtle, gentle motion with slow, minimal movement\", compact: \"subtle motion\" },\n moderate: { full: \"moderate, natural motion at an even pace\", compact: \"moderate motion\" },\n dynamic: { full: \"dynamic, energetic motion with fast, pronounced movement\", compact: \"dynamic motion\" },\n}\n\n/**\n * Dispatch by parameter-node type to its prompt-hint string. For camera-motion,\n * pass `ctx` to include the composed start/end clauses; otherwise only the\n * bare motion description is returned.\n *\n * VERBOSITY — a picker node may set `data.hintMode` to `\"compact\"` to inject\n * its short professional `term` (\"whip pan left\", \"hard cut\") instead of the\n * long `promptHint`. Absent, or any unrecognized value, means `\"full\"`, whose\n * output is byte-identical to what this function returned before hint modes\n * existed. ONLY the base catalog fragment swaps: `preText`/`postText`, the\n * transition / camera-motion / character-fx timing and start-state/end-state\n * clauses, multi-pick joining and multi-dimension composition are emitted the\n * same way in both modes.\n */\nexport function getParameterPromptHint(\n node: HintNodeLike | undefined,\n ctx?: HintGraphContext,\n): string {\n return resolveParameterHint(node, ctx)\n}\n\n/**\n * The dispatch body. `inherited` carries the mode DOWN into the nodes wired to\n * a composer's `startState` / `endState` handles, so a compact transition\n * composes compact start/end clauses rather than mixing a term with two\n * paragraphs. A node that declares its own `hintMode` still wins over what it\n * inherits.\n */\nfunction resolveParameterHint(\n node: HintNodeLike | undefined,\n ctx?: HintGraphContext,\n inherited?: PickerHintMode,\n): string {\n if (!node?.type) return \"\"\n const data = (node.data ?? {}) as Record<string, unknown>\n const mode: PickerHintMode = readHintMode(data) ?? inherited ?? \"full\"\n\n if (node.type === \"camera-motion\") {\n const motionId = asStr(data.cameraMotion) || undefined\n if (!ctx) return withCustomText(data, composeCameraMotionHintFromConnections(motionId, [], [], mode))\n const startHints: string[] = []\n const endHints: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n // Pass no ctx for nested resolution: startState/endState inputs are\n // themselves parameter nodes (framing/tone/etc.) that don't need graph\n // context, and avoiding recursion keeps the walk cycle-safe. The mode\n // rides down so the composed clause stays at one level of detail.\n const hint = resolveParameterHint(src, undefined, mode)\n if (!hint) continue\n if (edge.targetHandle === \"startState\") startHints.push(hint)\n else if (edge.targetHandle === \"endState\") endHints.push(hint)\n }\n return withCustomText(data, composeCameraMotionHintFromConnections(motionId, startHints, endHints, mode))\n }\n\n if (node.type === \"transition\") {\n const raw = data.transition\n const transitionId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: TransitionTiming = {\n position: asStr(data.position) as TransitionPosition | undefined,\n duration: asStr(data.duration) as TransitionDuration | undefined,\n intensity: asStr(data.intensity) as TransitionIntensity | undefined,\n }\n // A picked row's own options (a wipe's `wipeDirection`), off the same node data.\n const optionValues = readTransitionOptionValues(data)\n const hintOptions = optionValues ? { optionValues } : undefined\n if (!ctx) {\n return withCustomText(data, composeTransitionHintFromConnections(transitionId, [], [], timing, mode, hintOptions))\n }\n const startHints: string[] = []\n const endHints: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n const hint = resolveParameterHint(src, undefined, mode) // no ctx — cycle-safe\n if (!hint) continue\n if (edge.targetHandle === \"startState\") startHints.push(hint)\n else if (edge.targetHandle === \"endState\") endHints.push(hint)\n }\n return withCustomText(data, composeTransitionHintFromConnections(transitionId, startHints, endHints, timing, mode, hintOptions))\n }\n\n if (node.type === \"character-fx\") {\n const raw = data.characterFx\n const effectId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: CharacterFxTiming = {\n position: asStr(data.position) as CharacterFxPosition | undefined,\n duration: asStr(data.duration) as CharacterFxDuration | undefined,\n intensity: asStr(data.intensity) as CharacterFxIntensity | undefined,\n }\n if (!ctx) {\n return withCustomText(data, composeCharacterFxHintFromConnections(effectId, [], timing, mode))\n }\n const targetNames: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n if (edge.targetHandle !== \"target\") continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n const name = extractCharacterRefName(src)\n if (name) targetNames.push(name)\n }\n return withCustomText(data, composeCharacterFxHintFromConnections(effectId, targetNames, timing, mode))\n }\n\n if (node.type === \"character-motion\") {\n const raw = data.characterMotion\n const motionId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: CharacterMotionTiming = {\n position: asStr(data.position) as CharacterMotionPosition | undefined,\n pace: asStr(data.pace) as CharacterMotionPace | undefined,\n }\n if (!ctx) {\n return withCustomText(data, composeCharacterMotionHintFromConnections(motionId, [], [], timing, mode))\n }\n const { targetNames, partnerNames, subjectMinor } = getCharacterMotionBindings(node, ctx)\n return withCustomText(\n data,\n composeCharacterMotionHintFromConnections(motionId, targetNames, partnerNames, timing, mode, { subjectMinor }),\n )\n }\n\n const base = resolveBaseHint(node.type, data, mode)\n if (base) return base\n // Pack-extend fallback: a single-dim pack entry the per-catalog getter (which\n // reads the frozen base array) can't resolve. Resolve it against the\n // registered (pack-composed) catalog's options. Composition already resolved\n // `PickerOption.term`; `resolveTerm` is idempotent over a resolved option and\n // is called anyway so a pack option that reached this array by some other\n // route still injects SOMETHING in compact mode rather than `undefined`.\n const cat = getPickerCatalog(node.type)\n if (cat?.kind === \"single\" && cat.valueField) {\n const id = typeof data[cat.valueField] === \"string\" ? (data[cat.valueField] as string) : \"\"\n const opt = cat.options?.find((o) => o.id === id)\n if (opt) return byMode(mode, opt.promptHint, resolveTerm(opt))\n }\n return base\n}\n\n/**\n * Base (upstream) hint dispatch by node type — the per-catalog getters read the\n * frozen base arrays. Pack-added single-dim ids are resolved by the caller\n * against the registered (pack-composed) catalog.\n *\n * `mode` selects the base fragment only: the compact `get<Name>Term` getter /\n * `build<Name>Terms` builder instead of the verbose one. The `withCustomText`\n * wrapper, the builders' own pre/post composition, and the free-text node\n * types (tone / style-guide / text-prompt — user prose, not catalog copy) are\n * identical in both modes.\n */\nfunction resolveBaseHint(\n type: string,\n data: Record<string, unknown>,\n mode: PickerHintMode = \"full\",\n): string {\n switch (type) {\n case \"framing\":\n return withCustomText(data, buildFramingHints(data, false, mode).join(\", \"))\n case \"lighting\":\n return withCustomText(data, buildLightingHints(data, mode).join(\", \"))\n case \"lens\":\n return withCustomText(data, byMode(mode, getLensPromptHint, getLensTerm)(asStr(data.lens)))\n case \"camera-format\":\n return withCustomText(data, byMode(mode, getCameraFormatPromptHint, getCameraFormatTerm)(asStr(data.cameraFormat)))\n case \"color-look\":\n return withCustomText(data, byMode(mode, getColorLookPromptHint, getColorLookTerm)(asStr(data.colorLook)))\n\n // build*Hints in music-* / voice-* / mood / person / etc. compose\n // preText/postText internally — bypass the wrapper to avoid double-\n // composition.\n case \"music-genre\":\n return buildMusicGenreHints((data ?? {}) as Parameters<typeof buildMusicGenreHints>[0], mode)\n case \"music-mood\":\n return buildMusicMoodHints((data ?? {}) as Parameters<typeof buildMusicMoodHints>[0], mode)\n case \"instrumentation\":\n return buildInstrumentationHints((data ?? {}) as Parameters<typeof buildInstrumentationHints>[0], mode)\n case \"voice-character\":\n return buildVoiceCharacterHints((data ?? {}) as Parameters<typeof buildVoiceCharacterHints>[0], mode)\n case \"voice-delivery\":\n return buildVoiceDeliveryHints((data ?? {}) as Parameters<typeof buildVoiceDeliveryHints>[0], mode)\n case \"person\":\n return buildPersonHints(data, mode).join(\", \")\n case \"mood\":\n return buildMoodHints(data, mode).join(\", \")\n case \"pose\":\n return buildPoseHints(data, mode).join(\", \")\n case \"styling\":\n return buildStylingHints(data, mode).join(\", \")\n\n case \"atmosphere\":\n return withCustomText(data, buildAtmosphereHints(data.atmosphere, mode).join(\", \"))\n case \"action-fx\":\n return withCustomText(data, buildActionFxHints(data.actionFx, mode).join(\", \"))\n case \"style\":\n return withCustomText(data, byMode(mode, getStylePromptHint, getStyleTerm)(asStr(data.style)))\n case \"setting\":\n return withCustomText(data, byMode(mode, getSettingPromptHint, getSettingTerm)(asStr(data.setting)))\n case \"loop-subject\":\n return withCustomText(data, byMode(mode, getLoopSubjectPromptHint, getLoopSubjectTerm)(asStr(data.loopSubject)))\n case \"material\":\n return withCustomText(data, buildMaterialHints(data.material, mode))\n // The four object-entity catalogs are owned by @nodaro/shared and overlaid\n // in shared-catalog-overlay.ts — the ONE module every prompt-text read of\n // them goes through (the subject fold uses it too). Each returns \"\" on a\n // miss, so the entry lookup is the module's job, not this switch's.\n case \"animal\":\n return withCustomText(data, byMode(mode, curatedAnimalPromptHint, curatedAnimalTerm)(asStr(data.animal)))\n case \"vehicle\": {\n const t = curatedVehicleText(asStr(data.vehicle))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"weapon\": {\n const t = curatedWeaponText(asStr(data.weapon))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"furniture\": {\n const t = curatedFurnitureText(asStr(data.furniture))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"photo-genre\":\n return withCustomText(data, byMode(mode, getPhotoGenrePromptHint, getPhotoGenreTerm)(asStr(data.photoGenre)))\n case \"backdrop\":\n return withCustomText(data, byMode(mode, getBackdropPromptHint, getBackdropTerm)(asStr(data.backdrop)))\n case \"held-prop\":\n return withCustomText(data, buildHeldPropHints(data.heldProp, mode).join(\", \"))\n case \"photographer\":\n return withCustomText(data, buildPhotographerHints(data.photographer, mode))\n case \"aesthetic\":\n return withCustomText(data, buildAestheticHints(data.aesthetic, mode))\n case \"era\":\n return withCustomText(data, byMode(mode, getEraPromptHint, getEraTerm)(asStr(data.era)))\n case \"temporal\":\n return withCustomText(data, buildTemporalHints(data, mode).join(\", \"))\n case \"exposure-settings\":\n return withCustomText(data, buildExposureHints(data, mode).join(\", \"))\n case \"render-quality\":\n return withCustomText(data, byMode(mode, getRenderQualityPromptHint, getRenderQualityTerm)(asStr(data.renderQuality)))\n case \"composition-effects\":\n return withCustomText(data, byMode(mode, getCompositionEffectPromptHint, getCompositionEffectTerm)(asStr(data.compositionEffect)))\n case \"post-process-effects\":\n return withCustomText(data, buildPostProcessHints(data.postProcess, mode).join(\", \"))\n // Motion intensity: a Generation Settings node that a video node's\n // Settings input takes as a prompt fragment (video only).\n case \"motion\": {\n const hint = MOTION_INTENSITY_HINTS[asStr(data.motion)]\n return hint ? byMode(mode, hint.full, hint.compact) : \"\"\n }\n\n // Free text authored by the user, not catalog copy — there is no shorter\n // professional form to swap in, so these are identical in both modes.\n case \"tone\":\n return asStr(data.tone).trim()\n case \"style-guide\":\n // The node's whole purpose is injecting its style text into consumer\n // prompts; without this case, {Style Guide} refs stayed as literal\n // brace text and direct wires injected nothing (only fieldMappings\n // worked, via getParameterValue).\n return asStr(data.text).trim()\n case \"text-prompt\":\n return asStr(data.text).trim()\n default:\n return \"\"\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/age-floor.ts","../src/parameter-prompt-hint.ts"],"names":["getRegisteredPickerCatalogs","getRegisteredPeople","ADULT_AGE_IDS","MINOR_IMPLYING_TYPE_IDS","isMinorAge","joinHintFragments","composeCameraMotionHintFromConnections","readTransitionOptionValues","composeTransitionHintFromConnections","composeCharacterFxHintFromConnections","composeCharacterMotionHintFromConnections","getPickerCatalog","resolveTerm","buildFramingHints","buildLightingHints","getLensPromptHint","getLensTerm","getCameraFormatPromptHint","getCameraFormatTerm","getColorLookPromptHint","getColorLookTerm","buildMusicGenreHints","buildMusicMoodHints","buildInstrumentationHints","buildVoiceCharacterHints","buildVoiceDeliveryHints","buildPersonHints","buildMoodHints","buildPoseHints","buildStylingHints","buildAtmosphereHints","buildActionFxHints","getStylePromptHint","getStyleTerm","getSettingPromptHint","getSettingTerm","getLoopSubjectPromptHint","getLoopSubjectTerm","buildMaterialHints","curatedAnimalPromptHint","curatedAnimalTerm","curatedVehicleText","curatedWeaponText","curatedFurnitureText","getPhotoGenrePromptHint","getPhotoGenreTerm","getBackdropPromptHint","getBackdropTerm","buildHeldPropHints","buildPhotographerHints","buildAestheticHints","getEraPromptHint","getEraTerm","buildTemporalHints","buildExposureHints","getRenderQualityPromptHint","getRenderQualityTerm","getCompositionEffectPromptHint","getCompositionEffectTerm","buildPostProcessHints"],"mappings":"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","file":"chunk-PWWM7Q3T.cjs","sourcesContent":["/**\n * The minor-age floor — Layer 1 of spec 2026-09-01-app-reports-triage-design.md\n * §3.3 (W1-a). Content-free: this module decides WHICH catalog entries a minor\n * subject may not carry; the clause a deployment appends lives in its\n * registered PromptPolicy (backend/src/lib/prompt-policies/), never here.\n *\n * `ADULT_ONLY_FLAG`, `ADULT_AGE_IDS`, `MINOR_IMPLYING_TYPE_IDS` and\n * `isMinorAge` live in the import-free leaf `age-signal.ts` and are\n * re-exported here unchanged — this module's own catalog-funnel imports\n * (`person-packs.js`, `picker-catalogs.js`) are exactly what `person.ts` /\n * `styling.ts` must NOT reach through, on pain of reopening the\n * person → age-floor → picker-catalogs load-time cycle (see `age-signal.ts`'s\n * header). `person.ts` / `styling.ts` import `isMinorAge` from\n * `age-signal.ts` directly instead of from here.\n */\n\nimport { getRegisteredPeople } from \"./person-packs.js\"\nimport { getRegisteredPickerCatalogs, type PickerCatalog, type PickerOption } from \"./picker-catalogs.js\"\nimport { isMinorAge, ADULT_AGE_IDS, MINOR_IMPLYING_TYPE_IDS } from \"./age-signal.js\"\n\nexport { ADULT_ONLY_FLAG, ADULT_AGE_IDS, MINOR_IMPLYING_TYPE_IDS, isMinorAge } from \"./age-signal.js\"\n\n/** Shape shared by every catalog entry the floor reads. */\nexport interface AdultOnlyEntry {\n readonly id: string\n readonly promptHint: string\n readonly term?: string\n readonly adultOnly?: true\n}\n\n/** The picker catalogs (by `catalogId`) this floor sweeps beside person.\n * Exported because it is the SINGLE source of truth for two things that used\n * to be maintained by hand and drifted: which catalogs `getAdultOnlyEntries`\n * sweeps for the flag, and which analyzer keys `FLOORED_PICKER_KEYS` strips\n * flagged ids out of (a `photo-genre` swept for the flag but absent from the\n * strip list let `glamour-portrait` survive on a minor). */\nexport const ADULT_SWEPT_CATALOG_IDS = [\"styling\", \"mood\", \"pose\", \"photo-genre\", \"character-motion\"] as const\n\n/** Membership form of the list above (the sweep does one lookup per catalog). */\nconst ADULT_SWEPT_CATALOG_ID_SET: ReadonlySet<string> = new Set(ADULT_SWEPT_CATALOG_IDS)\n\n/** Flatten a catalog's options regardless of shape: single-dim catalogs carry\n * `options` directly, multi-dim ones carry `dimensions[].options` (mirrors\n * `applyDeny` in catalog-packs.ts, the other consumer that has to handle\n * both shapes). */\nfunction optionsOf(catalog: PickerCatalog): ReadonlyArray<PickerOption> {\n if (catalog.kind === \"single\") return catalog.options ?? []\n return (catalog.dimensions ?? []).flatMap((d) => d.options)\n}\n\n/** Every entry, across the swept catalogs, that carries the flag. Reads every\n * catalog through the pack-composed funnel — `getRegisteredPeople()` for\n * person, `getRegisteredPickerCatalogs()` for styling/mood/pose/photo-genre —\n * so a pack-added or pack-replaced entry is included. */\nexport function getAdultOnlyEntries(): ReadonlyArray<AdultOnlyEntry> {\n const catalogEntries = getRegisteredPickerCatalogs()\n .filter((c) => ADULT_SWEPT_CATALOG_ID_SET.has(c.catalogId))\n .flatMap(optionsOf)\n const all: ReadonlyArray<AdultOnlyEntry> = [...getRegisteredPeople(), ...catalogEntries]\n return all.filter((e) => e.adultOnly === true)\n}\n\n/** The set of flagged ids (fast membership for the collectors). */\nexport function getAdultOnlyIds(): ReadonlySet<string> {\n return new Set(getAdultOnlyEntries().map((e) => e.id))\n}\n\n/**\n * The pre-rework `promptHint` of every `adultOnly` entry the spec\n * (2026-09-01-app-reports-triage-design §3.3) listed for rewording — including\n * `eye-state-half-lidded` and `feature-collarbone-visible`, which the W1-b\n * harness initially left byte-identical (0/10 and 0/22 render rate under\n * either wording) and a 2026-09-03 replay then found renderable wordings for\n * — plus the hard-coded midriff+navel fold clause. These strings are permanently part of the strip\n * set: a consumer that has not bumped `@nodaro/prompts` still emits them, and\n * the client-assembled `seedPrompt` path is exactly how the 2026-07-30\n * minor-age prompts reached a provider. Retiring can only ever cause an EXTRA\n * strip, and only for a subject `isMinorAge` has already judged a minor — so\n * the list only grows, never shrinks.\n *\n * `promptHint` ONLY, for the same reason `getAdultOnlyHintStrings` gives:\n * `term` is short display vocabulary and the composed-catalog projection\n * back-fills a derived `term` for every option, so terms collide with benign\n * everyday text. Assembled prompts and client seedPrompts are built from\n * hints, never from terms. The three W1-b entries that are NOT flagged —\n * `texture-dewy`, `texture-baby-soft`, `eye-state-staring-camera` (spec\n * §3.3's \"deliberately not flagged\" list) — are absent: their old wording\n * never belonged to the floor.\n *\n * 15 flagged hints + the fold literal = 16.\n */\nexport const RETIRED_ADULT_ONLY_HINT_STRINGS: ReadonlyArray<string> = [\n // bust-very-full\n \"very full bust\",\n // silhouette-hourglass\n \"hourglass silhouette\",\n // waist-defined\n \"defined waist\",\n // lip-state-glossy\n \"with high-shine glossy wet-look lips\",\n // lip-state-parted\n \"with lips slightly parted, taking a soft breath\",\n // lip-state-bitten\n \"playfully biting the lower lip\",\n // eye-state-half-lidded\n \"with heavy half-lidded sleepy eyes\",\n // texture-glistening\n \"with glistening skin, sweat or oil catching the light\",\n // texture-shower-fresh-wet\n \"with just-out-of-the-shower wet skin, water beading on the surface and rolling in slow droplets down the curves of the body\",\n // feature-bare-shoulders\n \"with bare shoulders exposed, the line of the collarbone and shoulder muscles uncovered\",\n // feature-collarbone-visible\n \"with a prominent collarbone clearly defined and catching the light\",\n // feature-midriff-visible\n \"wearing a cropped style with the midriff visible\",\n // state-fitted — the 2026-07-30 incident clause\n \"the clothing fitted and form-conscious, hugging the contours of the body\",\n // state-wet\n \"the clothing soaked and wet, the fabric clinging to the body and dripping water\",\n // pose `biting-lip` (the lip-state-bitten twin)\n \"biting the lower lip with a subtle playful expression\",\n // the hard-coded midriff+navel fold in emitIndependentFragments — not any\n // entry's hint, so retiring it ADDS a needle for a clause that really is\n // emitted verbatim.\n \"wearing a cropped style, midriff and navel visible\",\n]\n\n/** Every full prompt-hint string a flagged entry can inject, lower-cased,\n * longest first — the backend policy strips text that contains any of them\n * (Layer 2), which is how flagged wording arriving inside free text (a\n * client-assembled seedPrompt) is caught. Seeded with\n * `RETIRED_ADULT_ONLY_HINT_STRINGS` so a catalog rewording can never narrow\n * the strip set for a consumer still shipping the pre-rephrase wording.\n *\n * `promptHint` ONLY, deliberately — `term` is analyzer/UI vocabulary\n * (compact-mode display), and `picker-catalogs.ts`'s composed-catalog\n * projection back-fills a `term` for EVERY option via `deriveTerm(label)`\n * when no explicit term was authored (e.g. \"lounging\", \"cropped top\",\n * \"school uniform\", \"lying down\"). Those short, generic derived terms are\n * exactly the kind of everyday word that collides with unrelated, benign\n * text and over-strips it. Assembled prompts and client seedPrompts are\n * built from HINTS, never from terms, so hints are the only strings that\n * can actually arrive verbatim in free text — terms don't need to be (and\n * must not be) swept here. */\nexport function getAdultOnlyHintStrings(): ReadonlyArray<string> {\n const out = new Set<string>(RETIRED_ADULT_ONLY_HINT_STRINGS)\n for (const e of getAdultOnlyEntries()) {\n if (e.promptHint) out.add(e.promptHint.toLowerCase())\n }\n return [...out].filter((s) => s.length >= 8).sort((a, b) => b.length - a.length)\n}\n\n/**\n * Every full prompt-hint string that DESCRIBES A MINOR — the mirror of\n * `getAdultOnlyHintStrings`, and the needle list for the TEXT signal below.\n *\n * Why a text signal exists at all: `isMinorAge` reads the structured picker\n * value, and the P0 arrival path does not have one. A thin client can create a\n * character row carrying only `{nodeId, name, projectId}` and send the picker\n * selection as an already-assembled `seedPrompt`, so `row.person === null`\n * while the prompt itself says \"a young child around 5 years old\". That client\n * assembles the text FROM THESE HINTS, which is exactly why the catalog is the\n * drift-proof needle list: a new minor age entry is swept the day it is added,\n * with no second list to remember.\n *\n * Selection is DERIVED, never hand-listed: an `age` entry is a minor unless its\n * id is in the `ADULT_AGE_IDS` allow-list (so a new age id is inside the floor\n * by default — same ratchet as `isMinorAge`), plus every `type` entry named by\n * `MINOR_IMPLYING_TYPE_IDS`. Read through the pack-composed funnel\n * (`getRegisteredPeople()`), so a deployment pack's entries are swept too.\n *\n * `promptHint` ONLY — never `term` and never `label`, for the same reason\n * `getAdultOnlyHintStrings` gives: `term` is short display vocabulary\n * (\"in their teens\" as a compact chip) and the composed-catalog projection\n * back-fills a derived `term` for every option, so terms collide with benign\n * text. The `>= 8` filter drops `age-custom`'s empty hint (`\"\"`), which would\n * otherwise match every string ever written.\n */\nlet cachedMinorHints: ReadonlyArray<string> | null = null\nlet cachedMinorHintSourceCount = -1\nexport function getMinorAgeHintStrings(): ReadonlyArray<string> {\n const people = getRegisteredPeople()\n if (cachedMinorHints && cachedMinorHintSourceCount === people.length) return cachedMinorHints\n const out = new Set<string>()\n for (const e of people) {\n const minorAge = e.dimension === \"age\" && !ADULT_AGE_IDS.has(e.id)\n const minorType = e.dimension === \"type\" && MINOR_IMPLYING_TYPE_IDS.has(e.id)\n if (!minorAge && !minorType) continue\n if (e.promptHint) out.add(e.promptHint.toLowerCase())\n }\n cachedMinorHintSourceCount = people.length\n cachedMinorHints = [...out].filter((s) => s.length >= 8).sort((a, b) => b.length - a.length)\n return cachedMinorHints\n}\n\nfunction escapeReSource(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n}\n\n/** One needle's regex source: the phrase's tokens — split on whitespace AND\n * hyphens — escaped and rejoined by `[\\s-]+`, so it matches however the text\n * that carries it happened to be spaced or hyphenated. */\nfunction needleTokenSource(needle: string): string {\n return needle\n .trim()\n .split(/[\\s-]+/)\n .filter((t) => t.length > 0)\n .map(escapeReSource)\n .join(\"[\\\\s-]+\")\n}\n\n/**\n * The word-bounded alternation SOURCE for a needle list — the one place both\n * layers of the floor build their matcher, so they can never disagree about\n * what \"the same phrase\" means.\n *\n * Two properties, both load-bearing:\n * - **Separator tolerance.** A catalog hint is authored with single spaces\n * (\"very full bust\"), but the free text that carries it is written by a\n * human or an LLM and arrives as \"very-full bust\" or \"very full bust\".\n * A literal alternation misses those, and a miss is a flagged phrase\n * reaching the provider on a minor's prompt. Each needle's tokens are\n * joined by `[\\s-]+`, which requires AT LEAST one separator — so\n * \"very fullbust\" (no separator at all) is still not a match, and the\n * phrase can't silently widen into a substring rule.\n * - **Word boundaries.** `(?<![\\w-])` / `(?![\\w-])` keep a needle from\n * gluing onto an adjacent word's characters (\"mesh tops\" must survive a\n * \"mesh top\" needle).\n *\n * Ordering is the CALLER's: pass needles longest-first so the alternation\n * consumes the longest match at a given position instead of leaving debris.\n * Returns `null` when there is nothing to match (an empty list would otherwise\n * compile to `(?:)`, which matches everywhere). Flags are the caller's too —\n * `\"i\"` for a `.test()` instance, `\"gi\"` for one used with `String.replace`.\n */\nexport function buildNeedleAlternationSource(needles: ReadonlyArray<string>): string | null {\n const alts = needles.map(needleTokenSource).filter((s) => s.length > 0)\n if (alts.length === 0) return null\n return `(?<![\\\\w-])(?:${alts.join(\"|\")})(?![\\\\w-])`\n}\n\n/** Needle alternation over `getMinorAgeHintStrings()`, word-bounded on both\n * sides so a hint can only match a whole phrase. Deliberately NOT global:\n * this instance is only ever `.test()`ed, and a `/g` regex would carry\n * `lastIndex` across calls. Cached by needle count (packs are registered\n * before the first prompt is assembled). */\nlet cachedMinorNeedleRe: RegExp | null = null\nlet cachedMinorNeedleCount = -1\nfunction minorNeedleRegex(): RegExp | null {\n const needles = getMinorAgeHintStrings()\n if (cachedMinorNeedleRe && cachedMinorNeedleCount === needles.length) return cachedMinorNeedleRe\n cachedMinorNeedleCount = needles.length\n const src = buildNeedleAlternationSource(needles)\n cachedMinorNeedleRe = src === null ? null : new RegExp(src, \"i\")\n return cachedMinorNeedleRe\n}\n\n/**\n * NUMBER-FIRST age shapes: the ones `buildAgeFragment` (person.ts) emits for a\n * CUSTOM age (\"N years old\", \"N year old\", \"N-year-old\") and the catalog's own\n * \"2-3 years old\" range (the FIRST number decides), plus the colloquial tails a\n * human or an LLM writes instead — \"12yo\", \"12 yo\", \"12 y.o.\", \"12 y/o\",\n * \"12 yr old\", \"12-yr-old\", \"12yrs old\", \"12 years of age\". The cut is `< 20`,\n * the same boundary `isMinorAge` uses for `customAge` and the same one\n * `buildAgeFragment` switches to \"in their teens\" at.\n *\n * Both boundaries are load-bearing. The LEADING one stops a match inside a\n * larger token; the TRAILING one is what makes \"a 5 year older sibling\" a\n * non-hit (\"old\" may not glue onto \"older\") and what stops \"yo\" from firing\n * inside \"12 young\" or \"12 yoga\". Used via `matchAll`, which clones the regex\n * rather than advancing this instance's `lastIndex`.\n */\nconst NUMERIC_AGE_RE =\n /(?<![\\w-])(\\d{1,3})(?:\\s*-\\s*\\d{1,3})?\\s*-?\\s*(?:years?\\s*-?\\s*old|yrs?\\s*-?\\s*old|y(?:\\.\\s*o\\.?|\\/o|o)|years?\\s+of\\s+age)(?![\\w-])/gi\n\n/**\n * AGE-FIRST shapes, where the number trails the word instead of leading it:\n * \"age 12\", \"aged 12\", \"at the age of 12\". The leading boundary is what keeps\n * \"image 12\" / \"page 12\" out (the `age` there is glued to a preceding word\n * character), and the trailing one keeps \"aged 12th\" out.\n */\nconst PREFIXED_AGE_RE = /(?<![\\w-])aged?\\s+(?:of\\s+)?(\\d{1,3})(?![\\w-])/gi\n\n/** Every rule that reads a NUMBER out of the text, each capturing the age in\n * group 1. Iterated together below so a new shape is one array entry. */\nconst AGE_NUMBER_RULES: ReadonlyArray<RegExp> = [NUMERIC_AGE_RE, PREFIXED_AGE_RE]\n\n/** The one NON-numeric shape `buildAgeFragment` emits below 20 (`${n} years\n * old, in their teens`). Kept as its own rule rather than as a catalog term.\n * Separator-tolerant on the same terms as the needle alternation, so\n * \"in their teens\" and \"in-their-teens\" are the same phrase. */\nconst IN_THEIR_TEENS_RE = /(?<![\\w-])in[\\s-]+their[\\s-]+teens(?![\\w-])/i\n\n/**\n * True when free text describes a MINOR subject. Three rules, in order:\n * 1. any minor-age / minor-implying-type prompt hint, word-bounded;\n * 2. a numeric age below 20 in any shape `buildAgeFragment` emits;\n * 3. the literal \"in their teens\".\n *\n * Deliberately NOT a bare-word check: \"child\", \"teen\", \"kid\" alone must never\n * fire, or an adult prompt that merely MENTIONS a child (\"a mother holding her\n * child\") would be floored — the spec's \"adults are byte-identical\" is a hard\n * requirement, so every rule here is a full phrase or a bounded number.\n *\n * Pairs with `isMinorAge`, never replaces it: the structured picker value is\n * the primary signal; this catches the same subject when only the assembled\n * text survives.\n */\nexport function containsMinorAgeHint(text: string | null | undefined): boolean {\n if (typeof text !== \"string\" || text.trim().length === 0) return false\n const re = minorNeedleRegex()\n if (re && re.test(text)) return true\n for (const rule of AGE_NUMBER_RULES) {\n for (const m of text.matchAll(rule)) {\n const n = Number(m[1])\n if (Number.isFinite(n) && n < 20) return true\n }\n }\n return IN_THEIR_TEENS_RE.test(text)\n}\n\n/** The analyzer/import value keys the floor strips flagged ids out of:\n * `person` plus EVERY catalog the flag sweep reads. DERIVED, never\n * hand-listed — the hand-written version omitted `photo-genre` while the\n * sweep included it, so a minor kept `glamour-portrait`. The analyzer JSON is\n * keyed by picker type id (`describe-to-picker.ts`), which is the same string\n * as the catalog id, so this list IS the set of keys to visit. */\nexport const FLOORED_PICKER_KEYS = [\"person\", ...ADULT_SWEPT_CATALOG_IDS] as const\n\nfunction stripIds(obj: Record<string, unknown>, drop: ReadonlySet<string>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n if (typeof v === \"string\") {\n if (!drop.has(v)) out[k] = v\n } else if (Array.isArray(v)) {\n const kept = v.filter((x) => !(typeof x === \"string\" && drop.has(x)))\n if (kept.length > 0) out[k] = kept\n } else {\n out[k] = v\n }\n }\n return out\n}\n\n/** Analyzer / import post-filter: when the person value describes a minor,\n * remove every flagged id from the person, styling, pose and mood values.\n * Identity (same reference) for an adult. */\nexport function applyMinorAgeFloorToPickerValues<T extends Record<string, unknown>>(values: T): T {\n const person = values.person\n if (!person || typeof person !== \"object\" || !isMinorAge(person as { age?: string; customAge?: number; type?: string })) return values\n const drop = getAdultOnlyIds()\n const out: Record<string, unknown> = { ...values }\n for (const key of FLOORED_PICKER_KEYS) {\n const v = out[key]\n if (v && typeof v === \"object\" && !Array.isArray(v)) out[key] = stripIds(v as Record<string, unknown>, drop)\n }\n return out as T\n}\n","import type { HintNodeLike, HintEdgeLike, HintGraphContext } from \"@nodaro/shared/types\"\nexport type { HintNodeLike, HintEdgeLike, HintGraphContext }\n/**\n * Single source of truth for parameter-node prompt-hint text.\n *\n * Every parameter node (framing, lens, camera-format, lighting, color-look,\n * atmosphere, style, setting, person, mood, pose, styling, temporal, tone,\n * text-prompt, camera-motion) dispatches through `getParameterPromptHint` to\n * produce the descriptive clause it contributes to a consumer's prompt.\n *\n * The frontend DAG executor and backend workflow orchestrator both call this,\n * so the text injected via the `cinematography` handle is identical to the\n * text injected when the node is wired directly into a Text Prompt / LLM Chat\n * / Combine Text input.\n *\n * Camera-motion is graph-aware: when `ctx` is provided the function walks the\n * node's `startState`/`endState` incoming edges and composes a fully formed\n * sentence via `composeCameraMotionHintFromConnections`. Without `ctx` only\n * the bare motion description is returned.\n */\n\nimport { buildFramingHints } from \"./framing.js\"\nimport { buildLightingHints } from \"./lighting.js\"\nimport { getLensPromptHint, getLensTerm } from \"./lens.js\"\nimport { getCameraFormatPromptHint, getCameraFormatTerm } from \"./camera-format.js\"\nimport { getColorLookPromptHint, getColorLookTerm } from \"./color-look.js\"\nimport { buildAtmosphereHints } from \"./atmosphere.js\"\nimport { buildActionFxHints } from \"./action-fx.js\"\nimport { getStylePromptHint, getStyleTerm } from \"./style.js\"\nimport { getSettingPromptHint, getSettingTerm } from \"./setting.js\"\nimport { getLoopSubjectPromptHint, getLoopSubjectTerm } from \"./loop-subject.js\"\nimport { buildPersonHints } from \"./person.js\"\nimport { buildMoodHints } from \"./mood.js\"\nimport { buildPoseHints } from \"./pose.js\"\nimport { buildStylingHints } from \"./styling.js\"\nimport { buildTemporalHints } from \"./temporal.js\"\nimport { composeCameraMotionHintFromConnections } from \"./camera-motions.js\"\nimport { joinHintFragments } from \"./hint-join.js\"\nimport { composeTransitionHintFromConnections, readTransitionOptionValues, type TransitionDuration, type TransitionIntensity, type TransitionPosition, type TransitionTiming } from \"./transitions.js\"\nimport { composeCharacterFxHintFromConnections, type CharacterFxDuration, type CharacterFxIntensity, type CharacterFxPosition, type CharacterFxTiming } from \"./character-fx.js\"\nimport { composeCharacterMotionHintFromConnections, type CharacterMotionPace, type CharacterMotionPosition, type CharacterMotionTiming } from \"./character-motion.js\"\nimport { containsMinorAgeHint, isMinorAge } from \"./age-floor.js\"\nimport { buildMaterialHints } from \"./materials.js\"\nimport { curatedAnimalPromptHint, curatedAnimalTerm, curatedVehicleText, curatedWeaponText, curatedFurnitureText } from \"./shared-catalog-overlay.js\"\nimport { getPhotoGenrePromptHint, getPhotoGenreTerm } from \"./photo-genre.js\"\nimport { getBackdropPromptHint, getBackdropTerm } from \"./backdrop.js\"\nimport { buildHeldPropHints } from \"./held-prop.js\"\nimport { buildPhotographerHints } from \"./photographer.js\"\nimport { buildAestheticHints } from \"./aesthetic.js\"\nimport { getEraPromptHint, getEraTerm } from \"./era.js\"\nimport { buildExposureHints } from \"./exposure-settings.js\"\nimport { getRenderQualityPromptHint, getRenderQualityTerm } from \"./render-quality.js\"\nimport { getCompositionEffectPromptHint, getCompositionEffectTerm } from \"./composition-effects.js\"\nimport { buildPostProcessHints } from \"./post-process-effects.js\"\nimport { buildMusicGenreHints } from \"./music-genre.js\"\nimport { buildMusicMoodHints } from \"./music-mood.js\"\nimport { buildInstrumentationHints } from \"./instrumentation.js\"\nimport { buildVoiceCharacterHints } from \"./voice-character.js\"\nimport { buildVoiceDeliveryHints } from \"./voice-delivery.js\"\nimport { getPickerCatalog } from \"./picker-catalogs.js\"\nimport { resolveTerm, type PickerHintMode } from \"./term.js\"\n\n\nfunction asStr(v: unknown): string {\n return typeof v === \"string\" ? v : \"\"\n}\n\n/** Extract the display name from a character / face / object / location ref node. */\nfunction extractCharacterRefName(node: HintNodeLike): string | undefined {\n const d = (node.data ?? {}) as Record<string, unknown>\n const candidates = [d.characterName, d.faceName, d.objectName, d.locationName]\n for (const v of candidates) {\n if (typeof v === \"string\" && v.trim().length > 0) return v.trim()\n }\n return undefined\n}\n\n/** Character Motion's name read: the shared character / face / object / location\n * read, then a creature's `creatureName`. Local to Character Motion so the\n * Character FX prompt, which shares `extractCharacterRefName`, stays unchanged. */\nfunction extractCharacterMotionRefName(node: HintNodeLike): string | undefined {\n const name = extractCharacterRefName(node)\n if (name) return name\n const creatureName = asStr(((node.data ?? {}) as Record<string, unknown>).creatureName).trim()\n return creatureName.length > 0 ? creatureName : undefined\n}\n\n/** Free-text fields a character / face / object / location ref node describes its subject in.\n * A creature ref uses the same `description` / `canonicalDescription` names. */\nconst REF_DESCRIPTION_FIELDS = [\"description\", \"seedPrompt\", \"canonicalDescription\"] as const\n\n/** True when a character / face / object / location ref node describes a minor:\n * its structured `person` age (the primary signal) or an age phrase in its\n * free-text description. Feeds the Character Motion floor (adult-only moves\n * dropped) — errs toward flooring, never toward letting an adult-only move through. */\nfunction extractCharacterRefMinor(node: HintNodeLike): boolean {\n const d = (node.data ?? {}) as Record<string, unknown>\n const person = d.person\n if (person && typeof person === \"object\" && !Array.isArray(person) && isMinorAge(person as Parameters<typeof isMinorAge>[0])) {\n return true\n }\n return REF_DESCRIPTION_FIELDS.some((field) => containsMinorAgeHint(asStr(d[field])))\n}\n\n/** The preview, diagnostics and execution use identical graph bindings. */\nexport function getCharacterMotionBindings(node: HintNodeLike, ctx?: HintGraphContext) {\n const targetNames: string[] = []\n const partnerNames: string[] = []\n const targetIds = new Set<string>()\n const partnerIds = new Set<string>()\n let subjectMinor = false\n for (const edge of ctx?.edges ?? []) {\n if (edge.target !== node.id || (edge.targetHandle !== \"target\" && edge.targetHandle !== \"partner\")) continue\n const src = ctx?.nodes.find(n => n.id === edge.source)\n if (!src) continue\n if (edge.targetHandle === \"target\") targetIds.add(src.id)\n else partnerIds.add(src.id)\n if (extractCharacterRefMinor(src)) subjectMinor = true\n const name = extractCharacterMotionRefName(src)\n if (!name) continue\n const names = edge.targetHandle === \"target\" ? targetNames : partnerNames\n if (!names.includes(name)) names.push(name)\n }\n return { targetNames, partnerNames, subjectMinor, selfPairing: [...targetIds].some(id => partnerIds.has(id)) }\n}\n\n/** Compose `[preText, mainHint, postText]` into a comma-joined string,\n * honoring the user's free-text fragments around the structured hint.\n * Helpers like `getStylePromptHint` that already include preText/postText\n * composition (build*Hints in mood/person/etc.) bypass this — they\n * return the fully-composed string directly. */\nfunction withCustomText(data: Record<string, unknown>, mainHint: string): string {\n const fragments: string[] = []\n const pre = typeof data.preText === \"string\" ? data.preText.trim() : \"\"\n if (pre) fragments.push(pre)\n if (mainHint) fragments.push(mainHint)\n const post = typeof data.postText === \"string\" ? data.postText.trim() : \"\"\n if (post) fragments.push(post)\n return joinHintFragments(fragments)\n}\n\n/**\n * The node-level hint mode a picker declares via `data.hintMode`.\n *\n * Only the two documented values count; anything else (a stale value, a typo,\n * a non-string) is treated as UNDECLARED and falls back — to the inherited\n * mode when the node is resolved as an upstream input, and to `\"full\"`\n * otherwise. Compact is opt-in, so an unrecognized value can never silently\n * shorten a prompt.\n */\nfunction readHintMode(data: Record<string, unknown>): PickerHintMode | undefined {\n const raw = data.hintMode\n return raw === \"compact\" || raw === \"full\" ? raw : undefined\n}\n\n/** Pick the full-hint or the compact-term getter for the active mode. */\nfunction byMode<T>(mode: PickerHintMode, full: T, compact: T): T {\n return mode === \"compact\" ? compact : full\n}\n\n/** How much a shot moves (the Motion node's three steps), as the clause it\n * adds to a video prompt; the compact form is the bare term. */\nconst MOTION_INTENSITY_HINTS: Readonly<Record<string, { readonly full: string; readonly compact: string }>> = {\n subtle: { full: \"subtle, gentle motion with slow, minimal movement\", compact: \"subtle motion\" },\n moderate: { full: \"moderate, natural motion at an even pace\", compact: \"moderate motion\" },\n dynamic: { full: \"dynamic, energetic motion with fast, pronounced movement\", compact: \"dynamic motion\" },\n}\n\n/**\n * Dispatch by parameter-node type to its prompt-hint string. For camera-motion,\n * pass `ctx` to include the composed start/end clauses; otherwise only the\n * bare motion description is returned.\n *\n * VERBOSITY — a picker node may set `data.hintMode` to `\"compact\"` to inject\n * its short professional `term` (\"whip pan left\", \"hard cut\") instead of the\n * long `promptHint`. Absent, or any unrecognized value, means `\"full\"`, whose\n * output is byte-identical to what this function returned before hint modes\n * existed. ONLY the base catalog fragment swaps: `preText`/`postText`, the\n * transition / camera-motion / character-fx timing and start-state/end-state\n * clauses, multi-pick joining and multi-dimension composition are emitted the\n * same way in both modes.\n */\nexport function getParameterPromptHint(\n node: HintNodeLike | undefined,\n ctx?: HintGraphContext,\n): string {\n return resolveParameterHint(node, ctx)\n}\n\n/**\n * The dispatch body. `inherited` carries the mode DOWN into the nodes wired to\n * a composer's `startState` / `endState` handles, so a compact transition\n * composes compact start/end clauses rather than mixing a term with two\n * paragraphs. A node that declares its own `hintMode` still wins over what it\n * inherits.\n */\nfunction resolveParameterHint(\n node: HintNodeLike | undefined,\n ctx?: HintGraphContext,\n inherited?: PickerHintMode,\n): string {\n if (!node?.type) return \"\"\n const data = (node.data ?? {}) as Record<string, unknown>\n const mode: PickerHintMode = readHintMode(data) ?? inherited ?? \"full\"\n\n if (node.type === \"camera-motion\") {\n const motionId = asStr(data.cameraMotion) || undefined\n if (!ctx) return withCustomText(data, composeCameraMotionHintFromConnections(motionId, [], [], mode))\n const startHints: string[] = []\n const endHints: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n // Pass no ctx for nested resolution: startState/endState inputs are\n // themselves parameter nodes (framing/tone/etc.) that don't need graph\n // context, and avoiding recursion keeps the walk cycle-safe. The mode\n // rides down so the composed clause stays at one level of detail.\n const hint = resolveParameterHint(src, undefined, mode)\n if (!hint) continue\n if (edge.targetHandle === \"startState\") startHints.push(hint)\n else if (edge.targetHandle === \"endState\") endHints.push(hint)\n }\n return withCustomText(data, composeCameraMotionHintFromConnections(motionId, startHints, endHints, mode))\n }\n\n if (node.type === \"transition\") {\n const raw = data.transition\n const transitionId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: TransitionTiming = {\n position: asStr(data.position) as TransitionPosition | undefined,\n duration: asStr(data.duration) as TransitionDuration | undefined,\n intensity: asStr(data.intensity) as TransitionIntensity | undefined,\n }\n // A picked row's own options (a wipe's `wipeDirection`), off the same node data.\n const optionValues = readTransitionOptionValues(data)\n const hintOptions = optionValues ? { optionValues } : undefined\n if (!ctx) {\n return withCustomText(data, composeTransitionHintFromConnections(transitionId, [], [], timing, mode, hintOptions))\n }\n const startHints: string[] = []\n const endHints: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n const hint = resolveParameterHint(src, undefined, mode) // no ctx — cycle-safe\n if (!hint) continue\n if (edge.targetHandle === \"startState\") startHints.push(hint)\n else if (edge.targetHandle === \"endState\") endHints.push(hint)\n }\n return withCustomText(data, composeTransitionHintFromConnections(transitionId, startHints, endHints, timing, mode, hintOptions))\n }\n\n if (node.type === \"character-fx\") {\n const raw = data.characterFx\n const effectId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: CharacterFxTiming = {\n position: asStr(data.position) as CharacterFxPosition | undefined,\n duration: asStr(data.duration) as CharacterFxDuration | undefined,\n intensity: asStr(data.intensity) as CharacterFxIntensity | undefined,\n }\n if (!ctx) {\n return withCustomText(data, composeCharacterFxHintFromConnections(effectId, [], timing, mode))\n }\n const targetNames: string[] = []\n for (const edge of ctx.edges) {\n if (edge.target !== node.id) continue\n if (edge.targetHandle !== \"target\") continue\n const src = ctx.nodes.find((n) => n.id === edge.source)\n if (!src) continue\n const name = extractCharacterRefName(src)\n if (name) targetNames.push(name)\n }\n return withCustomText(data, composeCharacterFxHintFromConnections(effectId, targetNames, timing, mode))\n }\n\n if (node.type === \"character-motion\") {\n const raw = data.characterMotion\n const motionId: string | string[] | undefined =\n Array.isArray(raw)\n ? raw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : (asStr(raw) || undefined)\n const timing: CharacterMotionTiming = {\n position: asStr(data.position) as CharacterMotionPosition | undefined,\n pace: asStr(data.pace) as CharacterMotionPace | undefined,\n }\n if (!ctx) {\n return withCustomText(data, composeCharacterMotionHintFromConnections(motionId, [], [], timing, mode))\n }\n const { targetNames, partnerNames, subjectMinor } = getCharacterMotionBindings(node, ctx)\n return withCustomText(\n data,\n composeCharacterMotionHintFromConnections(motionId, targetNames, partnerNames, timing, mode, { subjectMinor }),\n )\n }\n\n const base = resolveBaseHint(node.type, data, mode)\n if (base) return base\n // Pack-extend fallback: a single-dim pack entry the per-catalog getter (which\n // reads the frozen base array) can't resolve. Resolve it against the\n // registered (pack-composed) catalog's options. Composition already resolved\n // `PickerOption.term`; `resolveTerm` is idempotent over a resolved option and\n // is called anyway so a pack option that reached this array by some other\n // route still injects SOMETHING in compact mode rather than `undefined`.\n const cat = getPickerCatalog(node.type)\n if (cat?.kind === \"single\" && cat.valueField) {\n const id = typeof data[cat.valueField] === \"string\" ? (data[cat.valueField] as string) : \"\"\n const opt = cat.options?.find((o) => o.id === id)\n if (opt) return byMode(mode, opt.promptHint, resolveTerm(opt))\n }\n return base\n}\n\n/**\n * Base (upstream) hint dispatch by node type — the per-catalog getters read the\n * frozen base arrays. Pack-added single-dim ids are resolved by the caller\n * against the registered (pack-composed) catalog.\n *\n * `mode` selects the base fragment only: the compact `get<Name>Term` getter /\n * `build<Name>Terms` builder instead of the verbose one. The `withCustomText`\n * wrapper, the builders' own pre/post composition, and the free-text node\n * types (tone / style-guide / text-prompt — user prose, not catalog copy) are\n * identical in both modes.\n */\nfunction resolveBaseHint(\n type: string,\n data: Record<string, unknown>,\n mode: PickerHintMode = \"full\",\n): string {\n switch (type) {\n case \"framing\":\n return withCustomText(data, buildFramingHints(data, false, mode).join(\", \"))\n case \"lighting\":\n return withCustomText(data, buildLightingHints(data, mode).join(\", \"))\n case \"lens\":\n return withCustomText(data, byMode(mode, getLensPromptHint, getLensTerm)(asStr(data.lens)))\n case \"camera-format\":\n return withCustomText(data, byMode(mode, getCameraFormatPromptHint, getCameraFormatTerm)(asStr(data.cameraFormat)))\n case \"color-look\":\n return withCustomText(data, byMode(mode, getColorLookPromptHint, getColorLookTerm)(asStr(data.colorLook)))\n\n // build*Hints in music-* / voice-* / mood / person / etc. compose\n // preText/postText internally — bypass the wrapper to avoid double-\n // composition.\n case \"music-genre\":\n return buildMusicGenreHints((data ?? {}) as Parameters<typeof buildMusicGenreHints>[0], mode)\n case \"music-mood\":\n return buildMusicMoodHints((data ?? {}) as Parameters<typeof buildMusicMoodHints>[0], mode)\n case \"instrumentation\":\n return buildInstrumentationHints((data ?? {}) as Parameters<typeof buildInstrumentationHints>[0], mode)\n case \"voice-character\":\n return buildVoiceCharacterHints((data ?? {}) as Parameters<typeof buildVoiceCharacterHints>[0], mode)\n case \"voice-delivery\":\n return buildVoiceDeliveryHints((data ?? {}) as Parameters<typeof buildVoiceDeliveryHints>[0], mode)\n case \"person\":\n return buildPersonHints(data, mode).join(\", \")\n case \"mood\":\n return buildMoodHints(data, mode).join(\", \")\n case \"pose\":\n return buildPoseHints(data, mode).join(\", \")\n case \"styling\":\n return buildStylingHints(data, mode).join(\", \")\n\n case \"atmosphere\":\n return withCustomText(data, buildAtmosphereHints(data.atmosphere, mode).join(\", \"))\n case \"action-fx\":\n return withCustomText(data, buildActionFxHints(data.actionFx, mode).join(\", \"))\n case \"style\":\n return withCustomText(data, byMode(mode, getStylePromptHint, getStyleTerm)(asStr(data.style)))\n case \"setting\":\n return withCustomText(data, byMode(mode, getSettingPromptHint, getSettingTerm)(asStr(data.setting)))\n case \"loop-subject\":\n return withCustomText(data, byMode(mode, getLoopSubjectPromptHint, getLoopSubjectTerm)(asStr(data.loopSubject)))\n case \"material\":\n return withCustomText(data, buildMaterialHints(data.material, mode))\n // The four object-entity catalogs are owned by @nodaro/shared and overlaid\n // in shared-catalog-overlay.ts — the ONE module every prompt-text read of\n // them goes through (the subject fold uses it too). Each returns \"\" on a\n // miss, so the entry lookup is the module's job, not this switch's.\n case \"animal\":\n return withCustomText(data, byMode(mode, curatedAnimalPromptHint, curatedAnimalTerm)(asStr(data.animal)))\n case \"vehicle\": {\n const t = curatedVehicleText(asStr(data.vehicle))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"weapon\": {\n const t = curatedWeaponText(asStr(data.weapon))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"furniture\": {\n const t = curatedFurnitureText(asStr(data.furniture))\n return withCustomText(data, byMode(mode, t.hint, t.term))\n }\n case \"photo-genre\":\n return withCustomText(data, byMode(mode, getPhotoGenrePromptHint, getPhotoGenreTerm)(asStr(data.photoGenre)))\n case \"backdrop\":\n return withCustomText(data, byMode(mode, getBackdropPromptHint, getBackdropTerm)(asStr(data.backdrop)))\n case \"held-prop\":\n return withCustomText(data, buildHeldPropHints(data.heldProp, mode).join(\", \"))\n case \"photographer\":\n return withCustomText(data, buildPhotographerHints(data.photographer, mode))\n case \"aesthetic\":\n return withCustomText(data, buildAestheticHints(data.aesthetic, mode))\n case \"era\":\n return withCustomText(data, byMode(mode, getEraPromptHint, getEraTerm)(asStr(data.era)))\n case \"temporal\":\n return withCustomText(data, buildTemporalHints(data, mode).join(\", \"))\n case \"exposure-settings\":\n return withCustomText(data, buildExposureHints(data, mode).join(\", \"))\n case \"render-quality\":\n return withCustomText(data, byMode(mode, getRenderQualityPromptHint, getRenderQualityTerm)(asStr(data.renderQuality)))\n case \"composition-effects\":\n return withCustomText(data, byMode(mode, getCompositionEffectPromptHint, getCompositionEffectTerm)(asStr(data.compositionEffect)))\n case \"post-process-effects\":\n return withCustomText(data, buildPostProcessHints(data.postProcess, mode).join(\", \"))\n // Motion intensity: a Generation Settings node that a video node's\n // Settings input takes as a prompt fragment (video only).\n case \"motion\": {\n const hint = MOTION_INTENSITY_HINTS[asStr(data.motion)]\n return hint ? byMode(mode, hint.full, hint.compact) : \"\"\n }\n\n // Free text authored by the user, not catalog copy — there is no shorter\n // professional form to swap in, so these are identical in both modes.\n case \"tone\":\n return asStr(data.tone).trim()\n case \"style-guide\":\n // The node's whole purpose is injecting its style text into consumer\n // prompts; without this case, {Style Guide} refs stayed as literal\n // brace text and direct wires injected nothing (only fieldMappings\n // worked, via getParameterValue).\n return asStr(data.text).trim()\n case \"text-prompt\":\n return asStr(data.text).trim()\n default:\n return \"\"\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { curatedFurnitureText, curatedWeaponText, curatedVehicleText, curatedAnimalTerm, curatedAnimalPromptHint } from './chunk-UJKFHPZ7.js';
1
+ import { curatedFurnitureText, curatedWeaponText, curatedVehicleText, curatedAnimalTerm, curatedAnimalPromptHint } from './chunk-EAYEZXWT.js';
2
2
  import { getRegisteredPickerCatalogs, composeCameraMotionHintFromConnections, readTransitionOptionValues, composeTransitionHintFromConnections, composeCharacterFxHintFromConnections, composeCharacterMotionHintFromConnections, getPickerCatalog, buildPostProcessHints, buildExposureHints, buildTemporalHints, buildAestheticHints, buildPhotographerHints, buildHeldPropHints, buildMaterialHints, buildActionFxHints, buildAtmosphereHints, buildStylingHints, buildPoseHints, buildMoodHints, buildVoiceDeliveryHints, buildVoiceCharacterHints, buildInstrumentationHints, buildMusicMoodHints, buildMusicGenreHints, buildLightingHints, buildFramingHints, getCompositionEffectTerm, getCompositionEffectPromptHint, getRenderQualityTerm, getRenderQualityPromptHint, getEraTerm, getEraPromptHint, getBackdropTerm, getBackdropPromptHint, getPhotoGenreTerm, getPhotoGenrePromptHint, getLoopSubjectTerm, getLoopSubjectPromptHint, getSettingTerm, getSettingPromptHint, getStyleTerm, getStylePromptHint, getColorLookTerm, getColorLookPromptHint, getCameraFormatTerm, getCameraFormatPromptHint, getLensTerm, getLensPromptHint } from './chunk-SXXW4LCR.js';
3
3
  import { joinHintFragments } from './chunk-DVP6ILDR.js';
4
4
  import { getRegisteredPeople, ADULT_AGE_IDS, MINOR_IMPLYING_TYPE_IDS, isMinorAge, buildPersonHints } from './chunk-TDZFXOTE.js';
@@ -412,5 +412,5 @@ function resolveBaseHint(type, data, mode = "full") {
412
412
  }
413
413
 
414
414
  export { ADULT_SWEPT_CATALOG_IDS, FLOORED_PICKER_KEYS, RETIRED_ADULT_ONLY_HINT_STRINGS, applyMinorAgeFloorToPickerValues, buildNeedleAlternationSource, containsMinorAgeHint, getAdultOnlyEntries, getAdultOnlyHintStrings, getAdultOnlyIds, getCharacterMotionBindings, getMinorAgeHintStrings, getParameterPromptHint };
415
- //# sourceMappingURL=chunk-N7TOWXDJ.js.map
416
- //# sourceMappingURL=chunk-N7TOWXDJ.js.map
415
+ //# sourceMappingURL=chunk-QDUTMOF4.js.map
416
+ //# sourceMappingURL=chunk-QDUTMOF4.js.map