@ccslabs/xtend 0.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (664) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/LICENSE +201 -0
  3. package/README.md +184 -0
  4. package/a11y/motion-contrast-policy.d.ts +32 -0
  5. package/a11y/motion-contrast-policy.js +261 -0
  6. package/a11y/runtime-a11y-contract.d.ts +44 -0
  7. package/a11y/runtime-a11y-contract.js +385 -0
  8. package/a11y/screenreader-signals.d.ts +32 -0
  9. package/a11y/screenreader-signals.js +372 -0
  10. package/api.d.ts +168 -0
  11. package/api.js +864 -0
  12. package/catalog/catalog-public-types.d.ts +66 -0
  13. package/catalog/component-catalog-coverage.d.ts +20 -0
  14. package/catalog/component-catalog-coverage.js +377 -0
  15. package/catalog/component-long-tail-migration.d.ts +18 -0
  16. package/catalog/component-long-tail-migration.js +305 -0
  17. package/catalog/component-regression-priority.d.ts +20 -0
  18. package/catalog/component-regression-priority.js +305 -0
  19. package/catalog/enterprise-component-flex-release-handoff.d.ts +32 -0
  20. package/catalog/enterprise-component-flex-release-handoff.js +437 -0
  21. package/catalog/enterprise-component-style-audit.d.ts +22 -0
  22. package/catalog/enterprise-component-style-audit.js +353 -0
  23. package/catalog/enterprise-form-control-theme-a11y.d.ts +19 -0
  24. package/catalog/enterprise-form-control-theme-a11y.js +220 -0
  25. package/catalog/enterprise-icon-control-audit.d.ts +21 -0
  26. package/catalog/enterprise-icon-control-audit.js +258 -0
  27. package/catalog/enterprise-layout-display-media-tokenization.d.ts +20 -0
  28. package/catalog/enterprise-layout-display-media-tokenization.js +237 -0
  29. package/catalog/enterprise-navigation-routing-state-hardening.d.ts +20 -0
  30. package/catalog/enterprise-navigation-routing-state-hardening.js +255 -0
  31. package/catalog/enterprise-overlay-mode-token-parity.d.ts +15 -0
  32. package/catalog/enterprise-overlay-mode-token-parity.js +178 -0
  33. package/catalog/enterprise-third-party-authoring-guide.d.ts +23 -0
  34. package/catalog/enterprise-third-party-authoring-guide.js +310 -0
  35. package/catalog/enterprise-visual-dom-snapshot-matrix.d.ts +31 -0
  36. package/catalog/enterprise-visual-dom-snapshot-matrix.js +357 -0
  37. package/catalog/epic10-existing-component-metadata.d.ts +25 -0
  38. package/catalog/epic10-existing-component-metadata.js +534 -0
  39. package/catalog/epic10-p0-component-wave.d.ts +28 -0
  40. package/catalog/epic10-p0-component-wave.js +688 -0
  41. package/catalog/epic10-platform-gates.d.ts +31 -0
  42. package/catalog/epic10-platform-gates.js +425 -0
  43. package/catalog/epic10-release-handoff.d.ts +30 -0
  44. package/catalog/epic10-release-handoff.js +195 -0
  45. package/catalog/epic11-enterprise-ux-handoff.d.ts +29 -0
  46. package/catalog/epic11-enterprise-ux-handoff.js +403 -0
  47. package/catalog/epic12-docs-adoption.d.ts +29 -0
  48. package/catalog/epic12-docs-adoption.js +183 -0
  49. package/catalog/epic12-rc0-gate-matrix.d.ts +36 -0
  50. package/catalog/epic12-rc0-gate-matrix.js +439 -0
  51. package/catalog/epic12-rc0-handoff.d.ts +30 -0
  52. package/catalog/epic12-rc0-handoff.js +385 -0
  53. package/catalog/epic13-conditional-network-evidence-ci.d.ts +35 -0
  54. package/catalog/epic13-conditional-network-evidence-ci.js +278 -0
  55. package/catalog/epic13-conditional-network-evidence.d.ts +34 -0
  56. package/catalog/epic13-conditional-network-evidence.js +280 -0
  57. package/catalog/epic13-docs-rmt-production-hardening.d.ts +39 -0
  58. package/catalog/epic13-docs-rmt-production-hardening.js +286 -0
  59. package/catalog/epic13-hydration-performance-closure.d.ts +33 -0
  60. package/catalog/epic13-hydration-performance-closure.js +234 -0
  61. package/catalog/epic13-known-residual-triage.d.ts +32 -0
  62. package/catalog/epic13-known-residual-triage.js +339 -0
  63. package/catalog/epic13-package-export-lock.d.ts +41 -0
  64. package/catalog/epic13-package-export-lock.js +604 -0
  65. package/catalog/epic13-prod-browser-csp-smoke.d.ts +35 -0
  66. package/catalog/epic13-prod-browser-csp-smoke.js +218 -0
  67. package/catalog/epic13-rc1-gate-matrix-ci-handoff.d.ts +36 -0
  68. package/catalog/epic13-rc1-gate-matrix-ci-handoff.js +418 -0
  69. package/catalog/epic13-rc1-migration-notes.d.ts +36 -0
  70. package/catalog/epic13-rc1-migration-notes.js +271 -0
  71. package/catalog/epic13-rc1-readiness.d.ts +33 -0
  72. package/catalog/epic13-rc1-readiness.js +487 -0
  73. package/catalog/epic13-release-owner-acceptance.d.ts +33 -0
  74. package/catalog/epic13-release-owner-acceptance.js +354 -0
  75. package/catalog/epic13-release-report-pack-dry-run-evidence.d.ts +36 -0
  76. package/catalog/epic13-release-report-pack-dry-run-evidence.js +253 -0
  77. package/catalog/epic13-rmt-production-readiness.d.ts +35 -0
  78. package/catalog/epic13-rmt-production-readiness.js +314 -0
  79. package/catalog/epic13-trusted-dom-boundary.d.ts +36 -0
  80. package/catalog/epic13-trusted-dom-boundary.js +230 -0
  81. package/catalog/epic13-visual-owner-artifact.d.ts +35 -0
  82. package/catalog/epic13-visual-owner-artifact.js +233 -0
  83. package/catalog/epic14-lsp-handoff.d.ts +28 -0
  84. package/catalog/epic14-lsp-handoff.js +312 -0
  85. package/catalog/epic14-rmt-tooling.d.ts +33 -0
  86. package/catalog/epic14-rmt-tooling.js +282 -0
  87. package/catalog/surface-manager-adapter-runtime.d.ts +37 -0
  88. package/catalog/surface-manager-adapter-runtime.js +203 -0
  89. package/catalog/surface-manager-browser-lab.d.ts +39 -0
  90. package/catalog/surface-manager-browser-lab.js +225 -0
  91. package/catalog/surface-manager-controller.d.ts +43 -0
  92. package/catalog/surface-manager-controller.js +290 -0
  93. package/catalog/surface-manager-layout-engines.d.ts +32 -0
  94. package/catalog/surface-manager-layout-engines.js +161 -0
  95. package/catalog/surface-manager-lazy-loading.d.ts +35 -0
  96. package/catalog/surface-manager-lazy-loading.js +173 -0
  97. package/catalog/surface-manager-materialization.d.ts +37 -0
  98. package/catalog/surface-manager-materialization.js +202 -0
  99. package/catalog/surface-manager-native-rmt-surfaces.d.ts +48 -0
  100. package/catalog/surface-manager-native-rmt-surfaces.js +325 -0
  101. package/catalog/surface-manager-overlay-bridge.d.ts +42 -0
  102. package/catalog/surface-manager-overlay-bridge.js +247 -0
  103. package/catalog/surface-manager-persistence.d.ts +37 -0
  104. package/catalog/surface-manager-persistence.js +178 -0
  105. package/catalog/surface-manager-quality-gates.d.ts +48 -0
  106. package/catalog/surface-manager-quality-gates.js +324 -0
  107. package/catalog/surface-manager-release-handoff.d.ts +47 -0
  108. package/catalog/surface-manager-release-handoff.js +274 -0
  109. package/catalog/surface-manager-remote-policy.d.ts +34 -0
  110. package/catalog/surface-manager-remote-policy.js +199 -0
  111. package/catalog/surface-manager-rmt-authoring.d.ts +44 -0
  112. package/catalog/surface-manager-rmt-authoring.js +368 -0
  113. package/catalog/surface-manager-route-lifecycle.d.ts +32 -0
  114. package/catalog/surface-manager-route-lifecycle.js +162 -0
  115. package/catalog/surface-manager-runtime-release-handoff.d.ts +36 -0
  116. package/catalog/surface-manager-runtime-release-handoff.js +245 -0
  117. package/catalog/surface-manager-side-panel-runtime.d.ts +46 -0
  118. package/catalog/surface-manager-side-panel-runtime.js +307 -0
  119. package/catalog/surface-manager-stack-policy.d.ts +32 -0
  120. package/catalog/surface-manager-stack-policy.js +169 -0
  121. package/catalog/surface-manager-window-runtime.d.ts +45 -0
  122. package/catalog/surface-manager-window-runtime.js +285 -0
  123. package/catalog/surface-manager-workbench-fixture.d.ts +50 -0
  124. package/catalog/surface-manager-workbench-fixture.js +315 -0
  125. package/catalog/type-exports-api.js +236 -0
  126. package/catalog/type-exports-builder.js +405 -0
  127. package/catalog/type-exports-catalog.js +394 -0
  128. package/catalog/type-exports-loader.js +266 -0
  129. package/catalog/type-exports-policy.js +461 -0
  130. package/catalog/type-exports-rmt.js +407 -0
  131. package/catalog/type-exports-vendor.js +365 -0
  132. package/catalog/type-exports.js +574 -0
  133. package/components/icon-packs/core.js +154 -0
  134. package/components/icon-packs/lucide.js +136 -0
  135. package/components/manifest.json +44 -0
  136. package/components/prism.d.ts +73 -0
  137. package/components/prism.js +300 -0
  138. package/components/turndown.d.ts +34 -0
  139. package/components/turndown.js +107 -0
  140. package/components/x-rmt-lifecycle-demo-build.d.ts +78 -0
  141. package/components/x-rmt-lifecycle-demo-build.js +1175 -0
  142. package/components/x-rmt-lifecycle-demo.d.ts +83 -0
  143. package/components/x-rmt-lifecycle-demo.js +1175 -0
  144. package/components/xalert.d.ts +42 -0
  145. package/components/xalert.js +538 -0
  146. package/components/xbutton.d.ts +127 -0
  147. package/components/xbutton.js +612 -0
  148. package/components/xcalendar.d.ts +39 -0
  149. package/components/xcalendar.js +338 -0
  150. package/components/xcards.d.ts +34 -0
  151. package/components/xcards.js +253 -0
  152. package/components/xcheckbox.d.ts +48 -0
  153. package/components/xcheckbox.js +448 -0
  154. package/components/xcode.d.ts +35 -0
  155. package/components/xcode.js +370 -0
  156. package/components/xdialog.d.ts +48 -0
  157. package/components/xdialog.js +763 -0
  158. package/components/xdrawer.d.ts +61 -0
  159. package/components/xdrawer.js +654 -0
  160. package/components/xfooter.d.ts +41 -0
  161. package/components/xfooter.js +351 -0
  162. package/components/xform.d.ts +43 -0
  163. package/components/xform.js +456 -0
  164. package/components/xheader.d.ts +68 -0
  165. package/components/xheader.js +1253 -0
  166. package/components/xhero.d.ts +42 -0
  167. package/components/xhero.js +475 -0
  168. package/components/xicon.d.ts +146 -0
  169. package/components/xicon.js +688 -0
  170. package/components/xinput.d.ts +37 -0
  171. package/components/xinput.js +444 -0
  172. package/components/xlightbox.d.ts +48 -0
  173. package/components/xlightbox.js +571 -0
  174. package/components/xlink.d.ts +63 -0
  175. package/components/xlink.js +565 -0
  176. package/components/xmasonry.d.ts +35 -0
  177. package/components/xmasonry.js +666 -0
  178. package/components/xmenu.d.ts +118 -0
  179. package/components/xmenu.js +1005 -0
  180. package/components/xmodal.d.ts +64 -0
  181. package/components/xmodal.js +831 -0
  182. package/components/xplayer.d.ts +57 -0
  183. package/components/xplayer.js +1748 -0
  184. package/components/xpopover.d.ts +54 -0
  185. package/components/xpopover.js +466 -0
  186. package/components/xprogress.d.ts +40 -0
  187. package/components/xprogress.js +345 -0
  188. package/components/xradio.d.ts +50 -0
  189. package/components/xradio.js +474 -0
  190. package/components/xrouter.d.ts +244 -0
  191. package/components/xrouter.js +1841 -0
  192. package/components/xsection.d.ts +34 -0
  193. package/components/xsection.js +253 -0
  194. package/components/xselect.d.ts +46 -0
  195. package/components/xselect.js +463 -0
  196. package/components/xsidepanel.d.ts +56 -0
  197. package/components/xsidepanel.js +728 -0
  198. package/components/xspinner.d.ts +38 -0
  199. package/components/xspinner.js +388 -0
  200. package/components/xstate.d.ts +137 -0
  201. package/components/xstate.js +493 -0
  202. package/components/xstatus.d.ts +41 -0
  203. package/components/xstatus.js +381 -0
  204. package/components/xsummary.d.ts +43 -0
  205. package/components/xsummary.js +293 -0
  206. package/components/xsurfacemanager-controller.d.ts +130 -0
  207. package/components/xsurfacemanager-controller.js +699 -0
  208. package/components/xsurfacemanager.d.ts +452 -0
  209. package/components/xsurfacemanager.js +3775 -0
  210. package/components/xsurfaceoverlay-bridge.d.ts +43 -0
  211. package/components/xsurfaceoverlay-bridge.js +238 -0
  212. package/components/xsurfacewindow.d.ts +50 -0
  213. package/components/xsurfacewindow.js +576 -0
  214. package/components/xtabs.d.ts +73 -0
  215. package/components/xtabs.js +611 -0
  216. package/components/xtend-public-types.d.ts +208 -0
  217. package/components/xtextarea.d.ts +46 -0
  218. package/components/xtextarea.js +451 -0
  219. package/components/xtheme.d.ts +253 -0
  220. package/components/xtheme.js +1438 -0
  221. package/components/xtoast.d.ts +39 -0
  222. package/components/xtoast.js +389 -0
  223. package/components/xtooltip.d.ts +53 -0
  224. package/components/xtooltip.js +432 -0
  225. package/components/xtype.d.ts +42 -0
  226. package/components/xtype.js +244 -0
  227. package/components/xutils.d.ts +164 -0
  228. package/components/xutils.js +496 -0
  229. package/components/xwriter.d.ts +67 -0
  230. package/components/xwriter.js +854 -0
  231. package/design-tokens/themes/enterprise-light.json +40 -0
  232. package/design-tokens/themes/xtend-signature.json +126 -0
  233. package/design-tokens/xtend-design-tokens.d.ts +95 -0
  234. package/design-tokens/xtend-design-tokens.js +395 -0
  235. package/design-tokens/xtheme-token-alias-layer.d.ts +84 -0
  236. package/design-tokens/xtheme-token-alias-layer.js +423 -0
  237. package/docs/.htaccess +51 -0
  238. package/docs/README.md +340 -0
  239. package/docs/XTend-ADR.md +221 -0
  240. package/docs/a11y-keyboard-smokes.md +62 -0
  241. package/docs/about.md +18 -0
  242. package/docs/api.md +157 -0
  243. package/docs/best-practices.md +76 -0
  244. package/docs/component-catalog-coverage.md +58 -0
  245. package/docs/component-lab.md +103 -0
  246. package/docs/component-long-tail-migration.md +41 -0
  247. package/docs/component-platform.md +159 -0
  248. package/docs/component-ux-app-authoring.md +130 -0
  249. package/docs/component-ux-authoring.md +96 -0
  250. package/docs/component-ux-gates.md +45 -0
  251. package/docs/components/x-rmt-lifecycle-demo-build.md +60 -0
  252. package/docs/components/xalert.md +81 -0
  253. package/docs/components/xbutton.md +103 -0
  254. package/docs/components/xcalendar.md +82 -0
  255. package/docs/components/xcards.md +128 -0
  256. package/docs/components/xcheckbox.md +102 -0
  257. package/docs/components/xcode.md +126 -0
  258. package/docs/components/xdialog.md +92 -0
  259. package/docs/components/xdrawer.md +84 -0
  260. package/docs/components/xfooter.md +126 -0
  261. package/docs/components/xform.md +128 -0
  262. package/docs/components/xheader.md +308 -0
  263. package/docs/components/xhero.md +142 -0
  264. package/docs/components/xicon.md +125 -0
  265. package/docs/components/xinput.md +129 -0
  266. package/docs/components/xlightbox.md +98 -0
  267. package/docs/components/xlink.md +109 -0
  268. package/docs/components/xmasonry.md +124 -0
  269. package/docs/components/xmenu.md +158 -0
  270. package/docs/components/xmodal.md +82 -0
  271. package/docs/components/xplayer.md +104 -0
  272. package/docs/components/xpopover.md +67 -0
  273. package/docs/components/xprogress.md +56 -0
  274. package/docs/components/xradio.md +103 -0
  275. package/docs/components/xrouter.md +260 -0
  276. package/docs/components/xsection.md +125 -0
  277. package/docs/components/xselect.md +105 -0
  278. package/docs/components/xsidepanel.md +30 -0
  279. package/docs/components/xspinner.md +102 -0
  280. package/docs/components/xstate.md +148 -0
  281. package/docs/components/xstatus.md +55 -0
  282. package/docs/components/xsummary.md +78 -0
  283. package/docs/components/xsurfacemanager.md +27 -0
  284. package/docs/components/xsurfacewindow.md +21 -0
  285. package/docs/components/xtabs.md +160 -0
  286. package/docs/components/xtextarea.md +98 -0
  287. package/docs/components/xtheme.md +167 -0
  288. package/docs/components/xtoast.md +62 -0
  289. package/docs/components/xtooltip.md +66 -0
  290. package/docs/components/xtype.md +82 -0
  291. package/docs/components/xutils.md +144 -0
  292. package/docs/components/xwriter.md +94 -0
  293. package/docs/components.md +117 -0
  294. package/docs/conditional-network-evidence-ci.md +38 -0
  295. package/docs/conditional-network-evidence.md +50 -0
  296. package/docs/core-migration-guide.md +110 -0
  297. package/docs/design-tokens.md +116 -0
  298. package/docs/docs-rmt-production-hardening.md +31 -0
  299. package/docs/enterprise-adoption.md +411 -0
  300. package/docs/enterprise-component-flex-release-handoff.md +129 -0
  301. package/docs/epic10-platform-gates.md +62 -0
  302. package/docs/epic10-release-handoff.md +81 -0
  303. package/docs/epic11-enterprise-ux-handoff.md +70 -0
  304. package/docs/epic12-rc0-handoff.md +61 -0
  305. package/docs/existing-component-metadata.md +67 -0
  306. package/docs/hydration-performance-closure.md +34 -0
  307. package/docs/hydration-policies.md +71 -0
  308. package/docs/index.php +1625 -0
  309. package/docs/known-residual-triage.md +22 -0
  310. package/docs/manifest-import-policy.md +79 -0
  311. package/docs/manifest.md +106 -0
  312. package/docs/menu.json +1190 -0
  313. package/docs/motion-contrast.md +67 -0
  314. package/docs/package-export-lock.md +44 -0
  315. package/docs/performance-measurements.md +106 -0
  316. package/docs/performance-regression.md +89 -0
  317. package/docs/performance.md +94 -0
  318. package/docs/previews/README.md +17 -0
  319. package/docs/prod-browser-csp-smokes.md +40 -0
  320. package/docs/public-component-types.md +79 -0
  321. package/docs/quick-start-guide.md +152 -0
  322. package/docs/rc0-adoption-guide.md +102 -0
  323. package/docs/rc0-gate-matrix.md +58 -0
  324. package/docs/rc1-gate-matrix-ci-handoff.md +56 -0
  325. package/docs/rc1-migration-notes.md +69 -0
  326. package/docs/rc1-readiness.md +46 -0
  327. package/docs/release-owner-acceptance.md +56 -0
  328. package/docs/release-report-pack-dry-run-evidence.md +39 -0
  329. package/docs/rmt-dsl-authoring-polish.md +122 -0
  330. package/docs/rmt-first-demo-app.md +77 -0
  331. package/docs/rmt-first-xtend-apps.md +105 -0
  332. package/docs/rmt-kernel-panic-recovery-incident-handoff.md +61 -0
  333. package/docs/rmt-kernel-security-hardening-migration.md +50 -0
  334. package/docs/rmt-kernel-trusted-output-authoring.md +69 -0
  335. package/docs/rmt-language-server.md +177 -0
  336. package/docs/rmt-lifecycle-demo.md +25 -0
  337. package/docs/rmt-linter.md +140 -0
  338. package/docs/rmt-production-readiness.md +63 -0
  339. package/docs/rmt-tooling-release-gates.md +77 -0
  340. package/docs/rmt-vnext-authoring.md +60 -0
  341. package/docs/rmt-vnext-cross-surface-events.md +68 -0
  342. package/docs/rmt-vnext-enterprise-mfe-handoff.md +70 -0
  343. package/docs/rmt-vnext-migration-notes.md +62 -0
  344. package/docs/rmt-vnext-release-handoff.md +69 -0
  345. package/docs/rmt-vnext-remote-surfaces.md +90 -0
  346. package/docs/rmt-vnext-surface-registry-enterprise.md +76 -0
  347. package/docs/screenreader-signals.md +56 -0
  348. package/docs/supply-chain-gates.md +100 -0
  349. package/docs/surface-manager-authoring-guide.md +94 -0
  350. package/docs/surface-manager-browser-lab.md +45 -0
  351. package/docs/surface-manager-component-lab.md +43 -0
  352. package/docs/surface-manager-controller.md +66 -0
  353. package/docs/surface-manager-layout-engines.md +32 -0
  354. package/docs/surface-manager-lazy-hydration.md +63 -0
  355. package/docs/surface-manager-migration-guide.md +94 -0
  356. package/docs/surface-manager-native-rmt-surfaces.md +38 -0
  357. package/docs/surface-manager-overlay-bridge.md +53 -0
  358. package/docs/surface-manager-persistence.md +30 -0
  359. package/docs/surface-manager-quality-gates.md +51 -0
  360. package/docs/surface-manager-release-handoff.md +68 -0
  361. package/docs/surface-manager-remote-policy.md +54 -0
  362. package/docs/surface-manager-rmt-authoring.md +86 -0
  363. package/docs/surface-manager-route-lifecycle.md +59 -0
  364. package/docs/surface-manager-runtime-release-handoff.md +69 -0
  365. package/docs/surface-manager-side-panel-runtime.md +36 -0
  366. package/docs/surface-manager-stack-policy.md +39 -0
  367. package/docs/surface-manager-window-runtime.md +47 -0
  368. package/docs/surface-manager-workbench-fixture.md +43 -0
  369. package/docs/third-party-design-authoring.md +406 -0
  370. package/docs/trusted-dom-boundary-browser-proof.md +32 -0
  371. package/docs/trusted-dom-sanitizing.md +110 -0
  372. package/docs/type-exports.md +61 -0
  373. package/docs/typescript-components.md +63 -0
  374. package/docs/utils/fabric-runtime.js +650 -0
  375. package/docs/utils/pageloader.js +2823 -0
  376. package/docs/utils/parsedown.php +298 -0
  377. package/docs/visual-browser-regression.md +83 -0
  378. package/docs/visual-owner-artifacts.md +46 -0
  379. package/docs/visual-snapshot-automation.md +87 -0
  380. package/docs/xtend-api-types.md +55 -0
  381. package/docs/xtend-builder-types.md +55 -0
  382. package/docs/xtend-catalog-types.md +44 -0
  383. package/docs/xtend-fabric-rmt-lane-mapping.md +143 -0
  384. package/docs/xtend-fabric.md +474 -0
  385. package/docs/xtend-loader-types.md +58 -0
  386. package/docs/xtend-loader.md +265 -0
  387. package/docs/xtend-policy-types.md +38 -0
  388. package/docs/xtend-rmt-types.md +39 -0
  389. package/docs/xtend-vendor-types.md +36 -0
  390. package/docs/xtendrmt-app-dsl.md +269 -0
  391. package/docs/xtendrmt-migration-guide.md +235 -0
  392. package/docs/xtendrmt-native-authoring.md +337 -0
  393. package/docs/xtendrmt-overview.md +89 -0
  394. package/docs/xtendrmt-parsedown-docs.rmt +956 -0
  395. package/docs/xtendrmt-parsedown-scheduling.md +301 -0
  396. package/docs/xtendrmt-runtime-bridge.md +155 -0
  397. package/fabric/hydration-policy.d.ts +27 -0
  398. package/fabric/hydration-policy.js +306 -0
  399. package/fabric/package.json +58 -0
  400. package/fabric/rmt-lane-mapping.d.ts +47 -0
  401. package/fabric/rmt-lane-mapping.js +504 -0
  402. package/fabric/xtend-fabric.d.ts +81 -0
  403. package/fabric/xtend-fabric.js +2669 -0
  404. package/fabric/xtend-policy-public-types.d.ts +135 -0
  405. package/package.json +8225 -0
  406. package/security/README.md +54 -0
  407. package/security/manifest-import-policy.d.ts +43 -0
  408. package/security/manifest-import-policy.js +260 -0
  409. package/security/supply-chain-gate-policy.d.ts +45 -0
  410. package/security/supply-chain-gate-policy.js +249 -0
  411. package/security/trusted-dom-policy.d.ts +36 -0
  412. package/security/trusted-dom-policy.js +316 -0
  413. package/tools/package.json +77 -0
  414. package/tools/rmt-editor/vscode/README.md +33 -0
  415. package/tools/rmt-editor/vscode/extension.d.ts +9 -0
  416. package/tools/rmt-editor/vscode/extension.js +55 -0
  417. package/tools/rmt-editor/vscode/language-configuration.json +28 -0
  418. package/tools/rmt-editor/vscode/package.json +83 -0
  419. package/tools/rmt-editor/vscode/snippets/rmt.code-snippets +243 -0
  420. package/tools/rmt-editor/vscode/syntaxes/rmt.tmLanguage.json +13 -0
  421. package/tools/rmt-editor/vscode/xtend-rmt-language-0.0.0-enterprise-readiness.vsix +0 -0
  422. package/tools/rmt-language/code-actions.d.ts +15 -0
  423. package/tools/rmt-language/code-actions.js +566 -0
  424. package/tools/rmt-language/completions.d.ts +22 -0
  425. package/tools/rmt-language/completions.js +475 -0
  426. package/tools/rmt-language/definitions.d.ts +13 -0
  427. package/tools/rmt-language/definitions.js +212 -0
  428. package/tools/rmt-language/diagnostics.d.ts +23 -0
  429. package/tools/rmt-language/diagnostics.js +486 -0
  430. package/tools/rmt-language/format-adapter.d.ts +16 -0
  431. package/tools/rmt-language/format-adapter.js +270 -0
  432. package/tools/rmt-language/hover.d.ts +12 -0
  433. package/tools/rmt-language/hover.js +326 -0
  434. package/tools/rmt-language/kernel-escalation.d.ts +122 -0
  435. package/tools/rmt-language/kernel-escalation.js +427 -0
  436. package/tools/rmt-language/kernel-panic-monitor.d.ts +176 -0
  437. package/tools/rmt-language/kernel-panic-monitor.js +674 -0
  438. package/tools/rmt-language/kernel-policy-parity.d.ts +142 -0
  439. package/tools/rmt-language/kernel-policy-parity.js +629 -0
  440. package/tools/rmt-language/kernel-recovery.d.ts +173 -0
  441. package/tools/rmt-language/kernel-recovery.js +666 -0
  442. package/tools/rmt-language/kernel-scheduler-failure.d.ts +136 -0
  443. package/tools/rmt-language/kernel-scheduler-failure.js +486 -0
  444. package/tools/rmt-language/kernel-security-regression.d.ts +154 -0
  445. package/tools/rmt-language/kernel-security-regression.js +465 -0
  446. package/tools/rmt-language/kernel-trust-authority.d.ts +120 -0
  447. package/tools/rmt-language/kernel-trust-authority.js +549 -0
  448. package/tools/rmt-language/parser.d.ts +14 -0
  449. package/tools/rmt-language/parser.js +111 -0
  450. package/tools/rmt-language/rmt-tooling-public-types.d.ts +179 -0
  451. package/tools/rmt-language/rules/boundary-policy.js +81 -0
  452. package/tools/rmt-language/rules/document-policy.js +65 -0
  453. package/tools/rmt-language/rules/index.js +29 -0
  454. package/tools/rmt-language/rules/route-policy.js +81 -0
  455. package/tools/rmt-language/rules/scheduler-policy.js +66 -0
  456. package/tools/rmt-language/rules/template-policy.js +130 -0
  457. package/tools/rmt-language/semantic-graph.d.ts +18 -0
  458. package/tools/rmt-language/semantic-graph.js +827 -0
  459. package/tools/rmt-language/snippets/README.md +17 -0
  460. package/tools/rmt-language/snippets/index.d.ts +17 -0
  461. package/tools/rmt-language/snippets/index.js +417 -0
  462. package/tools/rmt-language/snippets/rmt.code-snippets +243 -0
  463. package/tools/rmt-language/source-model.d.ts +14 -0
  464. package/tools/rmt-language/source-model.js +731 -0
  465. package/tools/rmt-language/symbols.d.ts +13 -0
  466. package/tools/rmt-language/symbols.js +183 -0
  467. package/tools/rmt-language/vnext-compatibility.d.ts +28 -0
  468. package/tools/rmt-language/vnext-compatibility.js +675 -0
  469. package/tools/rmt-language/vnext-compiler.d.ts +17 -0
  470. package/tools/rmt-language/vnext-compiler.js +716 -0
  471. package/tools/rmt-language/vnext-composition.d.ts +30 -0
  472. package/tools/rmt-language/vnext-composition.js +595 -0
  473. package/tools/rmt-language/vnext-conditions.d.ts +25 -0
  474. package/tools/rmt-language/vnext-conditions.js +474 -0
  475. package/tools/rmt-language/vnext-cross-surface-events.d.ts +30 -0
  476. package/tools/rmt-language/vnext-cross-surface-events.js +607 -0
  477. package/tools/rmt-language/vnext-degradation.d.ts +23 -0
  478. package/tools/rmt-language/vnext-degradation.js +428 -0
  479. package/tools/rmt-language/vnext-enterprise-fixtures.d.ts +28 -0
  480. package/tools/rmt-language/vnext-enterprise-fixtures.js +487 -0
  481. package/tools/rmt-language/vnext-enterprise-registry.d.ts +21 -0
  482. package/tools/rmt-language/vnext-enterprise-registry.js +495 -0
  483. package/tools/rmt-language/vnext-enterprise-release.d.ts +44 -0
  484. package/tools/rmt-language/vnext-enterprise-release.js +472 -0
  485. package/tools/rmt-language/vnext-event-governance.d.ts +29 -0
  486. package/tools/rmt-language/vnext-event-governance.js +488 -0
  487. package/tools/rmt-language/vnext-events.d.ts +44 -0
  488. package/tools/rmt-language/vnext-events.js +680 -0
  489. package/tools/rmt-language/vnext-import-resolver.d.ts +28 -0
  490. package/tools/rmt-language/vnext-import-resolver.js +642 -0
  491. package/tools/rmt-language/vnext-lifecycle.d.ts +22 -0
  492. package/tools/rmt-language/vnext-lifecycle.js +404 -0
  493. package/tools/rmt-language/vnext-parser.d.ts +21 -0
  494. package/tools/rmt-language/vnext-parser.js +1391 -0
  495. package/tools/rmt-language/vnext-regression.d.ts +25 -0
  496. package/tools/rmt-language/vnext-regression.js +394 -0
  497. package/tools/rmt-language/vnext-release.d.ts +29 -0
  498. package/tools/rmt-language/vnext-release.js +293 -0
  499. package/tools/rmt-language/vnext-remote-compatibility.d.ts +33 -0
  500. package/tools/rmt-language/vnext-remote-compatibility.js +892 -0
  501. package/tools/rmt-language/vnext-remote-compiler.d.ts +14 -0
  502. package/tools/rmt-language/vnext-remote-compiler.js +520 -0
  503. package/tools/rmt-language/vnext-remote-manifest.d.ts +33 -0
  504. package/tools/rmt-language/vnext-remote-manifest.js +538 -0
  505. package/tools/rmt-language/vnext-remote-security.d.ts +27 -0
  506. package/tools/rmt-language/vnext-remote-security.js +380 -0
  507. package/tools/rmt-language/vnext-remote-tooling.d.ts +25 -0
  508. package/tools/rmt-language/vnext-remote-tooling.js +805 -0
  509. package/tools/rmt-language/vnext-scheduler.d.ts +24 -0
  510. package/tools/rmt-language/vnext-scheduler.js +469 -0
  511. package/tools/rmt-language/vnext-security.d.ts +28 -0
  512. package/tools/rmt-language/vnext-security.js +597 -0
  513. package/tools/rmt-language/vnext-streaming.d.ts +28 -0
  514. package/tools/rmt-language/vnext-streaming.js +593 -0
  515. package/tools/rmt-language/vnext-surfaces.d.ts +24 -0
  516. package/tools/rmt-language/vnext-surfaces.js +406 -0
  517. package/tools/rmt-language/vnext-tooling.d.ts +25 -0
  518. package/tools/rmt-language/vnext-tooling.js +728 -0
  519. package/tools/rmt-language-server/protocol.d.ts +22 -0
  520. package/tools/rmt-language-server/protocol.js +352 -0
  521. package/tools/rmt-language-server/server.d.ts +15 -0
  522. package/tools/rmt-language-server/server.js +622 -0
  523. package/tools/rmt-linter/cli.d.ts +14 -0
  524. package/tools/rmt-linter/cli.js +450 -0
  525. package/tools/rmt-linter/reporter.d.ts +16 -0
  526. package/tools/rmt-linter/reporter.js +472 -0
  527. package/xtend-builder/README.md +83 -0
  528. package/xtend-builder/a11y/README.md +42 -0
  529. package/xtend-builder/a11y/component-a11y-profile.d.ts +14 -0
  530. package/xtend-builder/a11y/component-a11y-profile.js +314 -0
  531. package/xtend-builder/blueprints/README.md +105 -0
  532. package/xtend-builder/blueprints/component-blueprint.contract.d.ts +16 -0
  533. package/xtend-builder/blueprints/component-blueprint.contract.js +343 -0
  534. package/xtend-builder/builder-public-types.d.ts +234 -0
  535. package/xtend-builder/extensions/README.md +26 -0
  536. package/xtend-builder/extensions/component-extension-points.d.ts +11 -0
  537. package/xtend-builder/extensions/component-extension-points.js +277 -0
  538. package/xtend-builder/generators/README.md +149 -0
  539. package/xtend-builder/generators/component-files.d.ts +5 -0
  540. package/xtend-builder/generators/component-files.js +769 -0
  541. package/xtend-builder/generators/component-plan.d.ts +4 -0
  542. package/xtend-builder/generators/component-plan.js +104 -0
  543. package/xtend-builder/generators/registry.d.ts +6 -0
  544. package/xtend-builder/generators/registry.js +118 -0
  545. package/xtend-builder/generators/rmt-build.js +738 -0
  546. package/xtend-builder/generators/rmt-lifecycle-demo.js +922 -0
  547. package/xtend-builder/lib/cli.d.ts +9 -0
  548. package/xtend-builder/lib/cli.js +543 -0
  549. package/xtend-builder/lib/layout.d.ts +6 -0
  550. package/xtend-builder/lib/layout.js +153 -0
  551. package/xtend-builder/lib/package-resolver.js +25 -0
  552. package/xtend-builder/package.json +90 -0
  553. package/xtend-builder/performance/README.md +31 -0
  554. package/xtend-builder/performance/component-performance-profile.d.ts +11 -0
  555. package/xtend-builder/performance/component-performance-profile.js +347 -0
  556. package/xtend-builder/performance/component-ux-performance-contract.d.ts +27 -0
  557. package/xtend-builder/performance/component-ux-performance-contract.js +424 -0
  558. package/xtend-builder/preview/README.md +61 -0
  559. package/xtend-builder/preview/component-lab-ux-inspector.d.ts +20 -0
  560. package/xtend-builder/preview/component-lab-ux-inspector.js +448 -0
  561. package/xtend-builder/preview/component-lab.d.ts +14 -0
  562. package/xtend-builder/preview/component-lab.js +278 -0
  563. package/xtend-builder/preview/component-preview.d.ts +5 -0
  564. package/xtend-builder/preview/component-preview.js +160 -0
  565. package/xtend-builder/scaffold.config.d.ts +4 -0
  566. package/xtend-builder/scaffold.config.js +2056 -0
  567. package/xtend-builder/scaffold.d.ts +3 -0
  568. package/xtend-builder/scaffold.js +11 -0
  569. package/xtend-builder/templates/README.md +33 -0
  570. package/xtend-builder/templates/component/a11y.template.ts +11 -0
  571. package/xtend-builder/templates/component/component-suite.template.d.ts +2 -0
  572. package/xtend-builder/templates/component/component-suite.template.js +108 -0
  573. package/xtend-builder/templates/component/contract.template.ts +10 -0
  574. package/xtend-builder/templates/component/demo-plan.template.md +73 -0
  575. package/xtend-builder/templates/component/docs.template.md +301 -0
  576. package/xtend-builder/templates/component/fixture-data.template.ts +28 -0
  577. package/xtend-builder/templates/component/fixture.template.html +37 -0
  578. package/xtend-builder/templates/component/manifest-plan.template.json +22 -0
  579. package/xtend-builder/templates/component/performance.template.ts +13 -0
  580. package/xtend-builder/templates/component/rmt.template.ts +12 -0
  581. package/xtend-builder/templates/component/source.template.d.ts +2 -0
  582. package/xtend-builder/templates/component/source.template.js +137 -0
  583. package/xtend-builder/templates/component/source.template.ts +110 -0
  584. package/xtend-builder/templates/component/types.template.d.ts +423 -0
  585. package/xtend-builder/templates/loader.d.ts +4 -0
  586. package/xtend-builder/templates/loader.js +51 -0
  587. package/xtend-builder/templates/registry.d.ts +6 -0
  588. package/xtend-builder/templates/registry.js +119 -0
  589. package/xtend-builder/typing/README.md +130 -0
  590. package/xtend-builder/typing/component-contract-v2.d.ts +15 -0
  591. package/xtend-builder/typing/component-contract-v2.js +248 -0
  592. package/xtend-builder/typing/component-network-contract.d.ts +22 -0
  593. package/xtend-builder/typing/component-network-contract.js +478 -0
  594. package/xtend-builder/typing/component-shell-contract.d.ts +21 -0
  595. package/xtend-builder/typing/component-shell-contract.js +312 -0
  596. package/xtend-builder/typing/component-styling-contract.d.ts +22 -0
  597. package/xtend-builder/typing/component-styling-contract.js +301 -0
  598. package/xtend-builder/typing/component-types.d.ts +10 -0
  599. package/xtend-builder/typing/component-types.js +551 -0
  600. package/xtend-builder/typing/enterprise-component-flex-hardening-contract.d.ts +20 -0
  601. package/xtend-builder/typing/enterprise-component-flex-hardening-contract.js +332 -0
  602. package/xtend-builder/typing/feedback-status-ux-contract.d.ts +25 -0
  603. package/xtend-builder/typing/feedback-status-ux-contract.js +347 -0
  604. package/xtend-builder/typing/form-controls-ux-contract.d.ts +25 -0
  605. package/xtend-builder/typing/form-controls-ux-contract.js +357 -0
  606. package/xtend-builder/typing/layout-display-media-ux-contract.d.ts +25 -0
  607. package/xtend-builder/typing/layout-display-media-ux-contract.js +420 -0
  608. package/xtend-builder/typing/navigation-routing-ux-contract.d.ts +17 -0
  609. package/xtend-builder/typing/navigation-routing-ux-contract.js +297 -0
  610. package/xtend-builder/typing/overlay-interaction-ux-contract.d.ts +25 -0
  611. package/xtend-builder/typing/overlay-interaction-ux-contract.js +383 -0
  612. package/xtend-builder/typing/rmt-dsl-authoring-polish.d.ts +27 -0
  613. package/xtend-builder/typing/rmt-dsl-authoring-polish.js +419 -0
  614. package/xtend-builder/typing/rmt-shell-authoring-contract.d.ts +26 -0
  615. package/xtend-builder/typing/rmt-shell-authoring-contract.js +315 -0
  616. package/xtend-builder/utils/README.md +8 -0
  617. package/xtend-builder/utils/naming.d.ts +7 -0
  618. package/xtend-builder/utils/naming.js +36 -0
  619. package/xtend-builder/utils/validation.d.ts +5 -0
  620. package/xtend-builder/utils/validation.js +95 -0
  621. package/xtend-builder/wiring/README.md +46 -0
  622. package/xtend-builder/wiring/features.d.ts +5 -0
  623. package/xtend-builder/wiring/features.js +165 -0
  624. package/xtend-builder/wiring/hydration.d.ts +4 -0
  625. package/xtend-builder/wiring/hydration.js +44 -0
  626. package/xtend-builder/wiring/manifest.d.ts +5 -0
  627. package/xtend-builder/wiring/manifest.js +48 -0
  628. package/xtend-builder/workflows/README.md +47 -0
  629. package/xtend-builder/workflows/developer-workflow.d.ts +6 -0
  630. package/xtend-builder/workflows/developer-workflow.js +125 -0
  631. package/xtend-builder/writing/manifest-patcher.d.ts +49 -0
  632. package/xtend-builder/writing/manifest-patcher.js +391 -0
  633. package/xtend-builder/writing/write-plan.d.ts +148 -0
  634. package/xtend-builder/writing/write-plan.js +646 -0
  635. package/xtend-dev.d.ts +23 -0
  636. package/xtend-dev.js +4 -0
  637. package/xtend-loader.d.ts +201 -0
  638. package/xtend-loader.js +1704 -0
  639. package/xtend.css +402 -0
  640. package/xtendrmt/package.json +64 -0
  641. package/xtendrmt/rmt-core.d.ts +4452 -0
  642. package/xtendrmt/rmt-core.esm.js +25793 -0
  643. package/xtendrmt/rmt-first-demo-app.js +265 -0
  644. package/xtendrmt/rmt-first-demo-app.rmt +737 -0
  645. package/xtendrmt/rmt-lifecycle-demo.app.js +493 -0
  646. package/xtendrmt/rmt-lifecycle-demo.core.json +810 -0
  647. package/xtendrmt/rmt-lifecycle-demo.rmt +35 -0
  648. package/xtendrmt/rmt-lifecycle-demo.rmt-build.app.js +153 -0
  649. package/xtendrmt/rmt-lifecycle-demo.rmt-build.core.json +810 -0
  650. package/xtendrmt/rmt-lifecycle-demo.rmt-build.scaffold.json +202 -0
  651. package/xtendrmt/rmt-lifecycle-demo.scaffold.json +187 -0
  652. package/xtendrmt/rmt-manifest.json +548 -0
  653. package/xtendrmt/rmt-runtime.browser.js +26183 -0
  654. package/xtendrmt/rmt-runtime.esm.js +26214 -0
  655. package/xtendrmt/rmt-vnext-enterprise-mfe-demo.core.json +849 -0
  656. package/xtendrmt/rmt-vnext-enterprise-mfe-demo.rmt +50 -0
  657. package/xtendrmt/rmt-vnext-reference-demo.core.json +1069 -0
  658. package/xtendrmt/rmt-vnext-reference-demo.rmt +50 -0
  659. package/xtendrmt/rmt.schema.json +3145 -0
  660. package/xtendrmt/surface-workbench.js +316 -0
  661. package/xtendrmt/surface-workbench.rmt +762 -0
  662. package/xtendrmt/xtendrmt-bestcase-demo.core.json +1187 -0
  663. package/xtendrmt/xtendrmt-bestcase-demo.js +1728 -0
  664. package/xtendrmt/xtendrmt-bestcase-demo.rmt +57 -0
