@wix/web5-core 1.56.1 → 1.57.1

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 (192) hide show
  1. package/dist/cjs/client/wixAuthFetch.js +2 -2
  2. package/dist/cjs/client/wixAuthFetch.js.map +1 -1
  3. package/dist/cjs/component/componentDefinitions/HeroEntitySectionDefinition.js +20 -15
  4. package/dist/cjs/component/componentDefinitions/HeroEntitySectionDefinition.js.map +1 -1
  5. package/dist/cjs/component/componentDefinitions/HeroSectionDefinition.js +12 -4
  6. package/dist/cjs/component/componentDefinitions/HeroSectionDefinition.js.map +1 -1
  7. package/dist/cjs/component/componentDefinitions/listItemsSectionDefinition.js +24 -29
  8. package/dist/cjs/component/componentDefinitions/listItemsSectionDefinition.js.map +1 -1
  9. package/dist/cjs/component/componentParser.js +8 -1
  10. package/dist/cjs/component/componentParser.js.map +1 -1
  11. package/dist/cjs/component/types.js.map +1 -1
  12. package/dist/cjs/components/placement/PlacementResponseRenderer.css +0 -4
  13. package/dist/cjs/components/placement/PlacementResponseRenderer.js +11 -33
  14. package/dist/cjs/components/placement/PlacementResponseRenderer.js.map +1 -1
  15. package/dist/cjs/components/placement/buildPlacementDependencies.js.map +1 -1
  16. package/dist/cjs/components/ui/OptimizedImage.js +59 -14
  17. package/dist/cjs/components/ui/OptimizedImage.js.map +1 -1
  18. package/dist/cjs/components/ui/SectionSkeleton.css +19 -0
  19. package/dist/cjs/components/ui/SectionSkeleton.js +8 -4
  20. package/dist/cjs/components/ui/SectionSkeleton.js.map +1 -1
  21. package/dist/cjs/components/ui/UserQuery.css +72 -0
  22. package/dist/cjs/components/ui/UserQuery.js +131 -37
  23. package/dist/cjs/components/ui/UserQuery.js.map +1 -1
  24. package/dist/cjs/context/UserQueryContext.js +34 -0
  25. package/dist/cjs/context/UserQueryContext.js.map +1 -0
  26. package/dist/cjs/entity/defaultExtractor.js +9 -2
  27. package/dist/cjs/entity/defaultExtractor.js.map +1 -1
  28. package/dist/cjs/entity/fetchEntityListData.js +13 -26
  29. package/dist/cjs/entity/fetchEntityListData.js.map +1 -1
  30. package/dist/cjs/entity/index.js +5 -1
  31. package/dist/cjs/entity/index.js.map +1 -1
  32. package/dist/cjs/entity/listEntityItems.js +90 -0
  33. package/dist/cjs/entity/listEntityItems.js.map +1 -0
  34. package/dist/cjs/hostScope.js +63 -0
  35. package/dist/cjs/hostScope.js.map +1 -0
  36. package/dist/cjs/index.js +38 -13
  37. package/dist/cjs/index.js.map +1 -1
  38. package/dist/cjs/patternValidator/validator.test.js +61 -61
  39. package/dist/cjs/patternValidator/validator.test.js.map +1 -1
  40. package/dist/cjs/registry/ComponentRegistry.js +22 -2
  41. package/dist/cjs/registry/ComponentRegistry.js.map +1 -1
  42. package/dist/cjs/registry/index.js +1 -3
  43. package/dist/cjs/registry/index.js.map +1 -1
  44. package/dist/cjs/registry/types.js.map +1 -1
  45. package/dist/cjs/styles/base-utilities.css +35 -0
  46. package/dist/cjs/styles/components.css +1 -0
  47. package/dist/cjs/styles/host-reset.css +100 -0
  48. package/dist/cjs/styles/tailwind-theme.css +6 -6
  49. package/dist/cjs/utils/backendEnvironment.js +78 -0
  50. package/dist/cjs/utils/backendEnvironment.js.map +1 -0
  51. package/dist/cjs/utils/entityLinkParser.js +3 -1
  52. package/dist/cjs/utils/entityLinkParser.js.map +1 -1
  53. package/dist/cjs/utils/imageBackdrop.js +269 -0
  54. package/dist/cjs/utils/imageBackdrop.js.map +1 -0
  55. package/dist/cjs/utils/intentExtractor.js +20 -9
  56. package/dist/cjs/utils/intentExtractor.js.map +1 -1
  57. package/dist/cjs/utils/productBackHandoff.js +106 -0
  58. package/dist/cjs/utils/productBackHandoff.js.map +1 -0
  59. package/dist/cjs/utils/refreshPrompts.js +72 -0
  60. package/dist/cjs/utils/refreshPrompts.js.map +1 -0
  61. package/dist/esm/client/wixAuthFetch.js +2 -2
  62. package/dist/esm/client/wixAuthFetch.js.map +1 -1
  63. package/dist/esm/component/componentDefinitions/HeroEntitySectionDefinition.js +20 -15
  64. package/dist/esm/component/componentDefinitions/HeroEntitySectionDefinition.js.map +1 -1
  65. package/dist/esm/component/componentDefinitions/HeroSectionDefinition.js +12 -4
  66. package/dist/esm/component/componentDefinitions/HeroSectionDefinition.js.map +1 -1
  67. package/dist/esm/component/componentDefinitions/listItemsSectionDefinition.js +25 -30
  68. package/dist/esm/component/componentDefinitions/listItemsSectionDefinition.js.map +1 -1
  69. package/dist/esm/component/componentParser.js +8 -1
  70. package/dist/esm/component/componentParser.js.map +1 -1
  71. package/dist/esm/component/types.js.map +1 -1
  72. package/dist/esm/components/placement/PlacementResponseRenderer.css +0 -4
  73. package/dist/esm/components/placement/PlacementResponseRenderer.js +1 -16
  74. package/dist/esm/components/placement/PlacementResponseRenderer.js.map +1 -1
  75. package/dist/esm/components/placement/buildPlacementDependencies.js.map +1 -1
  76. package/dist/esm/components/ui/OptimizedImage.js +50 -5
  77. package/dist/esm/components/ui/OptimizedImage.js.map +1 -1
  78. package/dist/esm/components/ui/SectionSkeleton.css +19 -0
  79. package/dist/esm/components/ui/SectionSkeleton.js +5 -1
  80. package/dist/esm/components/ui/SectionSkeleton.js.map +1 -1
  81. package/dist/esm/components/ui/UserQuery.css +72 -0
  82. package/dist/esm/components/ui/UserQuery.js +52 -6
  83. package/dist/esm/components/ui/UserQuery.js.map +1 -1
  84. package/dist/esm/context/UserQueryContext.js +21 -0
  85. package/dist/esm/context/UserQueryContext.js.map +1 -0
  86. package/dist/esm/entity/defaultExtractor.js +9 -2
  87. package/dist/esm/entity/defaultExtractor.js.map +1 -1
  88. package/dist/esm/entity/fetchEntityListData.js +14 -26
  89. package/dist/esm/entity/fetchEntityListData.js.map +1 -1
  90. package/dist/esm/entity/index.js +1 -0
  91. package/dist/esm/entity/index.js.map +1 -1
  92. package/dist/esm/entity/listEntityItems.js +85 -0
  93. package/dist/esm/entity/listEntityItems.js.map +1 -0
  94. package/dist/esm/hostScope.js +59 -0
  95. package/dist/esm/hostScope.js.map +1 -0
  96. package/dist/esm/index.js +13 -4
  97. package/dist/esm/index.js.map +1 -1
  98. package/dist/esm/patternValidator/validator.test.js +61 -61
  99. package/dist/esm/patternValidator/validator.test.js.map +1 -1
  100. package/dist/esm/registry/ComponentRegistry.js +22 -2
  101. package/dist/esm/registry/ComponentRegistry.js.map +1 -1
  102. package/dist/esm/registry/index.js +0 -1
  103. package/dist/esm/registry/index.js.map +1 -1
  104. package/dist/esm/registry/types.js.map +1 -1
  105. package/dist/esm/styles/base-utilities.css +35 -0
  106. package/dist/esm/styles/components.css +1 -0
  107. package/dist/esm/styles/host-reset.css +100 -0
  108. package/dist/esm/styles/tailwind-theme.css +6 -6
  109. package/dist/esm/utils/backendEnvironment.js +71 -0
  110. package/dist/esm/utils/backendEnvironment.js.map +1 -0
  111. package/dist/esm/utils/entityLinkParser.js +3 -1
  112. package/dist/esm/utils/entityLinkParser.js.map +1 -1
  113. package/dist/esm/utils/imageBackdrop.js +262 -0
  114. package/dist/esm/utils/imageBackdrop.js.map +1 -0
  115. package/dist/esm/utils/intentExtractor.js +21 -12
  116. package/dist/esm/utils/intentExtractor.js.map +1 -1
  117. package/dist/esm/utils/productBackHandoff.js +100 -0
  118. package/dist/esm/utils/productBackHandoff.js.map +1 -0
  119. package/dist/esm/utils/refreshPrompts.js +67 -0
  120. package/dist/esm/utils/refreshPrompts.js.map +1 -0
  121. package/dist/types/component/componentDefinitions/HeroEntitySectionDefinition.d.ts.map +1 -1
  122. package/dist/types/component/componentDefinitions/HeroSectionDefinition.d.ts.map +1 -1
  123. package/dist/types/component/componentDefinitions/listItemsSectionDefinition.d.ts +2 -2
  124. package/dist/types/component/componentDefinitions/listItemsSectionDefinition.d.ts.map +1 -1
  125. package/dist/types/component/componentParser.d.ts.map +1 -1
  126. package/dist/types/component/types.d.ts +1 -5
  127. package/dist/types/component/types.d.ts.map +1 -1
  128. package/dist/types/components/placement/PlacementResponseRenderer.d.ts +1 -1
  129. package/dist/types/components/placement/PlacementResponseRenderer.d.ts.map +1 -1
  130. package/dist/types/components/placement/buildPlacementDependencies.d.ts +1 -2
  131. package/dist/types/components/placement/buildPlacementDependencies.d.ts.map +1 -1
  132. package/dist/types/components/ui/OptimizedImage.d.ts +9 -0
  133. package/dist/types/components/ui/OptimizedImage.d.ts.map +1 -1
  134. package/dist/types/components/ui/SectionSkeleton.d.ts.map +1 -1
  135. package/dist/types/components/ui/UserQuery.d.ts +21 -0
  136. package/dist/types/components/ui/UserQuery.d.ts.map +1 -1
  137. package/dist/types/context/UserQueryContext.d.ts +12 -0
  138. package/dist/types/context/UserQueryContext.d.ts.map +1 -0
  139. package/dist/types/entity/defaultExtractor.d.ts.map +1 -1
  140. package/dist/types/entity/fetchEntityListData.d.ts +0 -2
  141. package/dist/types/entity/fetchEntityListData.d.ts.map +1 -1
  142. package/dist/types/entity/index.d.ts +1 -0
  143. package/dist/types/entity/index.d.ts.map +1 -1
  144. package/dist/types/entity/listEntityItems.d.ts +40 -0
  145. package/dist/types/entity/listEntityItems.d.ts.map +1 -0
  146. package/dist/types/hostScope.d.ts +83 -0
  147. package/dist/types/hostScope.d.ts.map +1 -0
  148. package/dist/types/index.d.ts +11 -7
  149. package/dist/types/index.d.ts.map +1 -1
  150. package/dist/types/registry/ComponentRegistry.d.ts +8 -0
  151. package/dist/types/registry/ComponentRegistry.d.ts.map +1 -1
  152. package/dist/types/registry/index.d.ts +0 -1
  153. package/dist/types/registry/index.d.ts.map +1 -1
  154. package/dist/types/registry/types.d.ts +5 -6
  155. package/dist/types/registry/types.d.ts.map +1 -1
  156. package/dist/types/utils/backendEnvironment.d.ts +30 -0
  157. package/dist/types/utils/backendEnvironment.d.ts.map +1 -0
  158. package/dist/types/utils/entityLinkParser.d.ts.map +1 -1
  159. package/dist/types/utils/imageBackdrop.d.ts +102 -0
  160. package/dist/types/utils/imageBackdrop.d.ts.map +1 -0
  161. package/dist/types/utils/intentExtractor.d.ts +21 -4
  162. package/dist/types/utils/intentExtractor.d.ts.map +1 -1
  163. package/dist/types/utils/productBackHandoff.d.ts +43 -0
  164. package/dist/types/utils/productBackHandoff.d.ts.map +1 -0
  165. package/dist/types/utils/refreshPrompts.d.ts +32 -0
  166. package/dist/types/utils/refreshPrompts.d.ts.map +1 -0
  167. package/package.json +2 -2
  168. package/src/components/placement/PlacementResponseRenderer.css +0 -4
  169. package/src/components/ui/SectionSkeleton.css +19 -0
  170. package/src/components/ui/UserQuery.css +72 -0
  171. package/src/styles/base-utilities.css +35 -0
  172. package/src/styles/components.css +1 -0
  173. package/src/styles/host-reset.css +100 -0
  174. package/src/styles/tailwind-theme.css +6 -6
  175. package/dist/cjs/registry/Intent.js +0 -19
  176. package/dist/cjs/registry/Intent.js.map +0 -1
  177. package/dist/cjs/utils/conversationApi.js +0 -52
  178. package/dist/cjs/utils/conversationApi.js.map +0 -1
  179. package/dist/cjs/utils/conversationMode.js +0 -23
  180. package/dist/cjs/utils/conversationMode.js.map +0 -1
  181. package/dist/esm/registry/Intent.js +0 -15
  182. package/dist/esm/registry/Intent.js.map +0 -1
  183. package/dist/esm/utils/conversationApi.js +0 -45
  184. package/dist/esm/utils/conversationApi.js.map +0 -1
  185. package/dist/esm/utils/conversationMode.js +0 -18
  186. package/dist/esm/utils/conversationMode.js.map +0 -1
  187. package/dist/types/registry/Intent.d.ts +0 -12
  188. package/dist/types/registry/Intent.d.ts.map +0 -1
  189. package/dist/types/utils/conversationApi.d.ts +0 -26
  190. package/dist/types/utils/conversationApi.d.ts.map +0 -1
  191. package/dist/types/utils/conversationMode.d.ts +0 -16
  192. package/dist/types/utils/conversationMode.d.ts.map +0 -1
