@syntrologie/runtime-sdk 0.2.21 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/CAPABILITIES.md +944 -440
  2. package/README.md +395 -66
  3. package/dist/RuntimeProvider.d.ts +51 -0
  4. package/dist/RuntimeProvider.js +113 -0
  5. package/dist/RuntimeProvider.js.map +1 -0
  6. package/dist/SmartCanvasApp.d.ts +16 -10
  7. package/dist/SmartCanvasApp.js +47 -51
  8. package/dist/SmartCanvasApp.js.map +1 -1
  9. package/dist/SmartCanvasElement.d.ts +5 -5
  10. package/dist/SmartCanvasElement.js +24 -14
  11. package/dist/SmartCanvasElement.js.map +1 -1
  12. package/dist/SmartCanvasPortal.d.ts +2 -2
  13. package/dist/SmartCanvasPortal.js +2 -2
  14. package/dist/SmartCanvasPortal.js.map +1 -1
  15. package/dist/actions/ActionEngine.d.ts +11 -0
  16. package/dist/actions/ActionEngine.js +272 -0
  17. package/dist/actions/ActionEngine.js.map +1 -0
  18. package/dist/actions/executors/index.d.ts +116 -0
  19. package/dist/actions/executors/index.js +240 -0
  20. package/dist/actions/executors/index.js.map +1 -0
  21. package/dist/actions/executors/tour.d.ts +18 -0
  22. package/dist/actions/executors/tour.js +332 -0
  23. package/dist/actions/executors/tour.js.map +1 -0
  24. package/dist/actions/index.d.ts +10 -0
  25. package/dist/actions/index.js +12 -0
  26. package/dist/actions/index.js.map +1 -0
  27. package/dist/actions/types.d.ts +399 -0
  28. package/dist/actions/types.js +8 -0
  29. package/dist/actions/types.js.map +1 -0
  30. package/dist/actions/validation.d.ts +14 -0
  31. package/dist/actions/validation.js +577 -0
  32. package/dist/actions/validation.js.map +1 -0
  33. package/dist/adaptives/adaptive-chatbot/index.js +9 -0
  34. package/dist/adaptives/adaptive-chatbot/index.js.map +7 -0
  35. package/dist/adaptives/adaptive-content/index.js +2 -0
  36. package/dist/adaptives/adaptive-content/index.js.map +7 -0
  37. package/dist/adaptives/adaptive-faq/index.js +11 -0
  38. package/dist/adaptives/adaptive-faq/index.js.map +7 -0
  39. package/dist/adaptives/adaptive-gamification/index.js +2 -0
  40. package/dist/adaptives/adaptive-gamification/index.js.map +7 -0
  41. package/dist/adaptives/adaptive-nav/index.js +11 -0
  42. package/dist/adaptives/adaptive-nav/index.js.map +7 -0
  43. package/dist/adaptives/adaptive-overlays/index.js +91 -0
  44. package/dist/adaptives/adaptive-overlays/index.js.map +7 -0
  45. package/dist/antiFlicker.js +1 -1
  46. package/dist/api.d.ts +40 -26
  47. package/dist/api.js +87 -60
  48. package/dist/api.js.map +1 -1
  49. package/dist/apps/AppContext.d.ts +31 -0
  50. package/dist/apps/AppContext.js +91 -0
  51. package/dist/apps/AppContext.js.map +1 -0
  52. package/dist/apps/AppLoader.d.ts +85 -0
  53. package/dist/apps/AppLoader.js +282 -0
  54. package/dist/apps/AppLoader.js.map +1 -0
  55. package/dist/apps/AppRegistry.d.ts +102 -0
  56. package/dist/apps/AppRegistry.js +317 -0
  57. package/dist/apps/AppRegistry.js.map +1 -0
  58. package/dist/apps/examples/gamification-app.example.d.ts +305 -0
  59. package/dist/apps/examples/gamification-app.example.js +329 -0
  60. package/dist/apps/examples/gamification-app.example.js.map +1 -0
  61. package/dist/apps/index.d.ts +14 -0
  62. package/dist/apps/index.js +16 -0
  63. package/dist/apps/index.js.map +1 -0
  64. package/dist/apps/types.d.ts +231 -0
  65. package/dist/apps/types.js +8 -0
  66. package/dist/apps/types.js.map +1 -0
  67. package/dist/blocks/data/ComparisonBlock.d.ts +1 -1
  68. package/dist/blocks/data/ComparisonBlock.js +40 -40
  69. package/dist/blocks/data/ComparisonBlock.js.map +1 -1
  70. package/dist/blocks/data/StatsBlock.d.ts +1 -1
  71. package/dist/blocks/data/StatsBlock.js +42 -44
  72. package/dist/blocks/data/StatsBlock.js.map +1 -1
  73. package/dist/blocks/data/index.d.ts +2 -2
  74. package/dist/blocks/data/index.js +2 -2
  75. package/dist/blocks/index.d.ts +5 -5
  76. package/dist/blocks/index.js +29 -30
  77. package/dist/blocks/index.js.map +1 -1
  78. package/dist/blocks/interactive/ChecklistBlock.d.ts +1 -1
  79. package/dist/blocks/interactive/ChecklistBlock.js +60 -60
  80. package/dist/blocks/interactive/ChecklistBlock.js.map +1 -1
  81. package/dist/blocks/interactive/RatingBlock.d.ts +1 -1
  82. package/dist/blocks/interactive/RatingBlock.js +73 -65
  83. package/dist/blocks/interactive/RatingBlock.js.map +1 -1
  84. package/dist/blocks/interactive/index.d.ts +2 -2
  85. package/dist/blocks/interactive/index.js +2 -2
  86. package/dist/blocks/notification/NotificationBlock.d.ts +2 -2
  87. package/dist/blocks/notification/NotificationBlock.js +68 -64
  88. package/dist/blocks/notification/NotificationBlock.js.map +1 -1
  89. package/dist/blocks/notification/index.d.ts +1 -1
  90. package/dist/blocks/notification/index.js +1 -1
  91. package/dist/bootstrap.d.ts +32 -8
  92. package/dist/bootstrap.js +218 -102
  93. package/dist/bootstrap.js.map +1 -1
  94. package/dist/components/ShadowCanvasOverlay.d.ts +6 -6
  95. package/dist/components/ShadowCanvasOverlay.js +156 -118
  96. package/dist/components/ShadowCanvasOverlay.js.map +1 -1
  97. package/dist/components/TileCard.d.ts +5 -5
  98. package/dist/components/TileCard.js +205 -154
  99. package/dist/components/TileCard.js.map +1 -1
  100. package/dist/components/TileWheel.d.ts +3 -3
  101. package/dist/components/TileWheel.js +29 -7
  102. package/dist/components/TileWheel.js.map +1 -1
  103. package/dist/config-validator.d.ts +49 -0
  104. package/dist/config-validator.js +173 -0
  105. package/dist/config-validator.js.map +1 -0
  106. package/dist/configFetcher.d.ts +7 -3
  107. package/dist/configFetcher.js +70 -29
  108. package/dist/configFetcher.js.map +1 -1
  109. package/dist/context/ContextManager.d.ts +3 -3
  110. package/dist/context/ContextManager.js +19 -18
  111. package/dist/context/ContextManager.js.map +1 -1
  112. package/dist/context/index.d.ts +4 -4
  113. package/dist/context/index.js +3 -3
  114. package/dist/context/schema.d.ts +9 -9
  115. package/dist/context/schema.js +2 -2
  116. package/dist/context/schema.js.map +1 -1
  117. package/dist/decisions/engine.d.ts +5 -5
  118. package/dist/decisions/engine.js +13 -13
  119. package/dist/decisions/engine.js.map +1 -1
  120. package/dist/decisions/index.d.ts +6 -6
  121. package/dist/decisions/index.js +5 -5
  122. package/dist/decisions/schema.d.ts +131 -131
  123. package/dist/decisions/schema.js +21 -21
  124. package/dist/decisions/schema.js.map +1 -1
  125. package/dist/decisions/strategies/rules.d.ts +1 -1
  126. package/dist/decisions/strategies/rules.js +24 -24
  127. package/dist/decisions/strategies/rules.js.map +1 -1
  128. package/dist/decisions/strategies/score.d.ts +1 -1
  129. package/dist/decisions/strategies/score.js +3 -3
  130. package/dist/decisions/types.d.ts +19 -19
  131. package/dist/earlyPatcher.d.ts +8 -20
  132. package/dist/earlyPatcher.js +13 -62
  133. package/dist/earlyPatcher.js.map +1 -1
  134. package/dist/editorLoader.d.ts +19 -7
  135. package/dist/editorLoader.js +154 -97
  136. package/dist/editorLoader.js.map +1 -1
  137. package/dist/events/EventBus.d.ts +3 -3
  138. package/dist/events/EventBus.js +5 -7
  139. package/dist/events/EventBus.js.map +1 -1
  140. package/dist/events/index.d.ts +6 -6
  141. package/dist/events/index.js +5 -5
  142. package/dist/events/normalizers/canvas.d.ts +2 -2
  143. package/dist/events/normalizers/canvas.js +3 -3
  144. package/dist/events/normalizers/canvas.js.map +1 -1
  145. package/dist/events/normalizers/posthog.d.ts +25 -1
  146. package/dist/events/normalizers/posthog.js +35 -27
  147. package/dist/events/normalizers/posthog.js.map +1 -1
  148. package/dist/events/schema.d.ts +13 -13
  149. package/dist/events/schema.js +3 -3
  150. package/dist/events/schema.js.map +1 -1
  151. package/dist/events/types.d.ts +7 -1
  152. package/dist/events/types.js +29 -21
  153. package/dist/events/types.js.map +1 -1
  154. package/dist/experiments/adapters/growthbook.d.ts +5 -4
  155. package/dist/experiments/adapters/growthbook.js +14 -6
  156. package/dist/experiments/adapters/growthbook.js.map +1 -1
  157. package/dist/experiments/index.d.ts +3 -3
  158. package/dist/experiments/index.js +1 -1
  159. package/dist/experiments/registry.d.ts +2 -2
  160. package/dist/experiments/registry.js +2 -2
  161. package/dist/experiments/types.d.ts +10 -1
  162. package/dist/fetchers/cdnFetcher.d.ts +1 -1
  163. package/dist/fetchers/cdnFetcher.js +4 -8
  164. package/dist/fetchers/cdnFetcher.js.map +1 -1
  165. package/dist/fetchers/experimentsFetcher.d.ts +25 -3
  166. package/dist/fetchers/experimentsFetcher.js +55 -8
  167. package/dist/fetchers/experimentsFetcher.js.map +1 -1
  168. package/dist/fetchers/index.d.ts +3 -3
  169. package/dist/fetchers/index.js +2 -2
  170. package/dist/fetchers/index.js.map +1 -1
  171. package/dist/fetchers/mergeConfigs.d.ts +29 -0
  172. package/dist/fetchers/mergeConfigs.js +38 -0
  173. package/dist/fetchers/mergeConfigs.js.map +1 -0
  174. package/dist/fetchers/registry.d.ts +1 -1
  175. package/dist/fetchers/registry.js +4 -4
  176. package/dist/fetchers/types.d.ts +1 -1
  177. package/dist/hooks/useCanvasOverlays.d.ts +8 -5
  178. package/dist/hooks/useCanvasOverlays.js +66 -17
  179. package/dist/hooks/useCanvasOverlays.js.map +1 -1
  180. package/dist/hooks/useHostPatches.d.ts +2 -2
  181. package/dist/hooks/useHostPatches.js +8 -8
  182. package/dist/hooks/useHostPatches.js.map +1 -1
  183. package/dist/hooks/useShadowCanvasConfig.d.ts +5 -9
  184. package/dist/hooks/useShadowCanvasConfig.js +7 -5
  185. package/dist/hooks/useShadowCanvasConfig.js.map +1 -1
  186. package/dist/hostPatcher/core/patcher.d.ts +1 -1
  187. package/dist/hostPatcher/core/patcher.js +18 -9
  188. package/dist/hostPatcher/core/patcher.js.map +1 -1
  189. package/dist/hostPatcher/core/sanitizer.js +24 -3
  190. package/dist/hostPatcher/core/sanitizer.js.map +1 -1
  191. package/dist/hostPatcher/policy/defaultPolicy.js +15 -5
  192. package/dist/hostPatcher/policy/defaultPolicy.js.map +1 -1
  193. package/dist/hostPatcher/utils/anchors.js +4 -6
  194. package/dist/hostPatcher/utils/anchors.js.map +1 -1
  195. package/dist/index.d.ts +34 -27
  196. package/dist/index.js +51 -24
  197. package/dist/index.js.map +1 -1
  198. package/dist/logger.d.ts +29 -0
  199. package/dist/logger.js +81 -0
  200. package/dist/logger.js.map +1 -0
  201. package/dist/metrics/index.d.ts +1 -1
  202. package/dist/metrics/index.js +1 -1
  203. package/dist/metrics/sessionMetrics.d.ts +1 -1
  204. package/dist/metrics/sessionMetrics.js +6 -6
  205. package/dist/overlays/fetcher.d.ts +2 -2
  206. package/dist/overlays/fetcher.js +13 -15
  207. package/dist/overlays/fetcher.js.map +1 -1
  208. package/dist/overlays/recipeRegistry.js +2 -2
  209. package/dist/overlays/recipeRegistry.js.map +1 -1
  210. package/dist/overlays/runtime/anchor/resolve.js +1 -1
  211. package/dist/overlays/runtime/anchor/resolve.js.map +1 -1
  212. package/dist/overlays/runtime/index.d.ts +7 -7
  213. package/dist/overlays/runtime/index.js +7 -7
  214. package/dist/overlays/runtime/overlay/highlight.js +39 -39
  215. package/dist/overlays/runtime/overlay/highlight.js.map +1 -1
  216. package/dist/overlays/runtime/overlay/modal.js +5 -5
  217. package/dist/overlays/runtime/overlay/modal.js.map +1 -1
  218. package/dist/overlays/runtime/overlay/root.js +1 -1
  219. package/dist/overlays/runtime/overlay/runner.js +88 -28
  220. package/dist/overlays/runtime/overlay/runner.js.map +1 -1
  221. package/dist/overlays/runtime/overlay/tooltip.d.ts +1 -1
  222. package/dist/overlays/runtime/overlay/tooltip.js +13 -15
  223. package/dist/overlays/runtime/overlay/tooltip.js.map +1 -1
  224. package/dist/overlays/runtime/utils/dom.js +4 -1
  225. package/dist/overlays/runtime/utils/dom.js.map +1 -1
  226. package/dist/overlays/schema.d.ts +146 -146
  227. package/dist/overlays/schema.js +12 -8
  228. package/dist/overlays/schema.js.map +1 -1
  229. package/dist/react.d.ts +7 -7
  230. package/dist/react.js +4 -4
  231. package/dist/react.js.map +1 -1
  232. package/dist/render/RenderContext.d.ts +2 -2
  233. package/dist/render/RenderContext.js +5 -5
  234. package/dist/render/RenderContext.js.map +1 -1
  235. package/dist/render/index.d.ts +3 -3
  236. package/dist/render/index.js +1 -1
  237. package/dist/render/types.d.ts +4 -4
  238. package/dist/runtime.d.ts +32 -8
  239. package/dist/runtime.js +109 -13
  240. package/dist/runtime.js.map +1 -1
  241. package/dist/smart-canvas.esm.js +144 -55
  242. package/dist/smart-canvas.esm.js.map +4 -4
  243. package/dist/smart-canvas.js +14688 -11455
  244. package/dist/smart-canvas.js.map +4 -4
  245. package/dist/smart-canvas.min.js +145 -55
  246. package/dist/smart-canvas.min.js.map +4 -4
  247. package/dist/state/StateStore.d.ts +1 -7
  248. package/dist/state/StateStore.js +15 -9
  249. package/dist/state/StateStore.js.map +1 -1
  250. package/dist/state/helpers/cooldowns.d.ts +1 -1
  251. package/dist/state/helpers/cooldowns.js +1 -1
  252. package/dist/state/helpers/dismissals.d.ts +1 -1
  253. package/dist/state/helpers/dismissals.js +1 -1
  254. package/dist/state/helpers/frequency.d.ts +1 -1
  255. package/dist/state/helpers/frequency.js +1 -1
  256. package/dist/state/index.d.ts +4 -4
  257. package/dist/state/index.js +3 -3
  258. package/dist/state/schema.d.ts +1 -1
  259. package/dist/state/schema.js +1 -1
  260. package/dist/store/example.d.ts +1 -0
  261. package/dist/store/example.js +43 -0
  262. package/dist/store/example.js.map +1 -0
  263. package/dist/store/mini-effector.d.ts +46 -0
  264. package/dist/store/mini-effector.js +88 -0
  265. package/dist/store/mini-effector.js.map +1 -0
  266. package/dist/surfaces/Surfaces.d.ts +11 -0
  267. package/dist/surfaces/Surfaces.js +361 -0
  268. package/dist/surfaces/Surfaces.js.map +1 -0
  269. package/dist/surfaces/index.d.ts +9 -0
  270. package/dist/surfaces/index.js +12 -0
  271. package/dist/surfaces/index.js.map +1 -0
  272. package/dist/surfaces/positioning.d.ts +50 -0
  273. package/dist/surfaces/positioning.js +228 -0
  274. package/dist/surfaces/positioning.js.map +1 -0
  275. package/dist/surfaces/types.d.ts +167 -0
  276. package/dist/surfaces/types.js +23 -0
  277. package/dist/surfaces/types.js.map +1 -0
  278. package/dist/telemetry/adapters/noop.d.ts +12 -0
  279. package/dist/telemetry/adapters/noop.js +42 -0
  280. package/dist/telemetry/adapters/noop.js.map +1 -0
  281. package/dist/telemetry/adapters/posthog.d.ts +8 -2
  282. package/dist/telemetry/adapters/posthog.js +36 -14
  283. package/dist/telemetry/adapters/posthog.js.map +1 -1
  284. package/dist/telemetry/index.d.ts +4 -3
  285. package/dist/telemetry/index.js +3 -2
  286. package/dist/telemetry/index.js.map +1 -1
  287. package/dist/telemetry/registry.d.ts +2 -9
  288. package/dist/telemetry/registry.js +4 -2
  289. package/dist/telemetry/registry.js.map +1 -1
  290. package/dist/telemetry/types.d.ts +1 -1
  291. package/dist/theme/ThemeProvider.d.ts +2 -2
  292. package/dist/theme/ThemeProvider.js +21 -21
  293. package/dist/theme/ThemeProvider.js.map +1 -1
  294. package/dist/theme/defaultTheme.d.ts +4 -5
  295. package/dist/theme/defaultTheme.js +127 -118
  296. package/dist/theme/defaultTheme.js.map +1 -1
  297. package/dist/theme/extractHostTheme.d.ts +1 -1
  298. package/dist/theme/extractHostTheme.js +43 -45
  299. package/dist/theme/extractHostTheme.js.map +1 -1
  300. package/dist/theme/index.d.ts +5 -5
  301. package/dist/theme/index.js +3 -3
  302. package/dist/theme/index.js.map +1 -1
  303. package/dist/theme/types.d.ts +2 -2
  304. package/dist/token.d.ts +2 -0
  305. package/dist/token.js +3 -6
  306. package/dist/token.js.map +1 -1
  307. package/dist/types-only.d.ts +32 -0
  308. package/dist/types-only.js +11 -0
  309. package/dist/types-only.js.map +1 -0
  310. package/dist/types.d.ts +89 -56
  311. package/dist/types.js +14 -2
  312. package/dist/types.js.map +1 -1
  313. package/dist/version.d.ts +13 -0
  314. package/dist/version.js +14 -0
  315. package/dist/version.js.map +1 -0
  316. package/dist/widgets/WidgetRegistry.d.ts +145 -0
  317. package/dist/widgets/WidgetRegistry.js +191 -0
  318. package/dist/widgets/WidgetRegistry.js.map +1 -0
  319. package/dist/widgets/index.d.ts +7 -0
  320. package/dist/widgets/index.js +7 -0
  321. package/dist/widgets/index.js.map +1 -0
  322. package/package.json +35 -15
  323. package/schema/canvas-config.schema.json +488 -254
  324. package/schema/runtime-context.schema.json +1 -5
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["shared-react:react", "../../../../adaptives/adaptive-faq/src/summarize.ts", "../../../../adaptives/adaptive-faq/src/types.ts", "shared-react:react/jsx-runtime", "../../../../adaptives/adaptive-faq/src/editor.tsx", "../../../../adaptives/adaptive-faq/src/executors.ts", "shared-react:react-dom/client", "../../../../adaptives/adaptive-faq/src/FAQWidget.tsx", "../../../../adaptives/adaptive-faq/src/runtime.ts", "../../../../adaptives/adaptive-faq/src/cdn.ts"],
4
+ "sourcesContent": ["\n var R = globalThis.__SYNTRO_REACT__ || {};\n export default R;\n export var useState = R.useState;\n export var useEffect = R.useEffect;\n export var useMemo = R.useMemo;\n export var useCallback = R.useCallback;\n export var useRef = R.useRef;\n export var useContext = R.useContext;\n export var useReducer = R.useReducer;\n export var createElement = R.createElement;\n export var createContext = R.createContext;\n export var Fragment = R.Fragment;\n export var forwardRef = R.forwardRef;\n export var memo = R.memo;\n export var lazy = R.lazy;\n export var Suspense = R.Suspense;\n export var Children = R.Children;\n export var isValidElement = R.isValidElement;\n export var cloneElement = R.cloneElement;\n export var Component = R.Component;\n export var PureComponent = R.PureComponent;\n export var useLayoutEffect = R.useLayoutEffect;\n export var useId = R.useId;\n ", "/**\n * Human-readable summary generation for FAQ items.\n * Pure functions \u2014 no DOM access, just string formatting.\n */\n\nimport type { FAQQuestionAction, FAQAnswer, DecisionStrategy, RuleStrategy } from './types';\n\nconst MAX_Q_LEN = 50;\nconst MAX_A_LEN = 40;\n\nfunction truncate(text: string, max: number): string {\n if (text.length <= max) return text;\n return `${text.slice(0, max).trimEnd()}...`;\n}\n\nfunction stripHtml(html: string): string {\n return html.replace(/<[^>]*>/g, '').trim();\n}\n\nfunction getAnswerPreview(answer: FAQAnswer): string {\n if (typeof answer === 'string') return answer;\n if (answer.type === 'rich') return stripHtml(answer.html);\n return answer.content.replace(/[*_#`]/g, '').trim();\n}\n\nfunction isRuleStrategy(s: unknown): s is RuleStrategy<boolean> {\n return (\n typeof s === 'object' &&\n s !== null &&\n (s as Record<string, unknown>).type === 'rules' &&\n Array.isArray((s as Record<string, unknown>).rules)\n );\n}\n\n/**\n * Parse a showWhen strategy into a human-readable trigger description.\n */\nexport function describeTrigger(showWhen?: DecisionStrategy<boolean> | null): string {\n if (!showWhen) return 'All pages';\n if (!isRuleStrategy(showWhen)) return 'All pages';\n\n const pages: string[] = [];\n const anchors: string[] = [];\n\n for (const rule of showWhen.rules) {\n for (const condition of rule.conditions) {\n if (condition.type === 'page_url' && typeof (condition as any).url === 'string') {\n pages.push((condition as any).url);\n }\n if (condition.type === 'anchor_visible' && typeof (condition as any).anchorId === 'string') {\n anchors.push((condition as any).anchorId);\n }\n }\n }\n\n const parts: string[] = [];\n if (pages.length > 0) parts.push(pages[0]);\n if (anchors.length > 0) parts.push(anchors[0]);\n\n return parts.length > 0 ? parts.join(' \\u00b7 ') : 'All pages';\n}\n\n/**\n * Generate a one-liner summary for an FAQ item.\n */\nexport function summarizeFAQItem(item: FAQQuestionAction): string {\n const q = truncate(item.config.question, MAX_Q_LEN);\n const a = truncate(getAnswerPreview(item.config.answer), MAX_A_LEN);\n return `Q: \"${q}\" \\u2014 ${a}`;\n}\n", "/**\n * Adaptive FAQ - Types\n *\n * Type definitions for the FAQ accordion adaptive.\n * Demonstrates compositional action pattern with per-item showWhen.\n */\n\n// ============================================================================\n// Decision Strategy Types (from runtime-sdk)\n// ============================================================================\n\n/**\n * Simplified DecisionStrategy type for this package.\n * Full definition is in @syntrologie/runtime-sdk.\n */\nexport type DecisionStrategy<T = unknown> =\n | RuleStrategy<T>\n | ScoreStrategy<T>\n | ModelStrategy<T>\n | ExternalStrategy<T>;\n\nexport interface RuleStrategy<T = unknown> {\n type: 'rules';\n rules: Array<{\n conditions: Array<Record<string, unknown>>;\n value: T;\n }>;\n default: T;\n}\n\nexport interface ScoreStrategy<T = unknown> {\n type: 'score';\n field: string;\n threshold: number;\n above: T;\n below: T;\n}\n\nexport interface ModelStrategy<T = unknown> {\n type: 'model';\n modelId: string;\n inputs: string[];\n outputMapping: Record<string, T>;\n default: T;\n}\n\nexport interface ExternalStrategy<T = unknown> {\n type: 'external';\n endpoint: string;\n method?: 'GET' | 'POST';\n default: T;\n timeoutMs?: number;\n}\n\n// ============================================================================\n// Rich Answer Content Types\n// ============================================================================\n\nexport interface Asset {\n id: string;\n type: 'image' | 'video';\n src: string;\n alt?: string;\n width?: number;\n height?: number;\n}\n\nexport interface RichHTMLAnswer {\n type: 'rich';\n html: string;\n}\n\nexport interface EnhancedMarkdownAnswer {\n type: 'markdown';\n content: string;\n assets?: Asset[];\n}\n\nexport type FAQAnswer = string | RichHTMLAnswer | EnhancedMarkdownAnswer;\n\n// ============================================================================\n// AI Answer Types\n// ============================================================================\n\nexport interface AnswerStrategy {\n endpoint: string;\n context?: string[];\n cache?: 'session' | 'none';\n fallback?: string;\n}\n\n// ============================================================================\n// Feedback Types\n// ============================================================================\n\nexport interface FeedbackConfig {\n style: 'thumbs' | 'rating';\n prompt?: string;\n}\n\nexport type FeedbackValue = 'up' | 'down' | number;\n\n// ============================================================================\n// Ordering Types\n// ============================================================================\n\nexport interface SegmentOrdering {\n type: 'segment';\n segmentWeights: Record<string, string[]>;\n}\n\nexport type OrderingStrategy = 'static' | 'priority' | SegmentOrdering;\n\n// ============================================================================\n// Injection Types\n// ============================================================================\n\nexport interface InjectionRule {\n trigger: DecisionStrategy<boolean>;\n items: FAQQuestionAction[];\n position?: 'prepend' | 'append';\n once?: boolean;\n}\n\n// ============================================================================\n// FAQ Question Action Types\n// ============================================================================\n\nexport interface FAQQuestionAction {\n kind: 'faq:question';\n config: {\n id: string;\n question: string;\n answer: FAQAnswer;\n category?: string;\n priority?: number;\n answerStrategy?: AnswerStrategy;\n };\n showWhen?: DecisionStrategy<boolean> | null;\n rationale?: {\n why: string;\n confidence?: number;\n };\n}\n\n// ============================================================================\n// FAQ Widget Configuration\n// ============================================================================\n\nexport type ExpandBehavior = 'single' | 'multiple';\n\nexport type FAQTheme = 'light' | 'dark' | 'auto';\n\nexport interface FAQConfig {\n expandBehavior: ExpandBehavior;\n searchable: boolean;\n theme: FAQTheme;\n actions: FAQQuestionAction[];\n feedback?: boolean | FeedbackConfig;\n ordering?: OrderingStrategy;\n injections?: InjectionRule[];\n}\n\n// ============================================================================\n// FAQ Action Types (for executor pattern)\n// ============================================================================\n\nexport interface ScrollToFaqAction {\n kind: 'faq:scroll_to';\n itemId?: string;\n itemQuestion?: string;\n expand?: boolean;\n behavior?: 'smooth' | 'instant' | 'auto';\n}\n\nexport interface ToggleFaqItemAction {\n kind: 'faq:toggle_item';\n itemId?: string;\n itemQuestion?: string;\n state?: 'open' | 'closed' | 'toggle';\n}\n\nexport interface UpdateFaqAction {\n kind: 'faq:update';\n operation: 'add' | 'remove' | 'reorder' | 'replace';\n items?: FAQQuestionAction[];\n itemId?: string;\n order?: string[];\n position?: 'prepend' | 'append' | 'before' | 'after';\n anchorId?: string;\n}\n\n// ============================================================================\n// Widget State Types\n// ============================================================================\n\nexport interface FAQWidgetState {\n expandedItems: Set<string>;\n items: FAQQuestionAction[];\n searchQuery: string;\n collapsedCategories: Set<string>;\n feedbackState: Map<string, FeedbackValue>;\n}\n\n// ============================================================================\n// Executor Infrastructure Types\n// ============================================================================\n\nexport type ExecutorCleanup = () => void;\n\nexport type ExecutorUpdate = (action: unknown) => Promise<void>;\n\nexport interface ExecutorResult {\n cleanup: ExecutorCleanup;\n updateFn?: ExecutorUpdate;\n}\n\nexport interface ExecutorContext {\n overlayRoot: HTMLElement;\n resolveAnchor: (anchorId: string) => HTMLElement | null;\n generateId: () => string;\n publishEvent: (name: string, props?: Record<string, unknown>) => void;\n adaptiveId?: string;\n}\n\nexport type ActionExecutor<T> = (action: T, context: ExecutorContext) => Promise<ExecutorResult>;\n\n// ============================================================================\n// Action Namespace\n// ============================================================================\n\nexport const ACTION_NAMESPACE = 'faq';\n\n/**\n * Returns true if the action belongs to this adaptive package.\n * Uses prefix matching so new kinds (e.g. faq:category) are automatically included.\n */\nexport function isOwnAction(action: { kind: string }): boolean {\n return action.kind.startsWith(`${ACTION_NAMESPACE}:`);\n}\n\n// ============================================================================\n// Editor Types\n// ============================================================================\n\nexport interface EditorPanelProps {\n config: Record<string, unknown>;\n onChange: (config: Record<string, unknown>) => void;\n editor: {\n setDirty: (dirty: boolean) => void;\n navigateHome: () => Promise<boolean>;\n save: () => Promise<void>;\n publish: (captureScreenshot?: boolean) => Promise<void>;\n navigateTo: (route: string) => Promise<void>;\n highlightElement: (selector: string) => void;\n clearHighlight: () => void;\n getCurrentRoute: () => string;\n previewConfig: (config: Record<string, unknown>) => void;\n /** Flat action index to open in edit mode (from accordion navigation). */\n initialEditKey?: string;\n /** Open the editor in create mode. */\n initialCreate?: boolean;\n /** Clear the initial navigation state (call after consuming). */\n clearInitialState?: () => void;\n };\n platformClient?: unknown;\n}\n", "\n function _getR() { return globalThis.__SYNTRO_REACT__; }\n function _jsx(type, props, key) {\n var R = _getR();\n var p = props || {};\n var c = p.children;\n delete p.children;\n if (key !== undefined) p.key = key;\n return Array.isArray(c)\n ? R.createElement.apply(null, [type, p].concat(c))\n : c !== undefined\n ? R.createElement(type, p, c)\n : R.createElement(type, p);\n }\n export var jsx = _jsx;\n export var jsxs = _jsx;\n export var Fragment = (_getR() || {}).Fragment;\n ", "/**\n * Adaptive FAQ - Editor Component\n *\n * Review & tweak editor for AI-generated FAQ question decisions.\n * Displays a scannable list of Q&A cards with trigger, rationale,\n * and inline editing. Includes detection badges and hover-to-highlight.\n */\n\nimport React, { useState, useCallback, useEffect, useRef } from 'react';\n\nimport { summarizeFAQItem, describeTrigger } from './summarize';\nimport {\n isOwnAction,\n type FAQConfig,\n type FAQQuestionAction,\n type FAQAnswer,\n type EditorPanelProps,\n type RuleStrategy,\n} from './types';\n\n// ============================================================================\n// Targeting Extraction (inlined \u2014 CDN builds can't import from editor-sdk)\n// ============================================================================\n\ninterface TargetingInfo {\n pagePatterns: string[];\n anchorSelectors: string[];\n hasTargeting: boolean;\n}\n\nfunction isRuleStrategy(s: unknown): s is RuleStrategy<boolean> {\n return (\n typeof s === 'object' &&\n s !== null &&\n (s as Record<string, unknown>).type === 'rules' &&\n Array.isArray((s as Record<string, unknown>).rules)\n );\n}\n\nfunction extractTargetingInfo(showWhen?: unknown | null): TargetingInfo {\n if (!showWhen || !isRuleStrategy(showWhen)) {\n return { pagePatterns: [], anchorSelectors: [], hasTargeting: false };\n }\n\n const pagePatterns = new Set<string>();\n const anchorSelectors = new Set<string>();\n\n for (const rule of showWhen.rules) {\n for (const cond of rule.conditions) {\n const c = cond as Record<string, unknown>;\n if (c.type === 'page_url' && typeof c.url === 'string') {\n pagePatterns.add(c.url);\n } else if (c.type === 'anchor_visible' && typeof c.anchorId === 'string') {\n anchorSelectors.add(c.anchorId);\n }\n }\n }\n\n const hasTargeting = pagePatterns.size > 0 || anchorSelectors.size > 0;\n return {\n pagePatterns: [...pagePatterns],\n anchorSelectors: [...anchorSelectors],\n hasTargeting,\n };\n}\n\nfunction extractFirstPage(showWhen?: unknown | null): string | null {\n const info = extractTargetingInfo(showWhen);\n return info.pagePatterns[0] || null;\n}\n\nfunction extractFirstAnchor(showWhen?: unknown | null): string | null {\n const info = extractTargetingInfo(showWhen);\n return info.anchorSelectors[0] || null;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction getAnswerText(answer: FAQAnswer): string {\n if (typeof answer === 'string') return answer;\n if (answer.type === 'rich') return answer.html;\n return answer.content;\n}\n\ninterface FlatItem {\n key: string;\n index: number;\n summary: string;\n trigger: string;\n rationale?: { why: string; confidence?: number };\n firstAnchor: string | null;\n question: FAQQuestionAction;\n}\n\nfunction flattenItems(config: FAQConfig): FlatItem[] {\n const actions = (config.actions || []).filter(isOwnAction);\n return actions.map((q, i) => ({\n key: String(i),\n index: i,\n summary: summarizeFAQItem(q),\n trigger: describeTrigger(q.showWhen),\n rationale: q.rationale,\n firstAnchor: extractFirstAnchor(q.showWhen),\n question: q,\n }));\n}\n\nfunction filterConfig(config: FAQConfig, dismissedKeys: Set<string>): FAQConfig {\n const ownActions = (config.actions || []).filter(isOwnAction);\n return {\n ...config,\n actions: ownActions.filter((_, i) => !dismissedKeys.has(String(i))),\n };\n}\n\n// ============================================================================\n// Detection Hook\n// ============================================================================\n\ninterface DetectionEntry {\n found: boolean;\n element: HTMLElement | null;\n}\n\nfunction useDetection(\n items: FlatItem[],\n getCurrentRoute: () => string\n): Map<string, DetectionEntry> {\n const [detectionMap, setDetectionMap] = useState<Map<string, DetectionEntry>>(new Map());\n const itemsRef = useRef(items);\n itemsRef.current = items;\n\n useEffect(() => {\n const runDetection = () => {\n const map = new Map<string, DetectionEntry>();\n const currentPath = getCurrentRoute();\n\n for (const item of itemsRef.current) {\n const targeting = extractTargetingInfo(item.question.showWhen);\n\n // Check page match\n let pageMatch = true;\n if (targeting.pagePatterns.length > 0) {\n pageMatch = targeting.pagePatterns.some((pattern) => {\n const regex = new RegExp(\n `^${pattern.replace(/\\*\\*/g, '.*').replace(/(?<!\\.)(\\*)/g, '[^/]*')}$`\n );\n return regex.test(currentPath);\n });\n }\n\n // Check anchor presence\n let anchorFound = false;\n let element: HTMLElement | null = null;\n if (item.firstAnchor) {\n try {\n element = document.querySelector(item.firstAnchor) as HTMLElement | null;\n anchorFound = element !== null;\n } catch {\n // Invalid selector\n }\n } else {\n // No anchor to check \u2014 if page matches, consider found\n anchorFound = pageMatch;\n }\n\n map.set(item.key, {\n found: pageMatch && anchorFound,\n element,\n });\n }\n\n setDetectionMap(map);\n };\n\n runDetection();\n\n const interval = setInterval(runDetection, 2000);\n window.addEventListener('popstate', runDetection);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener('popstate', runDetection);\n };\n }, [getCurrentRoute]);\n\n return detectionMap;\n}\n\n// ============================================================================\n// Detection Badge\n// ============================================================================\n\nfunction DetectionBadge({ found }: { found: boolean }) {\n return (\n <span\n style={{\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: found ? '#22c55e' : '#475569',\n flexShrink: 0,\n display: 'inline-block',\n }}\n title={found ? 'Found on this page' : 'Not found on this page'}\n />\n );\n}\n\n// ============================================================================\n// Styles\n// ============================================================================\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column' as const,\n height: '100%',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n },\n header: {\n padding: '16px',\n borderBottom: '1px solid #334155',\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n },\n backButton: {\n padding: '6px 12px',\n borderRadius: '6px',\n border: 'none',\n backgroundColor: 'rgba(255,255,255,0.05)',\n color: '#94a3b8',\n fontSize: '13px',\n cursor: 'pointer',\n },\n title: {\n margin: 0,\n fontSize: '15px',\n fontWeight: 600,\n color: '#f8fafc',\n },\n subtitle: {\n margin: '2px 0 0 0',\n fontSize: '11px',\n color: '#64748b',\n },\n body: {\n flex: 1,\n overflow: 'auto',\n padding: '16px',\n },\n groupHeader: {\n fontSize: '11px',\n fontWeight: 700,\n color: '#64748b',\n textTransform: 'uppercase' as const,\n letterSpacing: '0.06em',\n padding: '4px 0 8px 0',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n },\n groupCount: {\n fontSize: '10px',\n color: '#475569',\n backgroundColor: 'rgba(255,255,255,0.06)',\n padding: '2px 6px',\n borderRadius: '8px',\n },\n card: {\n padding: '8px 10px',\n borderRadius: '6px',\n border: '1px solid rgba(255,255,255,0.06)',\n background: 'rgba(255,255,255,0.02)',\n marginBottom: '4px',\n fontSize: '13px',\n color: '#e2e8f0',\n },\n triggerLine: {\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n fontSize: '11px',\n color: '#94a3b8',\n cursor: 'pointer',\n marginBottom: '4px',\n },\n cardBody: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n cursor: 'pointer',\n },\n cardText: {\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap' as const,\n },\n rationaleLine: {\n fontSize: '10px',\n color: '#64748b',\n marginTop: '4px',\n },\n dismissButton: {\n padding: '2px 6px',\n borderRadius: '4px',\n border: 'none',\n background: 'transparent',\n color: '#64748b',\n fontSize: '14px',\n cursor: 'pointer',\n flexShrink: 0,\n lineHeight: 1,\n },\n dismissedSection: {\n marginTop: '16px',\n cursor: 'pointer',\n userSelect: 'none' as const,\n },\n dismissedHeader: {\n fontSize: '11px',\n fontWeight: 600,\n color: '#475569',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n },\n dismissedCard: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '6px 10px',\n borderRadius: '6px',\n border: '1px solid rgba(255,255,255,0.03)',\n background: 'transparent',\n marginBottom: '3px',\n cursor: 'pointer',\n fontSize: '12px',\n color: '#475569',\n opacity: 0.6,\n },\n emptyState: {\n textAlign: 'center' as const,\n padding: '32px 16px',\n color: '#64748b',\n fontSize: '13px',\n },\n footer: {\n padding: '12px 16px',\n borderTop: '1px solid #334155',\n display: 'flex',\n gap: '8px',\n },\n saveButton: {\n flex: 1,\n padding: '10px',\n borderRadius: '8px',\n border: 'none',\n background: 'rgba(59, 130, 246, 0.15)',\n color: '#3b82f6',\n fontSize: '13px',\n fontWeight: 600,\n cursor: 'pointer',\n },\n publishButton: {\n flex: 1,\n padding: '10px',\n borderRadius: '8px',\n border: 'none',\n background: '#22c55e',\n color: 'white',\n fontSize: '13px',\n fontWeight: 600,\n cursor: 'pointer',\n },\n // Edit form styles\n editForm: {\n padding: '4px 0',\n },\n editHeader: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n marginBottom: '12px',\n fontSize: '13px',\n fontWeight: 600,\n color: '#e2e8f0',\n },\n editLabel: {\n fontSize: '11px',\n fontWeight: 600,\n color: '#64748b',\n marginBottom: '4px',\n display: 'block',\n },\n editInput: {\n width: '100%',\n padding: '6px 8px',\n borderRadius: '4px',\n border: '1px solid rgba(255,255,255,0.1)',\n background: 'rgba(255,255,255,0.04)',\n color: '#e2e8f0',\n fontSize: '12px',\n fontFamily: 'inherit',\n marginBottom: '8px',\n boxSizing: 'border-box' as const,\n },\n editTextarea: {\n width: '100%',\n padding: '6px 8px',\n borderRadius: '4px',\n border: '1px solid rgba(255,255,255,0.1)',\n background: 'rgba(255,255,255,0.04)',\n color: '#e2e8f0',\n fontSize: '12px',\n fontFamily: 'inherit',\n marginBottom: '8px',\n resize: 'vertical' as const,\n minHeight: '60px',\n boxSizing: 'border-box' as const,\n },\n editRationale: {\n padding: '8px',\n borderRadius: '4px',\n border: '1px dashed rgba(255,255,255,0.15)',\n background: 'rgba(255,255,255,0.02)',\n color: '#94a3b8',\n fontSize: '12px',\n marginBottom: '8px',\n },\n editBackButton: {\n padding: '6px 12px',\n borderRadius: '6px',\n border: '1px solid rgba(255,255,255,0.1)',\n background: 'transparent',\n color: '#94a3b8',\n fontSize: '12px',\n cursor: 'pointer',\n marginTop: '8px',\n },\n};\n\n// ============================================================================\n// FAQEditor Component\n// ============================================================================\n\nexport function FAQEditor({ config, onChange, editor }: EditorPanelProps) {\n const typedConfig = config as unknown as FAQConfig;\n const [dismissedKeys, setDismissedKeys] = useState<Set<string>>(new Set());\n const [dismissedOpen, setDismissedOpen] = useState(false);\n const [editingKey, setEditingKey] = useState<string | null>(null);\n const [previewMode, setPreviewMode] = useState<'before' | 'after'>('after');\n const [_hoveredKey, setHoveredKey] = useState<string | null>(null);\n\n // Consume initial navigation payload on mount (FAQ is a widget mount \u2014\n // initialEditKey points to the mount action, no sub-item to pre-select)\n const initialConsumed = useRef(false);\n useEffect(() => {\n if (!initialConsumed.current && (editor.initialEditKey != null || editor.initialCreate)) {\n initialConsumed.current = true;\n editor.clearInitialState?.();\n }\n }, [editor]);\n\n const allItems = flattenItems(typedConfig);\n const activeItems = allItems.filter((item) => !dismissedKeys.has(item.key));\n const dismissedItems = allItems.filter((item) => dismissedKeys.has(item.key));\n const totalQuestions = activeItems.length;\n\n const detectionMap = useDetection(allItems, editor.getCurrentRoute);\n const foundCount = activeItems.filter((item) => detectionMap.get(item.key)?.found).length;\n\n const handleDismiss = useCallback(\n (key: string) => {\n setDismissedKeys((prev) => {\n const next = new Set(prev);\n next.add(key);\n return next;\n });\n if (editingKey === key) setEditingKey(null);\n },\n [editingKey]\n );\n\n const handleRestore = useCallback((key: string) => {\n setDismissedKeys((prev) => {\n const next = new Set(prev);\n next.delete(key);\n return next;\n });\n }, []);\n\n const handleCardBodyClick = useCallback((item: FlatItem) => {\n setEditingKey(item.key);\n }, []);\n\n const handleTriggerClick = useCallback(\n (item: FlatItem) => {\n const pageUrl = extractFirstPage(item.question.showWhen);\n if (pageUrl) {\n editor.navigateTo(pageUrl);\n }\n if (item.firstAnchor) {\n editor.highlightElement(item.firstAnchor);\n }\n },\n [editor]\n );\n\n const handleBackToList = useCallback(() => {\n setEditingKey(null);\n setPreviewMode('after');\n editor.previewConfig(config);\n editor.clearHighlight();\n }, [editor, config]);\n\n const handleBeforeAfter = useCallback(\n (mode: 'before' | 'after') => {\n setPreviewMode(mode);\n if (mode === 'before') {\n const filtered = filterConfig(typedConfig, new Set([editingKey!]));\n editor.previewConfig(filtered as unknown as Record<string, unknown>);\n } else {\n editor.previewConfig(config);\n }\n },\n [typedConfig, editingKey, editor, config]\n );\n\n const handleFieldChange = useCallback(\n (index: number, field: string, value: unknown) => {\n const ownActions = (typedConfig.actions || []).filter(isOwnAction).slice();\n const q = { ...ownActions[index], config: { ...ownActions[index].config } };\n (q.config as Record<string, unknown>)[field] = value;\n ownActions[index] = q;\n const otherActions = (typedConfig.actions || []).filter((a) => !isOwnAction(a));\n const updated = { ...typedConfig, actions: [...otherActions, ...ownActions] };\n onChange(updated as unknown as Record<string, unknown>);\n editor.setDirty(true);\n },\n [typedConfig, onChange, editor]\n );\n\n const handlePublish = useCallback(() => {\n if (dismissedKeys.size > 0) {\n const filtered = filterConfig(typedConfig, dismissedKeys);\n onChange(filtered as unknown as Record<string, unknown>);\n }\n editor.publish();\n }, [dismissedKeys, typedConfig, onChange, editor]);\n\n const handleCardHover = useCallback(\n (item: FlatItem) => {\n setHoveredKey(item.key);\n if (item.firstAnchor) {\n editor.highlightElement(item.firstAnchor);\n }\n },\n [editor]\n );\n\n const handleCardLeave = useCallback(() => {\n setHoveredKey(null);\n editor.clearHighlight();\n }, [editor]);\n\n // ---- Edit form renderer ----\n\n const renderEditFields = (index: number) => {\n const actions = (typedConfig.actions || []).filter(isOwnAction);\n const q = actions[index];\n if (!q) return null;\n\n const item = allItems.find((it) => it.key === String(index));\n\n return (\n <div style={styles.editForm}>\n {/* Trigger line in edit mode */}\n {item && item.trigger !== 'All pages' && (\n <div data-trigger style={styles.triggerLine} onClick={() => handleTriggerClick(item)}>\n <span>{'\\u{1f4cd}'}</span>\n <span>{item.trigger}</span>\n </div>\n )}\n\n <label style={styles.editLabel}>Question</label>\n <input\n style={styles.editInput}\n value={q.config.question}\n onChange={(e) => handleFieldChange(index, 'question', e.target.value)}\n />\n\n <label style={styles.editLabel}>Answer</label>\n <textarea\n style={styles.editTextarea}\n value={getAnswerText(q.config.answer)}\n onChange={(e) => handleFieldChange(index, 'answer', e.target.value)}\n />\n\n <label style={styles.editLabel}>Category</label>\n <input\n style={styles.editInput}\n value={q.config.category || ''}\n onChange={(e) => handleFieldChange(index, 'category', e.target.value || undefined)}\n placeholder=\"e.g., Billing, Account\"\n />\n\n <label style={styles.editLabel}>AI Rationale</label>\n <div style={styles.editRationale}>{q.rationale ? q.rationale.why : 'N/A'}</div>\n </div>\n );\n };\n\n return (\n <div style={styles.container}>\n {/* Header */}\n <div style={styles.header}>\n <button onClick={() => editor.navigateHome()} style={styles.backButton}>\n &larr; Back\n </button>\n <div>\n <h2 style={styles.title}>Review Questions</h2>\n <p style={styles.subtitle}>\n {totalQuestions} question{totalQuestions !== 1 ? 's' : ''}\n {totalQuestions > 0 && ` (${foundCount} found on this page)`}\n </p>\n </div>\n </div>\n\n {/* Body */}\n <div style={styles.body}>\n {editingKey !== null ? (\n /* ---- Edit mode ---- */\n (() => {\n const editIndex = Number(editingKey);\n const editItem = allItems.find((it) => it.key === editingKey);\n return (\n <>\n <div style={styles.editHeader}>\n <span>{'\\u2753'}</span>\n <span>{editItem?.summary}</span>\n </div>\n <div\n style={{\n display: 'flex',\n gap: '0',\n marginBottom: '12px',\n borderRadius: '6px',\n overflow: 'hidden',\n border: '1px solid rgba(255,255,255,0.1)',\n }}\n >\n <button\n onClick={() => handleBeforeAfter('before')}\n style={{\n flex: 1,\n padding: '6px 12px',\n border: 'none',\n fontSize: '12px',\n fontWeight: 600,\n cursor: 'pointer',\n background: previewMode === 'before' ? 'rgba(59,130,246,0.2)' : 'transparent',\n color: previewMode === 'before' ? '#3b82f6' : '#64748b',\n }}\n >\n Before\n </button>\n <button\n onClick={() => handleBeforeAfter('after')}\n style={{\n flex: 1,\n padding: '6px 12px',\n border: 'none',\n borderLeft: '1px solid rgba(255,255,255,0.1)',\n fontSize: '12px',\n fontWeight: 600,\n cursor: 'pointer',\n background: previewMode === 'after' ? 'rgba(59,130,246,0.2)' : 'transparent',\n color: previewMode === 'after' ? '#3b82f6' : '#64748b',\n }}\n >\n After\n </button>\n </div>\n {renderEditFields(editIndex)}\n <button style={styles.editBackButton} onClick={handleBackToList}>\n &larr; List\n </button>\n </>\n );\n })()\n ) : (\n /* ---- List mode ---- */\n <>\n {allItems.length === 0 && (\n <div style={styles.emptyState}>No FAQ questions configured.</div>\n )}\n\n {activeItems.length > 0 && (\n <>\n <div style={styles.groupHeader}>\n <span>FAQ</span>\n <span style={styles.groupCount}>{activeItems.length}</span>\n </div>\n {activeItems.map((item) => {\n const detection = detectionMap.get(item.key);\n return (\n <div\n key={item.key}\n style={styles.card}\n data-item-key={item.key}\n onMouseEnter={() => handleCardHover(item)}\n onMouseLeave={handleCardLeave}\n >\n {/* Trigger line */}\n {item.trigger !== 'All pages' && (\n <div\n data-trigger\n style={styles.triggerLine}\n onClick={(e) => {\n e.stopPropagation();\n handleTriggerClick(item);\n }}\n >\n <span>{'\\u{1f4cd}'}</span>\n <span>{item.trigger}</span>\n </div>\n )}\n {/* Card body: badge + summary + dismiss */}\n <div\n data-card-body\n style={styles.cardBody}\n onClick={() => handleCardBodyClick(item)}\n >\n <DetectionBadge found={detection?.found ?? false} />\n <span style={styles.cardText}>{item.summary}</span>\n <button\n style={styles.dismissButton}\n onClick={(e) => {\n e.stopPropagation();\n handleDismiss(item.key);\n }}\n title=\"Dismiss this question\"\n >\n &times;\n </button>\n </div>\n {/* Rationale line */}\n <div style={styles.rationaleLine}>\n WHY: {item.rationale ? item.rationale.why : 'N/A'}\n </div>\n </div>\n );\n })}\n </>\n )}\n\n {/* Dismissed section */}\n {dismissedItems.length > 0 && (\n <div style={styles.dismissedSection}>\n <div\n style={{ ...styles.dismissedHeader, cursor: 'pointer' }}\n onClick={() => setDismissedOpen(!dismissedOpen)}\n >\n <span>{dismissedOpen ? '\\u25be' : '\\u25b8'}</span>\n <span>Dismissed ({dismissedItems.length})</span>\n </div>\n {dismissedOpen && (\n <div style={{ marginTop: '6px' }}>\n {dismissedItems.map((item) => (\n <div key={item.key} style={styles.dismissedCard}>\n <span style={{ ...styles.cardText, textDecoration: 'line-through' }}>\n {item.summary}\n </span>\n <button\n style={{\n ...styles.dismissButton,\n color: '#3b82f6',\n fontSize: '11px',\n }}\n onClick={(e) => {\n e.stopPropagation();\n handleRestore(item.key);\n }}\n >\n Restore\n </button>\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </>\n )}\n </div>\n\n {/* Footer */}\n <div style={styles.footer}>\n <button onClick={() => editor.save()} style={styles.saveButton}>\n Save Draft\n </button>\n <button onClick={handlePublish} style={styles.publishButton}>\n Publish\n </button>\n </div>\n </div>\n );\n}\n\n/**\n * Editor panel configuration for the app registry.\n */\nexport const editorPanel = {\n title: 'FAQ',\n icon: '\\u2753',\n description: 'FAQ accordion with per-item visibility',\n};\n\nexport const editor = {\n panel: editorPanel,\n component: FAQEditor,\n};\n\nexport default FAQEditor;\n", "/**\n * Adaptive FAQ - Action Executors\n *\n * Three executors that operate on the FAQStore:\n * - executeScrollToFaq: scroll to a FAQ item and optionally expand it\n * - executeToggleFaqItem: open / close / toggle a FAQ item\n * - executeUpdateFaq: add, remove, reorder, or replace FAQ items\n */\n\nimport type { FAQStore } from './state';\nimport type {\n ScrollToFaqAction,\n ToggleFaqItemAction,\n UpdateFaqAction,\n ExecutorResult,\n ExecutorContext,\n FAQQuestionAction,\n} from './types';\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Resolve a FAQ item by direct ID or by fuzzy question text match.\n * Throws if neither yields a result.\n */\nfunction resolveItem(store: FAQStore, itemId?: string, itemQuestion?: string): FAQQuestionAction {\n if (itemId) {\n const found = store.getState().items.find((i) => i.config.id === itemId);\n if (found) return found;\n }\n\n if (itemQuestion) {\n const found = store.findByQuestion(itemQuestion);\n if (found) return found;\n }\n\n throw new Error('FAQ item not found');\n}\n\n// ============================================================================\n// executeScrollToFaq\n// ============================================================================\n\n/**\n * Scroll to a FAQ item in the DOM and optionally expand it.\n *\n * Looks up the item by `itemId` or `itemQuestion`, scrolls the matching\n * `[data-faq-item-id]` element into view, and expands it unless\n * `expand` is explicitly set to `false`.\n */\nexport async function executeScrollToFaq(\n action: ScrollToFaqAction,\n context: ExecutorContext,\n store: FAQStore\n): Promise<ExecutorResult> {\n const item = resolveItem(store, action.itemId, action.itemQuestion);\n const { id } = item.config;\n\n // Expand the item unless explicitly told not to\n if (action.expand !== false) {\n store.expand(id);\n }\n\n // Scroll the DOM element into view (may be absent in test environments)\n const el = document.querySelector(`[data-faq-item-id=\"${id}\"]`);\n if (el) {\n el.scrollIntoView({\n behavior: action.behavior ?? 'smooth',\n });\n }\n\n // Publish analytics event\n context.publishEvent('faq:scroll_to', { itemId: id });\n\n return {\n cleanup: () => {\n // Optionally collapse on revert\n },\n };\n}\n\n// ============================================================================\n// executeToggleFaqItem\n// ============================================================================\n\n/**\n * Open, close, or toggle a FAQ item's expanded state.\n */\nexport async function executeToggleFaqItem(\n action: ToggleFaqItemAction,\n context: ExecutorContext,\n store: FAQStore\n): Promise<ExecutorResult> {\n const item = resolveItem(store, action.itemId, action.itemQuestion);\n const { id } = item.config;\n const desiredState = action.state ?? 'toggle';\n\n let newState: 'open' | 'closed';\n\n switch (desiredState) {\n case 'open':\n store.expand(id);\n newState = 'open';\n break;\n case 'closed':\n store.collapse(id);\n newState = 'closed';\n break;\n case 'toggle':\n default: {\n const wasExpanded = store.getState().expandedItems.has(id);\n store.toggle(id);\n newState = wasExpanded ? 'closed' : 'open';\n break;\n }\n }\n\n context.publishEvent('faq:toggle', { itemId: id, newState });\n\n return {\n cleanup: () => {\n // Revert toggle on cleanup\n },\n };\n}\n\n// ============================================================================\n// executeUpdateFaq\n// ============================================================================\n\n/**\n * Add, remove, reorder, or replace FAQ items in the store.\n */\nexport async function executeUpdateFaq(\n action: UpdateFaqAction,\n context: ExecutorContext,\n store: FAQStore\n): Promise<ExecutorResult> {\n switch (action.operation) {\n case 'add': {\n const items = action.items ?? [];\n const position = action.position === 'prepend' ? 'prepend' : 'append';\n store.addItems(items, position);\n break;\n }\n\n case 'remove': {\n if (!action.itemId) {\n throw new Error('FAQ item not found');\n }\n // Verify the item exists before removing\n const exists = store.getState().items.some((i) => i.config.id === action.itemId);\n if (!exists) {\n throw new Error('FAQ item not found');\n }\n store.removeItem(action.itemId);\n break;\n }\n\n case 'reorder': {\n const order = action.order ?? [];\n store.reorderItems(order);\n break;\n }\n\n case 'replace': {\n const items = action.items ?? [];\n store.replaceItems(items);\n break;\n }\n }\n\n context.publishEvent('faq:update', { operation: action.operation });\n\n return {\n cleanup: () => {\n // Could snapshot previous state for undo\n },\n };\n}\n\n// ============================================================================\n// Executor Definitions for Registration\n// ============================================================================\n\n/**\n * All executors provided by adaptive-faq.\n * These are registered with the runtime's ExecutorRegistry.\n */\nexport const executorDefinitions = [\n { kind: 'faq:scroll_to', executor: executeScrollToFaq },\n { kind: 'faq:toggle_item', executor: executeToggleFaqItem },\n { kind: 'faq:update', executor: executeUpdateFaq },\n] as const;\n", "\n var RD = globalThis.__SYNTRO_REACT_DOM__;\n export default RD;\n export var createRoot = RD?.createRoot;\n export var createPortal = RD?.createPortal;\n ", "/**\n * Adaptive FAQ - FAQWidget Component\n *\n * React component that renders a collapsible Q&A accordion with per-item\n * conditional visibility based on showWhen decision strategies.\n *\n * Demonstrates the compositional action pattern where child actions\n * (faq:question) serve as configuration data for the parent widget.\n */\n\nimport React, { useEffect, useReducer, useMemo, useCallback, useState } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport type {\n FAQQuestionAction,\n FAQConfig,\n FAQAnswer,\n FeedbackConfig,\n FeedbackValue,\n DecisionStrategy,\n} from './types';\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Extract plain text from an FAQAnswer for search matching */\nfunction getAnswerText(answer: FAQAnswer): string {\n if (typeof answer === 'string') return answer;\n if (answer.type === 'rich') return answer.html;\n return answer.content;\n}\n\n/** Render an FAQAnswer based on its type */\nfunction renderAnswer(answer: FAQAnswer): React.ReactNode {\n if (typeof answer === 'string') {\n return <p style={{ margin: 0 }}>{answer}</p>;\n }\n if (answer.type === 'rich') {\n return <div style={{ margin: 0 }} dangerouslySetInnerHTML={{ __html: answer.html }} />;\n }\n // markdown \u2014 render content as text (full markdown rendering is a future enhancement)\n return <p style={{ margin: 0 }}>{answer.content}</p>;\n}\n\n/** Resolve feedback config into a normalized FeedbackConfig or null */\nfunction resolveFeedbackConfig(\n feedback: boolean | FeedbackConfig | undefined\n): FeedbackConfig | null {\n if (!feedback) return null;\n if (feedback === true) {\n return { style: 'thumbs' };\n }\n return feedback;\n}\n\n/** Get the feedback prompt text */\nfunction getFeedbackPrompt(feedbackConfig: FeedbackConfig): string {\n return feedbackConfig.prompt || 'Was this helpful?';\n}\n\n// Widget runtime and props types defined inline (not part of the types.ts spec)\nexport interface FAQWidgetRuntime {\n evaluateSync: <T>(strategy: DecisionStrategy<T>) => { value: T; isFallback: boolean };\n context: { subscribe: (callback: () => void) => () => void };\n events: { publish: (name: string, props?: Record<string, unknown>) => void };\n state?: { get: (key: string) => unknown; set: (key: string, value: unknown) => void };\n}\n\ninterface FAQWidgetProps {\n config: FAQConfig;\n runtime: FAQWidgetRuntime;\n instanceId: string;\n}\n\n// ============================================================================\n// Styles\n// ============================================================================\n\nconst baseStyles = {\n container: {\n fontFamily: 'system-ui, -apple-system, sans-serif',\n maxWidth: '800px',\n margin: '0 auto',\n },\n searchWrapper: {\n marginBottom: '16px',\n },\n searchInput: {\n width: '100%',\n padding: '12px 16px',\n borderRadius: '8px',\n fontSize: '14px',\n outline: 'none',\n transition: 'border-color 0.15s ease',\n },\n accordion: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '8px',\n },\n item: {\n borderRadius: '8px',\n overflow: 'hidden',\n transition: 'box-shadow 0.15s ease',\n },\n question: {\n width: '100%',\n padding: '16px 20px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n border: 'none',\n cursor: 'pointer',\n fontSize: '15px',\n fontWeight: 500,\n textAlign: 'left' as const,\n transition: 'background-color 0.15s ease',\n },\n chevron: {\n fontSize: '18px',\n transition: 'transform 0.2s ease',\n },\n answer: {\n padding: '0 20px 16px 20px',\n fontSize: '14px',\n lineHeight: 1.6,\n overflow: 'hidden',\n transition: 'max-height 0.2s ease, padding 0.2s ease',\n },\n category: {\n display: 'inline-block',\n fontSize: '11px',\n fontWeight: 600,\n textTransform: 'uppercase' as const,\n letterSpacing: '0.05em',\n padding: '4px 8px',\n borderRadius: '4px',\n marginBottom: '8px',\n },\n categoryHeader: {\n fontSize: '13px',\n fontWeight: 700,\n textTransform: 'uppercase' as const,\n letterSpacing: '0.05em',\n padding: '12px 4px 6px 4px',\n marginTop: '8px',\n },\n feedback: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n marginTop: '12px',\n paddingTop: '10px',\n borderTop: '1px solid rgba(0, 0, 0, 0.08)',\n fontSize: '13px',\n },\n feedbackButton: {\n background: 'none',\n border: '1px solid transparent',\n cursor: 'pointer',\n fontSize: '16px',\n padding: '4px 8px',\n borderRadius: '4px',\n transition: 'background-color 0.15s ease, border-color 0.15s ease',\n },\n feedbackButtonSelected: {\n borderColor: 'rgba(0, 0, 0, 0.2)',\n backgroundColor: 'rgba(0, 0, 0, 0.04)',\n },\n emptyState: {\n textAlign: 'center' as const,\n padding: '48px 24px',\n fontSize: '14px',\n },\n noResults: {\n textAlign: 'center' as const,\n padding: '32px 16px',\n fontSize: '14px',\n },\n} as const;\n\nconst themeStyles = {\n light: {\n container: {\n backgroundColor: '#ffffff',\n color: '#111827',\n },\n searchInput: {\n backgroundColor: '#f9fafb',\n border: '1px solid #e5e7eb',\n color: '#111827',\n },\n item: {\n backgroundColor: '#f9fafb',\n border: '1px solid #e5e7eb',\n },\n itemExpanded: {\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08)',\n },\n question: {\n backgroundColor: 'transparent',\n color: '#111827',\n },\n questionHover: {\n backgroundColor: '#f3f4f6',\n },\n answer: {\n color: '#4b5563',\n },\n category: {\n backgroundColor: '#e0e7ff',\n color: '#4338ca',\n },\n categoryHeader: {\n color: '#6b7280',\n },\n emptyState: {\n color: '#9ca3af',\n },\n feedbackPrompt: {\n color: '#6b7280',\n },\n },\n dark: {\n container: {\n backgroundColor: '#111827',\n color: '#f9fafb',\n },\n searchInput: {\n backgroundColor: '#1f2937',\n border: '1px solid #374151',\n color: '#f9fafb',\n },\n item: {\n backgroundColor: '#1f2937',\n border: '1px solid #374151',\n },\n itemExpanded: {\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)',\n },\n question: {\n backgroundColor: 'transparent',\n color: '#f9fafb',\n },\n questionHover: {\n backgroundColor: '#374151',\n },\n answer: {\n color: '#9ca3af',\n },\n category: {\n backgroundColor: '#312e81',\n color: '#a5b4fc',\n },\n categoryHeader: {\n color: '#9ca3af',\n },\n emptyState: {\n color: '#6b7280',\n },\n feedbackPrompt: {\n color: '#9ca3af',\n },\n },\n} as const;\n\n// ============================================================================\n// FAQItem Component\n// ============================================================================\n\ninterface FAQItemProps {\n item: FAQQuestionAction;\n isExpanded: boolean;\n onToggle: () => void;\n theme: 'light' | 'dark';\n feedbackConfig: FeedbackConfig | null;\n feedbackValue: FeedbackValue | undefined;\n onFeedback: (itemId: string, question: string, value: FeedbackValue) => void;\n}\n\nfunction FAQItem({\n item,\n isExpanded,\n onToggle,\n theme,\n feedbackConfig,\n feedbackValue,\n onFeedback,\n}: FAQItemProps) {\n const [isHovered, setIsHovered] = useState(false);\n const colors = themeStyles[theme];\n const { question, answer } = item.config;\n\n const itemStyle: React.CSSProperties = {\n ...baseStyles.item,\n ...colors.item,\n ...(isExpanded ? colors.itemExpanded : {}),\n };\n\n const questionStyle: React.CSSProperties = {\n ...baseStyles.question,\n ...colors.question,\n ...(isHovered ? colors.questionHover : {}),\n };\n\n const chevronStyle: React.CSSProperties = {\n ...baseStyles.chevron,\n transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)',\n };\n\n const answerStyle: React.CSSProperties = {\n ...baseStyles.answer,\n ...colors.answer,\n maxHeight: isExpanded ? '500px' : '0',\n paddingBottom: isExpanded ? '16px' : '0',\n };\n\n const feedbackStyle: React.CSSProperties = {\n ...baseStyles.feedback,\n ...colors.feedbackPrompt,\n };\n\n return (\n <div style={itemStyle} data-faq-item-id={item.config.id}>\n <button\n style={questionStyle}\n onClick={onToggle}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n aria-expanded={isExpanded}\n >\n <span>{question}</span>\n <span style={chevronStyle}>{'\\u25BC'}</span>\n </button>\n <div style={answerStyle} aria-hidden={!isExpanded}>\n {renderAnswer(answer)}\n\n {/* Feedback UI \u2014 only when expanded and feedback is enabled */}\n {isExpanded && feedbackConfig && (\n <div style={feedbackStyle}>\n <span>{getFeedbackPrompt(feedbackConfig)}</span>\n <button\n style={{\n ...baseStyles.feedbackButton,\n ...(feedbackValue === 'up' ? baseStyles.feedbackButtonSelected : {}),\n }}\n aria-label=\"Thumbs up\"\n onClick={() => onFeedback(item.config.id, question, 'up')}\n >\n {'\\uD83D\\uDC4D'}\n </button>\n <button\n style={{\n ...baseStyles.feedbackButton,\n ...(feedbackValue === 'down' ? baseStyles.feedbackButtonSelected : {}),\n }}\n aria-label=\"Thumbs down\"\n onClick={() => onFeedback(item.config.id, question, 'down')}\n >\n {'\\uD83D\\uDC4E'}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// FAQWidget Component\n// ============================================================================\n\n/**\n * FAQWidget - Renders a collapsible Q&A accordion with per-item activation.\n *\n * This component demonstrates the compositional action pattern:\n * - Parent (FAQWidget) receives `config.actions` array\n * - Each action has optional `showWhen` for per-item visibility\n * - Parent evaluates showWhen and filters visible questions\n * - Parent manages expand state and re-rendering on context changes\n */\nexport function FAQWidget({ config, runtime, instanceId }: FAQWidgetProps) {\n // Force re-render when context changes\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n // Track expanded question IDs\n const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());\n\n // Search query state\n const [searchQuery, setSearchQuery] = useState('');\n\n // Track feedback state per item\n const [feedbackState, setFeedbackState] = useState<Map<string, FeedbackValue>>(new Map());\n\n // Resolve feedback config\n const feedbackConfig = useMemo(() => resolveFeedbackConfig(config.feedback), [config.feedback]);\n\n // Subscribe to context changes for reactive updates\n useEffect(() => {\n const unsubscribe = runtime.context.subscribe(() => {\n forceUpdate();\n });\n return unsubscribe;\n }, [runtime.context]);\n\n // Filter visible questions based on per-item showWhen\n const visibleQuestions = useMemo(\n () =>\n config.actions.filter((q) => {\n // No showWhen = always visible\n if (!q.showWhen) return true;\n\n // Evaluate the decision strategy\n const result = runtime.evaluateSync<boolean>(q.showWhen);\n return result.value;\n }),\n [config.actions, runtime]\n );\n\n // Apply priority ordering\n const orderedQuestions = useMemo(() => {\n if (config.ordering === 'priority') {\n return [...visibleQuestions].sort(\n (a, b) => (b.config.priority ?? 0) - (a.config.priority ?? 0)\n );\n }\n // 'static' or undefined \u2014 preserve config order\n return visibleQuestions;\n }, [visibleQuestions, config.ordering]);\n\n // Apply search filter\n const filteredQuestions = useMemo(() => {\n if (!config.searchable || !searchQuery.trim()) {\n return orderedQuestions;\n }\n\n const query = searchQuery.toLowerCase();\n return orderedQuestions.filter(\n (q) =>\n q.config.question.toLowerCase().includes(query) ||\n getAnswerText(q.config.answer).toLowerCase().includes(query) ||\n q.config.category?.toLowerCase().includes(query)\n );\n }, [orderedQuestions, searchQuery, config.searchable]);\n\n // Group by category\n const categoryGroups = useMemo(() => {\n const groups = new Map<string | undefined, FAQQuestionAction[]>();\n for (const q of filteredQuestions) {\n const cat = q.config.category;\n if (!groups.has(cat)) {\n groups.set(cat, []);\n }\n groups.get(cat)!.push(q);\n }\n return groups;\n }, [filteredQuestions]);\n\n // Check if any items have categories\n const hasCategories = useMemo(\n () => filteredQuestions.some((q) => q.config.category),\n [filteredQuestions]\n );\n\n // Resolve theme (auto -> detect system preference)\n const resolvedTheme = useMemo(() => {\n if (config.theme !== 'auto') return config.theme;\n\n // Check system preference (SSR-safe)\n if (typeof window !== 'undefined') {\n return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n return 'light';\n }, [config.theme]);\n\n // Handle question toggle\n const handleToggle = useCallback(\n (id: string) => {\n setExpandedIds((prev) => {\n const next = new Set(prev);\n\n if (config.expandBehavior === 'single') {\n // Single mode: collapse all others\n if (prev.has(id)) {\n return new Set();\n }\n return new Set([id]);\n }\n // Multiple mode: toggle this one\n if (prev.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n\n // Publish toggle event for analytics\n runtime.events.publish('faq:toggled', {\n instanceId,\n questionId: id,\n expanded: !expandedIds.has(id),\n timestamp: Date.now(),\n });\n },\n [config.expandBehavior, runtime.events, instanceId, expandedIds]\n );\n\n // Handle feedback\n const handleFeedback = useCallback(\n (itemId: string, question: string, value: FeedbackValue) => {\n setFeedbackState((prev) => {\n const next = new Map(prev);\n next.set(itemId, value);\n return next;\n });\n\n runtime.events.publish('faq:feedback', {\n itemId,\n question,\n value,\n });\n },\n [runtime.events]\n );\n\n // Compute styles\n const containerStyle: React.CSSProperties = {\n ...baseStyles.container,\n ...themeStyles[resolvedTheme].container,\n };\n\n const searchInputStyle: React.CSSProperties = {\n ...baseStyles.searchInput,\n ...themeStyles[resolvedTheme].searchInput,\n };\n\n const emptyStateStyle: React.CSSProperties = {\n ...baseStyles.emptyState,\n ...themeStyles[resolvedTheme].emptyState,\n };\n\n const categoryHeaderStyle: React.CSSProperties = {\n ...baseStyles.categoryHeader,\n ...themeStyles[resolvedTheme].categoryHeader,\n };\n\n // Render a list of FAQ items\n const renderItems = (items: FAQQuestionAction[]) =>\n items.map((q) => (\n <FAQItem\n key={q.config.id}\n item={q}\n isExpanded={expandedIds.has(q.config.id)}\n onToggle={() => handleToggle(q.config.id)}\n theme={resolvedTheme}\n feedbackConfig={feedbackConfig}\n feedbackValue={feedbackState.get(q.config.id)}\n onFeedback={handleFeedback}\n />\n ));\n\n // Empty state (no visible questions at all)\n if (visibleQuestions.length === 0) {\n return (\n <div style={containerStyle} data-adaptive-id={instanceId} data-adaptive-type=\"adaptive-faq\">\n <div style={emptyStateStyle}>No FAQ questions available.</div>\n </div>\n );\n }\n\n return (\n <div style={containerStyle} data-adaptive-id={instanceId} data-adaptive-type=\"adaptive-faq\">\n {/* Search input */}\n {config.searchable && (\n <div style={baseStyles.searchWrapper}>\n <input\n type=\"text\"\n placeholder=\"Search questions...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={searchInputStyle}\n />\n </div>\n )}\n\n {/* Accordion \u2014 grouped by category if categories are present */}\n <div style={baseStyles.accordion}>\n {hasCategories\n ? Array.from(categoryGroups.entries()).map(([category, items]) => (\n <React.Fragment key={category ?? '__ungrouped'}>\n {category && (\n <div style={categoryHeaderStyle} data-category-header={category}>\n {category}\n </div>\n )}\n {renderItems(items)}\n </React.Fragment>\n ))\n : renderItems(filteredQuestions)}\n </div>\n\n {/* No search results */}\n {config.searchable && filteredQuestions.length === 0 && searchQuery && (\n <div style={{ ...baseStyles.noResults, ...themeStyles[resolvedTheme].emptyState }}>\n No questions found matching &quot;{searchQuery}&quot;\n </div>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Mountable Widget Interface\n// ============================================================================\n\n/**\n * Mountable widget interface for the runtime's WidgetRegistry.\n */\nexport const FAQMountableWidget = {\n mount(\n container: HTMLElement,\n config?: FAQConfig & { runtime?: FAQWidgetRuntime; instanceId?: string }\n ) {\n const {\n runtime,\n instanceId = 'faq-widget',\n ...faqConfig\n } = config || {\n expandBehavior: 'single' as const,\n searchable: false,\n theme: 'auto' as const,\n actions: [],\n };\n\n // React rendering when runtime + ReactDOM are available\n if (runtime && typeof createRoot === 'function') {\n const root = createRoot(container);\n root.render(\n React.createElement(FAQWidget, {\n config: faqConfig as FAQConfig,\n runtime: runtime as FAQWidgetRuntime,\n instanceId,\n })\n );\n return () => { root.unmount(); };\n }\n\n // HTML fallback for non-React environments\n const questions = (faqConfig as FAQConfig).actions || [];\n container.innerHTML = `\n <div style=\"font-family: system-ui; max-width: 800px;\">\n ${questions\n .map(\n (q) => `\n <div style=\"margin-bottom: 8px; padding: 16px; background: #f9fafb; border-radius: 8px;\">\n <strong>${q.config.question}</strong>\n <p style=\"margin-top: 8px; color: #4b5563;\">${getAnswerText(q.config.answer)}</p>\n </div>\n `\n )\n .join('')}\n </div>\n `;\n\n return () => {\n container.innerHTML = '';\n };\n },\n};\n\nexport default FAQWidget;\n", "/**\n * Adaptive FAQ - Runtime Module\n *\n * Runtime manifest for the FAQ accordion adaptive.\n * Provides action executors and widget registration.\n */\n\nimport { executorDefinitions } from './executors';\nimport { FAQMountableWidget } from './FAQWidget';\n\n// ============================================================================\n// App Runtime Manifest\n// ============================================================================\n\n/**\n * Runtime manifest for adaptive-faq.\n *\n * Provides:\n * - FAQ action executors (scroll_to, toggle_item, update)\n * - Widget-based accordion (compositional faq:question actions)\n */\nexport const runtime = {\n id: 'adaptive-faq',\n version: '2.0.0',\n name: 'FAQ Accordion',\n description:\n 'Collapsible Q&A accordion with actions, rich content, feedback, and personalization',\n\n /**\n * Action executors for programmatic FAQ interaction.\n */\n executors: executorDefinitions,\n\n /**\n * Widget definitions for the runtime's WidgetRegistry.\n */\n widgets: [\n {\n id: 'adaptive-faq:accordion',\n component: FAQMountableWidget,\n metadata: {\n name: 'FAQ Accordion',\n description: 'Collapsible Q&A accordion with search, categories, and feedback',\n icon: '\u2753',\n },\n },\n ],\n};\n\nexport default runtime;\n", "/**\n * CDN Entry Point for Adaptive FAQ\n *\n * This module is bundled for CDN delivery and self-registers with the global\n * SynOS app registry when loaded dynamically via the AppLoader.\n */\n\nimport FAQEditor, { editorPanel } from './editor';\nimport { runtime } from './runtime';\n\n/**\n * App manifest for registry registration.\n * Follows the AppManifest interface expected by AppLoader/AppRegistry.\n */\nexport const manifest = {\n id: 'adaptive-faq',\n version: runtime.version,\n name: runtime.name,\n description: runtime.description,\n runtime: {\n actions: runtime.executors,\n widgets: runtime.widgets,\n },\n editor: { component: FAQEditor, panel: editorPanel },\n metadata: {\n isBuiltIn: false,\n },\n};\n\n/**\n * Self-register with global registry if available.\n * This happens when loaded via script tag (UMD).\n */\nif (typeof window !== 'undefined') {\n const registry = (window as any).SynOS?.appRegistry;\n if (registry && typeof registry.register === 'function') {\n registry.register(manifest);\n }\n}\n\nexport default manifest;\n"],
5
+ "mappings": "AACY,IAAIA,EAAI,WAAW,kBAAoB,CAAC,EACjCC,EAAQD,EACJE,EAAWF,EAAE,SACbG,EAAYH,EAAE,UACdI,EAAUJ,EAAE,QACZK,EAAcL,EAAE,YAChBM,EAASN,EAAE,OACXO,GAAaP,EAAE,WACfQ,EAAaR,EAAE,WACfS,GAAgBT,EAAE,cAClBU,GAAgBV,EAAE,cAClBW,GAAWX,EAAE,SACbY,GAAaZ,EAAE,WACfa,GAAOb,EAAE,KACTc,GAAOd,EAAE,KACTe,GAAWf,EAAE,SACbgB,GAAWhB,EAAE,SACbiB,GAAiBjB,EAAE,eACnBkB,GAAelB,EAAE,aACjBmB,GAAYnB,EAAE,UACdoB,GAAgBpB,EAAE,cAClBqB,GAAkBrB,EAAE,gBACpBsB,GAAQtB,EAAE,MCbjC,SAASuB,EAASC,EAAcC,EAAqB,CACnD,OAAID,EAAK,QAAUC,EAAYD,EACxB,GAAGA,EAAK,MAAM,EAAGC,CAAG,EAAE,QAAQ,CAAC,KACxC,CAEA,SAASC,GAAUC,EAAsB,CACvC,OAAOA,EAAK,QAAQ,WAAY,EAAE,EAAE,KAAK,CAC3C,CAEA,SAASC,GAAiBC,EAA2B,CACnD,OAAI,OAAOA,GAAW,SAAiBA,EACnCA,EAAO,OAAS,OAAeH,GAAUG,EAAO,IAAI,EACjDA,EAAO,QAAQ,QAAQ,UAAW,EAAE,EAAE,KAAK,CACpD,CAEA,SAASC,GAAeC,EAAwC,CAC9D,OACE,OAAOA,GAAM,UACbA,IAAM,MACLA,EAA8B,OAAS,SACxC,MAAM,QAASA,EAA8B,KAAK,CAEtD,CAKO,SAASC,EAAgBC,EAAqD,CAEnF,GADI,CAACA,GACD,CAACH,GAAeG,CAAQ,EAAG,MAAO,YAEtC,IAAMC,EAAkB,CAAC,EACnBC,EAAoB,CAAC,EAE3B,QAAWC,KAAQH,EAAS,MAC1B,QAAWI,KAAaD,EAAK,WACvBC,EAAU,OAAS,YAAc,OAAQA,EAAkB,KAAQ,UACrEH,EAAM,KAAMG,EAAkB,GAAG,EAE/BA,EAAU,OAAS,kBAAoB,OAAQA,EAAkB,UAAa,UAChFF,EAAQ,KAAME,EAAkB,QAAQ,EAK9C,IAAMC,EAAkB,CAAC,EACzB,OAAIJ,EAAM,OAAS,GAAGI,EAAM,KAAKJ,EAAM,CAAC,CAAC,EACrCC,EAAQ,OAAS,GAAGG,EAAM,KAAKH,EAAQ,CAAC,CAAC,EAEtCG,EAAM,OAAS,EAAIA,EAAM,KAAK,QAAU,EAAI,WACrD,CAKO,SAASC,GAAiBC,EAAiC,CAChE,IAAMC,EAAIlB,EAASiB,EAAK,OAAO,SAAU,EAAS,EAC5CE,EAAInB,EAASK,GAAiBY,EAAK,OAAO,MAAM,EAAG,EAAS,EAClE,MAAO,OAAOC,CAAC,YAAYC,CAAC,EAC9B,CCwKO,SAASC,EAAYC,EAAmC,CAC7D,OAAOA,EAAO,KAAK,WAAW,MAAsB,CACtD,CC9OY,SAASC,IAAQ,CAAE,OAAO,WAAW,gBAAkB,CACvD,SAASC,GAAKC,EAAMC,EAAOC,EAAK,CAC9B,IAAIC,EAAIL,GAAM,EACVM,EAAIH,GAAS,CAAC,EACdI,EAAID,EAAE,SACV,cAAOA,EAAE,SACLF,IAAQ,SAAWE,EAAE,IAAMF,GACxB,MAAM,QAAQG,CAAC,EAClBF,EAAE,cAAc,MAAM,KAAM,CAACH,EAAMI,CAAC,EAAE,OAAOC,CAAC,CAAC,EAC/CA,IAAM,OACJF,EAAE,cAAcH,EAAMI,EAAGC,CAAC,EAC1BF,EAAE,cAAcH,EAAMI,CAAC,CAC/B,CACO,IAAIE,EAAMP,GACNQ,EAAOR,GACPS,GAAYV,GAAM,GAAK,CAAC,GAAG,SCclD,SAASW,GAAeC,EAAwC,CAC9D,OACE,OAAOA,GAAM,UACbA,IAAM,MACLA,EAA8B,OAAS,SACxC,MAAM,QAASA,EAA8B,KAAK,CAEtD,CAEA,SAASC,EAAqBC,EAA0C,CACtE,GAAI,CAACA,GAAY,CAACH,GAAeG,CAAQ,EACvC,MAAO,CAAE,aAAc,CAAC,EAAG,gBAAiB,CAAC,EAAG,aAAc,EAAM,EAGtE,IAAMC,EAAe,IAAI,IACnBC,EAAkB,IAAI,IAE5B,QAAWC,KAAQH,EAAS,MAC1B,QAAWI,KAAQD,EAAK,WAAY,CAClC,IAAME,EAAID,EACNC,EAAE,OAAS,YAAc,OAAOA,EAAE,KAAQ,SAC5CJ,EAAa,IAAII,EAAE,GAAG,EACbA,EAAE,OAAS,kBAAoB,OAAOA,EAAE,UAAa,UAC9DH,EAAgB,IAAIG,EAAE,QAAQ,CAElC,CAGF,IAAMC,EAAeL,EAAa,KAAO,GAAKC,EAAgB,KAAO,EACrE,MAAO,CACL,aAAc,CAAC,GAAGD,CAAY,EAC9B,gBAAiB,CAAC,GAAGC,CAAe,EACpC,aAAAI,CACF,CACF,CAEA,SAASC,GAAiBP,EAA0C,CAElE,OADaD,EAAqBC,CAAQ,EAC9B,aAAa,CAAC,GAAK,IACjC,CAEA,SAASQ,GAAmBR,EAA0C,CAEpE,OADaD,EAAqBC,CAAQ,EAC9B,gBAAgB,CAAC,GAAK,IACpC,CAMA,SAASS,GAAcC,EAA2B,CAChD,OAAI,OAAOA,GAAW,SAAiBA,EACnCA,EAAO,OAAS,OAAeA,EAAO,KACnCA,EAAO,OAChB,CAYA,SAASC,GAAaC,EAA+B,CAEnD,OADiBA,EAAO,SAAW,CAAC,GAAG,OAAOC,CAAW,EAC1C,IAAI,CAACC,EAAGC,KAAO,CAC5B,IAAK,OAAOA,CAAC,EACb,MAAOA,EACP,QAASC,GAAiBF,CAAC,EAC3B,QAASG,EAAgBH,EAAE,QAAQ,EACnC,UAAWA,EAAE,UACb,YAAaN,GAAmBM,EAAE,QAAQ,EAC1C,SAAUA,CACZ,EAAE,CACJ,CAEA,SAASI,GAAaN,EAAmBO,EAAuC,CAC9E,IAAMC,GAAcR,EAAO,SAAW,CAAC,GAAG,OAAOC,CAAW,EAC5D,MAAO,CACL,GAAGD,EACH,QAASQ,EAAW,OAAO,CAACC,EAAGN,IAAM,CAACI,EAAc,IAAI,OAAOJ,CAAC,CAAC,CAAC,CACpE,CACF,CAWA,SAASO,GACPC,EACAC,EAC6B,CAC7B,GAAM,CAACC,EAAcC,CAAe,EAAIC,EAAsC,IAAI,GAAK,EACjFC,EAAWC,EAAON,CAAK,EAC7B,OAAAK,EAAS,QAAUL,EAEnBO,EAAU,IAAM,CACd,IAAMC,EAAe,IAAM,CACzB,IAAMC,EAAM,IAAI,IACVC,EAAcT,EAAgB,EAEpC,QAAWU,KAAQN,EAAS,QAAS,CACnC,IAAMO,EAAYpC,EAAqBmC,EAAK,SAAS,QAAQ,EAGzDE,EAAY,GACZD,EAAU,aAAa,OAAS,IAClCC,EAAYD,EAAU,aAAa,KAAME,GACzB,IAAI,OAChB,IAAIA,EAAQ,QAAQ,QAAS,IAAI,EAAE,QAAQ,eAAgB,OAAO,CAAC,GACrE,EACa,KAAKJ,CAAW,CAC9B,GAIH,IAAIK,EAAc,GACdC,EAA8B,KAClC,GAAIL,EAAK,YACP,GAAI,CACFK,EAAU,SAAS,cAAcL,EAAK,WAAW,EACjDI,EAAcC,IAAY,IAC5B,MAAQ,CAER,MAGAD,EAAcF,EAGhBJ,EAAI,IAAIE,EAAK,IAAK,CAChB,MAAOE,GAAaE,EACpB,QAAAC,CACF,CAAC,CACH,CAEAb,EAAgBM,CAAG,CACrB,EAEAD,EAAa,EAEb,IAAMS,EAAW,YAAYT,EAAc,GAAI,EAC/C,cAAO,iBAAiB,WAAYA,CAAY,EAEzC,IAAM,CACX,cAAcS,CAAQ,EACtB,OAAO,oBAAoB,WAAYT,CAAY,CACrD,CACF,EAAG,CAACP,CAAe,CAAC,EAEbC,CACT,CAMA,SAASgB,GAAe,CAAE,MAAAC,CAAM,EAAuB,CACrD,OACEC,EAAC,QACC,MAAO,CACL,MAAO,MACP,OAAQ,MACR,aAAc,MACd,gBAAiBD,EAAQ,UAAY,UACrC,WAAY,EACZ,QAAS,cACX,EACA,MAAOA,EAAQ,qBAAuB,yBACxC,CAEJ,CAMA,IAAME,EAAS,CACb,UAAW,CACT,QAAS,OACT,cAAe,SACf,OAAQ,OACR,WAAY,sCACd,EACA,OAAQ,CACN,QAAS,OACT,aAAc,oBACd,QAAS,OACT,WAAY,SACZ,IAAK,MACP,EACA,WAAY,CACV,QAAS,WACT,aAAc,MACd,OAAQ,OACR,gBAAiB,yBACjB,MAAO,UACP,SAAU,OACV,OAAQ,SACV,EACA,MAAO,CACL,OAAQ,EACR,SAAU,OACV,WAAY,IACZ,MAAO,SACT,EACA,SAAU,CACR,OAAQ,YACR,SAAU,OACV,MAAO,SACT,EACA,KAAM,CACJ,KAAM,EACN,SAAU,OACV,QAAS,MACX,EACA,YAAa,CACX,SAAU,OACV,WAAY,IACZ,MAAO,UACP,cAAe,YACf,cAAe,SACf,QAAS,cACT,QAAS,OACT,WAAY,SACZ,eAAgB,eAClB,EACA,WAAY,CACV,SAAU,OACV,MAAO,UACP,gBAAiB,yBACjB,QAAS,UACT,aAAc,KAChB,EACA,KAAM,CACJ,QAAS,WACT,aAAc,MACd,OAAQ,mCACR,WAAY,yBACZ,aAAc,MACd,SAAU,OACV,MAAO,SACT,EACA,YAAa,CACX,QAAS,OACT,WAAY,SACZ,IAAK,MACL,SAAU,OACV,MAAO,UACP,OAAQ,UACR,aAAc,KAChB,EACA,SAAU,CACR,QAAS,OACT,WAAY,SACZ,IAAK,MACL,OAAQ,SACV,EACA,SAAU,CACR,KAAM,EACN,SAAU,SACV,aAAc,WACd,WAAY,QACd,EACA,cAAe,CACb,SAAU,OACV,MAAO,UACP,UAAW,KACb,EACA,cAAe,CACb,QAAS,UACT,aAAc,MACd,OAAQ,OACR,WAAY,cACZ,MAAO,UACP,SAAU,OACV,OAAQ,UACR,WAAY,EACZ,WAAY,CACd,EACA,iBAAkB,CAChB,UAAW,OACX,OAAQ,UACR,WAAY,MACd,EACA,gBAAiB,CACf,SAAU,OACV,WAAY,IACZ,MAAO,UACP,QAAS,OACT,WAAY,SACZ,IAAK,KACP,EACA,cAAe,CACb,QAAS,OACT,WAAY,SACZ,IAAK,MACL,QAAS,WACT,aAAc,MACd,OAAQ,mCACR,WAAY,cACZ,aAAc,MACd,OAAQ,UACR,SAAU,OACV,MAAO,UACP,QAAS,EACX,EACA,WAAY,CACV,UAAW,SACX,QAAS,YACT,MAAO,UACP,SAAU,MACZ,EACA,OAAQ,CACN,QAAS,YACT,UAAW,oBACX,QAAS,OACT,IAAK,KACP,EACA,WAAY,CACV,KAAM,EACN,QAAS,OACT,aAAc,MACd,OAAQ,OACR,WAAY,2BACZ,MAAO,UACP,SAAU,OACV,WAAY,IACZ,OAAQ,SACV,EACA,cAAe,CACb,KAAM,EACN,QAAS,OACT,aAAc,MACd,OAAQ,OACR,WAAY,UACZ,MAAO,QACP,SAAU,OACV,WAAY,IACZ,OAAQ,SACV,EAEA,SAAU,CACR,QAAS,OACX,EACA,WAAY,CACV,QAAS,OACT,WAAY,SACZ,IAAK,MACL,aAAc,OACd,SAAU,OACV,WAAY,IACZ,MAAO,SACT,EACA,UAAW,CACT,SAAU,OACV,WAAY,IACZ,MAAO,UACP,aAAc,MACd,QAAS,OACX,EACA,UAAW,CACT,MAAO,OACP,QAAS,UACT,aAAc,MACd,OAAQ,kCACR,WAAY,yBACZ,MAAO,UACP,SAAU,OACV,WAAY,UACZ,aAAc,MACd,UAAW,YACb,EACA,aAAc,CACZ,MAAO,OACP,QAAS,UACT,aAAc,MACd,OAAQ,kCACR,WAAY,yBACZ,MAAO,UACP,SAAU,OACV,WAAY,UACZ,aAAc,MACd,OAAQ,WACR,UAAW,OACX,UAAW,YACb,EACA,cAAe,CACb,QAAS,MACT,aAAc,MACd,OAAQ,oCACR,WAAY,yBACZ,MAAO,UACP,SAAU,OACV,aAAc,KAChB,EACA,eAAgB,CACd,QAAS,WACT,aAAc,MACd,OAAQ,kCACR,WAAY,cACZ,MAAO,UACP,SAAU,OACV,OAAQ,UACR,UAAW,KACb,CACF,EAMO,SAASC,GAAU,CAAE,OAAAjC,EAAQ,SAAAkC,EAAU,OAAAC,CAAO,EAAqB,CACxE,IAAMC,EAAcpC,EACd,CAACO,EAAe8B,CAAgB,EAAItB,EAAsB,IAAI,GAAK,EACnE,CAACuB,EAAeC,CAAgB,EAAIxB,EAAS,EAAK,EAClD,CAACyB,EAAYC,CAAa,EAAI1B,EAAwB,IAAI,EAC1D,CAAC2B,EAAaC,CAAc,EAAI5B,EAA6B,OAAO,EACpE,CAAC6B,EAAaC,CAAa,EAAI9B,EAAwB,IAAI,EAI3D+B,EAAkB7B,EAAO,EAAK,EACpCC,EAAU,IAAM,CACV,CAAC4B,EAAgB,UAAYX,EAAO,gBAAkB,MAAQA,EAAO,iBACvEW,EAAgB,QAAU,GAC1BX,EAAO,oBAAoB,EAE/B,EAAG,CAACA,CAAM,CAAC,EAEX,IAAMY,EAAWhD,GAAaqC,CAAW,EACnCY,EAAcD,EAAS,OAAQzB,GAAS,CAACf,EAAc,IAAIe,EAAK,GAAG,CAAC,EACpE2B,EAAiBF,EAAS,OAAQzB,GAASf,EAAc,IAAIe,EAAK,GAAG,CAAC,EACtE4B,EAAiBF,EAAY,OAE7BnC,EAAeH,GAAaqC,EAAUZ,EAAO,eAAe,EAC5DgB,EAAaH,EAAY,OAAQ1B,GAAST,EAAa,IAAIS,EAAK,GAAG,GAAG,KAAK,EAAE,OAE7E8B,EAAgBC,EACnBC,GAAgB,CACfjB,EAAkBkB,GAAS,CACzB,IAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAAC,EAAK,IAAIF,CAAG,EACLE,CACT,CAAC,EACGhB,IAAec,GAAKb,EAAc,IAAI,CAC5C,EACA,CAACD,CAAU,CACb,EAEMiB,EAAgBJ,EAAaC,GAAgB,CACjDjB,EAAkBkB,GAAS,CACzB,IAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAAC,EAAK,OAAOF,CAAG,EACRE,CACT,CAAC,CACH,EAAG,CAAC,CAAC,EAECE,EAAsBL,EAAa/B,GAAmB,CAC1DmB,EAAcnB,EAAK,GAAG,CACxB,EAAG,CAAC,CAAC,EAECqC,EAAqBN,EACxB/B,GAAmB,CAClB,IAAMsC,EAAUjE,GAAiB2B,EAAK,SAAS,QAAQ,EACnDsC,GACFzB,EAAO,WAAWyB,CAAO,EAEvBtC,EAAK,aACPa,EAAO,iBAAiBb,EAAK,WAAW,CAE5C,EACA,CAACa,CAAM,CACT,EAEM0B,EAAmBR,EAAY,IAAM,CACzCZ,EAAc,IAAI,EAClBE,EAAe,OAAO,EACtBR,EAAO,cAAcnC,CAAM,EAC3BmC,EAAO,eAAe,CACxB,EAAG,CAACA,EAAQnC,CAAM,CAAC,EAEb8D,EAAoBT,EACvBU,GAA6B,CAE5B,GADApB,EAAeoB,CAAI,EACfA,IAAS,SAAU,CACrB,IAAMC,EAAW1D,GAAa8B,EAAa,IAAI,IAAI,CAACI,CAAW,CAAC,CAAC,EACjEL,EAAO,cAAc6B,CAA8C,CACrE,MACE7B,EAAO,cAAcnC,CAAM,CAE/B,EACA,CAACoC,EAAaI,EAAYL,EAAQnC,CAAM,CAC1C,EAEMiE,EAAoBZ,EACxB,CAACa,EAAeC,EAAeC,IAAmB,CAChD,IAAM5D,GAAc4B,EAAY,SAAW,CAAC,GAAG,OAAOnC,CAAW,EAAE,MAAM,EACnEC,EAAI,CAAE,GAAGM,EAAW0D,CAAK,EAAG,OAAQ,CAAE,GAAG1D,EAAW0D,CAAK,EAAE,MAAO,CAAE,EACzEhE,EAAE,OAAmCiE,CAAK,EAAIC,EAC/C5D,EAAW0D,CAAK,EAAIhE,EACpB,IAAMmE,IAAgBjC,EAAY,SAAW,CAAC,GAAG,OAAQkC,IAAM,CAACrE,EAAYqE,EAAC,CAAC,EACxEC,GAAU,CAAE,GAAGnC,EAAa,QAAS,CAAC,GAAGiC,GAAc,GAAG7D,CAAU,CAAE,EAC5E0B,EAASqC,EAA6C,EACtDpC,EAAO,SAAS,EAAI,CACtB,EACA,CAACC,EAAaF,EAAUC,CAAM,CAChC,EAEMqC,EAAgBnB,EAAY,IAAM,CACtC,GAAI9C,EAAc,KAAO,EAAG,CAC1B,IAAMyD,EAAW1D,GAAa8B,EAAa7B,CAAa,EACxD2B,EAAS8B,CAA8C,CACzD,CACA7B,EAAO,QAAQ,CACjB,EAAG,CAAC5B,EAAe6B,EAAaF,EAAUC,CAAM,CAAC,EAE3CsC,GAAkBpB,EACrB/B,GAAmB,CAClBuB,EAAcvB,EAAK,GAAG,EAClBA,EAAK,aACPa,EAAO,iBAAiBb,EAAK,WAAW,CAE5C,EACA,CAACa,CAAM,CACT,EAEMuC,GAAkBrB,EAAY,IAAM,CACxCR,EAAc,IAAI,EAClBV,EAAO,eAAe,CACxB,EAAG,CAACA,CAAM,CAAC,EAILwC,GAAoBT,GAAkB,CAE1C,IAAMhE,GADWkC,EAAY,SAAW,CAAC,GAAG,OAAOnC,CAAW,EAC5CiE,CAAK,EACvB,GAAI,CAAChE,EAAG,OAAO,KAEf,IAAMoB,EAAOyB,EAAS,KAAM6B,GAAOA,EAAG,MAAQ,OAAOV,CAAK,CAAC,EAE3D,OACEW,EAAC,OAAI,MAAO7C,EAAO,SAEhB,UAAAV,GAAQA,EAAK,UAAY,aACxBuD,EAAC,OAAI,eAAY,GAAC,MAAO7C,EAAO,YAAa,QAAS,IAAM2B,EAAmBrC,CAAI,EACjF,UAAAS,EAAC,QAAM,qBAAY,EACnBA,EAAC,QAAM,SAAAT,EAAK,QAAQ,GACtB,EAGFS,EAAC,SAAM,MAAOC,EAAO,UAAW,oBAAQ,EACxCD,EAAC,SACC,MAAOC,EAAO,UACd,MAAO9B,EAAE,OAAO,SAChB,SAAW4E,GAAMb,EAAkBC,EAAO,WAAYY,EAAE,OAAO,KAAK,EACtE,EAEA/C,EAAC,SAAM,MAAOC,EAAO,UAAW,kBAAM,EACtCD,EAAC,YACC,MAAOC,EAAO,aACd,MAAOnC,GAAcK,EAAE,OAAO,MAAM,EACpC,SAAW4E,GAAMb,EAAkBC,EAAO,SAAUY,EAAE,OAAO,KAAK,EACpE,EAEA/C,EAAC,SAAM,MAAOC,EAAO,UAAW,oBAAQ,EACxCD,EAAC,SACC,MAAOC,EAAO,UACd,MAAO9B,EAAE,OAAO,UAAY,GAC5B,SAAW4E,GAAMb,EAAkBC,EAAO,WAAYY,EAAE,OAAO,OAAS,MAAS,EACjF,YAAY,yBACd,EAEA/C,EAAC,SAAM,MAAOC,EAAO,UAAW,wBAAY,EAC5CD,EAAC,OAAI,MAAOC,EAAO,cAAgB,SAAA9B,EAAE,UAAYA,EAAE,UAAU,IAAM,MAAM,GAC3E,CAEJ,EAEA,OACE2E,EAAC,OAAI,MAAO7C,EAAO,UAEjB,UAAA6C,EAAC,OAAI,MAAO7C,EAAO,OACjB,UAAAD,EAAC,UAAO,QAAS,IAAMI,EAAO,aAAa,EAAG,MAAOH,EAAO,WAAY,uBAExE,EACA6C,EAAC,OACC,UAAA9C,EAAC,MAAG,MAAOC,EAAO,MAAO,4BAAgB,EACzC6C,EAAC,KAAE,MAAO7C,EAAO,SACd,UAAAkB,EAAe,YAAUA,IAAmB,EAAI,IAAM,GACtDA,EAAiB,GAAK,KAAKC,CAAU,wBACxC,GACF,GACF,EAGApB,EAAC,OAAI,MAAOC,EAAO,KAChB,SAAAQ,IAAe,MAEb,IAAM,CACL,IAAMuC,EAAY,OAAOvC,CAAU,EAC7BwC,EAAWjC,EAAS,KAAM6B,GAAOA,EAAG,MAAQpC,CAAU,EAC5D,OACEqC,EAAAI,EAAA,CACE,UAAAJ,EAAC,OAAI,MAAO7C,EAAO,WACjB,UAAAD,EAAC,QAAM,kBAAS,EAChBA,EAAC,QAAM,SAAAiD,GAAU,QAAQ,GAC3B,EACAH,EAAC,OACC,MAAO,CACL,QAAS,OACT,IAAK,IACL,aAAc,OACd,aAAc,MACd,SAAU,SACV,OAAQ,iCACV,EAEA,UAAA9C,EAAC,UACC,QAAS,IAAM+B,EAAkB,QAAQ,EACzC,MAAO,CACL,KAAM,EACN,QAAS,WACT,OAAQ,OACR,SAAU,OACV,WAAY,IACZ,OAAQ,UACR,WAAYpB,IAAgB,SAAW,uBAAyB,cAChE,MAAOA,IAAgB,SAAW,UAAY,SAChD,EACD,kBAED,EACAX,EAAC,UACC,QAAS,IAAM+B,EAAkB,OAAO,EACxC,MAAO,CACL,KAAM,EACN,QAAS,WACT,OAAQ,OACR,WAAY,kCACZ,SAAU,OACV,WAAY,IACZ,OAAQ,UACR,WAAYpB,IAAgB,QAAU,uBAAyB,cAC/D,MAAOA,IAAgB,QAAU,UAAY,SAC/C,EACD,iBAED,GACF,EACCiC,GAAiBI,CAAS,EAC3BhD,EAAC,UAAO,MAAOC,EAAO,eAAgB,QAAS6B,EAAkB,uBAEjE,GACF,CAEJ,GAAG,EAGHgB,EAAAI,EAAA,CACG,UAAAlC,EAAS,SAAW,GACnBhB,EAAC,OAAI,MAAOC,EAAO,WAAY,wCAA4B,EAG5DgB,EAAY,OAAS,GACpB6B,EAAAI,EAAA,CACE,UAAAJ,EAAC,OAAI,MAAO7C,EAAO,YACjB,UAAAD,EAAC,QAAK,eAAG,EACTA,EAAC,QAAK,MAAOC,EAAO,WAAa,SAAAgB,EAAY,OAAO,GACtD,EACCA,EAAY,IAAK1B,GAAS,CACzB,IAAM4D,EAAYrE,EAAa,IAAIS,EAAK,GAAG,EAC3C,OACEuD,EAAC,OAEC,MAAO7C,EAAO,KACd,gBAAeV,EAAK,IACpB,aAAc,IAAMmD,GAAgBnD,CAAI,EACxC,aAAcoD,GAGb,UAAApD,EAAK,UAAY,aAChBuD,EAAC,OACC,eAAY,GACZ,MAAO7C,EAAO,YACd,QAAU8C,GAAM,CACdA,EAAE,gBAAgB,EAClBnB,EAAmBrC,CAAI,CACzB,EAEA,UAAAS,EAAC,QAAM,qBAAY,EACnBA,EAAC,QAAM,SAAAT,EAAK,QAAQ,GACtB,EAGFuD,EAAC,OACC,iBAAc,GACd,MAAO7C,EAAO,SACd,QAAS,IAAM0B,EAAoBpC,CAAI,EAEvC,UAAAS,EAACF,GAAA,CAAe,MAAOqD,GAAW,OAAS,GAAO,EAClDnD,EAAC,QAAK,MAAOC,EAAO,SAAW,SAAAV,EAAK,QAAQ,EAC5CS,EAAC,UACC,MAAOC,EAAO,cACd,QAAU8C,GAAM,CACdA,EAAE,gBAAgB,EAClB1B,EAAc9B,EAAK,GAAG,CACxB,EACA,MAAM,wBACP,gBAED,GACF,EAEAuD,EAAC,OAAI,MAAO7C,EAAO,cAAe,kBAC1BV,EAAK,UAAYA,EAAK,UAAU,IAAM,OAC9C,IA1CKA,EAAK,GA2CZ,CAEJ,CAAC,GACH,EAID2B,EAAe,OAAS,GACvB4B,EAAC,OAAI,MAAO7C,EAAO,iBACjB,UAAA6C,EAAC,OACC,MAAO,CAAE,GAAG7C,EAAO,gBAAiB,OAAQ,SAAU,EACtD,QAAS,IAAMO,EAAiB,CAACD,CAAa,EAE9C,UAAAP,EAAC,QAAM,SAAAO,EAAgB,SAAW,SAAS,EAC3CuC,EAAC,QAAK,wBAAY5B,EAAe,OAAO,KAAC,GAC3C,EACCX,GACCP,EAAC,OAAI,MAAO,CAAE,UAAW,KAAM,EAC5B,SAAAkB,EAAe,IAAK3B,GACnBuD,EAAC,OAAmB,MAAO7C,EAAO,cAChC,UAAAD,EAAC,QAAK,MAAO,CAAE,GAAGC,EAAO,SAAU,eAAgB,cAAe,EAC/D,SAAAV,EAAK,QACR,EACAS,EAAC,UACC,MAAO,CACL,GAAGC,EAAO,cACV,MAAO,UACP,SAAU,MACZ,EACA,QAAU8C,GAAM,CACdA,EAAE,gBAAgB,EAClBrB,EAAcnC,EAAK,GAAG,CACxB,EACD,mBAED,IAhBQA,EAAK,GAiBf,CACD,EACH,GAEJ,GAEJ,EAEJ,EAGAuD,EAAC,OAAI,MAAO7C,EAAO,OACjB,UAAAD,EAAC,UAAO,QAAS,IAAMI,EAAO,KAAK,EAAG,MAAOH,EAAO,WAAY,sBAEhE,EACAD,EAAC,UAAO,QAASyC,EAAe,MAAOxC,EAAO,cAAe,mBAE7D,GACF,GACF,CAEJ,CAKO,IAAMmD,GAAc,CACzB,MAAO,MACP,KAAM,SACN,YAAa,wCACf,EAOA,IAAOC,GAAQC,GCjyBf,SAASC,GAAYC,EAAiBC,EAAiBC,EAA0C,CAC/F,GAAID,EAAQ,CACV,IAAME,EAAQH,EAAM,SAAS,EAAE,MAAM,KAAMI,GAAMA,EAAE,OAAO,KAAOH,CAAM,EACvE,GAAIE,EAAO,OAAOA,CACpB,CAEA,GAAID,EAAc,CAChB,IAAMC,EAAQH,EAAM,eAAeE,CAAY,EAC/C,GAAIC,EAAO,OAAOA,CACpB,CAEA,MAAM,IAAI,MAAM,oBAAoB,CACtC,CAaA,eAAsBE,GACpBC,EACAC,EACAP,EACyB,CACzB,IAAMQ,EAAOT,GAAYC,EAAOM,EAAO,OAAQA,EAAO,YAAY,EAC5D,CAAE,GAAAG,CAAG,EAAID,EAAK,OAGhBF,EAAO,SAAW,IACpBN,EAAM,OAAOS,CAAE,EAIjB,IAAMC,EAAK,SAAS,cAAc,sBAAsBD,CAAE,IAAI,EAC9D,OAAIC,GACFA,EAAG,eAAe,CAChB,SAAUJ,EAAO,UAAY,QAC/B,CAAC,EAIHC,EAAQ,aAAa,gBAAiB,CAAE,OAAQE,CAAG,CAAC,EAE7C,CACL,QAAS,IAAM,CAEf,CACF,CACF,CASA,eAAsBE,GACpBL,EACAC,EACAP,EACyB,CACzB,IAAMQ,EAAOT,GAAYC,EAAOM,EAAO,OAAQA,EAAO,YAAY,EAC5D,CAAE,GAAAG,CAAG,EAAID,EAAK,OACdI,EAAeN,EAAO,OAAS,SAEjCO,EAEJ,OAAQD,EAAc,CACpB,IAAK,OACHZ,EAAM,OAAOS,CAAE,EACfI,EAAW,OACX,MACF,IAAK,SACHb,EAAM,SAASS,CAAE,EACjBI,EAAW,SACX,MAEF,QAAS,CACP,IAAMC,EAAcd,EAAM,SAAS,EAAE,cAAc,IAAIS,CAAE,EACzDT,EAAM,OAAOS,CAAE,EACfI,EAAWC,EAAc,SAAW,OACpC,KACF,CACF,CAEA,OAAAP,EAAQ,aAAa,aAAc,CAAE,OAAQE,EAAI,SAAAI,CAAS,CAAC,EAEpD,CACL,QAAS,IAAM,CAEf,CACF,CACF,CASA,eAAsBE,GACpBT,EACAC,EACAP,EACyB,CACzB,OAAQM,EAAO,UAAW,CACxB,IAAK,MAAO,CACV,IAAMU,EAAQV,EAAO,OAAS,CAAC,EACzBW,EAAWX,EAAO,WAAa,UAAY,UAAY,SAC7DN,EAAM,SAASgB,EAAOC,CAAQ,EAC9B,KACF,CAEA,IAAK,SAAU,CACb,GAAI,CAACX,EAAO,OACV,MAAM,IAAI,MAAM,oBAAoB,EAItC,GAAI,CADWN,EAAM,SAAS,EAAE,MAAM,KAAMI,GAAMA,EAAE,OAAO,KAAOE,EAAO,MAAM,EAE7E,MAAM,IAAI,MAAM,oBAAoB,EAEtCN,EAAM,WAAWM,EAAO,MAAM,EAC9B,KACF,CAEA,IAAK,UAAW,CACd,IAAMY,EAAQZ,EAAO,OAAS,CAAC,EAC/BN,EAAM,aAAakB,CAAK,EACxB,KACF,CAEA,IAAK,UAAW,CACd,IAAMF,EAAQV,EAAO,OAAS,CAAC,EAC/BN,EAAM,aAAagB,CAAK,EACxB,KACF,CACF,CAEA,OAAAT,EAAQ,aAAa,aAAc,CAAE,UAAWD,EAAO,SAAU,CAAC,EAE3D,CACL,QAAS,IAAM,CAEf,CACF,CACF,CAUO,IAAMa,GAAsB,CACjC,CAAE,KAAM,gBAAiB,SAAUd,EAAmB,EACtD,CAAE,KAAM,kBAAmB,SAAUM,EAAqB,EAC1D,CAAE,KAAM,aAAc,SAAUI,EAAiB,CACnD,EClMY,IAAIK,GAAK,WAAW,qBAEb,IAAIC,EAAaC,IAAI,WACjBC,GAAeD,IAAI,aCuB1C,SAASE,GAAcC,EAA2B,CAChD,OAAI,OAAOA,GAAW,SAAiBA,EACnCA,EAAO,OAAS,OAAeA,EAAO,KACnCA,EAAO,OAChB,CAGA,SAASC,GAAaD,EAAoC,CACxD,OAAI,OAAOA,GAAW,SACbE,EAAC,KAAE,MAAO,CAAE,OAAQ,CAAE,EAAI,SAAAF,EAAO,EAEtCA,EAAO,OAAS,OACXE,EAAC,OAAI,MAAO,CAAE,OAAQ,CAAE,EAAG,wBAAyB,CAAE,OAAQF,EAAO,IAAK,EAAG,EAG/EE,EAAC,KAAE,MAAO,CAAE,OAAQ,CAAE,EAAI,SAAAF,EAAO,QAAQ,CAClD,CAGA,SAASG,GACPC,EACuB,CACvB,OAAKA,EACDA,IAAa,GACR,CAAE,MAAO,QAAS,EAEpBA,EAJe,IAKxB,CAGA,SAASC,GAAkBC,EAAwC,CACjE,OAAOA,EAAe,QAAU,mBAClC,CAoBA,IAAMC,EAAa,CACjB,UAAW,CACT,WAAY,uCACZ,SAAU,QACV,OAAQ,QACV,EACA,cAAe,CACb,aAAc,MAChB,EACA,YAAa,CACX,MAAO,OACP,QAAS,YACT,aAAc,MACd,SAAU,OACV,QAAS,OACT,WAAY,yBACd,EACA,UAAW,CACT,QAAS,OACT,cAAe,SACf,IAAK,KACP,EACA,KAAM,CACJ,aAAc,MACd,SAAU,SACV,WAAY,uBACd,EACA,SAAU,CACR,MAAO,OACP,QAAS,YACT,QAAS,OACT,WAAY,SACZ,eAAgB,gBAChB,OAAQ,OACR,OAAQ,UACR,SAAU,OACV,WAAY,IACZ,UAAW,OACX,WAAY,6BACd,EACA,QAAS,CACP,SAAU,OACV,WAAY,qBACd,EACA,OAAQ,CACN,QAAS,mBACT,SAAU,OACV,WAAY,IACZ,SAAU,SACV,WAAY,yCACd,EACA,SAAU,CACR,QAAS,eACT,SAAU,OACV,WAAY,IACZ,cAAe,YACf,cAAe,SACf,QAAS,UACT,aAAc,MACd,aAAc,KAChB,EACA,eAAgB,CACd,SAAU,OACV,WAAY,IACZ,cAAe,YACf,cAAe,SACf,QAAS,mBACT,UAAW,KACb,EACA,SAAU,CACR,QAAS,OACT,WAAY,SACZ,IAAK,MACL,UAAW,OACX,WAAY,OACZ,UAAW,gCACX,SAAU,MACZ,EACA,eAAgB,CACd,WAAY,OACZ,OAAQ,wBACR,OAAQ,UACR,SAAU,OACV,QAAS,UACT,aAAc,MACd,WAAY,sDACd,EACA,uBAAwB,CACtB,YAAa,qBACb,gBAAiB,qBACnB,EACA,WAAY,CACV,UAAW,SACX,QAAS,YACT,SAAU,MACZ,EACA,UAAW,CACT,UAAW,SACX,QAAS,YACT,SAAU,MACZ,CACF,EAEMC,EAAc,CAClB,MAAO,CACL,UAAW,CACT,gBAAiB,UACjB,MAAO,SACT,EACA,YAAa,CACX,gBAAiB,UACjB,OAAQ,oBACR,MAAO,SACT,EACA,KAAM,CACJ,gBAAiB,UACjB,OAAQ,mBACV,EACA,aAAc,CACZ,UAAW,gCACb,EACA,SAAU,CACR,gBAAiB,cACjB,MAAO,SACT,EACA,cAAe,CACb,gBAAiB,SACnB,EACA,OAAQ,CACN,MAAO,SACT,EACA,SAAU,CACR,gBAAiB,UACjB,MAAO,SACT,EACA,eAAgB,CACd,MAAO,SACT,EACA,WAAY,CACV,MAAO,SACT,EACA,eAAgB,CACd,MAAO,SACT,CACF,EACA,KAAM,CACJ,UAAW,CACT,gBAAiB,UACjB,MAAO,SACT,EACA,YAAa,CACX,gBAAiB,UACjB,OAAQ,oBACR,MAAO,SACT,EACA,KAAM,CACJ,gBAAiB,UACjB,OAAQ,mBACV,EACA,aAAc,CACZ,UAAW,+BACb,EACA,SAAU,CACR,gBAAiB,cACjB,MAAO,SACT,EACA,cAAe,CACb,gBAAiB,SACnB,EACA,OAAQ,CACN,MAAO,SACT,EACA,SAAU,CACR,gBAAiB,UACjB,MAAO,SACT,EACA,eAAgB,CACd,MAAO,SACT,EACA,WAAY,CACV,MAAO,SACT,EACA,eAAgB,CACd,MAAO,SACT,CACF,CACF,EAgBA,SAASC,GAAQ,CACf,KAAAC,EACA,WAAAC,EACA,SAAAC,EACA,MAAAC,EACA,eAAAP,EACA,cAAAQ,EACA,WAAAC,CACF,EAAiB,CACf,GAAM,CAACC,EAAWC,CAAY,EAAIC,EAAS,EAAK,EAC1CC,EAASX,EAAYK,CAAK,EAC1B,CAAE,SAAAO,EAAU,OAAApB,CAAO,EAAIU,EAAK,OAE5BW,EAAiC,CACrC,GAAGd,EAAW,KACd,GAAGY,EAAO,KACV,GAAIR,EAAaQ,EAAO,aAAe,CAAC,CAC1C,EAEMG,EAAqC,CACzC,GAAGf,EAAW,SACd,GAAGY,EAAO,SACV,GAAIH,EAAYG,EAAO,cAAgB,CAAC,CAC1C,EAEMI,EAAoC,CACxC,GAAGhB,EAAW,QACd,UAAWI,EAAa,iBAAmB,cAC7C,EAEMa,EAAmC,CACvC,GAAGjB,EAAW,OACd,GAAGY,EAAO,OACV,UAAWR,EAAa,QAAU,IAClC,cAAeA,EAAa,OAAS,GACvC,EAEMc,EAAqC,CACzC,GAAGlB,EAAW,SACd,GAAGY,EAAO,cACZ,EAEA,OACEO,EAAC,OAAI,MAAOL,EAAW,mBAAkBX,EAAK,OAAO,GACnD,UAAAgB,EAAC,UACC,MAAOJ,EACP,QAASV,EACT,aAAc,IAAMK,EAAa,EAAI,EACrC,aAAc,IAAMA,EAAa,EAAK,EACtC,gBAAeN,EAEf,UAAAT,EAAC,QAAM,SAAAkB,EAAS,EAChBlB,EAAC,QAAK,MAAOqB,EAAe,kBAAS,GACvC,EACAG,EAAC,OAAI,MAAOF,EAAa,cAAa,CAACb,EACpC,UAAAV,GAAaD,CAAM,EAGnBW,GAAcL,GACboB,EAAC,OAAI,MAAOD,EACV,UAAAvB,EAAC,QAAM,SAAAG,GAAkBC,CAAc,EAAE,EACzCJ,EAAC,UACC,MAAO,CACL,GAAGK,EAAW,eACd,GAAIO,IAAkB,KAAOP,EAAW,uBAAyB,CAAC,CACpE,EACA,aAAW,YACX,QAAS,IAAMQ,EAAWL,EAAK,OAAO,GAAIU,EAAU,IAAI,EAEvD,qBACH,EACAlB,EAAC,UACC,MAAO,CACL,GAAGK,EAAW,eACd,GAAIO,IAAkB,OAASP,EAAW,uBAAyB,CAAC,CACtE,EACA,aAAW,cACX,QAAS,IAAMQ,EAAWL,EAAK,OAAO,GAAIU,EAAU,MAAM,EAEzD,qBACH,GACF,GAEJ,GACF,CAEJ,CAeO,SAASO,GAAU,CAAE,OAAAC,EAAQ,QAAAC,EAAS,WAAAC,CAAW,EAAmB,CAEzE,GAAM,CAAC,CAAEC,CAAW,EAAIC,EAAYC,GAAMA,EAAI,EAAG,CAAC,EAG5C,CAACC,EAAaC,CAAc,EAAIjB,EAAsB,IAAI,GAAK,EAG/D,CAACkB,EAAaC,CAAc,EAAInB,EAAS,EAAE,EAG3C,CAACoB,EAAeC,CAAgB,EAAIrB,EAAqC,IAAI,GAAK,EAGlFZ,EAAiBkC,EAAQ,IAAMrC,GAAsByB,EAAO,QAAQ,EAAG,CAACA,EAAO,QAAQ,CAAC,EAG9Fa,EAAU,IACYZ,EAAQ,QAAQ,UAAU,IAAM,CAClDE,EAAY,CACd,CAAC,EAEA,CAACF,EAAQ,OAAO,CAAC,EAGpB,IAAMa,EAAmBF,EACvB,IACEZ,EAAO,QAAQ,OAAQe,GAEhBA,EAAE,SAGQd,EAAQ,aAAsBc,EAAE,QAAQ,EACzC,MAJU,EAKzB,EACH,CAACf,EAAO,QAASC,CAAO,CAC1B,EAGMe,EAAmBJ,EAAQ,IAC3BZ,EAAO,WAAa,WACf,CAAC,GAAGc,CAAgB,EAAE,KAC3B,CAACG,EAAGC,KAAOA,EAAE,OAAO,UAAY,IAAMD,EAAE,OAAO,UAAY,EAC7D,EAGKH,EACN,CAACA,EAAkBd,EAAO,QAAQ,CAAC,EAGhCmB,EAAoBP,EAAQ,IAAM,CACtC,GAAI,CAACZ,EAAO,YAAc,CAACQ,EAAY,KAAK,EAC1C,OAAOQ,EAGT,IAAMI,EAAQZ,EAAY,YAAY,EACtC,OAAOQ,EAAiB,OACrBD,GACCA,EAAE,OAAO,SAAS,YAAY,EAAE,SAASK,CAAK,GAC9CjD,GAAc4C,EAAE,OAAO,MAAM,EAAE,YAAY,EAAE,SAASK,CAAK,GAC3DL,EAAE,OAAO,UAAU,YAAY,EAAE,SAASK,CAAK,CACnD,CACF,EAAG,CAACJ,EAAkBR,EAAaR,EAAO,UAAU,CAAC,EAG/CqB,EAAiBT,EAAQ,IAAM,CACnC,IAAMU,EAAS,IAAI,IACnB,QAAWP,KAAKI,EAAmB,CACjC,IAAMI,EAAMR,EAAE,OAAO,SAChBO,EAAO,IAAIC,CAAG,GACjBD,EAAO,IAAIC,EAAK,CAAC,CAAC,EAEpBD,EAAO,IAAIC,CAAG,EAAG,KAAKR,CAAC,CACzB,CACA,OAAOO,CACT,EAAG,CAACH,CAAiB,CAAC,EAGhBK,EAAgBZ,EACpB,IAAMO,EAAkB,KAAMJ,GAAMA,EAAE,OAAO,QAAQ,EACrD,CAACI,CAAiB,CACpB,EAGMM,EAAgBb,EAAQ,IACxBZ,EAAO,QAAU,OAAeA,EAAO,MAGvC,OAAO,OAAW,KACb,OAAO,aAAa,8BAA8B,EAAE,QAAU,OAEhE,QACN,CAACA,EAAO,KAAK,CAAC,EAGX0B,EAAeC,EAClBC,GAAe,CACdrB,EAAgBsB,GAAS,CACvB,IAAMC,EAAO,IAAI,IAAID,CAAI,EAEzB,OAAI7B,EAAO,iBAAmB,SAExB6B,EAAK,IAAID,CAAE,EACN,IAAI,IAEN,IAAI,IAAI,CAACA,CAAE,CAAC,GAGjBC,EAAK,IAAID,CAAE,EACbE,EAAK,OAAOF,CAAE,EAEdE,EAAK,IAAIF,CAAE,EAENE,EACT,CAAC,EAGD7B,EAAQ,OAAO,QAAQ,cAAe,CACpC,WAAAC,EACA,WAAY0B,EACZ,SAAU,CAACtB,EAAY,IAAIsB,CAAE,EAC7B,UAAW,KAAK,IAAI,CACtB,CAAC,CACH,EACA,CAAC5B,EAAO,eAAgBC,EAAQ,OAAQC,EAAYI,CAAW,CACjE,EAGMyB,EAAiBJ,EACrB,CAACK,EAAgBxC,EAAkByC,IAAyB,CAC1DtB,EAAkBkB,GAAS,CACzB,IAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAAC,EAAK,IAAIE,EAAQC,CAAK,EACfH,CACT,CAAC,EAED7B,EAAQ,OAAO,QAAQ,eAAgB,CACrC,OAAA+B,EACA,SAAAxC,EACA,MAAAyC,CACF,CAAC,CACH,EACA,CAAChC,EAAQ,MAAM,CACjB,EAGMiC,EAAsC,CAC1C,GAAGvD,EAAW,UACd,GAAGC,EAAY6C,CAAa,EAAE,SAChC,EAEMU,EAAwC,CAC5C,GAAGxD,EAAW,YACd,GAAGC,EAAY6C,CAAa,EAAE,WAChC,EAEMW,EAAuC,CAC3C,GAAGzD,EAAW,WACd,GAAGC,EAAY6C,CAAa,EAAE,UAChC,EAEMY,EAA2C,CAC/C,GAAG1D,EAAW,eACd,GAAGC,EAAY6C,CAAa,EAAE,cAChC,EAGMa,EAAeC,GACnBA,EAAM,IAAKxB,GACTzC,EAACO,GAAA,CAEC,KAAMkC,EACN,WAAYT,EAAY,IAAIS,EAAE,OAAO,EAAE,EACvC,SAAU,IAAMW,EAAaX,EAAE,OAAO,EAAE,EACxC,MAAOU,EACP,eAAgB/C,EAChB,cAAegC,EAAc,IAAIK,EAAE,OAAO,EAAE,EAC5C,WAAYgB,GAPPhB,EAAE,OAAO,EAQhB,CACD,EAGH,OAAID,EAAiB,SAAW,EAE5BxC,EAAC,OAAI,MAAO4D,EAAgB,mBAAkBhC,EAAY,qBAAmB,eAC3E,SAAA5B,EAAC,OAAI,MAAO8D,EAAiB,uCAA2B,EAC1D,EAKFtC,EAAC,OAAI,MAAOoC,EAAgB,mBAAkBhC,EAAY,qBAAmB,eAE1E,UAAAF,EAAO,YACN1B,EAAC,OAAI,MAAOK,EAAW,cACrB,SAAAL,EAAC,SACC,KAAK,OACL,YAAY,sBACZ,MAAOkC,EACP,SAAWgC,GAAM/B,EAAe+B,EAAE,OAAO,KAAK,EAC9C,MAAOL,EACT,EACF,EAIF7D,EAAC,OAAI,MAAOK,EAAW,UACpB,SAAA6C,EACG,MAAM,KAAKH,EAAe,QAAQ,CAAC,EAAE,IAAI,CAAC,CAACoB,EAAUF,CAAK,IACxDzC,EAAC4C,EAAM,SAAN,CACE,UAAAD,GACCnE,EAAC,OAAI,MAAO+D,EAAqB,uBAAsBI,EACpD,SAAAA,EACH,EAEDH,EAAYC,CAAK,IANCE,GAAY,aAOjC,CACD,EACDH,EAAYnB,CAAiB,EACnC,EAGCnB,EAAO,YAAcmB,EAAkB,SAAW,GAAKX,GACtDV,EAAC,OAAI,MAAO,CAAE,GAAGnB,EAAW,UAAW,GAAGC,EAAY6C,CAAa,EAAE,UAAW,EAAG,0CAC9CjB,EAAY,KACjD,GAEJ,CAEJ,CASO,IAAMmC,GAAqB,CAChC,MACEC,EACA5C,EACA,CACA,GAAM,CACJ,QAAAC,EACA,WAAAC,EAAa,aACb,GAAG2C,CACL,EAAI7C,GAAU,CACZ,eAAgB,SAChB,WAAY,GACZ,MAAO,OACP,QAAS,CAAC,CACZ,EAGA,GAAIC,GAAW,OAAO6C,GAAe,WAAY,CAC/C,IAAMC,EAAOD,EAAWF,CAAS,EACjC,OAAAG,EAAK,OACHL,EAAM,cAAc3C,GAAW,CAC7B,OAAQ8C,EACR,QAAS5C,EACT,WAAAC,CACF,CAAC,CACH,EACO,IAAM,CAAE6C,EAAK,QAAQ,CAAG,CACjC,CAGA,IAAMC,EAAaH,EAAwB,SAAW,CAAC,EACvD,OAAAD,EAAU,UAAY;AAAA;AAAA,UAEhBI,EACC,IACEjC,GAAM;AAAA;AAAA,sBAEGA,EAAE,OAAO,QAAQ;AAAA,0DACmB5C,GAAc4C,EAAE,OAAO,MAAM,CAAC;AAAA;AAAA,SAG9E,EACC,KAAK,EAAE,CAAC;AAAA;AAAA,MAIR,IAAM,CACX6B,EAAU,UAAY,EACxB,CACF,CACF,ECzoBO,IAAMK,EAAU,CACrB,GAAI,eACJ,QAAS,QACT,KAAM,gBACN,YACE,sFAKF,UAAWC,GAKX,QAAS,CACP,CACE,GAAI,yBACJ,UAAWC,GACX,SAAU,CACR,KAAM,gBACN,YAAa,kEACb,KAAM,QACR,CACF,CACF,CACF,ECjCO,IAAMC,GAAW,CACtB,GAAI,eACJ,QAASC,EAAQ,QACjB,KAAMA,EAAQ,KACd,YAAaA,EAAQ,YACrB,QAAS,CACP,QAASA,EAAQ,UACjB,QAASA,EAAQ,OACnB,EACA,OAAQ,CAAE,UAAWC,GAAW,MAAOC,EAAY,EACnD,SAAU,CACR,UAAW,EACb,CACF,EAMA,GAAI,OAAO,OAAW,IAAa,CACjC,IAAMC,EAAY,OAAe,OAAO,YACpCA,GAAY,OAAOA,EAAS,UAAa,YAC3CA,EAAS,SAASJ,EAAQ,CAE9B,CAEA,IAAOK,GAAQL",
6
+ "names": ["R", "react_default", "useState", "useEffect", "useMemo", "useCallback", "useRef", "useContext", "useReducer", "createElement", "createContext", "Fragment", "forwardRef", "memo", "lazy", "Suspense", "Children", "isValidElement", "cloneElement", "Component", "PureComponent", "useLayoutEffect", "useId", "truncate", "text", "max", "stripHtml", "html", "getAnswerPreview", "answer", "isRuleStrategy", "s", "describeTrigger", "showWhen", "pages", "anchors", "rule", "condition", "parts", "summarizeFAQItem", "item", "q", "a", "isOwnAction", "action", "_getR", "_jsx", "type", "props", "key", "R", "p", "c", "jsx", "jsxs", "Fragment", "isRuleStrategy", "s", "extractTargetingInfo", "showWhen", "pagePatterns", "anchorSelectors", "rule", "cond", "c", "hasTargeting", "extractFirstPage", "extractFirstAnchor", "getAnswerText", "answer", "flattenItems", "config", "isOwnAction", "q", "i", "summarizeFAQItem", "describeTrigger", "filterConfig", "dismissedKeys", "ownActions", "_", "useDetection", "items", "getCurrentRoute", "detectionMap", "setDetectionMap", "useState", "itemsRef", "useRef", "useEffect", "runDetection", "map", "currentPath", "item", "targeting", "pageMatch", "pattern", "anchorFound", "element", "interval", "DetectionBadge", "found", "jsx", "styles", "FAQEditor", "onChange", "editor", "typedConfig", "setDismissedKeys", "dismissedOpen", "setDismissedOpen", "editingKey", "setEditingKey", "previewMode", "setPreviewMode", "_hoveredKey", "setHoveredKey", "initialConsumed", "allItems", "activeItems", "dismissedItems", "totalQuestions", "foundCount", "handleDismiss", "useCallback", "key", "prev", "next", "handleRestore", "handleCardBodyClick", "handleTriggerClick", "pageUrl", "handleBackToList", "handleBeforeAfter", "mode", "filtered", "handleFieldChange", "index", "field", "value", "otherActions", "a", "updated", "handlePublish", "handleCardHover", "handleCardLeave", "renderEditFields", "it", "jsxs", "e", "editIndex", "editItem", "Fragment", "detection", "editorPanel", "editor_default", "FAQEditor", "resolveItem", "store", "itemId", "itemQuestion", "found", "i", "executeScrollToFaq", "action", "context", "item", "id", "el", "executeToggleFaqItem", "desiredState", "newState", "wasExpanded", "executeUpdateFaq", "items", "position", "order", "executorDefinitions", "RD", "createRoot", "RD", "createPortal", "getAnswerText", "answer", "renderAnswer", "jsx", "resolveFeedbackConfig", "feedback", "getFeedbackPrompt", "feedbackConfig", "baseStyles", "themeStyles", "FAQItem", "item", "isExpanded", "onToggle", "theme", "feedbackValue", "onFeedback", "isHovered", "setIsHovered", "useState", "colors", "question", "itemStyle", "questionStyle", "chevronStyle", "answerStyle", "feedbackStyle", "jsxs", "FAQWidget", "config", "runtime", "instanceId", "forceUpdate", "useReducer", "x", "expandedIds", "setExpandedIds", "searchQuery", "setSearchQuery", "feedbackState", "setFeedbackState", "useMemo", "useEffect", "visibleQuestions", "q", "orderedQuestions", "a", "b", "filteredQuestions", "query", "categoryGroups", "groups", "cat", "hasCategories", "resolvedTheme", "handleToggle", "useCallback", "id", "prev", "next", "handleFeedback", "itemId", "value", "containerStyle", "searchInputStyle", "emptyStateStyle", "categoryHeaderStyle", "renderItems", "items", "e", "category", "react_default", "FAQMountableWidget", "container", "faqConfig", "createRoot", "root", "questions", "runtime", "executorDefinitions", "FAQMountableWidget", "manifest", "runtime", "editor_default", "editorPanel", "registry", "cdn_default"]
7
+ }
@@ -0,0 +1,2 @@
1
+ function p(){return globalThis.__SYNTRO_REACT__}function g(e,t,n){var o=p(),i=t||{},a=i.children;return delete i.children,n!==void 0&&(i.key=n),Array.isArray(a)?o.createElement.apply(null,[e,i].concat(a)):a!==void 0?o.createElement(e,i,a):o.createElement(e,i)}var d=g,m=g,A=(p()||{}).Fragment;function l({config:e,onChange:t,editor:n}){return m("div",{className:"syntro-gamification-editor",children:[d("p",{children:"Gamification editor coming soon..."}),d("p",{children:"Configure badges, points, rewards, and leaderboards."})]})}var u={panel:{title:"Gamification",icon:"\u{1F3AE}",description:"Badges, rewards, and engagement"},component:l};var x=async(e,t)=>{let{badgeId:n}=e;return t.publishEvent("gamification.badge_awarded",{badgeId:n,awardedAt:Date.now()}),{cleanup:()=>{}}},v=async(e,t)=>{let{points:n,reason:o}=e;return t.publishEvent("gamification.points_added",{points:n,reason:o,timestamp:Date.now()}),{cleanup:()=>{}}},w={names:["page_view","button_click"],handler:(e,t)=>{console.log("[Gamification] Event received for badge trigger check")}},s=[{kind:"gamification:awardBadge",executor:x},{kind:"gamification:addPoints",executor:v}],c=[w],r={id:"adaptive-gamification",version:"1.0.0",name:"Gamification",description:"Badges, rewards, points, and engagement mechanics",executors:s,eventHandlers:c};var f={id:"adaptive-gamification",version:r.version,name:r.name,description:r.description,runtime:{actions:s.map(({kind:e,executor:t})=>({kind:e,executor:t})),events:c},editor:u,metadata:{isBuiltIn:!1}};if(typeof window<"u"){let e=window.SynOS?.appRegistry;e&&typeof e.register=="function"&&e.register(f)}var k=f;export{k as default,f as manifest};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["shared-react:react/jsx-runtime", "../../../../adaptives/adaptive-gamification/src/editor.tsx", "../../../../adaptives/adaptive-gamification/src/runtime.ts", "../../../../adaptives/adaptive-gamification/src/cdn.ts"],
4
+ "sourcesContent": ["\n function _getR() { return globalThis.__SYNTRO_REACT__; }\n function _jsx(type, props, key) {\n var R = _getR();\n var p = props || {};\n var c = p.children;\n delete p.children;\n if (key !== undefined) p.key = key;\n return Array.isArray(c)\n ? R.createElement.apply(null, [type, p].concat(c))\n : c !== undefined\n ? R.createElement(type, p, c)\n : R.createElement(type, p);\n }\n export var jsx = _jsx;\n export var jsxs = _jsx;\n export var Fragment = (_getR() || {}).Fragment;\n ", "/**\n * Adaptive Gamification - Editor Module\n *\n * Editor panel for configuring gamification features.\n */\n\nimport type { EditorPanelProps } from './types';\n\n/**\n * Gamification editor panel component.\n */\nexport function GamificationEditor({\n config: _config,\n onChange: _onChange,\n editor: _editor,\n}: EditorPanelProps) {\n return (\n <div className=\"syntro-gamification-editor\">\n <p>Gamification editor coming soon...</p>\n <p>Configure badges, points, rewards, and leaderboards.</p>\n </div>\n );\n}\n\n/**\n * Editor module configuration.\n */\nexport const editor = {\n panel: {\n title: 'Gamification',\n icon: '\uD83C\uDFAE',\n description: 'Badges, rewards, and engagement',\n },\n component: GamificationEditor,\n};\n", "/**\n * Adaptive Gamification - Runtime Module\n *\n * Gamification actions: awardBadge, addPoints.\n * Provides gamification features like badges, points, and rewards.\n */\n\nimport type { ExecutorResult, ActionExecutor } from './types';\n\n// ============================================================================\n// Action Types\n// ============================================================================\n\n/**\n * Award badge action\n */\nexport interface AwardBadgeAction {\n kind: 'gamification:awardBadge';\n badgeId: string;\n anchorId?: string;\n label?: string;\n}\n\n/**\n * Add points action\n */\nexport interface AddPointsAction {\n kind: 'gamification:addPoints';\n points: number;\n reason?: string;\n label?: string;\n}\n\n// ============================================================================\n// Executors\n// ============================================================================\n\n/**\n * Execute an awardBadge action\n *\n * Note: This executor uses publishEvent to track badge awards.\n * State management is handled at the app level via AppContext,\n * not at the action executor level.\n */\nexport const executeAwardBadge: ActionExecutor<AwardBadgeAction> = async (\n action,\n context\n): Promise<ExecutorResult> => {\n const { badgeId } = action;\n\n // Emit telemetry event (state management handled at app level)\n context.publishEvent('gamification.badge_awarded', {\n badgeId,\n awardedAt: Date.now(),\n });\n\n return {\n cleanup: () => {\n // Badge awards are permanent, no cleanup needed\n },\n };\n};\n\n/**\n * Execute an addPoints action\n *\n * Note: This executor uses publishEvent to track points.\n * State management is handled at the app level via AppContext,\n * not at the action executor level.\n */\nexport const executeAddPoints: ActionExecutor<AddPointsAction> = async (\n action,\n context\n): Promise<ExecutorResult> => {\n const { points, reason } = action;\n\n // Emit telemetry event (state management handled at app level)\n context.publishEvent('gamification.points_added', {\n points,\n reason,\n timestamp: Date.now(),\n });\n\n return {\n cleanup: () => {\n // Points are permanent, no cleanup needed\n },\n };\n};\n\n// ============================================================================\n// Event Handlers\n// ============================================================================\n\n/**\n * Event handler for auto-awarding badges based on triggers.\n */\nexport const badgeTriggerHandler = {\n names: ['page_view', 'button_click'],\n handler: (_event: unknown, _ctx: unknown) => {\n // Auto-award badges based on event triggers\n // This would check badge trigger conditions in the config\n console.log('[Gamification] Event received for badge trigger check');\n },\n};\n\n// ============================================================================\n// Executor Definitions for Registration\n// ============================================================================\n\n/**\n * All executors provided by this app.\n * These are registered with the runtime's ExecutorRegistry.\n */\nexport const executors = [\n { kind: 'gamification:awardBadge', executor: executeAwardBadge },\n { kind: 'gamification:addPoints', executor: executeAddPoints },\n] as const;\n\n/**\n * Event handlers provided by this app.\n */\nexport const eventHandlers = [badgeTriggerHandler];\n\n/**\n * App runtime manifest.\n */\nexport const runtime = {\n id: 'adaptive-gamification',\n version: '1.0.0',\n name: 'Gamification',\n description: 'Badges, rewards, points, and engagement mechanics',\n executors,\n eventHandlers,\n};\n", "/**\n * CDN Entry Point for Adaptive Gamification\n *\n * This module is bundled for CDN delivery and self-registers with the global\n * SynOS app registry when loaded dynamically via the AppLoader.\n */\n\nimport { editor } from './editor';\nimport { executors, eventHandlers, runtime } from './runtime';\n\n/**\n * App manifest for registry registration.\n * Follows the AppManifest interface expected by AppLoader/AppRegistry.\n */\nexport const manifest = {\n id: 'adaptive-gamification',\n version: runtime.version,\n name: runtime.name,\n description: runtime.description,\n runtime: {\n actions: executors.map(({ kind, executor }) => ({\n kind,\n executor,\n })),\n events: eventHandlers,\n },\n editor,\n metadata: {\n isBuiltIn: false,\n },\n};\n\n/**\n * Self-register with global registry if available.\n * This happens when loaded via script tag (UMD).\n */\nif (typeof window !== 'undefined') {\n const registry = (window as any).SynOS?.appRegistry;\n if (registry && typeof registry.register === 'function') {\n registry.register(manifest);\n }\n}\n\nexport default manifest;\n"],
5
+ "mappings": "AACY,SAASA,GAAQ,CAAE,OAAO,WAAW,gBAAkB,CACvD,SAASC,EAAKC,EAAMC,EAAOC,EAAK,CAC9B,IAAIC,EAAIL,EAAM,EACVM,EAAIH,GAAS,CAAC,EACdI,EAAID,EAAE,SACV,cAAOA,EAAE,SACLF,IAAQ,SAAWE,EAAE,IAAMF,GACxB,MAAM,QAAQG,CAAC,EAClBF,EAAE,cAAc,MAAM,KAAM,CAACH,EAAMI,CAAC,EAAE,OAAOC,CAAC,CAAC,EAC/CA,IAAM,OACJF,EAAE,cAAcH,EAAMI,EAAGC,CAAC,EAC1BF,EAAE,cAAcH,EAAMI,CAAC,CAC/B,CACO,IAAIE,EAAMP,EACNQ,EAAOR,EACPS,GAAYV,EAAM,GAAK,CAAC,GAAG,SCL3C,SAASW,EAAmB,CACjC,OAAQC,EACR,SAAUC,EACV,OAAQC,CACV,EAAqB,CACnB,OACEC,EAAC,OAAI,UAAU,6BACb,UAAAC,EAAC,KAAE,8CAAkC,EACrCA,EAAC,KAAE,gEAAoD,GACzD,CAEJ,CAKO,IAAMC,EAAS,CACpB,MAAO,CACL,MAAO,eACP,KAAM,YACN,YAAa,iCACf,EACA,UAAWN,CACb,ECUO,IAAMO,EAAsD,MACjEC,EACAC,IAC4B,CAC5B,GAAM,CAAE,QAAAC,CAAQ,EAAIF,EAGpB,OAAAC,EAAQ,aAAa,6BAA8B,CACjD,QAAAC,EACA,UAAW,KAAK,IAAI,CACtB,CAAC,EAEM,CACL,QAAS,IAAM,CAEf,CACF,CACF,EASaC,EAAoD,MAC/DH,EACAC,IAC4B,CAC5B,GAAM,CAAE,OAAAG,EAAQ,OAAAC,CAAO,EAAIL,EAG3B,OAAAC,EAAQ,aAAa,4BAA6B,CAChD,OAAAG,EACA,OAAAC,EACA,UAAW,KAAK,IAAI,CACtB,CAAC,EAEM,CACL,QAAS,IAAM,CAEf,CACF,CACF,EASaC,EAAsB,CACjC,MAAO,CAAC,YAAa,cAAc,EACnC,QAAS,CAACC,EAAiBC,IAAkB,CAG3C,QAAQ,IAAI,uDAAuD,CACrE,CACF,EAUaC,EAAY,CACvB,CAAE,KAAM,0BAA2B,SAAUV,CAAkB,EAC/D,CAAE,KAAM,yBAA0B,SAAUI,CAAiB,CAC/D,EAKaO,EAAgB,CAACJ,CAAmB,EAKpCK,EAAU,CACrB,GAAI,wBACJ,QAAS,QACT,KAAM,eACN,YAAa,oDACb,UAAAF,EACA,cAAAC,CACF,ECxHO,IAAME,EAAW,CACtB,GAAI,wBACJ,QAASC,EAAQ,QACjB,KAAMA,EAAQ,KACd,YAAaA,EAAQ,YACrB,QAAS,CACP,QAASC,EAAU,IAAI,CAAC,CAAE,KAAAC,EAAM,SAAAC,CAAS,KAAO,CAC9C,KAAAD,EACA,SAAAC,CACF,EAAE,EACF,OAAQC,CACV,EACA,OAAAC,EACA,SAAU,CACR,UAAW,EACb,CACF,EAMA,GAAI,OAAO,OAAW,IAAa,CACjC,IAAMC,EAAY,OAAe,OAAO,YACpCA,GAAY,OAAOA,EAAS,UAAa,YAC3CA,EAAS,SAASP,CAAQ,CAE9B,CAEA,IAAOQ,EAAQR",
6
+ "names": ["_getR", "_jsx", "type", "props", "key", "R", "p", "c", "jsx", "jsxs", "Fragment", "GamificationEditor", "_config", "_onChange", "_editor", "jsxs", "jsx", "editor", "executeAwardBadge", "action", "context", "badgeId", "executeAddPoints", "points", "reason", "badgeTriggerHandler", "_event", "_ctx", "executors", "eventHandlers", "runtime", "manifest", "runtime", "executors", "kind", "executor", "eventHandlers", "editor", "registry", "cdn_default"]
7
+ }
@@ -0,0 +1,11 @@
1
+ var u=globalThis.__SYNTRO_REACT__||{},z=u,S=u.useState,A=u.useEffect,H=u.useMemo,x=u.useCallback,D=u.useRef,Ne=u.useContext,U=u.useReducer,Ie=u.createElement,Le=u.createContext,Pe=u.Fragment,_e=u.forwardRef,Me=u.memo,Be=u.lazy,ze=u.Suspense,He=u.Children,De=u.isValidElement,We=u.cloneElement,Fe=u.Component,$e=u.PureComponent,Oe=u.useLayoutEffect,je=u.useId;function V(e,o){return e.length<=o?e:`${e.slice(0,o).trimEnd()}...`}function xe(e){return typeof e=="object"&&e!==null&&e.type==="rules"&&Array.isArray(e.rules)}function X(e){if(!e||!xe(e))return"All pages";let o=[],t=[];for(let s of e.rules)for(let l of s.conditions)l.type==="page_url"&&typeof l.url=="string"&&o.push(l.url),l.type==="anchor_visible"&&typeof l.anchorId=="string"&&t.push(l.anchorId);let i=[];return o.length>0&&i.push(o[0]),t.length>0&&i.push(t[0]),i.length>0?i.join(" \xB7 "):"All pages"}function Y(e){let o=e.config.icon||"\u{1F517}",t=V(e.config.label,30),i=V(e.config.href,30);return`${o} ${t} \u2192 ${i}`}var be=["nav","navigation"];function E(e){return be.some(o=>e.kind.startsWith(`${o}:`))}function q(){return globalThis.__SYNTRO_REACT__}function G(e,o,t){var i=q(),s=o||{},l=s.children;return delete s.children,t!==void 0&&(s.key=t),Array.isArray(l)?i.createElement.apply(null,[e,s].concat(l)):l!==void 0?i.createElement(e,s,l):i.createElement(e,s)}var r=G,d=G,P=(q()||{}).Fragment;function ye(e){return typeof e=="object"&&e!==null&&e.type==="rules"&&Array.isArray(e.rules)}function W(e){if(!e||!ye(e))return{pagePatterns:[],anchorSelectors:[],hasTargeting:!1};let o=new Set,t=new Set;for(let s of e.rules)for(let l of s.conditions){let p=l;p.type==="page_url"&&typeof p.url=="string"?o.add(p.url):p.type==="anchor_visible"&&typeof p.anchorId=="string"&&t.add(p.anchorId)}let i=o.size>0||t.size>0;return{pagePatterns:[...o],anchorSelectors:[...t],hasTargeting:i}}function me(e){return W(e).pagePatterns[0]||null}function he(e){return W(e).anchorSelectors[0]||null}function ke(e){return(e.actions||[]).filter(E).map((t,i)=>({key:String(i),index:i,summary:Y(t),trigger:X(t.showWhen),rationale:t.rationale,firstAnchor:he(t.showWhen),link:t}))}function J(e,o){let t=(e.actions||[]).filter(E);return{...e,actions:t.filter((i,s)=>!o.has(String(s)))}}function we(e,o){let[t,i]=S(new Map),s=D(e);return s.current=e,A(()=>{let l=()=>{let y=new Map,c=o();for(let f of s.current){let m=W(f.link.showWhen),k=!0;m.pagePatterns.length>0&&(k=m.pagePatterns.some(I=>new RegExp(`^${I.replace(/\*\*/g,".*").replace(/(?<!\.)(\*)/g,"[^/]*")}$`).test(c)));let C=!1,R=null;if(f.firstAnchor)try{R=document.querySelector(f.firstAnchor),C=R!==null}catch{}else C=k;y.set(f.key,{found:k&&C,element:R})}i(y)};l();let p=setInterval(l,2e3);return window.addEventListener("popstate",l),()=>{clearInterval(p),window.removeEventListener("popstate",l)}},[o]),t}function Se({found:e}){return r("span",{style:{width:"8px",height:"8px",borderRadius:"50%",backgroundColor:e?"#22c55e":"#475569",flexShrink:0,display:"inline-block"},title:e?"Found on this page":"Not found on this page"})}var a={container:{display:"flex",flexDirection:"column",height:"100%",fontFamily:"system-ui, -apple-system, sans-serif"},header:{padding:"16px",borderBottom:"1px solid #334155",display:"flex",alignItems:"center",gap:"12px"},backButton:{padding:"6px 12px",borderRadius:"6px",border:"none",backgroundColor:"rgba(255,255,255,0.05)",color:"#94a3b8",fontSize:"13px",cursor:"pointer"},title:{margin:0,fontSize:"15px",fontWeight:600,color:"#f8fafc"},subtitle:{margin:"2px 0 0 0",fontSize:"11px",color:"#64748b"},body:{flex:1,overflow:"auto",padding:"16px"},groupHeader:{fontSize:"11px",fontWeight:700,color:"#64748b",textTransform:"uppercase",letterSpacing:"0.06em",padding:"4px 0 8px 0",display:"flex",alignItems:"center",justifyContent:"space-between"},groupCount:{fontSize:"10px",color:"#475569",backgroundColor:"rgba(255,255,255,0.06)",padding:"2px 6px",borderRadius:"8px"},card:{padding:"8px 10px",borderRadius:"6px",border:"1px solid rgba(255,255,255,0.06)",background:"rgba(255,255,255,0.02)",marginBottom:"4px",fontSize:"13px",color:"#e2e8f0"},triggerLine:{display:"flex",alignItems:"center",gap:"4px",fontSize:"11px",color:"#94a3b8",cursor:"pointer",marginBottom:"4px"},cardBody:{display:"flex",alignItems:"center",gap:"8px",cursor:"pointer"},cardText:{flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},rationaleLine:{fontSize:"10px",color:"#64748b",marginTop:"4px"},dismissButton:{padding:"2px 6px",borderRadius:"4px",border:"none",background:"transparent",color:"#64748b",fontSize:"14px",cursor:"pointer",flexShrink:0,lineHeight:1},dismissedSection:{marginTop:"16px",cursor:"pointer",userSelect:"none"},dismissedHeader:{fontSize:"11px",fontWeight:600,color:"#475569",display:"flex",alignItems:"center",gap:"6px"},dismissedCard:{display:"flex",alignItems:"center",gap:"8px",padding:"6px 10px",borderRadius:"6px",border:"1px solid rgba(255,255,255,0.03)",background:"transparent",marginBottom:"3px",cursor:"pointer",fontSize:"12px",color:"#475569",opacity:.6},emptyState:{textAlign:"center",padding:"32px 16px",color:"#64748b",fontSize:"13px"},footer:{padding:"12px 16px",borderTop:"1px solid #334155",display:"flex",gap:"8px"},saveButton:{flex:1,padding:"10px",borderRadius:"8px",border:"none",background:"rgba(59, 130, 246, 0.15)",color:"#3b82f6",fontSize:"13px",fontWeight:600,cursor:"pointer"},publishButton:{flex:1,padding:"10px",borderRadius:"8px",border:"none",background:"#22c55e",color:"white",fontSize:"13px",fontWeight:600,cursor:"pointer"},editForm:{padding:"4px 0"},editHeader:{display:"flex",alignItems:"center",gap:"8px",marginBottom:"12px",fontSize:"13px",fontWeight:600,color:"#e2e8f0"},editLabel:{fontSize:"11px",fontWeight:600,color:"#64748b",marginBottom:"4px",display:"block"},editInput:{width:"100%",padding:"6px 8px",borderRadius:"4px",border:"1px solid rgba(255,255,255,0.1)",background:"rgba(255,255,255,0.04)",color:"#e2e8f0",fontSize:"12px",fontFamily:"inherit",marginBottom:"8px",boxSizing:"border-box"},editRationale:{padding:"8px",borderRadius:"4px",border:"1px dashed rgba(255,255,255,0.15)",background:"rgba(255,255,255,0.02)",color:"#94a3b8",fontSize:"12px",marginBottom:"8px"},editBackButton:{padding:"6px 12px",borderRadius:"6px",border:"1px solid rgba(255,255,255,0.1)",background:"transparent",color:"#94a3b8",fontSize:"12px",cursor:"pointer",marginTop:"8px"},editCheckbox:{display:"flex",alignItems:"center",gap:"8px",fontSize:"12px",color:"#94a3b8",marginBottom:"8px"}};function Ce({config:e,onChange:o,editor:t}){let i=e,[s,l]=S(new Set),[p,y]=S(!1),[c,f]=S(null),[m,k]=S("after"),[C,R]=S(null),I=D(!1);A(()=>{!I.current&&(t.initialEditKey!=null||t.initialCreate)&&(I.current=!0,t.clearInitialState?.())},[t]);let w=ke(i),T=w.filter(n=>!s.has(n.key)),M=w.filter(n=>s.has(n.key)),B=T.length,O=we(w,t.getCurrentRoute),re=T.filter(n=>O.get(n.key)?.found).length,ie=x(n=>{l(v=>{let g=new Set(v);return g.add(n),g}),c===n&&f(null)},[c]),ae=x(n=>{l(v=>{let g=new Set(v);return g.delete(n),g})},[]),se=x(n=>{f(n.key)},[]),j=x(n=>{let v=me(n.link.showWhen);v&&t.navigateTo(v),n.firstAnchor&&t.highlightElement(n.firstAnchor)},[t]),le=x(()=>{f(null),k("after"),t.previewConfig(e),t.clearHighlight()},[t,e]),K=x(n=>{if(k(n),n==="before"){let v=J(i,new Set([c]));t.previewConfig(v)}else t.previewConfig(e)},[i,c,t,e]),L=x((n,v,g)=>{let h=(i.actions||[]).filter(E).slice(),b={...h[n],config:{...h[n].config}};b.config[v]=g,h[n]=b;let ge=(i.actions||[]).filter(ve=>!E(ve)),fe={...i,actions:[...ge,...h]};o(fe),t.setDirty(!0)},[i,o,t]),ce=x(()=>{if(s.size>0){let n=J(i,s);o(n)}t.publish()},[s,i,o,t]),pe=x(n=>{R(n.key),n.firstAnchor&&t.highlightElement(n.firstAnchor)},[t]),de=x(()=>{R(null),t.clearHighlight()},[t]),ue=n=>{let g=(i.actions||[]).filter(E)[n];if(!g)return null;let h=w.find(b=>b.key===String(n));return d("div",{style:a.editForm,children:[h&&h.trigger!=="All pages"&&d("div",{"data-trigger":!0,style:a.triggerLine,onClick:()=>j(h),children:[r("span",{children:"\u{1F4CD}"}),r("span",{children:h.trigger})]}),r("label",{style:a.editLabel,children:"Label"}),r("input",{style:a.editInput,value:g.config.label,onChange:b=>L(n,"label",b.target.value)}),r("label",{style:a.editLabel,children:"URL"}),r("input",{style:a.editInput,value:g.config.href,onChange:b=>L(n,"href",b.target.value)}),r("label",{style:a.editLabel,children:"Icon"}),r("input",{style:a.editInput,value:g.config.icon||"",onChange:b=>L(n,"icon",b.target.value),placeholder:"e.g., \\u{1f3e0}"}),d("label",{style:a.editCheckbox,children:[r("input",{type:"checkbox",checked:g.config.external||!1,onChange:b=>L(n,"external",b.target.checked)}),"Open in new tab"]}),r("label",{style:a.editLabel,children:"AI Rationale"}),r("div",{style:a.editRationale,children:g.rationale?g.rationale.why:"N/A"})]})};return d("div",{style:a.container,children:[d("div",{style:a.header,children:[r("button",{onClick:()=>t.navigateHome(),style:a.backButton,children:"\u2190 Back"}),d("div",{children:[r("h2",{style:a.title,children:"Navigation Links"}),d("p",{style:a.subtitle,children:[B," link",B!==1?"s":"",B>0&&` (${re} found on this page)`]})]})]}),r("div",{style:a.body,children:c!==null?(()=>{let n=Number(c),v=w.find(g=>g.key===c);return d(P,{children:[d("div",{style:a.editHeader,children:[r("span",{children:"\u{1F517}"}),r("span",{children:v?.summary})]}),d("div",{style:{display:"flex",gap:"0",marginBottom:"12px",borderRadius:"6px",overflow:"hidden",border:"1px solid rgba(255,255,255,0.1)"},children:[r("button",{onClick:()=>K("before"),style:{flex:1,padding:"6px 12px",border:"none",fontSize:"12px",fontWeight:600,cursor:"pointer",background:m==="before"?"rgba(59,130,246,0.2)":"transparent",color:m==="before"?"#3b82f6":"#64748b"},children:"Before"}),r("button",{onClick:()=>K("after"),style:{flex:1,padding:"6px 12px",border:"none",borderLeft:"1px solid rgba(255,255,255,0.1)",fontSize:"12px",fontWeight:600,cursor:"pointer",background:m==="after"?"rgba(59,130,246,0.2)":"transparent",color:m==="after"?"#3b82f6":"#64748b"},children:"After"})]}),ue(n),r("button",{style:a.editBackButton,onClick:le,children:"\u2190 List"})]})})():d(P,{children:[w.length===0&&r("div",{style:a.emptyState,children:"No links configured."}),T.length>0&&d(P,{children:[d("div",{style:a.groupHeader,children:[r("span",{children:"NAV"}),r("span",{style:a.groupCount,children:T.length})]}),T.map(n=>{let v=O.get(n.key);return d("div",{style:a.card,"data-item-key":n.key,onMouseEnter:()=>pe(n),onMouseLeave:de,children:[n.trigger!=="All pages"&&d("div",{"data-trigger":!0,style:a.triggerLine,onClick:g=>{g.stopPropagation(),j(n)},children:[r("span",{children:"\u{1F4CD}"}),r("span",{children:n.trigger})]}),d("div",{"data-card-body":!0,style:a.cardBody,onClick:()=>se(n),children:[r(Se,{found:v?.found??!1}),r("span",{style:a.cardText,children:n.summary}),r("button",{style:a.dismissButton,onClick:g=>{g.stopPropagation(),ie(n.key)},title:"Dismiss this link",children:"\xD7"})]}),d("div",{style:a.rationaleLine,children:["WHY: ",n.rationale?n.rationale.why:"N/A"]})]},n.key)})]}),M.length>0&&d("div",{style:a.dismissedSection,children:[d("div",{style:{...a.dismissedHeader,cursor:"pointer"},onClick:()=>y(!p),children:[r("span",{children:p?"\u25BE":"\u25B8"}),d("span",{children:["Dismissed (",M.length,")"]})]}),p&&r("div",{style:{marginTop:"6px"},children:M.map(n=>d("div",{style:a.dismissedCard,children:[r("span",{style:{...a.cardText,textDecoration:"line-through"},children:n.summary}),r("button",{style:{...a.dismissButton,color:"#3b82f6",fontSize:"11px"},onClick:v=>{v.stopPropagation(),ae(n.key)},children:"Restore"})]},n.key))})]})]})}),d("div",{style:a.footer,children:[r("button",{onClick:()=>t.save(),style:a.saveButton,children:"Save Draft"}),r("button",{onClick:ce,style:a.publishButton,children:"Publish"})]})]})}var Q={title:"Navigation",icon:"\u{1F517}",description:"Navigation link list with per-item visibility"};var Z=Ce;var ee=globalThis.__SYNTRO_REACT_DOM__;var F=ee?.createRoot,et=ee?.createPortal;var _={nav:{display:"flex",gap:"4px",padding:"8px",fontFamily:"system-ui, -apple-system, sans-serif"},link:{display:"flex",alignItems:"center",gap:"6px",padding:"8px 12px",borderRadius:"6px",textDecoration:"none",fontSize:"14px",fontWeight:500,transition:"background-color 0.15s ease, color 0.15s ease",cursor:"pointer",border:"none",background:"transparent"},icon:{fontSize:"16px"},externalIcon:{fontSize:"12px",opacity:.6}},te={light:{nav:{backgroundColor:"#ffffff"},link:{color:"#374151"},linkHover:{backgroundColor:"#f3f4f6",color:"#111827"}},dark:{nav:{backgroundColor:"#1f2937"},link:{color:"#d1d5db"},linkHover:{backgroundColor:"#374151",color:"#f9fafb"}}};function Re({link:e,theme:o,onNavigate:t}){let[i,s]=z.useState(!1),{label:l,href:p,icon:y,external:c}=e.config,f=te[o],m={..._.link,...f.link,...i?f.linkHover:{}};return d("a",{href:p,onClick:C=>{C.preventDefault(),t(p,c??!1)},style:m,onMouseEnter:()=>s(!0),onMouseLeave:()=>s(!1),target:c?"_blank":void 0,rel:c?"noopener noreferrer":void 0,children:[y&&r("span",{style:_.icon,children:y}),r("span",{children:l}),c&&r("span",{style:_.externalIcon,children:"\u2197"})]})}function Ee({config:e,runtime:o,instanceId:t}){let[,i]=U(c=>c+1,0);A(()=>o.context.subscribe(()=>{i()}),[o.context]);let s=H(()=>e.actions.filter(c=>c.showWhen?o.evaluateSync(c.showWhen).value:!0),[e.actions,o]),l=H(()=>e.theme!=="auto"?e.theme:typeof window<"u"&&window.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light",[e.theme]),p=x((c,f)=>{o.events.publish("nav:click",{instanceId:t,href:c,external:f,timestamp:Date.now()}),f?window.open(c,"_blank","noopener,noreferrer"):window.location.href=c},[o.events,t]),y={..._.nav,...te[l].nav,flexDirection:e.layout==="vertical"?"column":"row"};return s.length===0?null:r("nav",{style:y,"data-adaptive-id":t,"data-adaptive-type":"adaptive-nav",children:s.map((c,f)=>r(Re,{link:c,theme:l,onNavigate:p},c.config.href+f))})}var ne={mount(e,o){let{runtime:t,instanceId:i="nav-widget",...s}=o||{layout:"horizontal",theme:"auto",actions:[]};if(t&&typeof F=="function"){let p=F(e);return p.render(z.createElement(Ee,{config:s,runtime:t,instanceId:i})),()=>{p.unmount()}}let l=s.actions||[];return e.innerHTML=`
2
+ <nav style="display: flex; gap: 8px; padding: 8px; font-family: system-ui;">
3
+ ${l.map(p=>`
4
+ <a href="${p.config.href}" style="padding: 8px 12px; text-decoration: none; color: #374151;">
5
+ ${p.config.icon?`<span>${p.config.icon}</span>`:""}
6
+ ${p.config.label}
7
+ </a>
8
+ `).join("")}
9
+ </nav>
10
+ `,()=>{e.innerHTML=""}}};var Te=async(e,o)=>{let t=o.resolveAnchor(e.anchorId);if(!t)throw new Error(`Anchor not found: ${e.anchorId}`);return t.scrollIntoView({behavior:e.behavior??"smooth",block:e.block??"center",inline:e.inline??"nearest"}),o.publishEvent("action.applied",{id:o.generateId(),kind:"navigation:scrollTo",anchorId:e.anchorId,behavior:e.behavior??"smooth"}),{cleanup:()=>{}}},Ae=async(e,o)=>{let t=e.url.trim();if(t.toLowerCase().startsWith("javascript:"))throw new Error("javascript: URLs are not allowed");let i=e.target??"_self";return o.publishEvent("action.applied",{id:o.generateId(),kind:"navigation:navigate",url:e.url,target:i}),i==="_blank"?window.open(t,"_blank","noopener,noreferrer"):window.location.href=t,{cleanup:()=>{}}},$=[{kind:"navigation:scrollTo",executor:Te},{kind:"navigation:navigate",executor:Ae}],N={id:"adaptive-nav",version:"1.0.0",name:"Navigation Links",description:"Navigation actions and widget-based link list with per-item conditional visibility",executors:$,widgets:[{id:"adaptive-nav:links",component:ne,metadata:{name:"Navigation Links",description:"Horizontal or vertical navigation link list",icon:"\u{1F517}"}}]};var oe={id:"adaptive-nav",version:N.version,name:N.name,description:N.description,runtime:{actions:$.map(({kind:e,executor:o})=>({kind:e,executor:o})),widgets:N.widgets},editor:{component:Z,panel:Q},metadata:{isBuiltIn:!1}};if(typeof window<"u"){let e=window.SynOS?.appRegistry;e&&typeof e.register=="function"&&e.register(oe)}var pt=oe;export{pt as default,oe as manifest};
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["shared-react:react", "../../../../adaptives/adaptive-nav/src/summarize.ts", "../../../../adaptives/adaptive-nav/src/types.ts", "shared-react:react/jsx-runtime", "../../../../adaptives/adaptive-nav/src/editor.tsx", "shared-react:react-dom/client", "../../../../adaptives/adaptive-nav/src/NavWidget.tsx", "../../../../adaptives/adaptive-nav/src/runtime.ts", "../../../../adaptives/adaptive-nav/src/cdn.ts"],
4
+ "sourcesContent": ["\n var R = globalThis.__SYNTRO_REACT__ || {};\n export default R;\n export var useState = R.useState;\n export var useEffect = R.useEffect;\n export var useMemo = R.useMemo;\n export var useCallback = R.useCallback;\n export var useRef = R.useRef;\n export var useContext = R.useContext;\n export var useReducer = R.useReducer;\n export var createElement = R.createElement;\n export var createContext = R.createContext;\n export var Fragment = R.Fragment;\n export var forwardRef = R.forwardRef;\n export var memo = R.memo;\n export var lazy = R.lazy;\n export var Suspense = R.Suspense;\n export var Children = R.Children;\n export var isValidElement = R.isValidElement;\n export var cloneElement = R.cloneElement;\n export var Component = R.Component;\n export var PureComponent = R.PureComponent;\n export var useLayoutEffect = R.useLayoutEffect;\n export var useId = R.useId;\n ", "/**\n * Human-readable summary generation for Nav items.\n * Pure functions \u2014 no DOM access, just string formatting.\n */\n\nimport type { NavLinkAction, DecisionStrategy, RuleStrategy } from './types';\n\nconst MAX_LABEL_LEN = 30;\nconst MAX_HREF_LEN = 30;\n\nfunction truncate(text: string, max: number): string {\n if (text.length <= max) return text;\n return `${text.slice(0, max).trimEnd()}...`;\n}\n\nfunction isRuleStrategy(s: unknown): s is RuleStrategy<boolean> {\n return (\n typeof s === 'object' &&\n s !== null &&\n (s as Record<string, unknown>).type === 'rules' &&\n Array.isArray((s as Record<string, unknown>).rules)\n );\n}\n\n/**\n * Parse a showWhen strategy into a human-readable trigger description.\n */\nexport function describeTrigger(showWhen?: DecisionStrategy<boolean> | null): string {\n if (!showWhen) return 'All pages';\n if (!isRuleStrategy(showWhen)) return 'All pages';\n\n const pages: string[] = [];\n const anchors: string[] = [];\n\n for (const rule of showWhen.rules) {\n for (const condition of rule.conditions) {\n if (condition.type === 'page_url' && typeof (condition as any).url === 'string') {\n pages.push((condition as any).url);\n }\n if (condition.type === 'anchor_visible' && typeof (condition as any).anchorId === 'string') {\n anchors.push((condition as any).anchorId);\n }\n }\n }\n\n const parts: string[] = [];\n if (pages.length > 0) parts.push(pages[0]);\n if (anchors.length > 0) parts.push(anchors[0]);\n\n return parts.length > 0 ? parts.join(' \\u00b7 ') : 'All pages';\n}\n\n/**\n * Generate a one-liner summary for a Nav link.\n */\nexport function summarizeNavItem(item: NavLinkAction): string {\n const icon = item.config.icon || '\\u{1f517}';\n const label = truncate(item.config.label, MAX_LABEL_LEN);\n const href = truncate(item.config.href, MAX_HREF_LEN);\n return `${icon} ${label} \\u2192 ${href}`;\n}\n", "/**\n * Adaptive Nav - Types\n *\n * Type definitions for the navigation link list adaptive.\n * Demonstrates compositional action pattern with per-item showWhen.\n */\n\n// ============================================================================\n// Decision Strategy Types (from runtime-sdk)\n// ============================================================================\n\n/**\n * Simplified DecisionStrategy type for this package.\n * Full definition is in @syntrologie/runtime-sdk.\n */\nexport type DecisionStrategy<T = unknown> =\n | RuleStrategy<T>\n | ScoreStrategy<T>\n | ModelStrategy<T>\n | ExternalStrategy<T>;\n\nexport interface RuleStrategy<T = unknown> {\n type: 'rules';\n rules: Array<{\n conditions: Array<Record<string, unknown>>;\n value: T;\n }>;\n default: T;\n}\n\nexport interface ScoreStrategy<T = unknown> {\n type: 'score';\n field: string;\n threshold: number;\n above: T;\n below: T;\n}\n\nexport interface ModelStrategy<T = unknown> {\n type: 'model';\n modelId: string;\n inputs: string[];\n outputMapping: Record<string, T>;\n default: T;\n}\n\nexport interface ExternalStrategy<T = unknown> {\n type: 'external';\n endpoint: string;\n method?: 'GET' | 'POST';\n default: T;\n timeoutMs?: number;\n}\n\n// ============================================================================\n// Nav Link Action Types\n// ============================================================================\n\n/**\n * Single navigation link configuration.\n * This is a \"compositional action\" - it's not executed, but rendered by the parent.\n */\nexport interface NavLinkAction {\n /** Action kind identifier */\n kind: 'nav:link';\n /** Link configuration */\n config: {\n /** Display label for the link */\n label: string;\n /** Target URL */\n href: string;\n /** Optional icon (emoji or icon key) */\n icon?: string;\n /** Whether to open in new tab */\n external?: boolean;\n };\n /** Optional per-item activation strategy */\n showWhen?: DecisionStrategy<boolean> | null;\n /** AI-generated reasoning for why this link was recommended */\n rationale?: {\n why: string;\n confidence?: number;\n };\n}\n\n// ============================================================================\n// Nav Widget Configuration\n// ============================================================================\n\n/**\n * Layout orientation for the navigation links.\n */\nexport type NavLayout = 'horizontal' | 'vertical';\n\n/**\n * Theme for the navigation widget.\n */\nexport type NavTheme = 'light' | 'dark' | 'auto';\n\n/**\n * Full configuration for the adaptive-nav widget.\n */\nexport interface NavConfig {\n /** Layout orientation */\n layout: NavLayout;\n /** Color theme */\n theme: NavTheme;\n /** Navigation links (compositional actions) */\n actions: NavLinkAction[];\n}\n\n// ============================================================================\n// Widget Props Types\n// ============================================================================\n\n/**\n * Runtime services passed to the widget.\n */\nexport interface NavWidgetRuntime {\n /** Synchronously evaluate a decision strategy */\n evaluateSync: <T>(strategy: DecisionStrategy<T>) => { value: T; isFallback: boolean };\n /** Context manager for subscribing to changes */\n context: {\n subscribe: (callback: () => void) => () => void;\n };\n /** Event bus for publishing interactions */\n events: {\n publish: (name: string, props?: Record<string, unknown>) => void;\n };\n}\n\n/**\n * Props passed to the NavWidget component.\n */\nexport interface NavWidgetProps {\n /** Widget configuration */\n config: NavConfig;\n /** Runtime services */\n runtime: NavWidgetRuntime;\n /** Instance ID for telemetry */\n instanceId: string;\n}\n\n// ============================================================================\n// Navigation Action Types (merged from adaptive-navigation)\n// ============================================================================\n\ninterface BaseAction {\n label?: string;\n}\n\nexport interface ScrollToAction extends BaseAction {\n kind: 'navigation:scrollTo';\n anchorId: string;\n behavior?: ScrollBehavior;\n block?: ScrollLogicalPosition;\n inline?: ScrollLogicalPosition;\n}\n\nexport interface NavigateAction extends BaseAction {\n kind: 'navigation:navigate';\n url: string;\n target?: '_self' | '_blank';\n}\n\n// ============================================================================\n// Action Namespace\n// ============================================================================\n\nexport const ACTION_NAMESPACES = ['nav', 'navigation'] as const;\n\n/**\n * Returns true if the action belongs to this adaptive package.\n * Uses prefix matching so new kinds (e.g. nav:dropdown) are automatically included.\n * Covers both `nav:*` (compositional) and `navigation:*` (executor) prefixes.\n */\nexport function isOwnAction(action: { kind: string }): boolean {\n return ACTION_NAMESPACES.some((ns) => action.kind.startsWith(`${ns}:`));\n}\n\n// ============================================================================\n// Executor Types\n// ============================================================================\n\nexport type ExecutorCleanup = () => void | Promise<void>;\nexport type ExecutorUpdate = (changes: Record<string, unknown>) => void | Promise<void>;\n\nexport interface ExecutorResult {\n cleanup: ExecutorCleanup;\n updateFn?: ExecutorUpdate;\n}\n\nexport interface ExecutorContext {\n overlayRoot: HTMLElement;\n resolveAnchor: (anchorId: string) => HTMLElement | null;\n generateId: () => string;\n publishEvent: (name: string, props?: Record<string, unknown>) => void;\n adaptiveId?: string;\n}\n\nexport type ActionExecutor<T> = (action: T, context: ExecutorContext) => Promise<ExecutorResult>;\n\n// ============================================================================\n// Editor Types\n// ============================================================================\n\nexport interface EditorPanelProps {\n config: Record<string, unknown>;\n onChange: (config: Record<string, unknown>) => void;\n editor: {\n setDirty: (dirty: boolean) => void;\n navigateHome: () => Promise<boolean>;\n save: () => Promise<void>;\n publish: (captureScreenshot?: boolean) => Promise<void>;\n navigateTo: (route: string) => Promise<void>;\n highlightElement: (selector: string) => void;\n clearHighlight: () => void;\n getCurrentRoute: () => string;\n previewConfig: (config: Record<string, unknown>) => void;\n /** Flat action index to open in edit mode (from accordion navigation). */\n initialEditKey?: string;\n /** Open the editor in create mode. */\n initialCreate?: boolean;\n /** Clear the initial navigation state (call after consuming). */\n clearInitialState?: () => void;\n };\n platformClient?: unknown;\n}\n", "\n function _getR() { return globalThis.__SYNTRO_REACT__; }\n function _jsx(type, props, key) {\n var R = _getR();\n var p = props || {};\n var c = p.children;\n delete p.children;\n if (key !== undefined) p.key = key;\n return Array.isArray(c)\n ? R.createElement.apply(null, [type, p].concat(c))\n : c !== undefined\n ? R.createElement(type, p, c)\n : R.createElement(type, p);\n }\n export var jsx = _jsx;\n export var jsxs = _jsx;\n export var Fragment = (_getR() || {}).Fragment;\n ", "/**\n * Adaptive Nav - Editor Component\n *\n * Review & tweak editor for AI-generated navigation link decisions.\n * Displays a scannable list of link cards with trigger, rationale,\n * and inline editing. Includes detection badges and hover-to-highlight.\n */\n\nimport React, { useState, useCallback, useEffect, useRef } from 'react';\n\nimport { summarizeNavItem, describeTrigger } from './summarize';\nimport { isOwnAction, type NavConfig, type NavLinkAction, type EditorPanelProps, type RuleStrategy } from './types';\n\n// ============================================================================\n// Targeting Extraction (inlined \u2014 CDN builds can't import from editor-sdk)\n// ============================================================================\n\ninterface TargetingInfo {\n pagePatterns: string[];\n anchorSelectors: string[];\n hasTargeting: boolean;\n}\n\nfunction isRuleStrategy(s: unknown): s is RuleStrategy<boolean> {\n return (\n typeof s === 'object' &&\n s !== null &&\n (s as Record<string, unknown>).type === 'rules' &&\n Array.isArray((s as Record<string, unknown>).rules)\n );\n}\n\nfunction extractTargetingInfo(showWhen?: unknown | null): TargetingInfo {\n if (!showWhen || !isRuleStrategy(showWhen)) {\n return { pagePatterns: [], anchorSelectors: [], hasTargeting: false };\n }\n\n const pagePatterns = new Set<string>();\n const anchorSelectors = new Set<string>();\n\n for (const rule of showWhen.rules) {\n for (const cond of rule.conditions) {\n const c = cond as Record<string, unknown>;\n if (c.type === 'page_url' && typeof c.url === 'string') {\n pagePatterns.add(c.url);\n } else if (c.type === 'anchor_visible' && typeof c.anchorId === 'string') {\n anchorSelectors.add(c.anchorId);\n }\n }\n }\n\n const hasTargeting = pagePatterns.size > 0 || anchorSelectors.size > 0;\n return {\n pagePatterns: [...pagePatterns],\n anchorSelectors: [...anchorSelectors],\n hasTargeting,\n };\n}\n\nfunction extractFirstPage(showWhen?: unknown | null): string | null {\n const info = extractTargetingInfo(showWhen);\n return info.pagePatterns[0] || null;\n}\n\nfunction extractFirstAnchor(showWhen?: unknown | null): string | null {\n const info = extractTargetingInfo(showWhen);\n return info.anchorSelectors[0] || null;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\ninterface FlatItem {\n key: string;\n index: number;\n summary: string;\n trigger: string;\n rationale?: { why: string; confidence?: number };\n firstAnchor: string | null;\n link: NavLinkAction;\n}\n\nfunction flattenItems(config: NavConfig): FlatItem[] {\n const actions = (config.actions || []).filter(isOwnAction);\n return actions.map((link, i) => ({\n key: String(i),\n index: i,\n summary: summarizeNavItem(link),\n trigger: describeTrigger(link.showWhen),\n rationale: link.rationale,\n firstAnchor: extractFirstAnchor(link.showWhen),\n link,\n }));\n}\n\nfunction filterConfig(config: NavConfig, dismissedKeys: Set<string>): NavConfig {\n const ownActions = (config.actions || []).filter(isOwnAction);\n return {\n ...config,\n actions: ownActions.filter((_, i) => !dismissedKeys.has(String(i))),\n };\n}\n\n// ============================================================================\n// Detection Hook\n// ============================================================================\n\ninterface DetectionEntry {\n found: boolean;\n element: HTMLElement | null;\n}\n\nfunction useDetection(\n items: FlatItem[],\n getCurrentRoute: () => string\n): Map<string, DetectionEntry> {\n const [detectionMap, setDetectionMap] = useState<Map<string, DetectionEntry>>(new Map());\n const itemsRef = useRef(items);\n itemsRef.current = items;\n\n useEffect(() => {\n const runDetection = () => {\n const map = new Map<string, DetectionEntry>();\n const currentPath = getCurrentRoute();\n\n for (const item of itemsRef.current) {\n const targeting = extractTargetingInfo(item.link.showWhen);\n\n // Check page match\n let pageMatch = true;\n if (targeting.pagePatterns.length > 0) {\n pageMatch = targeting.pagePatterns.some((pattern) => {\n const regex = new RegExp(\n `^${pattern.replace(/\\*\\*/g, '.*').replace(/(?<!\\.)(\\*)/g, '[^/]*')}$`\n );\n return regex.test(currentPath);\n });\n }\n\n // Check anchor presence\n let anchorFound = false;\n let element: HTMLElement | null = null;\n if (item.firstAnchor) {\n try {\n element = document.querySelector(item.firstAnchor) as HTMLElement | null;\n anchorFound = element !== null;\n } catch {\n // Invalid selector\n }\n } else {\n anchorFound = pageMatch;\n }\n\n map.set(item.key, {\n found: pageMatch && anchorFound,\n element,\n });\n }\n\n setDetectionMap(map);\n };\n\n runDetection();\n\n const interval = setInterval(runDetection, 2000);\n window.addEventListener('popstate', runDetection);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener('popstate', runDetection);\n };\n }, [getCurrentRoute]);\n\n return detectionMap;\n}\n\n// ============================================================================\n// Detection Badge\n// ============================================================================\n\nfunction DetectionBadge({ found }: { found: boolean }) {\n return (\n <span\n style={{\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: found ? '#22c55e' : '#475569',\n flexShrink: 0,\n display: 'inline-block',\n }}\n title={found ? 'Found on this page' : 'Not found on this page'}\n />\n );\n}\n\n// ============================================================================\n// Styles\n// ============================================================================\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column' as const,\n height: '100%',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n },\n header: {\n padding: '16px',\n borderBottom: '1px solid #334155',\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n },\n backButton: {\n padding: '6px 12px',\n borderRadius: '6px',\n border: 'none',\n backgroundColor: 'rgba(255,255,255,0.05)',\n color: '#94a3b8',\n fontSize: '13px',\n cursor: 'pointer',\n },\n title: {\n margin: 0,\n fontSize: '15px',\n fontWeight: 600,\n color: '#f8fafc',\n },\n subtitle: {\n margin: '2px 0 0 0',\n fontSize: '11px',\n color: '#64748b',\n },\n body: {\n flex: 1,\n overflow: 'auto',\n padding: '16px',\n },\n groupHeader: {\n fontSize: '11px',\n fontWeight: 700,\n color: '#64748b',\n textTransform: 'uppercase' as const,\n letterSpacing: '0.06em',\n padding: '4px 0 8px 0',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n },\n groupCount: {\n fontSize: '10px',\n color: '#475569',\n backgroundColor: 'rgba(255,255,255,0.06)',\n padding: '2px 6px',\n borderRadius: '8px',\n },\n card: {\n padding: '8px 10px',\n borderRadius: '6px',\n border: '1px solid rgba(255,255,255,0.06)',\n background: 'rgba(255,255,255,0.02)',\n marginBottom: '4px',\n fontSize: '13px',\n color: '#e2e8f0',\n },\n triggerLine: {\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n fontSize: '11px',\n color: '#94a3b8',\n cursor: 'pointer',\n marginBottom: '4px',\n },\n cardBody: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n cursor: 'pointer',\n },\n cardText: {\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap' as const,\n },\n rationaleLine: {\n fontSize: '10px',\n color: '#64748b',\n marginTop: '4px',\n },\n dismissButton: {\n padding: '2px 6px',\n borderRadius: '4px',\n border: 'none',\n background: 'transparent',\n color: '#64748b',\n fontSize: '14px',\n cursor: 'pointer',\n flexShrink: 0,\n lineHeight: 1,\n },\n dismissedSection: {\n marginTop: '16px',\n cursor: 'pointer',\n userSelect: 'none' as const,\n },\n dismissedHeader: {\n fontSize: '11px',\n fontWeight: 600,\n color: '#475569',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n },\n dismissedCard: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '6px 10px',\n borderRadius: '6px',\n border: '1px solid rgba(255,255,255,0.03)',\n background: 'transparent',\n marginBottom: '3px',\n cursor: 'pointer',\n fontSize: '12px',\n color: '#475569',\n opacity: 0.6,\n },\n emptyState: {\n textAlign: 'center' as const,\n padding: '32px 16px',\n color: '#64748b',\n fontSize: '13px',\n },\n footer: {\n padding: '12px 16px',\n borderTop: '1px solid #334155',\n display: 'flex',\n gap: '8px',\n },\n saveButton: {\n flex: 1,\n padding: '10px',\n borderRadius: '8px',\n border: 'none',\n background: 'rgba(59, 130, 246, 0.15)',\n color: '#3b82f6',\n fontSize: '13px',\n fontWeight: 600,\n cursor: 'pointer',\n },\n publishButton: {\n flex: 1,\n padding: '10px',\n borderRadius: '8px',\n border: 'none',\n background: '#22c55e',\n color: 'white',\n fontSize: '13px',\n fontWeight: 600,\n cursor: 'pointer',\n },\n // Edit form styles\n editForm: {\n padding: '4px 0',\n },\n editHeader: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n marginBottom: '12px',\n fontSize: '13px',\n fontWeight: 600,\n color: '#e2e8f0',\n },\n editLabel: {\n fontSize: '11px',\n fontWeight: 600,\n color: '#64748b',\n marginBottom: '4px',\n display: 'block',\n },\n editInput: {\n width: '100%',\n padding: '6px 8px',\n borderRadius: '4px',\n border: '1px solid rgba(255,255,255,0.1)',\n background: 'rgba(255,255,255,0.04)',\n color: '#e2e8f0',\n fontSize: '12px',\n fontFamily: 'inherit',\n marginBottom: '8px',\n boxSizing: 'border-box' as const,\n },\n editRationale: {\n padding: '8px',\n borderRadius: '4px',\n border: '1px dashed rgba(255,255,255,0.15)',\n background: 'rgba(255,255,255,0.02)',\n color: '#94a3b8',\n fontSize: '12px',\n marginBottom: '8px',\n },\n editBackButton: {\n padding: '6px 12px',\n borderRadius: '6px',\n border: '1px solid rgba(255,255,255,0.1)',\n background: 'transparent',\n color: '#94a3b8',\n fontSize: '12px',\n cursor: 'pointer',\n marginTop: '8px',\n },\n editCheckbox: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n fontSize: '12px',\n color: '#94a3b8',\n marginBottom: '8px',\n },\n};\n\n// ============================================================================\n// NavEditor Component\n// ============================================================================\n\nexport function NavEditor({ config, onChange, editor }: EditorPanelProps) {\n const typedConfig = config as unknown as NavConfig;\n const [dismissedKeys, setDismissedKeys] = useState<Set<string>>(new Set());\n const [dismissedOpen, setDismissedOpen] = useState(false);\n const [editingKey, setEditingKey] = useState<string | null>(null);\n const [previewMode, setPreviewMode] = useState<'before' | 'after'>('after');\n const [_hoveredKey, setHoveredKey] = useState<string | null>(null);\n\n // Consume initial navigation payload on mount (Nav is a widget mount \u2014\n // initialEditKey points to the mount action, no sub-item to pre-select)\n const initialConsumed = useRef(false);\n useEffect(() => {\n if (!initialConsumed.current && (editor.initialEditKey != null || editor.initialCreate)) {\n initialConsumed.current = true;\n editor.clearInitialState?.();\n }\n }, [editor]);\n\n const allItems = flattenItems(typedConfig);\n const activeItems = allItems.filter((item) => !dismissedKeys.has(item.key));\n const dismissedItems = allItems.filter((item) => dismissedKeys.has(item.key));\n const totalLinks = activeItems.length;\n\n const detectionMap = useDetection(allItems, editor.getCurrentRoute);\n const foundCount = activeItems.filter((item) => detectionMap.get(item.key)?.found).length;\n\n const handleDismiss = useCallback(\n (key: string) => {\n setDismissedKeys((prev) => {\n const next = new Set(prev);\n next.add(key);\n return next;\n });\n if (editingKey === key) setEditingKey(null);\n },\n [editingKey]\n );\n\n const handleRestore = useCallback((key: string) => {\n setDismissedKeys((prev) => {\n const next = new Set(prev);\n next.delete(key);\n return next;\n });\n }, []);\n\n const handleCardBodyClick = useCallback((item: FlatItem) => {\n setEditingKey(item.key);\n }, []);\n\n const handleTriggerClick = useCallback(\n (item: FlatItem) => {\n const pageUrl = extractFirstPage(item.link.showWhen);\n if (pageUrl) {\n editor.navigateTo(pageUrl);\n }\n if (item.firstAnchor) {\n editor.highlightElement(item.firstAnchor);\n }\n },\n [editor]\n );\n\n const handleBackToList = useCallback(() => {\n setEditingKey(null);\n setPreviewMode('after');\n editor.previewConfig(config);\n editor.clearHighlight();\n }, [editor, config]);\n\n const handleBeforeAfter = useCallback(\n (mode: 'before' | 'after') => {\n setPreviewMode(mode);\n if (mode === 'before') {\n const filtered = filterConfig(typedConfig, new Set([editingKey!]));\n editor.previewConfig(filtered as unknown as Record<string, unknown>);\n } else {\n editor.previewConfig(config);\n }\n },\n [typedConfig, editingKey, editor, config]\n );\n\n const handleFieldChange = useCallback(\n (index: number, field: string, value: unknown) => {\n const ownActions = (typedConfig.actions || []).filter(isOwnAction).slice();\n const link = { ...ownActions[index], config: { ...ownActions[index].config } };\n (link.config as Record<string, unknown>)[field] = value;\n ownActions[index] = link;\n const otherActions = (typedConfig.actions || []).filter((a) => !isOwnAction(a));\n const updated = { ...typedConfig, actions: [...otherActions, ...ownActions] };\n onChange(updated as unknown as Record<string, unknown>);\n editor.setDirty(true);\n },\n [typedConfig, onChange, editor]\n );\n\n const handlePublish = useCallback(() => {\n if (dismissedKeys.size > 0) {\n const filtered = filterConfig(typedConfig, dismissedKeys);\n onChange(filtered as unknown as Record<string, unknown>);\n }\n editor.publish();\n }, [dismissedKeys, typedConfig, onChange, editor]);\n\n const handleCardHover = useCallback(\n (item: FlatItem) => {\n setHoveredKey(item.key);\n if (item.firstAnchor) {\n editor.highlightElement(item.firstAnchor);\n }\n },\n [editor]\n );\n\n const handleCardLeave = useCallback(() => {\n setHoveredKey(null);\n editor.clearHighlight();\n }, [editor]);\n\n // ---- Edit form renderer ----\n\n const renderEditFields = (index: number) => {\n const actions = (typedConfig.actions || []).filter(isOwnAction);\n const link = actions[index];\n if (!link) return null;\n\n const item = allItems.find((it) => it.key === String(index));\n\n return (\n <div style={styles.editForm}>\n {/* Trigger line in edit mode */}\n {item && item.trigger !== 'All pages' && (\n <div data-trigger style={styles.triggerLine} onClick={() => handleTriggerClick(item)}>\n <span>{'\\u{1f4cd}'}</span>\n <span>{item.trigger}</span>\n </div>\n )}\n\n <label style={styles.editLabel}>Label</label>\n <input\n style={styles.editInput}\n value={link.config.label}\n onChange={(e) => handleFieldChange(index, 'label', e.target.value)}\n />\n\n <label style={styles.editLabel}>URL</label>\n <input\n style={styles.editInput}\n value={link.config.href}\n onChange={(e) => handleFieldChange(index, 'href', e.target.value)}\n />\n\n <label style={styles.editLabel}>Icon</label>\n <input\n style={styles.editInput}\n value={link.config.icon || ''}\n onChange={(e) => handleFieldChange(index, 'icon', e.target.value)}\n placeholder=\"e.g., \\u{1f3e0}\"\n />\n\n <label style={styles.editCheckbox}>\n <input\n type=\"checkbox\"\n checked={link.config.external || false}\n onChange={(e) => handleFieldChange(index, 'external', e.target.checked)}\n />\n Open in new tab\n </label>\n\n <label style={styles.editLabel}>AI Rationale</label>\n <div style={styles.editRationale}>{link.rationale ? link.rationale.why : 'N/A'}</div>\n </div>\n );\n };\n\n return (\n <div style={styles.container}>\n {/* Header */}\n <div style={styles.header}>\n <button onClick={() => editor.navigateHome()} style={styles.backButton}>\n &larr; Back\n </button>\n <div>\n <h2 style={styles.title}>Navigation Links</h2>\n <p style={styles.subtitle}>\n {totalLinks} link{totalLinks !== 1 ? 's' : ''}\n {totalLinks > 0 && ` (${foundCount} found on this page)`}\n </p>\n </div>\n </div>\n\n {/* Body */}\n <div style={styles.body}>\n {editingKey !== null ? (\n /* ---- Edit mode ---- */\n (() => {\n const editIndex = Number(editingKey);\n const editItem = allItems.find((it) => it.key === editingKey);\n return (\n <>\n <div style={styles.editHeader}>\n <span>{'\\u{1f517}'}</span>\n <span>{editItem?.summary}</span>\n </div>\n <div\n style={{\n display: 'flex',\n gap: '0',\n marginBottom: '12px',\n borderRadius: '6px',\n overflow: 'hidden',\n border: '1px solid rgba(255,255,255,0.1)',\n }}\n >\n <button\n onClick={() => handleBeforeAfter('before')}\n style={{\n flex: 1,\n padding: '6px 12px',\n border: 'none',\n fontSize: '12px',\n fontWeight: 600,\n cursor: 'pointer',\n background: previewMode === 'before' ? 'rgba(59,130,246,0.2)' : 'transparent',\n color: previewMode === 'before' ? '#3b82f6' : '#64748b',\n }}\n >\n Before\n </button>\n <button\n onClick={() => handleBeforeAfter('after')}\n style={{\n flex: 1,\n padding: '6px 12px',\n border: 'none',\n borderLeft: '1px solid rgba(255,255,255,0.1)',\n fontSize: '12px',\n fontWeight: 600,\n cursor: 'pointer',\n background: previewMode === 'after' ? 'rgba(59,130,246,0.2)' : 'transparent',\n color: previewMode === 'after' ? '#3b82f6' : '#64748b',\n }}\n >\n After\n </button>\n </div>\n {renderEditFields(editIndex)}\n <button style={styles.editBackButton} onClick={handleBackToList}>\n &larr; List\n </button>\n </>\n );\n })()\n ) : (\n /* ---- List mode ---- */\n <>\n {allItems.length === 0 && <div style={styles.emptyState}>No links configured.</div>}\n\n {activeItems.length > 0 && (\n <>\n <div style={styles.groupHeader}>\n <span>NAV</span>\n <span style={styles.groupCount}>{activeItems.length}</span>\n </div>\n {activeItems.map((item) => {\n const detection = detectionMap.get(item.key);\n return (\n <div\n key={item.key}\n style={styles.card}\n data-item-key={item.key}\n onMouseEnter={() => handleCardHover(item)}\n onMouseLeave={handleCardLeave}\n >\n {/* Trigger line */}\n {item.trigger !== 'All pages' && (\n <div\n data-trigger\n style={styles.triggerLine}\n onClick={(e) => {\n e.stopPropagation();\n handleTriggerClick(item);\n }}\n >\n <span>{'\\u{1f4cd}'}</span>\n <span>{item.trigger}</span>\n </div>\n )}\n {/* Card body: badge + summary + dismiss */}\n <div\n data-card-body\n style={styles.cardBody}\n onClick={() => handleCardBodyClick(item)}\n >\n <DetectionBadge found={detection?.found ?? false} />\n <span style={styles.cardText}>{item.summary}</span>\n <button\n style={styles.dismissButton}\n onClick={(e) => {\n e.stopPropagation();\n handleDismiss(item.key);\n }}\n title=\"Dismiss this link\"\n >\n &times;\n </button>\n </div>\n {/* Rationale line */}\n <div style={styles.rationaleLine}>\n WHY: {item.rationale ? item.rationale.why : 'N/A'}\n </div>\n </div>\n );\n })}\n </>\n )}\n\n {/* Dismissed section */}\n {dismissedItems.length > 0 && (\n <div style={styles.dismissedSection}>\n <div\n style={{ ...styles.dismissedHeader, cursor: 'pointer' }}\n onClick={() => setDismissedOpen(!dismissedOpen)}\n >\n <span>{dismissedOpen ? '\\u25be' : '\\u25b8'}</span>\n <span>Dismissed ({dismissedItems.length})</span>\n </div>\n {dismissedOpen && (\n <div style={{ marginTop: '6px' }}>\n {dismissedItems.map((item) => (\n <div key={item.key} style={styles.dismissedCard}>\n <span style={{ ...styles.cardText, textDecoration: 'line-through' }}>\n {item.summary}\n </span>\n <button\n style={{\n ...styles.dismissButton,\n color: '#3b82f6',\n fontSize: '11px',\n }}\n onClick={(e) => {\n e.stopPropagation();\n handleRestore(item.key);\n }}\n >\n Restore\n </button>\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </>\n )}\n </div>\n\n {/* Footer */}\n <div style={styles.footer}>\n <button onClick={() => editor.save()} style={styles.saveButton}>\n Save Draft\n </button>\n <button onClick={handlePublish} style={styles.publishButton}>\n Publish\n </button>\n </div>\n </div>\n );\n}\n\n/**\n * Editor panel configuration for the app registry.\n */\nexport const editorPanel = {\n title: 'Navigation',\n icon: '\\u{1f517}',\n description: 'Navigation link list with per-item visibility',\n};\n\nexport const editor = {\n panel: editorPanel,\n component: NavEditor,\n};\n\nexport default NavEditor;\n", "\n var RD = globalThis.__SYNTRO_REACT_DOM__;\n export default RD;\n export var createRoot = RD?.createRoot;\n export var createPortal = RD?.createPortal;\n ", "/**\n * Adaptive Nav - NavWidget Component\n *\n * React component that renders a navigation link list with per-item\n * conditional visibility based on showWhen decision strategies.\n *\n * Demonstrates the compositional action pattern where child actions\n * (nav:link) serve as configuration data for the parent widget.\n */\n\nimport React, { useEffect, useReducer, useMemo, useCallback } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport type { NavWidgetProps, NavLinkAction, NavConfig, NavWidgetRuntime } from './types';\n\n// ============================================================================\n// Styles\n// ============================================================================\n\nconst baseStyles = {\n nav: {\n display: 'flex',\n gap: '4px',\n padding: '8px',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n },\n link: {\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n padding: '8px 12px',\n borderRadius: '6px',\n textDecoration: 'none',\n fontSize: '14px',\n fontWeight: 500,\n transition: 'background-color 0.15s ease, color 0.15s ease',\n cursor: 'pointer',\n border: 'none',\n background: 'transparent',\n },\n icon: {\n fontSize: '16px',\n },\n externalIcon: {\n fontSize: '12px',\n opacity: 0.6,\n },\n} as const;\n\nconst themeStyles = {\n light: {\n nav: {\n backgroundColor: '#ffffff',\n },\n link: {\n color: '#374151',\n },\n linkHover: {\n backgroundColor: '#f3f4f6',\n color: '#111827',\n },\n },\n dark: {\n nav: {\n backgroundColor: '#1f2937',\n },\n link: {\n color: '#d1d5db',\n },\n linkHover: {\n backgroundColor: '#374151',\n color: '#f9fafb',\n },\n },\n} as const;\n\n// ============================================================================\n// NavLink Component\n// ============================================================================\n\ninterface NavLinkComponentProps {\n link: NavLinkAction;\n theme: 'light' | 'dark';\n onNavigate: (href: string, external: boolean) => void;\n}\n\nfunction NavLinkComponent({ link, theme, onNavigate }: NavLinkComponentProps) {\n const [isHovered, setIsHovered] = React.useState(false);\n const { label, href, icon, external } = link.config;\n const colors = themeStyles[theme];\n\n const style: React.CSSProperties = {\n ...baseStyles.link,\n ...colors.link,\n ...(isHovered ? colors.linkHover : {}),\n };\n\n const handleClick = (e: React.MouseEvent) => {\n e.preventDefault();\n onNavigate(href, external ?? false);\n };\n\n return (\n <a\n href={href}\n onClick={handleClick}\n style={style}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n target={external ? '_blank' : undefined}\n rel={external ? 'noopener noreferrer' : undefined}\n >\n {icon && <span style={baseStyles.icon}>{icon}</span>}\n <span>{label}</span>\n {external && <span style={baseStyles.externalIcon}>\u2197</span>}\n </a>\n );\n}\n\n// ============================================================================\n// NavWidget Component\n// ============================================================================\n\n/**\n * NavWidget - Renders a navigation link list with per-item activation.\n *\n * This component demonstrates the compositional action pattern:\n * - Parent (NavWidget) receives `config.actions` array\n * - Each action has optional `showWhen` for per-item visibility\n * - Parent evaluates showWhen and filters visible links\n * - Parent manages re-rendering on context changes\n */\nexport function NavWidget({ config, runtime, instanceId }: NavWidgetProps) {\n // Force re-render when context changes\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n // Subscribe to context changes for reactive updates\n useEffect(() => {\n const unsubscribe = runtime.context.subscribe(() => {\n forceUpdate();\n });\n return unsubscribe;\n }, [runtime.context]);\n\n // Filter visible links based on per-item showWhen\n const visibleLinks = useMemo(\n () =>\n config.actions.filter((link) => {\n // No showWhen = always visible\n if (!link.showWhen) return true;\n\n // Evaluate the decision strategy\n const result = runtime.evaluateSync<boolean>(link.showWhen);\n return result.value;\n }),\n [config.actions, runtime]\n );\n\n // Resolve theme (auto \u2192 detect system preference)\n const resolvedTheme = useMemo(() => {\n if (config.theme !== 'auto') return config.theme;\n\n // Check system preference (SSR-safe)\n if (typeof window !== 'undefined') {\n return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n return 'light';\n }, [config.theme]);\n\n // Handle navigation with event publishing\n const handleNavigate = useCallback(\n (href: string, external: boolean) => {\n // Publish navigation event for analytics\n runtime.events.publish('nav:click', {\n instanceId,\n href,\n external,\n timestamp: Date.now(),\n });\n\n // Perform navigation\n if (external) {\n window.open(href, '_blank', 'noopener,noreferrer');\n } else {\n window.location.href = href;\n }\n },\n [runtime.events, instanceId]\n );\n\n // Compute nav styles\n const navStyle: React.CSSProperties = {\n ...baseStyles.nav,\n ...themeStyles[resolvedTheme].nav,\n flexDirection: config.layout === 'vertical' ? 'column' : 'row',\n };\n\n // Empty state\n if (visibleLinks.length === 0) {\n return null;\n }\n\n return (\n <nav style={navStyle} data-adaptive-id={instanceId} data-adaptive-type=\"adaptive-nav\">\n {visibleLinks.map((link, index) => (\n <NavLinkComponent\n key={link.config.href + index}\n link={link}\n theme={resolvedTheme}\n onNavigate={handleNavigate}\n />\n ))}\n </nav>\n );\n}\n\n// ============================================================================\n// Mountable Widget Interface\n// ============================================================================\n\n/**\n * Mountable widget interface for the runtime's WidgetRegistry.\n */\nexport const NavMountableWidget = {\n mount(\n container: HTMLElement,\n config?: NavConfig & { runtime?: NavWidgetRuntime; instanceId?: string }\n ) {\n const {\n runtime,\n instanceId = 'nav-widget',\n ...navConfig\n } = config || {\n layout: 'horizontal' as const,\n theme: 'auto' as const,\n actions: [],\n };\n\n // React rendering when runtime + ReactDOM are available\n if (runtime && typeof createRoot === 'function') {\n const root = createRoot(container);\n root.render(\n React.createElement(NavWidget, {\n config: navConfig as NavConfig,\n runtime: runtime as NavWidgetRuntime,\n instanceId,\n })\n );\n return () => { root.unmount(); };\n }\n\n // HTML fallback for non-React environments\n const links = (navConfig as NavConfig).actions || [];\n container.innerHTML = `\n <nav style=\"display: flex; gap: 8px; padding: 8px; font-family: system-ui;\">\n ${links\n .map(\n (link) => `\n <a href=\"${link.config.href}\" style=\"padding: 8px 12px; text-decoration: none; color: #374151;\">\n ${link.config.icon ? `<span>${link.config.icon}</span>` : ''}\n ${link.config.label}\n </a>\n `\n )\n .join('')}\n </nav>\n `;\n\n return () => {\n container.innerHTML = '';\n };\n },\n};\n\nexport default NavWidget;\n", "/**\n * Adaptive Nav - Runtime Module\n *\n * Runtime manifest for the navigation link list adaptive.\n * Includes widget-based nav links and navigation action executors\n * (scrollTo, navigate) previously in adaptive-navigation.\n */\n\nimport { NavMountableWidget } from './NavWidget';\nimport type { ScrollToAction, NavigateAction, ExecutorResult, ActionExecutor } from './types';\n\n// ============================================================================\n// Navigation Action Executors (merged from adaptive-navigation)\n// ============================================================================\n\n/**\n * Execute a scrollTo action\n */\nexport const executeScrollTo: ActionExecutor<ScrollToAction> = async (\n action,\n context\n): Promise<ExecutorResult> => {\n const anchorEl = context.resolveAnchor(action.anchorId);\n if (!anchorEl) {\n throw new Error(`Anchor not found: ${action.anchorId}`);\n }\n\n // Scroll to element\n anchorEl.scrollIntoView({\n behavior: action.behavior ?? 'smooth',\n block: action.block ?? 'center',\n inline: action.inline ?? 'nearest',\n });\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'navigation:scrollTo',\n anchorId: action.anchorId,\n behavior: action.behavior ?? 'smooth',\n });\n\n return {\n cleanup: () => {\n // Optionally restore scroll position on revert\n },\n };\n};\n\n/**\n * Execute a navigate action\n */\nexport const executeNavigate: ActionExecutor<NavigateAction> = async (\n action,\n context\n): Promise<ExecutorResult> => {\n // Validate URL to prevent javascript: URLs\n const url = action.url.trim();\n if (url.toLowerCase().startsWith('javascript:')) {\n throw new Error('javascript: URLs are not allowed');\n }\n\n const target = action.target ?? '_self';\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'navigation:navigate',\n url: action.url,\n target,\n });\n\n if (target === '_blank') {\n // Open in new tab\n window.open(url, '_blank', 'noopener,noreferrer');\n } else {\n // Navigate in current tab\n window.location.href = url;\n }\n\n return {\n cleanup: () => {\n // Navigation cannot be reverted\n },\n };\n};\n\n// ============================================================================\n// Executor Definitions for Registration\n// ============================================================================\n\n/**\n * All executors provided by this app.\n * These are registered with the runtime's ExecutorRegistry.\n */\nexport const executors = [\n { kind: 'navigation:scrollTo', executor: executeScrollTo },\n { kind: 'navigation:navigate', executor: executeNavigate },\n] as const;\n\n// ============================================================================\n// App Runtime Manifest\n// ============================================================================\n\n/**\n * Runtime manifest for adaptive-nav.\n *\n * Provides:\n * - Navigation action executors (scrollTo, navigate)\n * - Widget-based nav links (compositional nav:link actions)\n */\nexport const runtime = {\n id: 'adaptive-nav',\n version: '1.0.0',\n name: 'Navigation Links',\n description: 'Navigation actions and widget-based link list with per-item conditional visibility',\n\n /**\n * Navigation action executors (scrollTo, navigate).\n */\n executors,\n\n /**\n * Widget definitions for the runtime's WidgetRegistry.\n */\n widgets: [\n {\n id: 'adaptive-nav:links',\n component: NavMountableWidget,\n metadata: {\n name: 'Navigation Links',\n description: 'Horizontal or vertical navigation link list',\n icon: '\uD83D\uDD17',\n },\n },\n ],\n};\n\nexport default runtime;\n", "/**\n * CDN Entry Point for Adaptive Nav\n *\n * This module is bundled for CDN delivery and self-registers with the global\n * SynOS app registry when loaded dynamically via the AppLoader.\n */\n\nimport NavEditor, { editorPanel } from './editor';\nimport { executors, runtime } from './runtime';\n\n/**\n * App manifest for registry registration.\n * Follows the AppManifest interface expected by AppLoader/AppRegistry.\n */\nexport const manifest = {\n id: 'adaptive-nav',\n version: runtime.version,\n name: runtime.name,\n description: runtime.description,\n runtime: {\n actions: executors.map(({ kind, executor }) => ({\n kind,\n executor,\n })),\n widgets: runtime.widgets,\n },\n editor: { component: NavEditor, panel: editorPanel },\n metadata: {\n isBuiltIn: false,\n },\n};\n\n/**\n * Self-register with global registry if available.\n * This happens when loaded via script tag (UMD).\n */\nif (typeof window !== 'undefined') {\n const registry = (window as any).SynOS?.appRegistry;\n if (registry && typeof registry.register === 'function') {\n registry.register(manifest);\n }\n}\n\nexport default manifest;\n"],
5
+ "mappings": "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",
6
+ "names": ["R", "react_default", "useState", "useEffect", "useMemo", "useCallback", "useRef", "useContext", "useReducer", "createElement", "createContext", "Fragment", "forwardRef", "memo", "lazy", "Suspense", "Children", "isValidElement", "cloneElement", "Component", "PureComponent", "useLayoutEffect", "useId", "truncate", "text", "max", "isRuleStrategy", "s", "describeTrigger", "showWhen", "pages", "anchors", "rule", "condition", "parts", "summarizeNavItem", "item", "icon", "label", "href", "ACTION_NAMESPACES", "isOwnAction", "action", "ns", "_getR", "_jsx", "type", "props", "key", "R", "p", "c", "jsx", "jsxs", "Fragment", "isRuleStrategy", "s", "extractTargetingInfo", "showWhen", "pagePatterns", "anchorSelectors", "rule", "cond", "c", "hasTargeting", "extractFirstPage", "extractFirstAnchor", "flattenItems", "config", "isOwnAction", "link", "summarizeNavItem", "describeTrigger", "filterConfig", "dismissedKeys", "ownActions", "_", "i", "useDetection", "items", "getCurrentRoute", "detectionMap", "setDetectionMap", "useState", "itemsRef", "useRef", "useEffect", "runDetection", "map", "currentPath", "item", "targeting", "pageMatch", "pattern", "anchorFound", "element", "interval", "DetectionBadge", "found", "jsx", "styles", "NavEditor", "onChange", "editor", "typedConfig", "setDismissedKeys", "dismissedOpen", "setDismissedOpen", "editingKey", "setEditingKey", "previewMode", "setPreviewMode", "_hoveredKey", "setHoveredKey", "initialConsumed", "allItems", "activeItems", "dismissedItems", "totalLinks", "foundCount", "handleDismiss", "useCallback", "key", "prev", "next", "handleRestore", "handleCardBodyClick", "handleTriggerClick", "pageUrl", "handleBackToList", "handleBeforeAfter", "mode", "filtered", "handleFieldChange", "index", "field", "value", "otherActions", "a", "updated", "handlePublish", "handleCardHover", "handleCardLeave", "renderEditFields", "it", "jsxs", "e", "editIndex", "editItem", "Fragment", "detection", "editorPanel", "editor_default", "NavEditor", "RD", "createRoot", "RD", "createPortal", "baseStyles", "themeStyles", "NavLinkComponent", "link", "theme", "onNavigate", "isHovered", "setIsHovered", "react_default", "label", "href", "icon", "external", "colors", "style", "jsxs", "e", "jsx", "NavWidget", "config", "runtime", "instanceId", "forceUpdate", "useReducer", "x", "useEffect", "visibleLinks", "useMemo", "resolvedTheme", "handleNavigate", "useCallback", "navStyle", "index", "NavMountableWidget", "container", "navConfig", "createRoot", "root", "links", "executeScrollTo", "action", "context", "anchorEl", "executeNavigate", "url", "target", "executors", "runtime", "NavMountableWidget", "manifest", "runtime", "executors", "kind", "executor", "editor_default", "editorPanel", "registry", "cdn_default"]
7
+ }