@f-ewald/components 0.7.0 → 1.0.2

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 (193) hide show
  1. package/README.md +76 -47
  2. package/custom-elements.json +3049 -910
  3. package/dist/address-autocomplete.d.ts +8 -0
  4. package/dist/address-autocomplete.d.ts.map +1 -1
  5. package/dist/address-autocomplete.js +165 -15
  6. package/dist/address-autocomplete.js.map +1 -1
  7. package/dist/animate-confetti.d.ts +8 -5
  8. package/dist/animate-confetti.d.ts.map +1 -1
  9. package/dist/animate-confetti.js +46 -19
  10. package/dist/animate-confetti.js.map +1 -1
  11. package/dist/autocomplete-input.d.ts +8 -0
  12. package/dist/autocomplete-input.d.ts.map +1 -1
  13. package/dist/autocomplete-input.js +165 -15
  14. package/dist/autocomplete-input.js.map +1 -1
  15. package/dist/calendar-entry.d.ts +33 -0
  16. package/dist/calendar-entry.d.ts.map +1 -0
  17. package/dist/calendar-entry.js +64 -0
  18. package/dist/calendar-entry.js.map +1 -0
  19. package/dist/calendar-month.d.ts +67 -0
  20. package/dist/calendar-month.d.ts.map +1 -0
  21. package/dist/calendar-month.js +469 -0
  22. package/dist/calendar-month.js.map +1 -0
  23. package/dist/calendar-year.d.ts +43 -0
  24. package/dist/calendar-year.d.ts.map +1 -0
  25. package/dist/calendar-year.js +145 -0
  26. package/dist/calendar-year.js.map +1 -0
  27. package/dist/chat-message.d.ts.map +1 -1
  28. package/dist/chat-message.js +77 -24
  29. package/dist/chat-message.js.map +1 -1
  30. package/dist/confirm-dialog.d.ts +8 -1
  31. package/dist/confirm-dialog.d.ts.map +1 -1
  32. package/dist/confirm-dialog.js +130 -18
  33. package/dist/confirm-dialog.js.map +1 -1
  34. package/dist/copy-link-button.d.ts +2 -0
  35. package/dist/copy-link-button.d.ts.map +1 -1
  36. package/dist/copy-link-button.js +35 -3
  37. package/dist/copy-link-button.js.map +1 -1
  38. package/dist/data-table.d.ts +2 -0
  39. package/dist/data-table.d.ts.map +1 -1
  40. package/dist/data-table.js +83 -11
  41. package/dist/data-table.js.map +1 -1
  42. package/dist/distance-value.d.ts +0 -1
  43. package/dist/distance-value.d.ts.map +1 -1
  44. package/dist/distance-value.js +3 -8
  45. package/dist/distance-value.js.map +1 -1
  46. package/dist/distribution-chart.d.ts.map +1 -1
  47. package/dist/distribution-chart.js +54 -17
  48. package/dist/distribution-chart.js.map +1 -1
  49. package/dist/dropdown-button.d.ts.map +1 -1
  50. package/dist/dropdown-button.js +60 -11
  51. package/dist/dropdown-button.js.map +1 -1
  52. package/dist/editable-text.d.ts.map +1 -1
  53. package/dist/editable-text.js +46 -13
  54. package/dist/editable-text.js.map +1 -1
  55. package/dist/form-select.d.ts +21 -2
  56. package/dist/form-select.d.ts.map +1 -1
  57. package/dist/form-select.js +489 -37
  58. package/dist/form-select.js.map +1 -1
  59. package/dist/frame-box.d.ts.map +1 -1
  60. package/dist/frame-box.js +20 -12
  61. package/dist/frame-box.js.map +1 -1
  62. package/dist/icon-button.d.ts.map +1 -1
  63. package/dist/icon-button.js +11 -0
  64. package/dist/icon-button.js.map +1 -1
  65. package/dist/index.d.ts +4 -1
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +4 -1
  68. package/dist/index.js.map +1 -1
  69. package/dist/kbd-hint.d.ts +30 -0
  70. package/dist/kbd-hint.d.ts.map +1 -0
  71. package/dist/kbd-hint.js +184 -0
  72. package/dist/kbd-hint.js.map +1 -0
  73. package/dist/live-timer.d.ts +0 -1
  74. package/dist/live-timer.d.ts.map +1 -1
  75. package/dist/live-timer.js +1 -6
  76. package/dist/live-timer.js.map +1 -1
  77. package/dist/map-circle.d.ts +3 -0
  78. package/dist/map-circle.d.ts.map +1 -1
  79. package/dist/map-circle.js +19 -1
  80. package/dist/map-circle.js.map +1 -1
  81. package/dist/map-pin.d.ts.map +1 -1
  82. package/dist/map-pin.js +16 -1
  83. package/dist/map-pin.js.map +1 -1
  84. package/dist/percent-bar-chart.d.ts +3 -0
  85. package/dist/percent-bar-chart.d.ts.map +1 -1
  86. package/dist/percent-bar-chart.js +60 -4
  87. package/dist/percent-bar-chart.js.map +1 -1
  88. package/dist/photo-gallery.d.ts.map +1 -1
  89. package/dist/photo-gallery.js +12 -3
  90. package/dist/photo-gallery.js.map +1 -1
  91. package/dist/popover-panel.d.ts.map +1 -1
  92. package/dist/popover-panel.js +132 -23
  93. package/dist/popover-panel.js.map +1 -1
  94. package/dist/price-history-chart.d.ts.map +1 -1
  95. package/dist/price-history-chart.js +52 -18
  96. package/dist/price-history-chart.js.map +1 -1
  97. package/dist/radio-cards.d.ts +2 -0
  98. package/dist/radio-cards.d.ts.map +1 -1
  99. package/dist/radio-cards.js +51 -5
  100. package/dist/radio-cards.js.map +1 -1
  101. package/dist/radio-pills.d.ts +2 -0
  102. package/dist/radio-pills.d.ts.map +1 -1
  103. package/dist/radio-pills.js +46 -4
  104. package/dist/radio-pills.js.map +1 -1
  105. package/dist/relative-time.d.ts +0 -1
  106. package/dist/relative-time.d.ts.map +1 -1
  107. package/dist/relative-time.js +1 -6
  108. package/dist/relative-time.js.map +1 -1
  109. package/dist/reveal-button.d.ts +2 -0
  110. package/dist/reveal-button.d.ts.map +1 -1
  111. package/dist/reveal-button.js +42 -5
  112. package/dist/reveal-button.js.map +1 -1
  113. package/dist/roman-numeral.js +1 -1
  114. package/dist/roman-numeral.js.map +1 -1
  115. package/dist/slide-panel.d.ts +7 -3
  116. package/dist/slide-panel.d.ts.map +1 -1
  117. package/dist/slide-panel.js +95 -23
  118. package/dist/slide-panel.js.map +1 -1
  119. package/dist/stat-meter.d.ts.map +1 -1
  120. package/dist/stat-meter.js +17 -7
  121. package/dist/stat-meter.js.map +1 -1
  122. package/dist/status-pill.d.ts.map +1 -1
  123. package/dist/status-pill.js +26 -12
  124. package/dist/status-pill.js.map +1 -1
  125. package/dist/tile-grid.d.ts +8 -0
  126. package/dist/tile-grid.d.ts.map +1 -1
  127. package/dist/tile-grid.js +88 -12
  128. package/dist/tile-grid.js.map +1 -1
  129. package/dist/toast-notification.d.ts.map +1 -1
  130. package/dist/toast-notification.js +40 -11
  131. package/dist/toast-notification.js.map +1 -1
  132. package/dist/tokens.css +23 -0
  133. package/dist/tokens.d.ts.map +1 -1
  134. package/dist/tokens.js +16 -0
  135. package/dist/tokens.js.map +1 -1
  136. package/dist/ui-button.d.ts +2 -0
  137. package/dist/ui-button.d.ts.map +1 -1
  138. package/dist/ui-button.js +58 -9
  139. package/dist/ui-button.js.map +1 -1
  140. package/dist/user-avatar.d.ts.map +1 -1
  141. package/dist/user-avatar.js +18 -3
  142. package/dist/user-avatar.js.map +1 -1
  143. package/dist/utils/calendar.d.ts +77 -0
  144. package/dist/utils/calendar.d.ts.map +1 -0
  145. package/dist/utils/calendar.js +135 -0
  146. package/dist/utils/calendar.js.map +1 -0
  147. package/dist/utils/form.d.ts +3 -0
  148. package/dist/utils/form.d.ts.map +1 -0
  149. package/dist/utils/form.js +14 -0
  150. package/dist/utils/form.js.map +1 -0
  151. package/dist/utils/layer-stack.d.ts +9 -0
  152. package/dist/utils/layer-stack.d.ts.map +1 -0
  153. package/dist/utils/layer-stack.js +35 -0
  154. package/dist/utils/layer-stack.js.map +1 -0
  155. package/dist/weight-bar-chart.d.ts.map +1 -1
  156. package/dist/weight-bar-chart.js +27 -8
  157. package/dist/weight-bar-chart.js.map +1 -1
  158. package/docs/address-autocomplete.md +5 -0
  159. package/docs/autocomplete-input.md +5 -0
  160. package/docs/calendar-entry.md +53 -0
  161. package/docs/calendar-month.md +79 -0
  162. package/docs/calendar-year.md +53 -0
  163. package/docs/chat-message.md +4 -0
  164. package/docs/confirm-dialog.md +2 -0
  165. package/docs/copy-link-button.md +2 -0
  166. package/docs/data-table.md +2 -0
  167. package/docs/design-language.md +149 -0
  168. package/docs/distribution-chart.md +4 -0
  169. package/docs/dropdown-button.md +1 -0
  170. package/docs/form-select.md +15 -3
  171. package/docs/frame-box.md +2 -0
  172. package/docs/kbd-hint.md +42 -0
  173. package/docs/map-circle.md +4 -0
  174. package/docs/percent-bar-chart.md +4 -1
  175. package/docs/photo-gallery.md +1 -0
  176. package/docs/popover-panel.md +2 -0
  177. package/docs/price-history-chart.md +8 -1
  178. package/docs/radio-cards.md +2 -0
  179. package/docs/radio-pills.md +2 -0
  180. package/docs/reveal-button.md +3 -0
  181. package/docs/slide-panel.md +4 -2
  182. package/docs/status-pill.md +3 -0
  183. package/docs/tile-grid.md +10 -1
  184. package/docs/toast-notification.md +4 -1
  185. package/docs/ui-button.md +2 -0
  186. package/docs/user-avatar.md +1 -0
  187. package/llms.txt +175 -61
  188. package/package.json +14 -2
  189. package/dist/map-point.d.ts +0 -31
  190. package/dist/map-point.d.ts.map +0 -1
  191. package/dist/map-point.js +0 -83
  192. package/dist/map-point.js.map +0 -1
  193. package/docs/map-point.md +0 -44
