@nordcraft/runtime 1.0.76 → 1.0.78

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 (238) hide show
  1. package/dist/custom-element.main.esm.js +41 -50
  2. package/dist/custom-element.main.esm.js.map +4 -4
  3. package/dist/happydom.js +3 -0
  4. package/dist/happydom.js.map +1 -0
  5. package/dist/page.main.esm.js +3 -3
  6. package/dist/page.main.esm.js.map +4 -4
  7. package/dist/src/api/apiUtils.js.map +1 -0
  8. package/dist/src/api/createAPI.js.map +1 -0
  9. package/dist/src/api/createAPIv2.js.map +1 -0
  10. package/dist/{components → src/components}/createComponent.js +11 -0
  11. package/dist/src/components/createComponent.js.map +1 -0
  12. package/dist/{components → src/components}/createElement.js +1 -1
  13. package/dist/src/components/createElement.js.map +1 -0
  14. package/dist/src/components/createNode.js.map +1 -0
  15. package/dist/src/components/createSlot.js.map +1 -0
  16. package/dist/src/components/createText.js.map +1 -0
  17. package/dist/src/components/createText.test.js.map +1 -0
  18. package/dist/{components → src/components}/renderComponent.d.ts +4 -1
  19. package/dist/{components → src/components}/renderComponent.js +2 -1
  20. package/dist/src/components/renderComponent.js.map +1 -0
  21. package/dist/src/context/isContextProvider.js.map +1 -0
  22. package/dist/src/context/subscribeToContext.js.map +1 -0
  23. package/dist/src/custom-components/components.js.map +1 -0
  24. package/dist/src/custom-components/toddle-portal.js.map +1 -0
  25. package/dist/{custom-element → src/custom-element}/ToddleComponent.js +5 -0
  26. package/dist/src/custom-element/ToddleComponent.js.map +1 -0
  27. package/dist/src/custom-element/defineComponents.js.map +1 -0
  28. package/dist/src/custom-element.main.js.map +1 -0
  29. package/dist/src/debug/logState.js.map +1 -0
  30. package/dist/src/debug/panicScreen.js.map +1 -0
  31. package/dist/src/debug/sendEditorToast.js.map +1 -0
  32. package/dist/src/editor/drag-drop/dragEnded.js.map +1 -0
  33. package/dist/src/editor/drag-drop/dragMove.js.map +1 -0
  34. package/dist/src/editor/drag-drop/dragReorder.js.map +1 -0
  35. package/dist/src/editor/drag-drop/dragStarted.js.map +1 -0
  36. package/dist/src/editor/drag-drop/dropHighlight.js.map +1 -0
  37. package/dist/src/editor/drag-drop/getInsertAreas.js.map +1 -0
  38. package/dist/src/editor/graphql.js.map +1 -0
  39. package/dist/src/editor/input.js.map +1 -0
  40. package/dist/src/editor/links.js.map +1 -0
  41. package/dist/src/editor/overlay.js.map +1 -0
  42. package/dist/{editor → src/editor}/types.d.ts +3 -1
  43. package/dist/src/editor/types.js.map +1 -0
  44. package/dist/{editor-preview.main.js → src/editor-preview.main.js} +75 -27
  45. package/dist/src/editor-preview.main.js.map +1 -0
  46. package/dist/src/events/handleAction.js.map +1 -0
  47. package/dist/{page.main.js → src/page.main.js} +13 -0
  48. package/dist/src/page.main.js.map +1 -0
  49. package/dist/src/signal/signal.js.map +1 -0
  50. package/dist/src/styles/CustomPropertyStyleSheet.js.map +1 -0
  51. package/dist/src/styles/CustomPropertyStyleSheet.test.d.ts +1 -0
  52. package/dist/{styles → src/styles}/CustomPropertyStyleSheet.test.js +37 -0
  53. package/dist/src/styles/CustomPropertyStyleSheet.test.js.map +1 -0
  54. package/dist/{styles → src/styles}/style.js +2 -1
  55. package/dist/src/styles/style.js.map +1 -0
  56. package/dist/src/styles/style.test.js +179 -0
  57. package/dist/src/styles/style.test.js.map +1 -0
  58. package/dist/src/utils/BatchQueue.js.map +1 -0
  59. package/dist/src/utils/createFormulaCache.js.map +1 -0
  60. package/dist/src/utils/findNearestLine.js.map +1 -0
  61. package/dist/src/utils/findNearestLine.test.d.ts +1 -0
  62. package/dist/src/utils/findNearestLine.test.js.map +1 -0
  63. package/dist/src/utils/getDragData.js.map +1 -0
  64. package/dist/src/utils/getElementTagName.js.map +1 -0
  65. package/dist/src/utils/getThemeSignal.d.ts +4 -0
  66. package/dist/src/utils/getThemeSignal.js +51 -0
  67. package/dist/src/utils/getThemeSignal.js.map +1 -0
  68. package/dist/src/utils/isElementInViewport.js.map +1 -0
  69. package/dist/src/utils/nodes.js.map +1 -0
  70. package/dist/src/utils/omitStyle.js.map +1 -0
  71. package/dist/src/utils/rectHasPoint.js.map +1 -0
  72. package/dist/src/utils/setAttribute.js.map +1 -0
  73. package/dist/src/utils/storeScrollState.js.map +1 -0
  74. package/dist/src/utils/subscribeCustomProperty.js.map +1 -0
  75. package/dist/src/utils/tryStartViewTransition.js.map +1 -0
  76. package/dist/src/utils/url.js.map +1 -0
  77. package/package.json +8 -6
  78. package/src/components/createComponent.ts +12 -0
  79. package/src/components/createElement.ts +1 -1
  80. package/src/components/renderComponent.ts +5 -0
  81. package/src/custom-element/ToddleComponent.ts +5 -0
  82. package/src/editor/types.ts +4 -1
  83. package/src/editor-preview.main.ts +105 -37
  84. package/src/page.main.ts +13 -0
  85. package/src/styles/CustomPropertyStyleSheet.test.ts +46 -0
  86. package/src/styles/style.test.ts +214 -0
  87. package/src/styles/style.ts +2 -1
  88. package/src/types.d.ts +3 -0
  89. package/src/utils/getThemeSignal.ts +66 -0
  90. package/dist/api/apiUtils.js.map +0 -1
  91. package/dist/api/createAPI.js.map +0 -1
  92. package/dist/api/createAPIv2.js.map +0 -1
  93. package/dist/components/createComponent.js.map +0 -1
  94. package/dist/components/createElement.js.map +0 -1
  95. package/dist/components/createNode.js.map +0 -1
  96. package/dist/components/createSlot.js.map +0 -1
  97. package/dist/components/createText.js.map +0 -1
  98. package/dist/components/createText.test.js.map +0 -1
  99. package/dist/components/renderComponent.js.map +0 -1
  100. package/dist/context/isContextProvider.js.map +0 -1
  101. package/dist/context/subscribeToContext.js.map +0 -1
  102. package/dist/custom-components/components.js.map +0 -1
  103. package/dist/custom-components/toddle-portal.js.map +0 -1
  104. package/dist/custom-element/ToddleComponent.js.map +0 -1
  105. package/dist/custom-element/defineComponents.js.map +0 -1
  106. package/dist/custom-element.main.js.map +0 -1
  107. package/dist/debug/logState.js.map +0 -1
  108. package/dist/debug/panicScreen.js.map +0 -1
  109. package/dist/debug/sendEditorToast.js.map +0 -1
  110. package/dist/editor/drag-drop/dragEnded.js.map +0 -1
  111. package/dist/editor/drag-drop/dragMove.js.map +0 -1
  112. package/dist/editor/drag-drop/dragReorder.js.map +0 -1
  113. package/dist/editor/drag-drop/dragStarted.js.map +0 -1
  114. package/dist/editor/drag-drop/dropHighlight.js.map +0 -1
  115. package/dist/editor/drag-drop/getInsertAreas.js.map +0 -1
  116. package/dist/editor/graphql.js.map +0 -1
  117. package/dist/editor/input.js.map +0 -1
  118. package/dist/editor/links.js.map +0 -1
  119. package/dist/editor/overlay.js.map +0 -1
  120. package/dist/editor/types.js.map +0 -1
  121. package/dist/editor-preview.main.js.map +0 -1
  122. package/dist/events/handleAction.js.map +0 -1
  123. package/dist/page.main.js.map +0 -1
  124. package/dist/signal/signal.js.map +0 -1
  125. package/dist/styles/CustomPropertyStyleSheet.js.map +0 -1
  126. package/dist/styles/CustomPropertyStyleSheet.test.js.map +0 -1
  127. package/dist/styles/style.js.map +0 -1
  128. package/dist/utils/BatchQueue.js.map +0 -1
  129. package/dist/utils/createFormulaCache.js.map +0 -1
  130. package/dist/utils/findNearestLine.js.map +0 -1
  131. package/dist/utils/findNearestLine.test.js.map +0 -1
  132. package/dist/utils/getDragData.js.map +0 -1
  133. package/dist/utils/getElementTagName.js.map +0 -1
  134. package/dist/utils/isElementInViewport.js.map +0 -1
  135. package/dist/utils/nodes.js.map +0 -1
  136. package/dist/utils/omitStyle.js.map +0 -1
  137. package/dist/utils/rectHasPoint.js.map +0 -1
  138. package/dist/utils/setAttribute.js.map +0 -1
  139. package/dist/utils/storeScrollState.js.map +0 -1
  140. package/dist/utils/subscribeCustomProperty.js.map +0 -1
  141. package/dist/utils/tryStartViewTransition.js.map +0 -1
  142. package/dist/utils/url.js.map +0 -1
  143. /package/dist/{components/createText.test.d.ts → happydom.d.ts} +0 -0
  144. /package/dist/{api → src/api}/apiUtils.d.ts +0 -0
  145. /package/dist/{api → src/api}/apiUtils.js +0 -0
  146. /package/dist/{api → src/api}/createAPI.d.ts +0 -0
  147. /package/dist/{api → src/api}/createAPI.js +0 -0
  148. /package/dist/{api → src/api}/createAPIv2.d.ts +0 -0
  149. /package/dist/{api → src/api}/createAPIv2.js +0 -0
  150. /package/dist/{components → src/components}/createComponent.d.ts +0 -0
  151. /package/dist/{components → src/components}/createElement.d.ts +0 -0
  152. /package/dist/{components → src/components}/createNode.d.ts +0 -0
  153. /package/dist/{components → src/components}/createNode.js +0 -0
  154. /package/dist/{components → src/components}/createSlot.d.ts +0 -0
  155. /package/dist/{components → src/components}/createSlot.js +0 -0
  156. /package/dist/{components → src/components}/createText.d.ts +0 -0
  157. /package/dist/{components → src/components}/createText.js +0 -0
  158. /package/dist/{styles/CustomPropertyStyleSheet.test.d.ts → src/components/createText.test.d.ts} +0 -0
  159. /package/dist/{components → src/components}/createText.test.js +0 -0
  160. /package/dist/{context → src/context}/isContextProvider.d.ts +0 -0
  161. /package/dist/{context → src/context}/isContextProvider.js +0 -0
  162. /package/dist/{context → src/context}/subscribeToContext.d.ts +0 -0
  163. /package/dist/{context → src/context}/subscribeToContext.js +0 -0
  164. /package/dist/{custom-components → src/custom-components}/components.d.ts +0 -0
  165. /package/dist/{custom-components → src/custom-components}/components.js +0 -0
  166. /package/dist/{custom-components → src/custom-components}/toddle-portal.d.ts +0 -0
  167. /package/dist/{custom-components → src/custom-components}/toddle-portal.js +0 -0
  168. /package/dist/{custom-element → src/custom-element}/ToddleComponent.d.ts +0 -0
  169. /package/dist/{custom-element → src/custom-element}/defineComponents.d.ts +0 -0
  170. /package/dist/{custom-element → src/custom-element}/defineComponents.js +0 -0
  171. /package/dist/{custom-element.main.d.ts → src/custom-element.main.d.ts} +0 -0
  172. /package/dist/{custom-element.main.js → src/custom-element.main.js} +0 -0
  173. /package/dist/{debug → src/debug}/logState.d.ts +0 -0
  174. /package/dist/{debug → src/debug}/logState.js +0 -0
  175. /package/dist/{debug → src/debug}/panicScreen.d.ts +0 -0
  176. /package/dist/{debug → src/debug}/panicScreen.js +0 -0
  177. /package/dist/{debug → src/debug}/sendEditorToast.d.ts +0 -0
  178. /package/dist/{debug → src/debug}/sendEditorToast.js +0 -0
  179. /package/dist/{editor → src/editor}/drag-drop/dragEnded.d.ts +0 -0
  180. /package/dist/{editor → src/editor}/drag-drop/dragEnded.js +0 -0
  181. /package/dist/{editor → src/editor}/drag-drop/dragMove.d.ts +0 -0
  182. /package/dist/{editor → src/editor}/drag-drop/dragMove.js +0 -0
  183. /package/dist/{editor → src/editor}/drag-drop/dragReorder.d.ts +0 -0
  184. /package/dist/{editor → src/editor}/drag-drop/dragReorder.js +0 -0
  185. /package/dist/{editor → src/editor}/drag-drop/dragStarted.d.ts +0 -0
  186. /package/dist/{editor → src/editor}/drag-drop/dragStarted.js +0 -0
  187. /package/dist/{editor → src/editor}/drag-drop/dropHighlight.d.ts +0 -0
  188. /package/dist/{editor → src/editor}/drag-drop/dropHighlight.js +0 -0
  189. /package/dist/{editor → src/editor}/drag-drop/getInsertAreas.d.ts +0 -0
  190. /package/dist/{editor → src/editor}/drag-drop/getInsertAreas.js +0 -0
  191. /package/dist/{editor → src/editor}/graphql.d.ts +0 -0
  192. /package/dist/{editor → src/editor}/graphql.js +0 -0
  193. /package/dist/{editor → src/editor}/input.d.ts +0 -0
  194. /package/dist/{editor → src/editor}/input.js +0 -0
  195. /package/dist/{editor → src/editor}/links.d.ts +0 -0
  196. /package/dist/{editor → src/editor}/links.js +0 -0
  197. /package/dist/{editor → src/editor}/overlay.d.ts +0 -0
  198. /package/dist/{editor → src/editor}/overlay.js +0 -0
  199. /package/dist/{editor → src/editor}/types.js +0 -0
  200. /package/dist/{editor-preview.main.d.ts → src/editor-preview.main.d.ts} +0 -0
  201. /package/dist/{events → src/events}/handleAction.d.ts +0 -0
  202. /package/dist/{events → src/events}/handleAction.js +0 -0
  203. /package/dist/{page.main.d.ts → src/page.main.d.ts} +0 -0
  204. /package/dist/{signal → src/signal}/signal.d.ts +0 -0
  205. /package/dist/{signal → src/signal}/signal.js +0 -0
  206. /package/dist/{styles → src/styles}/CustomPropertyStyleSheet.d.ts +0 -0
  207. /package/dist/{styles → src/styles}/CustomPropertyStyleSheet.js +0 -0
  208. /package/dist/{styles → src/styles}/style.d.ts +0 -0
  209. /package/dist/{utils/findNearestLine.test.d.ts → src/styles/style.test.d.ts} +0 -0
  210. /package/dist/{utils → src/utils}/BatchQueue.d.ts +0 -0
  211. /package/dist/{utils → src/utils}/BatchQueue.js +0 -0
  212. /package/dist/{utils → src/utils}/createFormulaCache.d.ts +0 -0
  213. /package/dist/{utils → src/utils}/createFormulaCache.js +0 -0
  214. /package/dist/{utils → src/utils}/findNearestLine.d.ts +0 -0
  215. /package/dist/{utils → src/utils}/findNearestLine.js +0 -0
  216. /package/dist/{utils → src/utils}/findNearestLine.test.js +0 -0
  217. /package/dist/{utils → src/utils}/getDragData.d.ts +0 -0
  218. /package/dist/{utils → src/utils}/getDragData.js +0 -0
  219. /package/dist/{utils → src/utils}/getElementTagName.d.ts +0 -0
  220. /package/dist/{utils → src/utils}/getElementTagName.js +0 -0
  221. /package/dist/{utils → src/utils}/isElementInViewport.d.ts +0 -0
  222. /package/dist/{utils → src/utils}/isElementInViewport.js +0 -0
  223. /package/dist/{utils → src/utils}/nodes.d.ts +0 -0
  224. /package/dist/{utils → src/utils}/nodes.js +0 -0
  225. /package/dist/{utils → src/utils}/omitStyle.d.ts +0 -0
  226. /package/dist/{utils → src/utils}/omitStyle.js +0 -0
  227. /package/dist/{utils → src/utils}/rectHasPoint.d.ts +0 -0
  228. /package/dist/{utils → src/utils}/rectHasPoint.js +0 -0
  229. /package/dist/{utils → src/utils}/setAttribute.d.ts +0 -0
  230. /package/dist/{utils → src/utils}/setAttribute.js +0 -0
  231. /package/dist/{utils → src/utils}/storeScrollState.d.ts +0 -0
  232. /package/dist/{utils → src/utils}/storeScrollState.js +0 -0
  233. /package/dist/{utils → src/utils}/subscribeCustomProperty.d.ts +0 -0
  234. /package/dist/{utils → src/utils}/subscribeCustomProperty.js +0 -0
  235. /package/dist/{utils → src/utils}/tryStartViewTransition.d.ts +0 -0
  236. /package/dist/{utils → src/utils}/tryStartViewTransition.js +0 -0
  237. /package/dist/{utils → src/utils}/url.d.ts +0 -0
  238. /package/dist/{utils → src/utils}/url.js +0 -0
