@syntrologie/runtime-sdk 2.0.1-canary.4 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CAPABILITIES.md +286 -43
- package/README.md +87 -0
- package/dist/RuntimeProvider.d.ts +1 -1
- package/dist/RuntimeProvider.js.map +1 -1
- package/dist/SmartCanvasApp.d.ts +4 -4
- package/dist/SmartCanvasApp.js +4 -4
- package/dist/SmartCanvasApp.js.map +1 -1
- package/dist/SmartCanvasElement.d.ts +2 -2
- package/dist/SmartCanvasElement.js +1 -1
- package/dist/SmartCanvasElement.js.map +1 -1
- package/dist/SmartCanvasPortal.js.map +1 -1
- package/dist/actions/ActionEngine.js +2 -4
- package/dist/actions/ActionEngine.js.map +1 -1
- package/dist/actions/executors/index.d.ts +3 -4
- package/dist/actions/executors/index.js +9 -11
- package/dist/actions/executors/index.js.map +1 -1
- package/dist/actions/executors/tour.js +3 -3
- package/dist/actions/executors/tour.js.map +1 -1
- package/dist/actions/validation.js +6 -31
- package/dist/actions/validation.js.map +1 -1
- package/dist/adaptives/adaptive-chatbot/index.js +9 -0
- package/dist/adaptives/adaptive-chatbot/index.js.map +7 -0
- package/dist/adaptives/adaptive-content/index.js +2 -0
- package/dist/adaptives/adaptive-content/index.js.map +7 -0
- package/dist/adaptives/adaptive-faq/index.js +11 -0
- package/dist/adaptives/adaptive-faq/index.js.map +7 -0
- package/dist/adaptives/adaptive-gamification/index.js +2 -0
- package/dist/adaptives/adaptive-gamification/index.js.map +7 -0
- package/dist/adaptives/adaptive-nav/index.js +11 -0
- package/dist/adaptives/adaptive-nav/index.js.map +7 -0
- package/dist/adaptives/adaptive-overlays/index.js +91 -0
- package/dist/adaptives/adaptive-overlays/index.js.map +7 -0
- package/dist/api.d.ts +5 -5
- package/dist/api.js +4 -7
- package/dist/api.js.map +1 -1
- package/dist/apps/AppContext.js +3 -5
- package/dist/apps/AppContext.js.map +1 -1
- package/dist/apps/AppLoader.d.ts +2 -1
- package/dist/apps/AppLoader.js +37 -11
- package/dist/apps/AppLoader.js.map +1 -1
- package/dist/apps/AppRegistry.js.map +1 -1
- package/dist/apps/examples/gamification-app.example.d.ts +8 -8
- package/dist/apps/examples/gamification-app.example.js.map +1 -1
- package/dist/apps/index.d.ts +2 -3
- package/dist/apps/index.js +2 -3
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/types.d.ts +1 -1
- package/dist/blocks/data/ComparisonBlock.js +9 -9
- package/dist/blocks/data/ComparisonBlock.js.map +1 -1
- package/dist/blocks/data/StatsBlock.js +12 -14
- package/dist/blocks/data/StatsBlock.js.map +1 -1
- package/dist/blocks/index.d.ts +2 -2
- package/dist/blocks/index.js +3 -4
- package/dist/blocks/index.js.map +1 -1
- package/dist/blocks/interactive/ChecklistBlock.js +12 -12
- package/dist/blocks/interactive/ChecklistBlock.js.map +1 -1
- package/dist/blocks/interactive/RatingBlock.js +12 -14
- package/dist/blocks/interactive/RatingBlock.js.map +1 -1
- package/dist/blocks/notification/NotificationBlock.js +24 -24
- package/dist/blocks/notification/NotificationBlock.js.map +1 -1
- package/dist/bootstrap.d.ts +6 -6
- package/dist/bootstrap.js +31 -34
- package/dist/bootstrap.js.map +1 -1
- package/dist/components/ShadowCanvasOverlay.d.ts +2 -2
- package/dist/components/ShadowCanvasOverlay.js +25 -24
- package/dist/components/ShadowCanvasOverlay.js.map +1 -1
- package/dist/components/TileCard.d.ts +2 -2
- package/dist/components/TileCard.js +24 -23
- package/dist/components/TileCard.js.map +1 -1
- package/dist/components/TileWheel.d.ts +1 -1
- package/dist/components/TileWheel.js +23 -1
- package/dist/components/TileWheel.js.map +1 -1
- package/dist/config-validator.d.ts +49 -0
- package/dist/config-validator.js +173 -0
- package/dist/config-validator.js.map +1 -0
- package/dist/configFetcher.d.ts +6 -2
- package/dist/configFetcher.js +66 -29
- package/dist/configFetcher.js.map +1 -1
- package/dist/context/ContextManager.d.ts +1 -1
- package/dist/context/ContextManager.js +4 -3
- package/dist/context/ContextManager.js.map +1 -1
- package/dist/context/schema.d.ts +8 -8
- package/dist/context/schema.js +1 -1
- package/dist/context/schema.js.map +1 -1
- package/dist/decisions/engine.d.ts +2 -2
- package/dist/decisions/engine.js.map +1 -1
- package/dist/decisions/schema.d.ts +34 -34
- package/dist/decisions/schema.js +1 -1
- package/dist/decisions/schema.js.map +1 -1
- package/dist/editorLoader.d.ts +19 -9
- package/dist/editorLoader.js +107 -96
- package/dist/editorLoader.js.map +1 -1
- package/dist/events/normalizers/canvas.d.ts +1 -1
- package/dist/events/normalizers/canvas.js.map +1 -1
- package/dist/events/schema.d.ts +8 -8
- package/dist/events/schema.js +1 -1
- package/dist/events/schema.js.map +1 -1
- package/dist/experiments/adapters/growthbook.d.ts +2 -1
- package/dist/experiments/adapters/growthbook.js +9 -1
- package/dist/experiments/adapters/growthbook.js.map +1 -1
- package/dist/experiments/types.d.ts +5 -0
- package/dist/fetchers/cdnFetcher.js.map +1 -1
- package/dist/fetchers/experimentsFetcher.d.ts +24 -2
- package/dist/fetchers/experimentsFetcher.js +48 -1
- package/dist/fetchers/experimentsFetcher.js.map +1 -1
- package/dist/fetchers/mergeConfigs.d.ts +29 -0
- package/dist/fetchers/mergeConfigs.js +38 -0
- package/dist/fetchers/mergeConfigs.js.map +1 -0
- package/dist/hooks/useCanvasOverlays.d.ts +1 -1
- package/dist/hooks/useCanvasOverlays.js +2 -2
- package/dist/hooks/useCanvasOverlays.js.map +1 -1
- package/dist/hooks/useHostPatches.js.map +1 -1
- package/dist/hooks/useShadowCanvasConfig.d.ts +1 -1
- package/dist/hooks/useShadowCanvasConfig.js.map +1 -1
- package/dist/hostPatcher/core/patcher.js.map +1 -1
- package/dist/hostPatcher/policy/defaultPolicy.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -1
- package/dist/overlays/fetcher.d.ts +1 -1
- package/dist/overlays/fetcher.js +12 -14
- package/dist/overlays/fetcher.js.map +1 -1
- package/dist/overlays/runtime/overlay/runner.js +18 -5
- package/dist/overlays/runtime/overlay/runner.js.map +1 -1
- package/dist/overlays/runtime/overlay/tooltip.js +3 -5
- package/dist/overlays/runtime/overlay/tooltip.js.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js.map +1 -1
- package/dist/render/RenderContext.js.map +1 -1
- package/dist/runtime.d.ts +6 -6
- package/dist/runtime.js +38 -16
- package/dist/runtime.js.map +1 -1
- package/dist/smart-canvas.esm.js +97 -85
- package/dist/smart-canvas.esm.js.map +4 -4
- package/dist/smart-canvas.js +41592 -44370
- package/dist/smart-canvas.js.map +4 -4
- package/dist/smart-canvas.min.js +97 -85
- package/dist/smart-canvas.min.js.map +4 -4
- package/dist/state/StateStore.d.ts +0 -6
- package/dist/state/StateStore.js +7 -1
- package/dist/state/StateStore.js.map +1 -1
- package/dist/surfaces/Surfaces.js +1 -1
- package/dist/surfaces/Surfaces.js.map +1 -1
- package/dist/surfaces/positioning.js.map +1 -1
- package/dist/telemetry/adapters/posthog.js +1 -1
- package/dist/telemetry/adapters/posthog.js.map +1 -1
- package/dist/telemetry/registry.d.ts +0 -7
- package/dist/telemetry/registry.js +1 -1
- package/dist/telemetry/registry.js.map +1 -1
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/defaultTheme.d.ts +2 -3
- package/dist/theme/defaultTheme.js +60 -51
- package/dist/theme/defaultTheme.js.map +1 -1
- package/dist/theme/extractHostTheme.js +1 -1
- package/dist/theme/extractHostTheme.js.map +1 -1
- package/dist/types.d.ts +22 -1
- package/dist/types.js +14 -2
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +13 -0
- package/dist/version.js +14 -0
- package/dist/version.js.map +1 -0
- package/dist/widgets/WidgetRegistry.d.ts +6 -0
- package/dist/widgets/WidgetRegistry.js +12 -3
- package/dist/widgets/WidgetRegistry.js.map +1 -1
- package/package.json +19 -11
- package/dist/apps/adaptive-chatbot/index.js +0 -7
- package/dist/apps/adaptive-chatbot/index.js.map +0 -7
- package/dist/apps/faq/index.js +0 -11
- package/dist/apps/faq/index.js.map +0 -7
- package/dist/apps/gamification/index.js +0 -2
- package/dist/apps/gamification/index.js.map +0 -7
- package/dist/apps/nav/index.js +0 -11
- package/dist/apps/nav/index.js.map +0 -7
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["shared-react:react", "../../../../adaptives/adaptive-content/src/summarize.ts", "shared-react:react/jsx-runtime", "../../../../adaptives/adaptive-content/src/editor.tsx", "../../../../adaptives/adaptive-content/src/sanitizer.ts", "../../../../adaptives/adaptive-content/src/runtime.ts", "../../../../adaptives/adaptive-content/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 content config changes.\n *\n * Pure functions \u2014 no DOM access, just string formatting from config data.\n */\n\nimport type { ContentConfig } from './schema';\n\nconst MAX_TEXT_LEN = 40;\n\n/**\n * Convert a CSS selector into a human-friendly element description.\n */\nexport function describeSelector(selector: string): string {\n if (!selector) return '(no target)';\n\n // ID selector: strip # and common prefixes\n if (selector.startsWith('#')) {\n let name = selector.slice(1);\n const prefixes = ['hero-', 'main-', 'page-', 'app-', 'section-'];\n for (const prefix of prefixes) {\n if (name.startsWith(prefix)) {\n name = name.slice(prefix.length);\n break;\n }\n }\n return truncate(name, 50);\n }\n\n // data-testid selector\n const testIdMatch = selector.match(/\\[data-testid=\"([^\"]+)\"\\]/);\n if (testIdMatch) {\n return `${testIdMatch[1]} element`;\n }\n\n // Class selector or complex selector: keep as-is\n return truncate(selector, 50);\n}\n\nfunction truncate(text: string, max: number): string {\n if (text.length <= max) return text;\n return `${text.slice(0, max)}...`;\n}\n\nfunction truncateQuoted(text: string, max: number): string {\n if (text.length <= max) return `\"${text}\"`;\n return `\"${text.slice(0, max)}...\"`;\n}\n\n/**\n * Generate a human-readable one-liner for a content config change.\n */\nexport function summarizeContentChange(\n type: keyof ContentConfig,\n item: Record<string, unknown>\n): string {\n const desc = describeSelector((item.anchorId as string) || '');\n\n switch (type) {\n case 'textReplacements': {\n const text = (item.text as string) || '';\n return `Change ${desc} to ${truncateQuoted(text, MAX_TEXT_LEN)}`;\n }\n case 'attributeChanges': {\n const attr = (item.attr as string) || '';\n const value = (item.value as string) || '';\n return `Set ${desc} ${attr} to ${truncateQuoted(value, MAX_TEXT_LEN)}`;\n }\n case 'styleChanges': {\n const styles = (item.styles as Record<string, string>) || {};\n const count = Object.keys(styles).length;\n return `Restyle ${desc} (${count} ${count === 1 ? 'property' : 'properties'})`;\n }\n case 'htmlInsertions': {\n const position = (item.position as string) || 'append';\n return `Insert HTML ${position} ${desc}`;\n }\n case 'classAdditions': {\n const className = (item.className as string) || '';\n return `Add class \"${className}\" to ${desc}`;\n }\n case 'classRemovals': {\n const className = (item.className as string) || '';\n return `Remove class \"${className}\" from ${desc}`;\n }\n default:\n return `Unknown change on ${desc}`;\n }\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 Content - Editor Component\n *\n * Review & tweak editor for AI-generated content modifications.\n * Displays a scannable list of one-liner change summaries.\n * Clicking a card navigates to the element and shows a floating edit panel.\n */\n\nimport React, { useState, useCallback, useEffect, useRef } from 'react';\n\nimport type { ContentConfig } from './schema';\nimport { summarizeContentChange } from './summarize';\nimport type { EditorPanelProps } from './types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ntype SectionKey = keyof ContentConfig;\n\ninterface ItemRef {\n section: SectionKey;\n index: number;\n}\n\nfunction itemKey(section: SectionKey, index: number): string {\n return `${section}:${index}`;\n}\n\nfunction parseItemKey(key: string): ItemRef {\n const [section, indexStr] = key.split(':');\n return { section: section as SectionKey, index: Number(indexStr) };\n}\n\n// ============================================================================\n// Section Config\n// ============================================================================\n\nconst SECTION_ICONS: Record<SectionKey, string> = {\n textReplacements: '\\u{1f4dd}',\n attributeChanges: '\\u{1f3f7}\\u{fe0f}',\n styleChanges: '\\u{1f3a8}',\n htmlInsertions: '\\u{1f4c4}',\n classAdditions: '\\u{2795}',\n classRemovals: '\\u{2796}',\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 display: 'flex',\n alignItems: 'center',\n gap: '8px',\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 cursor: 'pointer',\n fontSize: '13px',\n color: '#e2e8f0',\n },\n cardIcon: {\n fontSize: '13px',\n flexShrink: 0,\n },\n cardText: {\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap' as const,\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 editTarget: {\n fontSize: '11px',\n fontFamily: 'monospace',\n color: '#94a3b8',\n padding: '4px 8px',\n background: 'rgba(255,255,255,0.04)',\n borderRadius: '4px',\n marginBottom: '12px',\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 editSelect: {\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 marginBottom: '8px',\n },\n};\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Build a flat list of all items across all section types. */\nfunction flattenItems(config: ContentConfig): Array<{\n key: string;\n section: SectionKey;\n index: number;\n icon: string;\n summary: string;\n anchorId: string;\n}> {\n const items: Array<{\n key: string;\n section: SectionKey;\n index: number;\n icon: string;\n summary: string;\n anchorId: string;\n }> = [];\n const sections = Object.keys(SECTION_ICONS) as SectionKey[];\n for (const section of sections) {\n const arr = (config[section] as unknown[] | undefined) || [];\n arr.forEach((item, i) => {\n const rec = item as Record<string, unknown>;\n items.push({\n key: itemKey(section, i),\n section,\n index: i,\n icon: SECTION_ICONS[section],\n summary: summarizeContentChange(section, rec),\n anchorId: (rec.anchorId as string) || '',\n });\n });\n }\n return items;\n}\n\n/** Remove items by key set from a config, returning a new config. */\nfunction filterConfig(config: ContentConfig, dismissedKeys: Set<string>): ContentConfig {\n const result = { ...config };\n const sections = Object.keys(SECTION_ICONS) as SectionKey[];\n for (const section of sections) {\n const arr = (config[section] as unknown[] | undefined) || [];\n const filtered = arr.filter((_, i) => !dismissedKeys.has(itemKey(section, i)));\n if (filtered.length > 0 || config[section] !== undefined) {\n (result as Record<string, unknown>)[section] = filtered;\n }\n }\n return result;\n}\n\n// ============================================================================\n// Detection\n// ============================================================================\n\ninterface DetectionEntry {\n found: boolean;\n element: HTMLElement | null;\n}\n\nfunction useAnchorDetection(\n items: Array<{ key: string; anchorId: 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 for (const item of itemsRef.current) {\n if (!item.anchorId) {\n map.set(item.key, { found: false, element: null });\n continue;\n }\n try {\n const el = document.querySelector(item.anchorId) as HTMLElement | null;\n map.set(item.key, { found: el !== null, element: el });\n } catch {\n map.set(item.key, { found: false, element: null });\n }\n }\n setDetectionMap(map);\n };\n\n runDetection();\n const interval = setInterval(runDetection, 2000);\n return () => clearInterval(interval);\n }, []);\n\n return detectionMap;\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// ContentEditor Component\n// ============================================================================\n\nexport function ContentEditor({ config, onChange, editor }: EditorPanelProps) {\n const typedConfig = config as unknown as ContentConfig;\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\n // Consume initialEditKey from accordion navigation on mount\n const initialConsumed = useRef(false);\n useEffect(() => {\n if (editor.initialEditKey != null && !initialConsumed.current) {\n initialConsumed.current = true;\n // Map flat action index to internal section:index key.\n // The flat index refers to the position within this app's actions only\n // (after actionsToAppConfig transformation), so we walk sections in order.\n const allFlat = flattenItems(typedConfig);\n const targetIdx = Number(editor.initialEditKey);\n if (targetIdx >= 0 && targetIdx < allFlat.length) {\n const target = allFlat[targetIdx];\n setEditingKey(target.key);\n if (target.anchorId) {\n editor.highlightElement(target.anchorId);\n }\n }\n editor.clearInitialState?.();\n } else if (editor.initialCreate && !initialConsumed.current) {\n initialConsumed.current = true;\n editor.clearInitialState?.();\n }\n }, [editor, typedConfig]);\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 totalChanges = activeItems.length;\n const [_hoveredKey, setHoveredKey] = useState<string | null>(null);\n\n const detectionMap = useAnchorDetection(allItems);\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 handleCardClick = useCallback(\n (item: { key: string; anchorId: string }) => {\n if (item.anchorId) {\n editor.highlightElement(item.anchorId);\n }\n setEditingKey(item.key);\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 (section: SectionKey, index: number, field: string, value: unknown) => {\n const arr = ((typedConfig[section] as unknown[]) || []).slice();\n const item = { ...(arr[index] as Record<string, unknown>) };\n item[field] = value;\n arr[index] = item;\n const updated = { ...typedConfig, [section]: arr };\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 // Filter dismissed items before publishing\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: { key: string; anchorId: string }) => {\n setHoveredKey(item.key);\n if (item.anchorId) {\n editor.highlightElement(item.anchorId);\n }\n },\n [editor]\n );\n\n const handleCardLeave = useCallback(() => {\n setHoveredKey(null);\n editor.clearHighlight();\n }, [editor]);\n\n // ---- Edit form renderers per section type ----\n\n const renderEditFields = (section: SectionKey, index: number) => {\n const arr = (typedConfig[section] as unknown[] | undefined) || [];\n const item = arr[index] as Record<string, unknown> | undefined;\n if (!item) return null;\n\n const anchorId = (item.anchorId as string) || '';\n\n switch (section) {\n case 'textReplacements':\n return (\n <div style={styles.editForm}>\n <div style={styles.editTarget}>{anchorId}</div>\n <label style={styles.editLabel}>Text</label>\n <textarea\n style={styles.editTextarea}\n value={(item.text as string) || ''}\n onChange={(e) => handleFieldChange(section, index, 'text', e.target.value)}\n />\n </div>\n );\n\n case 'attributeChanges':\n return (\n <div style={styles.editForm}>\n <div style={styles.editTarget}>{anchorId}</div>\n <label style={styles.editLabel}>Attribute</label>\n <input\n style={styles.editInput}\n value={(item.attr as string) || ''}\n onChange={(e) => handleFieldChange(section, index, 'attr', e.target.value)}\n />\n <label style={styles.editLabel}>Value</label>\n <input\n style={styles.editInput}\n value={(item.value as string) || ''}\n onChange={(e) => handleFieldChange(section, index, 'value', e.target.value)}\n />\n </div>\n );\n\n case 'styleChanges': {\n const styleObj = (item.styles as Record<string, string>) || {};\n return (\n <div style={styles.editForm}>\n <div style={styles.editTarget}>{anchorId}</div>\n <label style={styles.editLabel}>Styles</label>\n {Object.entries(styleObj).map(([prop, val]) => (\n <div key={prop} style={{ display: 'flex', gap: '4px', marginBottom: '4px' }}>\n <input\n style={{ ...styles.editInput, flex: 1, marginBottom: 0 }}\n value={prop}\n readOnly\n />\n <input\n style={{ ...styles.editInput, flex: 1, marginBottom: 0 }}\n value={val}\n onChange={(e) => {\n const newStyles = { ...styleObj, [prop]: e.target.value };\n handleFieldChange(section, index, 'styles', newStyles);\n }}\n />\n </div>\n ))}\n </div>\n );\n }\n\n case 'htmlInsertions':\n return (\n <div style={styles.editForm}>\n <div style={styles.editTarget}>{anchorId}</div>\n <label style={styles.editLabel}>Position</label>\n <select\n style={styles.editSelect}\n value={(item.position as string) || 'after'}\n onChange={(e) => handleFieldChange(section, index, 'position', e.target.value)}\n >\n <option value=\"before\">Before</option>\n <option value=\"after\">After</option>\n <option value=\"prepend\">Prepend</option>\n <option value=\"append\">Append</option>\n <option value=\"replace\">Replace</option>\n </select>\n <label style={styles.editLabel}>HTML</label>\n <textarea\n style={{ ...styles.editTextarea, fontFamily: 'monospace' }}\n value={(item.html as string) || ''}\n onChange={(e) => handleFieldChange(section, index, 'html', e.target.value)}\n />\n </div>\n );\n\n case 'classAdditions':\n case 'classRemovals':\n return (\n <div style={styles.editForm}>\n <div style={styles.editTarget}>{anchorId}</div>\n <label style={styles.editLabel}>Class Name</label>\n <input\n style={styles.editInput}\n value={(item.className as string) || ''}\n onChange={(e) => handleFieldChange(section, index, 'className', e.target.value)}\n />\n </div>\n );\n\n default:\n return null;\n }\n };\n\n return (\n <div style={styles.container}>\n {/* Header */}\n <div style={styles.header}>\n <button\n onClick={() => (editingKey !== null ? handleBackToList() : editor.navigateHome())}\n style={styles.backButton}\n >\n ← Back\n </button>\n <div>\n <h2 style={styles.title}>Review Changes</h2>\n <p style={styles.subtitle}>\n {totalChanges} change{totalChanges !== 1 ? 's' : ''}\n {totalChanges > 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 ref = parseItemKey(editingKey);\n const editItem = allItems.find((it) => it.key === editingKey);\n return (\n <>\n <div style={styles.editHeader}>\n <span>{editItem?.icon}</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(ref.section, ref.index)}\n </>\n );\n })()\n ) : (\n /* ---- List mode ---- */\n <>\n {allItems.length === 0 && (\n <div style={styles.emptyState}>No content changes configured.</div>\n )}\n\n {activeItems.length > 0 && (\n <>\n <div style={styles.groupHeader}>\n <span>CONTENT</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 <DetectionBadge found={detection?.found ?? false} />\n <span\n style={styles.cardIcon}\n onClick={(e) => {\n e.stopPropagation();\n handleCardClick(item);\n }}\n >\n {item.icon}\n </span>\n <span style={styles.cardText} onClick={() => handleCardClick(item)}>\n {item.summary}\n </span>\n <button\n style={styles.dismissButton}\n onClick={(e) => {\n e.stopPropagation();\n handleDismiss(item.key);\n }}\n title=\"Dismiss this change\"\n >\n ×\n </button>\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.cardIcon}>{item.icon}</span>\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 module configuration.\n */\nexport const editor = {\n panel: {\n title: 'Content',\n icon: '\\u{1f4dd}',\n description: 'Text and attribute modifications',\n },\n component: ContentEditor,\n};\n\nexport const editorPanel = editor.panel;\n\nexport default ContentEditor;\n", "/**\n * HTML Sanitizer\n *\n * Sanitizes HTML to prevent XSS attacks.\n * Uses native Sanitizer API when available, falls back to whitelist approach.\n */\n\nconst ALLOWED_TAGS = new Set([\n 'b',\n 'strong',\n 'i',\n 'em',\n 'u',\n 'span',\n 'div',\n 'p',\n 'br',\n 'ul',\n 'ol',\n 'li',\n 'code',\n 'pre',\n 'small',\n 'sup',\n 'sub',\n 'a',\n 'button',\n]);\n\nexport function sanitizeHtml(html: string): string {\n // Try native Sanitizer API first\n const hasNative = typeof (window as any).Sanitizer === 'function';\n if (hasNative) {\n try {\n const s = new (window as any).Sanitizer({});\n const frag = s.sanitizeToFragment(html);\n const div = document.createElement('div');\n div.append(frag);\n return div.innerHTML;\n } catch {\n // Fall through to manual sanitizer\n }\n }\n\n // Conservative fallback sanitizer\n const tpl = document.createElement('template');\n tpl.innerHTML = html;\n const root = tpl.content;\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null);\n const toRemove: Element[] = [];\n\n while (walker.nextNode()) {\n const el = walker.currentNode as Element;\n const tag = el.tagName.toLowerCase();\n\n if (!ALLOWED_TAGS.has(tag)) {\n toRemove.push(el);\n continue;\n }\n\n // Remove dangerous attributes\n for (const attr of Array.from(el.attributes)) {\n const name = attr.name.toLowerCase();\n const value = attr.value.trim().toLowerCase();\n const isEvent = name.startsWith('on');\n const isJsUrl = (name === 'href' || name === 'src') && value.startsWith('javascript:');\n\n if (isEvent || isJsUrl) {\n el.removeAttribute(attr.name);\n }\n }\n }\n\n // Remove disallowed elements but keep their children\n for (const el of toRemove) {\n while (el.firstChild) {\n el.parentNode?.insertBefore(el.firstChild, el);\n }\n el.remove();\n }\n\n return tpl.innerHTML;\n}\n", "/**\n * Adaptive Content - Runtime Module\n *\n * DOM manipulation actions: insertHtml, setText, setAttr, addClass, removeClass, setStyle.\n * These follow the hostPatcher snapshot pattern for safe reversibility.\n */\n\nimport { sanitizeHtml } from './sanitizer';\nimport type {\n InsertHtmlAction,\n SetTextAction,\n SetAttrAction,\n AddClassAction,\n RemoveClassAction,\n SetStyleAction,\n ExecutorResult,\n ActionExecutor,\n} from './types';\n\n// ============================================================================\n// Executors\n// ============================================================================\n\n/**\n * Execute an insertHtml action\n */\nexport const executeInsertHtml: ActionExecutor<InsertHtmlAction> = 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 // Sanitize HTML content using context utility\n const sanitizedHtml = sanitizeHtml(action.html);\n\n // Create container for inserted content\n const container = document.createElement('div');\n container.setAttribute('data-syntro-action-id', context.generateId());\n container.innerHTML = sanitizedHtml;\n\n // Keep track of original state for replace position\n let originalContent: string | null = null;\n\n switch (action.position) {\n case 'before':\n anchorEl.insertAdjacentElement('beforebegin', container);\n break;\n case 'after':\n anchorEl.insertAdjacentElement('afterend', container);\n break;\n case 'prepend':\n anchorEl.insertBefore(container, anchorEl.firstChild);\n break;\n case 'append':\n anchorEl.appendChild(container);\n break;\n case 'replace':\n originalContent = anchorEl.innerHTML;\n anchorEl.replaceWith(container);\n break;\n }\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'content:insertHtml',\n anchorId: action.anchorId,\n position: action.position,\n });\n\n return {\n cleanup: () => {\n if (action.position === 'replace' && originalContent !== null) {\n // Restore original element\n const restoredEl = document.createElement(anchorEl.tagName);\n restoredEl.innerHTML = originalContent;\n // Copy attributes\n Array.from(anchorEl.attributes).forEach((attr) => {\n restoredEl.setAttribute(attr.name, attr.value);\n });\n container.replaceWith(restoredEl);\n } else {\n container.remove();\n }\n },\n updateFn: (changes) => {\n if ('html' in changes && typeof changes.html === 'string') {\n container.innerHTML = sanitizeHtml(changes.html);\n }\n },\n };\n};\n\n/**\n * Execute a setText action\n */\nexport const executeSetText: ActionExecutor<SetTextAction> = 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 // Snapshot original text\n const originalText = anchorEl.textContent ?? '';\n\n // Set new text\n anchorEl.textContent = action.text;\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'content:setText',\n anchorId: action.anchorId,\n });\n\n return {\n cleanup: () => {\n anchorEl.textContent = originalText;\n },\n updateFn: (changes) => {\n if ('text' in changes && typeof changes.text === 'string') {\n anchorEl.textContent = changes.text;\n }\n },\n };\n};\n\n/**\n * Execute a setAttr action\n */\nexport const executeSetAttr: ActionExecutor<SetAttrAction> = 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 // Block dangerous attributes\n const dangerousAttrs = ['onclick', 'onerror', 'onload', 'onmouseover', 'onfocus', 'onblur'];\n if (dangerousAttrs.includes(action.attr.toLowerCase()) || action.attr.startsWith('on')) {\n throw new Error(`Dangerous attribute not allowed: ${action.attr}`);\n }\n\n // Snapshot original attribute value\n const originalValue = anchorEl.getAttribute(action.attr);\n const hadAttribute = anchorEl.hasAttribute(action.attr);\n\n // Set new attribute\n anchorEl.setAttribute(action.attr, action.value);\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'content:setAttr',\n anchorId: action.anchorId,\n attr: action.attr,\n });\n\n return {\n cleanup: () => {\n if (hadAttribute && originalValue !== null) {\n anchorEl.setAttribute(action.attr, originalValue);\n } else {\n anchorEl.removeAttribute(action.attr);\n }\n },\n updateFn: (changes) => {\n if ('value' in changes && typeof changes.value === 'string') {\n anchorEl.setAttribute(action.attr, changes.value);\n }\n },\n };\n};\n\n/**\n * Execute an addClass action\n */\nexport const executeAddClass: ActionExecutor<AddClassAction> = 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 // Check if class was already present\n const hadClass = anchorEl.classList.contains(action.className);\n\n // Add class\n anchorEl.classList.add(action.className);\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'content:addClass',\n anchorId: action.anchorId,\n className: action.className,\n });\n\n return {\n cleanup: () => {\n // Only remove if we added it\n if (!hadClass) {\n anchorEl.classList.remove(action.className);\n }\n },\n };\n};\n\n/**\n * Execute a removeClass action\n */\nexport const executeRemoveClass: ActionExecutor<RemoveClassAction> = 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 // Check if class was present\n const hadClass = anchorEl.classList.contains(action.className);\n\n // Remove class\n anchorEl.classList.remove(action.className);\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'content:removeClass',\n anchorId: action.anchorId,\n className: action.className,\n });\n\n return {\n cleanup: () => {\n // Only re-add if we removed it\n if (hadClass) {\n anchorEl.classList.add(action.className);\n }\n },\n };\n};\n\n/**\n * Execute a setStyle action\n */\nexport const executeSetStyle: ActionExecutor<SetStyleAction> = 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 // Snapshot original styles\n const originalStyles = new Map<string, string>();\n for (const prop of Object.keys(action.styles)) {\n const current = (anchorEl as HTMLElement).style.getPropertyValue(prop);\n originalStyles.set(prop, current);\n }\n\n // Apply new styles\n for (const [prop, value] of Object.entries(action.styles)) {\n (anchorEl as HTMLElement).style.setProperty(prop, value);\n }\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'content:setStyle',\n anchorId: action.anchorId,\n styles: Object.keys(action.styles),\n });\n\n return {\n cleanup: () => {\n // Restore original styles\n for (const [prop, originalValue] of originalStyles) {\n if (originalValue) {\n (anchorEl as HTMLElement).style.setProperty(prop, originalValue);\n } else {\n (anchorEl as HTMLElement).style.removeProperty(prop);\n }\n }\n },\n updateFn: (changes) => {\n if ('styles' in changes && typeof changes.styles === 'object' && changes.styles) {\n for (const [prop, value] of Object.entries(changes.styles as Record<string, string>)) {\n (anchorEl as HTMLElement).style.setProperty(prop, value);\n }\n }\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: 'content:insertHtml', executor: executeInsertHtml },\n { kind: 'content:setText', executor: executeSetText },\n { kind: 'content:setAttr', executor: executeSetAttr },\n { kind: 'content:addClass', executor: executeAddClass },\n { kind: 'content:removeClass', executor: executeRemoveClass },\n { kind: 'content:setStyle', executor: executeSetStyle },\n] as const;\n\n/**\n * App runtime manifest.\n */\nexport const runtime = {\n id: 'adaptive-content',\n version: '1.0.0',\n name: 'Content',\n description: 'DOM manipulation for text, attributes, and styles',\n executors,\n};\n", "/**\n * CDN Entry Point for Adaptive Content\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, 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: runtime.id,\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 },\n editor,\n metadata: {\n isBuiltIn: true,\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", "useState", "R", "useEffect", "useMemo", "useCallback", "useRef", "useContext", "useReducer", "createElement", "createContext", "Fragment", "forwardRef", "memo", "lazy", "Suspense", "Children", "isValidElement", "cloneElement", "Component", "PureComponent", "useLayoutEffect", "useId", "describeSelector", "selector", "name", "prefixes", "prefix", "truncate", "testIdMatch", "text", "max", "truncateQuoted", "summarizeContentChange", "type", "item", "desc", "attr", "value", "styles", "count", "_getR", "_jsx", "type", "props", "key", "R", "p", "jsx", "jsxs", "Fragment", "itemKey", "section", "index", "parseItemKey", "key", "indexStr", "SECTION_ICONS", "styles", "flattenItems", "config", "items", "sections", "item", "i", "rec", "summarizeContentChange", "filterConfig", "dismissedKeys", "result", "filtered", "_", "useAnchorDetection", "detectionMap", "setDetectionMap", "useState", "itemsRef", "useRef", "useEffect", "runDetection", "map", "el", "interval", "DetectionBadge", "found", "jsx", "ContentEditor", "onChange", "editor", "typedConfig", "setDismissedKeys", "dismissedOpen", "setDismissedOpen", "editingKey", "setEditingKey", "previewMode", "setPreviewMode", "initialConsumed", "allFlat", "targetIdx", "target", "allItems", "activeItems", "dismissedItems", "totalChanges", "_hoveredKey", "setHoveredKey", "foundCount", "handleDismiss", "useCallback", "prev", "next", "handleRestore", "handleCardClick", "handleBackToList", "handleBeforeAfter", "mode", "handleFieldChange", "field", "value", "arr", "updated", "handlePublish", "handleCardHover", "handleCardLeave", "renderEditFields", "anchorId", "jsxs", "e", "styleObj", "prop", "val", "newStyles", "ref", "editItem", "it", "Fragment", "detection", "editorPanel", "ALLOWED_TAGS", "sanitizeHtml", "html", "frag", "div", "tpl", "root", "walker", "toRemove", "el", "tag", "attr", "name", "value", "isEvent", "isJsUrl", "executeInsertHtml", "action", "context", "anchorEl", "sanitizedHtml", "sanitizeHtml", "container", "originalContent", "restoredEl", "attr", "changes", "executeSetText", "originalText", "executeSetAttr", "originalValue", "hadAttribute", "executeAddClass", "hadClass", "executeRemoveClass", "executeSetStyle", "originalStyles", "prop", "current", "value", "executors", "runtime", "manifest", "runtime", "executors", "kind", "executor", "editor", "registry", "cdn_default"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var g=globalThis.__SYNTRO_REACT__||{},K=g,C=g.useState,D=g.useEffect,q=g.useMemo,k=g.useCallback,U=g.useRef,_e=g.useContext,G=g.useReducer,He=g.createElement,Le=g.createContext,De=g.Fragment,We=g.forwardRef,Ne=g.memo,Oe=g.lazy,Ve=g.Suspense,$e=g.Children,je=g.isValidElement,Ke=g.cloneElement,Ue=g.Component,Xe=g.PureComponent,Ye=g.useLayoutEffect,Ge=g.useId;function J(e,n){return e.length<=n?e:`${e.slice(0,n).trimEnd()}...`}function ye(e){return e.replace(/<[^>]*>/g,"").trim()}function he(e){return typeof e=="string"?e:e.type==="rich"?ye(e.html):e.content.replace(/[*_#`]/g,"").trim()}function ve(e){return typeof e=="object"&&e!==null&&e.type==="rules"&&Array.isArray(e.rules)}function Z(e){if(!e||!ve(e))return"All pages";let n=[],t=[];for(let a of e.rules)for(let l of a.conditions)l.type==="page_url"&&typeof l.url=="string"&&n.push(l.url),l.type==="anchor_visible"&&typeof l.anchorId=="string"&&t.push(l.anchorId);let r=[];return n.length>0&&r.push(n[0]),t.length>0&&r.push(t[0]),r.length>0?r.join(" \xB7 "):"All pages"}function ee(e){let n=J(e.config.question,50),t=J(he(e.config.answer),40);return`Q: "${n}" \u2014 ${t}`}function P(e){return e.kind.startsWith("faq:")}function te(){return globalThis.__SYNTRO_REACT__}function ne(e,n,t){var r=te(),a=n||{},l=a.children;return delete a.children,t!==void 0&&(a.key=t),Array.isArray(l)?r.createElement.apply(null,[e,a].concat(l)):l!==void 0?r.createElement(e,a,l):r.createElement(e,a)}var i=ne,p=ne,O=(te()||{}).Fragment;function ke(e){return typeof e=="object"&&e!==null&&e.type==="rules"&&Array.isArray(e.rules)}function X(e){if(!e||!ke(e))return{pagePatterns:[],anchorSelectors:[],hasTargeting:!1};let n=new Set,t=new Set;for(let a of e.rules)for(let l of a.conditions){let d=l;d.type==="page_url"&&typeof d.url=="string"?n.add(d.url):d.type==="anchor_visible"&&typeof d.anchorId=="string"&&t.add(d.anchorId)}let r=n.size>0||t.size>0;return{pagePatterns:[...n],anchorSelectors:[...t],hasTargeting:r}}function Se(e){return X(e).pagePatterns[0]||null}function Ae(e){return X(e).anchorSelectors[0]||null}function we(e){return typeof e=="string"?e:e.type==="rich"?e.html:e.content}function Ce(e){return(e.actions||[]).filter(P).map((t,r)=>({key:String(r),index:r,summary:ee(t),trigger:Z(t.showWhen),rationale:t.rationale,firstAnchor:Ae(t.showWhen),question:t}))}function oe(e,n){let t=(e.actions||[]).filter(P);return{...e,actions:t.filter((r,a)=>!n.has(String(a)))}}function Fe(e,n){let[t,r]=C(new Map),a=U(e);return a.current=e,D(()=>{let l=()=>{let R=new Map,h=n();for(let x of a.current){let S=X(x.question.showWhen),A=!0;S.pagePatterns.length>0&&(A=S.pagePatterns.some(I=>new RegExp(`^${I.replace(/\*\*/g,".*").replace(/(?<!\.)(\*)/g,"[^/]*")}$`).test(h)));let Q=!1,y=null;if(x.firstAnchor)try{y=document.querySelector(x.firstAnchor),Q=y!==null}catch{}else Q=A;R.set(x.key,{found:A&&Q,element:y})}r(R)};l();let d=setInterval(l,2e3);return window.addEventListener("popstate",l),()=>{clearInterval(d),window.removeEventListener("popstate",l)}},[n]),t}function Re({found:e}){return i("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 c={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"},editTextarea:{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",resize:"vertical",minHeight:"60px",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"}};function Qe({config:e,onChange:n,editor:t}){let r=e,[a,l]=C(new Set),[d,R]=C(!1),[h,x]=C(null),[S,A]=C("after"),[Q,y]=C(null),I=U(!1);D(()=>{!I.current&&(t.initialEditKey!=null||t.initialCreate)&&(I.current=!0,t.clearInitialState?.())},[t]);let F=Ce(r),v=F.filter(o=>!a.has(o.key)),z=F.filter(o=>a.has(o.key)),_=v.length,H=Fe(F,t.getCurrentRoute),V=v.filter(o=>H.get(o.key)?.found).length,$=k(o=>{l(m=>{let f=new Set(m);return f.add(o),f}),h===o&&x(null)},[h]),j=k(o=>{l(m=>{let f=new Set(m);return f.delete(o),f})},[]),W=k(o=>{x(o.key)},[]),s=k(o=>{let m=Se(o.question.showWhen);m&&t.navigateTo(m),o.firstAnchor&&t.highlightElement(o.firstAnchor)},[t]),u=k(()=>{x(null),A("after"),t.previewConfig(e),t.clearHighlight()},[t,e]),w=k(o=>{if(A(o),o==="before"){let m=oe(r,new Set([h]));t.previewConfig(m)}else t.previewConfig(e)},[r,h,t,e]),L=k((o,m,f)=>{let E=(r.actions||[]).filter(P).slice(),T={...E[o],config:{...E[o].config}};T.config[m]=f,E[o]=T;let xe=(r.actions||[]).filter(be=>!P(be)),me={...r,actions:[...xe,...E]};n(me),t.setDirty(!0)},[r,n,t]),N=k(()=>{if(a.size>0){let o=oe(r,a);n(o)}t.publish()},[a,r,n,t]),ue=k(o=>{y(o.key),o.firstAnchor&&t.highlightElement(o.firstAnchor)},[t]),ge=k(()=>{y(null),t.clearHighlight()},[t]),fe=o=>{let f=(r.actions||[]).filter(P)[o];if(!f)return null;let E=F.find(T=>T.key===String(o));return p("div",{style:c.editForm,children:[E&&E.trigger!=="All pages"&&p("div",{"data-trigger":!0,style:c.triggerLine,onClick:()=>s(E),children:[i("span",{children:"\u{1F4CD}"}),i("span",{children:E.trigger})]}),i("label",{style:c.editLabel,children:"Question"}),i("input",{style:c.editInput,value:f.config.question,onChange:T=>L(o,"question",T.target.value)}),i("label",{style:c.editLabel,children:"Answer"}),i("textarea",{style:c.editTextarea,value:we(f.config.answer),onChange:T=>L(o,"answer",T.target.value)}),i("label",{style:c.editLabel,children:"Category"}),i("input",{style:c.editInput,value:f.config.category||"",onChange:T=>L(o,"category",T.target.value||void 0),placeholder:"e.g., Billing, Account"}),i("label",{style:c.editLabel,children:"AI Rationale"}),i("div",{style:c.editRationale,children:f.rationale?f.rationale.why:"N/A"})]})};return p("div",{style:c.container,children:[p("div",{style:c.header,children:[i("button",{onClick:()=>t.navigateHome(),style:c.backButton,children:"\u2190 Back"}),p("div",{children:[i("h2",{style:c.title,children:"Review Questions"}),p("p",{style:c.subtitle,children:[_," question",_!==1?"s":"",_>0&&` (${V} found on this page)`]})]})]}),i("div",{style:c.body,children:h!==null?(()=>{let o=Number(h),m=F.find(f=>f.key===h);return p(O,{children:[p("div",{style:c.editHeader,children:[i("span",{children:"\u2753"}),i("span",{children:m?.summary})]}),p("div",{style:{display:"flex",gap:"0",marginBottom:"12px",borderRadius:"6px",overflow:"hidden",border:"1px solid rgba(255,255,255,0.1)"},children:[i("button",{onClick:()=>w("before"),style:{flex:1,padding:"6px 12px",border:"none",fontSize:"12px",fontWeight:600,cursor:"pointer",background:S==="before"?"rgba(59,130,246,0.2)":"transparent",color:S==="before"?"#3b82f6":"#64748b"},children:"Before"}),i("button",{onClick:()=>w("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:S==="after"?"rgba(59,130,246,0.2)":"transparent",color:S==="after"?"#3b82f6":"#64748b"},children:"After"})]}),fe(o),i("button",{style:c.editBackButton,onClick:u,children:"\u2190 List"})]})})():p(O,{children:[F.length===0&&i("div",{style:c.emptyState,children:"No FAQ questions configured."}),v.length>0&&p(O,{children:[p("div",{style:c.groupHeader,children:[i("span",{children:"FAQ"}),i("span",{style:c.groupCount,children:v.length})]}),v.map(o=>{let m=H.get(o.key);return p("div",{style:c.card,"data-item-key":o.key,onMouseEnter:()=>ue(o),onMouseLeave:ge,children:[o.trigger!=="All pages"&&p("div",{"data-trigger":!0,style:c.triggerLine,onClick:f=>{f.stopPropagation(),s(o)},children:[i("span",{children:"\u{1F4CD}"}),i("span",{children:o.trigger})]}),p("div",{"data-card-body":!0,style:c.cardBody,onClick:()=>W(o),children:[i(Re,{found:m?.found??!1}),i("span",{style:c.cardText,children:o.summary}),i("button",{style:c.dismissButton,onClick:f=>{f.stopPropagation(),$(o.key)},title:"Dismiss this question",children:"\xD7"})]}),p("div",{style:c.rationaleLine,children:["WHY: ",o.rationale?o.rationale.why:"N/A"]})]},o.key)})]}),z.length>0&&p("div",{style:c.dismissedSection,children:[p("div",{style:{...c.dismissedHeader,cursor:"pointer"},onClick:()=>R(!d),children:[i("span",{children:d?"\u25BE":"\u25B8"}),p("span",{children:["Dismissed (",z.length,")"]})]}),d&&i("div",{style:{marginTop:"6px"},children:z.map(o=>p("div",{style:c.dismissedCard,children:[i("span",{style:{...c.cardText,textDecoration:"line-through"},children:o.summary}),i("button",{style:{...c.dismissButton,color:"#3b82f6",fontSize:"11px"},onClick:m=>{m.stopPropagation(),j(o.key)},children:"Restore"})]},o.key))})]})]})}),p("div",{style:c.footer,children:[i("button",{onClick:()=>t.save(),style:c.saveButton,children:"Save Draft"}),i("button",{onClick:N,style:c.publishButton,children:"Publish"})]})]})}var re={title:"FAQ",icon:"\u2753",description:"FAQ accordion with per-item visibility"};var ie=Qe;function ae(e,n,t){if(n){let r=e.getState().items.find(a=>a.config.id===n);if(r)return r}if(t){let r=e.findByQuestion(t);if(r)return r}throw new Error("FAQ item not found")}async function Te(e,n,t){let r=ae(t,e.itemId,e.itemQuestion),{id:a}=r.config;e.expand!==!1&&t.expand(a);let l=document.querySelector(`[data-faq-item-id="${a}"]`);return l&&l.scrollIntoView({behavior:e.behavior??"smooth"}),n.publishEvent("faq:scroll_to",{itemId:a}),{cleanup:()=>{}}}async function Ee(e,n,t){let r=ae(t,e.itemId,e.itemQuestion),{id:a}=r.config,l=e.state??"toggle",d;switch(l){case"open":t.expand(a),d="open";break;case"closed":t.collapse(a),d="closed";break;default:{let R=t.getState().expandedItems.has(a);t.toggle(a),d=R?"closed":"open";break}}return n.publishEvent("faq:toggle",{itemId:a,newState:d}),{cleanup:()=>{}}}async function Ie(e,n,t){switch(e.operation){case"add":{let r=e.items??[],a=e.position==="prepend"?"prepend":"append";t.addItems(r,a);break}case"remove":{if(!e.itemId)throw new Error("FAQ item not found");if(!t.getState().items.some(a=>a.config.id===e.itemId))throw new Error("FAQ item not found");t.removeItem(e.itemId);break}case"reorder":{let r=e.order??[];t.reorderItems(r);break}case"replace":{let r=e.items??[];t.replaceItems(r);break}}return n.publishEvent("faq:update",{operation:e.operation}),{cleanup:()=>{}}}var se=[{kind:"faq:scroll_to",executor:Te},{kind:"faq:toggle_item",executor:Ee},{kind:"faq:update",executor:Ie}];var ce=globalThis.__SYNTRO_REACT_DOM__;var Y=ce?.createRoot,lt=ce?.createPortal;function le(e){return typeof e=="string"?e:e.type==="rich"?e.html:e.content}function qe(e){return typeof e=="string"?i("p",{style:{margin:0},children:e}):e.type==="rich"?i("div",{style:{margin:0},dangerouslySetInnerHTML:{__html:e.html}}):i("p",{style:{margin:0},children:e.content})}function Pe(e){return e?e===!0?{style:"thumbs"}:e:null}function Be(e){return e.prompt||"Was this helpful?"}var b={container:{fontFamily:"system-ui, -apple-system, sans-serif",maxWidth:"800px",margin:"0 auto"},searchWrapper:{marginBottom:"16px"},searchInput:{width:"100%",padding:"12px 16px",borderRadius:"8px",fontSize:"14px",outline:"none",transition:"border-color 0.15s ease"},accordion:{display:"flex",flexDirection:"column",gap:"8px"},item:{borderRadius:"8px",overflow:"hidden",transition:"box-shadow 0.15s ease"},question:{width:"100%",padding:"16px 20px",display:"flex",alignItems:"center",justifyContent:"space-between",border:"none",cursor:"pointer",fontSize:"15px",fontWeight:500,textAlign:"left",transition:"background-color 0.15s ease"},chevron:{fontSize:"18px",transition:"transform 0.2s ease"},answer:{padding:"0 20px 16px 20px",fontSize:"14px",lineHeight:1.6,overflow:"hidden",transition:"max-height 0.2s ease, padding 0.2s ease"},category:{display:"inline-block",fontSize:"11px",fontWeight:600,textTransform:"uppercase",letterSpacing:"0.05em",padding:"4px 8px",borderRadius:"4px",marginBottom:"8px"},categoryHeader:{fontSize:"13px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.05em",padding:"12px 4px 6px 4px",marginTop:"8px"},feedback:{display:"flex",alignItems:"center",gap:"8px",marginTop:"12px",paddingTop:"10px",borderTop:"1px solid rgba(0, 0, 0, 0.08)",fontSize:"13px"},feedbackButton:{background:"none",border:"1px solid transparent",cursor:"pointer",fontSize:"16px",padding:"4px 8px",borderRadius:"4px",transition:"background-color 0.15s ease, border-color 0.15s ease"},feedbackButtonSelected:{borderColor:"rgba(0, 0, 0, 0.2)",backgroundColor:"rgba(0, 0, 0, 0.04)"},emptyState:{textAlign:"center",padding:"48px 24px",fontSize:"14px"},noResults:{textAlign:"center",padding:"32px 16px",fontSize:"14px"}},B={light:{container:{backgroundColor:"#ffffff",color:"#111827"},searchInput:{backgroundColor:"#f9fafb",border:"1px solid #e5e7eb",color:"#111827"},item:{backgroundColor:"#f9fafb",border:"1px solid #e5e7eb"},itemExpanded:{boxShadow:"0 4px 12px rgba(0, 0, 0, 0.08)"},question:{backgroundColor:"transparent",color:"#111827"},questionHover:{backgroundColor:"#f3f4f6"},answer:{color:"#4b5563"},category:{backgroundColor:"#e0e7ff",color:"#4338ca"},categoryHeader:{color:"#6b7280"},emptyState:{color:"#9ca3af"},feedbackPrompt:{color:"#6b7280"}},dark:{container:{backgroundColor:"#111827",color:"#f9fafb"},searchInput:{backgroundColor:"#1f2937",border:"1px solid #374151",color:"#f9fafb"},item:{backgroundColor:"#1f2937",border:"1px solid #374151"},itemExpanded:{boxShadow:"0 4px 12px rgba(0, 0, 0, 0.3)"},question:{backgroundColor:"transparent",color:"#f9fafb"},questionHover:{backgroundColor:"#374151"},answer:{color:"#9ca3af"},category:{backgroundColor:"#312e81",color:"#a5b4fc"},categoryHeader:{color:"#9ca3af"},emptyState:{color:"#6b7280"},feedbackPrompt:{color:"#9ca3af"}}};function Me({item:e,isExpanded:n,onToggle:t,theme:r,feedbackConfig:a,feedbackValue:l,onFeedback:d}){let[R,h]=C(!1),x=B[r],{question:S,answer:A}=e.config,Q={...b.item,...x.item,...n?x.itemExpanded:{}},y={...b.question,...x.question,...R?x.questionHover:{}},I={...b.chevron,transform:n?"rotate(180deg)":"rotate(0deg)"},F={...b.answer,...x.answer,maxHeight:n?"500px":"0",paddingBottom:n?"16px":"0"},v={...b.feedback,...x.feedbackPrompt};return p("div",{style:Q,"data-faq-item-id":e.config.id,children:[p("button",{style:y,onClick:t,onMouseEnter:()=>h(!0),onMouseLeave:()=>h(!1),"aria-expanded":n,children:[i("span",{children:S}),i("span",{style:I,children:"\u25BC"})]}),p("div",{style:F,"aria-hidden":!n,children:[qe(A),n&&a&&p("div",{style:v,children:[i("span",{children:Be(a)}),i("button",{style:{...b.feedbackButton,...l==="up"?b.feedbackButtonSelected:{}},"aria-label":"Thumbs up",onClick:()=>d(e.config.id,S,"up"),children:"\u{1F44D}"}),i("button",{style:{...b.feedbackButton,...l==="down"?b.feedbackButtonSelected:{}},"aria-label":"Thumbs down",onClick:()=>d(e.config.id,S,"down"),children:"\u{1F44E}"})]})]})]})}function ze({config:e,runtime:n,instanceId:t}){let[,r]=G(s=>s+1,0),[a,l]=C(new Set),[d,R]=C(""),[h,x]=C(new Map),S=q(()=>Pe(e.feedback),[e.feedback]);D(()=>n.context.subscribe(()=>{r()}),[n.context]);let A=q(()=>e.actions.filter(s=>s.showWhen?n.evaluateSync(s.showWhen).value:!0),[e.actions,n]),Q=q(()=>e.ordering==="priority"?[...A].sort((s,u)=>(u.config.priority??0)-(s.config.priority??0)):A,[A,e.ordering]),y=q(()=>{if(!e.searchable||!d.trim())return Q;let s=d.toLowerCase();return Q.filter(u=>u.config.question.toLowerCase().includes(s)||le(u.config.answer).toLowerCase().includes(s)||u.config.category?.toLowerCase().includes(s))},[Q,d,e.searchable]),I=q(()=>{let s=new Map;for(let u of y){let w=u.config.category;s.has(w)||s.set(w,[]),s.get(w).push(u)}return s},[y]),F=q(()=>y.some(s=>s.config.category),[y]),v=q(()=>e.theme!=="auto"?e.theme:typeof window<"u"&&window.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light",[e.theme]),z=k(s=>{l(u=>{let w=new Set(u);return e.expandBehavior==="single"?u.has(s)?new Set:new Set([s]):(u.has(s)?w.delete(s):w.add(s),w)}),n.events.publish("faq:toggled",{instanceId:t,questionId:s,expanded:!a.has(s),timestamp:Date.now()})},[e.expandBehavior,n.events,t,a]),_=k((s,u,w)=>{x(L=>{let N=new Map(L);return N.set(s,w),N}),n.events.publish("faq:feedback",{itemId:s,question:u,value:w})},[n.events]),H={...b.container,...B[v].container},V={...b.searchInput,...B[v].searchInput},$={...b.emptyState,...B[v].emptyState},j={...b.categoryHeader,...B[v].categoryHeader},W=s=>s.map(u=>i(Me,{item:u,isExpanded:a.has(u.config.id),onToggle:()=>z(u.config.id),theme:v,feedbackConfig:S,feedbackValue:h.get(u.config.id),onFeedback:_},u.config.id));return A.length===0?i("div",{style:H,"data-adaptive-id":t,"data-adaptive-type":"adaptive-faq",children:i("div",{style:$,children:"No FAQ questions available."})}):p("div",{style:H,"data-adaptive-id":t,"data-adaptive-type":"adaptive-faq",children:[e.searchable&&i("div",{style:b.searchWrapper,children:i("input",{type:"text",placeholder:"Search questions...",value:d,onChange:s=>R(s.target.value),style:V})}),i("div",{style:b.accordion,children:F?Array.from(I.entries()).map(([s,u])=>p(K.Fragment,{children:[s&&i("div",{style:j,"data-category-header":s,children:s}),W(u)]},s??"__ungrouped")):W(y)}),e.searchable&&y.length===0&&d&&p("div",{style:{...b.noResults,...B[v].emptyState},children:['No questions found matching "',d,'"']})]})}var de={mount(e,n){let{runtime:t,instanceId:r="faq-widget",...a}=n||{expandBehavior:"single",searchable:!1,theme:"auto",actions:[]};if(t&&typeof Y=="function"){let d=Y(e);return d.render(K.createElement(ze,{config:a,runtime:t,instanceId:r})),()=>{d.unmount()}}let l=a.actions||[];return e.innerHTML=`
|
|
2
|
+
<div style="font-family: system-ui; max-width: 800px;">
|
|
3
|
+
${l.map(d=>`
|
|
4
|
+
<div style="margin-bottom: 8px; padding: 16px; background: #f9fafb; border-radius: 8px;">
|
|
5
|
+
<strong>${d.config.question}</strong>
|
|
6
|
+
<p style="margin-top: 8px; color: #4b5563;">${le(d.config.answer)}</p>
|
|
7
|
+
</div>
|
|
8
|
+
`).join("")}
|
|
9
|
+
</div>
|
|
10
|
+
`,()=>{e.innerHTML=""}}};var M={id:"adaptive-faq",version:"2.0.0",name:"FAQ Accordion",description:"Collapsible Q&A accordion with actions, rich content, feedback, and personalization",executors:se,widgets:[{id:"adaptive-faq:accordion",component:de,metadata:{name:"FAQ Accordion",description:"Collapsible Q&A accordion with search, categories, and feedback",icon:"\u2753"}}]};var pe={id:"adaptive-faq",version:M.version,name:M.name,description:M.description,runtime:{actions:M.executors,widgets:M.widgets},editor:{component:ie,panel:re},metadata:{isBuiltIn:!1}};if(typeof window<"u"){let e=window.SynOS?.appRegistry;e&&typeof e.register=="function"&&e.register(pe)}var vt=pe;export{vt as default,pe as manifest};
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -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 ← 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 ← 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 ×\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 "{searchQuery}"\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": "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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", "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
|