@sankhyatronics/sankhya-cms 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/README.md +34 -3
  2. package/custom-elements.json +4008 -0
  3. package/dist/bento-grid/index.d.ts +27 -0
  4. package/dist/bento-grid/index.js +10 -0
  5. package/dist/bento-grid/index.js.map +1 -0
  6. package/dist/card/index.d.ts +20 -0
  7. package/dist/card/index.js +9 -0
  8. package/dist/card/index.js.map +1 -0
  9. package/dist/carousel/index.d.ts +44 -0
  10. package/dist/carousel/index.js +10 -0
  11. package/dist/carousel/index.js.map +1 -0
  12. package/dist/chunk-23IHTBAB.js +557 -0
  13. package/dist/chunk-23IHTBAB.js.map +1 -0
  14. package/dist/chunk-2VZFHTBC.js +203 -0
  15. package/dist/chunk-2VZFHTBC.js.map +1 -0
  16. package/dist/chunk-3ERKQNZT.js +155 -0
  17. package/dist/chunk-3ERKQNZT.js.map +1 -0
  18. package/dist/chunk-3JU3R22O.js +193 -0
  19. package/dist/chunk-3JU3R22O.js.map +1 -0
  20. package/dist/chunk-3TCP25JG.js +347 -0
  21. package/dist/chunk-3TCP25JG.js.map +1 -0
  22. package/dist/chunk-3VE6VFJ4.js +87 -0
  23. package/dist/chunk-3VE6VFJ4.js.map +1 -0
  24. package/dist/chunk-4HKSA5UT.js +312 -0
  25. package/dist/chunk-4HKSA5UT.js.map +1 -0
  26. package/dist/chunk-5REZSZCK.js +266 -0
  27. package/dist/chunk-5REZSZCK.js.map +1 -0
  28. package/dist/chunk-5UFRGZWG.js +268 -0
  29. package/dist/chunk-5UFRGZWG.js.map +1 -0
  30. package/dist/chunk-74MILER4.js +215 -0
  31. package/dist/chunk-74MILER4.js.map +1 -0
  32. package/dist/chunk-7PSYCTEN.js +118 -0
  33. package/dist/chunk-7PSYCTEN.js.map +1 -0
  34. package/dist/chunk-CDC4P77V.js +299 -0
  35. package/dist/chunk-CDC4P77V.js.map +1 -0
  36. package/dist/chunk-E52WO7R7.js +279 -0
  37. package/dist/chunk-E52WO7R7.js.map +1 -0
  38. package/dist/chunk-EUXUH3YW.js +15 -0
  39. package/dist/chunk-EUXUH3YW.js.map +1 -0
  40. package/dist/chunk-IMACP7HN.js +156 -0
  41. package/dist/chunk-IMACP7HN.js.map +1 -0
  42. package/dist/chunk-LHU23TF6.js +273 -0
  43. package/dist/chunk-LHU23TF6.js.map +1 -0
  44. package/dist/chunk-OEX5FDMR.js +250 -0
  45. package/dist/chunk-OEX5FDMR.js.map +1 -0
  46. package/dist/chunk-RHAOQ6K4.js +138 -0
  47. package/dist/chunk-RHAOQ6K4.js.map +1 -0
  48. package/dist/chunk-RMIJVTFS.js +397 -0
  49. package/dist/chunk-RMIJVTFS.js.map +1 -0
  50. package/dist/chunk-U7YKCCJG.js +228 -0
  51. package/dist/chunk-U7YKCCJG.js.map +1 -0
  52. package/dist/chunk-USNFT4DU.js +125 -0
  53. package/dist/chunk-USNFT4DU.js.map +1 -0
  54. package/dist/chunk-VYON56QO.js +90 -0
  55. package/dist/chunk-VYON56QO.js.map +1 -0
  56. package/dist/chunk-WCO7JAIK.js +195 -0
  57. package/dist/chunk-WCO7JAIK.js.map +1 -0
  58. package/dist/chunk-XHBC23TV.js +254 -0
  59. package/dist/chunk-XHBC23TV.js.map +1 -0
  60. package/dist/chunk-XXPBFHWR.js +70 -0
  61. package/dist/chunk-XXPBFHWR.js.map +1 -0
  62. package/dist/cms-theme.css +15 -0
  63. package/dist/content-block/index.d.ts +25 -0
  64. package/dist/content-block/index.js +11 -0
  65. package/dist/content-block/index.js.map +1 -0
  66. package/dist/cookie-consent/index.d.ts +33 -0
  67. package/dist/cookie-consent/index.js +9 -0
  68. package/dist/cookie-consent/index.js.map +1 -0
  69. package/dist/dropdown/index.d.ts +89 -0
  70. package/dist/dropdown/index.js +9 -0
  71. package/dist/dropdown/index.js.map +1 -0
  72. package/dist/feature-split/index.d.ts +38 -0
  73. package/dist/feature-split/index.js +11 -0
  74. package/dist/feature-split/index.js.map +1 -0
  75. package/dist/features-section/index.d.ts +50 -0
  76. package/dist/features-section/index.js +14 -0
  77. package/dist/features-section/index.js.map +1 -0
  78. package/dist/footer/index.d.ts +64 -0
  79. package/dist/footer/index.js +9 -0
  80. package/dist/footer/index.js.map +1 -0
  81. package/dist/header/index.d.ts +112 -0
  82. package/dist/header/index.js +10 -0
  83. package/dist/header/index.js.map +1 -0
  84. package/dist/hero/index.d.ts +32 -0
  85. package/dist/hero/index.js +10 -0
  86. package/dist/hero/index.js.map +1 -0
  87. package/dist/icon-button/index.d.ts +23 -0
  88. package/dist/icon-button/index.js +9 -0
  89. package/dist/icon-button/index.js.map +1 -0
  90. package/dist/index.d.ts +22 -0
  91. package/dist/index.js +93 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/items-accordion/index.d.ts +31 -0
  94. package/dist/items-accordion/index.js +10 -0
  95. package/dist/items-accordion/index.js.map +1 -0
  96. package/dist/markdown/index.d.ts +33 -0
  97. package/dist/markdown/index.js +9 -0
  98. package/dist/markdown/index.js.map +1 -0
  99. package/dist/menu-grid/index.d.ts +21 -0
  100. package/dist/menu-grid/index.js +9 -0
  101. package/dist/menu-grid/index.js.map +1 -0
  102. package/dist/menu-grid-item/index.d.ts +53 -0
  103. package/dist/menu-grid-item/index.js +9 -0
  104. package/dist/menu-grid-item/index.js.map +1 -0
  105. package/dist/menu-item/index.d.ts +50 -0
  106. package/dist/menu-item/index.js +9 -0
  107. package/dist/menu-item/index.js.map +1 -0
  108. package/dist/promo-banner/index.d.ts +22 -0
  109. package/dist/promo-banner/index.js +10 -0
  110. package/dist/promo-banner/index.js.map +1 -0
  111. package/dist/schema/index.d.ts +72 -0
  112. package/dist/schema/index.js +75 -0
  113. package/dist/schema/index.js.map +1 -0
  114. package/dist/select/index.d.ts +77 -0
  115. package/dist/select/index.js +10 -0
  116. package/dist/select/index.js.map +1 -0
  117. package/dist/shared/icons.d.ts +77 -0
  118. package/dist/shared/icons.js +64 -0
  119. package/dist/shared/icons.js.map +1 -0
  120. package/dist/shared/styles.d.ts +90 -0
  121. package/dist/shared/styles.js +48 -0
  122. package/dist/shared/styles.js.map +1 -0
  123. package/dist/stats/index.d.ts +17 -0
  124. package/dist/stats/index.js +9 -0
  125. package/dist/stats/index.js.map +1 -0
  126. package/dist/testimonials/index.d.ts +25 -0
  127. package/dist/testimonials/index.js +10 -0
  128. package/dist/testimonials/index.js.map +1 -0
  129. package/dist/theme.css +292 -0
  130. package/dist/themes.css +65 -0
  131. package/dist/theming/index.d.ts +28 -0
  132. package/dist/theming/index.js +53 -0
  133. package/dist/theming/index.js.map +1 -0
  134. package/package.json +161 -4