@@ -31,6 +31,7 @@ import {
31
31
  getThemeEntries,
32
32
  renderThemeValues,
33
33
  } from '@nordcraft/core/dist/styling/theme'
34
+ import { THEME_DATA_ATTRIBUTE } from '@nordcraft/core/dist/styling/theme.const'
34
35
  import type { StyleVariant } from '@nordcraft/core/dist/styling/variantSelector'
35
36
  import type {
36
37
  ActionHandler,
@@ -79,6 +80,7 @@ import type {
79
80
  PreviewShowSignal,
80
81
  } from './types'
81
82
  import { createFormulaCache } from './utils/createFormulaCache'
83
+ import { getThemeSignal } from './utils/getThemeSignal'
82
84
  import { getNodeAndAncestors, isNodeOrAncestorConditional } from './utils/nodes'
83
85
  import { rectHasPoint } from './utils/rectHasPoint'
84
86
  import {
@@ -217,6 +219,7 @@ export const createRoot = (
217
219
  displayedNodes: [],
218
220
  testMode: false,
219
221
  })
222
+ const themeSignal = signal<string | null>(null)
220
223
  window.toddle._preview = { showSignal }
221
224
  document.body.setAttribute('data-mode', 'design')
222
225
  let components: Component[] | null = null
@@ -913,38 +916,9 @@ export const createRoot = (
913
916
  })