@@ -0,0 +1,2823 @@
1
+ const DOCS_RMT_RENDER_SCHEMA = 'xtend.docs.parsedown-rmt-render.v1';
2
+ const DOCS_RMT_PRODUCTION_HARDENING_SCHEMA = 'xtend.epic13.docs-rmt-production-hardening.v1';
3
+ const DOCS_RMT_TRUST_BOUNDARY = 'xtend.security.sanitizing-boundary.v1';
4
+ const DOCS_RMT_TRUSTED_DOM_PROOF_SCHEMA = 'xtend.epic13.trusted-dom-boundary.v1';
5
+ const DOCS_RMT_TRUSTED_DOM_SANITIZER = 'xtend.security.trusted-dom-sanitizer.v1';
6
+ const DOCS_RMT_PARSEDOWN_ENDPOINT = 'xtendrmt.docs.parsedown.parse';
7
+ const DOCS_RMT_DEFAULT_SHELL_TEMPLATE = 'docs.app.shell';
8
+ const DOCS_RMT_DEFAULT_SEARCH_TEMPLATE = 'docs.header.search';
9
+ const DOCS_RMT_DEFAULT_DIAGNOSTICS_SCHEDULE = 'docs.diagnostics.snapshot';
10
+ const DOCS_SHELL_SHADOW_STYLE_ID = 'xtend-docs-shell-shadow-styles';
11
+ const DOCS_RMT_EXTENSION_SLOTS = Object.freeze([
12
+ 'docs.slot.content',
13
+ 'docs.slot.sidebar',
14
+ 'docs.slot.related',
15
+ 'docs.slot.component-demo',
16
+ 'docs.slot.rich-content',
17
+ 'docs.slot.media',
18
+ 'docs.slot.diagnostics'
19
+ ]);
20
+ const DOCS_TRUSTED_DOM_FORBIDDEN_TAGS = Object.freeze([
21
+ 'script',
22
+ 'iframe',
23
+ 'object',
24
+ 'embed',
25
+ 'link',
26
+ 'meta',
27
+ 'base',
28
+ 'form'
29
+ ]);
30
+ const DOCS_TRUSTED_DOM_URL_ATTRIBUTES = Object.freeze(['href', 'src', 'action', 'poster']);
31
+ const DOCS_COMPONENT_DEMOS = Object.freeze(createDocsComponentDemos());
32
+ const DOCS_ROUTE_CONTENT_CACHE_LIMIT = 32;
33
+ const DOCS_ROUTE_IDLE_TIMEOUT_MS = 520;
34
+ const DOCS_ROUTE_CONTENT_CACHE = new Map();
35
+ const DOCS_ROUTE_PAYLOAD_PROMISES = new Map();
36
+ const DOCS_SHELL_SCOPED_CSS = `
37
+ #outlet {
38
+ width: 100%;
39
+ max-width: 100%;
40
+ min-width: 0;
41
+ box-sizing: border-box;
42
+ }
43
+ xtend-doc-page {
44
+ display: block;
45
+ width: 100%;
46
+ max-width: 100%;
47
+ min-width: 0;
48
+ box-sizing: border-box;
49
+ opacity: 1;
50
+ transform: translateY(0);
51
+ transition: opacity 0.16s ease, transform 0.16s ease;
52
+ }
53
+ xtend-doc-page[data-docs-route-state="loading"] {
54
+ opacity: 0.72;
55
+ transform: translateY(4px);
56
+ }
57
+ xtend-doc-page [data-rmt-shell] {
58
+ transition: border-color 0.16s ease, box-shadow 0.16s ease;
59
+ }
60
+ xtend-doc-page[data-docs-route-state="ready"] [data-rmt-shell] {
61
+ box-shadow: 0 6px 18px rgba(15, 23, 42, 0.06);
62
+ }
63
+ .docs-shell-toolbar {
64
+ display: flex;
65
+ justify-content: flex-end;
66
+ align-items: center;
67
+ gap: 0.5rem;
68
+ margin-bottom: 0.8rem;
69
+ }
70
+ .docs-app-shell {
71
+ display: block;
72
+ width: 100%;
73
+ max-width: none;
74
+ min-width: 0;
75
+ box-sizing: border-box;
76
+ --section-bg: var(--docs-shell-bg);
77
+ --section-padding: 0;
78
+ --main-content-padding: 0;
79
+ --section-gap: 0;
80
+ --border-radius: 0;
81
+ }
82
+ x-section.docs-app-shell::part(container),
83
+ x-section.docs-app-shell::part(content) {
84
+ display: block;
85
+ width: 100%;
86
+ max-width: none;
87
+ min-width: 0;
88
+ flex: 1 1 auto;
89
+ box-sizing: border-box;
90
+ padding: 0;
91
+ overflow: visible;
92
+ }
93
+ .docs-shell-layout {
94
+ display: grid;
95
+ grid-template-columns: minmax(0, 1fr) var(--docs-sidebar-width, clamp(20rem, 24vw, 27rem));
96
+ gap: var(--docs-layout-gap, clamp(1rem, 2.2vw, 2.5rem));
97
+ align-items: start;
98
+ width: calc(100% - var(--docs-viewport-gutter, 0.5rem) - var(--docs-viewport-gutter, 0.5rem));
99
+ max-width: calc(100% - var(--docs-viewport-gutter, 0.5rem) - var(--docs-viewport-gutter, 0.5rem));
100
+ margin-inline: var(--docs-viewport-gutter, 0.5rem);
101
+ min-width: 0;
102
+ box-sizing: border-box;
103
+ }
104
+ .docs-article-surface,
105
+ .docs-page-sidebar {
106
+ min-width: 0;
107
+ max-width: 100%;
108
+ box-sizing: border-box;
109
+ }
110
+ .docs-article-surface {
111
+ background: var(--section-bg);
112
+ color: var(--text-color);
113
+ border: 1px solid var(--border-color);
114
+ border-radius: 8px;
115
+ padding: clamp(1rem, 2vw, 2rem);
116
+ box-shadow: 0 10px 28px rgba(15, 23, 42, 0.08);
117
+ }
118
+ .docs-page-sidebar {
119
+ position: static;
120
+ display: grid;
121
+ gap: 0.85rem;
122
+ align-self: start;
123
+ }
124
+ .docs-sidebar-section {
125
+ background: var(--docs-sidebar-bg);
126
+ color: var(--text-color);
127
+ border: 1px solid var(--border-color);
128
+ border-radius: 8px;
129
+ padding: 0.9rem;
130
+ box-shadow: 0 8px 22px rgba(15, 23, 42, 0.06);
131
+ box-sizing: border-box;
132
+ }
133
+ .docs-sidebar-heading {
134
+ display: flex;
135
+ align-items: center;
136
+ gap: 0.45rem;
137
+ margin: 0 0 0.65rem;
138
+ font-size: 0.86rem;
139
+ line-height: 1.2;
140
+ color: var(--text-color);
141
+ }
142
+ .docs-sidebar-heading x-icon,
143
+ .docs-related-link x-icon {
144
+ color: var(--primary-color);
145
+ flex: none;
146
+ }
147
+ .docs-sidebar-copy {
148
+ margin: -0.2rem 0 0.75rem;
149
+ color: var(--muted-text-color);
150
+ font-size: 0.88rem;
151
+ line-height: 1.45;
152
+ }
153
+ .docs-related-list {
154
+ display: grid;
155
+ gap: 0.5rem;
156
+ }
157
+ .docs-related-link {
158
+ display: grid;
159
+ grid-template-columns: auto minmax(0, 1fr) auto;
160
+ align-items: center;
161
+ gap: 0.55rem;
162
+ max-width: 100%;
163
+ min-width: 0;
164
+ box-sizing: border-box;
165
+ min-height: 42px;
166
+ padding: 0.55rem 0.62rem;
167
+ border: 1px solid var(--border-color);
168
+ border-radius: 7px;
169
+ background: var(--docs-sidebar-link-bg);
170
+ color: var(--text-color);
171
+ text-decoration: none;
172
+ transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease, transform 0.16s ease;
173
+ }
174
+ x-link.docs-related-link::part(link) {
175
+ display: grid;
176
+ grid-template-columns: auto minmax(0, 1fr) auto;
177
+ align-items: center;
178
+ gap: 0.55rem;
179
+ width: 100%;
180
+ max-width: 100%;
181
+ min-width: 0;
182
+ box-sizing: border-box;
183
+ color: inherit;
184
+ text-decoration: none;
185
+ }
186
+ .docs-related-link:hover,
187
+ .docs-related-link:focus-visible {
188
+ background: var(--docs-sidebar-link-hover-bg);
189
+ border-color: color-mix(in srgb, var(--primary-color) 56%, var(--border-color));
190
+ color: var(--primary-color);
191
+ transform: translateX(2px);
192
+ outline: none;
193
+ }
194
+ .docs-related-link span {
195
+ min-width: 0;
196
+ overflow-wrap: anywhere;
197
+ }
198
+ .docs-component-demo[hidden],
199
+ .docs-sidebar-section[hidden] {
200
+ display: none;
201
+ }
202
+ .docs-demo-preview {
203
+ display: grid;
204
+ gap: 0.7rem;
205
+ min-height: 4rem;
206
+ padding: 0.85rem;
207
+ border: 1px solid var(--border-color);
208
+ border-radius: 7px;
209
+ background: var(--surface-muted);
210
+ overflow: visible;
211
+ }
212
+ .docs-demo-preview x-button,
213
+ .docs-demo-preview x-input,
214
+ .docs-demo-preview x-select,
215
+ .docs-demo-preview x-textarea,
216
+ .docs-demo-preview x-status,
217
+ .docs-demo-preview x-progress,
218
+ .docs-demo-preview x-alert,
219
+ .docs-demo-preview x-toast,
220
+ .docs-demo-preview x-tabs,
221
+ .docs-demo-preview x-code,
222
+ .docs-demo-preview x-summary {
223
+ max-width: 100%;
224
+ }
225
+ .docs-demo-actions {
226
+ display: flex;
227
+ flex-wrap: wrap;
228
+ gap: 0.55rem;
229
+ align-items: center;
230
+ }
231
+ .docs-demo-code-grid {
232
+ display: grid;
233
+ gap: 0.7rem;
234
+ margin-top: 0.75rem;
235
+ }
236
+ .docs-demo-code-block h3 {
237
+ margin: 0 0 0.35rem;
238
+ color: var(--muted-text-color);
239
+ font-size: 0.78rem;
240
+ text-transform: uppercase;
241
+ }
242
+ .docs-demo-code-block x-code {
243
+ display: block;
244
+ width: 100%;
245
+ min-width: 0;
246
+ margin: 0;
247
+ max-height: 18rem;
248
+ max-width: 100%;
249
+ box-sizing: border-box;
250
+ background: var(--docs-code-bg);
251
+ color: var(--x-code-text, #f8fafc);
252
+ border-radius: 8px;
253
+ }
254
+ .docs-demo-surface-zone {
255
+ position: relative;
256
+ min-height: 15rem;
257
+ overflow: hidden;
258
+ border-radius: 7px;
259
+ background: color-mix(in srgb, var(--surface-muted) 80%, transparent);
260
+ }
261
+ .docs-demo-surface-zone x-surface-window,
262
+ .docs-demo-surface-zone x-side-panel {
263
+ position: absolute;
264
+ }
265
+ .download-link {
266
+ float: none;
267
+ font-size: 0.9em;
268
+ }
269
+ .docs-icon-button {
270
+ --xtend-button-min-touch-target: 44px;
271
+ color: var(--text-color);
272
+ flex: none;
273
+ }
274
+ .docs-icon-button::part(button) {
275
+ width: 44px;
276
+ height: 44px;
277
+ min-width: 44px;
278
+ min-height: 44px;
279
+ padding: 0;
280
+ border: 1px solid var(--border-color);
281
+ border-radius: 999px;
282
+ background: var(--surface-muted);
283
+ color: var(--text-color);
284
+ box-shadow: none;
285
+ backdrop-filter: none;
286
+ transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease, transform 0.16s ease;
287
+ }
288
+ .docs-icon-button:hover::part(button) {
289
+ transform: translateY(-1px);
290
+ border-color: color-mix(in srgb, var(--primary-color) 60%, var(--border-color));
291
+ background: var(--primary-color);
292
+ color: var(--section-bg);
293
+ }
294
+ .docs-icon-button:focus-visible::part(button) {
295
+ outline: 2px solid var(--focus-color);
296
+ outline-offset: 2px;
297
+ }
298
+ .docs-icon-button x-icon {
299
+ pointer-events: none;
300
+ }
301
+ .docs-visually-hidden {
302
+ position: absolute;
303
+ width: 1px;
304
+ height: 1px;
305
+ padding: 0;
306
+ margin: -1px;
307
+ overflow: hidden;
308
+ clip: rect(0, 0, 0, 0);
309
+ white-space: nowrap;
310
+ border: 0;
311
+ }
312
+ #md-content {
313
+ min-width: 0;
314
+ max-width: 100%;
315
+ box-sizing: border-box;
316
+ line-height: 1.65;
317
+ }
318
+ #md-content[data-xtend-skeleton-active="true"] {
319
+ min-height: var(--docs-content-skeleton-min-height, 24rem);
320
+ }
321
+ #md-content[data-xtend-skeleton-active="true"] > :not([data-xtend-skeleton-loader]) {
322
+ visibility: hidden;
323
+ }
324
+ [data-xtend-skeleton-loader] {
325
+ display: grid;
326
+ gap: 0.68rem;
327
+ width: 100%;
328
+ min-width: 0;
329
+ box-sizing: border-box;
330
+ min-height: var(--docs-content-skeleton-min-height, 24rem);
331
+ padding: 0;
332
+ border-radius: 8px;
333
+ background: transparent;
334
+ contain: layout paint;
335
+ }
336
+ [data-xtend-skeleton-line] {
337
+ display: block;
338
+ height: 0.82rem;
339
+ border-radius: 999px;
340
+ background: var(--xtend-skeleton-line-bg, rgba(148, 163, 184, 0.24));
341
+ }
342
+ [data-xtend-skeleton-line]:first-child {
343
+ height: 1.35rem;
344
+ }
345
+ #md-content > :first-child {
346
+ margin-top: 0;
347
+ }
348
+ #md-content > :last-child {
349
+ margin-bottom: 0;
350
+ }
351
+ #md-content h1,
352
+ #md-content h2,
353
+ #md-content h3 {
354
+ line-height: 1.18;
355
+ color: var(--text-color);
356
+ }
357
+ #md-content p,
358
+ #md-content li {
359
+ color: var(--text-color);
360
+ }
361
+ #md-content a,
362
+ #md-content x-link {
363
+ color: var(--primary-color);
364
+ }
365
+ #md-content pre {
366
+ max-width: 100%;
367
+ overflow: auto;
368
+ padding: 1rem;
369
+ border-radius: 8px;
370
+ background: var(--docs-code-bg);
371
+ color: #f8fafc;
372
+ }
373
+ #md-content code {
374
+ overflow-wrap: anywhere;
375
+ }
376
+ #md-content blockquote {
377
+ margin: 1rem 0;
378
+ padding: 0.7rem 1rem;
379
+ border-left: 3px solid var(--primary-color);
380
+ background: var(--surface-muted);
381
+ border-radius: 0 7px 7px 0;
382
+ }
383
+ #md-content hr {
384
+ height: 1px;
385
+ margin: 1.75rem 0;
386
+ border: 0;
387
+ background: var(--border-color);
388
+ }
389
+ #md-content table {
390
+ width: 100%;
391
+ border-collapse: collapse;
392
+ display: block;
393
+ overflow-x: auto;
394
+ }
395
+ #md-content th,
396
+ #md-content td {
397
+ border: 1px solid var(--border-color);
398
+ padding: 0.55rem;
399
+ }
400
+ @media (max-width: 700px) {
401
+ .docs-shell-layout {
402
+ grid-template-columns: 1fr;
403
+ }
404
+ .docs-page-sidebar {
405
+ position: static;
406
+ }
407
+ .docs-related-link:hover,
408
+ .docs-related-link:focus-visible,
409
+ xtend-doc-page[data-docs-route-state="loading"] {
410
+ transform: none;
411
+ }
412
+ }
413
+ `;
414
+
415
+ function getDocsAssetUrl(key, fallback) {
416
+ const assets = window.xtendDocsAssetUrls || {};
417
+ return typeof assets[key] === 'string' && assets[key] ? assets[key] : fallback;
418
+ }
419
+
420
+ function escapeDocsHtmlAttribute(value) {
421
+ return String(value == null ? '' : value)
422
+ .replace(/&/g, '&')
423
+ .replace(/"/g, '"')
424
+ .replace(/</g, '&lt;')
425
+ .replace(/>/g, '&gt;');
426
+ }
427
+
428
+ function docsPerfNow() {
429
+ return window.performance && typeof window.performance.now === 'function'
430
+ ? window.performance.now()
431
+ : Date.now();
432
+ }
433
+
434
+ function docsRoundDuration(value) {
435
+ return Math.round(Number(value || 0) * 10) / 10;
436
+ }
437
+
438
+ function rememberDocsCacheEntry(key, value) {
439
+ DOCS_ROUTE_CONTENT_CACHE.set(key, value);
440
+ while (DOCS_ROUTE_CONTENT_CACHE.size > DOCS_ROUTE_CONTENT_CACHE_LIMIT) {
441
+ const firstKey = DOCS_ROUTE_CONTENT_CACHE.keys().next().value;
442
+ DOCS_ROUTE_CONTENT_CACHE.delete(firstKey);
443
+ }
444
+ return value;
445
+ }
446
+
447
+ function createDocsRouteContentCacheKey(slug, html, options = {}) {
448
+ return [
449
+ slug || 'readme',
450
+ options.source || 'docs.parsedown',
451
+ options.markupClass || 'parsedownHtml',
452
+ options.trustBoundary || DOCS_RMT_TRUST_BOUNDARY,
453
+ String(html || '')
454
+ ].join('\u0000');
455
+ }
456
+
457
+ function cloneDocsSanitizeResult(result, cacheHit = false) {
458
+ return {
459
+ ...result,
460
+ removed: Array.isArray(result.removed) ? result.removed.slice() : [],
461
+ removedCount: Number(result.removedCount || 0),
462
+ cacheHit
463
+ };
464
+ }
465
+
466
+ function dispatchDocsLaneComplete(detail = {}) {
467
+ window.dispatchEvent(new CustomEvent('xtend-docs-lane-complete', {
468
+ detail: {
469
+ schema: 'xtend.docs.route-lane.v1',
470
+ completedAt: new Date().toISOString(),
471
+ ...detail
472
+ }
473
+ }));
474
+ }
475
+
476
+ function runDocsMeasuredLane(detail, callback) {
477
+ const startedAt = docsPerfNow();
478
+ const result = callback();
479
+ dispatchDocsLaneComplete({
480
+ ...detail,
481
+ durationMs: docsRoundDuration(docsPerfNow() - startedAt)
482
+ });
483
+ return result;
484
+ }
485
+
486
+ function scheduleDocsAfterPaint(callback) {
487
+ let cancelled = false;
488
+ let firstFrame = 0;
489
+ let secondFrame = 0;
490
+ const run = () => {
491
+ if (!cancelled) callback();
492
+ };
493
+ if (typeof window.requestAnimationFrame === 'function') {
494
+ firstFrame = window.requestAnimationFrame(() => {
495
+ secondFrame = window.requestAnimationFrame(run);
496
+ });
497
+ return () => {
498
+ cancelled = true;
499
+ if (firstFrame) window.cancelAnimationFrame(firstFrame);
500
+ if (secondFrame) window.cancelAnimationFrame(secondFrame);
501
+ };
502
+ }
503
+ const timer = window.setTimeout(run, 0);
504
+ return () => {
505
+ cancelled = true;
506
+ window.clearTimeout(timer);
507
+ };
508
+ }
509
+
510
+ function scheduleDocsIdle(callback, timeout = DOCS_ROUTE_IDLE_TIMEOUT_MS) {
511
+ let cancelled = false;
512
+ const run = (deadline) => {
513
+ if (!cancelled) callback(deadline || null);
514
+ };
515
+ if (typeof window.requestIdleCallback === 'function') {
516
+ const id = window.requestIdleCallback(run, { timeout });
517
+ return () => {
518
+ cancelled = true;
519
+ window.cancelIdleCallback(id);
520
+ };
521
+ }
522
+ const timer = window.setTimeout(run, Math.min(80, timeout));
523
+ return () => {
524
+ cancelled = true;
525
+ window.clearTimeout(timer);
526
+ };
527
+ }
528
+
529
+ function getXtendSkeletonLoader() {
530
+ if (window.XTendSkeletonLoader && typeof window.XTendSkeletonLoader.show === 'function') {
531
+ return window.XTendSkeletonLoader;
532
+ }
533
+ if (window.XTendLoader && window.XTendLoader.skeletonLoader && typeof window.XTendLoader.skeletonLoader.show === 'function') {
534
+ return window.XTendLoader.skeletonLoader;
535
+ }
536
+ if (window.XTendLoader && typeof window.XTendLoader.showSkeleton === 'function') {
537
+ return {
538
+ schema: window.XTendLoader.skeletonLoaderContract || 'xtend.loader.skeleton-loader.v1',
539
+ show: window.XTendLoader.showSkeleton,
540
+ hide: window.XTendLoader.hideSkeleton
541
+ };
542
+ }
543
+ return null;
544
+ }
545
+
546
+ function showDocsSkeleton(target, options = {}) {
547
+ if (!target) return null;
548
+ const loader = getXtendSkeletonLoader();
549
+ const skeletonOptions = {
550
+ variant: options.variant || 'article',
551
+ lines: options.lines || 10,
552
+ minHeight: options.minHeight || '24rem',
553
+ label: options.label || 'Dokumentation wird geladen',
554
+ source: options.source || 'docs.parsedown',
555
+ schedule: options.schedule || 'docs.markdown.parse'
556
+ };
557
+ if (loader && typeof loader.show === 'function') {
558
+ return loader.show(target, skeletonOptions);
559
+ }
560
+ target.setAttribute('data-xtend-skeleton-active', 'true');
561
+ target.setAttribute('aria-busy', 'true');
562
+ const skeleton = document.createElement('div');
563
+ skeleton.setAttribute('data-xtend-skeleton-loader', '');
564
+ skeleton.setAttribute('role', 'status');
565
+ skeleton.setAttribute('aria-label', skeletonOptions.label);
566
+ const widths = ['72%', '94%', '84%', '58%', '88%', '66%'];
567
+ for (let index = 0; index < skeletonOptions.lines; index += 1) {
568
+ const line = document.createElement('span');
569
+ line.setAttribute('data-xtend-skeleton-line', '');
570
+ line.style.width = widths[index % widths.length];
571
+ skeleton.appendChild(line);
572
+ }
573
+ target.appendChild(skeleton);
574
+ return skeleton;
575
+ }
576
+
577
+ function hideDocsSkeleton(target, options = {}) {
578
+ if (!target) return 0;
579
+ const loader = getXtendSkeletonLoader();
580
+ if (loader && typeof loader.hide === 'function') {
581
+ return loader.hide(target, options);
582
+ }
583
+ const skeletons = Array.from(target.querySelectorAll ? target.querySelectorAll('[data-xtend-skeleton-loader]') : []);
584
+ skeletons.forEach((skeleton) => skeleton.remove());
585
+ target.removeAttribute('data-xtend-skeleton-active');
586
+ if (!options.preserveBusy) target.removeAttribute('aria-busy');
587
+ return skeletons.length;
588
+ }
589
+
590
+ function createRmtSnippet(tag, attributes = {}, children = []) {
591
+ return JSON.stringify({ tag, attributes, children }, null, 2);
592
+ }
593
+
594
+ function createDocsComponentDemos() {
595
+ const demos = {};
596
+ const add = (slug, tag, title, description, html, options = {}) => {
597
+ demos[slug] = {
598
+ tag,
599
+ title,
600
+ description,
601
+ html,
602
+ previewHtml: options.previewHtml || html,
603
+ rmt: options.rmt || createRmtSnippet(tag, options.attributes || {}, options.children || []),
604
+ actions: options.actions || []
605
+ };
606
+ };
607
+
608
+ add('components-xbutton', 'x-button', 'x-button', 'Varianten, Iconographie und Button-Events direkt testen.', '<x-button variant="primary"><x-icon name="rocket" pack="lucide" decorative size="1rem"></x-icon>Deploy preview</x-button>', {
609
+ attributes: { variant: 'primary' },
610
+ children: [
611
+ { tag: 'x-icon', attributes: { name: 'rocket', pack: 'lucide', decorative: true, size: '1rem' } },
612
+ 'Deploy preview'
613
+ ]
614
+ });
615
+ add('components-xicon', 'x-icon', 'x-icon', 'Lokale Icon-Packs fuer Shell-Actions und Link-Signale.', '<div class="docs-demo-actions"><x-icon name="sparkles" pack="lucide" label="Innovation" size="1.4rem"></x-icon><x-icon name="shield-check" pack="lucide" label="Safety" size="1.4rem"></x-icon><x-icon name="route" pack="lucide" label="Routing" size="1.4rem"></x-icon></div>', {
616
+ attributes: { name: 'sparkles', pack: 'lucide', label: 'Innovation', size: '1.4rem' }
617
+ });
618
+ add('components-xlink', 'x-link', 'x-link', 'Hash-Routing mit visuell klarer Link-Affordance.', '<x-link class="docs-related-link" href="/quick-start-guide"><x-icon name="arrow-up-right" pack="lucide" decorative size="1rem"></x-icon><span>Quick Start Guide</span><x-icon name="chevron-right" pack="lucide" decorative size="1rem"></x-icon></x-link>', {
619
+ attributes: { href: '/quick-start-guide' },
620
+ children: ['Quick Start Guide']
621
+ });
622
+ add('components-xinput', 'x-input', 'x-input', 'Darkmode-faehige Eingabe als Shell-Suchfeld oder Form-Control.', '<x-input name="project" placeholder="Microfrontend suchen..." value="Surface Workbench"></x-input>', {
623
+ attributes: { name: 'project', placeholder: 'Microfrontend suchen...', value: 'Surface Workbench' }
624
+ });
625
+ add('components-xform', 'x-form', 'x-form', 'Komponierte Formular-Shell mit XTend Controls.', '<x-form><x-input name="name" placeholder="App Shell Name"></x-input><x-button variant="primary">Validieren</x-button></x-form>', {
626
+ attributes: {},
627
+ children: [
628
+ { tag: 'x-input', attributes: { name: 'name', placeholder: 'App Shell Name' } },
629
+ { tag: 'x-button', attributes: { variant: 'primary' }, children: ['Validieren'] }
630
+ ]
631
+ });
632
+ add('components-xselect', 'x-select', 'x-select', 'Auswahl-Control mit nativer Select-Semantik.', '<x-select label="Surface Type" placeholder="Bitte waehlen" value="window"><option value="window">Window</option><option value="side-panel">Side Panel</option><option value="modal">Modal</option></x-select>', {
633
+ attributes: { label: 'Surface Type', placeholder: 'Bitte waehlen', value: 'window' },
634
+ children: [
635
+ { tag: 'option', attributes: { value: 'window' }, children: ['Window'] },
636
+ { tag: 'option', attributes: { value: 'side-panel' }, children: ['Side Panel'] },
637
+ { tag: 'option', attributes: { value: 'modal' }, children: ['Modal'] }
638
+ ]
639
+ });
640
+ add('components-xcheckbox', 'x-checkbox', 'x-checkbox', 'Boolean-Settings fuer Shell Preferences.', '<x-checkbox name="remember" checked>Layout wiederherstellen</x-checkbox>', {
641
+ attributes: { name: 'remember', checked: true },
642
+ children: ['Layout wiederherstellen']
643
+ });
644
+ add('components-xradio', 'x-radio', 'x-radio', 'Einzeloptionen fuer kompakte Einstellbereiche.', '<div class="docs-demo-actions"><x-radio name="density" value="compact" checked>Compact</x-radio><x-radio name="density" value="comfortable">Comfortable</x-radio></div>', {
645
+ attributes: { name: 'density', value: 'compact', checked: true },
646
+ children: ['Compact']
647
+ });
648
+ add('components-xtextarea', 'x-textarea', 'x-textarea', 'Mehrzeilige Eingabe fuer Prompts, Notes oder Config-Fragmente.', '<x-textarea name="notes" rows="4" placeholder="Lifecycle notes">Hydrate shell, then schedule content.</x-textarea>', {
649
+ attributes: { name: 'notes', rows: '4', placeholder: 'Lifecycle notes' },
650
+ children: ['Hydrate shell, then schedule content.']
651
+ });
652
+ add('components-xcalendar', 'x-calendar', 'x-calendar', 'Datumsauswahl mit Grid-Interaktion.', '<x-calendar></x-calendar>');
653
+ add('components-xstatus', 'x-status', 'x-status', 'Statuszeilen fuer Shell- und Lifecycle-Zustaende.', '<x-status type="success" state="ready" message="Surface stack synchronized">Surface stack synchronized</x-status>', {
654
+ attributes: { type: 'success', state: 'ready', message: 'Surface stack synchronized' },
655
+ children: ['Surface stack synchronized']
656
+ });
657
+ add('components-xprogress', 'x-progress', 'x-progress', 'Fortschritt fuer Hydration, Import und Scheduler-Arbeit.', '<x-progress value="68" max="100" label="Hydration" status="68 Prozent">68 Prozent</x-progress>', {
658
+ attributes: { value: '68', max: '100', label: 'Hydration', status: '68 Prozent' },
659
+ children: ['68 Prozent']
660
+ });
661
+ add('components-xalert', 'x-alert', 'x-alert', 'Inline Feedback mit A11y-Live-Region.', '<x-alert type="info" closable>RMT shell rendered, Parsedown content scheduled.</x-alert>', {
662
+ attributes: { type: 'info', closable: true },
663
+ children: ['RMT shell rendered, Parsedown content scheduled.']
664
+ });
665
+ add('components-xtoast', 'x-toast', 'x-toast', 'Toast Feedback per API oder direktes Element.', '<div class="docs-demo-actions"><x-button data-demo-action="toast" variant="primary">Toast anzeigen</x-button></div>', {
666
+ attributes: { type: 'success', duration: '3000' },
667
+ children: ['Gespeichert'],
668
+ actions: ['toast']
669
+ });
670
+ add('components-xmodal', 'x-modal', 'x-modal', 'Modales Overlay mit Focus Trap, Escape und xstate-Sync.', '<div class="docs-demo-actions"><x-button data-demo-action="open-modal" variant="primary">Modal testen</x-button></div><x-modal id="docs-demo-modal" title="Release Check" content="XTend Modal laeuft in der Docs Shell." overlay></x-modal>', {
671
+ attributes: { id: 'docs-demo-modal', title: 'Release Check', content: 'XTend Modal laeuft in der Docs Shell.', overlay: true },
672
+ actions: ['open-modal']
673
+ });
674
+ add('components-xdialog', 'x-dialog', 'x-dialog', 'Dialog-Surface fuer bestaetigende UI-Flows.', '<div class="docs-demo-actions"><x-button data-demo-action="open-dialog" variant="secondary">Dialog testen</x-button></div><x-dialog id="docs-demo-dialog" title="Dialog Surface" width="420px" height="220px" overlay>RMT kann Dialoge als Shell-Surfaces beschreiben.</x-dialog>', {
675
+ attributes: { id: 'docs-demo-dialog', title: 'Dialog Surface', width: '420px', height: '220px', overlay: true },
676
+ children: ['RMT kann Dialoge als Shell-Surfaces beschreiben.'],
677
+ actions: ['open-dialog']
678
+ });
679
+ add('components-xdrawer', 'x-drawer', 'x-drawer', 'Drawer mit Trigger-Slot fuer Tooling- und Navigationsflaechen.', '<x-drawer id="docs-demo-drawer" label="Inspector" placement="right"><x-button slot="trigger" variant="secondary">Drawer oeffnen</x-button><p>Inspector-Panel fuer Shell-Metadaten.</p></x-drawer>', {
680
+ attributes: { id: 'docs-demo-drawer', label: 'Inspector', placement: 'right' },
681
+ children: [
682
+ { tag: 'x-button', attributes: { slot: 'trigger', variant: 'secondary' }, children: ['Drawer oeffnen'] },
683
+ { tag: 'p', children: ['Inspector-Panel fuer Shell-Metadaten.'] }
684
+ ]
685
+ });
686
+ add('components-xpopover', 'x-popover', 'x-popover', 'Kontextpanel mit Trigger, Placement und optionaler Modalitaet.', '<x-popover id="docs-demo-popover" placement="bottom"><x-button slot="trigger" variant="secondary">Popover</x-button><p>Microcopy, Actions oder kurze Settings.</p></x-popover>', {
687
+ attributes: { id: 'docs-demo-popover', placement: 'bottom' },
688
+ children: [
689
+ { tag: 'x-button', attributes: { slot: 'trigger', variant: 'secondary' }, children: ['Popover'] },
690
+ { tag: 'p', children: ['Microcopy, Actions oder kurze Settings.'] }
691
+ ]
692
+ });
693
+ add('components-xtooltip', 'x-tooltip', 'x-tooltip', 'Nicht-modale Hilfe am Control.', '<span id="docs-demo-tooltip-anchor">Hover oder Fokus</span><x-tooltip for="docs-demo-tooltip-anchor" placement="top" label="Tooltip">Kontext ohne Layoutsprung.</x-tooltip>', {
694
+ attributes: { for: 'docs-demo-tooltip-anchor', placement: 'top', label: 'Tooltip' },
695
+ children: ['Kontext ohne Layoutsprung.']
696
+ });
697
+ add('components-xtabs', 'x-tabs', 'x-tabs', 'Tab-Shell fuer dichte Tool- oder Contentbereiche.', '<x-tabs selected="0"><x-tab name="Preview">Preview</x-tab><x-tab name="RMT">RMT Descriptor</x-tab><x-tab name="Events">Events</x-tab></x-tabs>', {
698
+ attributes: { selected: '0' },
699
+ children: [
700
+ { tag: 'x-tab', attributes: { name: 'Preview' }, children: ['Preview'] },
701
+ { tag: 'x-tab', attributes: { name: 'RMT' }, children: ['RMT Descriptor'] },
702
+ { tag: 'x-tab', attributes: { name: 'Events' }, children: ['Events'] }
703
+ ]
704
+ });
705
+ add('components-xsummary', 'x-summary', 'x-summary', 'Disclosure-Control fuer progressive Detailtiefe.', '<x-summary type="info" open><span slot="summary">Contract Details</span><p>Shell-first, component-managed, RMT-schedulbar.</p></x-summary>', {
706
+ attributes: { type: 'info', open: true },
707
+ children: [
708
+ { tag: 'span', attributes: { slot: 'summary' }, children: ['Contract Details'] },
709
+ { tag: 'p', children: ['Shell-first, component-managed, RMT-schedulbar.'] }
710
+ ]
711
+ });
712
+ add('components-xcode', 'x-code', 'x-code', 'Copy-faehiger Codebereich fuer Beispiele und Snippets.', '<x-code lang="html"><template><x-button variant="primary">Ship it</x-button></template></x-code>', {
713
+ attributes: { lang: 'html' },
714
+ children: [
715
+ { tag: 'template', children: ['<x-button variant="primary">Ship it</x-button>'] }
716
+ ]
717
+ });
718
+ add('components-xsection', 'x-section', 'x-section', 'Layout-Sektion als RMT-Shell-Baustein.', '<x-section label="Demo Section" bordered><strong>Shell Slot</strong><p>Content, Aside und Footer bleiben komponierbar.</p></x-section>', {
719
+ attributes: { label: 'Demo Section', bordered: true },
720
+ children: [
721
+ { tag: 'strong', children: ['Shell Slot'] },
722
+ { tag: 'p', children: ['Content, Aside und Footer bleiben komponierbar.'] }
723
+ ]
724
+ });
725
+ add('components-xcards', 'x-cards', 'x-cards', 'Kompakte Kartenlisten fuer wiederholte Inhalte.', '<x-cards columns="2" gap="0.75rem"><article><strong>Surface</strong><p>Window</p></article><article><strong>Lane</strong><p>visible</p></article></x-cards>', {
726
+ attributes: { columns: '2', gap: '0.75rem' },
727
+ children: [
728
+ { tag: 'article', children: [{ tag: 'strong', children: ['Surface'] }, { tag: 'p', children: ['Window'] }] },
729
+ { tag: 'article', children: [{ tag: 'strong', children: ['Lane'] }, { tag: 'p', children: ['visible'] }] }
730
+ ]
731
+ });
732
+ add('components-xhero', 'x-hero', 'x-hero', 'First-viewport Signal fuer App-Shells.', '<x-hero background-light="#f8fbff" background-dark="#050506" font-color-light="#162033" font-color-dark="#f8fafc" align="block"><h2>XTend Shell</h2><p>RMT orchestrated.</p></x-hero>', {
733
+ attributes: { 'background-light': '#f8fbff', 'background-dark': '#050506', 'font-color-light': '#162033', 'font-color-dark': '#f8fafc', align: 'block' },
734
+ children: [{ tag: 'h2', children: ['XTend Shell'] }, { tag: 'p', children: ['RMT orchestrated.'] }]
735
+ });
736
+ add('components-xtype', 'x-type', 'x-type', 'Typographische Microanimation fuer Status- oder Hero-Zeilen.', '<x-type texts="[&quot;App Shell&quot;,&quot;RMT&quot;,&quot;Lifecycle&quot;]" speed="40" pause="900" cursor></x-type>', {
737
+ attributes: { texts: '["App Shell","RMT","Lifecycle"]', speed: '40', pause: '900', cursor: true }
738
+ });
739
+ add('components-xmasonry', 'x-masonry', 'x-masonry', 'Dichte Content-Galerien ohne externes Layout-Framework.', '<x-masonry columns="2" gap="0.6rem"><div>Window</div><div>Panel</div><div>Overlay</div></x-masonry>', {
740
+ attributes: { columns: '2', gap: '0.6rem' },
741
+ children: [{ tag: 'div', children: ['Window'] }, { tag: 'div', children: ['Panel'] }, { tag: 'div', children: ['Overlay'] }]
742
+ });
743
+ const lightboxLogoUrl = getDocsAssetUrl('lightboxLogo', 'index.php?xtend-docs-asset=xtend-logo.png');
744
+ add('components-xlightbox', 'x-lightbox', 'x-lightbox', 'Medien-Fokus ohne Shell-Kontext zu verlieren.', `<x-lightbox id="docs-demo-lightbox" src="${escapeDocsHtmlAttribute(lightboxLogoUrl)}" alt="XTend Logo"><x-button slot="trigger" variant="secondary">Logo ansehen</x-button></x-lightbox>`, {
745
+ attributes: { id: 'docs-demo-lightbox', src: lightboxLogoUrl, alt: 'XTend Logo' },
746
+ children: [{ tag: 'x-button', attributes: { slot: 'trigger', variant: 'secondary' }, children: ['Logo ansehen'] }]
747
+ });
748
+ add('components-xsidepanel', 'x-side-panel', 'x-side-panel', 'SidePanel-Surface fuer near-native App-Shells.', '<div class="docs-demo-surface-zone"><x-side-panel surface-id="docs.demo.panel" label="Docs Inspector" open active mode="docked" placement="right" initial-width="18rem"><p>Related Links und Demo-Code leben hier.</p></x-side-panel></div>', {
749
+ attributes: { 'surface-id': 'docs.demo.panel', label: 'Docs Inspector', open: true, active: true, mode: 'docked', placement: 'right', 'initial-width': '18rem' },
750
+ children: [{ tag: 'p', children: ['Related Links und Demo-Code leben hier.'] }]
751
+ });
752
+ add('components-xsurfacewindow', 'x-surface-window', 'x-surface-window', 'Window-Surface fuer Multi-Window SPAs.', '<div class="docs-demo-surface-zone"><x-surface-window surface-id="docs.demo.window" label="Preview Window" open active initial-x="16" initial-y="16" initial-width="18rem" initial-height="10rem" resizable draggable><p>Window Content</p></x-surface-window></div>', {
753
+ attributes: { 'surface-id': 'docs.demo.window', label: 'Preview Window', open: true, active: true, 'initial-x': '16', 'initial-y': '16', 'initial-width': '18rem', 'initial-height': '10rem', resizable: true, draggable: true },
754
+ children: [{ tag: 'p', children: ['Window Content'] }]
755
+ });
756
+ add('components-xsurfacemanager', 'x-surface-manager', 'x-surface-manager', 'Surface-Wurzel fuer Windows, Panels und Overlays.', '<div class="docs-demo-surface-zone"><x-surface-manager manager-id="docs.demo.manager" layout="workbench"><x-surface-window slot="windows" surface-id="docs.manager.window" label="Window" open initial-width="16rem" initial-height="9rem"><p>Managed Window</p></x-surface-window><x-side-panel slot="panels" surface-id="docs.manager.panel" label="Panel" open mode="docked" placement="right"><p>Managed Panel</p></x-side-panel></x-surface-manager></div>', {
757
+ attributes: { 'manager-id': 'docs.demo.manager', layout: 'workbench' },
758
+ children: [
759
+ { tag: 'x-surface-window', attributes: { slot: 'windows', 'surface-id': 'docs.manager.window', label: 'Window', open: true, 'initial-width': '16rem', 'initial-height': '9rem' }, children: [{ tag: 'p', children: ['Managed Window'] }] },
760
+ { tag: 'x-side-panel', attributes: { slot: 'panels', 'surface-id': 'docs.manager.panel', label: 'Panel', open: true, mode: 'docked', placement: 'right' }, children: [{ tag: 'p', children: ['Managed Panel'] }] }
761
+ ]
762
+ });
763
+
764
+ return demos;
765
+ }
766
+
767
+ function resolveDocsToastApi() {
768
+ const xtendToast = window.XTend && window.XTend.toast;
769
+ if (xtendToast && typeof xtendToast.show === 'function') return xtendToast;
770
+ if (window.XToast && typeof window.XToast.show === 'function') return window.XToast;
771
+ return null;
772
+ }
773
+
774
+ function waitForDocsToastApi(callback, attempt = 0) {
775
+ const toastApi = resolveDocsToastApi();
776
+ if (toastApi) return callback(toastApi);
777
+ if (attempt >= 20) {
778
+ window.dispatchEvent(new CustomEvent('xtend-docs-toast-dropped', {
779
+ detail: {
780
+ schema: 'xtend.docs.toast-bridge.v1',
781
+ reason: 'xtend-toast-api-unavailable'
782
+ }
783
+ }));
784
+ return null;
785
+ }
786
+ window.setTimeout(() => waitForDocsToastApi(callback, attempt + 1), attempt < 4 ? 50 : 100);
787
+ return null;
788
+ }
789
+
790
+ window.xtendShowToast = function(message, type = 'info', duration = 3000) {
791
+ return waitForDocsToastApi((toastApi) => toastApi.show(message, type, duration));
792
+ };
793
+
794
+ function getDocsRmtDocument() {
795
+ return window.xtendDocsRmtDocument && typeof window.xtendDocsRmtDocument === 'object'
796
+ ? window.xtendDocsRmtDocument
797
+ : {};
798
+ }
799
+
800
+ function indexRmtRecords(records) {
801
+ return new Map((Array.isArray(records) ? records : [])
802
+ .filter((record) => record && typeof record === 'object')
803
+ .map((record) => [record.id || record.qualifiedId || record.templateId, record]));
804
+ }
805
+
806
+ function findRmtRecord(records, id) {
807
+ if (!id) return null;
808
+ const byId = indexRmtRecords(records);
809
+ if (byId.has(id)) return byId.get(id);
810
+ return (Array.isArray(records) ? records : []).find((record) => (
811
+ record
812
+ && typeof record === 'object'
813
+ && (record.id === id || record.qualifiedId === id || record.templateId === id)
814
+ )) || null;
815
+ }
816
+
817
+ function getRmtTemplate(templateId) {
818
+ const documentRecord = getDocsRmtDocument();
819
+ return findRmtRecord(documentRecord.templates, templateId);
820
+ }
821
+
822
+ function getRmtSchedule(scheduleId) {
823
+ const documentRecord = getDocsRmtDocument();
824
+ return findRmtRecord(documentRecord.schedules, scheduleId);
825
+ }
826
+
827
+ function getDocsRmtProductionHardening() {
828
+ if (window.xtendDocsRmtProductionHardening && typeof window.xtendDocsRmtProductionHardening === 'object') {
829
+ return window.xtendDocsRmtProductionHardening;
830
+ }
831
+ const documentRecord = getDocsRmtDocument();
832
+ const metadata = documentRecord.manifest && documentRecord.manifest.metadata;
833
+ return metadata && metadata.productionHardening && typeof metadata.productionHardening === 'object'
834
+ ? metadata.productionHardening
835
+ : {};
836
+ }
837
+
838
+ function getTemplateDescriptorNodes(template) {
839
+ if (!template || typeof template !== 'object') return [];
840
+ if (Array.isArray(template.nodes)) return template.nodes;
841
+ const descriptor = template.metadata && template.metadata.descriptor;
842
+ if (descriptor && Array.isArray(descriptor.nodes)) return descriptor.nodes;
843
+ return [];
844
+ }
845
+
846
+ function resolveRmtValue(value, model = {}) {
847
+ if (typeof value !== 'string') return value;
848
+ return value
849
+ .replace(/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g, (match, key) => {
850
+ return Object.prototype.hasOwnProperty.call(model, key) ? String(model[key]) : match;
851
+ })
852
+ .replace(/\$\{\s*([a-zA-Z0-9_.-]+)\s*\}/g, (match, key) => {
853
+ return Object.prototype.hasOwnProperty.call(model, key) ? String(model[key]) : match;
854
+ });
855
+ }
856
+
857
+ function applyRmtAttributes(element, attributes = {}, model = {}) {
858
+ Object.entries(attributes || {}).forEach(([name, rawValue]) => {
859
+ if (rawValue === false || rawValue === null || rawValue === undefined) return;
860
+ if (name === 'style' && rawValue && typeof rawValue === 'object') {
861
+ Object.entries(rawValue).forEach(([prop, value]) => {
862
+ element.style[prop] = String(resolveRmtValue(value, model));
863
+ });
864
+ return;
865
+ }
866
+ const value = rawValue === true ? '' : String(resolveRmtValue(rawValue, model));
867
+ element.setAttribute(name, value);
868
+ });
869
+ }
870
+
871
+ function renderRmtDescriptorNode(node, model = {}) {
872
+ if (typeof node === 'string') {
873
+ return document.createTextNode(resolveRmtValue(node, model));
874
+ }
875
+ if (!node || typeof node !== 'object') {
876
+ return document.createTextNode('');
877
+ }
878
+ if (!node.tag && node.text !== undefined) {
879
+ return document.createTextNode(resolveRmtValue(String(node.text), model));
880
+ }
881
+
882
+ const element = document.createElement(String(node.tag || 'div'));
883
+ applyRmtAttributes(element, node.attributes || {}, model);
884
+
885
+ if (node.text !== undefined) {
886
+ element.appendChild(document.createTextNode(resolveRmtValue(String(node.text), model)));
887
+ }
888
+
889
+ (Array.isArray(node.children) ? node.children : []).forEach((child) => {
890
+ element.appendChild(renderRmtDescriptorNode(child, model));
891
+ });
892
+
893
+ return element;
894
+ }
895
+
896
+ function renderRmtDomTemplate(templateId, model = {}) {
897
+ const template = getRmtTemplate(templateId);
898
+ const fragment = document.createDocumentFragment();
899
+ const nodes = getTemplateDescriptorNodes(template);
900
+ nodes.forEach((node) => {
901
+ fragment.appendChild(renderRmtDescriptorNode(node, model));
902
+ });
903
+ return {
904
+ template,
905
+ fragment,
906
+ rendered: nodes.length > 0
907
+ };
908
+ }
909
+
910
+ function getDocsPageMeta(slug) {
911
+ return window.xtendDocsPagesMeta && window.xtendDocsPagesMeta[slug]
912
+ ? window.xtendDocsPagesMeta[slug]
913
+ : null;
914
+ }
915
+
916
+ function createDocsSidebarHeading(iconName, label, options = {}) {
917
+ const heading = document.createElement('h2');
918
+ heading.className = 'docs-sidebar-heading';
919
+ const icon = document.createElement('x-icon');
920
+ icon.setAttribute('name', iconName || 'link');
921
+ icon.setAttribute('pack', 'lucide');
922
+ icon.setAttribute('decorative', '');
923
+ icon.setAttribute('size', '1rem');
924
+ const text = document.createElement('span');
925
+ if (options.demoTitle) text.setAttribute('data-demo-title', '');
926
+ text.textContent = label;
927
+ heading.appendChild(icon);
928
+ heading.appendChild(text);
929
+ return heading;
930
+ }
931
+
932
+ function ensureDocsShellScopedStyles(root) {
933
+ if (!root || !root.host || typeof root.getElementById !== 'function' || typeof root.appendChild !== 'function') {
934
+ return;
935
+ }
936
+ if (root.getElementById(DOCS_SHELL_SHADOW_STYLE_ID)) return;
937
+ const style = document.createElement('style');
938
+ style.id = DOCS_SHELL_SHADOW_STYLE_ID;
939
+ style.setAttribute('data-rmt-style-scope', 'docs.shell');
940
+ style.textContent = DOCS_SHELL_SCOPED_CSS;
941
+ root.appendChild(style);
942
+ }
943
+
944
+ function createFallbackDocsShell() {
945
+ const section = document.createElement('section');
946
+ section.className = 'docs-app-shell';
947
+ section.setAttribute('aria-label', 'XTend Developer Center Content Shell');
948
+ section.setAttribute('data-rmt-shell', DOCS_RMT_DEFAULT_SHELL_TEMPLATE);
949
+ section.setAttribute('data-rmt-shell-mode', 'shell-first');
950
+
951
+ const layout = document.createElement('div');
952
+ layout.className = 'docs-shell-layout';
953
+ layout.setAttribute('data-rmt-layout', 'main-sidebar');
954
+ layout.setAttribute('data-rmt-component', 'docs.shellLayout');
955
+
956
+ const article = document.createElement('article');
957
+ article.className = 'docs-article-surface';
958
+ article.setAttribute('data-rmt-slot', 'article');
959
+ article.setAttribute('data-rmt-component', 'docs.article');
960
+
961
+ const toolbar = document.createElement('div');
962
+ toolbar.className = 'docs-shell-toolbar';
963
+ toolbar.setAttribute('data-rmt-slot', 'actions');
964
+
965
+ const download = document.createElement('x-button');
966
+ download.className = 'download-link';
967
+ download.id = 'download-link';
968
+ download.setAttribute('type', 'button');
969
+ download.setAttribute('data-rmt-action', 'docs.download.markdown');
970
+ configureDocsIconButton(download, {
971
+ icon: 'download',
972
+ pack: 'core',
973
+ label: 'Download als Markdown'
974
+ });
975
+
976
+ const mdContent = document.createElement('div');
977
+ mdContent.id = 'md-content';
978
+ mdContent.setAttribute('data-rmt-slot', 'content');
979
+ mdContent.setAttribute('data-rmt-extension-slot', 'docs.slot.content');
980
+ mdContent.setAttribute('data-rmt-content-kind', 'parsedownHtml');
981
+ mdContent.setAttribute('data-rmt-trust-boundary', DOCS_RMT_TRUST_BOUNDARY);
982
+
983
+ const sidebar = document.createElement('aside');
984
+ sidebar.id = 'docs-page-sidebar';
985
+ sidebar.className = 'docs-page-sidebar';
986
+ sidebar.setAttribute('data-rmt-slot', 'sidebar');
987
+ sidebar.setAttribute('data-rmt-extension-slot', 'docs.slot.sidebar');
988
+ sidebar.setAttribute('data-rmt-component', 'docs.sidebar');
989
+ sidebar.setAttribute('aria-label', 'Seitliche Dokumentationswerkzeuge');
990
+
991
+ const relatedSlot = document.createElement('section');
992
+ relatedSlot.id = 'docs-related-links';
993
+ relatedSlot.className = 'docs-sidebar-section docs-related-section';
994
+ relatedSlot.setAttribute('data-rmt-slot', 'related');
995
+ relatedSlot.setAttribute('data-rmt-component', 'docs.relatedLinks');
996
+ relatedSlot.setAttribute('data-rmt-schedule', 'docs.related.prepare');
997
+ relatedSlot.appendChild(createDocsSidebarHeading('link', 'Read Further'));
998
+ const relatedList = document.createElement('div');
999
+ relatedList.className = 'docs-related-list';
1000
+ relatedList.setAttribute('data-rmt-slot', 'related-links');
1001
+ relatedSlot.appendChild(relatedList);
1002
+
1003
+ const demoSlot = document.createElement('section');
1004
+ demoSlot.id = 'docs-component-demo';
1005
+ demoSlot.className = 'docs-sidebar-section docs-component-demo';
1006
+ demoSlot.hidden = true;
1007
+ demoSlot.setAttribute('data-rmt-slot', 'component-demo');
1008
+ demoSlot.setAttribute('data-rmt-component', 'docs.componentDemo');
1009
+ demoSlot.setAttribute('data-rmt-schedule', 'docs.demo.prepare');
1010
+ demoSlot.appendChild(createDocsSidebarHeading('play', 'Hands-on Demo', { demoTitle: true }));
1011
+ const demoCopy = document.createElement('p');
1012
+ demoCopy.className = 'docs-sidebar-copy';
1013
+ demoCopy.setAttribute('data-demo-description', '');
1014
+ demoCopy.textContent = 'Direkt testen, danach HTML und RMT uebernehmen.';
1015
+ const demoPreview = document.createElement('div');
1016
+ demoPreview.className = 'docs-demo-preview';
1017
+ demoPreview.setAttribute('data-demo-preview', '');
1018
+ const demoCode = document.createElement('div');
1019
+ demoCode.className = 'docs-demo-code-grid';
1020
+ demoCode.setAttribute('data-demo-code', '');
1021
+ demoSlot.appendChild(demoCopy);
1022
+ demoSlot.appendChild(demoPreview);
1023
+ demoSlot.appendChild(demoCode);
1024
+
1025
+ const richSlot = document.createElement('aside');
1026
+ richSlot.id = 'docs-rich-content';
1027
+ richSlot.hidden = true;
1028
+ richSlot.setAttribute('data-rmt-slot', 'rich-content');
1029
+ richSlot.setAttribute('data-rmt-extension-slot', 'docs.slot.rich-content');
1030
+ richSlot.setAttribute('data-rmt-content-kinds', 'richHtml,xplayerTutorial');
1031
+ richSlot.setAttribute('data-rmt-schedule', 'docs.rich-content.prepare');
1032
+ richSlot.setAttribute('data-rmt-media-schedule', 'docs.media.lazy');
1033
+ richSlot.setAttribute('data-rmt-production-hardening', DOCS_RMT_PRODUCTION_HARDENING_SCHEMA);
1034
+
1035
+ const diagnosticsSlot = document.createElement('div');
1036
+ diagnosticsSlot.id = 'docs-rmt-diagnostics';
1037
+ diagnosticsSlot.hidden = true;
1038
+ diagnosticsSlot.setAttribute('data-rmt-slot', 'diagnostics');
1039
+ diagnosticsSlot.setAttribute('data-rmt-extension-slot', 'docs.slot.diagnostics');
1040
+ diagnosticsSlot.setAttribute('data-rmt-schedule', DOCS_RMT_DEFAULT_DIAGNOSTICS_SCHEDULE);
1041
+ diagnosticsSlot.setAttribute('data-rmt-content-kind', 'diagnostics');
1042
+ diagnosticsSlot.setAttribute('data-rmt-production-hardening', DOCS_RMT_PRODUCTION_HARDENING_SCHEMA);
1043
+
1044
+ toolbar.appendChild(download);
1045
+ article.appendChild(toolbar);
1046
+ article.appendChild(mdContent);
1047
+ sidebar.appendChild(relatedSlot);
1048
+ sidebar.appendChild(demoSlot);
1049
+ sidebar.appendChild(richSlot);
1050
+ sidebar.appendChild(diagnosticsSlot);
1051
+ layout.appendChild(article);
1052
+ layout.appendChild(sidebar);
1053
+ section.appendChild(layout);
1054
+
1055
+ return {
1056
+ section,
1057
+ layout,
1058
+ article,
1059
+ mdContent,
1060
+ sidebar,
1061
+ relatedSlot,
1062
+ demoSlot,
1063
+ download,
1064
+ richSlot,
1065
+ diagnosticsSlot,
1066
+ shellTemplate: null
1067
+ };
1068
+ }
1069
+
1070
+ function createRmtDocsShell(slug, rmtMeta = {}) {
1071
+ const shellTemplateId = rmtMeta.shellTemplate || (window.xtendDocsRmtPilot && window.xtendDocsRmtPilot.shellTemplate) || DOCS_RMT_DEFAULT_SHELL_TEMPLATE;
1072
+ const shellSchedule = rmtMeta.schedules && rmtMeta.schedules.shell ? rmtMeta.schedules.shell : 'docs.shell.render';
1073
+ const rendered = renderRmtDomTemplate(shellTemplateId, {
1074
+ slug,
1075
+ source: rmtMeta.source || '',
1076
+ contentKind: rmtMeta.contentKind || 'parsedownHtml',
1077
+ shellSchedule
1078
+ });
1079
+
1080
+ if (!rendered.rendered) {
1081
+ const fallback = createFallbackDocsShell();
1082
+ fallback.shellTemplate = rendered.template;
1083
+ return fallback;
1084
+ }
1085
+
1086
+ const section = rendered.fragment.querySelector
1087
+ ? rendered.fragment.querySelector('[data-rmt-shell], .docs-app-shell')
1088
+ : null;
1089
+ const shell = section || rendered.fragment.firstElementChild || createFallbackDocsShell().section;
1090
+ shell.classList.add('docs-app-shell');
1091
+ const layout = shell.querySelector('[data-rmt-layout="main-sidebar"], .docs-shell-layout');
1092
+ const article = shell.querySelector('[data-rmt-slot="article"], .docs-article-surface');
1093
+ const mdContent = shell.querySelector('[data-rmt-slot="content"], #md-content') || document.createElement('div');
1094
+ const download = shell.querySelector('[data-rmt-action="docs.download.markdown"], #download-link') || document.createElement('x-button');
1095
+ const sidebar = shell.querySelector('[data-rmt-slot="sidebar"], #docs-page-sidebar');
1096
+ const relatedSlot = shell.querySelector('[data-rmt-slot="related"], #docs-related-links');
1097
+ const demoSlot = shell.querySelector('[data-rmt-slot="component-demo"], #docs-component-demo');
1098
+ const richSlot = shell.querySelector('[data-rmt-slot="rich-content"], #docs-rich-content');
1099
+ const diagnosticsSlot = shell.querySelector('[data-rmt-slot="diagnostics"], #docs-rmt-diagnostics');
1100
+
1101
+ if (!layout || !article || !sidebar || !relatedSlot || !demoSlot) {
1102
+ const fallback = createFallbackDocsShell();
1103
+ fallback.shellTemplate = rendered.template;
1104
+ fallback.section.setAttribute('data-rmt-shell-fallback', 'missing-sidebar-slots');
1105
+ return fallback;
1106
+ }
1107
+
1108
+ if (!mdContent.id) mdContent.id = 'md-content';
1109
+ if (!download.id) download.id = 'download-link';
1110
+ configureDocsIconButton(download, {
1111
+ icon: 'download',
1112
+ pack: 'core',
1113
+ label: 'Download als Markdown'
1114
+ });
1115
+ if (!download.parentNode) shell.insertBefore(download, shell.firstChild);
1116
+ if (!mdContent.parentNode) shell.appendChild(mdContent);
1117
+
1118
+ return {
1119
+ section: shell,
1120
+ layout,
1121
+ article,
1122
+ mdContent,
1123
+ sidebar,
1124
+ relatedSlot,
1125
+ demoSlot,
1126
+ download,
1127
+ richSlot,
1128
+ diagnosticsSlot,
1129
+ shellTemplate: rendered.template
1130
+ };
1131
+ }
1132
+
1133
+ function configureDocsIconButton(button, options = {}) {
1134
+ if (!button) return;
1135
+ const label = options.label || button.getAttribute('aria-label') || 'Aktion ausfuehren';
1136
+ const iconName = options.icon || 'download';
1137
+ const pack = options.pack || 'core';
1138
+ button.classList.add('docs-icon-button');
1139
+ button.setAttribute('type', 'button');
1140
+ button.setAttribute('variant', button.getAttribute('variant') || 'secondary');
1141
+ button.setAttribute('aria-label', label);
1142
+ button.setAttribute('title', label);
1143
+
1144
+ const existingIcon = button.querySelector('x-icon');
1145
+ const existingLabel = button.querySelector('.docs-visually-hidden');
1146
+ if (existingIcon) {
1147
+ existingIcon.setAttribute('name', iconName);
1148
+ existingIcon.setAttribute('pack', pack);
1149
+ existingIcon.setAttribute('decorative', '');
1150
+ if (!existingIcon.getAttribute('size')) existingIcon.setAttribute('size', '1.1rem');
1151
+ }
1152
+ if (existingLabel) {
1153
+ existingLabel.textContent = label;
1154
+ }
1155
+ if (existingIcon && existingLabel) return;
1156
+
1157
+ button.textContent = '';
1158
+ const icon = document.createElement('x-icon');
1159
+ icon.setAttribute('name', iconName);
1160
+ icon.setAttribute('pack', pack);
1161
+ icon.setAttribute('decorative', '');
1162
+ icon.setAttribute('size', '1.1rem');
1163
+ const hiddenLabel = document.createElement('span');
1164
+ hiddenLabel.className = 'docs-visually-hidden';
1165
+ hiddenLabel.textContent = label;
1166
+ button.appendChild(icon);
1167
+ button.appendChild(hiddenLabel);
1168
+ }
1169
+
1170
+ function setDocsButtonBusy(button, busy) {
1171
+ if (!button) return;
1172
+ if (busy) {
1173
+ button.setAttribute('disabled', '');
1174
+ button.setAttribute('aria-busy', 'true');
1175
+ } else {
1176
+ button.removeAttribute('disabled');
1177
+ button.removeAttribute('aria-busy');
1178
+ }
1179
+ }
1180
+
1181
+ function bindDocsButtonAction(button, handler) {
1182
+ if (!button || typeof handler !== 'function') return;
1183
+ const activationEvent = button.tagName === 'X-BUTTON' ? 'button-interaction' : 'click';
1184
+ button.addEventListener(activationEvent, handler);
1185
+ }
1186
+
1187
+ function applyRmtPageMetadata(section, mdContent, richSlot, diagnosticsSlot, rmtMeta = {}, sidebar = null, relatedSlot = null, demoSlot = null) {
1188
+ const schedules = rmtMeta.schedules || {};
1189
+ const endpoints = rmtMeta.endpoints || {};
1190
+ const shellSchedule = schedules.shell || 'docs.shell.render';
1191
+ const mediaSchedule = schedules.media || 'docs.media.lazy';
1192
+ const richSchedule = schedules.rich || 'docs.rich-content.prepare';
1193
+ const diagnosticsSchedule = schedules.diagnostics || DOCS_RMT_DEFAULT_DIAGNOSTICS_SCHEDULE;
1194
+ const hardening = getDocsRmtProductionHardening();
1195
+
1196
+ section.style.background = 'var(--section-bg, #fff)';
1197
+ section.style.color = 'var(--text-color, #222)';
1198
+ section.setAttribute('data-rmt-component', rmtMeta.component || 'docs.page');
1199
+ section.setAttribute('data-rmt-shell', rmtMeta.shellTemplate || DOCS_RMT_DEFAULT_SHELL_TEMPLATE);
1200
+ section.setAttribute('data-rmt-shell-first', 'true');
1201
+ section.setAttribute('data-rmt-production-hardening', hardening.schema || DOCS_RMT_PRODUCTION_HARDENING_SCHEMA);
1202
+ section.setAttribute('data-rmt-shell-schedule', shellSchedule);
1203
+ section.setAttribute('data-rmt-route-schedule', schedules.route || 'docs.route.render');
1204
+ section.setAttribute('data-rmt-hydrate-schedule', schedules.hydrate || 'docs.page.hydrate');
1205
+ section.setAttribute('data-rmt-route-title', rmtMeta.title || '');
1206
+ section.setAttribute('data-rmt-document-title', rmtMeta.documentTitle || '');
1207
+ section.setAttribute('data-rmt-title-template', rmtMeta.titleTemplate || '{{title}} | XTend Dokumentation');
1208
+
1209
+ if (sidebar) {
1210
+ sidebar.setAttribute('data-rmt-slot', 'sidebar');
1211
+ sidebar.setAttribute('data-rmt-extension-slot', 'docs.slot.sidebar');
1212
+ sidebar.setAttribute('data-rmt-component', 'docs.sidebar');
1213
+ sidebar.setAttribute('data-rmt-shell-schedule', shellSchedule);
1214
+ }
1215
+
1216
+ if (relatedSlot) {
1217
+ relatedSlot.setAttribute('data-rmt-slot', 'related');
1218
+ relatedSlot.setAttribute('data-rmt-extension-slot', 'docs.slot.related');
1219
+ relatedSlot.setAttribute('data-rmt-component', 'docs.relatedLinks');
1220
+ relatedSlot.setAttribute('data-rmt-schedule', 'docs.related.prepare');
1221
+ }
1222
+
1223
+ if (demoSlot) {
1224
+ demoSlot.setAttribute('data-rmt-slot', 'component-demo');
1225
+ demoSlot.setAttribute('data-rmt-extension-slot', 'docs.slot.component-demo');
1226
+ demoSlot.setAttribute('data-rmt-component', 'docs.componentDemo');
1227
+ demoSlot.setAttribute('data-rmt-schedule', 'docs.demo.prepare');
1228
+ }
1229
+
1230
+ mdContent.setAttribute('data-rmt-slot', mdContent.getAttribute('data-rmt-slot') || 'content');
1231
+ mdContent.setAttribute('data-rmt-extension-slot', 'docs.slot.content');
1232
+ mdContent.setAttribute('data-rmt-template', rmtMeta.template || '');
1233
+ mdContent.setAttribute('data-rmt-template-adapter', rmtMeta.adapter || 'docs.parsedown');
1234
+ mdContent.setAttribute('data-rmt-parse-schedule', schedules.parse || 'docs.markdown.parse');
1235
+ mdContent.setAttribute('data-rmt-parse-endpoint', endpoints.parse || DOCS_RMT_PARSEDOWN_ENDPOINT);
1236
+ mdContent.setAttribute('data-rmt-markup-class', rmtMeta.markupClass || 'parsedownHtml');
1237
+ mdContent.setAttribute('data-rmt-content-kind', rmtMeta.contentKind || 'parsedownHtml');
1238
+ mdContent.setAttribute('data-rmt-trust-boundary', rmtMeta.trustBoundary || DOCS_RMT_TRUST_BOUNDARY);
1239
+
1240
+ if (richSlot) {
1241
+ richSlot.setAttribute('data-rmt-extension-slot', 'docs.slot.rich-content');
1242
+ richSlot.setAttribute('data-rmt-schedule', richSchedule);
1243
+ richSlot.setAttribute('data-rmt-media-schedule', mediaSchedule);
1244
+ richSlot.setAttribute('data-rmt-content-kinds', 'richHtml,xplayerTutorial');
1245
+ richSlot.setAttribute('data-rmt-trust-boundary', rmtMeta.trustBoundary || DOCS_RMT_TRUST_BOUNDARY);
1246
+ richSlot.setAttribute('data-rmt-production-hardening', hardening.schema || DOCS_RMT_PRODUCTION_HARDENING_SCHEMA);
1247
+ }
1248
+
1249
+ if (diagnosticsSlot) {
1250
+ diagnosticsSlot.setAttribute('data-rmt-slot', 'diagnostics');
1251
+ diagnosticsSlot.setAttribute('data-rmt-extension-slot', 'docs.slot.diagnostics');
1252
+ diagnosticsSlot.setAttribute('data-rmt-schedule', diagnosticsSchedule);
1253
+ diagnosticsSlot.setAttribute('data-rmt-content-kind', 'diagnostics');
1254
+ diagnosticsSlot.setAttribute('data-rmt-production-hardening', hardening.schema || DOCS_RMT_PRODUCTION_HARDENING_SCHEMA);
1255
+ }
1256
+ }
1257
+
1258
+ function createDocsRmtProductionRenderSnapshot(slug, rmtMeta, shell) {
1259
+ const hardening = getDocsRmtProductionHardening();
1260
+ const schedules = rmtMeta.schedules || {};
1261
+ const extensionSlots = Array.isArray(hardening.extensionSlots)
1262
+ ? hardening.extensionSlots.slice()
1263
+ : DOCS_RMT_EXTENSION_SLOTS.slice();
1264
+ return {
1265
+ schema: hardening.renderSchema || DOCS_RMT_PRODUCTION_HARDENING_SCHEMA,
1266
+ slug,
1267
+ shellFirst: true,
1268
+ parsedownOrchestrated: true,
1269
+ parsedownEmbeddedInRmtKernel: false,
1270
+ extensionSlots,
1271
+ contentSlot: rmtMeta.contentSlot || 'content',
1272
+ sidebarSlotAvailable: Boolean(shell.sidebar),
1273
+ relatedSlotAvailable: Boolean(shell.relatedSlot),
1274
+ componentDemoSlotAvailable: Boolean(shell.demoSlot),
1275
+ richSlotAvailable: Boolean(shell.richSlot),
1276
+ diagnosticsSlotAvailable: Boolean(shell.diagnosticsSlot),
1277
+ parseSchedule: schedules.parse || 'docs.markdown.parse',
1278
+ richSchedule: schedules.rich || 'docs.rich-content.prepare',
1279
+ mediaSchedule: schedules.media || 'docs.media.lazy',
1280
+ diagnosticsSchedule: schedules.diagnostics || DOCS_RMT_DEFAULT_DIAGNOSTICS_SCHEDULE,
1281
+ trustBoundary: rmtMeta.trustBoundary || DOCS_RMT_TRUST_BOUNDARY,
1282
+ trustedDomProofSchema: DOCS_RMT_TRUSTED_DOM_PROOF_SCHEMA,
1283
+ trustedDomSanitizer: DOCS_RMT_TRUSTED_DOM_SANITIZER,
1284
+ sanitizerRequired: true,
1285
+ kernelBoundary: hardening.kernelBoundary || 'Parsedown, PHP execution and Sanitizing stay in the Docs host adapter.',
1286
+ nextWorkpackage: hardening.nextWorkpackage || 'WP-E13-13'
1287
+ };
1288
+ }
1289
+
1290
+ function wireDownloadButton(download, slug) {
1291
+ if (!download) return;
1292
+ download.__xtendDocsDownloadSlug = slug;
1293
+ if (download.__xtendDocsDownloadBound) return;
1294
+ download.__xtendDocsDownloadBound = true;
1295
+ configureDocsIconButton(download, {
1296
+ icon: 'download',
1297
+ pack: 'core',
1298
+ label: 'Download als Markdown'
1299
+ });
1300
+ download.setAttribute('type', 'button');
1301
+ bindDocsButtonAction(download, async function(e) {
1302
+ if (e) {
1303
+ e.preventDefault();
1304
+ e.stopPropagation();
1305
+ }
1306
+ if (download.hasAttribute('disabled')) return;
1307
+ const activeSlug = download.__xtendDocsDownloadSlug || slug;
1308
+ setDocsButtonBusy(download, true);
1309
+ try {
1310
+ const resp = await fetch(`?download=${activeSlug}`);
1311
+ if (!resp.ok) throw new Error('Download fehlgeschlagen');
1312
+ const blob = await resp.blob();
1313
+ const url = URL.createObjectURL(blob);
1314
+ const a = document.createElement('a');
1315
+ a.style.display = 'none';
1316
+ a.href = url;
1317
+ a.download = `${activeSlug}.md`;
1318
+ document.body.appendChild(a);
1319
+ a.click();
1320
+ setTimeout(() => {
1321
+ document.body.removeChild(a);
1322
+ URL.revokeObjectURL(url);
1323
+ }, 100);
1324
+ setTimeout(() => {
1325
+ window.xtendShowToast('Download erfolgreich!', 'success', 3000);
1326
+ }, 200);
1327
+ } catch (err) {
1328
+ setTimeout(() => {
1329
+ window.xtendShowToast('Download fehlgeschlagen!', 'error', 3000);
1330
+ }, 200);
1331
+ } finally {
1332
+ setTimeout(() => {
1333
+ setDocsButtonBusy(download, false);
1334
+ }, 300);
1335
+ }
1336
+ });
1337
+ }
1338
+
1339
+ function createFallbackSearchShell() {
1340
+ const form = document.createElement('x-form');
1341
+ form.id = 'xtend-search-form';
1342
+ form.setAttribute('slot', 'search');
1343
+ form.setAttribute('data-rmt-template', DOCS_RMT_DEFAULT_SEARCH_TEMPLATE);
1344
+ form.setAttribute('data-rmt-component', 'docs.search');
1345
+ form.setAttribute('data-rmt-schedule', 'docs.search.index');
1346
+
1347
+ const label = document.createElement('label');
1348
+ label.setAttribute('for', 'search-input');
1349
+ label.textContent = 'Suche:';
1350
+
1351
+ const input = document.createElement('x-input');
1352
+ input.id = 'search-input';
1353
+ input.setAttribute('name', 'search');
1354
+ input.setAttribute('placeholder', 'Suche...');
1355
+
1356
+ const searchResults = document.createElement('div');
1357
+ searchResults.id = 'search-results';
1358
+ searchResults.setAttribute('data-rmt-slot', 'results');
1359
+
1360
+ form.appendChild(label);
1361
+ form.appendChild(input);
1362
+ form.appendChild(searchResults);
1363
+ return form;
1364
+ }
1365
+
1366
+ function styleSearchShell(form, input, searchResults) {
1367
+ form.setAttribute('slot', 'search');
1368
+ form.classList.add('docs-search-form');
1369
+ form.style.width = '100%';
1370
+ form.style.maxWidth = '30rem';
1371
+ form.style.minWidth = '0';
1372
+ form.style.boxSizing = 'border-box';
1373
+ form.style.setProperty('--form-padding', '0');
1374
+ form.style.setProperty('--form-gap', '0');
1375
+ form.style.setProperty('--form-background', 'transparent');
1376
+ form.style.setProperty('--form-border', '0');
1377
+ form.style.setProperty('--form-shadow', 'none');
1378
+ searchResults.classList.add('docs-search-results');
1379
+ input.setAttribute('aria-controls', searchResults.id || 'search-results');
1380
+
1381
+ const label = form.querySelector('label');
1382
+ if (label) {
1383
+ label.style.position = 'absolute';
1384
+ label.style.width = '1px';
1385
+ label.style.height = '1px';
1386
+ label.style.padding = '0';
1387
+ label.style.margin = '-1px';
1388
+ label.style.overflow = 'hidden';
1389
+ label.style.clip = 'rect(0,0,0,0)';
1390
+ label.style.border = '0';
1391
+ }
1392
+
1393
+ input.style.width = '100%';
1394
+ input.style.minWidth = '12rem';
1395
+ input.style.maxWidth = '100%';
1396
+ input.style.boxSizing = 'border-box';
1397
+
1398
+ searchResults.style.position = 'fixed';
1399
+ searchResults.style.zIndex = '99999';
1400
+ searchResults.style.width = '16rem';
1401
+ searchResults.style.maxWidth = '90vw';
1402
+ searchResults.style.boxShadow = '0 12px 32px rgba(15, 23, 42, 0.18)';
1403
+ searchResults.style.borderRadius = '0.65rem';
1404
+ searchResults.style.margin = '0';
1405
+ searchResults.style.padding = '0.55rem';
1406
+ searchResults.style.display = 'none';
1407
+ searchResults.style.left = '0';
1408
+ searchResults.style.top = '0';
1409
+ }
1410
+
1411
+ function wireSearchForm(form, input, searchResults) {
1412
+ if (!form || !input || !searchResults || form.__xtendDocsSearchBound) return;
1413
+ form.__xtendDocsSearchBound = true;
1414
+
1415
+ function updateSearchResultsPosition() {
1416
+ const rect = input.getBoundingClientRect();
1417
+ searchResults.style.left = rect.left + 'px';
1418
+ searchResults.style.top = (rect.bottom + 6) + 'px';
1419
+ searchResults.style.width = rect.width + 'px';
1420
+ }
1421
+
1422
+ function clearResults() {
1423
+ while (searchResults.firstChild) {
1424
+ searchResults.removeChild(searchResults.firstChild);
1425
+ }
1426
+ }
1427
+
1428
+ input.addEventListener('focus', updateSearchResultsPosition);
1429
+ input.addEventListener('input', updateSearchResultsPosition);
1430
+ window.addEventListener('resize', updateSearchResultsPosition);
1431
+ window.addEventListener('scroll', updateSearchResultsPosition, true);
1432
+
1433
+ input.addEventListener('input', function() {
1434
+ const q = String(input.value || '').toLowerCase();
1435
+ const results = [];
1436
+ Object.entries(window.xtendDocsTitles || {}).forEach(([slug, title]) => {
1437
+ if (String(title).toLowerCase().includes(q)) {
1438
+ results.push({ slug, title });
1439
+ }
1440
+ });
1441
+
1442
+ clearResults();
1443
+ if (q && results.length) {
1444
+ results.forEach((result, index) => {
1445
+ const link = document.createElement('x-link');
1446
+ link.setAttribute('href', '/' + result.slug);
1447
+ link.textContent = result.title;
1448
+ searchResults.appendChild(link);
1449
+ });
1450
+ searchResults.style.display = 'block';
1451
+ } else if (q) {
1452
+ const empty = document.createElement('em');
1453
+ empty.textContent = 'Keine Treffer';
1454
+ searchResults.appendChild(empty);
1455
+ searchResults.style.display = 'block';
1456
+ } else {
1457
+ searchResults.style.display = 'none';
1458
+ }
1459
+ });
1460
+
1461
+ document.addEventListener('click', function(e) {
1462
+ if (!form.contains(e.target)) {
1463
+ searchResults.style.display = 'none';
1464
+ }
1465
+ });
1466
+
1467
+ searchResults.addEventListener('click', function(e) {
1468
+ const t = e.target;
1469
+ if (t.tagName === 'X-LINK') {
1470
+ const header = document.querySelector('x-header');
1471
+ if (header && header.id && window.xstate) {
1472
+ window.xstate.set(`xheader-state-${header.id}`, { menuOpen: false });
1473
+ }
1474
+ searchResults.style.display = 'none';
1475
+ }
1476
+ });
1477
+
1478
+ function applySearchTheme() {
1479
+ searchResults.style.background = getComputedStyle(document.documentElement).getPropertyValue('--section-bg').trim() || '#fff';
1480
+ searchResults.style.color = getComputedStyle(document.documentElement).getPropertyValue('--text-color').trim() || '#222';
1481
+ searchResults.style.borderColor = getComputedStyle(document.documentElement).getPropertyValue('--border-color').trim() || 'rgba(0,0,0,0.14)';
1482
+ }
1483
+
1484
+ document.addEventListener('theme-changed', applySearchTheme);
1485
+ applySearchTheme();
1486
+ }
1487
+
1488
+ function ensureRmtSearchShell() {
1489
+ const header = document.querySelector('x-header');
1490
+ if (!header) return;
1491
+ let form = document.getElementById('xtend-search-form');
1492
+
1493
+ if (!form) {
1494
+ const templateId = (window.xtendDocsRmtPilot && window.xtendDocsRmtPilot.searchTemplate) || DOCS_RMT_DEFAULT_SEARCH_TEMPLATE;
1495
+ const rendered = renderRmtDomTemplate(templateId, {
1496
+ searchSchedule: 'docs.search.index'
1497
+ });
1498
+ if (rendered.rendered) {
1499
+ form = rendered.fragment.querySelector('#xtend-search-form, [data-rmt-component="docs.search"]');
1500
+ if (form) form.setAttribute('slot', 'search');
1501
+ header.appendChild(form || rendered.fragment);
1502
+ form = document.getElementById('xtend-search-form');
1503
+ }
1504
+ if (!form) {
1505
+ form = createFallbackSearchShell();
1506
+ header.appendChild(form);
1507
+ }
1508
+ }
1509
+
1510
+ const input = form.querySelector('#search-input, x-input[name="search"]');
1511
+ const searchResults = form.querySelector('#search-results, [data-rmt-slot="results"]');
1512
+ if (input && searchResults) {
1513
+ styleSearchShell(form, input, searchResults);
1514
+ wireSearchForm(form, input, searchResults);
1515
+ }
1516
+ }
1517
+
1518
+ function applyMainBackground() {
1519
+ const main = document.querySelector('main');
1520
+ if (main) {
1521
+ main.style.background = 'transparent';
1522
+ }
1523
+ }
1524
+
1525
+ function ensureMainBackgroundBinding() {
1526
+ if (window.__xtendDocsMainBackgroundBound) return;
1527
+ window.__xtendDocsMainBackgroundBound = true;
1528
+ document.addEventListener('theme-changed', applyMainBackground);
1529
+ applyMainBackground();
1530
+ }
1531
+
1532
+ function getDocsPageSlugs() {
1533
+ const metaSlugs = Object.keys(window.xtendDocsPagesMeta || {});
1534
+ if (metaSlugs.length) return metaSlugs;
1535
+ return Object.keys(window.xtendDocsPages || {});
1536
+ }
1537
+
1538
+ function getDocsPageEndpoint() {
1539
+ const endpoint = window.xtendDocsPageEndpoint || '';
1540
+ return typeof endpoint === 'string' && endpoint ? endpoint : '';
1541
+ }
1542
+
1543
+ function buildDocsPagePayloadUrl(slug) {
1544
+ const endpoint = getDocsPageEndpoint();
1545
+ if (!endpoint) return '';
1546
+ if (endpoint.includes('{slug}')) return endpoint.replace('{slug}', encodeURIComponent(slug));
1547
+ return endpoint + encodeURIComponent(slug);
1548
+ }
1549
+
1550
+ function rememberDocsPagePayload(slug, payload = {}) {
1551
+ if (!window.xtendDocsPages || typeof window.xtendDocsPages !== 'object') {
1552
+ window.xtendDocsPages = {};
1553
+ }
1554
+ if (typeof payload.html === 'string') {
1555
+ window.xtendDocsPages[slug] = payload.html;
1556
+ }
1557
+ if (payload.meta && typeof payload.meta === 'object') {
1558
+ window.xtendDocsPagesMeta = {
1559
+ ...(window.xtendDocsPagesMeta || {}),
1560
+ [slug]: {
1561
+ ...(window.xtendDocsPagesMeta && window.xtendDocsPagesMeta[slug] || {}),
1562
+ ...payload.meta
1563
+ }
1564
+ };
1565
+ }
1566
+ return payload;
1567
+ }
1568
+
1569
+ function loadDocsParsedownContent(slug, rmtMeta = {}) {
1570
+ const inlineHtml = window.xtendDocsPages && typeof window.xtendDocsPages[slug] === 'string'
1571
+ ? window.xtendDocsPages[slug]
1572
+ : null;
1573
+ if (inlineHtml !== null) {
1574
+ return Promise.resolve({
1575
+ schema: 'xtend.docs.parsedown-rmt-page-payload.v1',
1576
+ ok: true,
1577
+ slug,
1578
+ html: inlineHtml,
1579
+ meta: rmtMeta,
1580
+ source: 'inline',
1581
+ cacheHit: true,
1582
+ skeletonLoader: 'xtend.loader.skeleton-loader.v1'
1583
+ });
1584
+ }
1585
+
1586
+ if (DOCS_ROUTE_PAYLOAD_PROMISES.has(slug)) {
1587
+ return DOCS_ROUTE_PAYLOAD_PROMISES.get(slug);
1588
+ }
1589
+
1590
+ const url = buildDocsPagePayloadUrl(slug);
1591
+ if (!url) {
1592
+ return Promise.resolve({
1593
+ schema: 'xtend.docs.parsedown-rmt-page-payload.v1',
1594
+ ok: false,
1595
+ slug,
1596
+ html: '<em>Seite nicht gefunden</em>',
1597
+ meta: rmtMeta,
1598
+ source: 'missing-endpoint',
1599
+ cacheHit: false,
1600
+ skeletonLoader: 'xtend.loader.skeleton-loader.v1'
1601
+ });
1602
+ }
1603
+
1604
+ const promise = fetch(url, {
1605
+ cache: 'no-store',
1606
+ headers: {
1607
+ Accept: 'application/json'
1608
+ }
1609
+ })
1610
+ .then((response) => {
1611
+ if (!response.ok) throw new Error(`Docs page payload failed with HTTP ${response.status}`);
1612
+ return response.json();
1613
+ })
1614
+ .then((payload) => rememberDocsPagePayload(slug, {
1615
+ ...payload,
1616
+ cacheHit: false
1617
+ }))
1618
+ .catch((error) => ({
1619
+ schema: 'xtend.docs.parsedown-rmt-page-payload.v1',
1620
+ ok: false,
1621
+ slug,
1622
+ html: '<em>Seite nicht gefunden</em>',
1623
+ meta: rmtMeta,
1624
+ source: 'fetch-error',
1625
+ cacheHit: false,
1626
+ error: error && error.message ? error.message : String(error),
1627
+ skeletonLoader: 'xtend.loader.skeleton-loader.v1'
1628
+ }))
1629
+ .finally(() => {
1630
+ DOCS_ROUTE_PAYLOAD_PROMISES.delete(slug);
1631
+ });
1632
+ DOCS_ROUTE_PAYLOAD_PROMISES.set(slug, promise);
1633
+ return promise;
1634
+ }
1635
+
1636
+ function normalizeMarkdownLinks(html) {
1637
+ return String(html || '').replace(/<a href=["']([^"'#?]+)["']>(.*?)<\/a>/g, function(match, href, text) {
1638
+ if (!href.endsWith('.md')) return match;
1639
+ let norm = href.replace(/^\.\//, '').replace(/^\.\./, '').replace(/^\./, '').replace(/\\/g, '/');
1640
+ let foundSlug = null;
1641
+
1642
+ for (const s of getDocsPageSlugs()) {
1643
+ let candidate = '';
1644
+ if (norm.startsWith('components/')) {
1645
+ candidate = 'components-' + norm.slice('components/'.length).replace(/\//g, '-').replace(/\.md$/, '').toLowerCase();
1646
+ } else {
1647
+ candidate = norm.replace(/\//g, '-').replace(/\.md$/, '').toLowerCase();
1648
+ }
1649
+ if (s === candidate) {
1650
+ foundSlug = s;
1651
+ break;
1652
+ }
1653
+ }
1654
+
1655
+ if (!foundSlug) {
1656
+ const base = norm.split('/').pop().replace(/\.md$/, '').toLowerCase();
1657
+ for (const s of getDocsPageSlugs()) {
1658
+ if (s.endsWith('-' + base) || s === base) {
1659
+ foundSlug = s;
1660
+ break;
1661
+ }
1662
+ }
1663
+ }
1664
+
1665
+ if (!foundSlug) {
1666
+ if (norm.startsWith('components/')) {
1667
+ foundSlug = 'components-' + norm.slice('components/'.length).replace(/\//g, '-').replace(/\.md$/, '').toLowerCase();
1668
+ } else {
1669
+ foundSlug = norm.replace(/\//g, '-').replace(/\.md$/, '').toLowerCase();
1670
+ }
1671
+ }
1672
+ return `<x-link href='/${foundSlug}'>${text}</x-link>`;
1673
+ });
1674
+ }
1675
+
1676
+ function isDocsTrustedDomUrlAllowed(value) {
1677
+ const normalized = String(value || '').trim().replace(/[\u0000-\u001F\u007F\s]+/g, '').toLowerCase();
1678
+ if (!normalized) return true;
1679
+ if (normalized.startsWith('#') || normalized.startsWith('/') || normalized.startsWith('./') || normalized.startsWith('../')) return true;
1680
+ if (normalized.startsWith('data:')) return normalized.startsWith('data:image/');
1681
+ return !(
1682
+ normalized.startsWith('javascript:')
1683
+ || normalized.startsWith('vbscript:')
1684
+ || normalized.startsWith('data:text/html')
1685
+ || normalized.startsWith('data:text/javascript')
1686
+ );
1687
+ }
1688
+
1689
+ function decodeDocsParsedownCodeEntities(value) {
1690
+ const text = String(value || '');
1691
+ if (!/&(?:amp|lt|gt|quot|#0?39|#x0?27);/i.test(text)) return text;
1692
+ const decoder = document.createElement('textarea');
1693
+ decoder.innerHTML = text;
1694
+ return decoder.value;
1695
+ }
1696
+
1697
+ function normalizeDocsParsedownCodeEntities(root) {
1698
+ let normalizedCount = 0;
1699
+ Array.from(root.querySelectorAll('code')).forEach((node) => {
1700
+ const original = node.textContent || '';
1701
+ const decoded = decodeDocsParsedownCodeEntities(original);
1702
+ if (decoded === original) return;
1703
+ node.textContent = decoded;
1704
+ node.setAttribute('data-parsedown-code-normalized', 'true');
1705
+ normalizedCount += 1;
1706
+ });
1707
+ return normalizedCount;
1708
+ }
1709
+
1710
+ function sanitizeDocsTrustedDomHtml(html, options = {}) {
1711
+ const template = document.createElement('template');
1712
+ const removed = [];
1713
+ template.innerHTML = String(html || '');
1714
+
1715
+ DOCS_TRUSTED_DOM_FORBIDDEN_TAGS.forEach((tagName) => {
1716
+ Array.from(template.content.querySelectorAll(tagName)).forEach((node) => {
1717
+ removed.push({ type: 'element', name: tagName });
1718
+ node.remove();
1719
+ });
1720
+ });
1721
+
1722
+ Array.from(template.content.querySelectorAll('*')).forEach((node) => {
1723
+ Array.from(node.attributes).forEach((attribute) => {
1724
+ const name = attribute.name;
1725
+ const lowerName = name.toLowerCase();
1726
+ if (lowerName.startsWith('on') || lowerName === 'srcdoc') {
1727
+ removed.push({ type: 'attribute', name });
1728
+ node.removeAttribute(name);
1729
+ return;
1730
+ }
1731
+
1732
+ if (DOCS_TRUSTED_DOM_URL_ATTRIBUTES.includes(lowerName) && !isDocsTrustedDomUrlAllowed(attribute.value)) {
1733
+ removed.push({ type: 'url', name, value: attribute.value });
1734
+ node.removeAttribute(name);
1735
+ }
1736
+ });
1737
+ });
1738
+
1739
+ const normalizedCodeEntityCount = normalizeDocsParsedownCodeEntities(template.content);
1740
+
1741
+ return {
1742
+ schema: DOCS_RMT_TRUSTED_DOM_PROOF_SCHEMA,
1743
+ sanitizer: DOCS_RMT_TRUSTED_DOM_SANITIZER,
1744
+ sanitized: true,
1745
+ boundary: options.trustBoundary || DOCS_RMT_TRUST_BOUNDARY,
1746
+ markupClass: options.markupClass || 'parsedownHtml',
1747
+ html: template.innerHTML,
1748
+ removed,
1749
+ removedCount: removed.length,
1750
+ normalizedCodeEntityCount,
1751
+ source: options.source || 'docs.parsedown'
1752
+ };
1753
+ }
1754
+
1755
+ function prepareDocsTrustedDomHtml(slug, html, options = {}) {
1756
+ const cacheKey = createDocsRouteContentCacheKey(slug, html, options);
1757
+ const cached = DOCS_ROUTE_CONTENT_CACHE.get(cacheKey);
1758
+ if (cached) return cloneDocsSanitizeResult(cached, true);
1759
+
1760
+ const normalizedHtml = normalizeMarkdownLinks(html);
1761
+ const result = sanitizeDocsTrustedDomHtml(normalizedHtml, options);
1762
+ result.cacheKey = cacheKey;
1763
+ result.cacheHit = false;
1764
+ rememberDocsCacheEntry(cacheKey, result);
1765
+ return cloneDocsSanitizeResult(result, false);
1766
+ }
1767
+
1768
+ function applyDocsTrustedDomHtml(target, html, options = {}) {
1769
+ const result = prepareDocsTrustedDomHtml(options.slug || '', html, options);
1770
+ target.innerHTML = result.html;
1771
+ target.setAttribute('data-rmt-sanitized', 'true');
1772
+ target.setAttribute('data-rmt-sanitizer', DOCS_RMT_TRUSTED_DOM_SANITIZER);
1773
+ target.setAttribute('data-rmt-trusted-dom-proof', DOCS_RMT_TRUSTED_DOM_PROOF_SCHEMA);
1774
+ target.setAttribute('data-rmt-content-cache-hit', result.cacheHit ? 'true' : 'false');
1775
+ window.xtendDocsTrustedDomLastSanitize = result;
1776
+ return result;
1777
+ }
1778
+
1779
+ window.xtendDocsTrustedDomBoundary = Object.freeze({
1780
+ schema: DOCS_RMT_TRUSTED_DOM_PROOF_SCHEMA,
1781
+ sanitizer: DOCS_RMT_TRUSTED_DOM_SANITIZER,
1782
+ trustBoundary: DOCS_RMT_TRUST_BOUNDARY,
1783
+ sanitize: sanitizeDocsTrustedDomHtml,
1784
+ apply: applyDocsTrustedDomHtml
1785
+ });
1786
+
1787
+ function upgradeRoutedLinks(root) {
1788
+ Array.from(root.querySelectorAll('x-link')).forEach((node) => {
1789
+ if (!(node instanceof HTMLElement)) return;
1790
+ const href = node.getAttribute('href');
1791
+ const text = node.textContent;
1792
+ const real = document.createElement('x-link');
1793
+ if (href) real.setAttribute('href', href);
1794
+ real.textContent = text;
1795
+ node.replaceWith(real);
1796
+ });
1797
+ }
1798
+
1799
+ function syncActiveHeaderLink(slug) {
1800
+ const header = document.querySelector('x-header');
1801
+ if (!header) return;
1802
+ header.querySelectorAll('x-link').forEach((a) => a.removeAttribute('active'));
1803
+ header.querySelectorAll('details[data-docs-menu-children]').forEach((details) => {
1804
+ details.open = false;
1805
+ syncDocsMenuDisclosureState(details);
1806
+ });
1807
+ const active = header.querySelector('x-link[href="#/' + slug + '"], x-link[href="/' + slug + '"]');
1808
+ if (active) {
1809
+ active.setAttribute('active', '');
1810
+ let parent = active.parentElement;
1811
+ while (parent) {
1812
+ if (parent.tagName && parent.tagName.toLowerCase() === 'details') {
1813
+ parent.open = true;
1814
+ syncDocsMenuDisclosureState(parent);
1815
+ }
1816
+ parent = parent.parentElement;
1817
+ }
1818
+ }
1819
+ }
1820
+
1821
+ function syncDocsMenuDisclosureState(details) {
1822
+ if (!details || !details.querySelector) return;
1823
+ const summary = details.querySelector(':scope > summary');
1824
+ if (summary) {
1825
+ summary.setAttribute('aria-expanded', details.open ? 'true' : 'false');
1826
+ }
1827
+ }
1828
+
1829
+ function closeDocsMenuDetailsTree(details) {
1830
+ if (!details || !details.querySelectorAll) return;
1831
+ details.open = false;
1832
+ syncDocsMenuDisclosureState(details);
1833
+ details.querySelectorAll('details[data-docs-menu-children]').forEach((child) => {
1834
+ child.open = false;
1835
+ syncDocsMenuDisclosureState(child);
1836
+ });
1837
+ }
1838
+
1839
+ function closeSiblingDocsSubmenus(details) {
1840
+ const node = details && details.parentElement;
1841
+ const container = node && node.parentElement;
1842
+ if (!container) return;
1843
+ Array.from(container.children).forEach((siblingNode) => {
1844
+ if (siblingNode === node || !siblingNode.querySelector) return;
1845
+ const siblingDetails = siblingNode.querySelector(':scope > details[data-docs-menu-children]');
1846
+ if (siblingDetails) {
1847
+ closeDocsMenuDetailsTree(siblingDetails);
1848
+ }
1849
+ });
1850
+ }
1851
+
1852
+ async function loadMenuConfig() {
1853
+ try {
1854
+ const resp = await fetch('/docs/menu.json', { cache: 'no-store' });
1855
+ if (resp.ok) {
1856
+ const json = await resp.json();
1857
+ if (Array.isArray(json)) {
1858
+ window.xtendMenuConfig = json;
1859
+ }
1860
+ }
1861
+ } catch (e) {
1862
+ // Fallback auf Default-Menue.
1863
+ }
1864
+ }
1865
+
1866
+ function getCurrentDocsSlug() {
1867
+ const slug = location.hash.replace(/^#\/?/, '').replace(/^\/+/, '') || 'readme';
1868
+ return slug === '' || slug === '/' ? 'readme' : slug;
1869
+ }
1870
+
1871
+ function resolveDocsMenuGroup(entry) {
1872
+ const slug = entry && entry.slug ? String(entry.slug) : '';
1873
+ if (entry && entry.group) return String(entry.group);
1874
+ if (slug === 'readme' || slug === 'about' || slug === 'best-practices' || slug === 'enterprise-adoption') return 'start';
1875
+ if (slug.startsWith('components')) return 'components';
1876
+ if (slug.startsWith('xtendrmt') || slug.startsWith('rmt-') || slug.includes('rmt-production') || slug.includes('parsedown')) return 'rmt';
1877
+ if (slug.includes('performance') || slug.includes('hydration') || slug.includes('a11y') || slug.includes('screenreader') || slug.includes('motion-contrast')) return 'quality';
1878
+ if (slug.includes('trusted-dom') || slug.includes('supply-chain') || slug.includes('manifest-import') || slug.includes('csp') || slug.includes('network')) return 'security';
1879
+ if (slug.startsWith('rc') || slug.startsWith('epic') || slug.includes('release') || slug.includes('package-export') || slug.includes('known-residual') || slug.includes('visual-owner')) return 'release';
1880
+ if (slug.includes('component-') || slug.includes('typescript') || slug.includes('catalog') || slug.includes('design-token') || slug.includes('visual')) return 'platform';
1881
+ return 'core';
1882
+ }
1883
+
1884
+ function getDocsMenuGroupLabel(groupId) {
1885
+ const labels = {
1886
+ start: 'Start',
1887
+ core: 'Core',
1888
+ platform: 'Platform',
1889
+ components: 'Komponenten',
1890
+ rmt: 'XTendRMT',
1891
+ quality: 'Quality',
1892
+ security: 'Security',
1893
+ release: 'Release'
1894
+ };
1895
+ return labels[groupId] || groupId;
1896
+ }
1897
+
1898
+ function getDocsMenuGroupIcon(groupId) {
1899
+ const icons = {
1900
+ start: 'home',
1901
+ core: 'package',
1902
+ platform: 'layers',
1903
+ components: 'boxes',
1904
+ rmt: 'route',
1905
+ quality: 'gauge',
1906
+ security: 'shield-check',
1907
+ release: 'rocket'
1908
+ };
1909
+ return icons[groupId] || 'docs';
1910
+ }
1911
+
1912
+ function getDocsMenuEntryIcon(entry) {
1913
+ const slug = entry && entry.slug ? String(entry.slug) : '';
1914
+ const explicitIcon = entry && (entry.icon || entry.iconName);
1915
+ if (explicitIcon) return String(explicitIcon);
1916
+
1917
+ const exact = {
1918
+ readme: 'home',
1919
+ 'quick-start-guide': 'book-open',
1920
+ about: 'info',
1921
+ 'best-practices': 'success',
1922
+ manifest: 'file',
1923
+ api: 'terminal',
1924
+ 'xtend-loader': 'download',
1925
+ 'xtend-fabric': 'zap',
1926
+ components: 'component',
1927
+ 'component-platform': 'layers',
1928
+ 'component-catalog-coverage': 'boxes',
1929
+ 'design-tokens': 'palette',
1930
+ 'xtendrmt-overview': 'route',
1931
+ 'rmt-linter': 'terminal',
1932
+ 'rmt-language-server': 'server',
1933
+ performance: 'gauge',
1934
+ 'hydration-policies': 'zap',
1935
+ 'a11y-keyboard-smokes': 'accessibility',
1936
+ 'trusted-dom-sanitizing': 'shield-check',
1937
+ 'supply-chain-gates': 'shield-check',
1938
+ 'rc0-gate-matrix': 'package',
1939
+ 'rc1-readiness': 'rocket',
1940
+ 'enterprise-adoption': 'layers'
1941
+ };
1942
+ if (exact[slug]) return exact[slug];
1943
+ if (slug.startsWith('components-xcode')) return 'code';
1944
+ if (slug.startsWith('components-xicon') || slug.startsWith('components-xtheme')) return 'palette';
1945
+ if (slug.startsWith('components-xstate')) return 'database';
1946
+ if (slug.startsWith('components-xrouter') || slug.startsWith('xtendrmt') || slug.startsWith('rmt-')) return 'route';
1947
+ if (slug.startsWith('components-')) return 'component';
1948
+ if (slug.includes('security') || slug.includes('trusted-dom') || slug.includes('supply-chain') || slug.includes('csp') || slug.includes('network')) return 'shield-check';
1949
+ if (slug.includes('performance') || slug.includes('hydration')) return 'gauge';
1950
+ if (slug.includes('a11y') || slug.includes('screenreader') || slug.includes('motion-contrast')) return 'accessibility';
1951
+ if (slug.includes('release') || slug.startsWith('rc') || slug.startsWith('epic')) return 'rocket';
1952
+ if (slug.includes('component') || slug.includes('surface') || slug.includes('visual')) return 'layers';
1953
+ return 'docs';
1954
+ }
1955
+
1956
+ function getDocsMenuEntryId(entry) {
1957
+ const slug = entry && entry.slug ? String(entry.slug) : '';
1958
+ if (entry && entry.id) return String(entry.id);
1959
+ if (slug.startsWith('components-')) {
1960
+ return `docs.components.${slug.slice('components-'.length).replace(/-/g, '.')}`;
1961
+ }
1962
+ return `docs.${slug.replace(/-/g, '.')}`;
1963
+ }
1964
+
1965
+ function computeDocsMenuRank(entry) {
1966
+ const explicit = Number(entry && (entry.rank || entry.score || entry.pageRank));
1967
+ if (Number.isFinite(explicit)) return explicit;
1968
+ const slug = entry && entry.slug ? String(entry.slug) : '';
1969
+ const group = resolveDocsMenuGroup(entry);
1970
+ if (slug === 'readme') return 100;
1971
+ if (['manifest', 'api', 'xtend-loader', 'components', 'xtendrmt-overview'].includes(slug)) return 94;
1972
+ if (['enterprise-adoption', 'best-practices', 'component-platform', 'performance', 'trusted-dom-sanitizing'].includes(slug)) return 88;
1973
+ if (slug.startsWith('components-')) return 58;
1974
+ if (entry && entry.parent) return 66;
1975
+ return { start: 82, core: 78, platform: 74, components: 72, rmt: 76, quality: 72, security: 72, release: 64 }[group] || 60;
1976
+ }
1977
+
1978
+ function getDocsMenuTier(entry) {
1979
+ if (entry && entry.tier) return String(entry.tier);
1980
+ if (entry && entry.parent) return 'deep-dive';
1981
+ return 'basic';
1982
+ }
1983
+
1984
+ function normalizeDocsMenuEntry(entry) {
1985
+ const slug = entry && entry.slug ? String(entry.slug) : '';
1986
+ const label = entry && entry.label
1987
+ ? String(entry.label)
1988
+ : slug.replace(/^components-/, '').replace(/-/g, ' ');
1989
+ const parent = entry && entry.parent ? String(entry.parent) : '';
1990
+ return {
1991
+ ...entry,
1992
+ slug,
1993
+ id: getDocsMenuEntryId(entry),
1994
+ label: label.charAt(0).toUpperCase() + label.slice(1),
1995
+ group: resolveDocsMenuGroup(entry),
1996
+ parent,
1997
+ rank: computeDocsMenuRank(entry),
1998
+ tier: getDocsMenuTier(entry),
1999
+ children: []
2000
+ };
2001
+ }
2002
+
2003
+ function sortDocsMenuEntries(entries = []) {
2004
+ return entries.sort((a, b) => {
2005
+ if (b.rank !== a.rank) return b.rank - a.rank;
2006
+ return String(a.label).localeCompare(String(b.label), 'de');
2007
+ });
2008
+ }
2009
+
2010
+ function groupDocsMenuEntries(entries = []) {
2011
+ const order = ['start', 'core', 'platform', 'components', 'rmt', 'quality', 'security', 'release'];
2012
+ const groups = new Map(order.map((id) => [id, { id, label: getDocsMenuGroupLabel(id), entries: [] }]));
2013
+ const normalizedEntries = entries
2014
+ .filter((entry) => entry && entry.slug)
2015
+ .map(normalizeDocsMenuEntry);
2016
+ const bySlug = new Map(normalizedEntries.map((entry) => [entry.slug, entry]));
2017
+ const byId = new Map(normalizedEntries.map((entry) => [entry.id, entry]));
2018
+ const roots = [];
2019
+
2020
+ normalizedEntries.forEach((entry) => {
2021
+ const parent = entry.parent ? (bySlug.get(entry.parent) || byId.get(entry.parent)) : null;
2022
+ if (parent) {
2023
+ parent.children.push(entry);
2024
+ } else {
2025
+ roots.push(entry);
2026
+ }
2027
+ });
2028
+
2029
+ const sortTree = (entry) => {
2030
+ entry.children = sortDocsMenuEntries(entry.children);
2031
+ entry.children.forEach(sortTree);
2032
+ };
2033
+ roots.forEach(sortTree);
2034
+
2035
+ sortDocsMenuEntries(roots).forEach((entry) => {
2036
+ const groupId = entry.group;
2037
+ if (!groups.has(groupId)) {
2038
+ groups.set(groupId, { id: groupId, label: getDocsMenuGroupLabel(groupId), entries: [] });
2039
+ }
2040
+ groups.get(groupId).entries.push(entry);
2041
+ });
2042
+
2043
+ return Array.from(groups.values()).filter((group) => group.entries.length > 0);
2044
+ }
2045
+
2046
+ function renderMenu() {
2047
+ const header = document.querySelector('x-header');
2048
+ if (!header) return;
2049
+ Array.from(header.querySelectorAll('x-link[slot="nav"]')).forEach((el) => el.remove());
2050
+ Array.from(header.querySelectorAll('[data-docs-menu-shell]')).forEach((el) => el.remove());
2051
+ const menu = window.xtendMenuConfig && window.xtendMenuConfig.length
2052
+ ? window.xtendMenuConfig
2053
+ : Object.keys(window.xtendDocsTitles || {}).map((slug) => ({ slug, label: window.xtendDocsTitles[slug] }));
2054
+
2055
+ const shell = document.createElement('div');
2056
+ shell.setAttribute('slot', 'nav');
2057
+ shell.setAttribute('data-menu-shell', '');
2058
+ shell.setAttribute('data-docs-menu-shell', '');
2059
+ shell.className = 'docs-menu-shell';
2060
+ shell.setAttribute('role', 'list');
2061
+ shell.setAttribute('aria-label', 'Dokumentationsbereiche');
2062
+
2063
+ const renderMenuNode = (entry, depth = 0) => {
2064
+ const node = document.createElement('div');
2065
+ node.className = 'docs-menu-node';
2066
+ node.setAttribute('data-doc-id', entry.id);
2067
+ node.setAttribute('data-doc-rank', String(entry.rank));
2068
+ node.setAttribute('data-doc-tier', entry.tier);
2069
+ node.setAttribute('data-doc-depth', String(depth));
2070
+
2071
+ const link = document.createElement('x-link');
2072
+ link.className = 'docs-menu-link';
2073
+ link.setAttribute('href', '/' + entry.slug);
2074
+ link.setAttribute('data-docs-menu-link', '');
2075
+ link.setAttribute('data-doc-id', entry.id);
2076
+ link.setAttribute('data-doc-rank', String(entry.rank));
2077
+ link.setAttribute('data-doc-tier', entry.tier);
2078
+ const icon = document.createElement('x-icon');
2079
+ icon.className = 'docs-menu-link-icon';
2080
+ icon.setAttribute('name', getDocsMenuEntryIcon(entry));
2081
+ icon.setAttribute('decorative', '');
2082
+ icon.setAttribute('size', depth === 0 ? '1rem' : '0.92rem');
2083
+ const label = document.createElement('span');
2084
+ label.className = 'docs-menu-link-label';
2085
+ label.textContent = entry.label;
2086
+ link.appendChild(icon);
2087
+ link.appendChild(label);
2088
+ node.appendChild(link);
2089
+
2090
+ if (entry.children && entry.children.length) {
2091
+ const details = document.createElement('details');
2092
+ details.className = 'docs-menu-children';
2093
+ details.setAttribute('data-docs-menu-children', '');
2094
+ details.setAttribute('data-doc-parent', entry.id);
2095
+ details.setAttribute('data-doc-depth', String(depth + 1));
2096
+
2097
+ const summary = document.createElement('summary');
2098
+ summary.className = 'docs-menu-disclosure';
2099
+ summary.setAttribute('aria-expanded', 'false');
2100
+ const summaryIcon = document.createElement('x-icon');
2101
+ summaryIcon.className = 'docs-menu-disclosure-icon';
2102
+ summaryIcon.setAttribute('name', 'chevron-right');
2103
+ summaryIcon.setAttribute('decorative', '');
2104
+ summaryIcon.setAttribute('size', '0.9rem');
2105
+ const summaryLabel = document.createElement('span');
2106
+ summaryLabel.className = 'docs-menu-disclosure-label';
2107
+ summaryLabel.textContent = depth === 0 ? 'Deep Dives' : 'Weitere Themen';
2108
+ const summaryCount = document.createElement('span');
2109
+ summaryCount.className = 'docs-menu-disclosure-count';
2110
+ summaryCount.textContent = String(entry.children.length);
2111
+ summary.appendChild(summaryIcon);
2112
+ summary.appendChild(summaryLabel);
2113
+ summary.appendChild(summaryCount);
2114
+
2115
+ const childList = document.createElement('div');
2116
+ childList.className = 'docs-menu-child-list';
2117
+ entry.children.forEach((child) => {
2118
+ childList.appendChild(renderMenuNode(child, depth + 1));
2119
+ });
2120
+
2121
+ details.appendChild(summary);
2122
+ details.appendChild(childList);
2123
+ details.addEventListener('toggle', () => {
2124
+ syncDocsMenuDisclosureState(details);
2125
+ if (details.open) {
2126
+ closeSiblingDocsSubmenus(details);
2127
+ }
2128
+ });
2129
+ node.appendChild(details);
2130
+ }
2131
+
2132
+ return node;
2133
+ };
2134
+
2135
+ groupDocsMenuEntries(menu).forEach((group) => {
2136
+ const section = document.createElement('section');
2137
+ section.className = 'docs-menu-section';
2138
+ section.setAttribute('role', 'listitem');
2139
+ section.setAttribute('aria-labelledby', `docs-menu-${group.id}`);
2140
+
2141
+ const title = document.createElement('h3');
2142
+ title.id = `docs-menu-${group.id}`;
2143
+ title.className = 'docs-menu-section-title';
2144
+ const icon = document.createElement('x-icon');
2145
+ icon.setAttribute('name', getDocsMenuGroupIcon(group.id));
2146
+ icon.setAttribute('decorative', '');
2147
+ icon.setAttribute('size', '1rem');
2148
+ const titleText = document.createElement('span');
2149
+ titleText.textContent = group.label;
2150
+ title.appendChild(icon);
2151
+ title.appendChild(titleText);
2152
+
2153
+ const links = document.createElement('div');
2154
+ links.className = 'docs-menu-section-links';
2155
+
2156
+ group.entries.forEach((entry) => {
2157
+ links.appendChild(renderMenuNode(entry));
2158
+ });
2159
+
2160
+ section.appendChild(title);
2161
+ section.appendChild(links);
2162
+ shell.appendChild(section);
2163
+ });
2164
+
2165
+ header.appendChild(shell);
2166
+ syncActiveHeaderLink(getCurrentDocsSlug());
2167
+ }
2168
+
2169
+ function ensureMenuBinding() {
2170
+ if (window.__xtendDocsMenuBound) {
2171
+ syncActiveHeaderLink(getCurrentDocsSlug());
2172
+ return;
2173
+ }
2174
+ window.__xtendDocsMenuBound = true;
2175
+ loadMenuConfig().then(renderMenu);
2176
+ window.addEventListener('hashchange', () => syncActiveHeaderLink(getCurrentDocsSlug()));
2177
+ }
2178
+
2179
+ function docsPageExists(slug) {
2180
+ return Boolean(slug && (
2181
+ window.xtendDocsPages && window.xtendDocsPages[slug] ||
2182
+ window.xtendDocsPagesMeta && window.xtendDocsPagesMeta[slug]
2183
+ ));
2184
+ }
2185
+
2186
+ function docsTitleForSlug(slug) {
2187
+ return (window.xtendDocsTitles && window.xtendDocsTitles[slug]) ||
2188
+ (slug ? slug.replace(/^components-/, '').replace(/-/g, ' ') : '');
2189
+ }
2190
+
2191
+ function normalizeDocsSlugFromHref(href) {
2192
+ if (!href) return '';
2193
+ let value = String(href).trim();
2194
+ if (!value || value.startsWith('#') || /^[a-z][a-z0-9+.-]*:/i.test(value)) return '';
2195
+ value = value.split('#')[0].split('?')[0];
2196
+ value = value.replace(/^#\/?/, '').replace(/^\/+/, '').replace(/^\.\//, '');
2197
+ while (value.startsWith('../')) value = value.slice(3);
2198
+ if (value.startsWith('docs/')) value = value.slice('docs/'.length);
2199
+ if (value.startsWith('components/')) {
2200
+ value = 'components-' + value.slice('components/'.length);
2201
+ }
2202
+ value = value.replace(/\.md$/i, '').replace(/\//g, '-').toLowerCase();
2203
+ if (docsPageExists(value)) return value;
2204
+ const base = value.split('-').pop();
2205
+ const match = getDocsPageSlugs().find((slug) => slug === value || slug.endsWith('-' + base));
2206
+ return match || value;
2207
+ }
2208
+
2209
+ function collectRelatedLinksFromNode(node) {
2210
+ const links = [];
2211
+ Array.from(node.querySelectorAll('x-link, a')).forEach((link) => {
2212
+ const href = link.getAttribute('href') || '';
2213
+ const slug = normalizeDocsSlugFromHref(href);
2214
+ const label = (link.textContent || (slug ? docsTitleForSlug(slug) : href)).trim();
2215
+ if (slug && docsPageExists(slug)) {
2216
+ links.push({
2217
+ slug,
2218
+ href: '/' + slug,
2219
+ label: label || docsTitleForSlug(slug),
2220
+ source: 'parsedown'
2221
+ });
2222
+ return;
2223
+ }
2224
+ if (href && isDocsTrustedDomUrlAllowed(href)) {
2225
+ links.push({
2226
+ href,
2227
+ label: label || href,
2228
+ source: 'parsedown'
2229
+ });
2230
+ }
2231
+ });
2232
+ return links;
2233
+ }
2234
+
2235
+ function isRelatedText(value) {
2236
+ return /(siehe auch|weiterfuehr|weiterführ|verwandte|read further|related|see also)/i.test(String(value || ''));
2237
+ }
2238
+
2239
+ function headingLevel(node) {
2240
+ return /^H[1-6]$/i.test(node.tagName || '') ? Number(node.tagName.slice(1)) : 0;
2241
+ }
2242
+
2243
+ function extractDocsRelatedLinks(contentRoot) {
2244
+ if (!contentRoot) return [];
2245
+ const links = [];
2246
+
2247
+ Array.from(contentRoot.querySelectorAll('blockquote')).forEach((node) => {
2248
+ if (!isRelatedText(node.textContent)) return;
2249
+ links.push(...collectRelatedLinksFromNode(node));
2250
+ node.remove();
2251
+ });
2252
+
2253
+ Array.from(contentRoot.querySelectorAll('p')).forEach((node) => {
2254
+ if (!isRelatedText(node.textContent)) return;
2255
+ const nodeLinks = collectRelatedLinksFromNode(node);
2256
+ if (!nodeLinks.length) return;
2257
+ links.push(...nodeLinks);
2258
+ node.remove();
2259
+ });
2260
+
2261
+ Array.from(contentRoot.querySelectorAll('h2, h3, h4')).forEach((heading) => {
2262
+ if (!heading.isConnected || !isRelatedText(heading.textContent)) return;
2263
+ const baseLevel = headingLevel(heading);
2264
+ let cursor = heading.nextElementSibling;
2265
+ const remove = [heading];
2266
+ while (cursor) {
2267
+ const level = headingLevel(cursor);
2268
+ if (level && level <= baseLevel) break;
2269
+ links.push(...collectRelatedLinksFromNode(cursor));
2270
+ remove.push(cursor);
2271
+ cursor = cursor.nextElementSibling;
2272
+ }
2273
+ remove.forEach((node) => node.remove());
2274
+ });
2275
+
2276
+ const seen = new Set();
2277
+ return links.filter((link) => {
2278
+ const key = link.slug || link.href;
2279
+ if (!key || seen.has(key)) return false;
2280
+ seen.add(key);
2281
+ return true;
2282
+ });
2283
+ }
2284
+
2285
+ function fallbackRelatedLinksForSlug(slug) {
2286
+ const menu = Array.isArray(window.xtendMenuConfig) && window.xtendMenuConfig.length
2287
+ ? window.xtendMenuConfig
2288
+ : [];
2289
+ const current = menu.find((entry) => entry && entry.slug === slug);
2290
+ const candidates = [];
2291
+
2292
+ if (current) {
2293
+ const parent = current.parent || '';
2294
+ menu.forEach((entry) => {
2295
+ if (!entry || entry.slug === slug) return;
2296
+ if ((parent && entry.parent === parent) || entry.parent === slug || current.parent === entry.slug || entry.group === current.group) {
2297
+ candidates.push({ slug: entry.slug, label: entry.label || docsTitleForSlug(entry.slug), source: 'menu' });
2298
+ }
2299
+ });
2300
+ }
2301
+
2302
+ if (slug.startsWith('components-')) {
2303
+ ['components', 'component-catalog-coverage', 'component-lab', 'component-ux-authoring'].forEach((candidate) => {
2304
+ candidates.push({ slug: candidate, label: docsTitleForSlug(candidate), source: 'component-index' });
2305
+ });
2306
+ }
2307
+
2308
+ if (!candidates.length) {
2309
+ ['quick-start-guide', 'components', 'xtendrmt-overview', 'xtend-loader'].forEach((candidate) => {
2310
+ candidates.push({ slug: candidate, label: docsTitleForSlug(candidate), source: 'default' });
2311
+ });
2312
+ }
2313
+
2314
+ const seen = new Set([slug]);
2315
+ return candidates
2316
+ .filter((entry) => docsPageExists(entry.slug))
2317
+ .filter((entry) => {
2318
+ if (seen.has(entry.slug)) return false;
2319
+ seen.add(entry.slug);
2320
+ return true;
2321
+ })
2322
+ .slice(0, 7);
2323
+ }
2324
+
2325
+ function createRelatedLink(entry) {
2326
+ const link = document.createElement('x-link');
2327
+ link.className = 'docs-related-link';
2328
+ const href = entry.href || (entry.slug ? '/' + entry.slug : '#');
2329
+ link.setAttribute('href', href);
2330
+ link.setAttribute('data-rmt-component', 'docs.relatedLinks');
2331
+ if (entry.slug) {
2332
+ link.setAttribute('data-rmt-route-ref', 'docs.' + entry.slug.replace(/-/g, '.'));
2333
+ }
2334
+
2335
+ const icon = document.createElement('x-icon');
2336
+ icon.setAttribute('name', 'arrow-up-right');
2337
+ icon.setAttribute('pack', 'lucide');
2338
+ icon.setAttribute('decorative', '');
2339
+ icon.setAttribute('size', '1rem');
2340
+
2341
+ const label = document.createElement('span');
2342
+ label.textContent = entry.label || (entry.slug ? docsTitleForSlug(entry.slug) : href);
2343
+
2344
+ const chevron = document.createElement('x-icon');
2345
+ chevron.setAttribute('name', 'chevron-right');
2346
+ chevron.setAttribute('pack', 'lucide');
2347
+ chevron.setAttribute('decorative', '');
2348
+ chevron.setAttribute('size', '1rem');
2349
+
2350
+ link.appendChild(icon);
2351
+ link.appendChild(label);
2352
+ link.appendChild(chevron);
2353
+ return link;
2354
+ }
2355
+
2356
+ function renderDocsRelatedSidebar(relatedSlot, slug, explicitLinks) {
2357
+ if (!relatedSlot) return;
2358
+ const list = relatedSlot.querySelector('[data-rmt-slot="related-links"], .docs-related-list') || relatedSlot;
2359
+ while (list.firstChild) list.removeChild(list.firstChild);
2360
+ const links = explicitLinks && explicitLinks.length ? explicitLinks : fallbackRelatedLinksForSlug(slug);
2361
+ links.forEach((entry) => list.appendChild(createRelatedLink(entry)));
2362
+ relatedSlot.hidden = links.length === 0;
2363
+ relatedSlot.setAttribute('data-related-count', String(links.length));
2364
+ }
2365
+
2366
+ function createDemoCodeBlock(title, lang, code, mode = 'html') {
2367
+ const block = document.createElement('div');
2368
+ block.className = 'docs-demo-code-block';
2369
+ const heading = document.createElement('h3');
2370
+ heading.textContent = title;
2371
+ const codeElement = document.createElement('x-code');
2372
+ codeElement.setAttribute('lang', lang);
2373
+ const template = document.createElement('template');
2374
+ const snippetCode = code == null ? '' : String(code);
2375
+ template.setAttribute('data-x-code-mode', mode === 'html' ? 'html' : 'text');
2376
+ if (mode === 'html') {
2377
+ template.innerHTML = snippetCode;
2378
+ } else {
2379
+ template.content.appendChild(document.createTextNode(snippetCode));
2380
+ }
2381
+ codeElement.appendChild(template);
2382
+ block.appendChild(heading);
2383
+ block.appendChild(codeElement);
2384
+ return block;
2385
+ }
2386
+
2387
+ function ensureDocsDemoScaffold(demoSlot) {
2388
+ let title = demoSlot.querySelector('[data-demo-title]');
2389
+ if (!title) {
2390
+ let heading = demoSlot.querySelector('.docs-sidebar-heading');
2391
+ if (!heading) {
2392
+ heading = createDocsSidebarHeading('play', 'Hands-on Demo', { demoTitle: true });
2393
+ demoSlot.insertBefore(heading, demoSlot.firstChild);
2394
+ title = heading.querySelector('[data-demo-title]');
2395
+ } else {
2396
+ title = document.createElement('span');
2397
+ title.setAttribute('data-demo-title', '');
2398
+ heading.appendChild(title);
2399
+ }
2400
+ }
2401
+
2402
+ let description = demoSlot.querySelector('[data-demo-description]');
2403
+ if (!description) {
2404
+ description = document.createElement('p');
2405
+ description.className = 'docs-sidebar-copy';
2406
+ description.setAttribute('data-demo-description', '');
2407
+ demoSlot.appendChild(description);
2408
+ }
2409
+
2410
+ let preview = demoSlot.querySelector('[data-demo-preview]');
2411
+ if (!preview) {
2412
+ preview = document.createElement('div');
2413
+ preview.className = 'docs-demo-preview';
2414
+ preview.setAttribute('data-demo-preview', '');
2415
+ demoSlot.appendChild(preview);
2416
+ }
2417
+
2418
+ let code = demoSlot.querySelector('[data-demo-code]');
2419
+ if (!code) {
2420
+ code = document.createElement('div');
2421
+ code.className = 'docs-demo-code-grid';
2422
+ code.setAttribute('data-demo-code', '');
2423
+ demoSlot.appendChild(code);
2424
+ }
2425
+
2426
+ return { title, description, preview, code };
2427
+ }
2428
+
2429
+ function hydrateDocsCodeBlocks(root, metadata = {}) {
2430
+ const scope = root || document;
2431
+ const codeBlocks = Array.from(scope.querySelectorAll ? scope.querySelectorAll('x-code') : []);
2432
+ if (!codeBlocks.length) {
2433
+ return Promise.resolve({
2434
+ schema: 'xtend.docs.code-hydration.v1',
2435
+ hydrated: 0,
2436
+ count: 0,
2437
+ skipped: 'no-code-blocks'
2438
+ });
2439
+ }
2440
+
2441
+ const publishHydration = (loaderSnapshot = {}) => {
2442
+ const hydrated = Number.isFinite(loaderSnapshot.hydrated)
2443
+ ? loaderSnapshot.hydrated
2444
+ : codeBlocks.filter((codeBlock) => typeof codeBlock.hydrate === 'function').length;
2445
+
2446
+ const snapshot = {
2447
+ schema: 'xtend.docs.code-hydration.v1',
2448
+ slug: metadata.slug || '',
2449
+ reason: metadata.reason || 'route-render',
2450
+ schedule: metadata.schedule || 'docs.page.hydrate',
2451
+ count: codeBlocks.length,
2452
+ hydrated,
2453
+ componentDefined: Boolean(customElements.get('x-code')),
2454
+ loader: loaderSnapshot.schema || null
2455
+ };
2456
+ window.xtendDocsLastCodeHydration = snapshot;
2457
+ window.dispatchEvent(new CustomEvent('xtend-docs-code-hydrated', { detail: snapshot }));
2458
+ return snapshot;
2459
+ };
2460
+
2461
+ if (window.XTendLoader && typeof window.XTendLoader.hydrateTree === 'function') {
2462
+ return window.XTendLoader.hydrateTree(scope, {
2463
+ tags: ['x-code'],
2464
+ source: 'docs.component-demo',
2465
+ reason: metadata.reason || 'route-render',
2466
+ schedule: metadata.schedule || 'docs.page.hydrate'
2467
+ }).then(publishHydration);
2468
+ }
2469
+
2470
+ return new Promise((resolve) => {
2471
+ const commit = () => {
2472
+ codeBlocks.forEach((codeBlock) => {
2473
+ if (typeof codeBlock.hydrate === 'function') codeBlock.hydrate();
2474
+ });
2475
+ resolve(publishHydration());
2476
+ };
2477
+ if (typeof requestAnimationFrame === 'function') requestAnimationFrame(commit);
2478
+ else window.setTimeout(commit, 0);
2479
+ });
2480
+ }
2481
+
2482
+ function bindDocsDemoInteractions(container, demo) {
2483
+ if (!container || !demo || !Array.isArray(demo.actions)) return;
2484
+ if (demo.actions.includes('toast')) {
2485
+ container.querySelectorAll('[data-demo-action="toast"]').forEach((button) => {
2486
+ bindDocsButtonAction(button, () => window.xtendShowToast('XTend Demo Toast', 'success', 2800));
2487
+ });
2488
+ }
2489
+ if (demo.actions.includes('open-modal')) {
2490
+ container.querySelectorAll('[data-demo-action="open-modal"]').forEach((button) => {
2491
+ bindDocsButtonAction(button, () => {
2492
+ const modal = container.querySelector('#docs-demo-modal');
2493
+ if (modal && typeof modal.open === 'function') modal.open();
2494
+ else if (modal) modal.setAttribute('open', '');
2495
+ });
2496
+ });
2497
+ }
2498
+ if (demo.actions.includes('open-dialog')) {
2499
+ container.querySelectorAll('[data-demo-action="open-dialog"]').forEach((button) => {
2500
+ bindDocsButtonAction(button, () => {
2501
+ const dialog = container.querySelector('#docs-demo-dialog');
2502
+ if (dialog && typeof dialog.open === 'function') dialog.open();
2503
+ else if (dialog) dialog.setAttribute('open', '');
2504
+ });
2505
+ });
2506
+ }
2507
+ }
2508
+
2509
+ function renderDocsComponentDemo(demoSlot, slug) {
2510
+ if (!demoSlot) return;
2511
+ const demo = DOCS_COMPONENT_DEMOS[slug];
2512
+ if (!demo) {
2513
+ demoSlot.hidden = true;
2514
+ demoSlot.removeAttribute('data-demo-component');
2515
+ return;
2516
+ }
2517
+
2518
+ demoSlot.hidden = false;
2519
+ demoSlot.setAttribute('data-demo-component', demo.tag);
2520
+ const { title, description, preview, code } = ensureDocsDemoScaffold(demoSlot);
2521
+ if (title) title.textContent = `${demo.title} Hands-on`;
2522
+ if (description) description.textContent = demo.description;
2523
+ if (preview) {
2524
+ preview.innerHTML = demo.previewHtml;
2525
+ bindDocsDemoInteractions(preview, demo);
2526
+ }
2527
+ if (code) {
2528
+ while (code.firstChild) code.removeChild(code.firstChild);
2529
+ code.appendChild(createDemoCodeBlock('HTML', 'html', demo.html, 'html'));
2530
+ code.appendChild(createDemoCodeBlock('RMT', 'json', demo.rmt, 'text'));
2531
+ }
2532
+ }
2533
+
2534
+ function resolveDocsSlugFromRouteContext(context = {}) {
2535
+ const explicit = context.slug || context.path || context.to || '';
2536
+ const raw = explicit ? String(explicit) : location.hash;
2537
+ const withoutQuery = raw.split('?')[0];
2538
+ let slug = withoutQuery.replace(/^#\/?/, '').replace(/^\/+/, '') || 'readme';
2539
+ if (slug === '' || slug === '/') slug = 'readme';
2540
+ return slug;
2541
+ }
2542
+
2543
+ class XtendDocPage extends HTMLElement {
2544
+ constructor() {
2545
+ super();
2546
+ this.__xtendDocsShell = null;
2547
+ this.__xtendDocsRouteToken = 0;
2548
+ this.__xtendDocsScheduledDisposers = [];
2549
+ }
2550
+
2551
+ connectedCallback() {
2552
+ this.renderRoute({ source: 'connected-callback' });
2553
+ }
2554
+
2555
+ disconnectedCallback() {
2556
+ this.cancelScheduledRouteWork();
2557
+ }
2558
+
2559
+ updateRoute(context = {}) {
2560
+ return this.renderRoute({ ...context, source: 'x-router-reuse' });
2561
+ }
2562
+
2563
+ cancelScheduledRouteWork() {
2564
+ this.__xtendDocsScheduledDisposers.splice(0).forEach((dispose) => {
2565
+ if (typeof dispose === 'function') dispose();
2566
+ });
2567
+ }
2568
+
2569
+ scheduleRouteWork(dispose) {
2570
+ if (typeof dispose === 'function') this.__xtendDocsScheduledDisposers.push(dispose);
2571
+ }
2572
+
2573
+ isActiveRouteToken(token) {
2574
+ return this.isConnected && this.__xtendDocsRouteToken === token;
2575
+ }
2576
+
2577
+ ensureRouteShell(slug, rmtMeta) {
2578
+ if (!this.__xtendDocsShell) {
2579
+ this.__xtendDocsShell = createRmtDocsShell(slug, rmtMeta);
2580
+ this.innerHTML = '';
2581
+ this.appendChild(this.__xtendDocsShell.section);
2582
+ this.setAttribute('data-docs-shell-reused', 'false');
2583
+ return this.__xtendDocsShell;
2584
+ }
2585
+ this.setAttribute('data-docs-shell-reused', 'true');
2586
+ return this.__xtendDocsShell;
2587
+ }
2588
+
2589
+ renderRoute(context = {}) {
2590
+ this.cancelScheduledRouteWork();
2591
+ const token = this.__xtendDocsRouteToken + 1;
2592
+ this.__xtendDocsRouteToken = token;
2593
+
2594
+ const slug = resolveDocsSlugFromRouteContext(context);
2595
+ const docsRouteStartedAt = new Date().toISOString();
2596
+ const routePerfStartedAt = docsPerfNow();
2597
+ const reducedMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
2598
+ const reused = context.source === 'x-router-reuse' || context.reused === true;
2599
+
2600
+ this.setAttribute('data-docs-route-state', reducedMotion ? 'ready' : 'loading');
2601
+ this.setAttribute('data-docs-route-slug', slug);
2602
+ this.setAttribute('data-docs-route-reused', reused ? 'true' : 'false');
2603
+ this.setAttribute('aria-busy', 'true');
2604
+ ensureDocsShellScopedStyles(this.getRootNode());
2605
+
2606
+ const rmtMeta = getDocsPageMeta(slug) || {};
2607
+ const hadShell = Boolean(this.__xtendDocsShell);
2608
+ const shell = this.ensureRouteShell(slug, rmtMeta);
2609
+ applyRmtPageMetadata(shell.section, shell.mdContent, shell.richSlot, shell.diagnosticsSlot, rmtMeta, shell.sidebar, shell.relatedSlot, shell.demoSlot);
2610
+ wireDownloadButton(shell.download, slug);
2611
+
2612
+ const parseSchedule = rmtMeta.schedules && rmtMeta.schedules.parse ? rmtMeta.schedules.parse : 'docs.markdown.parse';
2613
+ const routeSchedule = rmtMeta.schedules && rmtMeta.schedules.route ? rmtMeta.schedules.route : 'docs.route.render';
2614
+ const hydrateSchedule = rmtMeta.schedules && rmtMeta.schedules.hydrate ? rmtMeta.schedules.hydrate : 'docs.page.hydrate';
2615
+ const shellSchedule = rmtMeta.schedules && rmtMeta.schedules.shell ? rmtMeta.schedules.shell : 'docs.shell.render';
2616
+ const richSchedule = rmtMeta.schedules && rmtMeta.schedules.rich ? rmtMeta.schedules.rich : 'docs.rich-content.prepare';
2617
+ const mediaSchedule = rmtMeta.schedules && rmtMeta.schedules.media ? rmtMeta.schedules.media : 'docs.media.lazy';
2618
+ const diagnosticsSchedule = rmtMeta.schedules && rmtMeta.schedules.diagnostics ? rmtMeta.schedules.diagnostics : DOCS_RMT_DEFAULT_DIAGNOSTICS_SCHEDULE;
2619
+ const relatedSchedule = 'docs.related.prepare';
2620
+ const demoSchedule = 'docs.demo.prepare';
2621
+ const laneDurations = [];
2622
+
2623
+ const measuredLane = (lane, schedule, operation, callback) => runDocsMeasuredLane({
2624
+ slug,
2625
+ lane,
2626
+ schedule,
2627
+ operation,
2628
+ routeRef: rmtMeta.routeId || ('docs.' + slug.replace(/-/g, '.')),
2629
+ routeToken: token,
2630
+ reused
2631
+ }, () => {
2632
+ const startedAt = docsPerfNow();
2633
+ const result = callback();
2634
+ laneDurations.push({ lane, schedule, operation, durationMs: docsRoundDuration(docsPerfNow() - startedAt) });
2635
+ return result;
2636
+ });
2637
+
2638
+ window.xtendDocsRmtLastRender = {
2639
+ schema: DOCS_RMT_RENDER_SCHEMA,
2640
+ slug,
2641
+ shellFirst: true,
2642
+ shellReused: hadShell,
2643
+ routeReuse: reused,
2644
+ insularHydration: true,
2645
+ productionHardeningSchema: DOCS_RMT_PRODUCTION_HARDENING_SCHEMA,
2646
+ shellTemplate: rmtMeta.shellTemplate || DOCS_RMT_DEFAULT_SHELL_TEMPLATE,
2647
+ shellSchedule,
2648
+ shellEndpoint: getRmtSchedule(shellSchedule) ? getRmtSchedule(shellSchedule).endpointName : 'xtendrmt.shell.render',
2649
+ searchTemplate: rmtMeta.searchTemplate || DOCS_RMT_DEFAULT_SEARCH_TEMPLATE,
2650
+ title: rmtMeta.title || '',
2651
+ documentTitle: rmtMeta.documentTitle || '',
2652
+ titleTemplate: rmtMeta.titleTemplate || '',
2653
+ metaDescription: rmtMeta.metaDescription || '',
2654
+ metaKeywords: rmtMeta.metaKeywords || [],
2655
+ template: rmtMeta.template || '',
2656
+ adapter: rmtMeta.adapter || 'docs.parsedown',
2657
+ parseSchedule,
2658
+ routeSchedule,
2659
+ hydrateSchedule,
2660
+ richSchedule,
2661
+ mediaSchedule,
2662
+ relatedSchedule,
2663
+ demoSchedule,
2664
+ diagnosticsSchedule,
2665
+ markupClass: rmtMeta.markupClass || 'parsedownHtml',
2666
+ contentKind: rmtMeta.contentKind || 'parsedownHtml',
2667
+ contentSlot: rmtMeta.contentSlot || 'content',
2668
+ extensionSlots: DOCS_RMT_EXTENSION_SLOTS.slice(),
2669
+ sidebarSlotAvailable: Boolean(shell.sidebar),
2670
+ relatedSlotAvailable: Boolean(shell.relatedSlot),
2671
+ componentDemoSlotAvailable: Boolean(shell.demoSlot),
2672
+ diagnosticsSlotAvailable: Boolean(shell.diagnosticsSlot),
2673
+ trustBoundary: rmtMeta.trustBoundary || DOCS_RMT_TRUST_BOUNDARY
2674
+ };
2675
+ window.xtendDocsRmtProductionLastRender = createDocsRmtProductionRenderSnapshot(slug, rmtMeta, shell);
2676
+
2677
+ ensureRmtSearchShell();
2678
+ ensureMainBackgroundBinding();
2679
+
2680
+ syncActiveHeaderLink(slug);
2681
+ ensureMenuBinding();
2682
+ while (shell.mdContent.firstChild) {
2683
+ shell.mdContent.removeChild(shell.mdContent.firstChild);
2684
+ }
2685
+ showDocsSkeleton(shell.mdContent, {
2686
+ variant: 'article',
2687
+ lines: 11,
2688
+ minHeight: '24rem',
2689
+ label: 'Dokumentationsinhalt wird geladen',
2690
+ source: 'docs.parsedown',
2691
+ schedule: parseSchedule
2692
+ });
2693
+
2694
+ const contentPayloadPromise = loadDocsParsedownContent(slug, rmtMeta);
2695
+ let relatedLinks = [];
2696
+ let contentCommitted = false;
2697
+
2698
+ const commitParsedownContent = async () => {
2699
+ if (!this.isActiveRouteToken(token) || contentCommitted) return false;
2700
+ const payload = await contentPayloadPromise;
2701
+ if (!this.isActiveRouteToken(token) || contentCommitted) return false;
2702
+ contentCommitted = true;
2703
+ const html = payload && typeof payload.html === 'string'
2704
+ ? payload.html
2705
+ : '<em>Seite nicht gefunden</em>';
2706
+ const payloadMeta = payload && payload.meta && typeof payload.meta === 'object'
2707
+ ? payload.meta
2708
+ : rmtMeta;
2709
+ const trustedDomResult = measuredLane('visible', parseSchedule, 'article.trusted-dom-commit', () => applyDocsTrustedDomHtml(shell.mdContent, html, {
2710
+ slug,
2711
+ source: payloadMeta.source || rmtMeta.source || 'docs.parsedown',
2712
+ markupClass: payloadMeta.markupClass || rmtMeta.markupClass || 'parsedownHtml',
2713
+ trustBoundary: payloadMeta.trustBoundary || rmtMeta.trustBoundary || DOCS_RMT_TRUST_BOUNDARY
2714
+ }));
2715
+ hideDocsSkeleton(shell.mdContent);
2716
+ window.xtendDocsRmtLastRender.lazyPayload = payload && payload.source !== 'inline';
2717
+ window.xtendDocsRmtLastRender.payloadSource = payload ? payload.source : 'unknown';
2718
+ window.xtendDocsRmtLastRender.skeletonLoader = 'xtend.loader.skeleton-loader.v1';
2719
+ window.xtendDocsRmtProductionLastRender.trustedDom = {
2720
+ schema: trustedDomResult.schema,
2721
+ sanitizer: trustedDomResult.sanitizer,
2722
+ sanitized: trustedDomResult.sanitized,
2723
+ removedCount: trustedDomResult.removedCount,
2724
+ boundary: trustedDomResult.boundary,
2725
+ markupClass: trustedDomResult.markupClass,
2726
+ cacheHit: trustedDomResult.cacheHit === true
2727
+ };
2728
+
2729
+ relatedLinks = measuredLane('visible', relatedSchedule, 'article.related-extract', () => {
2730
+ upgradeRoutedLinks(shell.mdContent);
2731
+ return extractDocsRelatedLinks(shell.mdContent);
2732
+ });
2733
+ return true;
2734
+ };
2735
+
2736
+ let transitionCompleted = false;
2737
+ const finishTransition = () => {
2738
+ if (!this.isActiveRouteToken(token) || transitionCompleted) return;
2739
+ transitionCompleted = true;
2740
+ this.setAttribute('data-docs-route-state', 'ready');
2741
+ this.removeAttribute('aria-busy');
2742
+ window.dispatchEvent(new CustomEvent('xtend-docs-route-transition', {
2743
+ detail: {
2744
+ schema: 'xtend.docs.route-transition.v1',
2745
+ slug,
2746
+ reducedMotion,
2747
+ reused,
2748
+ insularHydration: true,
2749
+ startedAt: docsRouteStartedAt,
2750
+ completedAt: new Date().toISOString(),
2751
+ durationMs: docsRoundDuration(docsPerfNow() - routePerfStartedAt),
2752
+ laneDurations: laneDurations.slice(),
2753
+ routeRef: rmtMeta.routeId || ('docs.' + slug.replace(/-/g, '.')),
2754
+ routeId: rmtMeta.routeId || ('docs.' + slug.replace(/-/g, '.')),
2755
+ componentRef: 'xtend-doc-page',
2756
+ rmtComponentId: 'docs.page',
2757
+ schedule: routeSchedule,
2758
+ routeSchedule,
2759
+ hydrateSchedule,
2760
+ relatedSchedule,
2761
+ demoSchedule,
2762
+ diagnosticsSchedule,
2763
+ shellSchedule,
2764
+ parseSchedule,
2765
+ metadata: window.xtendDocsRmtLastRender || null
2766
+ }
2767
+ }));
2768
+ };
2769
+
2770
+ const afterPaintDisposer = scheduleDocsAfterPaint(() => {
2771
+ if (!this.isActiveRouteToken(token)) return;
2772
+ commitParsedownContent().then((committed) => {
2773
+ if (!committed || !this.isActiveRouteToken(token)) return;
2774
+ measuredLane('idle', relatedSchedule, 'sidebar.related-render', () => renderDocsRelatedSidebar(shell.relatedSlot, slug, relatedLinks));
2775
+ window.dispatchEvent(new CustomEvent('xtend-docs-content-ready', {
2776
+ detail: {
2777
+ schema: 'xtend.docs.content-ready.v1',
2778
+ slug,
2779
+ routeRef: rmtMeta.routeId || ('docs.' + slug.replace(/-/g, '.')),
2780
+ root: shell.mdContent,
2781
+ schedule: hydrateSchedule,
2782
+ syntaxSchedule: 'docs.syntax.highlight',
2783
+ reused,
2784
+ insularHydration: true,
2785
+ skeletonLoader: 'xtend.loader.skeleton-loader.v1'
2786
+ }
2787
+ }));
2788
+ finishTransition();
2789
+ }).catch((error) => {
2790
+ if (!this.isActiveRouteToken(token)) return;
2791
+ hideDocsSkeleton(shell.mdContent);
2792
+ shell.mdContent.innerHTML = '<em>Seite konnte nicht geladen werden.</em>';
2793
+ window.dispatchEvent(new CustomEvent('xtend-docs-content-error', {
2794
+ detail: {
2795
+ schema: 'xtend.docs.content-error.v1',
2796
+ slug,
2797
+ schedule: parseSchedule,
2798
+ message: error && error.message ? error.message : String(error)
2799
+ }
2800
+ }));
2801
+ finishTransition();
2802
+ });
2803
+ });
2804
+ this.scheduleRouteWork(afterPaintDisposer);
2805
+
2806
+ const idleDisposer = scheduleDocsIdle(() => {
2807
+ if (!this.isActiveRouteToken(token)) return;
2808
+ measuredLane('idle', demoSchedule, 'component-demo.render', () => renderDocsComponentDemo(shell.demoSlot, slug));
2809
+ hydrateDocsCodeBlocks(shell.demoSlot, {
2810
+ slug,
2811
+ reason: 'component-demo-idle-route-render',
2812
+ schedule: demoSchedule
2813
+ });
2814
+ });
2815
+ this.scheduleRouteWork(idleDisposer);
2816
+
2817
+ return true;
2818
+ }
2819
+ }
2820
+
2821
+ if (!customElements.get('xtend-doc-page')) {
2822
+ customElements.define('xtend-doc-page', XtendDocPage);
2823
+ }