@@ -256,6 +256,26 @@ export class ComponentRegistry {
256
256
  getAllSections() {
257
257
  return Array.from(this.sections.keys());
258
258
  }
259
+
260
+ /**
261
+ * Every intent that has at least one registered slot or section variant —
262
+ * i.e. the client's own intent list, derived from what it actually
263
+ * registered. Assembly uses this to validate an incoming intent before it
264
+ * becomes a resolution key, falling back to core's `DEFAULT_INTENTS` only
265
+ * when a client registers no intent variants at all.
266
+ */
267
+ getKnownIntents() {
268
+ const intents = new Set();
269
+ for (const node of this.slots.values()) {
270
+ var _node$byIntent5;
271
+ (_node$byIntent5 = node.byIntent) == null || _node$byIntent5.forEach((_variant, key) => intents.add(key));
272
+ }
273
+ for (const node of this.sections.values()) {
274
+ var _node$byIntent6;
275
+ (_node$byIntent6 = node.byIntent) == null || _node$byIntent6.forEach((_variant, key) => intents.add(key));
276
+ }
277
+ return Array.from(intents);
278
+ }
259
279
  getAllDefinitions() {
260
280
  return Array.from(this.definitions.entries()).map(_ref => {
261
281
  let [sectionType, definition] = _ref;
@@ -282,13 +302,13 @@ export class ComponentRegistry {
282
302
  * everywhere.
283
303
  */
284
304
  isPlacementOnly(sectionType) {
285
- var _node$forPlacementByI2, _node$byIntent5, _node$bySemantic3;
305
+ var _node$forPlacementByI2, _node$byIntent7, _node$bySemantic3;
286
306
  const node = this.sections.get(sectionType);
287
307
  if (!node) {
288
308
  return false;
289
309
  }
290
310
  const hasPlacement = node.forPlacement != null || (((_node$forPlacementByI2 = node.forPlacementById) == null ? void 0 : _node$forPlacementByI2.size) ?? 0) > 0;
291
- const hasNonPlacement = node.default != null || (((_node$byIntent5 = node.byIntent) == null ? void 0 : _node$byIntent5.size) ?? 0) > 0 || (((_node$bySemantic3 = node.bySemantic) == null ? void 0 : _node$bySemantic3.size) ?? 0) > 0;
311
+ const hasNonPlacement = node.default != null || (((_node$byIntent7 = node.byIntent) == null ? void 0 : _node$byIntent7.size) ?? 0) > 0 || (((_node$bySemantic3 = node.bySemantic) == null ? void 0 : _node$bySemantic3.size) ?? 0) > 0;
292
312
  return hasPlacement && !hasNonPlacement;
293
313
  }
294
314
  getSlotVariants(name) {
@@ -1 +1 @@
1
- {"version":3,"names":["normalizeResolveOptions","intentOrOptions","semantic","intent","ComponentRegistry","constructor","fallback","_defineProperty","Map","registerSlot","name","component","options","node","slots","get","set","intentNode","ensureSlotIntent","bySemantic","default","register","definition","variants","console","warn","definitions","sectionType","registration","sections","placement","placementId","forPlacementById","forPlacement","ensureSectionIntent","registerAction","handler","actions","resolveSlot","_node$byIntent","found","byIntent","_node$byIntent2","_node$bySemantic","resolveSection","resolveSectionRegistration","resolveSectionOptions","_this$resolveSectionR","undefined","_node$forPlacementByI","byId","_node$byIntent3","_node$byIntent4","_node$bySemantic2","getAllSlots","Array","from","keys","getAllSections","getAllDefinitions","entries","map","_ref","getDefinition","isPlacementOnly","_node$forPlacementByI2","_node$byIntent5","_node$bySemantic3","hasPlacement","size","hasNonPlacement","getSlotVariants","push","getSectionVariants","hasAction","has","executeAction","params","success","message","getRegisteredActions","getCatalog"],"sources":["../../../src/registry/ComponentRegistry.ts"],"sourcesContent":["import type { SectionDefinition } from '../component/componentDefinitions';\nimport type {\n SlotOptions,\n SectionOptions,\n SectionRegistration,\n SlotNode,\n SlotIntentNode,\n SectionNode,\n SectionIntentNode,\n SlotVariant,\n SectionVariant,\n RegistryCatalog,\n ResolveSectionOptions,\n ActionHandler,\n ActionResult,\n} from './types';\n\n/**\n * Accept the legacy positional form `(intent, semantic)` and the new\n * options-object form `({ intent, semantic, placement })`. Returns a\n * normalized `ResolveSectionOptions`.\n */\nfunction normalizeResolveOptions(\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n): ResolveSectionOptions {\n if (intentOrOptions == null) {\n return semantic ? { semantic } : {};\n }\n if (typeof intentOrOptions === 'string') {\n return semantic ? { intent: intentOrOptions, semantic } : { intent: intentOrOptions };\n }\n return intentOrOptions;\n}\n\nexport class ComponentRegistry<C> {\n private slots = new Map<string, SlotNode<C>>();\n private sections = new Map<string, SectionNode<C>>();\n private definitions = new Map<string, SectionDefinition>();\n private actions = new Map<string, ActionHandler>();\n\n constructor(private fallback: C) {}\n\n // ---------------------------------------------------------------------------\n // Registration\n // ---------------------------------------------------------------------------\n\n registerSlot(name: string, component: C, options?: SlotOptions): this {\n let node = this.slots.get(name);\n if (!node) {\n node = {};\n this.slots.set(name, node);\n }\n\n const { intent, semantic } = options ?? {};\n\n if (intent && semantic) {\n const intentNode = this.ensureSlotIntent(node, intent);\n if (!intentNode.bySemantic) {\n intentNode.bySemantic = new Map();\n }\n intentNode.bySemantic.set(semantic, component);\n } else if (intent) {\n const intentNode = this.ensureSlotIntent(node, intent);\n intentNode.default = component;\n } else if (semantic) {\n if (!node.bySemantic) {\n node.bySemantic = new Map();\n }\n node.bySemantic.set(semantic, component);\n } else {\n node.default = component;\n }\n\n return this;\n }\n\n register(\n definition: SectionDefinition,\n variants?: SectionRegistration<C>[],\n ): this {\n // Tolerate missing definitions instead of crashing app init. This\n // happens when a client UMD references a `SectionDefinition` symbol\n // that doesn't exist on the consuming bundle's `Web5Core` global\n // (e.g. UMD built against newer `web5-core` than the app bundle).\n // Without this guard a single missing export breaks every other\n // section the client tries to register.\n if (definition == null) {\n // eslint-disable-next-line no-console\n console.warn(\n '[ComponentRegistry] register() called with a null/undefined SectionDefinition — ' +\n 'likely a version skew between the client UMD and web5-core ' +\n '(an exported definition the UMD imports does not exist on this Web5Core). Skipping.',\n );\n return this;\n }\n this.definitions.set(definition.sectionType, definition);\n\n if (variants) {\n const sectionType = definition.sectionType;\n for (const registration of variants) {\n let node = this.sections.get(sectionType);\n if (!node) {\n node = {};\n this.sections.set(sectionType, node);\n }\n const { intent, semantic, placement, placementId } =\n registration.options ?? {};\n\n // Placement variants are stored on their own slot — no further\n // intent/semantic sub-variants (DL #088 D3.1). If a developer also\n // supplies intent/semantic alongside placement, those are ignored for\n // the placement registration. To register both a placement variant AND\n // an intent variant, register them as separate entries.\n if (placement) {\n // Scoped to a specific placement slot id — keyed so one section type\n // can render differently per placement. An id-less placement variant\n // remains the generic fallback.\n if (placementId) {\n if (!node.forPlacementById) {\n node.forPlacementById = new Map();\n }\n node.forPlacementById.set(placementId, registration);\n } else {\n node.forPlacement = registration;\n }\n continue;\n }\n\n if (intent && semantic) {\n const intentNode = this.ensureSectionIntent(node, intent);\n if (!intentNode.bySemantic) {\n intentNode.bySemantic = new Map();\n }\n intentNode.bySemantic.set(semantic, registration);\n } else if (intent) {\n const intentNode = this.ensureSectionIntent(node, intent);\n intentNode.default = registration;\n } else if (semantic) {\n if (!node.bySemantic) {\n node.bySemantic = new Map();\n }\n node.bySemantic.set(semantic, registration);\n } else {\n node.default = registration;\n }\n }\n }\n\n return this;\n }\n\n registerAction(name: string, handler: ActionHandler): this {\n this.actions.set(name, handler);\n return this;\n }\n\n // ---------------------------------------------------------------------------\n // Resolution\n // ---------------------------------------------------------------------------\n\n resolveSlot(name: string, intent?: string, semantic?: string): C {\n const node = this.slots.get(name);\n if (!node) {\n return this.fallback;\n }\n\n if (intent && semantic) {\n const found = node.byIntent?.get(intent)?.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n if (intent) {\n const found = node.byIntent?.get(intent)?.default;\n if (found) {\n return found;\n }\n }\n if (semantic) {\n const found = node.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n\n return node.default ?? this.fallback;\n }\n\n /**\n * Resolve a section component by type, optionally narrowed by intent /\n * semantic / placement.\n *\n * Accepts both call forms for backward compatibility:\n * resolveSection('hero') — default\n * resolveSection('hero', 'DISCOVERY') — intent (legacy positional)\n * resolveSection('hero', 'DISCOVERY', 'compact') — intent + semantic (legacy)\n * resolveSection('hero', { intent: 'DISCOVERY' }) — options object\n * resolveSection('hero', { placement: true }) — placement variant (DL #088 D3.1)\n * resolveSection('hero', { intent: 'X', placement: true }) — placement wins\n */\n resolveSection(sectionType: string, intent?: string, semantic?: string): C;\n resolveSection(sectionType: string, options: ResolveSectionOptions): C;\n resolveSection(\n sectionType: string,\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n ): C {\n const registration = this.resolveSectionRegistration(\n sectionType,\n normalizeResolveOptions(intentOrOptions, semantic),\n );\n return registration?.component ?? this.fallback;\n }\n\n /**\n * Resolve the options bundle associated with the matched registration.\n * Same overload semantics as `resolveSection`.\n */\n resolveSectionOptions(\n sectionType: string,\n intent?: string,\n semantic?: string,\n ): SectionOptions | undefined;\n resolveSectionOptions(\n sectionType: string,\n options: ResolveSectionOptions,\n ): SectionOptions | undefined;\n resolveSectionOptions(\n sectionType: string,\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n ): SectionOptions | undefined {\n return this.resolveSectionRegistration(\n sectionType,\n normalizeResolveOptions(intentOrOptions, semantic),\n )?.options;\n }\n\n private resolveSectionRegistration(\n sectionType: string,\n options: ResolveSectionOptions,\n ): SectionRegistration<C> | undefined {\n const node = this.sections.get(sectionType);\n if (!node) {\n return undefined;\n }\n\n const { intent, semantic, placement, placementId } = options;\n\n // Placement wins over intent / semantic when requested AND a placement\n // variant is registered for this section (DL #088 D3.1). Cascade:\n // id-scoped variant → generic placement variant → regular chain.\n if (placement) {\n if (placementId) {\n const byId = node.forPlacementById?.get(placementId);\n if (byId) {\n return byId;\n }\n }\n if (node.forPlacement) {\n return node.forPlacement;\n }\n }\n\n if (intent && semantic) {\n const found = node.byIntent?.get(intent as string)?.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n if (intent) {\n const found = node.byIntent?.get(intent as string)?.default;\n if (found) {\n return found;\n }\n }\n if (semantic) {\n const found = node.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n\n return node.default;\n }\n\n // ---------------------------------------------------------------------------\n // Introspection\n // ---------------------------------------------------------------------------\n\n getAllSlots(): string[] {\n return Array.from(this.slots.keys());\n }\n\n getAllSections(): string[] {\n return Array.from(this.sections.keys());\n }\n\n getAllDefinitions(): {\n sectionType: string;\n definition: SectionDefinition;\n }[] {\n return Array.from(this.definitions.entries()).map(\n ([sectionType, definition]) => ({\n sectionType,\n definition,\n }),\n );\n }\n\n getDefinition(sectionType: string): SectionDefinition | undefined {\n return this.definitions.get(sectionType);\n }\n\n /**\n * True when a section type was registered with placement variant(s) only —\n * a `{ placement: true }` (or `placementId`) registration and NO\n * non-placement variant (default / intent / semantic). Such a section is\n * meaningful only inside a placement render; the parser skips its definition\n * when matching in a non-placement context (the main app), so its markdown\n * falls through to the generic sections there.\n *\n * A definition registered with no variants at all (structural defs like\n * `skipNodes` / `htmlComment`) is NOT placement-only — it still matches\n * everywhere.\n */\n isPlacementOnly(sectionType: string): boolean {\n const node = this.sections.get(sectionType);\n if (!node) {\n return false;\n }\n const hasPlacement =\n node.forPlacement != null || (node.forPlacementById?.size ?? 0) > 0;\n const hasNonPlacement =\n node.default != null ||\n (node.byIntent?.size ?? 0) > 0 ||\n (node.bySemantic?.size ?? 0) > 0;\n return hasPlacement && !hasNonPlacement;\n }\n\n getSlotVariants(name: string): SlotVariant[] {\n const node = this.slots.get(name);\n if (!node) {\n return [];\n }\n\n const variants: SlotVariant[] = [];\n if (node.default) {\n variants.push({});\n }\n\n if (node.bySemantic) {\n for (const semantic of node.bySemantic.keys()) {\n variants.push({ semantic });\n }\n }\n\n if (node.byIntent) {\n for (const [intent, intentNode] of node.byIntent) {\n if (intentNode.default) {\n variants.push({ intent });\n }\n if (intentNode.bySemantic) {\n for (const semantic of intentNode.bySemantic.keys()) {\n variants.push({ intent, semantic });\n }\n }\n }\n }\n\n return variants;\n }\n\n getSectionVariants(sectionType: string): SectionVariant[] {\n const node = this.sections.get(sectionType);\n if (!node) {\n return [];\n }\n\n const variants: SectionVariant[] = [];\n if (node.default) {\n variants.push({});\n }\n\n if (node.bySemantic) {\n for (const semantic of node.bySemantic.keys()) {\n variants.push({ semantic });\n }\n }\n\n if (node.byIntent) {\n for (const [intent, intentNode] of node.byIntent) {\n if (intentNode.default) {\n variants.push({ intent });\n }\n if (intentNode.bySemantic) {\n for (const semantic of intentNode.bySemantic.keys()) {\n variants.push({ intent, semantic });\n }\n }\n }\n }\n\n if (node.forPlacement) {\n variants.push({ placement: true });\n }\n\n if (node.forPlacementById) {\n for (const placementId of node.forPlacementById.keys()) {\n variants.push({ placement: true, placementId });\n }\n }\n\n return variants;\n }\n\n hasAction(name: string): boolean {\n return this.actions.has(name);\n }\n\n async executeAction(\n name: string,\n params: Record<string, string>,\n ): Promise<ActionResult> {\n const handler = this.actions.get(name);\n if (!handler) {\n console.warn(`[Action] No handler for: \"${name}\"`);\n return { success: false, message: `Unknown action: ${name}` };\n }\n return handler(params);\n }\n\n getRegisteredActions(): string[] {\n return Array.from(this.actions.keys());\n }\n\n getCatalog(): RegistryCatalog {\n return {\n slots: this.getAllSlots().map((name) => ({\n name,\n variants: this.getSlotVariants(name),\n })),\n sections: this.getAllSections().map((sectionType) => ({\n name: sectionType,\n variants: this.getSectionVariants(sectionType),\n })),\n definitions: this.getAllDefinitions(),\n };\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private ensureSectionIntent(\n node: SectionNode<C>,\n intent: string,\n ): SectionIntentNode<C> {\n if (!node.byIntent) {\n node.byIntent = new Map();\n }\n let intentNode = node.byIntent.get(intent);\n if (!intentNode) {\n intentNode = {};\n node.byIntent.set(intent, intentNode);\n }\n return intentNode;\n }\n\n private ensureSlotIntent(\n node: SlotNode<C>,\n intent: string,\n ): SlotIntentNode<C> {\n if (!node.byIntent) {\n node.byIntent = new Map();\n }\n let intentNode = node.byIntent.get(intent);\n if (!intentNode) {\n intentNode = {};\n node.byIntent.set(intent, intentNode);\n }\n return intentNode;\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["normalizeResolveOptions","intentOrOptions","semantic","intent","ComponentRegistry","constructor","fallback","_defineProperty","Map","registerSlot","name","component","options","node","slots","get","set","intentNode","ensureSlotIntent","bySemantic","default","register","definition","variants","console","warn","definitions","sectionType","registration","sections","placement","placementId","forPlacementById","forPlacement","ensureSectionIntent","registerAction","handler","actions","resolveSlot","_node$byIntent","found","byIntent","_node$byIntent2","_node$bySemantic","resolveSection","resolveSectionRegistration","resolveSectionOptions","_this$resolveSectionR","undefined","_node$forPlacementByI","byId","_node$byIntent3","_node$byIntent4","_node$bySemantic2","getAllSlots","Array","from","keys","getAllSections","getKnownIntents","intents","Set","values","_node$byIntent5","forEach","_variant","key","add","_node$byIntent6","getAllDefinitions","entries","map","_ref","getDefinition","isPlacementOnly","_node$forPlacementByI2","_node$byIntent7","_node$bySemantic3","hasPlacement","size","hasNonPlacement","getSlotVariants","push","getSectionVariants","hasAction","has","executeAction","params","success","message","getRegisteredActions","getCatalog"],"sources":["../../../src/registry/ComponentRegistry.ts"],"sourcesContent":["import type { SectionDefinition } from '../component/componentDefinitions';\nimport type {\n SlotOptions,\n SectionOptions,\n SectionRegistration,\n SlotNode,\n SlotIntentNode,\n SectionNode,\n SectionIntentNode,\n SlotVariant,\n SectionVariant,\n RegistryCatalog,\n ResolveSectionOptions,\n ActionHandler,\n ActionResult,\n} from './types';\n\n/**\n * Accept the legacy positional form `(intent, semantic)` and the new\n * options-object form `({ intent, semantic, placement })`. Returns a\n * normalized `ResolveSectionOptions`.\n */\nfunction normalizeResolveOptions(\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n): ResolveSectionOptions {\n if (intentOrOptions == null) {\n return semantic ? { semantic } : {};\n }\n if (typeof intentOrOptions === 'string') {\n return semantic ? { intent: intentOrOptions, semantic } : { intent: intentOrOptions };\n }\n return intentOrOptions;\n}\n\nexport class ComponentRegistry<C> {\n private slots = new Map<string, SlotNode<C>>();\n private sections = new Map<string, SectionNode<C>>();\n private definitions = new Map<string, SectionDefinition>();\n private actions = new Map<string, ActionHandler>();\n\n constructor(private fallback: C) {}\n\n // ---------------------------------------------------------------------------\n // Registration\n // ---------------------------------------------------------------------------\n\n registerSlot(name: string, component: C, options?: SlotOptions): this {\n let node = this.slots.get(name);\n if (!node) {\n node = {};\n this.slots.set(name, node);\n }\n\n const { intent, semantic } = options ?? {};\n\n if (intent && semantic) {\n const intentNode = this.ensureSlotIntent(node, intent);\n if (!intentNode.bySemantic) {\n intentNode.bySemantic = new Map();\n }\n intentNode.bySemantic.set(semantic, component);\n } else if (intent) {\n const intentNode = this.ensureSlotIntent(node, intent);\n intentNode.default = component;\n } else if (semantic) {\n if (!node.bySemantic) {\n node.bySemantic = new Map();\n }\n node.bySemantic.set(semantic, component);\n } else {\n node.default = component;\n }\n\n return this;\n }\n\n register(\n definition: SectionDefinition,\n variants?: SectionRegistration<C>[],\n ): this {\n // Tolerate missing definitions instead of crashing app init. This\n // happens when a client UMD references a `SectionDefinition` symbol\n // that doesn't exist on the consuming bundle's `Web5Core` global\n // (e.g. UMD built against newer `web5-core` than the app bundle).\n // Without this guard a single missing export breaks every other\n // section the client tries to register.\n if (definition == null) {\n // eslint-disable-next-line no-console\n console.warn(\n '[ComponentRegistry] register() called with a null/undefined SectionDefinition — ' +\n 'likely a version skew between the client UMD and web5-core ' +\n '(an exported definition the UMD imports does not exist on this Web5Core). Skipping.',\n );\n return this;\n }\n this.definitions.set(definition.sectionType, definition);\n\n if (variants) {\n const sectionType = definition.sectionType;\n for (const registration of variants) {\n let node = this.sections.get(sectionType);\n if (!node) {\n node = {};\n this.sections.set(sectionType, node);\n }\n const { intent, semantic, placement, placementId } =\n registration.options ?? {};\n\n // Placement variants are stored on their own slot — no further\n // intent/semantic sub-variants (DL #088 D3.1). If a developer also\n // supplies intent/semantic alongside placement, those are ignored for\n // the placement registration. To register both a placement variant AND\n // an intent variant, register them as separate entries.\n if (placement) {\n // Scoped to a specific placement slot id — keyed so one section type\n // can render differently per placement. An id-less placement variant\n // remains the generic fallback.\n if (placementId) {\n if (!node.forPlacementById) {\n node.forPlacementById = new Map();\n }\n node.forPlacementById.set(placementId, registration);\n } else {\n node.forPlacement = registration;\n }\n continue;\n }\n\n if (intent && semantic) {\n const intentNode = this.ensureSectionIntent(node, intent);\n if (!intentNode.bySemantic) {\n intentNode.bySemantic = new Map();\n }\n intentNode.bySemantic.set(semantic, registration);\n } else if (intent) {\n const intentNode = this.ensureSectionIntent(node, intent);\n intentNode.default = registration;\n } else if (semantic) {\n if (!node.bySemantic) {\n node.bySemantic = new Map();\n }\n node.bySemantic.set(semantic, registration);\n } else {\n node.default = registration;\n }\n }\n }\n\n return this;\n }\n\n registerAction(name: string, handler: ActionHandler): this {\n this.actions.set(name, handler);\n return this;\n }\n\n // ---------------------------------------------------------------------------\n // Resolution\n // ---------------------------------------------------------------------------\n\n resolveSlot(name: string, intent?: string, semantic?: string): C {\n const node = this.slots.get(name);\n if (!node) {\n return this.fallback;\n }\n\n if (intent && semantic) {\n const found = node.byIntent?.get(intent)?.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n if (intent) {\n const found = node.byIntent?.get(intent)?.default;\n if (found) {\n return found;\n }\n }\n if (semantic) {\n const found = node.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n\n return node.default ?? this.fallback;\n }\n\n /**\n * Resolve a section component by type, optionally narrowed by intent /\n * semantic / placement.\n *\n * Accepts both call forms for backward compatibility:\n * resolveSection('hero') — default\n * resolveSection('hero', 'DISCOVERY') — intent (legacy positional)\n * resolveSection('hero', 'DISCOVERY', 'compact') — intent + semantic (legacy)\n * resolveSection('hero', { intent: 'DISCOVERY' }) — options object\n * resolveSection('hero', { placement: true }) — placement variant (DL #088 D3.1)\n * resolveSection('hero', { intent: 'X', placement: true }) — placement wins\n */\n resolveSection(sectionType: string, intent?: string, semantic?: string): C;\n resolveSection(sectionType: string, options: ResolveSectionOptions): C;\n resolveSection(\n sectionType: string,\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n ): C {\n const registration = this.resolveSectionRegistration(\n sectionType,\n normalizeResolveOptions(intentOrOptions, semantic),\n );\n return registration?.component ?? this.fallback;\n }\n\n /**\n * Resolve the options bundle associated with the matched registration.\n * Same overload semantics as `resolveSection`.\n */\n resolveSectionOptions(\n sectionType: string,\n intent?: string,\n semantic?: string,\n ): SectionOptions | undefined;\n resolveSectionOptions(\n sectionType: string,\n options: ResolveSectionOptions,\n ): SectionOptions | undefined;\n resolveSectionOptions(\n sectionType: string,\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n ): SectionOptions | undefined {\n return this.resolveSectionRegistration(\n sectionType,\n normalizeResolveOptions(intentOrOptions, semantic),\n )?.options;\n }\n\n private resolveSectionRegistration(\n sectionType: string,\n options: ResolveSectionOptions,\n ): SectionRegistration<C> | undefined {\n const node = this.sections.get(sectionType);\n if (!node) {\n return undefined;\n }\n\n const { intent, semantic, placement, placementId } = options;\n\n // Placement wins over intent / semantic when requested AND a placement\n // variant is registered for this section (DL #088 D3.1). Cascade:\n // id-scoped variant → generic placement variant → regular chain.\n if (placement) {\n if (placementId) {\n const byId = node.forPlacementById?.get(placementId);\n if (byId) {\n return byId;\n }\n }\n if (node.forPlacement) {\n return node.forPlacement;\n }\n }\n\n if (intent && semantic) {\n const found = node.byIntent?.get(intent as string)?.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n if (intent) {\n const found = node.byIntent?.get(intent as string)?.default;\n if (found) {\n return found;\n }\n }\n if (semantic) {\n const found = node.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n\n return node.default;\n }\n\n // ---------------------------------------------------------------------------\n // Introspection\n // ---------------------------------------------------------------------------\n\n getAllSlots(): string[] {\n return Array.from(this.slots.keys());\n }\n\n getAllSections(): string[] {\n return Array.from(this.sections.keys());\n }\n\n /**\n * Every intent that has at least one registered slot or section variant —\n * i.e. the client's own intent list, derived from what it actually\n * registered. Assembly uses this to validate an incoming intent before it\n * becomes a resolution key, falling back to core's `DEFAULT_INTENTS` only\n * when a client registers no intent variants at all.\n */\n getKnownIntents(): string[] {\n const intents = new Set<string>();\n for (const node of this.slots.values()) {\n node.byIntent?.forEach((_variant, key) => intents.add(key));\n }\n for (const node of this.sections.values()) {\n node.byIntent?.forEach((_variant, key) => intents.add(key));\n }\n return Array.from(intents);\n }\n\n getAllDefinitions(): {\n sectionType: string;\n definition: SectionDefinition;\n }[] {\n return Array.from(this.definitions.entries()).map(\n ([sectionType, definition]) => ({\n sectionType,\n definition,\n }),\n );\n }\n\n getDefinition(sectionType: string): SectionDefinition | undefined {\n return this.definitions.get(sectionType);\n }\n\n /**\n * True when a section type was registered with placement variant(s) only —\n * a `{ placement: true }` (or `placementId`) registration and NO\n * non-placement variant (default / intent / semantic). Such a section is\n * meaningful only inside a placement render; the parser skips its definition\n * when matching in a non-placement context (the main app), so its markdown\n * falls through to the generic sections there.\n *\n * A definition registered with no variants at all (structural defs like\n * `skipNodes` / `htmlComment`) is NOT placement-only — it still matches\n * everywhere.\n */\n isPlacementOnly(sectionType: string): boolean {\n const node = this.sections.get(sectionType);\n if (!node) {\n return false;\n }\n const hasPlacement =\n node.forPlacement != null || (node.forPlacementById?.size ?? 0) > 0;\n const hasNonPlacement =\n node.default != null ||\n (node.byIntent?.size ?? 0) > 0 ||\n (node.bySemantic?.size ?? 0) > 0;\n return hasPlacement && !hasNonPlacement;\n }\n\n getSlotVariants(name: string): SlotVariant[] {\n const node = this.slots.get(name);\n if (!node) {\n return [];\n }\n\n const variants: SlotVariant[] = [];\n if (node.default) {\n variants.push({});\n }\n\n if (node.bySemantic) {\n for (const semantic of node.bySemantic.keys()) {\n variants.push({ semantic });\n }\n }\n\n if (node.byIntent) {\n for (const [intent, intentNode] of node.byIntent) {\n if (intentNode.default) {\n variants.push({ intent });\n }\n if (intentNode.bySemantic) {\n for (const semantic of intentNode.bySemantic.keys()) {\n variants.push({ intent, semantic });\n }\n }\n }\n }\n\n return variants;\n }\n\n getSectionVariants(sectionType: string): SectionVariant[] {\n const node = this.sections.get(sectionType);\n if (!node) {\n return [];\n }\n\n const variants: SectionVariant[] = [];\n if (node.default) {\n variants.push({});\n }\n\n if (node.bySemantic) {\n for (const semantic of node.bySemantic.keys()) {\n variants.push({ semantic });\n }\n }\n\n if (node.byIntent) {\n for (const [intent, intentNode] of node.byIntent) {\n if (intentNode.default) {\n variants.push({ intent });\n }\n if (intentNode.bySemantic) {\n for (const semantic of intentNode.bySemantic.keys()) {\n variants.push({ intent, semantic });\n }\n }\n }\n }\n\n if (node.forPlacement) {\n variants.push({ placement: true });\n }\n\n if (node.forPlacementById) {\n for (const placementId of node.forPlacementById.keys()) {\n variants.push({ placement: true, placementId });\n }\n }\n\n return variants;\n }\n\n hasAction(name: string): boolean {\n return this.actions.has(name);\n }\n\n async executeAction(\n name: string,\n params: Record<string, string>,\n ): Promise<ActionResult> {\n const handler = this.actions.get(name);\n if (!handler) {\n console.warn(`[Action] No handler for: \"${name}\"`);\n return { success: false, message: `Unknown action: ${name}` };\n }\n return handler(params);\n }\n\n getRegisteredActions(): string[] {\n return Array.from(this.actions.keys());\n }\n\n getCatalog(): RegistryCatalog {\n return {\n slots: this.getAllSlots().map((name) => ({\n name,\n variants: this.getSlotVariants(name),\n })),\n sections: this.getAllSections().map((sectionType) => ({\n name: sectionType,\n variants: this.getSectionVariants(sectionType),\n })),\n definitions: this.getAllDefinitions(),\n };\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private ensureSectionIntent(\n node: SectionNode<C>,\n intent: string,\n ): SectionIntentNode<C> {\n if (!node.byIntent) {\n node.byIntent = new Map();\n }\n let intentNode = node.byIntent.get(intent);\n if (!intentNode) {\n intentNode = {};\n node.byIntent.set(intent, intentNode);\n }\n return intentNode;\n }\n\n private ensureSlotIntent(\n node: SlotNode<C>,\n intent: string,\n ): SlotIntentNode<C> {\n if (!node.byIntent) {\n node.byIntent = new Map();\n }\n let intentNode = node.byIntent.get(intent);\n if (!intentNode) {\n intentNode = {};\n node.byIntent.set(intent, intentNode);\n }\n return intentNode;\n }\n}\n"],"mappings":";AAiBA;AACA;AACA;AACA;AACA;AACA,SAASA,uBAAuBA,CAC9BC,eAAgD,EAChDC,QAAiB,EACM;EACvB,IAAID,eAAe,IAAI,IAAI,EAAE;IAC3B,OAAOC,QAAQ,GAAG;MAAEA;IAAS,CAAC,GAAG,CAAC,CAAC;EACrC;EACA,IAAI,OAAOD,eAAe,KAAK,QAAQ,EAAE;IACvC,OAAOC,QAAQ,GAAG;MAAEC,MAAM,EAAEF,eAAe;MAAEC;IAAS,CAAC,GAAG;MAAEC,MAAM,EAAEF;IAAgB,CAAC;EACvF;EACA,OAAOA,eAAe;AACxB;AAEA,OAAO,MAAMG,iBAAiB,CAAI;EAMhCC,WAAWA,CAASC,QAAW,EAAE;IAAA,KAAbA,QAAW,GAAXA,QAAW;IAAAC,eAAA,gBALf,IAAIC,GAAG,CAAsB,CAAC;IAAAD,eAAA,mBAC3B,IAAIC,GAAG,CAAyB,CAAC;IAAAD,eAAA,sBAC9B,IAAIC,GAAG,CAA4B,CAAC;IAAAD,eAAA,kBACxC,IAAIC,GAAG,CAAwB,CAAC;EAEhB;;EAElC;EACA;EACA;;EAEAC,YAAYA,CAACC,IAAY,EAAEC,SAAY,EAAEC,OAAqB,EAAQ;IACpE,IAAIC,IAAI,GAAG,IAAI,CAACC,KAAK,CAACC,GAAG,CAACL,IAAI,CAAC;IAC/B,IAAI,CAACG,IAAI,EAAE;MACTA,IAAI,GAAG,CAAC,CAAC;MACT,IAAI,CAACC,KAAK,CAACE,GAAG,CAACN,IAAI,EAAEG,IAAI,CAAC;IAC5B;IAEA,MAAM;MAAEV,MAAM;MAAED;IAAS,CAAC,GAAGU,OAAO,IAAI,CAAC,CAAC;IAE1C,IAAIT,MAAM,IAAID,QAAQ,EAAE;MACtB,MAAMe,UAAU,GAAG,IAAI,CAACC,gBAAgB,CAACL,IAAI,EAAEV,MAAM,CAAC;MACtD,IAAI,CAACc,UAAU,CAACE,UAAU,EAAE;QAC1BF,UAAU,CAACE,UAAU,GAAG,IAAIX,GAAG,CAAC,CAAC;MACnC;MACAS,UAAU,CAACE,UAAU,CAACH,GAAG,CAACd,QAAQ,EAAES,SAAS,CAAC;IAChD,CAAC,MAAM,IAAIR,MAAM,EAAE;MACjB,MAAMc,UAAU,GAAG,IAAI,CAACC,gBAAgB,CAACL,IAAI,EAAEV,MAAM,CAAC;MACtDc,UAAU,CAACG,OAAO,GAAGT,SAAS;IAChC,CAAC,MAAM,IAAIT,QAAQ,EAAE;MACnB,IAAI,CAACW,IAAI,CAACM,UAAU,EAAE;QACpBN,IAAI,CAACM,UAAU,GAAG,IAAIX,GAAG,CAAC,CAAC;MAC7B;MACAK,IAAI,CAACM,UAAU,CAACH,GAAG,CAACd,QAAQ,EAAES,SAAS,CAAC;IAC1C,CAAC,MAAM;MACLE,IAAI,CAACO,OAAO,GAAGT,SAAS;IAC1B;IAEA,OAAO,IAAI;EACb;EAEAU,QAAQA,CACNC,UAA6B,EAC7BC,QAAmC,EAC7B;IACN;IACA;IACA;IACA;IACA;IACA;IACA,IAAID,UAAU,IAAI,IAAI,EAAE;MACtB;MACAE,OAAO,CAACC,IAAI,CACV,kFAAkF,GAChF,6DAA6D,GAC7D,qFACJ,CAAC;MACD,OAAO,IAAI;IACb;IACA,IAAI,CAACC,WAAW,CAACV,GAAG,CAACM,UAAU,CAACK,WAAW,EAAEL,UAAU,CAAC;IAExD,IAAIC,QAAQ,EAAE;MACZ,MAAMI,WAAW,GAAGL,UAAU,CAACK,WAAW;MAC1C,KAAK,MAAMC,YAAY,IAAIL,QAAQ,EAAE;QACnC,IAAIV,IAAI,GAAG,IAAI,CAACgB,QAAQ,CAACd,GAAG,CAACY,WAAW,CAAC;QACzC,IAAI,CAACd,IAAI,EAAE;UACTA,IAAI,GAAG,CAAC,CAAC;UACT,IAAI,CAACgB,QAAQ,CAACb,GAAG,CAACW,WAAW,EAAEd,IAAI,CAAC;QACtC;QACA,MAAM;UAAEV,MAAM;UAAED,QAAQ;UAAE4B,SAAS;UAAEC;QAAY,CAAC,GAChDH,YAAY,CAAChB,OAAO,IAAI,CAAC,CAAC;;QAE5B;QACA;QACA;QACA;QACA;QACA,IAAIkB,SAAS,EAAE;UACb;UACA;UACA;UACA,IAAIC,WAAW,EAAE;YACf,IAAI,CAAClB,IAAI,CAACmB,gBAAgB,EAAE;cAC1BnB,IAAI,CAACmB,gBAAgB,GAAG,IAAIxB,GAAG,CAAC,CAAC;YACnC;YACAK,IAAI,CAACmB,gBAAgB,CAAChB,GAAG,CAACe,WAAW,EAAEH,YAAY,CAAC;UACtD,CAAC,MAAM;YACLf,IAAI,CAACoB,YAAY,GAAGL,YAAY;UAClC;UACA;QACF;QAEA,IAAIzB,MAAM,IAAID,QAAQ,EAAE;UACtB,MAAMe,UAAU,GAAG,IAAI,CAACiB,mBAAmB,CAACrB,IAAI,EAAEV,MAAM,CAAC;UACzD,IAAI,CAACc,UAAU,CAACE,UAAU,EAAE;YAC1BF,UAAU,CAACE,UAAU,GAAG,IAAIX,GAAG,CAAC,CAAC;UACnC;UACAS,UAAU,CAACE,UAAU,CAACH,GAAG,CAACd,QAAQ,EAAE0B,YAAY,CAAC;QACnD,CAAC,MAAM,IAAIzB,MAAM,EAAE;UACjB,MAAMc,UAAU,GAAG,IAAI,CAACiB,mBAAmB,CAACrB,IAAI,EAAEV,MAAM,CAAC;UACzDc,UAAU,CAACG,OAAO,GAAGQ,YAAY;QACnC,CAAC,MAAM,IAAI1B,QAAQ,EAAE;UACnB,IAAI,CAACW,IAAI,CAACM,UAAU,EAAE;YACpBN,IAAI,CAACM,UAAU,GAAG,IAAIX,GAAG,CAAC,CAAC;UAC7B;UACAK,IAAI,CAACM,UAAU,CAACH,GAAG,CAACd,QAAQ,EAAE0B,YAAY,CAAC;QAC7C,CAAC,MAAM;UACLf,IAAI,CAACO,OAAO,GAAGQ,YAAY;QAC7B;MACF;IACF;IAEA,OAAO,IAAI;EACb;EAEAO,cAAcA,CAACzB,IAAY,EAAE0B,OAAsB,EAAQ;IACzD,IAAI,CAACC,OAAO,CAACrB,GAAG,CAACN,IAAI,EAAE0B,OAAO,CAAC;IAC/B,OAAO,IAAI;EACb;;EAEA;EACA;EACA;;EAEAE,WAAWA,CAAC5B,IAAY,EAAEP,MAAe,EAAED,QAAiB,EAAK;IAC/D,MAAMW,IAAI,GAAG,IAAI,CAACC,KAAK,CAACC,GAAG,CAACL,IAAI,CAAC;IACjC,IAAI,CAACG,IAAI,EAAE;MACT,OAAO,IAAI,CAACP,QAAQ;IACtB;IAEA,IAAIH,MAAM,IAAID,QAAQ,EAAE;MAAA,IAAAqC,cAAA;MACtB,MAAMC,KAAK,IAAAD,cAAA,GAAG1B,IAAI,CAAC4B,QAAQ,cAAAF,cAAA,GAAbA,cAAA,CAAexB,GAAG,CAACZ,MAAM,CAAC,cAAAoC,cAAA,GAA1BA,cAAA,CAA4BpB,UAAU,qBAAtCoB,cAAA,CAAwCxB,GAAG,CAACb,QAAQ,CAAC;MACnE,IAAIsC,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IACA,IAAIrC,MAAM,EAAE;MAAA,IAAAuC,eAAA;MACV,MAAMF,KAAK,IAAAE,eAAA,GAAG7B,IAAI,CAAC4B,QAAQ,cAAAC,eAAA,GAAbA,eAAA,CAAe3B,GAAG,CAACZ,MAAM,CAAC,qBAA1BuC,eAAA,CAA4BtB,OAAO;MACjD,IAAIoB,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IACA,IAAItC,QAAQ,EAAE;MAAA,IAAAyC,gBAAA;MACZ,MAAMH,KAAK,IAAAG,gBAAA,GAAG9B,IAAI,CAACM,UAAU,qBAAfwB,gBAAA,CAAiB5B,GAAG,CAACb,QAAQ,CAAC;MAC5C,IAAIsC,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IAEA,OAAO3B,IAAI,CAACO,OAAO,IAAI,IAAI,CAACd,QAAQ;EACtC;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAGEsC,cAAcA,CACZjB,WAAmB,EACnB1B,eAAgD,EAChDC,QAAiB,EACd;IACH,MAAM0B,YAAY,GAAG,IAAI,CAACiB,0BAA0B,CAClDlB,WAAW,EACX3B,uBAAuB,CAACC,eAAe,EAAEC,QAAQ,CACnD,CAAC;IACD,OAAO,CAAA0B,YAAY,oBAAZA,YAAY,CAAEjB,SAAS,KAAI,IAAI,CAACL,QAAQ;EACjD;;EAEA;AACF;AACA;AACA;;EAUEwC,qBAAqBA,CACnBnB,WAAmB,EACnB1B,eAAgD,EAChDC,QAAiB,EACW;IAAA,IAAA6C,qBAAA;IAC5B,QAAAA,qBAAA,GAAO,IAAI,CAACF,0BAA0B,CACpClB,WAAW,EACX3B,uBAAuB,CAACC,eAAe,EAAEC,QAAQ,CACnD,CAAC,qBAHM6C,qBAAA,CAGJnC,OAAO;EACZ;EAEQiC,0BAA0BA,CAChClB,WAAmB,EACnBf,OAA8B,EACM;IACpC,MAAMC,IAAI,GAAG,IAAI,CAACgB,QAAQ,CAACd,GAAG,CAACY,WAAW,CAAC;IAC3C,IAAI,CAACd,IAAI,EAAE;MACT,OAAOmC,SAAS;IAClB;IAEA,MAAM;MAAE7C,MAAM;MAAED,QAAQ;MAAE4B,SAAS;MAAEC;IAAY,CAAC,GAAGnB,OAAO;;IAE5D;IACA;IACA;IACA,IAAIkB,SAAS,EAAE;MACb,IAAIC,WAAW,EAAE;QAAA,IAAAkB,qBAAA;QACf,MAAMC,IAAI,IAAAD,qBAAA,GAAGpC,IAAI,CAACmB,gBAAgB,qBAArBiB,qBAAA,CAAuBlC,GAAG,CAACgB,WAAW,CAAC;QACpD,IAAImB,IAAI,EAAE;UACR,OAAOA,IAAI;QACb;MACF;MACA,IAAIrC,IAAI,CAACoB,YAAY,EAAE;QACrB,OAAOpB,IAAI,CAACoB,YAAY;MAC1B;IACF;IAEA,IAAI9B,MAAM,IAAID,QAAQ,EAAE;MAAA,IAAAiD,eAAA;MACtB,MAAMX,KAAK,IAAAW,eAAA,GAAGtC,IAAI,CAAC4B,QAAQ,cAAAU,eAAA,GAAbA,eAAA,CAAepC,GAAG,CAACZ,MAAgB,CAAC,cAAAgD,eAAA,GAApCA,eAAA,CAAsChC,UAAU,qBAAhDgC,eAAA,CAAkDpC,GAAG,CAACb,QAAQ,CAAC;MAC7E,IAAIsC,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IACA,IAAIrC,MAAM,EAAE;MAAA,IAAAiD,eAAA;MACV,MAAMZ,KAAK,IAAAY,eAAA,GAAGvC,IAAI,CAAC4B,QAAQ,cAAAW,eAAA,GAAbA,eAAA,CAAerC,GAAG,CAACZ,MAAgB,CAAC,qBAApCiD,eAAA,CAAsChC,OAAO;MAC3D,IAAIoB,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IACA,IAAItC,QAAQ,EAAE;MAAA,IAAAmD,iBAAA;MACZ,MAAMb,KAAK,IAAAa,iBAAA,GAAGxC,IAAI,CAACM,UAAU,qBAAfkC,iBAAA,CAAiBtC,GAAG,CAACb,QAAQ,CAAC;MAC5C,IAAIsC,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IAEA,OAAO3B,IAAI,CAACO,OAAO;EACrB;;EAEA;EACA;EACA;;EAEAkC,WAAWA,CAAA,EAAa;IACtB,OAAOC,KAAK,CAACC,IAAI,CAAC,IAAI,CAAC1C,KAAK,CAAC2C,IAAI,CAAC,CAAC,CAAC;EACtC;EAEAC,cAAcA,CAAA,EAAa;IACzB,OAAOH,KAAK,CAACC,IAAI,CAAC,IAAI,CAAC3B,QAAQ,CAAC4B,IAAI,CAAC,CAAC,CAAC;EACzC;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEE,eAAeA,CAAA,EAAa;IAC1B,MAAMC,OAAO,GAAG,IAAIC,GAAG,CAAS,CAAC;IACjC,KAAK,MAAMhD,IAAI,IAAI,IAAI,CAACC,KAAK,CAACgD,MAAM,CAAC,CAAC,EAAE;MAAA,IAAAC,eAAA;MACtC,CAAAA,eAAA,GAAAlD,IAAI,CAAC4B,QAAQ,aAAbsB,eAAA,CAAeC,OAAO,CAAC,CAACC,QAAQ,EAAEC,GAAG,KAAKN,OAAO,CAACO,GAAG,CAACD,GAAG,CAAC,CAAC;IAC7D;IACA,KAAK,MAAMrD,IAAI,IAAI,IAAI,CAACgB,QAAQ,CAACiC,MAAM,CAAC,CAAC,EAAE;MAAA,IAAAM,eAAA;MACzC,CAAAA,eAAA,GAAAvD,IAAI,CAAC4B,QAAQ,aAAb2B,eAAA,CAAeJ,OAAO,CAAC,CAACC,QAAQ,EAAEC,GAAG,KAAKN,OAAO,CAACO,GAAG,CAACD,GAAG,CAAC,CAAC;IAC7D;IACA,OAAOX,KAAK,CAACC,IAAI,CAACI,OAAO,CAAC;EAC5B;EAEAS,iBAAiBA,CAAA,EAGb;IACF,OAAOd,KAAK,CAACC,IAAI,CAAC,IAAI,CAAC9B,WAAW,CAAC4C,OAAO,CAAC,CAAC,CAAC,CAACC,GAAG,CAC/CC,IAAA;MAAA,IAAC,CAAC7C,WAAW,EAAEL,UAAU,CAAC,GAAAkD,IAAA;MAAA,OAAM;QAC9B7C,WAAW;QACXL;MACF,CAAC;IAAA,CACH,CAAC;EACH;EAEAmD,aAAaA,CAAC9C,WAAmB,EAAiC;IAChE,OAAO,IAAI,CAACD,WAAW,CAACX,GAAG,CAACY,WAAW,CAAC;EAC1C;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE+C,eAAeA,CAAC/C,WAAmB,EAAW;IAAA,IAAAgD,sBAAA,EAAAC,eAAA,EAAAC,iBAAA;IAC5C,MAAMhE,IAAI,GAAG,IAAI,CAACgB,QAAQ,CAACd,GAAG,CAACY,WAAW,CAAC;IAC3C,IAAI,CAACd,IAAI,EAAE;MACT,OAAO,KAAK;IACd;IACA,MAAMiE,YAAY,GAChBjE,IAAI,CAACoB,YAAY,IAAI,IAAI,IAAI,CAAC,EAAA0C,sBAAA,GAAA9D,IAAI,CAACmB,gBAAgB,qBAArB2C,sBAAA,CAAuBI,IAAI,KAAI,CAAC,IAAI,CAAC;IACrE,MAAMC,eAAe,GACnBnE,IAAI,CAACO,OAAO,IAAI,IAAI,IACpB,CAAC,EAAAwD,eAAA,GAAA/D,IAAI,CAAC4B,QAAQ,qBAAbmC,eAAA,CAAeG,IAAI,KAAI,CAAC,IAAI,CAAC,IAC9B,CAAC,EAAAF,iBAAA,GAAAhE,IAAI,CAACM,UAAU,qBAAf0D,iBAAA,CAAiBE,IAAI,KAAI,CAAC,IAAI,CAAC;IAClC,OAAOD,YAAY,IAAI,CAACE,eAAe;EACzC;EAEAC,eAAeA,CAACvE,IAAY,EAAiB;IAC3C,MAAMG,IAAI,GAAG,IAAI,CAACC,KAAK,CAACC,GAAG,CAACL,IAAI,CAAC;IACjC,IAAI,CAACG,IAAI,EAAE;MACT,OAAO,EAAE;IACX;IAEA,MAAMU,QAAuB,GAAG,EAAE;IAClC,IAAIV,IAAI,CAACO,OAAO,EAAE;MAChBG,QAAQ,CAAC2D,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB;IAEA,IAAIrE,IAAI,CAACM,UAAU,EAAE;MACnB,KAAK,MAAMjB,QAAQ,IAAIW,IAAI,CAACM,UAAU,CAACsC,IAAI,CAAC,CAAC,EAAE;QAC7ClC,QAAQ,CAAC2D,IAAI,CAAC;UAAEhF;QAAS,CAAC,CAAC;MAC7B;IACF;IAEA,IAAIW,IAAI,CAAC4B,QAAQ,EAAE;MACjB,KAAK,MAAM,CAACtC,MAAM,EAAEc,UAAU,CAAC,IAAIJ,IAAI,CAAC4B,QAAQ,EAAE;QAChD,IAAIxB,UAAU,CAACG,OAAO,EAAE;UACtBG,QAAQ,CAAC2D,IAAI,CAAC;YAAE/E;UAAO,CAAC,CAAC;QAC3B;QACA,IAAIc,UAAU,CAACE,UAAU,EAAE;UACzB,KAAK,MAAMjB,QAAQ,IAAIe,UAAU,CAACE,UAAU,CAACsC,IAAI,CAAC,CAAC,EAAE;YACnDlC,QAAQ,CAAC2D,IAAI,CAAC;cAAE/E,MAAM;cAAED;YAAS,CAAC,CAAC;UACrC;QACF;MACF;IACF;IAEA,OAAOqB,QAAQ;EACjB;EAEA4D,kBAAkBA,CAACxD,WAAmB,EAAoB;IACxD,MAAMd,IAAI,GAAG,IAAI,CAACgB,QAAQ,CAACd,GAAG,CAACY,WAAW,CAAC;IAC3C,IAAI,CAACd,IAAI,EAAE;MACT,OAAO,EAAE;IACX;IAEA,MAAMU,QAA0B,GAAG,EAAE;IACrC,IAAIV,IAAI,CAACO,OAAO,EAAE;MAChBG,QAAQ,CAAC2D,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB;IAEA,IAAIrE,IAAI,CAACM,UAAU,EAAE;MACnB,KAAK,MAAMjB,QAAQ,IAAIW,IAAI,CAACM,UAAU,CAACsC,IAAI,CAAC,CAAC,EAAE;QAC7ClC,QAAQ,CAAC2D,IAAI,CAAC;UAAEhF;QAAS,CAAC,CAAC;MAC7B;IACF;IAEA,IAAIW,IAAI,CAAC4B,QAAQ,EAAE;MACjB,KAAK,MAAM,CAACtC,MAAM,EAAEc,UAAU,CAAC,IAAIJ,IAAI,CAAC4B,QAAQ,EAAE;QAChD,IAAIxB,UAAU,CAACG,OAAO,EAAE;UACtBG,QAAQ,CAAC2D,IAAI,CAAC;YAAE/E;UAAO,CAAC,CAAC;QAC3B;QACA,IAAIc,UAAU,CAACE,UAAU,EAAE;UACzB,KAAK,MAAMjB,QAAQ,IAAIe,UAAU,CAACE,UAAU,CAACsC,IAAI,CAAC,CAAC,EAAE;YACnDlC,QAAQ,CAAC2D,IAAI,CAAC;cAAE/E,MAAM;cAAED;YAAS,CAAC,CAAC;UACrC;QACF;MACF;IACF;IAEA,IAAIW,IAAI,CAACoB,YAAY,EAAE;MACrBV,QAAQ,CAAC2D,IAAI,CAAC;QAAEpD,SAAS,EAAE;MAAK,CAAC,CAAC;IACpC;IAEA,IAAIjB,IAAI,CAACmB,gBAAgB,EAAE;MACzB,KAAK,MAAMD,WAAW,IAAIlB,IAAI,CAACmB,gBAAgB,CAACyB,IAAI,CAAC,CAAC,EAAE;QACtDlC,QAAQ,CAAC2D,IAAI,CAAC;UAAEpD,SAAS,EAAE,IAAI;UAAEC;QAAY,CAAC,CAAC;MACjD;IACF;IAEA,OAAOR,QAAQ;EACjB;EAEA6D,SAASA,CAAC1E,IAAY,EAAW;IAC/B,OAAO,IAAI,CAAC2B,OAAO,CAACgD,GAAG,CAAC3E,IAAI,CAAC;EAC/B;EAEA,MAAM4E,aAAaA,CACjB5E,IAAY,EACZ6E,MAA8B,EACP;IACvB,MAAMnD,OAAO,GAAG,IAAI,CAACC,OAAO,CAACtB,GAAG,CAACL,IAAI,CAAC;IACtC,IAAI,CAAC0B,OAAO,EAAE;MACZZ,OAAO,CAACC,IAAI,CAAC,6BAA6Bf,IAAI,GAAG,CAAC;MAClD,OAAO;QAAE8E,OAAO,EAAE,KAAK;QAAEC,OAAO,EAAE,mBAAmB/E,IAAI;MAAG,CAAC;IAC/D;IACA,OAAO0B,OAAO,CAACmD,MAAM,CAAC;EACxB;EAEAG,oBAAoBA,CAAA,EAAa;IAC/B,OAAOnC,KAAK,CAACC,IAAI,CAAC,IAAI,CAACnB,OAAO,CAACoB,IAAI,CAAC,CAAC,CAAC;EACxC;EAEAkC,UAAUA,CAAA,EAAoB;IAC5B,OAAO;MACL7E,KAAK,EAAE,IAAI,CAACwC,WAAW,CAAC,CAAC,CAACiB,GAAG,CAAE7D,IAAI,KAAM;QACvCA,IAAI;QACJa,QAAQ,EAAE,IAAI,CAAC0D,eAAe,CAACvE,IAAI;MACrC,CAAC,CAAC,CAAC;MACHmB,QAAQ,EAAE,IAAI,CAAC6B,cAAc,CAAC,CAAC,CAACa,GAAG,CAAE5C,WAAW,KAAM;QACpDjB,IAAI,EAAEiB,WAAW;QACjBJ,QAAQ,EAAE,IAAI,CAAC4D,kBAAkB,CAACxD,WAAW;MAC/C,CAAC,CAAC,CAAC;MACHD,WAAW,EAAE,IAAI,CAAC2C,iBAAiB,CAAC;IACtC,CAAC;EACH;;EAEA;EACA;EACA;;EAEQnC,mBAAmBA,CACzBrB,IAAoB,EACpBV,MAAc,EACQ;IACtB,IAAI,CAACU,IAAI,CAAC4B,QAAQ,EAAE;MAClB5B,IAAI,CAAC4B,QAAQ,GAAG,IAAIjC,GAAG,CAAC,CAAC;IAC3B;IACA,IAAIS,UAAU,GAAGJ,IAAI,CAAC4B,QAAQ,CAAC1B,GAAG,CAACZ,MAAM,CAAC;IAC1C,IAAI,CAACc,UAAU,EAAE;MACfA,UAAU,GAAG,CAAC,CAAC;MACfJ,IAAI,CAAC4B,QAAQ,CAACzB,GAAG,CAACb,MAAM,EAAEc,UAAU,CAAC;IACvC;IACA,OAAOA,UAAU;EACnB;EAEQC,gBAAgBA,CACtBL,IAAiB,EACjBV,MAAc,EACK;IACnB,IAAI,CAACU,IAAI,CAAC4B,QAAQ,EAAE;MAClB5B,IAAI,CAAC4B,QAAQ,GAAG,IAAIjC,GAAG,CAAC,CAAC;IAC3B;IACA,IAAIS,UAAU,GAAGJ,IAAI,CAAC4B,QAAQ,CAAC1B,GAAG,CAACZ,MAAM,CAAC;IAC1C,IAAI,CAACc,UAAU,EAAE;MACfA,UAAU,GAAG,CAAC,CAAC;MACfJ,IAAI,CAAC4B,QAAQ,CAACzB,GAAG,CAACb,MAAM,EAAEc,UAAU,CAAC;IACvC;IACA,OAAOA,UAAU;EACnB;AACF","ignoreList":[]}
@@ -1,3 +1,2 @@
1
1
  export { ComponentRegistry } from './ComponentRegistry.js';
2
- export { Intent } from './Intent.js';
3
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["ComponentRegistry","Intent"],"sources":["../../../src/registry/index.ts"],"sourcesContent":["export { ComponentRegistry } from './ComponentRegistry';\nexport { Intent } from './Intent';\nexport type {\n SlotOptions,\n SectionOptions,\n SectionRegistration,\n SlotNode,\n SlotIntentNode,\n SectionIntentNode,\n SectionNode,\n SlotVariant,\n SectionVariant,\n RegistryCatalog,\n ActionResult,\n ActionHandler,\n} from './types';\n"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,qBAAqB;AACvD,SAASC,MAAM,QAAQ,UAAU","ignoreList":[]}
1
+ {"version":3,"names":["ComponentRegistry"],"sources":["../../../src/registry/index.ts"],"sourcesContent":["export { ComponentRegistry } from './ComponentRegistry';\nexport type {\n SlotOptions,\n SectionOptions,\n SectionRegistration,\n SlotNode,\n SlotIntentNode,\n SectionIntentNode,\n SectionNode,\n SlotVariant,\n SectionVariant,\n RegistryCatalog,\n ActionResult,\n ActionHandler,\n} from './types';\n"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,qBAAqB","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["../../../src/registry/types.ts"],"sourcesContent":["import type { SectionDefinition } from '../component/section-definition';\nimport type { Intent } from './Intent';\n\nexport interface SlotOptions {\n intent?: Intent | string;\n semantic?: string;\n}\n\nexport interface SectionOptions {\n intent?: Intent | string;\n semantic?: string;\n /**\n * Marks this registration as a placement variant — used when the section is\n * rendered inside a placement slot (DL #088 D3.1). Placement variants win\n * over intent / semantic variants at resolve time when `{ placement: true }`\n * is passed to `resolveSection`.\n */\n placement?: boolean;\n /**\n * Narrows a placement variant to a specific placement slot — the value of\n * `data-web5-placement=\"X\"` on the host slot (e.g. `pdpFraming`). Only\n * meaningful together with `placement: true`. At resolve time, a registration\n * with a matching `placementId` wins over the generic (id-less) placement\n * variant. Lets one section type render differently per placement slot.\n */\n placementId?: string;\n componentOptions?: Record<string, any>;\n}\n\n/**\n * Options accepted by `resolveSection` / `resolveSectionOptions` in the\n * options-object form. Mirrors `SectionOptions` minus `componentOptions`.\n */\nexport interface ResolveSectionOptions {\n intent?: Intent | string;\n semantic?: string;\n placement?: boolean;\n /** Placement slot id to match against `placementId` registrations. */\n placementId?: string;\n}\n\nexport interface SectionRegistration<C> {\n component: C;\n options?: SectionOptions;\n}\n\nexport interface SlotIntentNode<C> {\n default?: C;\n bySemantic?: Map<string, C>;\n}\n\nexport interface SlotNode<C> {\n default?: C;\n byIntent?: Map<string, SlotIntentNode<C>>;\n bySemantic?: Map<string, C>;\n}\n\nexport interface SectionIntentNode<C> {\n default?: SectionRegistration<C>;\n bySemantic?: Map<string, SectionRegistration<C>>;\n}\n\nexport interface SectionNode<C> {\n default?: SectionRegistration<C>;\n byIntent?: Map<string, SectionIntentNode<C>>;\n bySemantic?: Map<string, SectionRegistration<C>>;\n /** Generic placement-specific variant (DL #088 D3.1). One per section type. */\n forPlacement?: SectionRegistration<C>;\n /**\n * Placement variants keyed by placement slot id (the `data-web5-placement`\n * value). Resolved before `forPlacement` when a matching id is requested.\n */\n forPlacementById?: Map<string, SectionRegistration<C>>;\n}\n\nexport interface SlotVariant {\n intent?: Intent | string;\n semantic?: string;\n}\n\nexport interface SectionVariant {\n intent?: Intent | string;\n semantic?: string;\n /** True when this variant is the placement-specific one (DL #088 D3.1). */\n placement?: boolean;\n /** Set when this variant is scoped to a specific placement slot id. */\n placementId?: string;\n}\n\nexport interface RegistryCatalog {\n slots: { name: string; variants: SlotVariant[] }[];\n sections: { name: string; variants: SectionVariant[] }[];\n definitions: { sectionType: string; definition: SectionDefinition }[];\n}\n\nexport interface ActionResult {\n success: boolean;\n data?: unknown;\n message?: string;\n}\n\nexport type ActionHandler = (\n params: Record<string, string>,\n) => Promise<ActionResult> | ActionResult;\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["../../../src/registry/types.ts"],"sourcesContent":["import type { SectionDefinition } from '../component/section-definition';\n\nexport interface SlotOptions {\n intent?: string;\n semantic?: string;\n}\n\nexport interface SectionOptions {\n intent?: string;\n semantic?: string;\n /**\n * Marks this registration as a placement variant — used when the section is\n * rendered inside a placement slot (DL #088 D3.1). Placement variants win\n * over intent / semantic variants at resolve time when `{ placement: true }`\n * is passed to `resolveSection`.\n */\n placement?: boolean;\n /**\n * Narrows a placement variant to a specific placement slot — the value of\n * `data-web5-placement=\"X\"` on the host slot (e.g. `pdpFraming`). Only\n * meaningful together with `placement: true`. At resolve time, a registration\n * with a matching `placementId` wins over the generic (id-less) placement\n * variant. Lets one section type render differently per placement slot.\n */\n placementId?: string;\n componentOptions?: Record<string, any>;\n}\n\n/**\n * Options accepted by `resolveSection` / `resolveSectionOptions` in the\n * options-object form. Mirrors `SectionOptions` minus `componentOptions`.\n */\nexport interface ResolveSectionOptions {\n intent?: string;\n semantic?: string;\n placement?: boolean;\n /** Placement slot id to match against `placementId` registrations. */\n placementId?: string;\n}\n\nexport interface SectionRegistration<C> {\n component: C;\n options?: SectionOptions;\n}\n\nexport interface SlotIntentNode<C> {\n default?: C;\n bySemantic?: Map<string, C>;\n}\n\nexport interface SlotNode<C> {\n default?: C;\n byIntent?: Map<string, SlotIntentNode<C>>;\n bySemantic?: Map<string, C>;\n}\n\nexport interface SectionIntentNode<C> {\n default?: SectionRegistration<C>;\n bySemantic?: Map<string, SectionRegistration<C>>;\n}\n\nexport interface SectionNode<C> {\n default?: SectionRegistration<C>;\n byIntent?: Map<string, SectionIntentNode<C>>;\n bySemantic?: Map<string, SectionRegistration<C>>;\n /** Generic placement-specific variant (DL #088 D3.1). One per section type. */\n forPlacement?: SectionRegistration<C>;\n /**\n * Placement variants keyed by placement slot id (the `data-web5-placement`\n * value). Resolved before `forPlacement` when a matching id is requested.\n */\n forPlacementById?: Map<string, SectionRegistration<C>>;\n}\n\nexport interface SlotVariant {\n intent?: string;\n semantic?: string;\n}\n\nexport interface SectionVariant {\n intent?: string;\n semantic?: string;\n /** True when this variant is the placement-specific one (DL #088 D3.1). */\n placement?: boolean;\n /** Set when this variant is scoped to a specific placement slot id. */\n placementId?: string;\n}\n\nexport interface RegistryCatalog {\n slots: { name: string; variants: SlotVariant[] }[];\n sections: { name: string; variants: SectionVariant[] }[];\n definitions: { sectionType: string; definition: SectionDefinition }[];\n}\n\nexport interface ActionResult {\n success: boolean;\n data?: unknown;\n message?: string;\n}\n\nexport type ActionHandler = (\n params: Record<string, string>,\n) => Promise<ActionResult> | ActionResult;\n"],"mappings":"","ignoreList":[]}
@@ -378,6 +378,41 @@
378
378
  100% { background-position: 200% 0; }
379
379
  }
380
380
 
381
+ /* Section content reveal (DL #114 C) — a one-shot fade/slide-in applied the first
382
+ time a streamed section swaps from its skeleton to real content, so it appears
383
+ smoothly instead of popping in. Motion is suppressed under reduced-motion. */
384
+ @keyframes w5-section-in {
385
+ from { opacity: 0; transform: translateY(16px); }
386
+ to { opacity: 1; transform: none; }
387
+ }
388
+ .w5-section-enter {
389
+ animation: w5-section-in 360ms ease-out both;
390
+ }
391
+ @media (prefers-reduced-motion: reduce) {
392
+ .w5-section-enter {
393
+ animation: none;
394
+ }
395
+ }
396
+
397
+ /* Section skeleton entrance (DL #114 C) — when a section's skeleton first shows
398
+ up it unfolds from the top (scaleY) so it grows into place instead of popping
399
+ in at full height. Transform-based, so it doesn't shift the sections below
400
+ (their space is already reserved). Shared by every client skeleton (core
401
+ default + per-client overrides) via `w5-skeleton-expand`. Reduced-motion off. */
402
+ @keyframes w5-skeleton-expand {
403
+ from { opacity: 0; transform: scaleY(0); }
404
+ to { opacity: 1; transform: scaleY(1); }
405
+ }
406
+ .w5-skeleton-expand {
407
+ transform-origin: top center;
408
+ animation: w5-skeleton-expand 320ms ease-out both;
409
+ }
410
+ @media (prefers-reduced-motion: reduce) {
411
+ .w5-skeleton-expand {
412
+ animation: none;
413
+ }
414
+ }
415
+
381
416
  /* Global accessible focus indicator — only visible on keyboard navigation */
382
417
  :focus-visible {
383
418
  outline: 2px solid rgba(128, 0, 177, 0.5);
@@ -2,5 +2,6 @@
2
2
  @import '../components/ui/PromptEntryEmptyState.css';
3
3
  @import '../components/ui/FeedbackBar.css';
4
4
  @import '../components/ui/Disclaimer.css';
5
+ @import '../components/ui/UserQuery.css';
5
6
  @import '../components/ui/PlacementLoader.css';
6
7
  @import '../components/placement/PlacementResponseRenderer.css';
@@ -0,0 +1,100 @@
1
+ /*
2
+ * host-reset.css — re-establishes the Web5 typographic baseline inside the
3
+ * mount root.
4
+ *
5
+ * Tailwind's preflight already neutralises most of what a host theme imposes
6
+ * (margins, list markers, heading font-size/weight, link decoration), and the
7
+ * build scopes it to the root, so inside Web5 it outranks the theme. What
8
+ * preflight does NOT cover is everything it expects to inherit from `html`:
9
+ * font-family, line-height, letter-spacing, text-transform and colour. A theme
10
+ * that sets those on its rich-text wrapper — `.rte p { line-height: 1.4 }`,
11
+ * `.rte h1 { font-family: … }` — still wins there, because inheritance loses to
12
+ * any matching rule.
13
+ *
14
+ * So each of those properties is re-asserted here at element specificity. After
15
+ * scoping these become `(1,0,1)`: above a theme's `(0,1,1)` descendant rules,
16
+ * below our own `(1,1,0)` utilities. That ordering is the whole point — the
17
+ * theme is overridden, atoms still win.
18
+ *
19
+ * Wrapped in `@layer base` so Storybook (which compiles this file without the
20
+ * scoping pass) keeps the same relationship to utilities as the shipped bundle.
21
+ *
22
+ * `#root` is rewritten to the scope selector by `config/scope-css.ts`.
23
+ */
24
+
25
+ @layer base {
26
+ /*
27
+ * The baseline every descendant inherits. Without it the root inherits the
28
+ * theme's body type — 14px/1.4 on the reference store — and every element we
29
+ * do not explicitly size comes out wrong.
30
+ *
31
+ * `--w5-root-font-size` is the escape hatch for themes that rescale the root
32
+ * (`html { font-size: 62.5% }` is a common pattern): a client sets it in
33
+ * `users/<msid>/theme.css` to bring our rem-based scale back to intent.
34
+ */
35
+ #root {
36
+ font-family: var(--font-sans);
37
+ font-size: var(--w5-root-font-size, 1rem);
38
+ font-style: normal;
39
+ font-weight: 400;
40
+ line-height: 1.5;
41
+ letter-spacing: normal;
42
+ text-align: start;
43
+ text-transform: none;
44
+ color: hsl(var(--foreground));
45
+ }
46
+
47
+ /* Headings take the display face regardless of what the theme sets on its
48
+ * rich-text headings. Sizes and weights come from the Heading atom. */
49
+ :is(h1, h2, h3, h4, h5, h6) {
50
+ font-family: var(--font-display);
51
+ letter-spacing: inherit;
52
+ text-transform: none;
53
+ color: inherit;
54
+ }
55
+
56
+ /* Everything that carries body copy inherits our baseline rather than the
57
+ * theme's rich-text rules. */
58
+ :is(p, li, dd, dt, blockquote, figcaption, label, td, th, address, small) {
59
+ font-family: inherit;
60
+ font-size: inherit;
61
+ line-height: inherit;
62
+ letter-spacing: inherit;
63
+ text-transform: none;
64
+ color: inherit;
65
+ }
66
+
67
+ /* Links: preflight already inherits colour and decoration; themes also set
68
+ * the face and casing on them. */
69
+ a {
70
+ font-family: inherit;
71
+ letter-spacing: inherit;
72
+ text-transform: none;
73
+ }
74
+
75
+ /* Form controls inherit the face from preflight but not the rest, and the
76
+ * conversation input is a form control. */
77
+ :is(button, input, optgroup, select, textarea) {
78
+ letter-spacing: inherit;
79
+ text-transform: none;
80
+ }
81
+
82
+ /*
83
+ * Layout properties a host theme sets that our utilities never do.
84
+ *
85
+ * Scoping wins the properties we declare; it cannot touch the ones we don't.
86
+ * Tailwind's `grid-cols-*` sets `grid-template-columns` and nothing else, so
87
+ * a theme that also styles a class called `.grid` — Shopify's Horizon
88
+ * declares `grid-template-areas: "column-0 column-1 … column-13"` on it —
89
+ * leaks 14 named areas into our grid. The areas extend the explicit track
90
+ * list, our four `1fr` columns collapse to 0px, and every card in the row
91
+ * renders one character wide. Measured on a stock Horizon store.
92
+ *
93
+ * `grid-template-areas` is the only such leak found so far. Add to this list
94
+ * only with a reproduction: an unproven reset is a layout bug waiting to
95
+ * happen. Our own utilities are (1,1,0) and still win over these.
96
+ */
97
+ * {
98
+ grid-template-areas: none;
99
+ }
100
+ }
@@ -117,12 +117,12 @@
117
117
  --leading-body-sm: var(--body-small-text-line-height);
118
118
  --leading-callout: 36px;
119
119
 
120
- /* Placement card body copy — short framing / conversation answers.
121
- Figma 128:5257 (Web5_Proto): 20/30, medium weight body with bold
122
- leading-phrase emphasis. Used by `PlacementGeneralTextSection` (the
123
- placement variant of the fallback section). */
124
- --text-placement-body: 20px;
125
- --leading-placement-body: 30px;
120
+ /* Placement card body copy — short framing / conversation answers and the
121
+ search-overview lead block. Medium weight body with bold leading-phrase
122
+ emphasis. Used by `PlacementGeneralTextSection` (the placement variant of
123
+ the fallback section) and `SearchOverviewSection`. */
124
+ --text-placement-body: 16px;
125
+ --leading-placement-body: 24px;
126
126
  }
127
127
 
128
128
  /* Font tokens use @theme inline so utilities emit `font-family: var(--font-*)`
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Backend environment selection (debug-only).
3
+ *
4
+ * Selects which backend environment a conversation runs against: `production`
5
+ * (default) or `staging`. Resolved at request time from, in order of
6
+ * precedence: the `?backendEnv=staging|production` query param (one-shot
7
+ * override, e.g. for simulations), then
8
+ * `localStorage["web5_backend_environment"]` (the debug toggle), then the
9
+ * default `production`.
10
+ *
11
+ * When `staging` is selected the Turn RPC carries the environment to the BE via
12
+ * `additionalData.mode` (DL #110). Lives in web5-core so any surface can honor
13
+ * the same toggle.
14
+ */
15
+
16
+ export const BACKEND_ENVIRONMENT_KEY = 'web5_backend_environment';
17
+
18
+ /** Query param that forces a backend environment, overriding localStorage. */
19
+ export const BACKEND_ENVIRONMENT_QUERY_PARAM = 'backendEnv';
20
+ export const DEFAULT_BACKEND_ENVIRONMENT = 'production';
21
+ const isBackendEnvironment = value => value === 'staging' || value === 'production';
22
+
23
+ /**
24
+ * Read a backend environment override from the `?backendEnv=` query param.
25
+ * Returns `null` when the param is absent, invalid, or `window` is unavailable.
26
+ */
27
+ const getBackendEnvironmentFromQuery = () => {
28
+ try {
29
+ const value = new URLSearchParams(window.location.search).get(BACKEND_ENVIRONMENT_QUERY_PARAM);
30
+ if (isBackendEnvironment(value)) {
31
+ return value;
32
+ }
33
+ } catch {
34
+ // window / URLSearchParams unavailable (SSR, non-DOM environments).
35
+ }
36
+ return null;
37
+ };
38
+
39
+ /**
40
+ * Resolve the selected backend environment. The `?backendEnv=` query param wins
41
+ * over localStorage; both fall back to the default (`production`) when unset,
42
+ * invalid, or storage is unavailable.
43
+ */
44
+ export const getBackendEnvironment = () => {
45
+ const fromQuery = getBackendEnvironmentFromQuery();
46
+ if (fromQuery) {
47
+ return fromQuery;
48
+ }
49
+ try {
50
+ const value = localStorage.getItem(BACKEND_ENVIRONMENT_KEY);
51
+ if (isBackendEnvironment(value)) {
52
+ return value;
53
+ }
54
+ } catch {
55
+ // localStorage can throw in privacy mode / non-DOM environments.
56
+ }
57
+ return DEFAULT_BACKEND_ENVIRONMENT;
58
+ };
59
+
60
+ /** Persist the selected backend environment to localStorage. */
61
+ export const setBackendEnvironment = env => {
62
+ try {
63
+ localStorage.setItem(BACKEND_ENVIRONMENT_KEY, env);
64
+ } catch {
65
+ // Ignore — selection simply won't persist across reloads.
66
+ }
67
+ };
68
+
69
+ /** Whether the conversation should target the staging backend (default is production). */
70
+ export const usesStagingBackend = () => getBackendEnvironment() === 'staging';
71
+ //# sourceMappingURL=backendEnvironment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["BACKEND_ENVIRONMENT_KEY","BACKEND_ENVIRONMENT_QUERY_PARAM","DEFAULT_BACKEND_ENVIRONMENT","isBackendEnvironment","value","getBackendEnvironmentFromQuery","URLSearchParams","window","location","search","get","getBackendEnvironment","fromQuery","localStorage","getItem","setBackendEnvironment","env","setItem","usesStagingBackend"],"sources":["../../../src/utils/backendEnvironment.ts"],"sourcesContent":["/**\n * Backend environment selection (debug-only).\n *\n * Selects which backend environment a conversation runs against: `production`\n * (default) or `staging`. Resolved at request time from, in order of\n * precedence: the `?backendEnv=staging|production` query param (one-shot\n * override, e.g. for simulations), then\n * `localStorage[\"web5_backend_environment\"]` (the debug toggle), then the\n * default `production`.\n *\n * When `staging` is selected the Turn RPC carries the environment to the BE via\n * `additionalData.mode` (DL #110). Lives in web5-core so any surface can honor\n * the same toggle.\n */\n\nexport type BackendEnvironment = 'staging' | 'production';\n\nexport const BACKEND_ENVIRONMENT_KEY = 'web5_backend_environment';\n\n/** Query param that forces a backend environment, overriding localStorage. */\nexport const BACKEND_ENVIRONMENT_QUERY_PARAM = 'backendEnv';\n\nexport const DEFAULT_BACKEND_ENVIRONMENT: BackendEnvironment = 'production';\n\nconst isBackendEnvironment = (value: unknown): value is BackendEnvironment =>\n value === 'staging' || value === 'production';\n\n/**\n * Read a backend environment override from the `?backendEnv=` query param.\n * Returns `null` when the param is absent, invalid, or `window` is unavailable.\n */\nconst getBackendEnvironmentFromQuery = (): BackendEnvironment | null => {\n try {\n const value = new URLSearchParams(window.location.search).get(\n BACKEND_ENVIRONMENT_QUERY_PARAM,\n );\n if (isBackendEnvironment(value)) {\n return value;\n }\n } catch {\n // window / URLSearchParams unavailable (SSR, non-DOM environments).\n }\n return null;\n};\n\n/**\n * Resolve the selected backend environment. The `?backendEnv=` query param wins\n * over localStorage; both fall back to the default (`production`) when unset,\n * invalid, or storage is unavailable.\n */\nexport const getBackendEnvironment = (): BackendEnvironment => {\n const fromQuery = getBackendEnvironmentFromQuery();\n if (fromQuery) {\n return fromQuery;\n }\n try {\n const value = localStorage.getItem(BACKEND_ENVIRONMENT_KEY);\n if (isBackendEnvironment(value)) {\n return value;\n }\n } catch {\n // localStorage can throw in privacy mode / non-DOM environments.\n }\n return DEFAULT_BACKEND_ENVIRONMENT;\n};\n\n/** Persist the selected backend environment to localStorage. */\nexport const setBackendEnvironment = (env: BackendEnvironment): void => {\n try {\n localStorage.setItem(BACKEND_ENVIRONMENT_KEY, env);\n } catch {\n // Ignore — selection simply won't persist across reloads.\n }\n};\n\n/** Whether the conversation should target the staging backend (default is production). */\nexport const usesStagingBackend = (): boolean =>\n getBackendEnvironment() === 'staging';\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA,OAAO,MAAMA,uBAAuB,GAAG,0BAA0B;;AAEjE;AACA,OAAO,MAAMC,+BAA+B,GAAG,YAAY;AAE3D,OAAO,MAAMC,2BAA+C,GAAG,YAAY;AAE3E,MAAMC,oBAAoB,GAAIC,KAAc,IAC1CA,KAAK,KAAK,SAAS,IAAIA,KAAK,KAAK,YAAY;;AAE/C;AACA;AACA;AACA;AACA,MAAMC,8BAA8B,GAAGA,CAAA,KAAiC;EACtE,IAAI;IACF,MAAMD,KAAK,GAAG,IAAIE,eAAe,CAACC,MAAM,CAACC,QAAQ,CAACC,MAAM,CAAC,CAACC,GAAG,CAC3DT,+BACF,CAAC;IACD,IAAIE,oBAAoB,CAACC,KAAK,CAAC,EAAE;MAC/B,OAAOA,KAAK;IACd;EACF,CAAC,CAAC,MAAM;IACN;EAAA;EAEF,OAAO,IAAI;AACb,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMO,qBAAqB,GAAGA,CAAA,KAA0B;EAC7D,MAAMC,SAAS,GAAGP,8BAA8B,CAAC,CAAC;EAClD,IAAIO,SAAS,EAAE;IACb,OAAOA,SAAS;EAClB;EACA,IAAI;IACF,MAAMR,KAAK,GAAGS,YAAY,CAACC,OAAO,CAACd,uBAAuB,CAAC;IAC3D,IAAIG,oBAAoB,CAACC,KAAK,CAAC,EAAE;MAC/B,OAAOA,KAAK;IACd;EACF,CAAC,CAAC,MAAM;IACN;EAAA;EAEF,OAAOF,2BAA2B;AACpC,CAAC;;AAED;AACA,OAAO,MAAMa,qBAAqB,GAAIC,GAAuB,IAAW;EACtE,IAAI;IACFH,YAAY,CAACI,OAAO,CAACjB,uBAAuB,EAAEgB,GAAG,CAAC;EACpD,CAAC,CAAC,MAAM;IACN;EAAA;AAEJ,CAAC;;AAED;AACA,OAAO,MAAME,kBAAkB,GAAGA,CAAA,KAChCP,qBAAqB,CAAC,CAAC,KAAK,SAAS","ignoreList":[]}
@@ -31,6 +31,8 @@ export function parseWeb5Url(url) {
31
31
  {
32
32
  const slashIndex = path.indexOf('/');
33
33
  if (slashIndex === -1) {
34
+ // The type segment is used verbatim (the `<type>` in
35
+ // `web5://entity/<type>/<id>`); the backend sends the semantic type.
34
36
  return {
35
37
  type: Web5UrlType.ENTITY,
36
38
  path,
@@ -167,7 +169,7 @@ export function parseEntityLink(url) {
167
169
  }
168
170
  const path = url.slice('web5://entity/'.length);
169
171
 
170
- // Split by '/' to get entityType and entityId
172
+ // Split by '/' to get entityType and entityId. The type is used verbatim.
171
173
  const slashIndex = path.indexOf('/');
172
174
  if (slashIndex === -1) {
173
175
  // No slash found - only entityType, no entityId
@@ -1 +1 @@
1
- {"version":3,"names":["Web5UrlType","isWeb5EntityUrl","WEB5_TYPE_PREFIXES","Object","values","parseWeb5Url","url","startsWith","fullPath","slice","length","prefix","path","ENTITY","slashIndex","indexOf","type","entityType","entityId","ACTION","qIndex","actionName","actionParams","params","searchParams","URLSearchParams","forEach","value","key","SEARCH","searchQuery","decodeURIComponent","replace","ASK","IMAGE","ICON","isValidWeb5Url","LEGACY_PROTOCOLS","validateLinkUrl","undefined","console","log","some","p","isEntityLink","parseEntityLink","trim","extractProtocol","match","toLowerCase","extractLinkMetadata","node","metadata","protocol","parsed","web5Type"],"sources":["../../../src/utils/entityLinkParser.ts"],"sourcesContent":["import type { LinkMetadata } from '../patternValidator/types';\nimport {\n Web5UrlType,\n isWeb5EntityUrl,\n type ValidLinkUrl,\n} from '../types/link-types';\n\nexport interface Web5AskParsed {\n type: Web5UrlType.ASK;\n path: string;\n}\n\nexport interface Web5EntityParsed {\n type: Web5UrlType.ENTITY;\n path: string;\n entityType: string;\n entityId: string;\n}\n\nexport interface Web5ImageParsed {\n type: Web5UrlType.IMAGE;\n path: string;\n}\n\nexport interface Web5IconParsed {\n type: Web5UrlType.ICON;\n path: string;\n}\n\nexport interface Web5ActionParsed {\n type: Web5UrlType.ACTION;\n path: string;\n actionName: string;\n actionParams: Record<string, string>;\n}\n\nexport interface Web5SearchParsed {\n type: Web5UrlType.SEARCH;\n path: string;\n searchQuery: string;\n}\n\nexport type Web5UrlParsed =\n | Web5AskParsed\n | Web5EntityParsed\n | Web5ImageParsed\n | Web5IconParsed\n | Web5ActionParsed\n | Web5SearchParsed;\n\nconst WEB5_TYPE_PREFIXES = Object.values(Web5UrlType);\n\n/**\n * Central parser for unified web5:// URLs.\n *\n * Supported formats:\n * - `web5://ask/msg` → `{ type: Web5UrlType.ASK, path: 'msg' }`\n * - `web5://entity/solution/123` → `{ type: Web5UrlType.ENTITY, path: 'solution/123', entityType: 'solution', entityId: '123' }`\n * - `web5://image/kw` → `{ type: Web5UrlType.IMAGE, path: 'kw' }`\n * - `web5://icon/name` → `{ type: Web5UrlType.ICON, path: 'name' }`\n * - `web5://action/name?param=val` → `{ type: Web5UrlType.ACTION, path: 'name?param=val', actionName: 'name', actionParams: { param: 'val' } }`\n * - `web5://search/query` → `{ type: Web5UrlType.SEARCH, path: 'query', searchQuery: 'query' }`\n */\nexport function parseWeb5Url(url: string): Web5UrlParsed | null {\n if (!url || typeof url !== 'string') {\n return null;\n }\n\n if (!url.startsWith('web5://')) {\n return null;\n }\n\n const fullPath = url.slice('web5://'.length);\n if (!fullPath) {\n return null;\n }\n\n for (const prefix of WEB5_TYPE_PREFIXES) {\n if (fullPath === prefix || fullPath.startsWith(prefix + '/')) {\n const path = fullPath.slice(prefix.length + 1);\n\n switch (prefix) {\n case Web5UrlType.ENTITY: {\n const slashIndex = path.indexOf('/');\n if (slashIndex === -1) {\n return {\n type: Web5UrlType.ENTITY,\n path,\n entityType: path,\n entityId: '',\n };\n }\n return {\n type: Web5UrlType.ENTITY,\n path,\n entityType: path.slice(0, slashIndex),\n entityId: path.slice(slashIndex + 1),\n };\n }\n case Web5UrlType.ACTION: {\n const qIndex = path.indexOf('?');\n if (qIndex === -1) {\n return {\n type: Web5UrlType.ACTION,\n path,\n actionName: path,\n actionParams: {},\n };\n }\n const params: Record<string, string> = {};\n const searchParams = new URLSearchParams(path.slice(qIndex + 1));\n searchParams.forEach((value, key) => {\n params[key] = value;\n });\n return {\n type: Web5UrlType.ACTION,\n path,\n actionName: path.slice(0, qIndex),\n actionParams: params,\n };\n }\n case Web5UrlType.SEARCH:\n return {\n type: Web5UrlType.SEARCH,\n path,\n searchQuery: path\n ? decodeURIComponent(path.replace(/\\+/g, ' '))\n : '',\n };\n case Web5UrlType.ASK:\n return { type: Web5UrlType.ASK, path };\n case Web5UrlType.IMAGE:\n return { type: Web5UrlType.IMAGE, path };\n case Web5UrlType.ICON:\n return { type: Web5UrlType.ICON, path };\n }\n }\n }\n\n return null;\n}\n\n/**\n * Check if a URL is a valid web5:// URL with a recognized type prefix.\n */\nexport function isValidWeb5Url(url: string): boolean {\n return parseWeb5Url(url) !== null;\n}\n\n/** Known legacy protocols that are no longer supported */\nconst LEGACY_PROTOCOLS = ['entity://', 'image://', 'action://', 'ask://'];\n\n/**\n * Validate whether a URL is safe to render as a clickable link.\n *\n * - Standard protocols (http, https, mailto, relative paths) → allowed\n * - Valid `web5://` URLs (recognized type prefix) → allowed\n * - Invalid `web5://` URLs (unrecognized prefix) → rejected\n * - Legacy protocols (`entity://`, `image://`, `action://`, `ask://`) → rejected\n * - Other custom protocols → rejected\n *\n * @returns the URL as `ValidLinkUrl` if valid, or `undefined` if it should not be rendered.\n * When invalid, logs a warning for observability.\n */\nexport function validateLinkUrl(\n url: string | undefined,\n): ValidLinkUrl | undefined {\n if (!url) {\n return undefined;\n }\n\n if (\n url.startsWith('http://') ||\n url.startsWith('https://') ||\n url.startsWith('mailto:') ||\n url.startsWith('/')\n ) {\n return url as ValidLinkUrl;\n }\n\n if (url.startsWith('web5://')) {\n if (parseWeb5Url(url)) {\n return url as ValidLinkUrl;\n }\n console.log(`[web5-link] Invalid web5:// URL rejected: \"${url}\"`);\n return undefined;\n }\n\n if (LEGACY_PROTOCOLS.some((p) => url.startsWith(p))) {\n console.log(\n `[web5-link] Legacy protocol URL rejected: \"${url}\". Use web5:// format instead.`,\n );\n return undefined;\n }\n\n return undefined;\n}\n\n/**\n * Check if a URL is a web5://entity/ link\n * @param url - The URL to check\n * @returns true if the URL is an entity link\n */\nexport function isEntityLink(url: string): boolean {\n if (!url || typeof url !== 'string') {\n return false;\n }\n return isWeb5EntityUrl(url);\n}\n\n/**\n * Parse a web5://entity/ URL and extract entityType and entityId\n * Format: web5://entity/{entityType}/{entityId}\n *\n * @param url - The web5://entity/ URL to parse\n * @returns Object with entityType and entityId, or null if not a valid entity link\n *\n * @example\n * parseEntityLink('web5://entity/blog_post/abc123')\n * // Returns: { entityType: 'blog_post', entityId: 'abc123' }\n */\nexport function parseEntityLink(\n url: string,\n): { entityType: string; entityId: string } | null {\n if (!isEntityLink(url)) {\n return null;\n }\n\n const path = url.slice('web5://entity/'.length);\n\n // Split by '/' to get entityType and entityId\n const slashIndex = path.indexOf('/');\n if (slashIndex === -1) {\n // No slash found - only entityType, no entityId\n const entityType = path.trim();\n if (entityType) {\n return { entityType, entityId: '' };\n }\n return null;\n }\n\n const entityType = path.slice(0, slashIndex).trim();\n const entityId = path.slice(slashIndex + 1).trim();\n\n if (!entityType) {\n return null;\n }\n\n return { entityType, entityId };\n}\n\n/**\n * Extract protocol from a URL\n * @param url - The URL to extract protocol from\n * @returns The protocol (e.g., 'entity', 'http', 'https') or undefined\n */\nexport function extractProtocol(url: string): string | undefined {\n if (!url || typeof url !== 'string') {\n return undefined;\n }\n\n const match = url.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):\\/\\//);\n if (match) {\n return match[1].toLowerCase();\n }\n\n return undefined;\n}\n\n/**\n * Extract LinkMetadata from a link AST node\n * @param node - AST node of type 'link'\n * @returns LinkMetadata object with url, protocol, and entity fields, or null\n * when the URL is missing or whitespace-only (empty-href links are dropped\n * by the upstream pipeline; see `markdownBlocks.ts`).\n */\nexport function extractLinkMetadata(node: any): LinkMetadata | null {\n if (!node || node.type !== 'link') {\n return null;\n }\n\n const url = node.url;\n if (typeof url !== 'string' || url.trim() === '') {\n return null;\n }\n\n const metadata: LinkMetadata = {\n url,\n };\n\n // Extract protocol\n const protocol = extractProtocol(url);\n if (protocol) {\n metadata.protocol = protocol;\n }\n\n if (protocol === 'web5') {\n const parsed = parseWeb5Url(url);\n if (parsed) {\n metadata.web5Type = parsed.type;\n if (parsed.type === Web5UrlType.ENTITY) {\n metadata.entityType = parsed.entityType;\n metadata.entityId = parsed.entityId;\n }\n }\n }\n\n return metadata;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["Web5UrlType","isWeb5EntityUrl","WEB5_TYPE_PREFIXES","Object","values","parseWeb5Url","url","startsWith","fullPath","slice","length","prefix","path","ENTITY","slashIndex","indexOf","type","entityType","entityId","ACTION","qIndex","actionName","actionParams","params","searchParams","URLSearchParams","forEach","value","key","SEARCH","searchQuery","decodeURIComponent","replace","ASK","IMAGE","ICON","isValidWeb5Url","LEGACY_PROTOCOLS","validateLinkUrl","undefined","console","log","some","p","isEntityLink","parseEntityLink","trim","extractProtocol","match","toLowerCase","extractLinkMetadata","node","metadata","protocol","parsed","web5Type"],"sources":["../../../src/utils/entityLinkParser.ts"],"sourcesContent":["import type { LinkMetadata } from '../patternValidator/types';\nimport {\n Web5UrlType,\n isWeb5EntityUrl,\n type ValidLinkUrl,\n} from '../types/link-types';\n\nexport interface Web5AskParsed {\n type: Web5UrlType.ASK;\n path: string;\n}\n\nexport interface Web5EntityParsed {\n type: Web5UrlType.ENTITY;\n path: string;\n entityType: string;\n entityId: string;\n}\n\nexport interface Web5ImageParsed {\n type: Web5UrlType.IMAGE;\n path: string;\n}\n\nexport interface Web5IconParsed {\n type: Web5UrlType.ICON;\n path: string;\n}\n\nexport interface Web5ActionParsed {\n type: Web5UrlType.ACTION;\n path: string;\n actionName: string;\n actionParams: Record<string, string>;\n}\n\nexport interface Web5SearchParsed {\n type: Web5UrlType.SEARCH;\n path: string;\n searchQuery: string;\n}\n\nexport type Web5UrlParsed =\n | Web5AskParsed\n | Web5EntityParsed\n | Web5ImageParsed\n | Web5IconParsed\n | Web5ActionParsed\n | Web5SearchParsed;\n\nconst WEB5_TYPE_PREFIXES = Object.values(Web5UrlType);\n\n/**\n * Central parser for unified web5:// URLs.\n *\n * Supported formats:\n * - `web5://ask/msg` → `{ type: Web5UrlType.ASK, path: 'msg' }`\n * - `web5://entity/solution/123` → `{ type: Web5UrlType.ENTITY, path: 'solution/123', entityType: 'solution', entityId: '123' }`\n * - `web5://image/kw` → `{ type: Web5UrlType.IMAGE, path: 'kw' }`\n * - `web5://icon/name` → `{ type: Web5UrlType.ICON, path: 'name' }`\n * - `web5://action/name?param=val` → `{ type: Web5UrlType.ACTION, path: 'name?param=val', actionName: 'name', actionParams: { param: 'val' } }`\n * - `web5://search/query` → `{ type: Web5UrlType.SEARCH, path: 'query', searchQuery: 'query' }`\n */\nexport function parseWeb5Url(url: string): Web5UrlParsed | null {\n if (!url || typeof url !== 'string') {\n return null;\n }\n\n if (!url.startsWith('web5://')) {\n return null;\n }\n\n const fullPath = url.slice('web5://'.length);\n if (!fullPath) {\n return null;\n }\n\n for (const prefix of WEB5_TYPE_PREFIXES) {\n if (fullPath === prefix || fullPath.startsWith(prefix + '/')) {\n const path = fullPath.slice(prefix.length + 1);\n\n switch (prefix) {\n case Web5UrlType.ENTITY: {\n const slashIndex = path.indexOf('/');\n if (slashIndex === -1) {\n // The type segment is used verbatim (the `<type>` in\n // `web5://entity/<type>/<id>`); the backend sends the semantic type.\n return {\n type: Web5UrlType.ENTITY,\n path,\n entityType: path,\n entityId: '',\n };\n }\n return {\n type: Web5UrlType.ENTITY,\n path,\n entityType: path.slice(0, slashIndex),\n entityId: path.slice(slashIndex + 1),\n };\n }\n case Web5UrlType.ACTION: {\n const qIndex = path.indexOf('?');\n if (qIndex === -1) {\n return {\n type: Web5UrlType.ACTION,\n path,\n actionName: path,\n actionParams: {},\n };\n }\n const params: Record<string, string> = {};\n const searchParams = new URLSearchParams(path.slice(qIndex + 1));\n searchParams.forEach((value, key) => {\n params[key] = value;\n });\n return {\n type: Web5UrlType.ACTION,\n path,\n actionName: path.slice(0, qIndex),\n actionParams: params,\n };\n }\n case Web5UrlType.SEARCH:\n return {\n type: Web5UrlType.SEARCH,\n path,\n searchQuery: path\n ? decodeURIComponent(path.replace(/\\+/g, ' '))\n : '',\n };\n case Web5UrlType.ASK:\n return { type: Web5UrlType.ASK, path };\n case Web5UrlType.IMAGE:\n return { type: Web5UrlType.IMAGE, path };\n case Web5UrlType.ICON:\n return { type: Web5UrlType.ICON, path };\n }\n }\n }\n\n return null;\n}\n\n/**\n * Check if a URL is a valid web5:// URL with a recognized type prefix.\n */\nexport function isValidWeb5Url(url: string): boolean {\n return parseWeb5Url(url) !== null;\n}\n\n/** Known legacy protocols that are no longer supported */\nconst LEGACY_PROTOCOLS = ['entity://', 'image://', 'action://', 'ask://'];\n\n/**\n * Validate whether a URL is safe to render as a clickable link.\n *\n * - Standard protocols (http, https, mailto, relative paths) → allowed\n * - Valid `web5://` URLs (recognized type prefix) → allowed\n * - Invalid `web5://` URLs (unrecognized prefix) → rejected\n * - Legacy protocols (`entity://`, `image://`, `action://`, `ask://`) → rejected\n * - Other custom protocols → rejected\n *\n * @returns the URL as `ValidLinkUrl` if valid, or `undefined` if it should not be rendered.\n * When invalid, logs a warning for observability.\n */\nexport function validateLinkUrl(\n url: string | undefined,\n): ValidLinkUrl | undefined {\n if (!url) {\n return undefined;\n }\n\n if (\n url.startsWith('http://') ||\n url.startsWith('https://') ||\n url.startsWith('mailto:') ||\n url.startsWith('/')\n ) {\n return url as ValidLinkUrl;\n }\n\n if (url.startsWith('web5://')) {\n if (parseWeb5Url(url)) {\n return url as ValidLinkUrl;\n }\n console.log(`[web5-link] Invalid web5:// URL rejected: \"${url}\"`);\n return undefined;\n }\n\n if (LEGACY_PROTOCOLS.some((p) => url.startsWith(p))) {\n console.log(\n `[web5-link] Legacy protocol URL rejected: \"${url}\". Use web5:// format instead.`,\n );\n return undefined;\n }\n\n return undefined;\n}\n\n/**\n * Check if a URL is a web5://entity/ link\n * @param url - The URL to check\n * @returns true if the URL is an entity link\n */\nexport function isEntityLink(url: string): boolean {\n if (!url || typeof url !== 'string') {\n return false;\n }\n return isWeb5EntityUrl(url);\n}\n\n/**\n * Parse a web5://entity/ URL and extract entityType and entityId\n * Format: web5://entity/{entityType}/{entityId}\n *\n * @param url - The web5://entity/ URL to parse\n * @returns Object with entityType and entityId, or null if not a valid entity link\n *\n * @example\n * parseEntityLink('web5://entity/blog_post/abc123')\n * // Returns: { entityType: 'blog_post', entityId: 'abc123' }\n */\nexport function parseEntityLink(\n url: string,\n): { entityType: string; entityId: string } | null {\n if (!isEntityLink(url)) {\n return null;\n }\n\n const path = url.slice('web5://entity/'.length);\n\n // Split by '/' to get entityType and entityId. The type is used verbatim.\n const slashIndex = path.indexOf('/');\n if (slashIndex === -1) {\n // No slash found - only entityType, no entityId\n const entityType = path.trim();\n if (entityType) {\n return { entityType, entityId: '' };\n }\n return null;\n }\n\n const entityType = path.slice(0, slashIndex).trim();\n const entityId = path.slice(slashIndex + 1).trim();\n\n if (!entityType) {\n return null;\n }\n\n return { entityType, entityId };\n}\n\n/**\n * Extract protocol from a URL\n * @param url - The URL to extract protocol from\n * @returns The protocol (e.g., 'entity', 'http', 'https') or undefined\n */\nexport function extractProtocol(url: string): string | undefined {\n if (!url || typeof url !== 'string') {\n return undefined;\n }\n\n const match = url.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):\\/\\//);\n if (match) {\n return match[1].toLowerCase();\n }\n\n return undefined;\n}\n\n/**\n * Extract LinkMetadata from a link AST node\n * @param node - AST node of type 'link'\n * @returns LinkMetadata object with url, protocol, and entity fields, or null\n * when the URL is missing or whitespace-only (empty-href links are dropped\n * by the upstream pipeline; see `markdownBlocks.ts`).\n */\nexport function extractLinkMetadata(node: any): LinkMetadata | null {\n if (!node || node.type !== 'link') {\n return null;\n }\n\n const url = node.url;\n if (typeof url !== 'string' || url.trim() === '') {\n return null;\n }\n\n const metadata: LinkMetadata = {\n url,\n };\n\n // Extract protocol\n const protocol = extractProtocol(url);\n if (protocol) {\n metadata.protocol = protocol;\n }\n\n if (protocol === 'web5') {\n const parsed = parseWeb5Url(url);\n if (parsed) {\n metadata.web5Type = parsed.type;\n if (parsed.type === Web5UrlType.ENTITY) {\n metadata.entityType = parsed.entityType;\n metadata.entityId = parsed.entityId;\n }\n }\n }\n\n return metadata;\n}\n"],"mappings":"AACA,SACEA,WAAW,EACXC,eAAe,QAEV,qBAAqB;AA6C5B,MAAMC,kBAAkB,GAAGC,MAAM,CAACC,MAAM,CAACJ,WAAW,CAAC;;AAErD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASK,YAAYA,CAACC,GAAW,EAAwB;EAC9D,IAAI,CAACA,GAAG,IAAI,OAAOA,GAAG,KAAK,QAAQ,EAAE;IACnC,OAAO,IAAI;EACb;EAEA,IAAI,CAACA,GAAG,CAACC,UAAU,CAAC,SAAS,CAAC,EAAE;IAC9B,OAAO,IAAI;EACb;EAEA,MAAMC,QAAQ,GAAGF,GAAG,CAACG,KAAK,CAAC,SAAS,CAACC,MAAM,CAAC;EAC5C,IAAI,CAACF,QAAQ,EAAE;IACb,OAAO,IAAI;EACb;EAEA,KAAK,MAAMG,MAAM,IAAIT,kBAAkB,EAAE;IACvC,IAAIM,QAAQ,KAAKG,MAAM,IAAIH,QAAQ,CAACD,UAAU,CAACI,MAAM,GAAG,GAAG,CAAC,EAAE;MAC5D,MAAMC,IAAI,GAAGJ,QAAQ,CAACC,KAAK,CAACE,MAAM,CAACD,MAAM,GAAG,CAAC,CAAC;MAE9C,QAAQC,MAAM;QACZ,KAAKX,WAAW,CAACa,MAAM;UAAE;YACvB,MAAMC,UAAU,GAAGF,IAAI,CAACG,OAAO,CAAC,GAAG,CAAC;YACpC,IAAID,UAAU,KAAK,CAAC,CAAC,EAAE;cACrB;cACA;cACA,OAAO;gBACLE,IAAI,EAAEhB,WAAW,CAACa,MAAM;gBACxBD,IAAI;gBACJK,UAAU,EAAEL,IAAI;gBAChBM,QAAQ,EAAE;cACZ,CAAC;YACH;YACA,OAAO;cACLF,IAAI,EAAEhB,WAAW,CAACa,MAAM;cACxBD,IAAI;cACJK,UAAU,EAAEL,IAAI,CAACH,KAAK,CAAC,CAAC,EAAEK,UAAU,CAAC;cACrCI,QAAQ,EAAEN,IAAI,CAACH,KAAK,CAACK,UAAU,GAAG,CAAC;YACrC,CAAC;UACH;QACA,KAAKd,WAAW,CAACmB,MAAM;UAAE;YACvB,MAAMC,MAAM,GAAGR,IAAI,CAACG,OAAO,CAAC,GAAG,CAAC;YAChC,IAAIK,MAAM,KAAK,CAAC,CAAC,EAAE;cACjB,OAAO;gBACLJ,IAAI,EAAEhB,WAAW,CAACmB,MAAM;gBACxBP,IAAI;gBACJS,UAAU,EAAET,IAAI;gBAChBU,YAAY,EAAE,CAAC;cACjB,CAAC;YACH;YACA,MAAMC,MAA8B,GAAG,CAAC,CAAC;YACzC,MAAMC,YAAY,GAAG,IAAIC,eAAe,CAACb,IAAI,CAACH,KAAK,CAACW,MAAM,GAAG,CAAC,CAAC,CAAC;YAChEI,YAAY,CAACE,OAAO,CAAC,CAACC,KAAK,EAAEC,GAAG,KAAK;cACnCL,MAAM,CAACK,GAAG,CAAC,GAAGD,KAAK;YACrB,CAAC,CAAC;YACF,OAAO;cACLX,IAAI,EAAEhB,WAAW,CAACmB,MAAM;cACxBP,IAAI;cACJS,UAAU,EAAET,IAAI,CAACH,KAAK,CAAC,CAAC,EAAEW,MAAM,CAAC;cACjCE,YAAY,EAAEC;YAChB,CAAC;UACH;QACA,KAAKvB,WAAW,CAAC6B,MAAM;UACrB,OAAO;YACLb,IAAI,EAAEhB,WAAW,CAAC6B,MAAM;YACxBjB,IAAI;YACJkB,WAAW,EAAElB,IAAI,GACbmB,kBAAkB,CAACnB,IAAI,CAACoB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,GAC5C;UACN,CAAC;QACH,KAAKhC,WAAW,CAACiC,GAAG;UAClB,OAAO;YAAEjB,IAAI,EAAEhB,WAAW,CAACiC,GAAG;YAAErB;UAAK,CAAC;QACxC,KAAKZ,WAAW,CAACkC,KAAK;UACpB,OAAO;YAAElB,IAAI,EAAEhB,WAAW,CAACkC,KAAK;YAAEtB;UAAK,CAAC;QAC1C,KAAKZ,WAAW,CAACmC,IAAI;UACnB,OAAO;YAAEnB,IAAI,EAAEhB,WAAW,CAACmC,IAAI;YAAEvB;UAAK,CAAC;MAC3C;IACF;EACF;EAEA,OAAO,IAAI;AACb;;AAEA;AACA;AACA;AACA,OAAO,SAASwB,cAAcA,CAAC9B,GAAW,EAAW;EACnD,OAAOD,YAAY,CAACC,GAAG,CAAC,KAAK,IAAI;AACnC;;AAEA;AACA,MAAM+B,gBAAgB,GAAG,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,CAAC;;AAEzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAC7BhC,GAAuB,EACG;EAC1B,IAAI,CAACA,GAAG,EAAE;IACR,OAAOiC,SAAS;EAClB;EAEA,IACEjC,GAAG,CAACC,UAAU,CAAC,SAAS,CAAC,IACzBD,GAAG,CAACC,UAAU,CAAC,UAAU,CAAC,IAC1BD,GAAG,CAACC,UAAU,CAAC,SAAS,CAAC,IACzBD,GAAG,CAACC,UAAU,CAAC,GAAG,CAAC,EACnB;IACA,OAAOD,GAAG;EACZ;EAEA,IAAIA,GAAG,CAACC,UAAU,CAAC,SAAS,CAAC,EAAE;IAC7B,IAAIF,YAAY,CAACC,GAAG,CAAC,EAAE;MACrB,OAAOA,GAAG;IACZ;IACAkC,OAAO,CAACC,GAAG,CAAC,8CAA8CnC,GAAG,GAAG,CAAC;IACjE,OAAOiC,SAAS;EAClB;EAEA,IAAIF,gBAAgB,CAACK,IAAI,CAAEC,CAAC,IAAKrC,GAAG,CAACC,UAAU,CAACoC,CAAC,CAAC,CAAC,EAAE;IACnDH,OAAO,CAACC,GAAG,CACT,8CAA8CnC,GAAG,gCACnD,CAAC;IACD,OAAOiC,SAAS;EAClB;EAEA,OAAOA,SAAS;AAClB;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASK,YAAYA,CAACtC,GAAW,EAAW;EACjD,IAAI,CAACA,GAAG,IAAI,OAAOA,GAAG,KAAK,QAAQ,EAAE;IACnC,OAAO,KAAK;EACd;EACA,OAAOL,eAAe,CAACK,GAAG,CAAC;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASuC,eAAeA,CAC7BvC,GAAW,EACsC;EACjD,IAAI,CAACsC,YAAY,CAACtC,GAAG,CAAC,EAAE;IACtB,OAAO,IAAI;EACb;EAEA,MAAMM,IAAI,GAAGN,GAAG,CAACG,KAAK,CAAC,gBAAgB,CAACC,MAAM,CAAC;;EAE/C;EACA,MAAMI,UAAU,GAAGF,IAAI,CAACG,OAAO,CAAC,GAAG,CAAC;EACpC,IAAID,UAAU,KAAK,CAAC,CAAC,EAAE;IACrB;IACA,MAAMG,UAAU,GAAGL,IAAI,CAACkC,IAAI,CAAC,CAAC;IAC9B,IAAI7B,UAAU,EAAE;MACd,OAAO;QAAEA,UAAU;QAAEC,QAAQ,EAAE;MAAG,CAAC;IACrC;IACA,OAAO,IAAI;EACb;EAEA,MAAMD,UAAU,GAAGL,IAAI,CAACH,KAAK,CAAC,CAAC,EAAEK,UAAU,CAAC,CAACgC,IAAI,CAAC,CAAC;EACnD,MAAM5B,QAAQ,GAAGN,IAAI,CAACH,KAAK,CAACK,UAAU,GAAG,CAAC,CAAC,CAACgC,IAAI,CAAC,CAAC;EAElD,IAAI,CAAC7B,UAAU,EAAE;IACf,OAAO,IAAI;EACb;EAEA,OAAO;IAAEA,UAAU;IAAEC;EAAS,CAAC;AACjC;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS6B,eAAeA,CAACzC,GAAW,EAAsB;EAC/D,IAAI,CAACA,GAAG,IAAI,OAAOA,GAAG,KAAK,QAAQ,EAAE;IACnC,OAAOiC,SAAS;EAClB;EAEA,MAAMS,KAAK,GAAG1C,GAAG,CAAC0C,KAAK,CAAC,iCAAiC,CAAC;EAC1D,IAAIA,KAAK,EAAE;IACT,OAAOA,KAAK,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;EAC/B;EAEA,OAAOV,SAAS;AAClB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASW,mBAAmBA,CAACC,IAAS,EAAuB;EAClE,IAAI,CAACA,IAAI,IAAIA,IAAI,CAACnC,IAAI,KAAK,MAAM,EAAE;IACjC,OAAO,IAAI;EACb;EAEA,MAAMV,GAAG,GAAG6C,IAAI,CAAC7C,GAAG;EACpB,IAAI,OAAOA,GAAG,KAAK,QAAQ,IAAIA,GAAG,CAACwC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;IAChD,OAAO,IAAI;EACb;EAEA,MAAMM,QAAsB,GAAG;IAC7B9C;EACF,CAAC;;EAED;EACA,MAAM+C,QAAQ,GAAGN,eAAe,CAACzC,GAAG,CAAC;EACrC,IAAI+C,QAAQ,EAAE;IACZD,QAAQ,CAACC,QAAQ,GAAGA,QAAQ;EAC9B;EAEA,IAAIA,QAAQ,KAAK,MAAM,EAAE;IACvB,MAAMC,MAAM,GAAGjD,YAAY,CAACC,GAAG,CAAC;IAChC,IAAIgD,MAAM,EAAE;MACVF,QAAQ,CAACG,QAAQ,GAAGD,MAAM,CAACtC,IAAI;MAC/B,IAAIsC,MAAM,CAACtC,IAAI,KAAKhB,WAAW,CAACa,MAAM,EAAE;QACtCuC,QAAQ,CAACnC,UAAU,GAAGqC,MAAM,CAACrC,UAAU;QACvCmC,QAAQ,CAAClC,QAAQ,GAAGoC,MAAM,CAACpC,QAAQ;MACrC;IACF;EACF;EAEA,OAAOkC,QAAQ;AACjB","ignoreList":[]}