@@ -0,0 +1,299 @@
1
+ import {
2
+ controlBaseStyles,
3
+ rootFontFamilyStyles
4
+ } from "./chunk-RHAOQ6K4.js";
5
+ import {
6
+ __decorateClass
7
+ } from "./chunk-EUXUH3YW.js";
8
+
9
+ // src/footer/Footer.ts
10
+ import { LitElement, css, html, nothing } from "lit";
11
+ import { customElement, property } from "lit/decorators.js";
12
+ import "iconify-icon";
13
+ var Footer = class extends LitElement {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.inverted = false;
17
+ this.companyName = "";
18
+ this.copyright = "";
19
+ this.poweredBy = "";
20
+ this.poweredByLink = "";
21
+ this.version = "";
22
+ this.imageSrc = "";
23
+ this.description = "";
24
+ this.columns = [];
25
+ this.socialLinks = [];
26
+ }
27
+ get isSite() {
28
+ return !!(this.columns.length || this.socialLinks.length || this.description || this.imageSrc);
29
+ }
30
+ get resolvedCopyright() {
31
+ if (this.copyright) return this.copyright;
32
+ if (this.companyName) return `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} ${this.companyName}`;
33
+ return `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()}`;
34
+ }
35
+ willUpdate(changed) {
36
+ if (changed.size) this.toggleAttribute("site", this.isSite);
37
+ }
38
+ onLinkClick(event, href) {
39
+ const select = new CustomEvent("footer-link", {
40
+ detail: { href },
41
+ bubbles: true,
42
+ composed: true,
43
+ cancelable: true
44
+ });
45
+ this.dispatchEvent(select);
46
+ if (select.defaultPrevented) event.preventDefault();
47
+ }
48
+ renderLink(link) {
49
+ return /^https?:/i.test(link.href) ? html`<a part="link" class="link" href=${link.href} target="_blank" rel="noopener noreferrer">${link.label}</a>` : html`<a part="link" class="link" href=${link.href} @click=${(event) => this.onLinkClick(event, link.href)}>${link.label}</a>`;
50
+ }
51
+ renderPoweredBy() {
52
+ return this.poweredBy ? html`
53
+ <a part="powered-by" class="powered-by" href=${this.poweredByLink || "#"} target="_blank" rel="noopener noreferrer">
54
+ ${this.poweredBy}
55
+ </a>
56
+ ` : nothing;
57
+ }
58
+ renderSite() {
59
+ return html`
60
+ <div class="site" part="site">
61
+ <div class="grid">
62
+ <div class="brand" part="brand">
63
+ ${this.imageSrc || this.companyName ? html`<div class="logo">
64
+ ${this.imageSrc ? html`<img class="logo-img" src=${this.imageSrc} alt=${this.companyName || "Logo"} />` : nothing}
65
+ ${this.companyName ? html`<span>${this.companyName}</span>` : nothing}
66
+ </div>` : nothing}
67
+ ${this.description ? html`<p class="description">${this.description}</p>` : nothing}
68
+ ${this.socialLinks.length ? html`<div class="social">
69
+ ${this.socialLinks.map(
70
+ (social) => html`<a part="social" class="social-link" href=${social.href} target="_blank" rel="noopener noreferrer" aria-label=${social.icon}>
71
+ <iconify-icon icon=${social.icon} width="24" height="24"></iconify-icon>
72
+ </a>`
73
+ )}
74
+ </div>` : nothing}
75
+ </div>
76
+ ${this.columns.map(
77
+ (column) => html`<div class="column" part="column">
78
+ <h4 class="column-title">${column.title}</h4>
79
+ <div class="links">${column.links.map((link) => this.renderLink(link))}</div>
80
+ </div>`
81
+ )}
82
+ </div>
83
+ <div class="bottom" part="bottom">
84
+ <div class="bottom-text">
85
+ <span part="copyright">${this.resolvedCopyright}</span>
86
+ ${this.version ? html`<span part="version">v${this.version}</span>` : nothing} ${this.renderPoweredBy()}
87
+ </div>
88
+ </div>
89
+ </div>
90
+ `;
91
+ }
92
+ render() {
93
+ if (this.isSite) return this.renderSite();
94
+ return html`
95
+ <span part="copyright">${this.resolvedCopyright}</span>
96
+ ${this.version ? html`<span part="version">v${this.version}</span>` : nothing} ${this.renderPoweredBy()}
97
+ `;
98
+ }
99
+ };
100
+ Footer.styles = css`
101
+ ${controlBaseStyles}
102
+
103
+ :host {
104
+ display: flex;
105
+ align-items: center;
106
+ justify-content: space-between;
107
+ gap: var(--st-space-16);
108
+ flex-wrap: wrap;
109
+ /* !important on padding/border-top only: a shadow host's own :host rule always loses to ANY
110
+ * rule the consuming page has for the same property on that element, regardless of
111
+ * specificity — so a page that resets margin/padding/border on every element (e.g. Tailwind
112
+ * Preflight, which every app but Template Hub loads) silently zeroes this footer's padding
113
+ * and top border unless these two win the conflict outright via !important. */
114
+ padding: var(--st-space-16) var(--st-space-28) !important;
115
+ border-top: 1px solid var(--st-color-border) !important;
116
+ color: var(--st-color-text-muted);
117
+ font-size: var(--st-text-xs);
118
+ ${rootFontFamilyStyles}
119
+ }
120
+
121
+ .powered-by {
122
+ color: inherit;
123
+ text-decoration: none;
124
+ font-weight: var(--st-font-weight-semibold);
125
+ }
126
+
127
+ .powered-by:hover {
128
+ color: var(--st-color-text-strong);
129
+ }
130
+
131
+ :host([inverted]) {
132
+ background: var(--st-color-text-strong);
133
+ color: var(--st-color-on-solid);
134
+ border-top-color: transparent !important;
135
+ }
136
+
137
+ /* Site layout */
138
+ :host([site]) {
139
+ display: block;
140
+ padding: 64px var(--st-space-28) 32px !important;
141
+ font-size: var(--st-text-sm);
142
+ }
143
+
144
+ .site {
145
+ max-width: 1200px;
146
+ margin: 0 auto;
147
+ }
148
+
149
+ .grid {
150
+ display: grid;
151
+ grid-template-columns: 2fr repeat(3, 1fr);
152
+ gap: 64px;
153
+ margin-bottom: 64px;
154
+ }
155
+
156
+ .brand {
157
+ display: flex;
158
+ flex-direction: column;
159
+ gap: 16px;
160
+ }
161
+
162
+ .logo {
163
+ display: flex;
164
+ align-items: center;
165
+ gap: 8px;
166
+ font-size: 1.25rem;
167
+ font-weight: 700;
168
+ color: var(--st-color-text-strong);
169
+ }
170
+
171
+ .logo-img {
172
+ height: 32px;
173
+ width: auto;
174
+ }
175
+
176
+ .description {
177
+ margin: 0;
178
+ max-width: 300px;
179
+ line-height: 1.6;
180
+ }
181
+
182
+ .social {
183
+ display: flex;
184
+ gap: 16px;
185
+ margin-top: 16px;
186
+ }
187
+
188
+ .social-link,
189
+ .link {
190
+ color: inherit;
191
+ text-decoration: none;
192
+ transition: color 0.2s ease;
193
+ }
194
+
195
+ .social-link:hover,
196
+ .link:hover {
197
+ color: var(--st-color-text-strong);
198
+ }
199
+
200
+ .column-title {
201
+ margin: 0 0 24px;
202
+ font-size: var(--st-text-xs);
203
+ font-weight: var(--st-font-weight-semibold);
204
+ color: var(--st-color-text-strong);
205
+ text-transform: uppercase;
206
+ letter-spacing: 0.05em;
207
+ }
208
+
209
+ .links {
210
+ display: flex;
211
+ flex-direction: column;
212
+ gap: 16px;
213
+ }
214
+
215
+ .bottom {
216
+ padding-top: 32px;
217
+ border-top: 1px solid var(--st-color-border);
218
+ font-size: var(--st-text-xs);
219
+ }
220
+
221
+ .bottom-text {
222
+ display: flex;
223
+ flex-direction: column;
224
+ gap: 4px;
225
+ }
226
+
227
+ .bottom-text .powered-by {
228
+ font-size: 0.85em;
229
+ font-weight: inherit;
230
+ opacity: 0.8;
231
+ }
232
+
233
+ @media (max-width: 1024px) {
234
+ .grid {
235
+ grid-template-columns: repeat(3, 1fr);
236
+ gap: 48px;
237
+ }
238
+ }
239
+
240
+ @media (max-width: 768px) {
241
+ .grid {
242
+ grid-template-columns: 1fr;
243
+ gap: 40px;
244
+ }
245
+
246
+ .bottom {
247
+ text-align: center;
248
+ }
249
+ }
250
+
251
+ :host([site][inverted]) .logo,
252
+ :host([site][inverted]) .column-title,
253
+ :host([site][inverted]) .social-link:hover,
254
+ :host([site][inverted]) .link:hover {
255
+ color: var(--st-color-on-solid);
256
+ }
257
+
258
+ :host([site][inverted]) .bottom {
259
+ border-top-color: color-mix(in oklch, var(--st-color-on-solid) 20%, var(--st-color-text-strong));
260
+ }
261
+ `;
262
+ __decorateClass([
263
+ property({ type: Boolean, reflect: true })
264
+ ], Footer.prototype, "inverted", 2);
265
+ __decorateClass([
266
+ property({ type: String, attribute: "company-name" })
267
+ ], Footer.prototype, "companyName", 2);
268
+ __decorateClass([
269
+ property({ type: String })
270
+ ], Footer.prototype, "copyright", 2);
271
+ __decorateClass([
272
+ property({ type: String, attribute: "powered-by" })
273
+ ], Footer.prototype, "poweredBy", 2);
274
+ __decorateClass([
275
+ property({ type: String, attribute: "powered-by-link" })
276
+ ], Footer.prototype, "poweredByLink", 2);
277
+ __decorateClass([
278
+ property({ type: String })
279
+ ], Footer.prototype, "version", 2);
280
+ __decorateClass([
281
+ property({ type: String, attribute: "image-src" })
282
+ ], Footer.prototype, "imageSrc", 2);
283
+ __decorateClass([
284
+ property({ type: String })
285
+ ], Footer.prototype, "description", 2);
286
+ __decorateClass([
287
+ property({ attribute: false })
288
+ ], Footer.prototype, "columns", 2);
289
+ __decorateClass([
290
+ property({ attribute: false })
291
+ ], Footer.prototype, "socialLinks", 2);
292
+ Footer = __decorateClass([
293
+ customElement("st-footer")
294
+ ], Footer);
295
+
296
+ export {
297
+ Footer
298
+ };
299
+ //# sourceMappingURL=chunk-CDC4P77V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/footer/Footer.ts"],"sourcesContent":["import { LitElement, PropertyValues, css, html, nothing } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\nimport 'iconify-icon';\r\n\r\nimport { controlBaseStyles, rootFontFamilyStyles } from '../shared/styles';\r\n\r\nexport interface FooterLink {\r\n label: string;\r\n href: string;\r\n}\r\n\r\nexport interface FooterColumn {\r\n title: string;\r\n links: FooterLink[];\r\n}\r\n\r\nexport interface FooterSocialLink {\r\n /** Iconify icon name, e.g. `mdi:github`. */\r\n icon: string;\r\n href: string;\r\n}\r\n\r\n/** Fired when an internal footer link is activated — cancelable, so an SPA can `preventDefault()` and route instead. */\r\nexport interface FooterLinkEventDetail {\r\n href: string;\r\n}\r\n\r\n/**\r\n * The footer, in two layouts:\r\n *\r\n * - **Bar** (default): a copyright line plus an optional \"powered by\" link — what the suite's\r\n * authenticated apps use.\r\n * - **Site**: when `columns`, `socialLinks`, `description` or `imageSrc` is set, the footer becomes a\r\n * marketing-site footer — brand (logo/company name, description, social icons), link columns and a\r\n * bottom bar with the copyright and \"powered by\".\r\n *\r\n * Fires a cancelable `footer-link` event (detail `{ href }`) when an internal link is clicked.\r\n */\r\n@customElement('st-footer')\r\nexport class Footer extends LitElement {\r\n static styles = css`\r\n ${controlBaseStyles}\r\n\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: var(--st-space-16);\r\n flex-wrap: wrap;\r\n /* !important on padding/border-top only: a shadow host's own :host rule always loses to ANY\r\n * rule the consuming page has for the same property on that element, regardless of\r\n * specificity — so a page that resets margin/padding/border on every element (e.g. Tailwind\r\n * Preflight, which every app but Template Hub loads) silently zeroes this footer's padding\r\n * and top border unless these two win the conflict outright via !important. */\r\n padding: var(--st-space-16) var(--st-space-28) !important;\r\n border-top: 1px solid var(--st-color-border) !important;\r\n color: var(--st-color-text-muted);\r\n font-size: var(--st-text-xs);\r\n ${rootFontFamilyStyles}\r\n }\r\n\r\n .powered-by {\r\n color: inherit;\r\n text-decoration: none;\r\n font-weight: var(--st-font-weight-semibold);\r\n }\r\n\r\n .powered-by:hover {\r\n color: var(--st-color-text-strong);\r\n }\r\n\r\n :host([inverted]) {\r\n background: var(--st-color-text-strong);\r\n color: var(--st-color-on-solid);\r\n border-top-color: transparent !important;\r\n }\r\n\r\n /* Site layout */\r\n :host([site]) {\r\n display: block;\r\n padding: 64px var(--st-space-28) 32px !important;\r\n font-size: var(--st-text-sm);\r\n }\r\n\r\n .site {\r\n max-width: 1200px;\r\n margin: 0 auto;\r\n }\r\n\r\n .grid {\r\n display: grid;\r\n grid-template-columns: 2fr repeat(3, 1fr);\r\n gap: 64px;\r\n margin-bottom: 64px;\r\n }\r\n\r\n .brand {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n }\r\n\r\n .logo {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n font-size: 1.25rem;\r\n font-weight: 700;\r\n color: var(--st-color-text-strong);\r\n }\r\n\r\n .logo-img {\r\n height: 32px;\r\n width: auto;\r\n }\r\n\r\n .description {\r\n margin: 0;\r\n max-width: 300px;\r\n line-height: 1.6;\r\n }\r\n\r\n .social {\r\n display: flex;\r\n gap: 16px;\r\n margin-top: 16px;\r\n }\r\n\r\n .social-link,\r\n .link {\r\n color: inherit;\r\n text-decoration: none;\r\n transition: color 0.2s ease;\r\n }\r\n\r\n .social-link:hover,\r\n .link:hover {\r\n color: var(--st-color-text-strong);\r\n }\r\n\r\n .column-title {\r\n margin: 0 0 24px;\r\n font-size: var(--st-text-xs);\r\n font-weight: var(--st-font-weight-semibold);\r\n color: var(--st-color-text-strong);\r\n text-transform: uppercase;\r\n letter-spacing: 0.05em;\r\n }\r\n\r\n .links {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n }\r\n\r\n .bottom {\r\n padding-top: 32px;\r\n border-top: 1px solid var(--st-color-border);\r\n font-size: var(--st-text-xs);\r\n }\r\n\r\n .bottom-text {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n }\r\n\r\n .bottom-text .powered-by {\r\n font-size: 0.85em;\r\n font-weight: inherit;\r\n opacity: 0.8;\r\n }\r\n\r\n @media (max-width: 1024px) {\r\n .grid {\r\n grid-template-columns: repeat(3, 1fr);\r\n gap: 48px;\r\n }\r\n }\r\n\r\n @media (max-width: 768px) {\r\n .grid {\r\n grid-template-columns: 1fr;\r\n gap: 40px;\r\n }\r\n\r\n .bottom {\r\n text-align: center;\r\n }\r\n }\r\n\r\n :host([site][inverted]) .logo,\r\n :host([site][inverted]) .column-title,\r\n :host([site][inverted]) .social-link:hover,\r\n :host([site][inverted]) .link:hover {\r\n color: var(--st-color-on-solid);\r\n }\r\n\r\n :host([site][inverted]) .bottom {\r\n border-top-color: color-mix(in oklch, var(--st-color-on-solid) 20%, var(--st-color-text-strong));\r\n }\r\n `;\r\n\r\n /** Inverts the footer's color roles (light-on-dark instead of dark-on-light) — matches the\r\n * source component's `inverted` (from its shared `BaseProps`), same as `st-header`'s. */\r\n @property({ type: Boolean, reflect: true })\r\n inverted = false;\r\n\r\n /** Used to build the default `copyright` line (`© {year} {companyName}`) when `copyright` isn't set explicitly. */\r\n @property({ type: String, attribute: 'company-name' })\r\n companyName = '';\r\n\r\n /** Overrides the default computed copyright line entirely. */\r\n @property({ type: String })\r\n copyright = '';\r\n\r\n @property({ type: String, attribute: 'powered-by' })\r\n poweredBy = '';\r\n\r\n @property({ type: String, attribute: 'powered-by-link' })\r\n poweredByLink = '';\r\n\r\n /** App version, rendered as `v{version}` after the copyright line — for apps that show their own\r\n * version in the footer rather than the header title. */\r\n @property({ type: String })\r\n version = '';\r\n\r\n /** Logo shown in the brand block (site layout). */\r\n @property({ type: String, attribute: 'image-src' })\r\n imageSrc = '';\r\n\r\n /** Short blurb under the logo (site layout). */\r\n @property({ type: String })\r\n description = '';\r\n\r\n /** Link columns (site layout). */\r\n @property({ attribute: false })\r\n columns: FooterColumn[] = [];\r\n\r\n /** Social icon links under the description (site layout). */\r\n @property({ attribute: false })\r\n socialLinks: FooterSocialLink[] = [];\r\n\r\n private get isSite(): boolean {\r\n return !!(this.columns.length || this.socialLinks.length || this.description || this.imageSrc);\r\n }\r\n\r\n private get resolvedCopyright(): string {\r\n if (this.copyright) return this.copyright;\r\n if (this.companyName) return `© ${new Date().getFullYear()} ${this.companyName}`;\r\n return `© ${new Date().getFullYear()}`;\r\n }\r\n\r\n protected willUpdate(changed: PropertyValues): void {\r\n if (changed.size) this.toggleAttribute('site', this.isSite);\r\n }\r\n\r\n private onLinkClick(event: MouseEvent, href: string): void {\r\n const select = new CustomEvent<FooterLinkEventDetail>('footer-link', {\r\n detail: { href },\r\n bubbles: true,\r\n composed: true,\r\n cancelable: true\r\n });\r\n this.dispatchEvent(select);\r\n if (select.defaultPrevented) event.preventDefault();\r\n }\r\n\r\n private renderLink(link: FooterLink) {\r\n return /^https?:/i.test(link.href)\r\n ? html`<a part=\"link\" class=\"link\" href=${link.href} target=\"_blank\" rel=\"noopener noreferrer\">${link.label}</a>`\r\n : html`<a part=\"link\" class=\"link\" href=${link.href} @click=${(event: MouseEvent) => this.onLinkClick(event, link.href)}>${link.label}</a>`;\r\n }\r\n\r\n private renderPoweredBy() {\r\n return this.poweredBy\r\n ? html`\r\n <a part=\"powered-by\" class=\"powered-by\" href=${this.poweredByLink || '#'} target=\"_blank\" rel=\"noopener noreferrer\">\r\n ${this.poweredBy}\r\n </a>\r\n `\r\n : nothing;\r\n }\r\n\r\n private renderSite() {\r\n return html`\r\n <div class=\"site\" part=\"site\">\r\n <div class=\"grid\">\r\n <div class=\"brand\" part=\"brand\">\r\n ${this.imageSrc || this.companyName\r\n ? html`<div class=\"logo\">\r\n ${this.imageSrc ? html`<img class=\"logo-img\" src=${this.imageSrc} alt=${this.companyName || 'Logo'} />` : nothing}\r\n ${this.companyName ? html`<span>${this.companyName}</span>` : nothing}\r\n </div>`\r\n : nothing}\r\n ${this.description ? html`<p class=\"description\">${this.description}</p>` : nothing}\r\n ${this.socialLinks.length\r\n ? html`<div class=\"social\">\r\n ${this.socialLinks.map(\r\n social => html`<a part=\"social\" class=\"social-link\" href=${social.href} target=\"_blank\" rel=\"noopener noreferrer\" aria-label=${social.icon}>\r\n <iconify-icon icon=${social.icon} width=\"24\" height=\"24\"></iconify-icon>\r\n </a>`\r\n )}\r\n </div>`\r\n : nothing}\r\n </div>\r\n ${this.columns.map(\r\n column => html`<div class=\"column\" part=\"column\">\r\n <h4 class=\"column-title\">${column.title}</h4>\r\n <div class=\"links\">${column.links.map(link => this.renderLink(link))}</div>\r\n </div>`\r\n )}\r\n </div>\r\n <div class=\"bottom\" part=\"bottom\">\r\n <div class=\"bottom-text\">\r\n <span part=\"copyright\">${this.resolvedCopyright}</span>\r\n ${this.version ? html`<span part=\"version\">v${this.version}</span>` : nothing} ${this.renderPoweredBy()}\r\n </div>\r\n </div>\r\n </div>\r\n `;\r\n }\r\n\r\n render() {\r\n if (this.isSite) return this.renderSite();\r\n return html`\r\n <span part=\"copyright\">${this.resolvedCopyright}</span>\r\n ${this.version ? html`<span part=\"version\">v${this.version}</span>` : nothing} ${this.renderPoweredBy()}\r\n `;\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,279 @@
1
+ import {
2
+ cardDescriptionStyles,
3
+ cardTitleStyles,
4
+ sectionHeaderStyles,
5
+ sectionSubtitleStyles,
6
+ sectionTitleStyles
7
+ } from "./chunk-3VE6VFJ4.js";
8
+ import {
9
+ controlBaseStyles,
10
+ fontFamilyStyles
11
+ } from "./chunk-RHAOQ6K4.js";
12
+ import {
13
+ __decorateClass
14
+ } from "./chunk-EUXUH3YW.js";
15
+
16
+ // src/features-section/FeaturesSection.ts
17
+ import { LitElement as LitElement2, css as css2, html as html2, nothing as nothing2 } from "lit";
18
+ import { customElement as customElement2, property as property2 } from "lit/decorators.js";
19
+
20
+ // src/features-section/FeatureItem.ts
21
+ import { LitElement, css, html, nothing } from "lit";
22
+ import { customElement, property } from "lit/decorators.js";
23
+ import "iconify-icon";
24
+ var FeatureItem = class extends LitElement {
25
+ constructor() {
26
+ super(...arguments);
27
+ this.icon = "";
28
+ this.title = "";
29
+ this.description = "";
30
+ this.href = "";
31
+ this.actionLabel = "Learn more";
32
+ this.inverted = false;
33
+ }
34
+ render() {
35
+ const external = this.href.startsWith("http");
36
+ return html`
37
+ <st-card hoverable elevation="sm" ?inverted=${this.inverted} part="card">
38
+ <div class="content" part="content">
39
+ ${this.icon ? html`<div class="icon" part="icon"><iconify-icon icon=${this.icon}></iconify-icon></div>` : nothing}
40
+ <h3 class="title" part="title">${this.title}</h3>
41
+ <st-markdown class="description" part="description" .content=${this.description}></st-markdown>
42
+ ${this.href ? html`
43
+ <a
44
+ class="link"
45
+ part="link"
46
+ href=${this.href}
47
+ target=${external ? "_blank" : "_self"}
48
+ rel=${external ? "noopener noreferrer" : nothing}
49
+ >
50
+ ${this.actionLabel} <span>&rarr;</span>
51
+ </a>
52
+ ` : nothing}
53
+ </div>
54
+ </st-card>
55
+ `;
56
+ }
57
+ };
58
+ FeatureItem.styles = css`
59
+ ${controlBaseStyles}
60
+
61
+ :host {
62
+ display: block;
63
+ ${fontFamilyStyles}
64
+ }
65
+
66
+ st-card {
67
+ height: 100%;
68
+ }
69
+
70
+ .content {
71
+ display: flex;
72
+ flex-direction: column;
73
+ align-items: flex-start;
74
+ gap: var(--st-space-16);
75
+ height: 100%;
76
+ }
77
+
78
+ .icon {
79
+ display: flex;
80
+ align-items: center;
81
+ justify-content: center;
82
+ width: 48px;
83
+ height: 48px;
84
+ border-radius: var(--st-radius-lg);
85
+ background: var(--st-color-subtle);
86
+ color: var(--st-color-text-strong);
87
+ margin-bottom: var(--st-space-8);
88
+ font-size: 24px;
89
+ }
90
+
91
+ :host([inverted]) .icon {
92
+ background: var(--st-color-text-muted);
93
+ color: var(--st-color-on-solid);
94
+ }
95
+
96
+ .title {
97
+ ${cardTitleStyles}
98
+ margin: 0;
99
+ }
100
+
101
+ .description {
102
+ ${cardDescriptionStyles}
103
+ margin: 0;
104
+ }
105
+
106
+ :host([inverted]) .title,
107
+ :host([inverted]) .description {
108
+ color: inherit;
109
+ }
110
+
111
+ .link {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: var(--st-space-4);
115
+ margin-top: auto;
116
+ color: var(--st-color-text-muted);
117
+ font-weight: var(--st-font-weight-medium);
118
+ font-size: var(--st-text-md);
119
+ text-decoration: none;
120
+ transition: color 0.2s ease;
121
+ }
122
+
123
+ .link:hover {
124
+ color: var(--st-color-text-strong);
125
+ text-decoration: underline;
126
+ }
127
+
128
+ :host([inverted]) .link,
129
+ :host([inverted]) .link:hover {
130
+ color: inherit;
131
+ }
132
+
133
+ @media (prefers-reduced-motion: reduce) {
134
+ .link {
135
+ transition: none;
136
+ }
137
+ }
138
+ `;
139
+ __decorateClass([
140
+ property({ type: String })
141
+ ], FeatureItem.prototype, "icon", 2);
142
+ __decorateClass([
143
+ property({ type: String })
144
+ ], FeatureItem.prototype, "title", 2);
145
+ __decorateClass([
146
+ property({ type: String })
147
+ ], FeatureItem.prototype, "description", 2);
148
+ __decorateClass([
149
+ property({ type: String })
150
+ ], FeatureItem.prototype, "href", 2);
151
+ __decorateClass([
152
+ property({ type: String, attribute: "action-label" })
153
+ ], FeatureItem.prototype, "actionLabel", 2);
154
+ __decorateClass([
155
+ property({ type: Boolean, reflect: true })
156
+ ], FeatureItem.prototype, "inverted", 2);
157
+ FeatureItem = __decorateClass([
158
+ customElement("st-feature-item")
159
+ ], FeatureItem);
160
+
161
+ // src/features-section/FeaturesSection.ts
162
+ var FeaturesSection = class extends LitElement2 {
163
+ constructor() {
164
+ super(...arguments);
165
+ this.title = "";
166
+ this.subtitle = "";
167
+ this.actionLabel = "Learn more";
168
+ this.columns = 0;
169
+ this.inverted = false;
170
+ this.items = [];
171
+ }
172
+ render() {
173
+ const gridStyle = this.columns ? `--features-columns: ${this.columns}` : nothing2;
174
+ return html2`
175
+ <section class="container" part="container">
176
+ <div class="header" part="header">
177
+ <div class="title" part="title">${this.title}</div>
178
+ ${this.subtitle ? html2`<div class="subtitle" part="subtitle">${this.subtitle}</div>` : nothing2}
179
+ </div>
180
+ <div class="grid" part="grid" style=${gridStyle}>
181
+ <slot></slot>
182
+ ${this.items.map(
183
+ (item) => html2`
184
+ <st-feature-item
185
+ .icon=${item.icon ?? ""}
186
+ .title=${item.title}
187
+ .description=${item.description}
188
+ .href=${item.href ?? ""}
189
+ .actionLabel=${this.actionLabel}
190
+ ?inverted=${this.inverted}
191
+ ></st-feature-item>
192
+ `
193
+ )}
194
+ </div>
195
+ </section>
196
+ `;
197
+ }
198
+ };
199
+ FeaturesSection.styles = css2`
200
+ ${controlBaseStyles}
201
+
202
+ :host {
203
+ display: block;
204
+ ${fontFamilyStyles}
205
+ padding: var(--st-cms-section-padding) var(--st-space-24);
206
+ background: var(--st-color-surface);
207
+ }
208
+
209
+ :host([inverted]) {
210
+ background: var(--st-color-text-strong);
211
+ }
212
+
213
+ .container {
214
+ max-width: var(--st-cms-container-max);
215
+ margin: 0 auto;
216
+ }
217
+
218
+ .header {
219
+ ${sectionHeaderStyles}
220
+ }
221
+
222
+ .title {
223
+ ${sectionTitleStyles}
224
+ margin: 0;
225
+ }
226
+
227
+ .subtitle {
228
+ ${sectionSubtitleStyles}
229
+ margin: 0 auto;
230
+ }
231
+
232
+ :host([inverted]) .title,
233
+ :host([inverted]) .subtitle {
234
+ color: var(--st-color-on-solid);
235
+ }
236
+
237
+ .grid {
238
+ display: grid;
239
+ grid-template-columns: repeat(var(--features-columns, 2), 1fr);
240
+ gap: var(--st-space-32);
241
+ }
242
+
243
+ @media (max-width: 768px) {
244
+ :host {
245
+ padding: var(--st-space-48) var(--st-space-16);
246
+ }
247
+
248
+ .grid {
249
+ grid-template-columns: 1fr;
250
+ }
251
+ }
252
+ `;
253
+ __decorateClass([
254
+ property2({ type: String })
255
+ ], FeaturesSection.prototype, "title", 2);
256
+ __decorateClass([
257
+ property2({ type: String })
258
+ ], FeaturesSection.prototype, "subtitle", 2);
259
+ __decorateClass([
260
+ property2({ type: String, attribute: "action-label" })
261
+ ], FeaturesSection.prototype, "actionLabel", 2);
262
+ __decorateClass([
263
+ property2({ type: Number })
264
+ ], FeaturesSection.prototype, "columns", 2);
265
+ __decorateClass([
266
+ property2({ type: Boolean, reflect: true })
267
+ ], FeaturesSection.prototype, "inverted", 2);
268
+ __decorateClass([
269
+ property2({ attribute: false })
270
+ ], FeaturesSection.prototype, "items", 2);
271
+ FeaturesSection = __decorateClass([
272
+ customElement2("st-features-section")
273
+ ], FeaturesSection);
274
+
275
+ export {
276
+ FeatureItem,
277
+ FeaturesSection
278
+ };
279
+ //# sourceMappingURL=chunk-E52WO7R7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/features-section/FeaturesSection.ts","../src/features-section/FeatureItem.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\n\r\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\r\nimport { sectionSubtitleStyles, sectionTitleStyles, sectionHeaderStyles } from '../shared/section-styles';\r\nimport './FeatureItem';\r\n\r\n/** Data for one tile when using the `items` property (mirrors `st-feature-item`'s properties). */\r\nexport interface FeatureItemData {\r\n icon?: string;\r\n title: string;\r\n description: string;\r\n href?: string;\r\n}\r\n\r\n/**\r\n * A titled grid of feature tiles. Ports `SankhyaUI`'s React `FeaturesSection`: tiles come from the\r\n * `items` property, from slotted `st-feature-item` elements (the source's `children`), or both\r\n * (slotted first). `columns` sets the grid width (default 2; one column below 768px). `inverted`\r\n * is passed on to the `items` tiles; slotted tiles need their own `inverted` attribute.\r\n */\r\n@customElement('st-features-section')\r\nexport class FeaturesSection extends LitElement {\r\n static styles = css`\r\n ${controlBaseStyles}\r\n\r\n :host {\r\n display: block;\r\n ${fontFamilyStyles}\r\n padding: var(--st-cms-section-padding) var(--st-space-24);\r\n background: var(--st-color-surface);\r\n }\r\n\r\n :host([inverted]) {\r\n background: var(--st-color-text-strong);\r\n }\r\n\r\n .container {\r\n max-width: var(--st-cms-container-max);\r\n margin: 0 auto;\r\n }\r\n\r\n .header {\r\n ${sectionHeaderStyles}\r\n }\r\n\r\n .title {\r\n ${sectionTitleStyles}\r\n margin: 0;\r\n }\r\n\r\n .subtitle {\r\n ${sectionSubtitleStyles}\r\n margin: 0 auto;\r\n }\r\n\r\n :host([inverted]) .title,\r\n :host([inverted]) .subtitle {\r\n color: var(--st-color-on-solid);\r\n }\r\n\r\n .grid {\r\n display: grid;\r\n grid-template-columns: repeat(var(--features-columns, 2), 1fr);\r\n gap: var(--st-space-32);\r\n }\r\n\r\n @media (max-width: 768px) {\r\n :host {\r\n padding: var(--st-space-48) var(--st-space-16);\r\n }\r\n\r\n .grid {\r\n grid-template-columns: 1fr;\r\n }\r\n }\r\n `;\r\n\r\n @property({ type: String })\r\n title = '';\r\n\r\n @property({ type: String })\r\n subtitle = '';\r\n\r\n /** Applied to every tile built from `items`. */\r\n @property({ type: String, attribute: 'action-label' })\r\n actionLabel = 'Learn more';\r\n\r\n @property({ type: Number })\r\n columns = 0;\r\n\r\n @property({ type: Boolean, reflect: true })\r\n inverted = false;\r\n\r\n /** Tiles to render (property only). */\r\n @property({ attribute: false })\r\n items: FeatureItemData[] = [];\r\n\r\n render() {\r\n const gridStyle = this.columns ? `--features-columns: ${this.columns}` : nothing;\r\n return html`\r\n <section class=\"container\" part=\"container\">\r\n <div class=\"header\" part=\"header\">\r\n <div class=\"title\" part=\"title\">${this.title}</div>\r\n ${this.subtitle ? html`<div class=\"subtitle\" part=\"subtitle\">${this.subtitle}</div>` : nothing}\r\n </div>\r\n <div class=\"grid\" part=\"grid\" style=${gridStyle}>\r\n <slot></slot>\r\n ${this.items.map(\r\n (item) => html`\r\n <st-feature-item\r\n .icon=${item.icon ?? ''}\r\n .title=${item.title}\r\n .description=${item.description}\r\n .href=${item.href ?? ''}\r\n .actionLabel=${this.actionLabel}\r\n ?inverted=${this.inverted}\r\n ></st-feature-item>\r\n `\r\n )}\r\n </div>\r\n </section>\r\n `;\r\n }\r\n}\r\n","import { LitElement, css, html, nothing } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\nimport 'iconify-icon';\r\n\r\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\r\nimport { cardDescriptionStyles, cardTitleStyles } from '../shared/section-styles';\r\nimport '../card';\r\nimport '../markdown';\r\n\r\n/**\r\n * One feature tile for `st-features-section`: optional icon, title, Markdown description and an\r\n * optional \"Learn more\" link, rendered on an `st-card`. `icon` is an Iconify name (e.g.\r\n * `mdi:rocket`). The link is a plain `<a>` (the source used react-router's `Link` for non-http\r\n * hrefs; there is no Lit equivalent). The click is composed, so an SPA router can intercept it\r\n * (e.g. via `event.composedPath()`) and navigate client-side; `http(s)` links open in a new tab.\r\n */\r\n@customElement('st-feature-item')\r\nexport class FeatureItem extends LitElement {\r\n static styles = css`\r\n ${controlBaseStyles}\r\n\r\n :host {\r\n display: block;\r\n ${fontFamilyStyles}\r\n }\r\n\r\n st-card {\r\n height: 100%;\r\n }\r\n\r\n .content {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: flex-start;\r\n gap: var(--st-space-16);\r\n height: 100%;\r\n }\r\n\r\n .icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 48px;\r\n height: 48px;\r\n border-radius: var(--st-radius-lg);\r\n background: var(--st-color-subtle);\r\n color: var(--st-color-text-strong);\r\n margin-bottom: var(--st-space-8);\r\n font-size: 24px;\r\n }\r\n\r\n :host([inverted]) .icon {\r\n background: var(--st-color-text-muted);\r\n color: var(--st-color-on-solid);\r\n }\r\n\r\n .title {\r\n ${cardTitleStyles}\r\n margin: 0;\r\n }\r\n\r\n .description {\r\n ${cardDescriptionStyles}\r\n margin: 0;\r\n }\r\n\r\n :host([inverted]) .title,\r\n :host([inverted]) .description {\r\n color: inherit;\r\n }\r\n\r\n .link {\r\n display: flex;\r\n align-items: center;\r\n gap: var(--st-space-4);\r\n margin-top: auto;\r\n color: var(--st-color-text-muted);\r\n font-weight: var(--st-font-weight-medium);\r\n font-size: var(--st-text-md);\r\n text-decoration: none;\r\n transition: color 0.2s ease;\r\n }\r\n\r\n .link:hover {\r\n color: var(--st-color-text-strong);\r\n text-decoration: underline;\r\n }\r\n\r\n :host([inverted]) .link,\r\n :host([inverted]) .link:hover {\r\n color: inherit;\r\n }\r\n\r\n @media (prefers-reduced-motion: reduce) {\r\n .link {\r\n transition: none;\r\n }\r\n }\r\n `;\r\n\r\n /** Iconify icon name, e.g. `mdi:rocket`. */\r\n @property({ type: String })\r\n icon = '';\r\n\r\n @property({ type: String })\r\n title = '';\r\n\r\n /** Markdown. */\r\n @property({ type: String })\r\n description = '';\r\n\r\n @property({ type: String })\r\n href = '';\r\n\r\n @property({ type: String, attribute: 'action-label' })\r\n actionLabel = 'Learn more';\r\n\r\n @property({ type: Boolean, reflect: true })\r\n inverted = false;\r\n\r\n render() {\r\n const external = this.href.startsWith('http');\r\n return html`\r\n <st-card hoverable elevation=\"sm\" ?inverted=${this.inverted} part=\"card\">\r\n <div class=\"content\" part=\"content\">\r\n ${this.icon\r\n ? html`<div class=\"icon\" part=\"icon\"><iconify-icon icon=${this.icon}></iconify-icon></div>`\r\n : nothing}\r\n <h3 class=\"title\" part=\"title\">${this.title}</h3>\r\n <st-markdown class=\"description\" part=\"description\" .content=${this.description}></st-markdown>\r\n ${this.href\r\n ? html`\r\n <a\r\n class=\"link\"\r\n part=\"link\"\r\n href=${this.href}\r\n target=${external ? '_blank' : '_self'}\r\n rel=${external ? 'noopener noreferrer' : nothing}\r\n >\r\n ${this.actionLabel} <span>&rarr;</span>\r\n </a>\r\n `\r\n : nothing}\r\n </div>\r\n </st-card>\r\n `;\r\n }\r\n}\r\n"],"mappings":"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","names":["LitElement","css","html","nothing","customElement","property","LitElement","nothing","html","css","property","customElement"]}
@@ -0,0 +1,15 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __decorateClass = (decorators, target, key, kind) => {
4
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
+ if (decorator = decorators[i])
7
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
+ if (kind && result) __defProp(target, key, result);
9
+ return result;
10
+ };
11
+
12
+ export {
13
+ __decorateClass
14
+ };
15
+ //# sourceMappingURL=chunk-EUXUH3YW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}