914
917
  break
915
918
  case 'preview_style':
916
- const { styles: previewStyleStyles, theme, resources } = message.data
919
+ const { styles: previewStyleStyles, theme } = message.data
917
920
  cancelAnimationFrame(previewStyleAnimationFrame)
918
921
  previewStyleAnimationFrame = requestAnimationFrame(() => {
919
- // Allow for temporarily adding preview resources (e.g. fonts).
920
- const resourceElements = Array.from(
921
- document.head.querySelectorAll('[data-id="preview-resource"]'),
922
- )
923
- // Remove any resources that are no longer needed
924
- resourceElements.forEach((el) => {
925
- if (
926
- !resources ||
927
- resources.length === 0 ||
928
- !resources.some((res) => res.href === el.getAttribute('href'))
929
- ) {
930
- el.remove()
931
- }
932
- })
933
- resources
934
- ?.filter(
935
- (resource) =>
936
- !resourceElements.some(
937
- (el) => el.getAttribute('href') === resource.href,
938
- ),
939
- )
940
- .forEach((resource) => {
941
- const resourceElement = document.createElement('link')
942
- resourceElement.setAttribute('data-id', 'preview-resource')
943
- resourceElement.rel = 'stylesheet'
944
- resourceElement.href = resource.href
945
- document.head.appendChild(resourceElement)
946
- })
947
-
948
922
  // Update or create a new style tag and set the given styles with important priority
949
923
  let styleElement = document.head.querySelector(
950
924
  '[data-id="selected-node-styles"]',
@@ -1031,7 +1005,7 @@ export const createRoot = (
1031
1005
  }
1032
1006
  cssBlocks.push(
1033
1007
  renderThemeValues(
1034
- `[data-theme~="${theme.key}"]`,
1008
+ `[${THEME_DATA_ATTRIBUTE}~="${theme.key}"]`,
1035
1009
  getThemeEntries(theme.value, theme.key),
1036
1010
  ),
1037
1011
  )
@@ -1047,12 +1021,43 @@ export const createRoot = (
1047
1021
  }
1048
1022
  })
1049
1023
  break
1024
+ case 'preview_resources': {
1025
+ const { resources } = message.data
1026
+ // Allow for temporarily adding preview resources (e.g. fonts).
1027
+ const resourceElements = Array.from(
1028
+ document.head.querySelectorAll('[data-id="preview-resource"]'),
1029
+ )
1030
+ // Remove any resources that are no longer needed
1031
+ resourceElements.forEach((el) => {
1032
+ if (
1033
+ resources.length === 0 ||
1034
+ !resources.some((res) => res.href === el.getAttribute('href'))
1035
+ ) {
1036
+ el.remove()
1037
+ }
1038
+ })
1039
+ resources
1040
+ .filter(
1041
+ (resource) =>
1042
+ !resourceElements.some(
1043
+ (el) => el.getAttribute('href') === resource.href,
1044
+ ),
1045
+ )
1046
+ .forEach((resource) => {
1047
+ const resourceElement = document.createElement('link')
1048
+ resourceElement.setAttribute('data-id', 'preview-resource')
1049
+ resourceElement.rel = 'stylesheet'
1050
+ resourceElement.href = resource.href
1051
+ document.head.appendChild(resourceElement)
1052
+ })
1053
+ break
1054
+ }
1050
1055
  case 'preview_theme': {
1051
1056
  const { theme } = message.data
1052
1057
  if (theme) {
1053
- document.body.setAttribute('data-theme', theme)
1058
+ document.body.setAttribute(THEME_DATA_ATTRIBUTE, theme)
1054
1059
  } else {
1055
- document.body.removeAttribute('data-theme')
1060
+ document.body.removeAttribute(THEME_DATA_ATTRIBUTE)
1056
1061
  }
1057
1062
  }
1058
1063
  }