@@ -1 +1 @@
1
- {"version":3,"file":"live-timer.js","sourceRoot":"","sources":["../src/live-timer.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAuB,MAAM,qBAAqB,CAAC;AAE1E,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B;;;;;;GAMG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QAOL,kEAAkE;QACtD,UAAK,GAAkB,IAAI,CAAC;QACxC,6FAA6F;QACjF,WAAM,GAAmB,SAAS,CAAC;QAC/C,gDAAgD;QAC3B,WAAM,GAAG,EAAE,CAAC;QACjC,+CAA+C;QACnC,WAAM,GAAG,EAAE,CAAC;QAEP,SAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE3B,WAAM,GAA0C,IAAI,CAAC;IAsB/D,CAAC;aAvCiB,WAAM,GAAG,GAAG,CAAA;;;;GAI3B,AAJqB,CAIpB;IAeO,iBAAiB;QACxB,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,CAAC,EAAE,gBAAgB,CAAC,CAAC;IACvB,CAAC;IAEQ,oBAAoB;QAC3B,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI;YAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAEQ,MAAM;QACb,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IACnF,CAAC;CACF,CAAA;AAhCa;IAAX,QAAQ,EAAE;wCAA6B;AAE5B;IAAX,QAAQ,EAAE;yCAAoC;AAE1B;IAApB,QAAQ,EAAE;yCAAsB;AAErB;IAAX,QAAQ,EAAE;yCAAa;AAEP;IAAhB,KAAK,EAAE;uCAA2B;AAhBxB,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CAwCrB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { formatDuration, type DurationFormat } from \"./utils/duration.js\";\n\nconst TICK_INTERVAL_MS = 1000;\n\n/**\n * Per-second ticking count-up timer, e.g. a live \"running for 12s\" or\n * \"Sleeping for 3 seconds\" indicator. Renders nothing while `since` is unset\n * or unparseable.\n *\n * @element live-timer\n */\n@customElement(\"live-timer\")\nexport class LiveTimer extends LitElement {\n static override styles = css`\n :host {\n display: inline;\n }\n `;\n\n /** ISO-8601 start instant; elapsed time is measured from here. */\n @property() since: string | null = null;\n /** `\"seconds\"` -> \"1 second\", \"12 seconds\"; `\"compact\"` -> \"12s\", \"3m 12s\", \"1h 03m 12s\". */\n @property() format: DurationFormat = \"seconds\";\n /** Text rendered before the formatted value. */\n @property() override prefix = \"\";\n /** Text rendered after the formatted value. */\n @property() suffix = \"\";\n\n @state() private _now = Date.now();\n\n private _timer: ReturnType<typeof setInterval> | null = null;\n\n override connectedCallback() {\n super.connectedCallback();\n this._timer = setInterval(() => {\n this._now = Date.now();\n }, TICK_INTERVAL_MS);\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (this._timer != null) clearInterval(this._timer);\n this._timer = null;\n }\n\n override render() {\n if (!this.since) return html``;\n const start = Date.parse(this.since);\n if (Number.isNaN(start)) return html``;\n const elapsed = Math.max(0, this._now - start);\n return html`${this.prefix}${formatDuration(elapsed, this.format)}${this.suffix}`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"live-timer\": LiveTimer;\n }\n}\n"]}
1
+ {"version":3,"file":"live-timer.js","sourceRoot":"","sources":["../src/live-timer.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAuB,MAAM,qBAAqB,CAAC;AAE1E,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B;;;;;;GAMG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QACL,kEAAkE;QACtD,UAAK,GAAkB,IAAI,CAAC;QACxC,6FAA6F;QACjF,WAAM,GAAmB,SAAS,CAAC;QAC/C,gDAAgD;QAC3B,WAAM,GAAG,EAAE,CAAC;QACjC,+CAA+C;QACnC,WAAM,GAAG,EAAE,CAAC;QAEP,SAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE3B,WAAM,GAA0C,IAAI,CAAC;IAsB/D,CAAC;IApBU,iBAAiB;QACxB,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,CAAC,EAAE,gBAAgB,CAAC,CAAC;IACvB,CAAC;IAEQ,oBAAoB;QAC3B,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI;YAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAEQ,MAAM;QACb,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IACnF,CAAC;CACF,CAAA;AAhCa;IAAX,QAAQ,EAAE;wCAA6B;AAE5B;IAAX,QAAQ,EAAE;yCAAoC;AAE1B;IAApB,QAAQ,EAAE;yCAAsB;AAErB;IAAX,QAAQ,EAAE;yCAAa;AAEP;IAAhB,KAAK,EAAE;uCAA2B;AAVxB,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CAkCrB","sourcesContent":["import { LitElement, html } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { formatDuration, type DurationFormat } from \"./utils/duration.js\";\n\nconst TICK_INTERVAL_MS = 1000;\n\n/**\n * Per-second ticking count-up timer, e.g. a live \"running for 12s\" or\n * \"Sleeping for 3 seconds\" indicator. Renders nothing while `since` is unset\n * or unparseable.\n *\n * @element live-timer\n */\n@customElement(\"live-timer\")\nexport class LiveTimer extends LitElement {\n /** ISO-8601 start instant; elapsed time is measured from here. */\n @property() since: string | null = null;\n /** `\"seconds\"` -> \"1 second\", \"12 seconds\"; `\"compact\"` -> \"12s\", \"3m 12s\", \"1h 03m 12s\". */\n @property() format: DurationFormat = \"seconds\";\n /** Text rendered before the formatted value. */\n @property() override prefix = \"\";\n /** Text rendered after the formatted value. */\n @property() suffix = \"\";\n\n @state() private _now = Date.now();\n\n private _timer: ReturnType<typeof setInterval> | null = null;\n\n override connectedCallback() {\n super.connectedCallback();\n this._timer = setInterval(() => {\n this._now = Date.now();\n }, TICK_INTERVAL_MS);\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (this._timer != null) clearInterval(this._timer);\n this._timer = null;\n }\n\n override render() {\n if (!this.since) return html``;\n const start = Date.parse(this.since);\n if (Number.isNaN(start)) return html``;\n const elapsed = Math.max(0, this._now - start);\n return html`${this.prefix}${formatDuration(elapsed, this.format)}${this.suffix}`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"live-timer\": LiveTimer;\n }\n}\n"]}
@@ -5,6 +5,9 @@ import { LitElement } from "lit";
5
5
  * need to visually "point" at their exact coordinate. Purely a visual
6
6
  * primitive — it has no `mapbox-gl` (or any mapping library) dependency;
7
7
  * the consumer positions it, e.g. via `new mapboxgl.Marker({ element: el })`.
8
+ * It can also replace the former `<map-point>` dense-layer primitive: use
9
+ * `size="14" ring-width="3"`, leave the slot empty, and rasterize one marker
10
+ * per color for use as a map `icon-image`.
8
11
  *
9
12
  * @element map-circle
10
13
  * @slot - Optional badge content shown centered on the circle — a rank
@@ -1 +1 @@
1
- {"version":3,"file":"map-circle.d.ts","sourceRoot":"","sources":["../src/map-circle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C;;;;;;;;;;GAUG;AACH,qBACa,SAAU,SAAQ,UAAU;IACvC,OAAgB,MAAM,4BA8BpB;IAEF,4FAA4F;IAChF,KAAK,SAAa;IAC9B,+BAA+B;IACH,IAAI,SAAM;IACtC,wFAAwF;IACnC,SAAS,SAAK;IACnE,sFAAsF;IAC1C,WAAW,UAAS;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IAE3D,MAAM,yCAuBd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
1
+ {"version":3,"file":"map-circle.d.ts","sourceRoot":"","sources":["../src/map-circle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C;;;;;;;;;;;;;GAaG;AACH,qBACa,SAAU,SAAQ,UAAU;IACvC,OAAgB,MAAM,4BA4CpB;IAEF,4FAA4F;IAChF,KAAK,SAAa;IAC9B,+BAA+B;IACH,IAAI,SAAM;IACtC,wFAAwF;IACnC,SAAS,SAAK;IACnE,sFAAsF;IAC1C,WAAW,UAAS;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IAE3D,MAAM,yCAwBd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
@@ -15,6 +15,9 @@ let gradientIdCounter = 0;
15
15
  * need to visually "point" at their exact coordinate. Purely a visual
16
16
  * primitive — it has no `mapbox-gl` (or any mapping library) dependency;
17
17
  * the consumer positions it, e.g. via `new mapboxgl.Marker({ element: el })`.
18
+ * It can also replace the former `<map-point>` dense-layer primitive: use
19
+ * `size="14" ring-width="3"`, leave the slot empty, and rasterize one marker
20
+ * per color for use as a map `icon-image`.
18
21
  *
19
22
  * @element map-circle
20
23
  * @slot - Optional badge content shown centered on the circle — a rank
@@ -55,13 +58,27 @@ let MapCircle = class MapCircle extends LitElement {
55
58
  left: 50%;
56
59
  transform: translate(-50%, -50%);
57
60
  color: #fff;
58
- font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);
61
+ font-family: var(
62
+ --ui-font,
63
+ ui-sans-serif,
64
+ system-ui,
65
+ sans-serif,
66
+ "Apple Color Emoji",
67
+ "Segoe UI Emoji",
68
+ "Segoe UI Symbol",
69
+ "Noto Color Emoji"
70
+ );
59
71
  font-weight: 700;
60
72
  line-height: 1;
61
73
  text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);
62
74
  pointer-events: none;
63
75
  white-space: nowrap;
64
76
  }
77
+ @media (prefers-reduced-motion: reduce) {
78
+ svg {
79
+ transition: none;
80
+ }
81
+ }
65
82
  `,
66
83
  ]; }
67
84
  render() {
@@ -69,6 +86,7 @@ let MapCircle = class MapCircle extends LitElement {
69
86
  const dark = mixHex(this.color, "#000000", 30);
70
87
  return html `
71
88
  <svg
89
+ aria-hidden="true"
72
90
  width=${this.size}
73
91
  height=${this.size}
74
92
  viewBox="0 0 32 32"
@@ -1 +1 @@
1
- {"version":3,"file":"map-circle.js","sourceRoot":"","sources":["../src/map-circle.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;;GAUG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QAiCL,4FAA4F;QAChF,UAAK,GAAG,SAAS,CAAC;QAC9B,+BAA+B;QACH,SAAI,GAAG,EAAE,CAAC;QACtC,wFAAwF;QACnC,cAAS,GAAG,CAAC,CAAC;QACnE,sFAAsF;QAC1C,gBAAW,GAAG,KAAK,CAAC;QAE/C,YAAO,GAAG,mBAAmB,iBAAiB,EAAE,EAAE,CAAC;IA0BtE,CAAC;aAnEiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BF;KACF,AA9BqB,CA8BpB;IAaO,MAAM;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAA;;gBAEC,IAAI,CAAC,IAAI;iBACR,IAAI,CAAC,IAAI;;;;;;+BAMK,IAAI,CAAC,OAAO;2CACA,KAAK;6CACH,IAAI;;;oDAGG,IAAI,CAAC,OAAO,oCAAoC,IAAI,CAAC,SAAS;;8CAEpE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;;;KAGpE,CAAC;IACJ,CAAC;CACF,CAAA;AAlCa;IAAX,QAAQ,EAAE;wCAAmB;AAEF;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uCAAW;AAEe;IAApD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;4CAAe;AAEvB;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;8CAAqB;AAxCrD,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CAoErB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\nimport { mixHex } from \"./utils/color.js\";\n\nlet gradientIdCounter = 0;\n\n/**\n * A plain circular map marker: a light-to-dark gradient fill with a white\n * outer ring, no point/tail (unlike `<map-pin>`) — for markers that don't\n * need to visually \"point\" at their exact coordinate. Purely a visual\n * primitive — it has no `mapbox-gl` (or any mapping library) dependency;\n * the consumer positions it, e.g. via `new mapboxgl.Marker({ element: el })`.\n *\n * @element map-circle\n * @slot - Optional badge content shown centered on the circle — a rank\n * number, an emoji, a small icon.\n */\n@customElement(\"map-circle\")\nexport class MapCircle extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n position: relative;\n line-height: 0;\n }\n svg {\n display: block;\n transition: transform 120ms ease, filter 120ms ease;\n }\n :host([highlighted]) svg {\n transform: scale(1.12);\n filter: brightness(1.08) drop-shadow(0 0 5px rgb(0 0 0 / 0.35));\n }\n .content {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #fff;\n font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);\n font-weight: 700;\n line-height: 1;\n text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);\n pointer-events: none;\n white-space: nowrap;\n }\n `,\n ];\n\n /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */\n @property() color = \"#4f46e5\";\n /** Diameter, in CSS pixels. */\n @property({ type: Number }) size = 18;\n /** White outer ring thickness, in the same viewBox units as `size` (scales with it). */\n @property({ type: Number, attribute: \"ring-width\" }) ringWidth = 4;\n /** Scales and glows the circle — a generic emphasis state (e.g. hover, selection). */\n @property({ type: Boolean, reflect: true }) highlighted = false;\n\n private readonly _gradId = `map-circle-grad-${gradientIdCounter++}`;\n\n override render() {\n const light = mixHex(this.color, \"#ffffff\", 30);\n const dark = mixHex(this.color, \"#000000\", 30);\n return html`\n <svg\n width=${this.size}\n height=${this.size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=${this._gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=${light} />\n <stop offset=\"100%\" stop-color=${dark} />\n </linearGradient>\n </defs>\n <circle cx=\"16\" cy=\"16\" r=\"13\" fill=\"url(#${this._gradId})\" stroke=\"#ffffff\" stroke-width=${this.ringWidth} />\n </svg>\n <div class=\"content\" style=\"font-size:${Math.round(this.size * 0.4)}px\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"map-circle\": MapCircle;\n }\n}\n"]}
1
+ {"version":3,"file":"map-circle.js","sourceRoot":"","sources":["../src/map-circle.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;;;;;GAaG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QA+CL,4FAA4F;QAChF,UAAK,GAAG,SAAS,CAAC;QAC9B,+BAA+B;QACH,SAAI,GAAG,EAAE,CAAC;QACtC,wFAAwF;QACnC,cAAS,GAAG,CAAC,CAAC;QACnE,sFAAsF;QAC1C,gBAAW,GAAG,KAAK,CAAC;QAE/C,YAAO,GAAG,mBAAmB,iBAAiB,EAAE,EAAE,CAAC;IA2BtE,CAAC;aAlFiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAyCF;KACF,AA5CqB,CA4CpB;IAaO,MAAM;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAA;;;gBAGC,IAAI,CAAC,IAAI;iBACR,IAAI,CAAC,IAAI;;;;;;+BAMK,IAAI,CAAC,OAAO;2CACA,KAAK;6CACH,IAAI;;;oDAGG,IAAI,CAAC,OAAO,oCAAoC,IAAI,CAAC,SAAS;;8CAEpE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;;;KAGpE,CAAC;IACJ,CAAC;CACF,CAAA;AAnCa;IAAX,QAAQ,EAAE;wCAAmB;AAEF;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uCAAW;AAEe;IAApD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;4CAAe;AAEvB;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;8CAAqB;AAtDrD,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CAmFrB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\nimport { mixHex } from \"./utils/color.js\";\n\nlet gradientIdCounter = 0;\n\n/**\n * A plain circular map marker: a light-to-dark gradient fill with a white\n * outer ring, no point/tail (unlike `<map-pin>`) — for markers that don't\n * need to visually \"point\" at their exact coordinate. Purely a visual\n * primitive — it has no `mapbox-gl` (or any mapping library) dependency;\n * the consumer positions it, e.g. via `new mapboxgl.Marker({ element: el })`.\n * It can also replace the former `<map-point>` dense-layer primitive: use\n * `size=\"14\" ring-width=\"3\"`, leave the slot empty, and rasterize one marker\n * per color for use as a map `icon-image`.\n *\n * @element map-circle\n * @slot - Optional badge content shown centered on the circle — a rank\n * number, an emoji, a small icon.\n */\n@customElement(\"map-circle\")\nexport class MapCircle extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n position: relative;\n line-height: 0;\n }\n svg {\n display: block;\n transition: transform 120ms ease, filter 120ms ease;\n }\n :host([highlighted]) svg {\n transform: scale(1.12);\n filter: brightness(1.08) drop-shadow(0 0 5px rgb(0 0 0 / 0.35));\n }\n .content {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #fff;\n font-family: var(\n --ui-font,\n ui-sans-serif,\n system-ui,\n sans-serif,\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"Segoe UI Symbol\",\n \"Noto Color Emoji\"\n );\n font-weight: 700;\n line-height: 1;\n text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);\n pointer-events: none;\n white-space: nowrap;\n }\n @media (prefers-reduced-motion: reduce) {\n svg {\n transition: none;\n }\n }\n `,\n ];\n\n /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */\n @property() color = \"#4f46e5\";\n /** Diameter, in CSS pixels. */\n @property({ type: Number }) size = 18;\n /** White outer ring thickness, in the same viewBox units as `size` (scales with it). */\n @property({ type: Number, attribute: \"ring-width\" }) ringWidth = 4;\n /** Scales and glows the circle — a generic emphasis state (e.g. hover, selection). */\n @property({ type: Boolean, reflect: true }) highlighted = false;\n\n private readonly _gradId = `map-circle-grad-${gradientIdCounter++}`;\n\n override render() {\n const light = mixHex(this.color, \"#ffffff\", 30);\n const dark = mixHex(this.color, \"#000000\", 30);\n return html`\n <svg\n aria-hidden=\"true\"\n width=${this.size}\n height=${this.size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=${this._gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=${light} />\n <stop offset=\"100%\" stop-color=${dark} />\n </linearGradient>\n </defs>\n <circle cx=\"16\" cy=\"16\" r=\"13\" fill=\"url(#${this._gradId})\" stroke=\"#ffffff\" stroke-width=${this.ringWidth} />\n </svg>\n <div class=\"content\" style=\"font-size:${Math.round(this.size * 0.4)}px\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"map-circle\": MapCircle;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"map-pin.d.ts","sourceRoot":"","sources":["../src/map-pin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C;;;;;;;;;GASG;AACH,qBACa,MAAO,SAAQ,UAAU;IACpC,OAAgB,MAAM,4BAiCpB;IAEF,4FAA4F;IAChF,KAAK,SAAa;IAC9B,oDAAoD;IACxB,IAAI,SAAM;IACtC,mFAAmF;IACvC,WAAW,UAAS;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAExD,MAAM,yCA6Bd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
1
+ {"version":3,"file":"map-pin.d.ts","sourceRoot":"","sources":["../src/map-pin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C;;;;;;;;;GASG;AACH,qBACa,MAAO,SAAQ,UAAU;IACpC,OAAgB,MAAM,4BA+CpB;IAEF,4FAA4F;IAChF,KAAK,SAAa;IAC9B,oDAAoD;IACxB,IAAI,SAAM;IACtC,mFAAmF;IACvC,WAAW,UAAS;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAExD,MAAM,yCA8Bd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
package/dist/map-pin.js CHANGED
@@ -55,13 +55,27 @@ let MapPin = class MapPin extends LitElement {
55
55
  left: 50%;
56
56
  transform: translate(-50%, -50%);
57
57
  color: #fff;
58
- font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);
58
+ font-family: var(
59
+ --ui-font,
60
+ ui-sans-serif,
61
+ system-ui,
62
+ sans-serif,
63
+ "Apple Color Emoji",
64
+ "Segoe UI Emoji",
65
+ "Segoe UI Symbol",
66
+ "Noto Color Emoji"
67
+ );
59
68
  font-weight: 700;
60
69
  line-height: 1;
61
70
  text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);
62
71
  pointer-events: none;
63
72
  white-space: nowrap;
64
73
  }
74
+ @media (prefers-reduced-motion: reduce) {
75
+ svg {
76
+ transition: none;
77
+ }
78
+ }
65
79
  `,
66
80
  ]; }
67
81
  render() {
@@ -70,6 +84,7 @@ let MapPin = class MapPin extends LitElement {
70
84
  const height = Math.round(this.size * (34 / 32));
71
85
  return html `
72
86
  <svg
87
+ aria-hidden="true"
73
88
  width=${this.size}
74
89
  height=${height}
75
90
  viewBox="0 0 32 34"
@@ -1 +1 @@
1
- {"version":3,"file":"map-pin.js","sourceRoot":"","sources":["../src/map-pin.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;GASG;AAEI,IAAM,MAAM,GAAZ,MAAM,MAAO,SAAQ,UAAU;IAA/B;;QAoCL,4FAA4F;QAChF,UAAK,GAAG,SAAS,CAAC;QAC9B,oDAAoD;QACxB,SAAI,GAAG,EAAE,CAAC;QACtC,mFAAmF;QACvC,gBAAW,GAAG,KAAK,CAAC;QAE/C,YAAO,GAAG,gBAAgB,iBAAiB,EAAE,EAAE,CAAC;IAgCnE,CAAC;aA1EiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA8BF;KACF,AAjCqB,CAiCpB;IAWO,MAAM;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACjD,OAAO,IAAI,CAAA;;gBAEC,IAAI,CAAC,IAAI;iBACR,MAAM;;;;;;+BAMQ,IAAI,CAAC,OAAO;2CACA,KAAK;6CACH,IAAI;;;;;uBAK1B,IAAI,CAAC,OAAO;;;;;8CAKW,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;;;KAGpE,CAAC;IACJ,CAAC;CACF,CAAA;AAtCa;IAAX,QAAQ,EAAE;qCAAmB;AAEF;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCAAW;AAEM;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;2CAAqB;AAzCrD,MAAM;IADlB,aAAa,CAAC,SAAS,CAAC;GACZ,MAAM,CA2ElB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\nimport { mixHex } from \"./utils/color.js\";\n\nlet gradientIdCounter = 0;\n\n/**\n * A circular \"Apple Maps\"-style map pin: a light-to-dark gradient fill with\n * a slight point at the bottom. Purely a visual primitive — it has no\n * `mapbox-gl` (or any mapping library) dependency; the consumer positions\n * it, e.g. via `new mapboxgl.Marker({ element: pinEl })`.\n *\n * @element map-pin\n * @slot - Badge content shown centered on the pin's circular head — a rank\n * number, an emoji, a small icon.\n */\n@customElement(\"map-pin\")\nexport class MapPin extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n position: relative;\n line-height: 0;\n }\n svg {\n display: block;\n transition: transform 120ms ease, filter 120ms ease;\n }\n :host([highlighted]) svg {\n transform: scale(1.12);\n filter: brightness(1.08) drop-shadow(0 0 5px rgb(0 0 0 / 0.35));\n }\n .content {\n position: absolute;\n /* The path's circular head is centered at viewBox y=13 of 34 total\n (13/34 ≈ 38%) — not the pin's full bounding box, which is pulled\n down by the point below the circle. */\n top: 38%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #fff;\n font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);\n font-weight: 700;\n line-height: 1;\n text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);\n pointer-events: none;\n white-space: nowrap;\n }\n `,\n ];\n\n /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */\n @property() color = \"#4f46e5\";\n /** Diameter of the circular head, in CSS pixels. */\n @property({ type: Number }) size = 32;\n /** Scales and glows the pin — a generic emphasis state (e.g. hover, selection). */\n @property({ type: Boolean, reflect: true }) highlighted = false;\n\n private readonly _gradId = `map-pin-grad-${gradientIdCounter++}`;\n\n override render() {\n const light = mixHex(this.color, \"#ffffff\", 30);\n const dark = mixHex(this.color, \"#000000\", 30);\n const height = Math.round(this.size * (34 / 32));\n return html`\n <svg\n width=${this.size}\n height=${height}\n viewBox=\"0 0 32 34\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=${this._gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=${light} />\n <stop offset=\"100%\" stop-color=${dark} />\n </linearGradient>\n </defs>\n <path\n d=\"M16 30 C10 24 4 19.5 4 13 A12 12 0 1 1 28 13 C28 19.5 22 24 16 30 Z\"\n fill=\"url(#${this._gradId})\"\n stroke=\"#ffffff\"\n stroke-width=\"1.5\"\n />\n </svg>\n <div class=\"content\" style=\"font-size:${Math.round(this.size * 0.4)}px\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"map-pin\": MapPin;\n }\n}\n"]}
1
+ {"version":3,"file":"map-pin.js","sourceRoot":"","sources":["../src/map-pin.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;GASG;AAEI,IAAM,MAAM,GAAZ,MAAM,MAAO,SAAQ,UAAU;IAA/B;;QAkDL,4FAA4F;QAChF,UAAK,GAAG,SAAS,CAAC;QAC9B,oDAAoD;QACxB,SAAI,GAAG,EAAE,CAAC;QACtC,mFAAmF;QACvC,gBAAW,GAAG,KAAK,CAAC;QAE/C,YAAO,GAAG,gBAAgB,iBAAiB,EAAE,EAAE,CAAC;IAiCnE,CAAC;aAzFiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4CF;KACF,AA/CqB,CA+CpB;IAWO,MAAM;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACjD,OAAO,IAAI,CAAA;;;gBAGC,IAAI,CAAC,IAAI;iBACR,MAAM;;;;;;+BAMQ,IAAI,CAAC,OAAO;2CACA,KAAK;6CACH,IAAI;;;;;uBAK1B,IAAI,CAAC,OAAO;;;;;8CAKW,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;;;KAGpE,CAAC;IACJ,CAAC;CACF,CAAA;AAvCa;IAAX,QAAQ,EAAE;qCAAmB;AAEF;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCAAW;AAEM;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;2CAAqB;AAvDrD,MAAM;IADlB,aAAa,CAAC,SAAS,CAAC;GACZ,MAAM,CA0FlB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\nimport { mixHex } from \"./utils/color.js\";\n\nlet gradientIdCounter = 0;\n\n/**\n * A circular \"Apple Maps\"-style map pin: a light-to-dark gradient fill with\n * a slight point at the bottom. Purely a visual primitive — it has no\n * `mapbox-gl` (or any mapping library) dependency; the consumer positions\n * it, e.g. via `new mapboxgl.Marker({ element: pinEl })`.\n *\n * @element map-pin\n * @slot - Badge content shown centered on the pin's circular head — a rank\n * number, an emoji, a small icon.\n */\n@customElement(\"map-pin\")\nexport class MapPin extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n position: relative;\n line-height: 0;\n }\n svg {\n display: block;\n transition: transform 120ms ease, filter 120ms ease;\n }\n :host([highlighted]) svg {\n transform: scale(1.12);\n filter: brightness(1.08) drop-shadow(0 0 5px rgb(0 0 0 / 0.35));\n }\n .content {\n position: absolute;\n /* The path's circular head is centered at viewBox y=13 of 34 total\n (13/34 ≈ 38%) — not the pin's full bounding box, which is pulled\n down by the point below the circle. */\n top: 38%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #fff;\n font-family: var(\n --ui-font,\n ui-sans-serif,\n system-ui,\n sans-serif,\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"Segoe UI Symbol\",\n \"Noto Color Emoji\"\n );\n font-weight: 700;\n line-height: 1;\n text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);\n pointer-events: none;\n white-space: nowrap;\n }\n @media (prefers-reduced-motion: reduce) {\n svg {\n transition: none;\n }\n }\n `,\n ];\n\n /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */\n @property() color = \"#4f46e5\";\n /** Diameter of the circular head, in CSS pixels. */\n @property({ type: Number }) size = 32;\n /** Scales and glows the pin — a generic emphasis state (e.g. hover, selection). */\n @property({ type: Boolean, reflect: true }) highlighted = false;\n\n private readonly _gradId = `map-pin-grad-${gradientIdCounter++}`;\n\n override render() {\n const light = mixHex(this.color, \"#ffffff\", 30);\n const dark = mixHex(this.color, \"#000000\", 30);\n const height = Math.round(this.size * (34 / 32));\n return html`\n <svg\n aria-hidden=\"true\"\n width=${this.size}\n height=${height}\n viewBox=\"0 0 32 34\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=${this._gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=${light} />\n <stop offset=\"100%\" stop-color=${dark} />\n </linearGradient>\n </defs>\n <path\n d=\"M16 30 C10 24 4 19.5 4 13 A12 12 0 1 1 28 13 C28 19.5 22 24 16 30 Z\"\n fill=\"url(#${this._gradId})\"\n stroke=\"#ffffff\"\n stroke-width=\"1.5\"\n />\n </svg>\n <div class=\"content\" style=\"font-size:${Math.round(this.size * 0.4)}px\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"map-pin\": MapPin;\n }\n}\n"]}
@@ -17,6 +17,9 @@ export declare class PercentBarChart extends LitElement {
17
17
  groups: PercentBarGroup[];
18
18
  private _width;
19
19
  private _ro;
20
+ private readonly _gradIdBase;
21
+ /** Per-row gradient id, unique across instances and rows. */
22
+ private _gradId;
20
23
  firstUpdated(): void;
21
24
  disconnectedCallback(): void;
22
25
  render(): import("lit-html").TemplateResult<1>;
@@ -1 +1 @@
1
- {"version":3,"file":"percent-bar-chart.d.ts","sourceRoot":"","sources":["../src/percent-bar-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAC;AAKjD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAOD;;;;;GAKG;AACH,qBACa,eAAgB,SAAQ,UAAU;IAC7C,OAAgB,MAAM,4BAYpB;IAEF,qCAAqC;IACL,MAAM,EAAE,eAAe,EAAE,CAAM;IACtD,OAAO,CAAC,MAAM,CAAK;IAE5B,OAAO,CAAC,GAAG,CAA+B;IAEjC,YAAY,SAMpB;IAEQ,oBAAoB,SAI5B;IAEQ,MAAM,yCA4Bd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}
1
+ {"version":3,"file":"percent-bar-chart.d.ts","sourceRoot":"","sources":["../src/percent-bar-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAC;AAMjD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AASD;;;;;GAKG;AACH,qBACa,eAAgB,SAAQ,UAAU;IAC7C,OAAgB,MAAM,4BA+BpB;IAEF,qCAAqC;IACL,MAAM,EAAE,eAAe,EAAE,CAAM;IACtD,OAAO,CAAC,MAAM,CAAK;IAE5B,OAAO,CAAC,GAAG,CAA+B;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6C;IAEzE,6DAA6D;IAC7D,OAAO,CAAC,OAAO;IAIN,YAAY,SAMpB;IAEQ,oBAAoB,SAI5B;IAEQ,MAAM,yCA2Dd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}
@@ -6,12 +6,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { LitElement, css, html, svg } from "lit";
8
8
  import { customElement, property, state } from "lit/decorators.js";
9
+ import { styleMap } from "lit/directives/style-map.js";
9
10
  import { scaleLinear } from "d3-scale";
10
11
  import { tokens } from "./tokens.js";
11
12
  const ROW_H = 20;
12
13
  const LABEL_W = 56;
13
14
  const PCT_W = 36;
14
15
  const PAD = { top: 4, right: 4, bottom: 4, left: 4 };
16
+ let gradientIdCounter = 0;
15
17
  /**
16
18
  * Horizontal bar chart for labeled percentage rows, using D3's linear scale.
17
19
  * Each group gets its own labeled row; bars are proportional to percentage of 100.
@@ -25,6 +27,7 @@ let PercentBarChart = class PercentBarChart extends LitElement {
25
27
  this.groups = [];
26
28
  this._width = 0;
27
29
  this._ro = null;
30
+ this._gradIdBase = `percent-bar-grad-${gradientIdCounter++}`;
28
31
  }
29
32
  static { this.styles = [
30
33
  tokens,
@@ -36,9 +39,32 @@ let PercentBarChart = class PercentBarChart extends LitElement {
36
39
  svg {
37
40
  display: block;
38
41
  overflow: visible;
42
+ font-family: var(
43
+ --ui-font,
44
+ ui-sans-serif,
45
+ system-ui,
46
+ sans-serif,
47
+ "Apple Color Emoji",
48
+ "Segoe UI Emoji",
49
+ "Segoe UI Symbol",
50
+ "Noto Color Emoji"
51
+ );
52
+ }
53
+ .chart-label {
54
+ fill: var(--ui-text-muted, #64748b);
55
+ }
56
+ .gradient-start {
57
+ stop-color: color-mix(in srgb, var(--percent-bar-color) 70%, #ffffff);
58
+ }
59
+ .gradient-end {
60
+ stop-color: color-mix(in srgb, var(--percent-bar-color) 70%, #000000);
39
61
  }
40
62
  `,
41
63
  ]; }
64
+ /** Per-row gradient id, unique across instances and rows. */
65
+ _gradId(index) {
66
+ return `${this._gradIdBase}-${index}`;
67
+ }
42
68
  firstUpdated() {
43
69
  this._ro = new ResizeObserver((entries) => {
44
70
  const w = Math.floor(entries[0].contentRect.width);
@@ -59,21 +85,51 @@ let PercentBarChart = class PercentBarChart extends LitElement {
59
85
  const barMaxW = innerW - LABEL_W - PCT_W;
60
86
  const svgH = PAD.top + this.groups.length * ROW_H + PAD.bottom;
61
87
  const xScale = scaleLinear().domain([0, 100]).range([0, barMaxW]);
88
+ // CSS stop styles preserve every valid CSS color format while matching
89
+ // map-circle's 30% white/black vertical depth.
90
+ const rowFills = this.groups.map((g, i) => {
91
+ const color = g.color.trim();
92
+ const gradId = this._gradId(i);
93
+ return {
94
+ fill: `url(#${gradId})`,
95
+ gradient: svg `
96
+ <linearGradient
97
+ id=${gradId}
98
+ x1="0"
99
+ y1="0"
100
+ x2="0"
101
+ y2="1"
102
+ style=${styleMap({ "--percent-bar-color": color })}
103
+ >
104
+ <stop class="gradient-start" offset="0%" />
105
+ <stop class="gradient-end" offset="100%" />
106
+ </linearGradient>
107
+ `,
108
+ };
109
+ });
110
+ const gradients = rowFills.map((row) => row.gradient);
62
111
  const rows = this.groups.map((g, i) => {
63
112
  const cy = PAD.top + i * ROW_H + ROW_H / 2;
64
113
  const bw = Math.max(0, xScale(g.pct));
65
114
  return svg `
66
- <text x=${PAD.left} y=${cy} font-size="10" fill="#64748b"
115
+ <text class="chart-label" x=${PAD.left} y=${cy} font-size="10"
67
116
  text-anchor="start" dominant-baseline="middle">${g.label}</text>
68
117
  <rect x=${PAD.left + LABEL_W} y=${cy - 5}
69
118
  width=${bw} height="10" rx="2"
70
- fill=${g.color} fill-opacity="0.82" />
71
- <text x=${PAD.left + LABEL_W + barMaxW + 4} y=${cy} font-size="10" fill="#64748b"
119
+ fill=${rowFills[i].fill} />
120
+ <text class="chart-label" x=${PAD.left + LABEL_W + barMaxW + 4} y=${cy} font-size="10"
72
121
  text-anchor="start" dominant-baseline="middle">${g.pct.toFixed(1)}%</text>
73
122
  `;
74
123
  });
75
124
  return html `
76
- <svg viewBox="0 0 ${this._width} ${svgH}" width=${this._width} height=${svgH}>
125
+ <svg
126
+ viewBox="0 0 ${this._width} ${svgH}"
127
+ width=${this._width}
128
+ height=${svgH}
129
+ role="img"
130
+ aria-label=${`Percentages: ${this.groups.map((group) => `${group.label} ${group.pct.toFixed(1)}%`).join(", ")}`}
131
+ >
132
+ <defs>${gradients}</defs>
77
133
  ${rows}
78
134
  </svg>
79
135
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"percent-bar-chart.js","sourceRoot":"","sources":["../src/percent-bar-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, css, html, svg } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { scaleLinear } from \"d3-scale\";\nimport { tokens } from \"./tokens.js\";\n\nexport interface PercentBarGroup {\n key: string;\n label: string;\n pct: number;\n color: string;\n}\n\nconst ROW_H = 20;\nconst LABEL_W = 56;\nconst PCT_W = 36;\nconst PAD = { top: 4, right: 4, bottom: 4, left: 4 };\n\n/**\n * Horizontal bar chart for labeled percentage rows, using D3's linear scale.\n * Each group gets its own labeled row; bars are proportional to percentage of 100.\n *\n * @element percent-bar-chart\n */\n@customElement(\"percent-bar-chart\")\nexport class PercentBarChart extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n width: 100%;\n }\n svg {\n display: block;\n overflow: visible;\n }\n `,\n ];\n\n /** Rows to render, one per group. */\n @property({ attribute: false }) groups: PercentBarGroup[] = [];\n @state() private _width = 0;\n\n private _ro: ResizeObserver | null = null;\n\n override firstUpdated() {\n this._ro = new ResizeObserver((entries) => {\n const w = Math.floor(entries[0].contentRect.width);\n if (w > 0 && w !== this._width) this._width = w;\n });\n this._ro.observe(this);\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this._ro?.disconnect();\n this._ro = null;\n }\n\n override render() {\n if (this._width === 0 || this.groups.length === 0) return html``;\n\n const innerW = this._width - PAD.left - PAD.right;\n const barMaxW = innerW - LABEL_W - PCT_W;\n const svgH = PAD.top + this.groups.length * ROW_H + PAD.bottom;\n\n const xScale = scaleLinear().domain([0, 100]).range([0, barMaxW]);\n\n const rows = this.groups.map((g, i) => {\n const cy = PAD.top + i * ROW_H + ROW_H / 2;\n const bw = Math.max(0, xScale(g.pct));\n return svg`\n <text x=${PAD.left} y=${cy} font-size=\"10\" fill=\"#64748b\"\n text-anchor=\"start\" dominant-baseline=\"middle\">${g.label}</text>\n <rect x=${PAD.left + LABEL_W} y=${cy - 5}\n width=${bw} height=\"10\" rx=\"2\"\n fill=${g.color} fill-opacity=\"0.82\" />\n <text x=${PAD.left + LABEL_W + barMaxW + 4} y=${cy} font-size=\"10\" fill=\"#64748b\"\n text-anchor=\"start\" dominant-baseline=\"middle\">${g.pct.toFixed(1)}%</text>\n `;\n });\n\n return html`\n <svg viewBox=\"0 0 ${this._width} ${svgH}\" width=${this._width} height=${svgH}>\n ${rows}\n </svg>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"percent-bar-chart\": PercentBarChart;\n }\n}\n"]}
1
+ {"version":3,"file":"percent-bar-chart.js","sourceRoot":"","sources":["../src/percent-bar-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, css, html, svg } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport { scaleLinear } from \"d3-scale\";\nimport { tokens } from \"./tokens.js\";\n\nexport interface PercentBarGroup {\n key: string;\n label: string;\n pct: number;\n color: string;\n}\n\nconst ROW_H = 20;\nconst LABEL_W = 56;\nconst PCT_W = 36;\nconst PAD = { top: 4, right: 4, bottom: 4, left: 4 };\n\nlet gradientIdCounter = 0;\n\n/**\n * Horizontal bar chart for labeled percentage rows, using D3's linear scale.\n * Each group gets its own labeled row; bars are proportional to percentage of 100.\n *\n * @element percent-bar-chart\n */\n@customElement(\"percent-bar-chart\")\nexport class PercentBarChart extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n width: 100%;\n }\n svg {\n display: block;\n overflow: visible;\n font-family: var(\n --ui-font,\n ui-sans-serif,\n system-ui,\n sans-serif,\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"Segoe UI Symbol\",\n \"Noto Color Emoji\"\n );\n }\n .chart-label {\n fill: var(--ui-text-muted, #64748b);\n }\n .gradient-start {\n stop-color: color-mix(in srgb, var(--percent-bar-color) 70%, #ffffff);\n }\n .gradient-end {\n stop-color: color-mix(in srgb, var(--percent-bar-color) 70%, #000000);\n }\n `,\n ];\n\n /** Rows to render, one per group. */\n @property({ attribute: false }) groups: PercentBarGroup[] = [];\n @state() private _width = 0;\n\n private _ro: ResizeObserver | null = null;\n private readonly _gradIdBase = `percent-bar-grad-${gradientIdCounter++}`;\n\n /** Per-row gradient id, unique across instances and rows. */\n private _gradId(index: number): string {\n return `${this._gradIdBase}-${index}`;\n }\n\n override firstUpdated() {\n this._ro = new ResizeObserver((entries) => {\n const w = Math.floor(entries[0].contentRect.width);\n if (w > 0 && w !== this._width) this._width = w;\n });\n this._ro.observe(this);\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this._ro?.disconnect();\n this._ro = null;\n }\n\n override render() {\n if (this._width === 0 || this.groups.length === 0) return html``;\n\n const innerW = this._width - PAD.left - PAD.right;\n const barMaxW = innerW - LABEL_W - PCT_W;\n const svgH = PAD.top + this.groups.length * ROW_H + PAD.bottom;\n\n const xScale = scaleLinear().domain([0, 100]).range([0, barMaxW]);\n\n // CSS stop styles preserve every valid CSS color format while matching\n // map-circle's 30% white/black vertical depth.\n const rowFills = this.groups.map((g, i) => {\n const color = g.color.trim();\n const gradId = this._gradId(i);\n return {\n fill: `url(#${gradId})`,\n gradient: svg`\n <linearGradient\n id=${gradId}\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n style=${styleMap({ \"--percent-bar-color\": color })}\n >\n <stop class=\"gradient-start\" offset=\"0%\" />\n <stop class=\"gradient-end\" offset=\"100%\" />\n </linearGradient>\n `,\n };\n });\n const gradients = rowFills.map((row) => row.gradient);\n\n const rows = this.groups.map((g, i) => {\n const cy = PAD.top + i * ROW_H + ROW_H / 2;\n const bw = Math.max(0, xScale(g.pct));\n return svg`\n <text class=\"chart-label\" x=${PAD.left} y=${cy} font-size=\"10\"\n text-anchor=\"start\" dominant-baseline=\"middle\">${g.label}</text>\n <rect x=${PAD.left + LABEL_W} y=${cy - 5}\n width=${bw} height=\"10\" rx=\"2\"\n fill=${rowFills[i].fill} />\n <text class=\"chart-label\" x=${PAD.left + LABEL_W + barMaxW + 4} y=${cy} font-size=\"10\"\n text-anchor=\"start\" dominant-baseline=\"middle\">${g.pct.toFixed(1)}%</text>\n `;\n });\n\n return html`\n <svg\n viewBox=\"0 0 ${this._width} ${svgH}\"\n width=${this._width}\n height=${svgH}\n role=\"img\"\n aria-label=${`Percentages: ${this.groups.map((group) => `${group.label} ${group.pct.toFixed(1)}%`).join(\", \")}`}\n >\n <defs>${gradients}</defs>\n ${rows}\n </svg>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"percent-bar-chart\": PercentBarChart;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"photo-gallery.d.ts","sourceRoot":"","sources":["../src/photo-gallery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"photo-gallery.d.ts","sourceRoot":"","sources":["../src/photo-gallery.ts"],"names":[],"mappings":"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"}
@@ -64,7 +64,16 @@ let PhotoGallery = class PhotoGallery extends LitElement {
64
64
  :host {
65
65
  display: block;
66
66
  color: var(--ui-text, #0f172a);
67
- font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);
67
+ font-family: var(
68
+ --ui-font,
69
+ ui-sans-serif,
70
+ system-ui,
71
+ sans-serif,
72
+ "Apple Color Emoji",
73
+ "Segoe UI Emoji",
74
+ "Segoe UI Symbol",
75
+ "Noto Color Emoji"
76
+ );
68
77
  font-size: var(--ui-font-size, 0.875rem);
69
78
  }
70
79
  .gallery {
@@ -137,7 +146,7 @@ let PhotoGallery = class PhotoGallery extends LitElement {
137
146
  width: 2.5rem;
138
147
  height: 2.5rem;
139
148
  padding: 0;
140
- color: var(--ui-surface, #fff);
149
+ color: var(--ui-on-accent, #ffffff);
141
150
  background: var(--ui-overlay, rgb(15 23 42 / 0.45));
142
151
  border-radius: 9999px;
143
152
  pointer-events: auto;
@@ -189,7 +198,7 @@ let PhotoGallery = class PhotoGallery extends LitElement {
189
198
  white-space: nowrap;
190
199
  }
191
200
  .autoplay-button:hover {
192
- background: var(--ui-surface, #fff);
201
+ background: var(--ui-surface, #ffffff);
193
202
  }
194
203
  slot {
195
204
  display: none;
@@ -1 +1 @@
1
- {"version":3,"file":"photo-gallery.js","sourceRoot":"","sources":["../src/photo-gallery.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, css, html, nothing, type PropertyValues } from \"lit\";\nimport { customElement, property, queryAssignedElements, state } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport type { GalleryItemVariant } from \"./gallery-item-variant.js\";\nimport { GalleryItem } from \"./gallery-item.js\";\nimport { iconChevronLeft, iconChevronRight } from \"./icons.js\";\nimport { tokens } from \"./tokens.js\";\n\nexport type PhotoGalleryObjectFit = \"cover\" | \"contain\";\nexport type PhotoGalleryChangeReason =\n | \"autoplay\"\n | \"indicator\"\n | \"items\"\n | \"keyboard\"\n | \"next\"\n | \"previous\"\n | \"programmatic\"\n | \"swipe\";\n\nexport interface PhotoGallerySlideChangeDetail {\n previousIndex: number;\n currentIndex: number;\n item: GalleryItem;\n reason: PhotoGalleryChangeReason;\n}\n\nconst transitionDurationMs = 250;\nconst swipeThresholdPx = 40;\nconst booleanAttribute = {\n fromAttribute(value: string | null): boolean {\n return value !== null && value !== \"false\";\n },\n};\n\n/**\n * Responsive, accessible image carousel composed from declarative\n * `gallery-item` children.\n *\n * @element photo-gallery\n * @slot - `gallery-item` elements rendered as slides.\n * @fires slide-change - The active image changed.\n */\n@customElement(\"photo-gallery\")\nexport class PhotoGallery extends LitElement {\n /** Zero-based active image index. */\n @property({ type: Number, attribute: \"current-index\", reflect: true })\n currentIndex = 0;\n\n /** Autoplay interval in milliseconds. Set to zero to disable autoplay. */\n @property({ type: Number }) delay = 0;\n\n /** Whether previous and next buttons are shown. */\n @property({ attribute: \"show-controls\", converter: booleanAttribute })\n showControls = true;\n\n /** Whether a current/total counter is shown. */\n @property({ type: Boolean, attribute: \"show-counter\" })\n showCounter = false;\n\n /** Whether clickable slide indicators are shown. */\n @property({ type: Boolean, attribute: \"show-indicators\" })\n showIndicators = false;\n\n /** Whether autoplay includes a built-in pause/play control. */\n @property({ attribute: \"show-autoplay-control\", converter: booleanAttribute })\n showAutoplayControl = true;\n\n /** Whether autoplay is explicitly paused. */\n @property({ type: Boolean, reflect: true })\n paused = false;\n\n /** CSS aspect ratio used by the image viewport. */\n @property({ attribute: \"aspect-ratio\" })\n aspectRatio = \"16 / 9\";\n\n /** How images fit within the stable viewport. */\n @property({ attribute: \"object-fit\" })\n objectFit: PhotoGalleryObjectFit = \"cover\";\n\n @queryAssignedElements({ selector: \"gallery-item\" })\n private readonly _galleryItems!: GalleryItem[];\n\n @state()\n private _previousIndex: number | null = null;\n\n @state()\n private _itemsVersion = 0;\n\n private _autoplayTimer?: number;\n private _transitionTimer?: number;\n private _metadataObserver?: MutationObserver;\n private _hovered = false;\n private _focusWithin = false;\n private _nextChangeReason: PhotoGalleryChangeReason | null = null;\n private _pendingChange?: PhotoGallerySlideChangeDetail;\n private _pointerStart?: { id: number; x: number; y: number };\n private _itemsChanged = false;\n private _activeItem?: GalleryItem;\n private _renderedIndex = 0;\n\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n color: var(--ui-text, #0f172a);\n font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);\n font-size: var(--ui-font-size, 0.875rem);\n }\n .gallery {\n outline: none;\n }\n figure {\n margin: 0;\n }\n .viewport {\n position: relative;\n overflow: hidden;\n aspect-ratio: var(--photo-gallery-aspect-ratio, 16 / 9);\n border-radius: var(--ui-radius, 0.5rem);\n background: var(--ui-surface-muted, #f8fafc);\n touch-action: pan-y;\n user-select: none;\n }\n .gallery:focus-visible .viewport {\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .slides {\n display: grid;\n width: 100%;\n height: 100%;\n }\n picture {\n grid-area: 1 / 1;\n display: block;\n width: 100%;\n height: 100%;\n }\n picture img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: var(--photo-gallery-object-fit, cover);\n }\n .entering {\n z-index: 2;\n animation: gallery-fade-in 250ms ease both;\n }\n .leaving {\n z-index: 1;\n pointer-events: none;\n animation: gallery-fade-out 250ms ease both;\n }\n .arrow-controls {\n position: absolute;\n z-index: 3;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem;\n pointer-events: none;\n }\n button {\n border: 0;\n font: inherit;\n cursor: pointer;\n }\n button:focus-visible {\n outline: none;\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .arrow-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n padding: 0;\n color: var(--ui-surface, #fff);\n background: var(--ui-overlay, rgb(15 23 42 / 0.45));\n border-radius: 9999px;\n pointer-events: auto;\n }\n .arrow-button:hover {\n background: color-mix(in srgb, var(--ui-text, #0f172a) 70%, transparent);\n }\n figcaption {\n padding: 0.5rem 0.25rem 0;\n color: var(--ui-text-muted, #64748b);\n }\n .footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.75rem;\n min-height: 2rem;\n padding-top: 0.5rem;\n }\n .counter {\n color: var(--ui-text-muted, #64748b);\n font-size: var(--ui-font-size-sm, 0.75rem);\n white-space: nowrap;\n }\n .indicators {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n }\n .indicator {\n width: 0.625rem;\n height: 0.625rem;\n padding: 0;\n background: var(--ui-border, #e2e8f0);\n border-radius: 9999px;\n }\n .indicator[aria-current=\"true\"] {\n background: var(--ui-primary, #4f46e5);\n }\n .autoplay-button {\n padding: 0.25rem 0.625rem;\n color: var(--ui-text, #0f172a);\n background: var(--ui-surface-muted, #f8fafc);\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: var(--ui-radius-sm, 0.25rem);\n font-size: var(--ui-font-size-sm, 0.75rem);\n white-space: nowrap;\n }\n .autoplay-button:hover {\n background: var(--ui-surface, #fff);\n }\n slot {\n display: none;\n }\n @keyframes gallery-fade-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n @keyframes gallery-fade-out {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .entering,\n .leaving {\n animation: none;\n }\n }\n `,\n ];\n\n /** Starts observers and autoplay integration when the element connects. */\n override connectedCallback(): void {\n super.connectedCallback();\n this._metadataObserver ??= new MutationObserver(() => this._handleMetadataChange());\n this._metadataObserver.observe(this, {\n attributes: true,\n attributeFilter: [\"alt\", \"caption\", \"media\", \"src\", \"srcset\"],\n childList: true,\n subtree: true,\n });\n document.addEventListener(\"visibilitychange\", this._handleVisibilityChange);\n }\n\n /** Releases timers and observers when the element disconnects. */\n override disconnectedCallback(): void {\n this._clearAutoplay();\n this._clearTransition();\n this._metadataObserver?.disconnect();\n document.removeEventListener(\"visibilitychange\", this._handleVisibilityChange);\n super.disconnectedCallback();\n }\n\n /** Normalizes external index changes before rendering. */\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (!changed.has(\"currentIndex\")) return;\n\n const normalized = this._normalizeIndex(this.currentIndex);\n if (normalized !== this.currentIndex) {\n this.currentIndex = normalized;\n }\n\n const previousValue = changed.get(\"currentIndex\");\n if (previousValue === undefined || this._galleryItems.length === 0) {\n this._nextChangeReason = null;\n return;\n }\n\n const previousIndex = this._normalizeIndex(Number(previousValue));\n if (previousIndex === normalized) {\n this._nextChangeReason = null;\n return;\n }\n\n const reason = this._nextChangeReason ?? \"programmatic\";\n this._previousIndex = reason === \"items\" ? null : previousIndex;\n this._pendingChange = {\n previousIndex,\n currentIndex: normalized,\n item: this._galleryItems[normalized],\n reason,\n };\n this._nextChangeReason = null;\n }\n\n /** Emits completed changes and keeps autoplay synchronized with properties. */\n protected override updated(changed: PropertyValues<this>): void {\n if (this._pendingChange) {\n this.dispatchEvent(\n new CustomEvent<PhotoGallerySlideChangeDetail>(\"slide-change\", {\n bubbles: true,\n composed: true,\n detail: this._pendingChange,\n }),\n );\n this._pendingChange = undefined;\n this._scheduleTransitionCleanup();\n }\n\n if (changed.has(\"currentIndex\") || changed.has(\"delay\") || changed.has(\"paused\") || this._itemsChanged) {\n this._itemsChanged = false;\n this._restartAutoplay();\n }\n this._activeItem = this._galleryItems[this.currentIndex];\n this._renderedIndex = this.currentIndex;\n }\n\n /** Wraps any requested index into the current item range. */\n private _normalizeIndex(index: number): number {\n const count = this._galleryItems.length;\n if (count === 0 || !Number.isFinite(index)) return 0;\n return ((Math.trunc(index) % count) + count) % count;\n }\n\n /** Returns responsive variants declared directly under an item. */\n private _variantsFor(item: GalleryItem): GalleryItemVariant[] {\n return Array.from(item.children).filter(\n (child): child is GalleryItemVariant => child.tagName.toLowerCase() === \"gallery-item-variant\",\n );\n }\n\n /** Changes slides through the shared state and event path. */\n private _goTo(index: number, reason: PhotoGalleryChangeReason): void {\n const normalized = this._normalizeIndex(index);\n if (this._galleryItems.length < 2 || normalized === this.currentIndex) {\n this._restartAutoplay();\n return;\n }\n\n this._nextChangeReason = reason;\n this.currentIndex = normalized;\n }\n\n /** Moves to the previous image. */\n private _showPrevious(reason: PhotoGalleryChangeReason = \"previous\"): void {\n this._goTo(this.currentIndex - 1, reason);\n }\n\n /** Moves to the next image. */\n private _showNext(reason: PhotoGalleryChangeReason = \"next\"): void {\n this._goTo(this.currentIndex + 1, reason);\n }\n\n /** Toggles explicit autoplay pause state. */\n private _togglePaused(): void {\n this.paused = !this.paused;\n }\n\n /** Clears and conditionally schedules the next autoplay advance. */\n private _restartAutoplay(): void {\n this._clearAutoplay();\n if (!this._canAutoplay()) return;\n\n this._autoplayTimer = window.setTimeout(() => {\n this._showNext(\"autoplay\");\n }, this.delay);\n }\n\n /** Reports whether autoplay may currently schedule a transition. */\n private _canAutoplay(): boolean {\n return (\n this.delay > 0 &&\n this._galleryItems.length > 1 &&\n !this.paused &&\n !this._hovered &&\n !this._focusWithin &&\n !document.hidden\n );\n }\n\n /** Clears the pending autoplay timeout. */\n private _clearAutoplay(): void {\n if (this._autoplayTimer === undefined) return;\n window.clearTimeout(this._autoplayTimer);\n this._autoplayTimer = undefined;\n }\n\n /** Removes the outgoing crossfade layer after the animation completes. */\n private _scheduleTransitionCleanup(): void {\n this._clearTransition();\n this._transitionTimer = window.setTimeout(() => {\n this._previousIndex = null;\n this._transitionTimer = undefined;\n }, transitionDurationMs);\n }\n\n /** Clears pending transition cleanup. */\n private _clearTransition(): void {\n if (this._transitionTimer === undefined) return;\n window.clearTimeout(this._transitionTimer);\n this._transitionTimer = undefined;\n }\n\n /** Refreshes item metadata and clamps the active index after light-DOM changes. */\n private _handleMetadataChange(): void {\n this._itemsChanged = true;\n this._itemsVersion += 1;\n const preserveActiveItem = this.currentIndex === this._renderedIndex;\n const preservedIndex =\n preserveActiveItem && this._activeItem ? this._galleryItems.indexOf(this._activeItem) : -1;\n const normalized = preservedIndex >= 0 ? preservedIndex : this._normalizeIndex(this.currentIndex);\n if (normalized === this.currentIndex) {\n const item = this._galleryItems[normalized];\n const activeItemRemoved = Boolean(this._activeItem && !this._galleryItems.includes(this._activeItem));\n if (item && activeItemRemoved) {\n this._previousIndex = null;\n this._pendingChange = {\n previousIndex: this._renderedIndex,\n currentIndex: normalized,\n item,\n reason: \"items\",\n };\n }\n return;\n }\n this._nextChangeReason = \"items\";\n this.currentIndex = normalized;\n }\n\n /** Refreshes item state after the default slot changes. */\n private _handleSlotChange(): void {\n this._handleMetadataChange();\n }\n\n /** Temporarily pauses autoplay while the pointer is over the gallery. */\n private _handleMouseEnter(): void {\n this._hovered = true;\n this._restartAutoplay();\n }\n\n /** Resumes autoplay with a fresh delay after hover ends. */\n private _handleMouseLeave(): void {\n this._hovered = false;\n this._restartAutoplay();\n }\n\n /** Temporarily pauses autoplay while focus is inside the gallery. */\n private _handleFocusIn(): void {\n this._focusWithin = true;\n this._restartAutoplay();\n }\n\n /** Resumes autoplay with a fresh delay after focus leaves the gallery. */\n private _handleFocusOut(): void {\n queueMicrotask(() => {\n this._focusWithin = this.matches(\":focus-within\");\n this._restartAutoplay();\n });\n }\n\n /** Pauses or resumes scheduling when page visibility changes. */\n private readonly _handleVisibilityChange = (): void => {\n this._restartAutoplay();\n };\n\n /** Handles Left and Right arrow keyboard navigation. */\n private _handleKeyDown(event: KeyboardEvent): void {\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n this._showPrevious(\"keyboard\");\n return;\n }\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n this._showNext(\"keyboard\");\n }\n }\n\n /** Records the starting point of a primary pointer gesture. */\n private _handlePointerDown(event: PointerEvent): void {\n if (!event.isPrimary || event.button !== 0) return;\n if (event.composedPath().some((target) => target instanceof HTMLButtonElement)) return;\n this._pointerStart = { id: event.pointerId, x: event.clientX, y: event.clientY };\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\n }\n\n /** Converts a sufficiently horizontal pointer gesture into navigation. */\n private _handlePointerUp(event: PointerEvent): void {\n const start = this._pointerStart;\n this._pointerStart = undefined;\n if (!start || start.id !== event.pointerId) return;\n\n const deltaX = event.clientX - start.x;\n const deltaY = event.clientY - start.y;\n if (Math.abs(deltaX) < swipeThresholdPx || Math.abs(deltaX) <= Math.abs(deltaY)) return;\n\n event.preventDefault();\n if (deltaX < 0) {\n this._showNext(\"swipe\");\n return;\n }\n this._showPrevious(\"swipe\");\n }\n\n /** Cancels an incomplete pointer gesture. */\n private _handlePointerCancel(): void {\n this._pointerStart = undefined;\n }\n\n /** Renders one responsive image layer for the crossfade stack. */\n private _renderPicture(index: number, state: \"current\" | \"previous\") {\n const item = this._galleryItems[index];\n if (!item) return nothing;\n\n const isPrevious = state === \"previous\";\n const transitionClass = this._previousIndex === null ? \"\" : isPrevious ? \"leaving\" : \"entering\";\n return html`\n <picture class=${transitionClass} aria-hidden=${isPrevious ? \"true\" : nothing}>\n ${this._variantsFor(item)\n .filter((variant) => variant.srcset)\n .map(\n (variant) =>\n html`<source media=${ifDefined(variant.media || undefined)} srcset=${variant.srcset} />`,\n )}\n <img src=${item.src} alt=${isPrevious ? \"\" : item.alt} draggable=\"false\" />\n </picture>\n `;\n }\n\n /** Renders enabled counter, indicator, and autoplay controls. */\n private _renderFooter(itemCount: number) {\n const showIndicators = this.showIndicators && itemCount > 1;\n const showAutoplay = this.showAutoplayControl && this.delay > 0 && itemCount > 1;\n if (!this.showCounter && !showIndicators && !showAutoplay) return nothing;\n\n return html`\n <div class=\"footer\">\n ${this.showCounter\n ? html`<span class=\"counter\">${this.currentIndex + 1} / ${itemCount}</span>`\n : nothing}\n ${showIndicators\n ? html`\n <div class=\"indicators\" role=\"group\" aria-label=\"Choose image\">\n ${this._galleryItems.map(\n (_item, index) => html`\n <button\n class=\"indicator\"\n type=\"button\"\n aria-label=\"Show image ${index + 1} of ${itemCount}\"\n aria-current=${String(index === this.currentIndex)}\n @click=${() => this._goTo(index, \"indicator\")}\n ></button>\n `,\n )}\n </div>\n `\n : nothing}\n ${showAutoplay\n ? html`\n <button\n class=\"autoplay-button\"\n type=\"button\"\n aria-label=${this.paused ? \"Resume slideshow\" : \"Pause slideshow\"}\n @click=${this._togglePaused}\n >\n ${this.paused ? \"Play\" : \"Pause\"}\n </button>\n `\n : nothing}\n </div>\n `;\n }\n\n /** Renders the active image, navigation, caption, and hidden metadata slot. */\n protected override render() {\n const itemCount = this._galleryItems.length;\n const currentItem = this._galleryItems[this.currentIndex];\n const objectFit: PhotoGalleryObjectFit = this.objectFit === \"contain\" ? \"contain\" : \"cover\";\n const viewportStyles = {\n \"--photo-gallery-aspect-ratio\": this.aspectRatio.trim() || \"16 / 9\",\n \"--photo-gallery-object-fit\": objectFit,\n };\n\n return html`\n <div\n class=\"gallery\"\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label=\"Photo gallery\"\n tabindex=\"0\"\n @keydown=${this._handleKeyDown}\n @mouseenter=${this._handleMouseEnter}\n @mouseleave=${this._handleMouseLeave}\n @focusin=${this._handleFocusIn}\n @focusout=${this._handleFocusOut}\n >\n ${currentItem\n ? html`\n <figure>\n <div\n class=\"viewport\"\n style=${styleMap(viewportStyles)}\n @pointerdown=${this._handlePointerDown}\n @pointerup=${this._handlePointerUp}\n @pointercancel=${this._handlePointerCancel}\n >\n <div class=\"slides\">\n ${this._previousIndex === null\n ? nothing\n : this._renderPicture(this._previousIndex, \"previous\")}\n ${this._renderPicture(this.currentIndex, \"current\")}\n </div>\n ${this.showControls && itemCount > 1\n ? html`\n <div class=\"arrow-controls\">\n <button\n class=\"arrow-button previous\"\n type=\"button\"\n aria-label=\"Previous image\"\n @click=${() => this._showPrevious()}\n >\n ${iconChevronLeft(24)}\n </button>\n <button\n class=\"arrow-button next\"\n type=\"button\"\n aria-label=\"Next image\"\n @click=${() => this._showNext()}\n >\n ${iconChevronRight(24)}\n </button>\n </div>\n `\n : nothing}\n </div>\n ${currentItem.caption ? html`<figcaption>${currentItem.caption}</figcaption>` : nothing}\n </figure>\n ${this._renderFooter(itemCount)}\n `\n : nothing}\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"photo-gallery\": PhotoGallery;\n }\n}\n"]}
1
+ {"version":3,"file":"photo-gallery.js","sourceRoot":"","sources":["../src/photo-gallery.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAuB,MAAM,KAAK,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,qBAAqB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAoBrC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACjC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC5B,MAAM,gBAAgB,GAAG;IACvB,aAAa,CAAC,KAAoB;QAChC,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,OAAO,CAAC;IAC7C,CAAC;CACF,CAAC;AAEF;;;;;;;GAOG;AAEI,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU;IAArC;;QACL,qCAAqC;QAErC,iBAAY,GAAG,CAAC,CAAC;QAEjB,0EAA0E;QAC9C,UAAK,GAAG,CAAC,CAAC;QAEtC,mDAAmD;QAEnD,iBAAY,GAAG,IAAI,CAAC;QAEpB,gDAAgD;QAEhD,gBAAW,GAAG,KAAK,CAAC;QAEpB,oDAAoD;QAEpD,mBAAc,GAAG,KAAK,CAAC;QAEvB,+DAA+D;QAE/D,wBAAmB,GAAG,IAAI,CAAC;QAE3B,6CAA6C;QAE7C,WAAM,GAAG,KAAK,CAAC;QAEf,mDAAmD;QAEnD,gBAAW,GAAG,QAAQ,CAAC;QAEvB,iDAAiD;QAEjD,cAAS,GAA0B,OAAO,CAAC;QAMnC,mBAAc,GAAkB,IAAI,CAAC;QAGrC,kBAAa,GAAG,CAAC,CAAC;QAKlB,aAAQ,GAAG,KAAK,CAAC;QACjB,iBAAY,GAAG,KAAK,CAAC;QACrB,sBAAiB,GAAoC,IAAI,CAAC;QAG1D,kBAAa,GAAG,KAAK,CAAC;QAEtB,mBAAc,GAAG,CAAC,CAAC;QAuY3B,iEAAiE;QAChD,4BAAuB,GAAG,GAAS,EAAE;YACpD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,CAAC,CAAC;IAqLJ,CAAC;aA7jBiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqKF;KACF,AAxKqB,CAwKpB;IAEF,2EAA2E;IAClE,iBAAiB;QACxB,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,iBAAiB,KAAK,IAAI,gBAAgB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;QACpF,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE;YACnC,UAAU,EAAE,IAAI;YAChB,eAAe,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC;YAC7D,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QACH,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC9E,CAAC;IAED,kEAAkE;IACzD,oBAAoB;QAC3B,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,CAAC;QACrC,QAAQ,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC/E,KAAK,CAAC,oBAAoB,EAAE,CAAC;IAC/B,CAAC;IAED,0DAA0D;IACvC,UAAU,CAAC,OAA6B;QACzD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YAAE,OAAO;QAEzC,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3D,IAAI,UAAU,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACrC,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;QACjC,CAAC;QAED,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAClD,IAAI,aAAa,KAAK,SAAS,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;QAClE,IAAI,aAAa,KAAK,UAAU,EAAE,CAAC;YACjC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,IAAI,cAAc,CAAC;QACxD,IAAI,CAAC,cAAc,GAAG,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC;QAChE,IAAI,CAAC,cAAc,GAAG;YACpB,aAAa;YACb,YAAY,EAAE,UAAU;YACxB,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC;YACpC,MAAM;SACP,CAAC;QACF,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAChC,CAAC;IAED,+EAA+E;IAC5D,OAAO,CAAC,OAA6B;QACtD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAgC,cAAc,EAAE;gBAC7D,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,IAAI,CAAC,cAAc;aAC5B,CAAC,CACH,CAAC;YACF,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;YAChC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACpC,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvG,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;YAC3B,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC;IAC1C,CAAC;IAED,6DAA6D;IACrD,eAAe,CAAC,KAAa;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QACxC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QACrD,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;IACvD,CAAC;IAED,mEAAmE;IAC3D,YAAY,CAAC,IAAiB;QACpC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CACrC,CAAC,KAAK,EAA+B,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,sBAAsB,CAC/F,CAAC;IACJ,CAAC;IAED,8DAA8D;IACtD,KAAK,CAAC,KAAa,EAAE,MAAgC;QAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACtE,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;IACjC,CAAC;IAED,mCAAmC;IAC3B,aAAa,CAAC,MAAM,GAA6B,UAAU;QACjE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,+BAA+B;IACvB,SAAS,CAAC,MAAM,GAA6B,MAAM;QACzD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,6CAA6C;IACrC,aAAa;QACnB,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,oEAAoE;IAC5D,gBAAgB;QACtB,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YAAE,OAAO;QAEjC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YAC3C,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC7B,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;IAED,oEAAoE;IAC5D,YAAY;QAClB,OAAO,CACL,IAAI,CAAC,KAAK,GAAG,CAAC;YACd,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;YAC7B,CAAC,IAAI,CAAC,MAAM;YACZ,CAAC,IAAI,CAAC,QAAQ;YACd,CAAC,IAAI,CAAC,YAAY;YAClB,CAAC,QAAQ,CAAC,MAAM,CACjB,CAAC;IACJ,CAAC;IAED,2CAA2C;IACnC,cAAc;QACpB,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS;YAAE,OAAO;QAC9C,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACzC,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IAClC,CAAC;IAED,0EAA0E;IAClE,0BAA0B;QAChC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YAC7C,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACpC,CAAC,EAAE,oBAAoB,CAAC,CAAC;IAC3B,CAAC;IAED,yCAAyC;IACjC,gBAAgB;QACtB,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS;YAAE,OAAO;QAChD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC3C,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;IACpC,CAAC;IAED,mFAAmF;IAC3E,qBAAqB;QAC3B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;QACxB,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,cAAc,CAAC;QACrE,MAAM,cAAc,GAClB,kBAAkB,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7F,MAAM,UAAU,GAAG,cAAc,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAClG,IAAI,UAAU,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YAC5C,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YACtG,IAAI,IAAI,IAAI,iBAAiB,EAAE,CAAC;gBAC9B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,IAAI,CAAC,cAAc,GAAG;oBACpB,aAAa,EAAE,IAAI,CAAC,cAAc;oBAClC,YAAY,EAAE,UAAU;oBACxB,IAAI;oBACJ,MAAM,EAAE,OAAO;iBAChB,CAAC;YACJ,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;IACjC,CAAC;IAED,2DAA2D;IACnD,iBAAiB;QACvB,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED,yEAAyE;IACjE,iBAAiB;QACvB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED,4DAA4D;IACpD,iBAAiB;QACvB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED,qEAAqE;IAC7D,cAAc;QACpB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED,0EAA0E;IAClE,eAAe;QACrB,cAAc,CAAC,GAAG,EAAE;YAClB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAClD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAOD,wDAAwD;IAChD,cAAc,CAAC,KAAoB;QACzC,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;YAC9B,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,KAAK,YAAY,EAAE,CAAC;YAC/B,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,+DAA+D;IACvD,kBAAkB,CAAC,KAAmB;QAC5C,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACnD,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,YAAY,iBAAiB,CAAC;YAAE,OAAO;QACvF,IAAI,CAAC,aAAa,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAChF,KAAK,CAAC,aAA6B,CAAC,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC1E,CAAC;IAED,0EAA0E;IAClE,gBAAgB,CAAC,KAAmB;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC;QACjC,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,SAAS;YAAE,OAAO;QAEnD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,gBAAgB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO;QAExF,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,6CAA6C;IACrC,oBAAoB;QAC1B,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;IACjC,CAAC;IAED,kEAAkE;IAC1D,cAAc,CAAC,KAAa,EAAE,KAA6B;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI;YAAE,OAAO,OAAO,CAAC;QAE1B,MAAM,UAAU,GAAG,KAAK,KAAK,UAAU,CAAC;QACxC,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;QAChG,OAAO,IAAI,CAAA;uBACQ,eAAe,gBAAgB,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;UACzE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;aACtB,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;aACnC,GAAG,CACF,CAAC,OAAO,EAAE,EAAE,CACV,IAAI,CAAA,iBAAiB,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC,WAAW,OAAO,CAAC,MAAM,KAAK,CAC3F;mBACQ,IAAI,CAAC,GAAG,QAAQ,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG;;KAExD,CAAC;IACJ,CAAC;IAED,iEAAiE;IACzD,aAAa,CAAC,SAAiB;QACrC,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,SAAS,GAAG,CAAC,CAAC;QAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC;QACjF,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,cAAc,IAAI,CAAC,YAAY;YAAE,OAAO,OAAO,CAAC;QAE1E,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,WAAW;YAChB,CAAC,CAAC,IAAI,CAAA,yBAAyB,IAAI,CAAC,YAAY,GAAG,CAAC,MAAM,SAAS,SAAS;YAC5E,CAAC,CAAC,OAAO;UACT,cAAc;YACd,CAAC,CAAC,IAAI,CAAA;;kBAEE,IAAI,CAAC,aAAa,CAAC,GAAG,CACtB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAA;;;;+CAIO,KAAK,GAAG,CAAC,OAAO,SAAS;qCACnC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,YAAY,CAAC;+BACzC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC;;mBAEhD,CACF;;aAEJ;YACH,CAAC,CAAC,OAAO;UACT,YAAY;YACZ,CAAC,CAAC,IAAI,CAAA;;;;6BAIa,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,iBAAiB;yBACxD,IAAI,CAAC,aAAa;;kBAEzB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;;aAEnC;YACH,CAAC,CAAC,OAAO;;KAEd,CAAC;IACJ,CAAC;IAED,+EAA+E;IAC5D,MAAM;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1D,MAAM,SAAS,GAA0B,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QAC5F,MAAM,cAAc,GAAG;YACrB,8BAA8B,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,QAAQ;YACnE,4BAA4B,EAAE,SAAS;SACxC,CAAC;QAEF,OAAO,IAAI,CAAA;;;;;;;mBAOI,IAAI,CAAC,cAAc;sBAChB,IAAI,CAAC,iBAAiB;sBACtB,IAAI,CAAC,iBAAiB;mBACzB,IAAI,CAAC,cAAc;oBAClB,IAAI,CAAC,eAAe;;UAE9B,WAAW;YACX,CAAC,CAAC,IAAI,CAAA;;;;0BAIU,QAAQ,CAAC,cAAc,CAAC;iCACjB,IAAI,CAAC,kBAAkB;+BACzB,IAAI,CAAC,gBAAgB;mCACjB,IAAI,CAAC,oBAAoB;;;sBAGtC,IAAI,CAAC,cAAc,KAAK,IAAI;gBAC5B,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC;sBACtD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC;;oBAEnD,IAAI,CAAC,YAAY,IAAI,SAAS,GAAG,CAAC;gBAClC,CAAC,CAAC,IAAI,CAAA;;;;;;qCAMW,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE;;8BAEjC,eAAe,CAAC,EAAE,CAAC;;;;;;qCAMZ,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE;;8BAE7B,gBAAgB,CAAC,EAAE,CAAC;;;uBAG3B;gBACH,CAAC,CAAC,OAAO;;kBAEX,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA,eAAe,WAAW,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,OAAO;;gBAEvF,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;aAChC;YACH,CAAC,CAAC,OAAO;4BACS,IAAI,CAAC,iBAAiB;;KAE7C,CAAC;IACJ,CAAC;CACF,CAAA;AAnnBC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;kDACrD;AAGW;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CAAW;AAItC;IADC,QAAQ,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC;kDAClD;AAIpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;iDACnC;AAIpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;oDACnC;AAIvB;IADC,QAAQ,CAAC,EAAE,SAAS,EAAE,uBAAuB,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC;yDACnD;AAI3B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;4CAC5B;AAIf;IADC,QAAQ,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;iDACjB;AAIvB;IADC,QAAQ,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;+CACK;AAG1B;IADhB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;mDACL;AAGvC;IADP,KAAK,EAAE;oDACqC;AAGrC;IADP,KAAK,EAAE;mDACkB;AA3Cf,YAAY;IADxB,aAAa,CAAC,eAAe,CAAC;GAClB,YAAY,CAsnBxB","sourcesContent":["import { LitElement, css, html, nothing, type PropertyValues } from \"lit\";\nimport { customElement, property, queryAssignedElements, state } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport type { GalleryItemVariant } from \"./gallery-item-variant.js\";\nimport { GalleryItem } from \"./gallery-item.js\";\nimport { iconChevronLeft, iconChevronRight } from \"./icons.js\";\nimport { tokens } from \"./tokens.js\";\n\nexport type PhotoGalleryObjectFit = \"cover\" | \"contain\";\nexport type PhotoGalleryChangeReason =\n | \"autoplay\"\n | \"indicator\"\n | \"items\"\n | \"keyboard\"\n | \"next\"\n | \"previous\"\n | \"programmatic\"\n | \"swipe\";\n\nexport interface PhotoGallerySlideChangeDetail {\n previousIndex: number;\n currentIndex: number;\n item: GalleryItem;\n reason: PhotoGalleryChangeReason;\n}\n\nconst transitionDurationMs = 250;\nconst swipeThresholdPx = 40;\nconst booleanAttribute = {\n fromAttribute(value: string | null): boolean {\n return value !== null && value !== \"false\";\n },\n};\n\n/**\n * Responsive, accessible image carousel composed from declarative\n * `gallery-item` children.\n *\n * @element photo-gallery\n * @slot - `gallery-item` elements rendered as slides.\n * @fires slide-change - The active image changed.\n */\n@customElement(\"photo-gallery\")\nexport class PhotoGallery extends LitElement {\n /** Zero-based active image index. */\n @property({ type: Number, attribute: \"current-index\", reflect: true })\n currentIndex = 0;\n\n /** Autoplay interval in milliseconds. Set to zero to disable autoplay. */\n @property({ type: Number }) delay = 0;\n\n /** Whether previous and next buttons are shown. */\n @property({ attribute: \"show-controls\", converter: booleanAttribute })\n showControls = true;\n\n /** Whether a current/total counter is shown. */\n @property({ type: Boolean, attribute: \"show-counter\" })\n showCounter = false;\n\n /** Whether clickable slide indicators are shown. */\n @property({ type: Boolean, attribute: \"show-indicators\" })\n showIndicators = false;\n\n /** Whether autoplay includes a built-in pause/play control. */\n @property({ attribute: \"show-autoplay-control\", converter: booleanAttribute })\n showAutoplayControl = true;\n\n /** Whether autoplay is explicitly paused. */\n @property({ type: Boolean, reflect: true })\n paused = false;\n\n /** CSS aspect ratio used by the image viewport. */\n @property({ attribute: \"aspect-ratio\" })\n aspectRatio = \"16 / 9\";\n\n /** How images fit within the stable viewport. */\n @property({ attribute: \"object-fit\" })\n objectFit: PhotoGalleryObjectFit = \"cover\";\n\n @queryAssignedElements({ selector: \"gallery-item\" })\n private readonly _galleryItems!: GalleryItem[];\n\n @state()\n private _previousIndex: number | null = null;\n\n @state()\n private _itemsVersion = 0;\n\n private _autoplayTimer?: number;\n private _transitionTimer?: number;\n private _metadataObserver?: MutationObserver;\n private _hovered = false;\n private _focusWithin = false;\n private _nextChangeReason: PhotoGalleryChangeReason | null = null;\n private _pendingChange?: PhotoGallerySlideChangeDetail;\n private _pointerStart?: { id: number; x: number; y: number };\n private _itemsChanged = false;\n private _activeItem?: GalleryItem;\n private _renderedIndex = 0;\n\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n color: var(--ui-text, #0f172a);\n font-family: var(\n --ui-font,\n ui-sans-serif,\n system-ui,\n sans-serif,\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"Segoe UI Symbol\",\n \"Noto Color Emoji\"\n );\n font-size: var(--ui-font-size, 0.875rem);\n }\n .gallery {\n outline: none;\n }\n figure {\n margin: 0;\n }\n .viewport {\n position: relative;\n overflow: hidden;\n aspect-ratio: var(--photo-gallery-aspect-ratio, 16 / 9);\n border-radius: var(--ui-radius, 0.5rem);\n background: var(--ui-surface-muted, #f8fafc);\n touch-action: pan-y;\n user-select: none;\n }\n .gallery:focus-visible .viewport {\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .slides {\n display: grid;\n width: 100%;\n height: 100%;\n }\n picture {\n grid-area: 1 / 1;\n display: block;\n width: 100%;\n height: 100%;\n }\n picture img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: var(--photo-gallery-object-fit, cover);\n }\n .entering {\n z-index: 2;\n animation: gallery-fade-in 250ms ease both;\n }\n .leaving {\n z-index: 1;\n pointer-events: none;\n animation: gallery-fade-out 250ms ease both;\n }\n .arrow-controls {\n position: absolute;\n z-index: 3;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem;\n pointer-events: none;\n }\n button {\n border: 0;\n font: inherit;\n cursor: pointer;\n }\n button:focus-visible {\n outline: none;\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .arrow-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n padding: 0;\n color: var(--ui-on-accent, #ffffff);\n background: var(--ui-overlay, rgb(15 23 42 / 0.45));\n border-radius: 9999px;\n pointer-events: auto;\n }\n .arrow-button:hover {\n background: color-mix(in srgb, var(--ui-text, #0f172a) 70%, transparent);\n }\n figcaption {\n padding: 0.5rem 0.25rem 0;\n color: var(--ui-text-muted, #64748b);\n }\n .footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.75rem;\n min-height: 2rem;\n padding-top: 0.5rem;\n }\n .counter {\n color: var(--ui-text-muted, #64748b);\n font-size: var(--ui-font-size-sm, 0.75rem);\n white-space: nowrap;\n }\n .indicators {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n }\n .indicator {\n width: 0.625rem;\n height: 0.625rem;\n padding: 0;\n background: var(--ui-border, #e2e8f0);\n border-radius: 9999px;\n }\n .indicator[aria-current=\"true\"] {\n background: var(--ui-primary, #4f46e5);\n }\n .autoplay-button {\n padding: 0.25rem 0.625rem;\n color: var(--ui-text, #0f172a);\n background: var(--ui-surface-muted, #f8fafc);\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: var(--ui-radius-sm, 0.25rem);\n font-size: var(--ui-font-size-sm, 0.75rem);\n white-space: nowrap;\n }\n .autoplay-button:hover {\n background: var(--ui-surface, #ffffff);\n }\n slot {\n display: none;\n }\n @keyframes gallery-fade-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n @keyframes gallery-fade-out {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .entering,\n .leaving {\n animation: none;\n }\n }\n `,\n ];\n\n /** Starts observers and autoplay integration when the element connects. */\n override connectedCallback(): void {\n super.connectedCallback();\n this._metadataObserver ??= new MutationObserver(() => this._handleMetadataChange());\n this._metadataObserver.observe(this, {\n attributes: true,\n attributeFilter: [\"alt\", \"caption\", \"media\", \"src\", \"srcset\"],\n childList: true,\n subtree: true,\n });\n document.addEventListener(\"visibilitychange\", this._handleVisibilityChange);\n }\n\n /** Releases timers and observers when the element disconnects. */\n override disconnectedCallback(): void {\n this._clearAutoplay();\n this._clearTransition();\n this._metadataObserver?.disconnect();\n document.removeEventListener(\"visibilitychange\", this._handleVisibilityChange);\n super.disconnectedCallback();\n }\n\n /** Normalizes external index changes before rendering. */\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (!changed.has(\"currentIndex\")) return;\n\n const normalized = this._normalizeIndex(this.currentIndex);\n if (normalized !== this.currentIndex) {\n this.currentIndex = normalized;\n }\n\n const previousValue = changed.get(\"currentIndex\");\n if (previousValue === undefined || this._galleryItems.length === 0) {\n this._nextChangeReason = null;\n return;\n }\n\n const previousIndex = this._normalizeIndex(Number(previousValue));\n if (previousIndex === normalized) {\n this._nextChangeReason = null;\n return;\n }\n\n const reason = this._nextChangeReason ?? \"programmatic\";\n this._previousIndex = reason === \"items\" ? null : previousIndex;\n this._pendingChange = {\n previousIndex,\n currentIndex: normalized,\n item: this._galleryItems[normalized],\n reason,\n };\n this._nextChangeReason = null;\n }\n\n /** Emits completed changes and keeps autoplay synchronized with properties. */\n protected override updated(changed: PropertyValues<this>): void {\n if (this._pendingChange) {\n this.dispatchEvent(\n new CustomEvent<PhotoGallerySlideChangeDetail>(\"slide-change\", {\n bubbles: true,\n composed: true,\n detail: this._pendingChange,\n }),\n );\n this._pendingChange = undefined;\n this._scheduleTransitionCleanup();\n }\n\n if (changed.has(\"currentIndex\") || changed.has(\"delay\") || changed.has(\"paused\") || this._itemsChanged) {\n this._itemsChanged = false;\n this._restartAutoplay();\n }\n this._activeItem = this._galleryItems[this.currentIndex];\n this._renderedIndex = this.currentIndex;\n }\n\n /** Wraps any requested index into the current item range. */\n private _normalizeIndex(index: number): number {\n const count = this._galleryItems.length;\n if (count === 0 || !Number.isFinite(index)) return 0;\n return ((Math.trunc(index) % count) + count) % count;\n }\n\n /** Returns responsive variants declared directly under an item. */\n private _variantsFor(item: GalleryItem): GalleryItemVariant[] {\n return Array.from(item.children).filter(\n (child): child is GalleryItemVariant => child.tagName.toLowerCase() === \"gallery-item-variant\",\n );\n }\n\n /** Changes slides through the shared state and event path. */\n private _goTo(index: number, reason: PhotoGalleryChangeReason): void {\n const normalized = this._normalizeIndex(index);\n if (this._galleryItems.length < 2 || normalized === this.currentIndex) {\n this._restartAutoplay();\n return;\n }\n\n this._nextChangeReason = reason;\n this.currentIndex = normalized;\n }\n\n /** Moves to the previous image. */\n private _showPrevious(reason: PhotoGalleryChangeReason = \"previous\"): void {\n this._goTo(this.currentIndex - 1, reason);\n }\n\n /** Moves to the next image. */\n private _showNext(reason: PhotoGalleryChangeReason = \"next\"): void {\n this._goTo(this.currentIndex + 1, reason);\n }\n\n /** Toggles explicit autoplay pause state. */\n private _togglePaused(): void {\n this.paused = !this.paused;\n }\n\n /** Clears and conditionally schedules the next autoplay advance. */\n private _restartAutoplay(): void {\n this._clearAutoplay();\n if (!this._canAutoplay()) return;\n\n this._autoplayTimer = window.setTimeout(() => {\n this._showNext(\"autoplay\");\n }, this.delay);\n }\n\n /** Reports whether autoplay may currently schedule a transition. */\n private _canAutoplay(): boolean {\n return (\n this.delay > 0 &&\n this._galleryItems.length > 1 &&\n !this.paused &&\n !this._hovered &&\n !this._focusWithin &&\n !document.hidden\n );\n }\n\n /** Clears the pending autoplay timeout. */\n private _clearAutoplay(): void {\n if (this._autoplayTimer === undefined) return;\n window.clearTimeout(this._autoplayTimer);\n this._autoplayTimer = undefined;\n }\n\n /** Removes the outgoing crossfade layer after the animation completes. */\n private _scheduleTransitionCleanup(): void {\n this._clearTransition();\n this._transitionTimer = window.setTimeout(() => {\n this._previousIndex = null;\n this._transitionTimer = undefined;\n }, transitionDurationMs);\n }\n\n /** Clears pending transition cleanup. */\n private _clearTransition(): void {\n if (this._transitionTimer === undefined) return;\n window.clearTimeout(this._transitionTimer);\n this._transitionTimer = undefined;\n }\n\n /** Refreshes item metadata and clamps the active index after light-DOM changes. */\n private _handleMetadataChange(): void {\n this._itemsChanged = true;\n this._itemsVersion += 1;\n const preserveActiveItem = this.currentIndex === this._renderedIndex;\n const preservedIndex =\n preserveActiveItem && this._activeItem ? this._galleryItems.indexOf(this._activeItem) : -1;\n const normalized = preservedIndex >= 0 ? preservedIndex : this._normalizeIndex(this.currentIndex);\n if (normalized === this.currentIndex) {\n const item = this._galleryItems[normalized];\n const activeItemRemoved = Boolean(this._activeItem && !this._galleryItems.includes(this._activeItem));\n if (item && activeItemRemoved) {\n this._previousIndex = null;\n this._pendingChange = {\n previousIndex: this._renderedIndex,\n currentIndex: normalized,\n item,\n reason: \"items\",\n };\n }\n return;\n }\n this._nextChangeReason = \"items\";\n this.currentIndex = normalized;\n }\n\n /** Refreshes item state after the default slot changes. */\n private _handleSlotChange(): void {\n this._handleMetadataChange();\n }\n\n /** Temporarily pauses autoplay while the pointer is over the gallery. */\n private _handleMouseEnter(): void {\n this._hovered = true;\n this._restartAutoplay();\n }\n\n /** Resumes autoplay with a fresh delay after hover ends. */\n private _handleMouseLeave(): void {\n this._hovered = false;\n this._restartAutoplay();\n }\n\n /** Temporarily pauses autoplay while focus is inside the gallery. */\n private _handleFocusIn(): void {\n this._focusWithin = true;\n this._restartAutoplay();\n }\n\n /** Resumes autoplay with a fresh delay after focus leaves the gallery. */\n private _handleFocusOut(): void {\n queueMicrotask(() => {\n this._focusWithin = this.matches(\":focus-within\");\n this._restartAutoplay();\n });\n }\n\n /** Pauses or resumes scheduling when page visibility changes. */\n private readonly _handleVisibilityChange = (): void => {\n this._restartAutoplay();\n };\n\n /** Handles Left and Right arrow keyboard navigation. */\n private _handleKeyDown(event: KeyboardEvent): void {\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n this._showPrevious(\"keyboard\");\n return;\n }\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n this._showNext(\"keyboard\");\n }\n }\n\n /** Records the starting point of a primary pointer gesture. */\n private _handlePointerDown(event: PointerEvent): void {\n if (!event.isPrimary || event.button !== 0) return;\n if (event.composedPath().some((target) => target instanceof HTMLButtonElement)) return;\n this._pointerStart = { id: event.pointerId, x: event.clientX, y: event.clientY };\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\n }\n\n /** Converts a sufficiently horizontal pointer gesture into navigation. */\n private _handlePointerUp(event: PointerEvent): void {\n const start = this._pointerStart;\n this._pointerStart = undefined;\n if (!start || start.id !== event.pointerId) return;\n\n const deltaX = event.clientX - start.x;\n const deltaY = event.clientY - start.y;\n if (Math.abs(deltaX) < swipeThresholdPx || Math.abs(deltaX) <= Math.abs(deltaY)) return;\n\n event.preventDefault();\n if (deltaX < 0) {\n this._showNext(\"swipe\");\n return;\n }\n this._showPrevious(\"swipe\");\n }\n\n /** Cancels an incomplete pointer gesture. */\n private _handlePointerCancel(): void {\n this._pointerStart = undefined;\n }\n\n /** Renders one responsive image layer for the crossfade stack. */\n private _renderPicture(index: number, state: \"current\" | \"previous\") {\n const item = this._galleryItems[index];\n if (!item) return nothing;\n\n const isPrevious = state === \"previous\";\n const transitionClass = this._previousIndex === null ? \"\" : isPrevious ? \"leaving\" : \"entering\";\n return html`\n <picture class=${transitionClass} aria-hidden=${isPrevious ? \"true\" : nothing}>\n ${this._variantsFor(item)\n .filter((variant) => variant.srcset)\n .map(\n (variant) =>\n html`<source media=${ifDefined(variant.media || undefined)} srcset=${variant.srcset} />`,\n )}\n <img src=${item.src} alt=${isPrevious ? \"\" : item.alt} draggable=\"false\" />\n </picture>\n `;\n }\n\n /** Renders enabled counter, indicator, and autoplay controls. */\n private _renderFooter(itemCount: number) {\n const showIndicators = this.showIndicators && itemCount > 1;\n const showAutoplay = this.showAutoplayControl && this.delay > 0 && itemCount > 1;\n if (!this.showCounter && !showIndicators && !showAutoplay) return nothing;\n\n return html`\n <div class=\"footer\">\n ${this.showCounter\n ? html`<span class=\"counter\">${this.currentIndex + 1} / ${itemCount}</span>`\n : nothing}\n ${showIndicators\n ? html`\n <div class=\"indicators\" role=\"group\" aria-label=\"Choose image\">\n ${this._galleryItems.map(\n (_item, index) => html`\n <button\n class=\"indicator\"\n type=\"button\"\n aria-label=\"Show image ${index + 1} of ${itemCount}\"\n aria-current=${String(index === this.currentIndex)}\n @click=${() => this._goTo(index, \"indicator\")}\n ></button>\n `,\n )}\n </div>\n `\n : nothing}\n ${showAutoplay\n ? html`\n <button\n class=\"autoplay-button\"\n type=\"button\"\n aria-label=${this.paused ? \"Resume slideshow\" : \"Pause slideshow\"}\n @click=${this._togglePaused}\n >\n ${this.paused ? \"Play\" : \"Pause\"}\n </button>\n `\n : nothing}\n </div>\n `;\n }\n\n /** Renders the active image, navigation, caption, and hidden metadata slot. */\n protected override render() {\n const itemCount = this._galleryItems.length;\n const currentItem = this._galleryItems[this.currentIndex];\n const objectFit: PhotoGalleryObjectFit = this.objectFit === \"contain\" ? \"contain\" : \"cover\";\n const viewportStyles = {\n \"--photo-gallery-aspect-ratio\": this.aspectRatio.trim() || \"16 / 9\",\n \"--photo-gallery-object-fit\": objectFit,\n };\n\n return html`\n <div\n class=\"gallery\"\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label=\"Photo gallery\"\n tabindex=\"0\"\n @keydown=${this._handleKeyDown}\n @mouseenter=${this._handleMouseEnter}\n @mouseleave=${this._handleMouseLeave}\n @focusin=${this._handleFocusIn}\n @focusout=${this._handleFocusOut}\n >\n ${currentItem\n ? html`\n <figure>\n <div\n class=\"viewport\"\n style=${styleMap(viewportStyles)}\n @pointerdown=${this._handlePointerDown}\n @pointerup=${this._handlePointerUp}\n @pointercancel=${this._handlePointerCancel}\n >\n <div class=\"slides\">\n ${this._previousIndex === null\n ? nothing\n : this._renderPicture(this._previousIndex, \"previous\")}\n ${this._renderPicture(this.currentIndex, \"current\")}\n </div>\n ${this.showControls && itemCount > 1\n ? html`\n <div class=\"arrow-controls\">\n <button\n class=\"arrow-button previous\"\n type=\"button\"\n aria-label=\"Previous image\"\n @click=${() => this._showPrevious()}\n >\n ${iconChevronLeft(24)}\n </button>\n <button\n class=\"arrow-button next\"\n type=\"button\"\n aria-label=\"Next image\"\n @click=${() => this._showNext()}\n >\n ${iconChevronRight(24)}\n </button>\n </div>\n `\n : nothing}\n </div>\n ${currentItem.caption ? html`<figcaption>${currentItem.caption}</figcaption>` : nothing}\n </figure>\n ${this._renderFooter(itemCount)}\n `\n : nothing}\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"photo-gallery\": PhotoGallery;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"popover-panel.d.ts","sourceRoot":"","sources":["../src/popover-panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAKjE;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,YAAa,SAAQ,UAAU;;IAC1C,gDAAgD;IACJ,IAAI,UAAS;IACzD,8CAA8C;IAClC,OAAO,SAAM;IACzB,uFAAuF;IAC3C,QAAQ,UAAS;IAE7D,OAAgB,MAAM,4BA8EpB;IAEO,oBAAoB,IAAI,IAAI,CAIpC;IAED,UAAmB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CASxD;IAqBQ,MAAM,yCAed;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,YAAY,CAAC;KAC/B;CACF"}
1
+ {"version":3,"file":"popover-panel.d.ts","sourceRoot":"","sources":["../src/popover-panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAW1E;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,YAAa,SAAQ,UAAU;;IAC1C,gDAAgD;IACJ,IAAI,UAAS;IACzD,8CAA8C;IAClC,OAAO,SAAM;IACzB,uFAAuF;IAC3C,QAAQ,UAAS;IAE7D,OAAgB,MAAM,4BAkGpB;IAKO,oBAAoB,IAAI,IAAI,CAUpC;IAED,UAAmB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAyBxD;IA0EQ,MAAM,yCAuBd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,YAAY,CAAC;KAC/B;CACF"}