@@ -1246,7 +1251,8 @@ export const createRoot = (
1246
1251
  fastDeepEqual(
1247
1252
  ctx?.component.route?.info?.meta,
1248
1253
  _component.route?.info?.meta,
1249
- ) === false
1254
+ ) === false ||
1255
+ !ctx
1250
1256
  ) {
1251
1257
  insertHeadTags(_component.route?.info?.meta ?? {}, {
1252
1258
  component: _component,
@@ -1388,6 +1394,21 @@ export const createRoot = (
1388
1394
  component: _component,
1389
1395
  }
1390
1396
 
1397
+ if (
1398
+ fastDeepEqual(
1399
+ newCtx.component.route?.info?.theme,
1400
+ ctx?.component.route?.info?.theme,
1401
+ ) === false
1402
+ ) {
1403
+ setupThemeSubscription(
1404
+ newCtx.component,
1405
+ newCtx.dataSignal,
1406
+ env,
1407
+ ).subscribe((theme) => {
1408
+ newCtx.stores.theme.set(theme)
1409
+ })
1410
+ }
1411
+
1391
1412
  for (const api in newCtx.component.apis) {
1392
1413
  // check if the api has changed (ignoring onCompleted and onFailed).
1393
1414
  const apiInstance = newCtx.component.apis[api]
@@ -1552,11 +1573,20 @@ export const createRoot = (
1552
1573
  abortSignal: new AbortController().signal,
1553
1574
  formulaCache: createFormulaCache(component),
1554
1575
  providers: {},
1576
+ stores: {
1577
+ theme: themeSignal,
1578
+ },
1555
1579
  package: undefined,
1556
1580
  toddle: window.toddle,
1557
1581
  env,
1558
1582
  }
1559
1583
 
1584
+ setupThemeSubscription(ctx.component, ctx.dataSignal, env).subscribe(
1585
+ (theme) => {
1586
+ ctx.stores.theme.set(theme)
1587
+ },
1588
+ )
1589
+
1560
1590
  if (isContextProvider(component)) {
1561
1591
  // Subscribe to exposed formulas and update the component's data signal
1562
1592
  const formulaDataSignals = Object.fromEntries(
@@ -1670,7 +1700,7 @@ const insertHeadTags = (
1670
1700
  .filter((elem) => !entries[elem.getAttribute('data-meta-id')!])
1671
1701
  .forEach((elem) => elem.remove())
1672
1702
 
1673
- // Skip anything that is not <link> or <script> tags, as they don't have any influence on the preview
1703
+ // Skip anything that is not <link>, <style> or <script> tags, as they don't have any influence on the preview
1674
1704
  Object.entries(entries).forEach(([id, entry]) => {
1675
1705
  switch (entry.tag) {
1676
1706
  case HeadTagTypes.Link:
@@ -1697,9 +1727,22 @@ const insertHeadTags = (
1697
1727
  ></script>
1698
1728
  `),
1699
1729
  )
1730
+ case HeadTagTypes.Style:
1731
+ return insertOrReplaceHeadNode(
1732
+ id,
1733
+ document.createRange().createContextualFragment(`
1734
+ <style
1735
+ data-meta-id="${id}"
1736
+ ${Object.entries(entry.attrs)
1737
+ .map(([key, value]) => `${key}="${applyFormula(value, context)}"`)
1738
+ .join(' ')}
1739
+ >
1740
+ ${applyFormula(entry.content ?? '', context)}
1741
+ </style>
1742
+ `),
1743
+ )
1700
1744
  default:
1701
- // TODO: handle style meta tags?
1702
- break
1745
+ return
1703
1746
  }
1704
1747
  })
1705
1748
  }
@@ -1872,3 +1915,28 @@ const registerFormulas = (
1872
1915
  const postMessageToEditor = (message: EditorPostMessageType) => {
1873
1916
  window.parent?.postMessage(message, '*')
1874
1917
  }
1918
+
1919
+ let _themeRootSignal = null as Signal<string | null> | null
1920
+ function setupThemeSubscription(
1921
+ component: Component,
1922
+ dataSignal: Signal<ComponentData>,
1923
+ env: ToddleEnv,
1924
+ ) {
1925
+ _themeRootSignal?.destroy()
1926
+ _themeRootSignal = getThemeSignal(component, dataSignal, env)
1927
+ _themeRootSignal.subscribe((theme) => {
1928
+ if (isDefined(theme)) {
1929
+ document.documentElement.setAttribute(THEME_DATA_ATTRIBUTE, theme)
1930
+ } else {
1931
+ document.documentElement.removeAttribute(THEME_DATA_ATTRIBUTE)
1932
+ }
1933
+ dataSignal.update((data) => ({
1934
+ ...data,
1935
+ Page: {
1936
+ Theme: theme ?? null,
1937
+ },
1938
+ }))
1939
+ })
1940
+
1941
+ return _themeRootSignal
1942
+ }
package/src/page.main.ts CHANGED
@@ -6,6 +6,7 @@ import type {
6
6
  import type { ToddleEnv } from '@nordcraft/core/dist/formula/formula'
7
7
  import { applyFormula } from '@nordcraft/core/dist/formula/formula'
8
8
  import type { PluginFormula } from '@nordcraft/core/dist/formula/formulaTypes'
9
+ import { THEME_DATA_ATTRIBUTE } from '@nordcraft/core/dist/styling/theme.const'
9
10
  import type {
10
11
  ActionHandler,
11
12
  ArgumentInputDataFunction,
@@ -29,6 +30,7 @@ import { initLogState, registerComponentToLogState } from './debug/logState'
29
30
  import type { Signal } from './signal/signal'
30
31
  import { signal } from './signal/signal'
31
32
  import type { ComponentContext, LocationSignal } from './types'
33
+ import { getThemeSignal } from './utils/getThemeSignal'
32
34
 
33
35
  initLogState()
34
36
 
@@ -203,6 +205,9 @@ export const createRoot = (domNode: HTMLElement) => {
203
205
  children: {},
204
206
  formulaCache: {},
205
207
  providers: {},
208
+ stores: {
209
+ theme: getThemeSignal(component, dataSignal, env),
210
+ },
206
211
  apis: {},
207
212
  toddle: window.toddle,
208
213
  triggerEvent: (event: string, data: unknown) =>
@@ -265,6 +270,14 @@ export const createRoot = (domNode: HTMLElement) => {
265
270
  }
266
271
  }
267
272
 
273
+ ctx.stores.theme.subscribe((newTheme) => {
274
+ if (isDefined(newTheme)) {
275
+ document.documentElement.setAttribute(THEME_DATA_ATTRIBUTE, newTheme)
276
+ } else {
277
+ document.documentElement.removeAttribute(THEME_DATA_ATTRIBUTE)
278
+ }
279
+ })
280
+
268
281
  // We can only setup meta updates after the dataSignal has been initiated with API data etc.
269
282
  setupMetaUpdates(component, dataSignal)
270
283
 
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
+ import '../../happydom'
2
3
  import { CustomPropertyStyleSheet } from './CustomPropertyStyleSheet'
3
4
 
4
5
  describe('CustomPropertyStyleSheet', () => {
@@ -57,6 +58,51 @@ describe('CustomPropertyStyleSheet', () => {
57
58
  )
58
59
  })
59
60
 
61
+ test('it works with prefers-reduced-motion: reduce', () => {
62
+ const instance = new CustomPropertyStyleSheet(document)
63
+ instance.registerProperty('.my-class', '--my-property', {
64
+ mediaQuery: { 'prefers-reduced-motion': 'reduce' },
65
+ })('256px')
66
+ expect(instance.getStyleSheet().cssRules.length).toBe(1)
67
+ expect(instance.getStyleSheet().cssRules[0].cssText).toBe(
68
+ `\
69
+ @media (prefers-reduced-motion: reduce) {
70
+ .my-class { --my-property: 256px; }
71
+ }`,
72
+ )
73
+ })
74
+
75
+ test('it works with prefers-reduced-motion: no-preference', () => {
76
+ const instance = new CustomPropertyStyleSheet(document)
77
+ instance.registerProperty('.my-class', '--my-property', {
78
+ mediaQuery: { 'prefers-reduced-motion': 'no-preference' },
79
+ })('256px')
80
+ expect(instance.getStyleSheet().cssRules.length).toBe(1)
81
+ expect(instance.getStyleSheet().cssRules[0].cssText).toBe(
82
+ `\
83
+ @media (prefers-reduced-motion: no-preference) {
84
+ .my-class { --my-property: 256px; }
85
+ }`,
86
+ )
87
+ })
88
+
89
+ test('it combines prefers-reduced-motion with other media queries', () => {
90
+ const instance = new CustomPropertyStyleSheet(document)
91
+ instance.registerProperty('.my-class', '--my-property', {
92
+ mediaQuery: {
93
+ 'prefers-reduced-motion': 'reduce',
94
+ 'max-width': '768px',
95
+ },
96
+ })('256px')
97
+ expect(instance.getStyleSheet().cssRules.length).toBe(1)
98
+ expect(instance.getStyleSheet().cssRules[0].cssText).toBe(
99
+ `\
100
+ @media (prefers-reduced-motion: reduce) and (max-width: 768px) {
101
+ .my-class { --my-property: 256px; }
102
+ }`,
103
+ )
104
+ })
105
+
60
106
  test('it unregisters a property', () => {
61
107
  const instance = new CustomPropertyStyleSheet(document)
62
108
  const setter = instance.registerProperty('.my-class', '--my-property')
@@ -0,0 +1,214 @@
1
+ import type { Component } from '@nordcraft/core/dist/component/component.types'
2
+ import { describe, expect, test } from 'bun:test'
3
+ import { insertStyles } from './style'
4
+
5
+ describe('insertStyles() - prefers-reduced-motion', () => {
6
+ test('it inserts styles with prefers-reduced-motion: reduce media query', () => {
7
+ const component: Component = {
8
+ name: 'TestComponent',
9
+ nodes: {
10
+ '0': {
11
+ type: 'element',
12
+ tag: 'div',
13
+ style: {
14
+ color: 'red',
15
+ },
16
+ variants: [
17
+ {
18
+ style: {
19
+ transition: 'none',
20
+ animation: 'none',
21
+ },
22
+ mediaQuery: {
23
+ 'prefers-reduced-motion': 'reduce',
24
+ },
25
+ },
26
+ ],
27
+ children: [],
28
+ attrs: {},
29
+ events: {},
30
+ },
31
+ },
32
+ }
33
+
34
+ const parent = document.createElement('div')
35
+ insertStyles(parent, component, [])
36
+
37
+ const styleElement = parent.querySelector('[data-hash]')
38
+ expect(styleElement).toBeTruthy()
39
+
40
+ const styleText = styleElement?.textContent ?? ''
41
+
42
+ // Check that the media query for prefers-reduced-motion: reduce is present
43
+ expect(styleText).toContain('@media (prefers-reduced-motion: reduce)')
44
+
45
+ // Check that the variant styles are present
46
+ expect(styleText).toContain('transition:none')
47
+ expect(styleText).toContain('animation:none')
48
+ })
49
+
50
+ test('it inserts styles with prefers-reduced-motion: no-preference media query', () => {
51
+ const component: Component = {
52
+ name: 'TestComponent',
53
+ nodes: {
54
+ '0': {
55
+ type: 'element',
56
+ tag: 'div',
57
+ style: {},
58
+ variants: [
59
+ {
60
+ style: {
61
+ animation: 'fadeIn 1s',
62
+ },
63
+ mediaQuery: {
64
+ 'prefers-reduced-motion': 'no-preference',
65
+ },
66
+ },
67
+ ],
68
+ children: [],
69
+ attrs: {},
70
+ events: {},
71
+ },
72
+ },
73
+ }
74
+
75
+ const parent = document.createElement('div')
76
+ insertStyles(parent, component, [])
77
+
78
+ const styleElement = parent.querySelector('[data-hash]')
79
+ expect(styleElement).toBeTruthy()
80
+
81
+ const styleText = styleElement?.textContent ?? ''
82
+
83
+ // Check that the media query for prefers-reduced-motion: no-preference is present
84
+ expect(styleText).toContain(
85
+ '@media (prefers-reduced-motion: no-preference)',
86
+ )
87
+
88
+ // Check that the animation property is present
89
+ expect(styleText).toContain('animation:fadeIn 1s')
90
+ })
91
+
92
+ test('it combines prefers-reduced-motion with other media queries', () => {
93
+ const component: Component = {
94
+ name: 'TestComponent',
95
+ nodes: {
96
+ '0': {
97
+ type: 'element',
98
+ tag: 'div',
99
+ style: {},
100
+ variants: [
101
+ {
102
+ style: {
103
+ fontSize: '14px',
104
+ },
105
+ mediaQuery: {
106
+ 'prefers-reduced-motion': 'reduce',
107
+ 'max-width': '768px',
108
+ },
109
+ },
110
+ ],
111
+ children: [],
112
+ attrs: {},
113
+ events: {},
114
+ },
115
+ },
116
+ }
117
+
118
+ const parent = document.createElement('div')
119
+ insertStyles(parent, component, [])
120
+
121
+ const styleElement = parent.querySelector('[data-hash]')
122
+ expect(styleElement).toBeTruthy()
123
+
124
+ const styleText = styleElement?.textContent ?? ''
125
+
126
+ // Should combine media queries with 'and'
127
+ expect(styleText).toMatch(
128
+ /@media \(prefers-reduced-motion: reduce\) and \(max-width: 768px\)/,
129
+ )
130
+ })
131
+
132
+ test('it handles multiple variants with different motion preferences', () => {
133
+ const component: Component = {
134
+ name: 'TestComponent',
135
+ nodes: {
136
+ '0': {
137
+ type: 'element',
138
+ tag: 'div',
139
+ style: {},
140
+ variants: [
141
+ {
142
+ style: { animation: 'none' },
143
+ mediaQuery: { 'prefers-reduced-motion': 'reduce' },
144
+ },
145
+ {
146
+ style: { animation: 'fadeIn 1s' },
147
+ mediaQuery: { 'prefers-reduced-motion': 'no-preference' },
148
+ },
149
+ ],
150
+ children: [],
151
+ attrs: {},
152
+ events: {},
153
+ },
154
+ },
155
+ }
156
+
157
+ const parent = document.createElement('div')
158
+ insertStyles(parent, component, [])
159
+
160
+ const styleElement = parent.querySelector('[data-hash]')
161
+ expect(styleElement).toBeTruthy()
162
+
163
+ const styleText = styleElement?.textContent ?? ''
164
+
165
+ // Check that both media queries are present
166
+ expect(styleText).toContain('@media (prefers-reduced-motion: reduce)')
167
+ expect(styleText).toContain(
168
+ '@media (prefers-reduced-motion: no-preference)',
169
+ )
170
+
171
+ // Check that both animation values are present
172
+ expect(styleText).toContain('animation:none')
173
+ expect(styleText).toContain('animation:fadeIn 1s')
174
+ })
175
+
176
+ test('it filters out null prefers-reduced-motion values', () => {
177
+ const component: Component = {
178
+ name: 'TestComponent',
179
+ nodes: {
180
+ '0': {
181
+ type: 'element',
182
+ tag: 'div',
183
+ style: {},
184
+ variants: [
185
+ {
186
+ style: { color: 'red' },
187
+ mediaQuery: {
188
+ 'prefers-reduced-motion': null,
189
+ 'max-width': '768px',
190
+ },
191
+ },
192
+ ],
193
+ children: [],
194
+ attrs: {},
195
+ events: {},
196
+ },
197
+ },
198
+ }
199
+
200
+ const parent = document.createElement('div')
201
+ insertStyles(parent, component, [])
202
+
203
+ const styleElement = parent.querySelector('[data-hash]')
204
+ expect(styleElement).toBeTruthy()
205
+
206
+ const styleText = styleElement?.textContent ?? ''
207
+
208
+ // null values should be filtered out
209
+ expect(styleText).not.toContain('prefers-reduced-motion: null')
210
+
211
+ // max-width should still be present
212
+ expect(styleText).toContain('max-width: 768px')
213
+ })
214
+ })
@@ -11,6 +11,7 @@ import {
11
11
  import { kebabCase } from '@nordcraft/core/dist/styling/style.css'
12
12
  import { variantSelector } from '@nordcraft/core/dist/styling/variantSelector'
13
13
  import { omitKeys } from '@nordcraft/core/dist/utils/collections'
14
+ import { isDefined } from '@nordcraft/core/dist/utils/util'
14
15
 
15
16
  const LEGACY_BREAKPOINTS = {
16
17
  large: 1440,
@@ -89,8 +90,8 @@ ${
89
90
  return variant.mediaQuery
90
91
  ? `
91
92
  @media (${Object.entries(variant.mediaQuery)
93
+ .filter(([_, value]) => isDefined(value))
92
94
  .map(([key, value]) => `${key}: ${value}`)
93
- .filter(Boolean)
94
95
  .join(') and (')}) {
95
96
  ${renderedVariant}
96
97
  }
package/src/types.d.ts CHANGED
@@ -80,6 +80,9 @@ export interface ComponentContext {
80
80
  ctx: ComponentContext
81
81
  }
82
82
  >
83
+ stores: {
84
+ theme: Signal<string | null>
85
+ }
83
86
  toddle: Toddle<LocationSignal, PreviewShowSignal>
84
87
  env: ToddleEnv
85
88
  }
@@ -0,0 +1,66 @@
1
+ import type {
2
+ Component,
3
+ ComponentData,
4
+ } from '@nordcraft/core/dist/component/component.types'
5
+ import {
6
+ applyFormula,
7
+ type ToddleEnv,
8
+ } from '@nordcraft/core/dist/formula/formula'
9
+ import { THEME_COOKIE_NAME } from '@nordcraft/core/dist/styling/theme.const'
10
+ import { isDefined } from '@nordcraft/core/dist/utils/util'
11
+ import { signal, type Signal } from '../signal/signal'
12
+
13
+ export const getThemeSignal = (
14
+ component: Component,
15
+ dataSignal: Signal<ComponentData>,
16
+ env: ToddleEnv,
17
+ ) => {
18
+ const theme = component.route?.info?.theme
19
+ const themeFormula = theme?.formula
20
+ const dynamicTheme = themeFormula && themeFormula.type !== 'value'
21
+ if (dynamicTheme) {
22
+ const sig = dataSignal.map<string | null>(() =>
23
+ applyFormula(themeFormula, {
24
+ data: dataSignal.get(),
25
+ component,
26
+ root: document,
27
+ package: undefined,
28
+ toddle: window.toddle,
29
+ env,
30
+ }),
31
+ )
32
+
33
+ return sig
34
+ } else if (isDefined(themeFormula)) {
35
+ // Set static theme value
36
+ return signal<string | null>(themeFormula.value as string | null)
37
+ } else {
38
+ // This is the standard theme resolution logic, if not overridden:
39
+ // 1. Check for 'nc-theme' cookie
40
+ // 2. Default to null
41
+ // 2.1 No theme set explicitly will default to system preference
42
+ // 2.2 Default theme (or initial value) is handled in CSS
43
+ const initialThemeValue =
44
+ document.cookie
45
+ .split('; ')
46
+ .find((row) => row.startsWith(`${THEME_COOKIE_NAME}=`))
47
+ ?.split('=')[1] ?? null
48
+
49
+ const sig = signal<string | null>(initialThemeValue as string | null)
50
+ // Listen to cookie store API changes for 'nc-theme'
51
+ cookieStore.addEventListener('change', (event) => {
52
+ for (const change of event.changed) {
53
+ if (change.name === THEME_COOKIE_NAME) {
54
+ sig.set(change.value ?? null)
55
+ }
56
+ }
57
+ for (const removal of event.deleted) {
58
+ if (removal.name === THEME_COOKIE_NAME) {
59
+ sig.set(null)
60
+ }
61
+ }
62
+ })
63
+
64
+ return sig
65
+ }
66
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"apiUtils.js","sourceRoot":"","sources":["../../src/api/apiUtils.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAe,EAAuB,EAAE,CACrE,gBAAgB,IAAI,GAAG,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"createAPI.js","sourceRoot":"","sources":["../../src/api/createAPI.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AAErE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAA;AAE9E,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAA;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAYrD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAuB,EACvB,GAAqB,EACrB;IACA,IAAI,KAAK,GAAQ,IAAI,CAAA;IAErB,kDAAkD;IAClD,qHAAqH;IACrH,SAAS,gBAAgB,CACvB,GAAuB,EACvB,IAAmB,EACP;QACZ,MAAM,cAAc,GAAG;YACrB,IAAI;YACJ,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,YAAY,EAAE,GAAG,CAAC,YAAY;YAC9B,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,EAAE,GAAG,CAAC,GAAG;SACb,CAAA;QAED,oBAAoB;QACpB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,EAAE,CAAA;QAC3D,MAAM,OAAO,GACX,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;YAC7B,CAAC,CAAC,GAAG;gBACH,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YACxE,CAAC,CAAC,EAAE,CAAA;QAER,oBAAoB;QACpB,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAA;QACxD,MAAM,WAAW,GACf,WAAW,CAAC,MAAM,GAAG,CAAC;YACpB,CAAC,CAAC,GAAG;gBACH,WAAW;qBACR,GAAG,CACF,CAAC,KAAK,EAAE,EAAE,CACR,GAAG,KAAK,CAAC,IAAI,IAAI,kBAAkB,CACjC,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAC5C,EAAE,CACN;qBACA,IAAI,CAAC,GAAG,CAAC;YACd,CAAC,CAAC,EAAE,CAAA;QACR,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,uHAAuH;YAC5J,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE;gBACxB,IAAI;gBACJ,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,EAAE,GAAG,CAAC,GAAG;aACb,CAAC;YACJ,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CACrC,YAAY,CAAC,KAAK,EAAE;gBAClB,IAAI;gBACJ,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,EAAE,GAAG,CAAC,GAAG;aACb,CAAC,CACH,CAAA;QACL,MAAM,WAAW,GAAG,MAAM,CACxB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAC1B,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,iBAAiB,EAAE,KAAK,cAAc,CACtD,EAAE,CAAC,CAAC,CAAC,CACP,CAAA;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,KAAK,CAAA;QAClC,MAAM,IAAI,GACR,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC7D,CAAC,CAAC,UAAU,CACR,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE;gBACrB,IAAI;gBACJ,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,EAAE,GAAG,CAAC,GAAG;aACb,CAAC,EACF,WAAW,CACZ;YACH,CAAC,CAAC,SAAS,CAAA;QACf,OAAO;YACL,GAAG,EAAE,OAAO,GAAG,OAAO,GAAG,WAAW;YACpC,MAAM;YACN,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO;YACP,IAAI;SACL,CAAA;IAAA,CACF;IAED,4BAA4B;IAC5B,KAAK,UAAU,OAAO,CAAC,GAAa,EAAE;QACpC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;QACjC,IAAI,CAAC;YACH,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAA;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAA;QACjB,CAAC;IAAA,CACF;IAED,SAAS,UAAU,CAAC,IAAS,EAAE,WAAoB,EAAqB;QACtE,QAAQ,WAAW,EAAE,CAAC;YACpB,KAAK,mCAAmC,EAAE,CAAC;gBACzC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;oBAC9C,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;yBACxB,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;wBACrB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;4BACzB,OAAO,KAAK;iCACT,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,EAAE,CACxD;iCACA,IAAI,CAAC,GAAG,CAAC,CAAA;wBACd,CAAC;6BAAM,CAAC;4BACN,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,kBAAkB,CACrD,MAAM,CAAC,KAAK,CAAC,CACd,EAAE,CAAA;wBACL,CAAC;oBAAA,CACF,CAAC;yBACD,IAAI,CAAC,GAAG,CAAC,CAAA;gBACd,CAAC;gBACD,OAAO,EAAE,CAAA;YACX,CAAC;YACD,KAAK,qBAAqB,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAA;gBAC/B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;oBAC9C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;wBAC7C,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAsB,CAAC,CAAA;oBAAA,CAC1C,CAAC,CAAA;gBACJ,CAAC;gBACD,OAAO,QAAQ,CAAA;YACjB,CAAC;YACD,KAAK,YAAY;gBACf,OAAO,MAAM,CAAC,IAAI,CAAC,CAAA;YACrB;gBACE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAC/B,CAAC;IAAA,CACF;IAED,SAAS,UAAU,CAAC,IAAS,EAAE;QAC7B,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YACjB,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE;YACvB,IAAI,EAAE;gBACJ,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI;gBAC5B,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;oBACV,IAAI;oBACJ,KAAK,EAAE,IAAI;oBACX,SAAS,EAAE,KAAK;iBACjB;aACF;SACF,CAAC,CAAA;QACF,GAAG,CAAC,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5C,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAA;QAAA,CAChD,CAAC,CAAA;IAAA,CACH;IAED,SAAS,QAAQ,CAAC,KAAU,EAAE;QAC5B,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YACjB,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE;YACvB,IAAI,EAAE;gBACJ,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI;gBAC5B,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;oBACV,IAAI,EAAE,IAAI;oBACV,SAAS,EAAE,KAAK;oBAChB,KAAK,EAAE,KAAK;iBACb;aACF;SACF,CAAC,CAAA;QACF,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAA;QAAA,CAChD,CAAC,CAAA;IAAA,CACH;IAED,oDAAoD;IACpD,KAAK,UAAU,OAAO,CAAC,OAAmB,EAAE;QAC1C,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YACjB,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE;YACvB,IAAI,EAAE;gBACJ,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI;gBAC5B,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;oBACV,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,IAAI;oBACzD,SAAS,EAAE,IAAI;oBACf,KAAK,EAAE,IAAI;iBACZ;aACF;SACF,CAAC,CAAA;QACF,IAAI,QAAQ,CAAA;QAEZ,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;gBACxB,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;oBAClC,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,IAAI,EAAE,OAAO,CAAC,IAAI;iBACnB,CAAC,CAAA;YACJ,CAAC;iBAAM,CAAC;gBACN,QAAQ,GAAG,MAAM,KAAK,CACpB,WAAW,kBAAkB,CAC3B,GAAG,CAAC,SAAS,CAAC,IAAI,CACnB,IAAI,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EACnC;oBACE,MAAM,EAAE,MAAM;oBACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;oBAC7B,MAAM,EAAE,GAAG,CAAC,WAAW;oBACvB,OAAO,EAAE;wBACP,cAAc,EAAE,kBAAkB;qBACnC;iBACF,CACF,CAAA;YACH,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAA;YACpC,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAChB,UAAU,CAAC,IAAI,CAAC,CAAA;YAClB,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAA;YACZ,CAAC;QACH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,QAAQ,CAAC,KAAK,CAAC,CAAA;YACf,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9B,CAAC;IAAA,CACF;IAED,wCAAwC;IACxC,SAAS,OAAO,CAAC,IAAgB,EAAE;QACjC,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACrC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;gBACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC9B,YAAY,CAAC,KAAK,CAAC,CAAA;gBACrB,CAAC;gBACD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;oBACvB,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;gBAAA,CACpC,EAAE,GAAG,CAAC,QAAkB,CAAC,CAAA;YAAA,CAC3B,CAAC,CAAA;QACJ,CAAC;aAAM,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAAC,CAAA;YAC9B,CAAC;YACD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;gBACvB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC9B,YAAY,CAAC,KAAK,CAAC,CAAA;gBACrB,CAAC;YAAA,CACF,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAA;YAChB,OAAO,OAAO,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;aAAM,CAAC;YACN,OAAO,OAAO,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;IAAA,CACF;IAED,IAAI,aAA6C,CAAA;IACjD,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9B,OAAO;YACL,GAAG,IAAI;YACP,IAAI,EAAE;gBACJ,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;gBACpB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI;oBACnC,IAAI,EAAE,IAAI;oBACV,SAAS,EACP,GAAG,CAAC,SAAS;wBACb,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE;4BAC1B,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE;4BAC1B,SAAS,EAAE,GAAG,CAAC,SAAS;4BACxB,YAAY,EAAE,GAAG,CAAC,YAAY;4BAC9B,IAAI,EAAE,GAAG,CAAC,IAAI;4BACd,OAAO,EAAE,GAAG,CAAC,OAAO;4BACpB,MAAM,EAAE,GAAG,CAAC,MAAM;4BAClB,GAAG,EAAE,GAAG,CAAC,GAAG;yBACb,CAAC;wBACA,CAAC,CAAC,IAAI;wBACN,CAAC,CAAC,KAAK;oBACX,KAAK,EAAE,IAAI;iBACZ;aACF;SACF,CAAA;IAAA,CACF,CAAC,CAAA;IACF,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,aAAa,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;QACzE,IAAI,QAAQ,GAAG,IAAI,CAAA;QACnB,aAAa,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAChC,IACE,GAAG,CAAC,SAAS;gBACb,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE;oBAC1B,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE;oBAC1B,SAAS,EAAE,GAAG,CAAC,SAAS;oBACxB,YAAY,EAAE,GAAG,CAAC,YAAY;oBAC9B,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,GAAG,EAAE,GAAG,CAAC,GAAG;iBACb,CAAC,EACF,CAAC;gBACD,oDAAoD;gBACpD,oDAAoD;gBACpD,IAAI,QAAQ,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;oBACpC,QAAQ,GAAG,KAAK,CAAA;oBAChB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;oBACtD,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;wBAC1B,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;4BACpC,4CAA4C;4BAC5C,mCAAmC;4BACnC,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;wBAC5C,CAAC;6BAAM,CAAC;4BACN,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;wBACzB,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,IAAI,CAAC,CAAA;oBACf,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,CAAA;gBACf,CAAC;YACH,CAAC;QAAA,CACF,CAAC,CAAA;IACJ,CAAC;IACD,OAAO;QACL,KAAK,EAAE,CAAC,OAAoB,EAAE,EAAE,CAAC;YAC/B,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAA;YAC9D,IAAI,IAAI,GAAG,UAAU,CAAC,IAAI,CAAA;YAC1B,mDAAmD;YACnD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;gBAC1B,GAAG,UAAU,CAAC,OAAO;gBACrB,GAAG,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;aAC5B,CAAC,CAAA;YACF,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;gBAClB,IAAI,GAAG,UAAU,CACf,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CACzC,CAAA;YACH,CAAC;YACD,IAAI,IAAI,YAAY,QAAQ,EAAE,CAAC;gBAC7B,0DAA0D;gBAC1D,8DAA8D;gBAC9D,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;YAChC,CAAC;YACD,MAAM,OAAO,GAAe;gBAC1B,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,UAAU,CAAC,GAAG;gBACnC,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,UAAU,CAAC,MAAM;gBAC5C,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,UAAU,CAAC,IAAI;gBACtC,OAAO,EAAE,kBAAkB,CAAC,OAAO,CAAC;gBACpC,IAAI;aACL,CAAA;YACD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAA;QAAA,CACxB;QACD,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE,OAAO,EAAE;KACxC,CAAA;AAAA,CACF"}