@gxpl/sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -0
  3. package/dist/Client/Client.d.ts +32 -0
  4. package/dist/Client/Client.js +128 -0
  5. package/dist/Client/Client.test.d.ts +1 -0
  6. package/dist/Client/__mock__/articleMock.d.ts +2 -0
  7. package/dist/Client/__mock__/keyframesMock.d.ts +2 -0
  8. package/dist/Client/__mock__/projectMock.d.ts +2 -0
  9. package/dist/Components/ControlSlider/ControlSlider.d.ts +91 -0
  10. package/dist/Components/ControlSlider/ControlSliderComponent.d.ts +519 -0
  11. package/dist/Components/ImageRevealSlider/ControlImageRevealSliderComponent.d.ts +209 -0
  12. package/dist/Components/ImageRevealSlider/ImageRevealSlider.d.ts +39 -0
  13. package/dist/Components/components.d.ts +2 -0
  14. package/dist/Components/helpers/RichTextRenderer/RichTextRenderer.d.ts +6 -0
  15. package/dist/Components/helpers/SvgImage/SvgImage.d.ts +9 -0
  16. package/dist/Components/utils/scalingValue.d.ts +1 -0
  17. package/dist/FontFaceGenerator/FontFaceGenerator.d.ts +6 -0
  18. package/dist/FontFaceGenerator/FontFaceGenerator.test.d.ts +1 -0
  19. package/dist/ScrollPlaybackVideoManager/ScrollPlaybackVideoManager.d.ts +31 -0
  20. package/dist/VideoDecoder/VideoDecoder.d.ts +12 -0
  21. package/dist/cli.d.ts +10 -0
  22. package/dist/cli.js +64 -0
  23. package/dist/index.d.ts +23 -0
  24. package/dist/index.js +2730 -0
  25. package/dist/index.mjs +2713 -0
  26. package/dist/schemas/article/Article.schema.d.ts +328 -0
  27. package/dist/schemas/article/Article.schema.js +11 -0
  28. package/dist/schemas/article/FillLayer.schema.d.ts +186 -0
  29. package/dist/schemas/article/FillLayer.schema.js +53 -0
  30. package/dist/schemas/article/Interaction.schema.d.ts +103 -0
  31. package/dist/schemas/article/Interaction.schema.js +30 -0
  32. package/dist/schemas/article/Item.schema.d.ts +40 -0
  33. package/dist/schemas/article/Item.schema.js +242 -0
  34. package/dist/schemas/article/ItemArea.schema.d.ts +36 -0
  35. package/dist/schemas/article/ItemArea.schema.js +17 -0
  36. package/dist/schemas/article/ItemBase.schema.d.ts +137 -0
  37. package/dist/schemas/article/ItemBase.schema.js +23 -0
  38. package/dist/schemas/article/ItemState.schema.d.ts +15723 -0
  39. package/dist/schemas/article/ItemState.schema.js +75 -0
  40. package/dist/schemas/article/RichTextItem.schema.d.ts +1372 -0
  41. package/dist/schemas/article/RichTextItem.schema.js +60 -0
  42. package/dist/schemas/article/Section.schema.d.ts +176 -0
  43. package/dist/schemas/article/Section.schema.js +38 -0
  44. package/dist/schemas/keyframe/Keyframes.schema.d.ts +2000 -0
  45. package/dist/schemas/keyframe/Keyframes.schema.js +116 -0
  46. package/dist/schemas/project/Layout.schema.d.ts +17 -0
  47. package/dist/schemas/project/Layout.schema.js +10 -0
  48. package/dist/schemas/project/Project.schema.d.ts +253 -0
  49. package/dist/schemas/project/Project.schema.js +48 -0
  50. package/dist/schemas/shared/FillLayer.schema.d.ts +186 -0
  51. package/dist/sdk.css +1 -0
  52. package/dist/types/article/Article.d.ts +7 -0
  53. package/dist/types/article/Article.js +2 -0
  54. package/dist/types/article/ArticleItemType.d.ts +13 -0
  55. package/dist/types/article/ArticleItemType.js +17 -0
  56. package/dist/types/article/CompoundSettings.d.ts +6 -0
  57. package/dist/types/article/CompoundSettings.js +2 -0
  58. package/dist/types/article/FX.d.ts +23 -0
  59. package/dist/types/article/FX.js +2 -0
  60. package/dist/types/article/Interaction.d.ts +28 -0
  61. package/dist/types/article/Interaction.js +2 -0
  62. package/dist/types/article/Item.d.ts +250 -0
  63. package/dist/types/article/Item.js +3 -0
  64. package/dist/types/article/ItemArea.d.ts +36 -0
  65. package/dist/types/article/ItemArea.js +31 -0
  66. package/dist/types/article/ItemState.d.ts +78 -0
  67. package/dist/types/article/ItemState.js +3 -0
  68. package/dist/types/article/RichText.d.ts +40 -0
  69. package/dist/types/article/RichText.js +27 -0
  70. package/dist/types/article/Section.d.ts +37 -0
  71. package/dist/types/article/Section.js +8 -0
  72. package/dist/types/component/Component.d.ts +15 -0
  73. package/dist/types/keyframe/Keyframe.d.ts +86 -0
  74. package/dist/types/keyframe/Keyframe.js +21 -0
  75. package/dist/types/project/Fonts.d.ts +22 -0
  76. package/dist/types/project/Fonts.js +11 -0
  77. package/dist/types/project/Layout.d.ts +6 -0
  78. package/dist/types/project/Layout.js +2 -0
  79. package/dist/types/project/Meta.d.ts +9 -0
  80. package/dist/types/project/Meta.js +2 -0
  81. package/dist/types/project/Page.d.ts +11 -0
  82. package/dist/types/project/Page.js +2 -0
  83. package/dist/types/project/Project.d.ts +17 -0
  84. package/dist/types/project/Project.js +2 -0
  85. package/dist/utils.d.ts +3 -0
  86. package/package.json +84 -0
  87. package/resources/template.scss.ejs +50 -0
package/dist/index.js ADDED
@@ -0,0 +1,2730 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const fetch$1 = require("isomorphic-fetch");
4
+ const url = require("url");
5
+ const zod = require("zod");
6
+ const UAParser = require("ua-parser-js");
7
+ const MP4Box = require("mp4box");
8
+ const jsxRuntime = require("react/jsx-runtime");
9
+ const react = require("react");
10
+ const reactSplide = require("@splidejs/react-splide");
11
+ const cn = require("classnames");
12
+ function _interopNamespaceDefault(e) {
13
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
14
+ if (e) {
15
+ for (const k in e) {
16
+ if (k !== "default") {
17
+ const d = Object.getOwnPropertyDescriptor(e, k);
18
+ Object.defineProperty(n, k, d.get ? d : {
19
+ enumerable: true,
20
+ get: () => e[k]
21
+ });
22
+ }
23
+ }
24
+ }
25
+ n.default = e;
26
+ return Object.freeze(n);
27
+ }
28
+ const MP4Box__namespace = /* @__PURE__ */ _interopNamespaceDefault(MP4Box);
29
+ var SectionHeightMode = /* @__PURE__ */ ((SectionHeightMode2) => {
30
+ SectionHeightMode2["ControlUnits"] = "control-units";
31
+ SectionHeightMode2["ViewportHeightUnits"] = "viewport-height-units";
32
+ return SectionHeightMode2;
33
+ })(SectionHeightMode || {});
34
+ const ColorPointSchema = zod.z.object({
35
+ id: zod.z.string(),
36
+ value: zod.z.string(),
37
+ position: zod.z.number()
38
+ });
39
+ const FillLayerSchema = zod.z.discriminatedUnion("type", [
40
+ zod.z.object({
41
+ id: zod.z.string(),
42
+ type: zod.z.literal("solid"),
43
+ value: zod.z.string(),
44
+ blendMode: zod.z.string()
45
+ }),
46
+ zod.z.object({
47
+ id: zod.z.string(),
48
+ type: zod.z.literal("linear-gradient"),
49
+ colors: zod.z.array(ColorPointSchema),
50
+ start: zod.z.tuple([zod.z.number(), zod.z.number()]),
51
+ end: zod.z.tuple([zod.z.number(), zod.z.number()]),
52
+ angle: zod.z.number(),
53
+ blendMode: zod.z.string()
54
+ }),
55
+ zod.z.object({
56
+ id: zod.z.string(),
57
+ type: zod.z.literal("radial-gradient"),
58
+ colors: zod.z.array(ColorPointSchema),
59
+ center: zod.z.tuple([zod.z.number(), zod.z.number()]),
60
+ diameter: zod.z.number(),
61
+ angle: zod.z.number(),
62
+ blendMode: zod.z.string()
63
+ }),
64
+ zod.z.object({
65
+ id: zod.z.string(),
66
+ type: zod.z.literal("conic-gradient"),
67
+ colors: zod.z.array(ColorPointSchema),
68
+ center: zod.z.tuple([zod.z.number(), zod.z.number()]),
69
+ angle: zod.z.number(),
70
+ blendMode: zod.z.string()
71
+ }),
72
+ zod.z.object({
73
+ id: zod.z.string(),
74
+ type: zod.z.literal("image"),
75
+ src: zod.z.string(),
76
+ behavior: zod.z.string(),
77
+ backgroundSize: zod.z.number(),
78
+ opacity: zod.z.number(),
79
+ blendMode: zod.z.string(),
80
+ rotation: zod.z.number().optional()
81
+ })
82
+ ]);
83
+ const TransitionSchema = zod.z.object({
84
+ timing: zod.z.string(),
85
+ duration: zod.z.number(),
86
+ delay: zod.z.number()
87
+ });
88
+ const getStateParamsSchema = (schema) => {
89
+ return zod.z.object({
90
+ value: schema,
91
+ in: TransitionSchema,
92
+ out: TransitionSchema
93
+ }).optional();
94
+ };
95
+ const ItemStateBaseSchema = zod.z.object({
96
+ width: getStateParamsSchema(zod.z.number()),
97
+ height: getStateParamsSchema(zod.z.number()),
98
+ angle: getStateParamsSchema(zod.z.number()),
99
+ top: getStateParamsSchema(zod.z.number()),
100
+ left: getStateParamsSchema(zod.z.number()),
101
+ scale: getStateParamsSchema(zod.z.number()),
102
+ blur: getStateParamsSchema(zod.z.number())
103
+ });
104
+ const MediaStateParamsSchema = zod.z.object({
105
+ opacity: getStateParamsSchema(zod.z.number()),
106
+ radius: getStateParamsSchema(zod.z.number()),
107
+ strokeWidth: getStateParamsSchema(zod.z.number()),
108
+ strokeFill: getStateParamsSchema(zod.z.array(FillLayerSchema))
109
+ }).merge(ItemStateBaseSchema);
110
+ const RectangleStateParamsSchema = zod.z.object({
111
+ strokeWidth: getStateParamsSchema(zod.z.number()),
112
+ radius: getStateParamsSchema(zod.z.number()),
113
+ fill: getStateParamsSchema(zod.z.array(FillLayerSchema)),
114
+ strokeFill: getStateParamsSchema(zod.z.array(FillLayerSchema)),
115
+ backdropBlur: getStateParamsSchema(zod.z.number())
116
+ }).merge(ItemStateBaseSchema);
117
+ const CustomItemStateParamsSchema = ItemStateBaseSchema;
118
+ const EmbedStateParamsSchema = zod.z.object({
119
+ radius: getStateParamsSchema(zod.z.number()),
120
+ opacity: getStateParamsSchema(zod.z.number().nonnegative())
121
+ }).merge(ItemStateBaseSchema);
122
+ const RichTextStateParamsSchema = zod.z.object({
123
+ color: getStateParamsSchema(zod.z.string()),
124
+ letterSpacing: getStateParamsSchema(zod.z.number()),
125
+ wordSpacing: getStateParamsSchema(zod.z.number())
126
+ }).merge(ItemStateBaseSchema);
127
+ const GroupStateParamsSchema = zod.z.object({
128
+ opacity: getStateParamsSchema(zod.z.number().nonnegative()),
129
+ blur: getStateParamsSchema(zod.z.number().nonnegative())
130
+ }).merge(ItemStateBaseSchema);
131
+ const CompoundStateParamsSchema = zod.z.object({
132
+ opacity: getStateParamsSchema(zod.z.number().nonnegative())
133
+ }).merge(ItemStateBaseSchema);
134
+ const CodeEmbedStateParamsSchema = zod.z.object({
135
+ opacity: getStateParamsSchema(zod.z.number().nonnegative())
136
+ }).merge(ItemStateBaseSchema);
137
+ const ComponentStateParamsSchema = zod.z.object({
138
+ opacity: getStateParamsSchema(zod.z.number().nonnegative())
139
+ }).merge(ItemStateBaseSchema);
140
+ zod.z.union([
141
+ EmbedStateParamsSchema,
142
+ MediaStateParamsSchema,
143
+ RectangleStateParamsSchema,
144
+ RichTextStateParamsSchema,
145
+ CustomItemStateParamsSchema,
146
+ GroupStateParamsSchema,
147
+ CompoundStateParamsSchema,
148
+ CodeEmbedStateParamsSchema,
149
+ ComponentStateParamsSchema
150
+ ]);
151
+ var TextAlign = /* @__PURE__ */ ((TextAlign2) => {
152
+ TextAlign2["Left"] = "left";
153
+ TextAlign2["Right"] = "right";
154
+ TextAlign2["Center"] = "center";
155
+ TextAlign2["Justify"] = "justify";
156
+ return TextAlign2;
157
+ })(TextAlign || {});
158
+ var TextTransform = /* @__PURE__ */ ((TextTransform2) => {
159
+ TextTransform2["None"] = "none";
160
+ TextTransform2["Uppercase"] = "uppercase";
161
+ TextTransform2["Lowercase"] = "lowercase";
162
+ return TextTransform2;
163
+ })(TextTransform || {});
164
+ var VerticalAlign = /* @__PURE__ */ ((VerticalAlign2) => {
165
+ VerticalAlign2["Super"] = "super";
166
+ VerticalAlign2["Sub"] = "sub";
167
+ VerticalAlign2["Unset"] = "unset";
168
+ return VerticalAlign2;
169
+ })(VerticalAlign || {});
170
+ var TextDecoration = /* @__PURE__ */ ((TextDecoration2) => {
171
+ TextDecoration2["Underline"] = "underline";
172
+ TextDecoration2["None"] = "none";
173
+ return TextDecoration2;
174
+ })(TextDecoration || {});
175
+ var AnchorSide = /* @__PURE__ */ ((AnchorSide2) => {
176
+ AnchorSide2["Top"] = "top";
177
+ AnchorSide2["Bottom"] = "bottom";
178
+ AnchorSide2["Center"] = "center";
179
+ return AnchorSide2;
180
+ })(AnchorSide || {});
181
+ var PositionType = /* @__PURE__ */ ((PositionType2) => {
182
+ PositionType2["SectionBased"] = "section-based";
183
+ PositionType2["ScreenBased"] = "screen-based";
184
+ return PositionType2;
185
+ })(PositionType || {});
186
+ var AreaAnchor = /* @__PURE__ */ ((AreaAnchor2) => {
187
+ AreaAnchor2["TopLeft"] = "top-left";
188
+ AreaAnchor2["TopCenter"] = "top-center";
189
+ AreaAnchor2["TopRight"] = "top-right";
190
+ AreaAnchor2["MiddleLeft"] = "middle-left";
191
+ AreaAnchor2["MiddleCenter"] = "middle-center";
192
+ AreaAnchor2["MiddleRight"] = "middle-right";
193
+ AreaAnchor2["BottomLeft"] = "bottom-left";
194
+ AreaAnchor2["BottomCenter"] = "bottom-center";
195
+ AreaAnchor2["BottomRight"] = "bottom-right";
196
+ return AreaAnchor2;
197
+ })(AreaAnchor || {});
198
+ var DimensionMode = /* @__PURE__ */ ((DimensionMode2) => {
199
+ DimensionMode2["ControlUnits"] = "control-units";
200
+ DimensionMode2["Relative"] = "relative";
201
+ return DimensionMode2;
202
+ })(DimensionMode || {});
203
+ const ItemAreaSchema = zod.z.object({
204
+ top: zod.z.number(),
205
+ left: zod.z.number(),
206
+ width: zod.z.number(),
207
+ height: zod.z.number(),
208
+ zIndex: zod.z.number(),
209
+ angle: zod.z.number(),
210
+ anchorSide: zod.z.nativeEnum(AnchorSide).optional(),
211
+ scale: zod.z.number().nonnegative(),
212
+ positionType: zod.z.nativeEnum(PositionType),
213
+ scaleAnchor: zod.z.nativeEnum(AreaAnchor)
214
+ });
215
+ const Link = zod.z.object({
216
+ url: zod.z.string().min(1),
217
+ target: zod.z.string().min(1)
218
+ });
219
+ const CompoundSettingsSchema = zod.z.object({
220
+ positionAnchor: zod.z.nativeEnum(AreaAnchor),
221
+ widthMode: zod.z.nativeEnum(DimensionMode),
222
+ heightMode: zod.z.nativeEnum(DimensionMode)
223
+ });
224
+ const ItemBaseSchema = zod.z.object({
225
+ id: zod.z.string().min(1),
226
+ area: zod.z.record(ItemAreaSchema),
227
+ hidden: zod.z.record(zod.z.boolean()),
228
+ link: Link.optional(),
229
+ compoundSettings: zod.z.record(CompoundSettingsSchema).optional(),
230
+ layoutParams: zod.z.record(zod.z.any()).optional()
231
+ });
232
+ var ArticleItemType = /* @__PURE__ */ ((ArticleItemType2) => {
233
+ ArticleItemType2["Image"] = "image";
234
+ ArticleItemType2["RichText"] = "richtext";
235
+ ArticleItemType2["Video"] = "video";
236
+ ArticleItemType2["Rectangle"] = "rectangle";
237
+ ArticleItemType2["VimeoEmbed"] = "vimeo-embed";
238
+ ArticleItemType2["YoutubeEmbed"] = "youtube-embed";
239
+ ArticleItemType2["Custom"] = "custom";
240
+ ArticleItemType2["Group"] = "group";
241
+ ArticleItemType2["CodeEmbed"] = "code-embed";
242
+ ArticleItemType2["Compound"] = "compound";
243
+ ArticleItemType2["Component"] = "component";
244
+ return ArticleItemType2;
245
+ })(ArticleItemType || {});
246
+ const pointerEvents$1 = zod.z.enum(["never", "when_visible", "always"]).optional();
247
+ const RichTextEntitySchema = zod.z.object({
248
+ start: zod.z.number().nonnegative(),
249
+ end: zod.z.number().nonnegative(),
250
+ type: zod.z.string(),
251
+ data: zod.z.any().optional()
252
+ });
253
+ const RichTextStyleSchema = zod.z.object({
254
+ start: zod.z.number().nonnegative(),
255
+ end: zod.z.number().nonnegative(),
256
+ style: zod.z.string().min(1),
257
+ value: zod.z.string().optional()
258
+ });
259
+ const RichTextBlockSchema = zod.z.lazy(() => zod.z.object({
260
+ start: zod.z.number().nonnegative(),
261
+ end: zod.z.number().nonnegative(),
262
+ type: zod.z.string().min(1),
263
+ entities: zod.z.array(RichTextEntitySchema).optional(),
264
+ children: zod.z.array(RichTextBlockSchema).optional(),
265
+ data: zod.z.any().optional()
266
+ }));
267
+ const RichTextItemSchema = ItemBaseSchema.extend({
268
+ type: zod.z.literal(ArticleItemType.RichText),
269
+ commonParams: zod.z.object({
270
+ text: zod.z.string(),
271
+ blocks: zod.z.array(RichTextBlockSchema).optional(),
272
+ pointerEvents: pointerEvents$1
273
+ }),
274
+ sticky: zod.z.record(
275
+ zod.z.object({
276
+ from: zod.z.number(),
277
+ to: zod.z.number().optional()
278
+ }).nullable()
279
+ ),
280
+ layoutParams: zod.z.record(
281
+ zod.z.object({
282
+ rangeStyles: zod.z.array(RichTextStyleSchema).optional(),
283
+ textAlign: zod.z.nativeEnum(TextAlign),
284
+ sizing: zod.z.string(),
285
+ blur: zod.z.number(),
286
+ fontSize: zod.z.number(),
287
+ lineHeight: zod.z.number(),
288
+ letterSpacing: zod.z.number(),
289
+ wordSpacing: zod.z.number(),
290
+ textTransform: zod.z.nativeEnum(TextTransform),
291
+ verticalAlign: zod.z.nativeEnum(VerticalAlign),
292
+ color: zod.z.string(),
293
+ typeFace: zod.z.string(),
294
+ fontStyle: zod.z.string(),
295
+ fontWeight: zod.z.number(),
296
+ fontVariant: zod.z.string(),
297
+ isDraggable: zod.z.boolean().optional()
298
+ })
299
+ ),
300
+ state: zod.z.record(RichTextStateParamsSchema)
301
+ });
302
+ const pointerEvents = zod.z.enum(["never", "when_visible", "always"]).optional();
303
+ const FXControlSchema = zod.z.discriminatedUnion("type", [
304
+ zod.z.object({
305
+ type: zod.z.literal("float"),
306
+ shaderParam: zod.z.string(),
307
+ value: zod.z.number()
308
+ }),
309
+ zod.z.object({
310
+ type: zod.z.literal("int"),
311
+ shaderParam: zod.z.string(),
312
+ value: zod.z.number()
313
+ }),
314
+ zod.z.object({
315
+ type: zod.z.literal("vec2"),
316
+ shaderParam: zod.z.string(),
317
+ value: zod.z.tuple([zod.z.number(), zod.z.number()])
318
+ })
319
+ ]);
320
+ const FXParams = zod.z.object({
321
+ url: zod.z.string().min(1),
322
+ hasGLEffect: zod.z.boolean().optional(),
323
+ fragmentShader: zod.z.string().nullable(),
324
+ FXControls: zod.z.array(FXControlSchema).optional()
325
+ });
326
+ const ImageItemSchema = ItemBaseSchema.extend({
327
+ type: zod.z.literal(ArticleItemType.Image),
328
+ commonParams: zod.z.object({
329
+ pointerEvents
330
+ }).merge(FXParams),
331
+ sticky: zod.z.record(
332
+ zod.z.object({
333
+ from: zod.z.number(),
334
+ to: zod.z.number().optional()
335
+ }).nullable()
336
+ ),
337
+ layoutParams: zod.z.record(
338
+ zod.z.object({
339
+ opacity: zod.z.number().nonnegative(),
340
+ radius: zod.z.number(),
341
+ strokeWidth: zod.z.number(),
342
+ strokeFill: zod.z.array(FillLayerSchema),
343
+ blur: zod.z.number(),
344
+ isDraggable: zod.z.boolean().optional()
345
+ })
346
+ ),
347
+ state: zod.z.record(MediaStateParamsSchema)
348
+ });
349
+ const VideoItemSchema = ItemBaseSchema.extend({
350
+ type: zod.z.literal(ArticleItemType.Video),
351
+ commonParams: zod.z.object({
352
+ coverUrl: zod.z.string().nullable(),
353
+ pointerEvents
354
+ }).merge(FXParams),
355
+ sticky: zod.z.record(
356
+ zod.z.object({
357
+ from: zod.z.number(),
358
+ to: zod.z.number().optional()
359
+ }).nullable()
360
+ ),
361
+ layoutParams: zod.z.record(
362
+ zod.z.object({
363
+ scrollPlayback: zod.z.object({
364
+ from: zod.z.number(),
365
+ to: zod.z.number()
366
+ }).nullable(),
367
+ opacity: zod.z.number().nonnegative(),
368
+ radius: zod.z.number(),
369
+ strokeWidth: zod.z.number(),
370
+ strokeFill: zod.z.array(FillLayerSchema),
371
+ blur: zod.z.number(),
372
+ isDraggable: zod.z.boolean().optional(),
373
+ play: zod.z.enum(["on-hover", "on-click", "auto"]),
374
+ muted: zod.z.boolean(),
375
+ controls: zod.z.boolean()
376
+ })
377
+ ),
378
+ state: zod.z.record(MediaStateParamsSchema)
379
+ });
380
+ const RectangleItemSchema = ItemBaseSchema.extend({
381
+ type: zod.z.literal(ArticleItemType.Rectangle),
382
+ commonParams: zod.z.object({
383
+ ratioLock: zod.z.boolean(),
384
+ pointerEvents
385
+ }),
386
+ sticky: zod.z.record(
387
+ zod.z.object({
388
+ from: zod.z.number(),
389
+ to: zod.z.number().optional()
390
+ }).nullable()
391
+ ),
392
+ layoutParams: zod.z.record(
393
+ zod.z.object({
394
+ radius: zod.z.number(),
395
+ strokeWidth: zod.z.number(),
396
+ fill: zod.z.array(FillLayerSchema),
397
+ strokeFill: zod.z.array(FillLayerSchema),
398
+ blur: zod.z.number(),
399
+ backdropBlur: zod.z.number(),
400
+ blurMode: zod.z.enum(["default", "backdrop"]),
401
+ isDraggable: zod.z.boolean().optional()
402
+ })
403
+ ),
404
+ state: zod.z.record(RectangleStateParamsSchema)
405
+ });
406
+ const CustomItemSchema = ItemBaseSchema.extend({
407
+ type: zod.z.literal(ArticleItemType.Custom),
408
+ commonParams: zod.z.object({
409
+ name: zod.z.string(),
410
+ pointerEvents
411
+ }),
412
+ sticky: zod.z.record(
413
+ zod.z.object({
414
+ from: zod.z.number(),
415
+ to: zod.z.number().optional()
416
+ }).nullable()
417
+ ),
418
+ layoutParams: zod.z.record(zod.z.object({
419
+ isDraggable: zod.z.boolean().optional()
420
+ })),
421
+ state: zod.z.record(CustomItemStateParamsSchema)
422
+ });
423
+ const VimeoEmbedItemSchema = ItemBaseSchema.extend({
424
+ type: zod.z.literal(ArticleItemType.VimeoEmbed),
425
+ commonParams: zod.z.object({
426
+ url: zod.z.string().min(1),
427
+ coverUrl: zod.z.string().nullable(),
428
+ ratioLock: zod.z.boolean(),
429
+ pointerEvents
430
+ }),
431
+ sticky: zod.z.record(
432
+ zod.z.object({
433
+ from: zod.z.number(),
434
+ to: zod.z.number().optional()
435
+ }).nullable()
436
+ ),
437
+ layoutParams: zod.z.record(
438
+ zod.z.object({
439
+ radius: zod.z.number(),
440
+ blur: zod.z.number(),
441
+ opacity: zod.z.number().nonnegative(),
442
+ play: zod.z.union([zod.z.literal("on-hover"), zod.z.literal("on-click"), zod.z.literal("auto")]),
443
+ controls: zod.z.boolean(),
444
+ loop: zod.z.boolean(),
445
+ muted: zod.z.boolean(),
446
+ pictureInPicture: zod.z.boolean()
447
+ })
448
+ ),
449
+ state: zod.z.record(EmbedStateParamsSchema)
450
+ });
451
+ const YoutubeEmbedItemSchema = ItemBaseSchema.extend({
452
+ type: zod.z.literal(ArticleItemType.YoutubeEmbed),
453
+ commonParams: zod.z.object({
454
+ url: zod.z.string().min(1),
455
+ coverUrl: zod.z.string().nullable(),
456
+ pointerEvents
457
+ }),
458
+ sticky: zod.z.record(
459
+ zod.z.object({
460
+ from: zod.z.number(),
461
+ to: zod.z.number().optional()
462
+ }).nullable()
463
+ ),
464
+ layoutParams: zod.z.record(
465
+ zod.z.object({
466
+ radius: zod.z.number(),
467
+ blur: zod.z.number(),
468
+ opacity: zod.z.number().nonnegative(),
469
+ play: zod.z.enum(["on-hover", "on-click", "auto"]),
470
+ controls: zod.z.boolean(),
471
+ loop: zod.z.boolean()
472
+ })
473
+ ),
474
+ state: zod.z.record(EmbedStateParamsSchema)
475
+ });
476
+ const CodeEmbedItemSchema = ItemBaseSchema.extend({
477
+ type: zod.z.literal(ArticleItemType.CodeEmbed),
478
+ commonParams: zod.z.object({
479
+ html: zod.z.string(),
480
+ scale: zod.z.boolean(),
481
+ iframe: zod.z.boolean(),
482
+ pointerEvents
483
+ }),
484
+ sticky: zod.z.record(
485
+ zod.z.object({
486
+ from: zod.z.number(),
487
+ to: zod.z.number().optional()
488
+ }).nullable()
489
+ ),
490
+ layoutParams: zod.z.record(
491
+ zod.z.object({
492
+ areaAnchor: zod.z.nativeEnum(AreaAnchor),
493
+ opacity: zod.z.number().nonnegative(),
494
+ blur: zod.z.number(),
495
+ isDraggable: zod.z.boolean().optional()
496
+ })
497
+ ),
498
+ state: zod.z.record(CodeEmbedStateParamsSchema)
499
+ });
500
+ const ComponentItemSchema = ItemBaseSchema.extend({
501
+ type: zod.z.literal(ArticleItemType.Component),
502
+ commonParams: zod.z.object({
503
+ componentId: zod.z.string(),
504
+ content: zod.z.any().optional()
505
+ }),
506
+ sticky: zod.z.record(
507
+ zod.z.object({
508
+ from: zod.z.number(),
509
+ to: zod.z.number().optional()
510
+ }).nullable()
511
+ ),
512
+ layoutParams: zod.z.record(zod.z.object({
513
+ parameters: zod.z.any().optional(),
514
+ opacity: zod.z.number().nonnegative(),
515
+ blur: zod.z.number()
516
+ })),
517
+ state: zod.z.record(ComponentStateParamsSchema)
518
+ });
519
+ const ItemSchema = zod.z.lazy(() => zod.z.discriminatedUnion("type", [
520
+ ImageItemSchema,
521
+ VideoItemSchema,
522
+ RectangleItemSchema,
523
+ CustomItemSchema,
524
+ RichTextItemSchema,
525
+ VimeoEmbedItemSchema,
526
+ YoutubeEmbedItemSchema,
527
+ CodeEmbedItemSchema,
528
+ ComponentItemSchema,
529
+ ItemBaseSchema.extend({
530
+ type: zod.z.literal(ArticleItemType.Group),
531
+ commonParams: zod.z.object({
532
+ pointerEvents
533
+ }),
534
+ items: zod.z.array(ItemSchema),
535
+ sticky: zod.z.record(
536
+ zod.z.object({
537
+ from: zod.z.number(),
538
+ to: zod.z.number().optional()
539
+ }).nullable()
540
+ ),
541
+ layoutParams: zod.z.record(
542
+ zod.z.object({
543
+ opacity: zod.z.number().nonnegative(),
544
+ blur: zod.z.number()
545
+ })
546
+ ),
547
+ state: zod.z.record(GroupStateParamsSchema)
548
+ }),
549
+ ItemBaseSchema.extend({
550
+ type: zod.z.literal(ArticleItemType.Compound),
551
+ commonParams: zod.z.object({
552
+ overflow: zod.z.enum(["hidden", "visible"]),
553
+ pointerEvents
554
+ }),
555
+ items: zod.z.array(ItemSchema),
556
+ sticky: zod.z.record(
557
+ zod.z.object({
558
+ from: zod.z.number(),
559
+ to: zod.z.number().optional()
560
+ }).nullable()
561
+ ),
562
+ layoutParams: zod.z.record(
563
+ zod.z.object({
564
+ opacity: zod.z.number().nonnegative()
565
+ })
566
+ ),
567
+ state: zod.z.record(CompoundStateParamsSchema)
568
+ })
569
+ ]));
570
+ const SectionHeightSchema = zod.z.object({
571
+ mode: zod.z.nativeEnum(SectionHeightMode),
572
+ units: zod.z.number().nonnegative(),
573
+ vhUnits: zod.z.number().nonnegative().optional()
574
+ });
575
+ const SectionVideoSchema = zod.z.object({
576
+ url: zod.z.string(),
577
+ size: zod.z.string(),
578
+ type: zod.z.literal("video"),
579
+ play: zod.z.enum(["on-click", "auto"]),
580
+ coverUrl: zod.z.string().nullable(),
581
+ position: zod.z.string(),
582
+ offsetX: zod.z.number().nullable()
583
+ });
584
+ const SectionImageSchema = zod.z.object({
585
+ url: zod.z.string(),
586
+ type: zod.z.literal("image"),
587
+ size: zod.z.string(),
588
+ position: zod.z.string(),
589
+ offsetX: zod.z.number().nullable()
590
+ });
591
+ const SectionMediaSchema = zod.z.discriminatedUnion("type", [SectionVideoSchema, SectionImageSchema]);
592
+ const SectionSchema = zod.z.object({
593
+ id: zod.z.string().min(1),
594
+ items: zod.z.array(ItemSchema),
595
+ name: zod.z.string().optional(),
596
+ height: zod.z.record(SectionHeightSchema),
597
+ position: zod.z.record(zod.z.number()),
598
+ hidden: zod.z.record(zod.z.boolean()),
599
+ color: zod.z.record(zod.z.nullable(zod.z.string())),
600
+ media: zod.z.record(SectionMediaSchema).optional()
601
+ });
602
+ const ItemTriggerSchema = zod.z.object({
603
+ itemId: zod.z.string(),
604
+ type: zod.z.enum(["hover-in", "hover-out", "click"]),
605
+ from: zod.z.string(),
606
+ to: zod.z.string()
607
+ });
608
+ const ScrollTriggerSchema = zod.z.object({
609
+ position: zod.z.number(),
610
+ from: zod.z.string(),
611
+ to: zod.z.string(),
612
+ isReverse: zod.z.boolean()
613
+ });
614
+ const VideoInteractionActionSchema = zod.z.object({
615
+ type: zod.z.enum(["play", "pause"]),
616
+ itemId: zod.z.string()
617
+ });
618
+ const StateSchema = zod.z.object({
619
+ id: zod.z.string(),
620
+ actions: zod.z.array(VideoInteractionActionSchema).optional()
621
+ });
622
+ const InteractionSchema = zod.z.object({
623
+ id: zod.z.string(),
624
+ triggers: zod.z.array(zod.z.union([ItemTriggerSchema, ScrollTriggerSchema])),
625
+ states: zod.z.array(StateSchema),
626
+ startStateId: zod.z.string()
627
+ });
628
+ const ArticleSchema = zod.z.object({
629
+ id: zod.z.string().min(1),
630
+ sections: zod.z.array(SectionSchema),
631
+ interactions: zod.z.record(zod.z.array(InteractionSchema))
632
+ });
633
+ const LayoutSchema = zod.z.object({
634
+ id: zod.z.string(),
635
+ title: zod.z.string(),
636
+ startsWith: zod.z.number().nonnegative(),
637
+ exemplary: zod.z.number().positive()
638
+ });
639
+ var FontFileTypes = /* @__PURE__ */ ((FontFileTypes2) => {
640
+ FontFileTypes2["OTF"] = "otf";
641
+ FontFileTypes2["TTF"] = "ttf";
642
+ FontFileTypes2["WOFF"] = "woff";
643
+ FontFileTypes2["WOFF2"] = "woff2";
644
+ FontFileTypes2["EOT"] = "eot";
645
+ return FontFileTypes2;
646
+ })(FontFileTypes || {});
647
+ const ProjectSchema = zod.z.object({
648
+ id: zod.z.string().min(1),
649
+ html: zod.z.object({
650
+ head: zod.z.string(),
651
+ afterBodyOpen: zod.z.string(),
652
+ beforeBodyClose: zod.z.string()
653
+ }),
654
+ meta: zod.z.object({
655
+ title: zod.z.string().optional(),
656
+ description: zod.z.string().optional(),
657
+ opengraphThumbnail: zod.z.string().optional(),
658
+ keywords: zod.z.string().optional(),
659
+ favicon: zod.z.string().optional()
660
+ }),
661
+ layouts: zod.z.array(LayoutSchema),
662
+ pages: zod.z.array(zod.z.object({
663
+ title: zod.z.string(),
664
+ articleId: zod.z.string().min(1),
665
+ slug: zod.z.string(),
666
+ meta: zod.z.object({
667
+ title: zod.z.string().optional(),
668
+ description: zod.z.string().optional(),
669
+ opengraphThumbnail: zod.z.string().optional(),
670
+ keywords: zod.z.string().optional(),
671
+ enabled: zod.z.boolean()
672
+ }).optional(),
673
+ id: zod.z.string().min(1)
674
+ })),
675
+ fonts: zod.z.object({
676
+ google: zod.z.string(),
677
+ adobe: zod.z.string(),
678
+ custom: zod.z.array(zod.z.object({
679
+ name: zod.z.string().min(1),
680
+ style: zod.z.string().min(1),
681
+ weight: zod.z.number(),
682
+ files: zod.z.array(
683
+ zod.z.object({
684
+ type: zod.z.nativeEnum(FontFileTypes),
685
+ url: zod.z.string()
686
+ })
687
+ )
688
+ }))
689
+ })
690
+ });
691
+ var KeyframeType = /* @__PURE__ */ ((KeyframeType2) => {
692
+ KeyframeType2["Dimensions"] = "dimensions";
693
+ KeyframeType2["Position"] = "position";
694
+ KeyframeType2["Rotation"] = "rotation";
695
+ KeyframeType2["BorderRadius"] = "border-radius";
696
+ KeyframeType2["BorderWidth"] = "border-width";
697
+ KeyframeType2["Opacity"] = "opacity";
698
+ KeyframeType2["Scale"] = "scale";
699
+ KeyframeType2["TextColor"] = "text-color";
700
+ KeyframeType2["LetterSpacing"] = "letter-spacing";
701
+ KeyframeType2["WordSpacing"] = "word-spacing";
702
+ KeyframeType2["Blur"] = "blur";
703
+ KeyframeType2["BackdropBlur"] = "backdrop-blur";
704
+ KeyframeType2["FXParams"] = "fx-params";
705
+ KeyframeType2["BorderFill"] = "border-fill";
706
+ KeyframeType2["Fill"] = "fill";
707
+ return KeyframeType2;
708
+ })(KeyframeType || {});
709
+ const KeyframesBaseSchema = zod.z.object({
710
+ id: zod.z.string().min(1),
711
+ layoutId: zod.z.string().min(1),
712
+ itemId: zod.z.string().min(1),
713
+ position: zod.z.number()
714
+ });
715
+ const DimensionsKeyframeSchema = KeyframesBaseSchema.extend({
716
+ type: zod.z.literal(KeyframeType.Dimensions),
717
+ value: zod.z.object({
718
+ width: zod.z.number().nonnegative(),
719
+ height: zod.z.number().nonnegative()
720
+ })
721
+ });
722
+ const PositionKeyframeSchema = KeyframesBaseSchema.extend({
723
+ type: zod.z.literal(KeyframeType.Position),
724
+ value: zod.z.object({
725
+ top: zod.z.number(),
726
+ left: zod.z.number()
727
+ })
728
+ });
729
+ const RotationKeyframeSchema = KeyframesBaseSchema.extend({
730
+ type: zod.z.literal(KeyframeType.Rotation),
731
+ value: zod.z.object({
732
+ angle: zod.z.number()
733
+ })
734
+ });
735
+ const BorderRadiusKeyframeSchema = KeyframesBaseSchema.extend({
736
+ type: zod.z.literal(KeyframeType.BorderRadius),
737
+ value: zod.z.object({
738
+ radius: zod.z.number().nonnegative()
739
+ })
740
+ });
741
+ const BorderWidthKeyframeSchema = KeyframesBaseSchema.extend({
742
+ type: zod.z.literal(KeyframeType.BorderWidth),
743
+ value: zod.z.object({
744
+ borderWidth: zod.z.number().nonnegative()
745
+ })
746
+ });
747
+ const BorderFillKeyframeSchema = KeyframesBaseSchema.extend({
748
+ type: zod.z.literal(KeyframeType.BorderFill),
749
+ value: zod.z.array(FillLayerSchema)
750
+ });
751
+ const OpacityKeyframeSchema = KeyframesBaseSchema.extend({
752
+ type: zod.z.literal(KeyframeType.Opacity),
753
+ value: zod.z.object({
754
+ opacity: zod.z.number().nonnegative()
755
+ })
756
+ });
757
+ const ScaleKeyframeSchema = KeyframesBaseSchema.extend({
758
+ type: zod.z.literal(KeyframeType.Scale),
759
+ value: zod.z.object({
760
+ scale: zod.z.number().nonnegative()
761
+ })
762
+ });
763
+ const BlurKeyframeSchema = KeyframesBaseSchema.extend({
764
+ type: zod.z.literal(KeyframeType.Blur),
765
+ value: zod.z.object({
766
+ blur: zod.z.number()
767
+ })
768
+ });
769
+ const BackdropBlurKeyframeSchema = KeyframesBaseSchema.extend({
770
+ type: zod.z.literal(KeyframeType.BackdropBlur),
771
+ value: zod.z.object({
772
+ backdropBlur: zod.z.number()
773
+ })
774
+ });
775
+ const TextColorKeyframeSchema = KeyframesBaseSchema.extend({
776
+ type: zod.z.literal(KeyframeType.TextColor),
777
+ value: zod.z.object({
778
+ color: zod.z.string()
779
+ })
780
+ });
781
+ const LetterSpacingKeyframeSchema = KeyframesBaseSchema.extend({
782
+ type: zod.z.literal(KeyframeType.LetterSpacing),
783
+ value: zod.z.object({
784
+ letterSpacing: zod.z.number()
785
+ })
786
+ });
787
+ const WordSpacingKeyframeSchema = KeyframesBaseSchema.extend({
788
+ type: zod.z.literal(KeyframeType.WordSpacing),
789
+ value: zod.z.object({
790
+ wordSpacing: zod.z.number()
791
+ })
792
+ });
793
+ const FXParamsKeyframeSchema = KeyframesBaseSchema.extend({
794
+ type: zod.z.literal(KeyframeType.FXParams),
795
+ value: zod.z.record(zod.z.string(), zod.z.number())
796
+ });
797
+ const FillKeyframeSchema = KeyframesBaseSchema.extend({
798
+ type: zod.z.literal(KeyframeType.Fill),
799
+ value: zod.z.array(FillLayerSchema)
800
+ });
801
+ const KeyframeSchema = zod.z.discriminatedUnion("type", [
802
+ DimensionsKeyframeSchema,
803
+ PositionKeyframeSchema,
804
+ RotationKeyframeSchema,
805
+ BorderRadiusKeyframeSchema,
806
+ BorderWidthKeyframeSchema,
807
+ BorderFillKeyframeSchema,
808
+ OpacityKeyframeSchema,
809
+ ScaleKeyframeSchema,
810
+ BlurKeyframeSchema,
811
+ BackdropBlurKeyframeSchema,
812
+ TextColorKeyframeSchema,
813
+ LetterSpacingKeyframeSchema,
814
+ WordSpacingKeyframeSchema,
815
+ FXParamsKeyframeSchema,
816
+ FillKeyframeSchema
817
+ ]);
818
+ const KeyframesSchema = zod.z.array(KeyframeSchema);
819
+ class Client {
820
+ constructor(APIUrl, fetchImpl = fetch$1) {
821
+ this.fetchImpl = fetchImpl;
822
+ this.url = new url.URL(APIUrl);
823
+ if (!this.url.username) {
824
+ throw new Error("Project ID is missing in the URL.");
825
+ }
826
+ if (!this.url.password) {
827
+ throw new Error("API key is missing in the URL.");
828
+ }
829
+ }
830
+ static getPageMeta(projectMeta, pageMeta) {
831
+ return pageMeta.enabled ? {
832
+ title: pageMeta.title ? pageMeta.title : projectMeta.title ?? "",
833
+ description: pageMeta.description ? pageMeta.description : projectMeta.description ?? "",
834
+ keywords: pageMeta.keywords ? pageMeta.keywords : projectMeta.keywords ?? "",
835
+ opengraphThumbnail: pageMeta.opengraphThumbnail ? pageMeta.opengraphThumbnail : projectMeta.opengraphThumbnail ?? "",
836
+ favicon: projectMeta.favicon ?? ""
837
+ } : projectMeta;
838
+ }
839
+ async getPageData(pageSlug, buildMode = "default") {
840
+ try {
841
+ const project = await this.fetchProject(buildMode);
842
+ const articleId = this.findArticleIdByPageSlug(pageSlug, project.pages);
843
+ const { article, keyframes } = await this.fetchArticle(articleId, buildMode);
844
+ const page = project.pages.find((page2) => page2.slug === pageSlug);
845
+ const meta = Client.getPageMeta(project.meta, page == null ? void 0 : page.meta);
846
+ return {
847
+ project,
848
+ article,
849
+ keyframes,
850
+ meta
851
+ };
852
+ } catch (e) {
853
+ throw e;
854
+ }
855
+ }
856
+ async getProjectPagesPaths() {
857
+ try {
858
+ const { pages } = await this.fetchProject();
859
+ return pages.map((p) => p.slug);
860
+ } catch (e) {
861
+ throw e;
862
+ }
863
+ }
864
+ async getLayouts() {
865
+ try {
866
+ const { layouts } = await this.fetchProject();
867
+ return layouts;
868
+ } catch (e) {
869
+ throw e;
870
+ }
871
+ }
872
+ async fetchProject(buildMode = "default") {
873
+ const { username: projectId, password: apiKey, origin } = this.url;
874
+ const url$1 = new url.URL(`/projects/${projectId}?buildMode=${buildMode}`, origin);
875
+ const response = await this.fetchImpl(url$1.href, {
876
+ headers: {
877
+ Authorization: `Bearer ${apiKey}`
878
+ }
879
+ });
880
+ if (!response.ok) {
881
+ throw new Error(`Failed to fetch project with id #${projectId}: ${response.statusText}`);
882
+ }
883
+ const data = await response.json();
884
+ const project = ProjectSchema.parse(data);
885
+ return project;
886
+ }
887
+ async fetchArticle(articleId, buildMode = "default") {
888
+ const { username: projectId, password: apiKey, origin } = this.url;
889
+ const url$1 = new url.URL(`/projects/${projectId}/articles/${articleId}?buildMode=${buildMode}`, origin);
890
+ const response = await this.fetchImpl(url$1.href, {
891
+ headers: {
892
+ Authorization: `Bearer ${apiKey}`
893
+ }
894
+ });
895
+ if (!response.ok) {
896
+ throw new Error(`Failed to fetch article with id #${articleId}: ${response.statusText}`);
897
+ }
898
+ const data = await response.json();
899
+ const article = ArticleSchema.parse(data.article);
900
+ const keyframes = KeyframesSchema.parse(data.keyframes);
901
+ return { article, keyframes };
902
+ }
903
+ findArticleIdByPageSlug(slug, pages) {
904
+ const { username: projectId } = this.url;
905
+ const page = pages.find((page2) => page2.slug === slug);
906
+ if (!page) {
907
+ throw new Error(`Page with a slug ${slug} was not found in project with id #${projectId}`);
908
+ }
909
+ return page.articleId;
910
+ }
911
+ }
912
+ const FILE_TYPES_MAP = {
913
+ ttf: "truetype",
914
+ otf: "opentype"
915
+ };
916
+ class FontFaceGenerator {
917
+ constructor(fonts) {
918
+ this.fonts = fonts;
919
+ }
920
+ generate() {
921
+ return this.fonts.map((font) => {
922
+ const eotFile = font.files.find((file) => file.type === "eot");
923
+ const otherFiles = font.files.filter((file) => file.type !== "eot").map((file) => `url('${file.url}') format('${FILE_TYPES_MAP[file.type] || file.type}')`);
924
+ return `
925
+ @font-face {
926
+ font-family: "${font.name}";
927
+ font-weight: ${font.weight};
928
+ font-style: ${font.style};
929
+ ${eotFile ? `src: url('${eotFile.url}');
930
+ ` : ""}src: ${otherFiles.join(", ")};
931
+ }`;
932
+ }).join("\n");
933
+ }
934
+ }
935
+ function getLayoutStyles(layouts, layoutValues, mapToStyles) {
936
+ const mediaQueries = layouts.sort((a, b) => a.startsWith - b.startsWith).reduce(
937
+ (acc, layout) => {
938
+ const values = layoutValues.map((lv) => lv[layout.id]);
939
+ return `
940
+ ${acc}
941
+ ${layout.startsWith !== 0 ? `@media (min-width: ${layout.startsWith}px) {${mapToStyles(values, layout.exemplary)}}` : `${mapToStyles(values, layout.exemplary)}`}`;
942
+ },
943
+ ""
944
+ );
945
+ return mediaQueries;
946
+ }
947
+ function getLayoutMediaQuery(layoutId, layouts) {
948
+ const sorted = layouts.slice().sort((a, b) => a.startsWith - b.startsWith);
949
+ const layoutIndex = sorted.findIndex((l) => l.id === layoutId);
950
+ if (layoutIndex === -1) {
951
+ throw new Error(`No layout was found by the given id #${layoutId}`);
952
+ }
953
+ const current = sorted[layoutIndex];
954
+ const next = sorted[layoutIndex + 1];
955
+ if (!next) {
956
+ return `@media (min-width: ${current.startsWith}px)`;
957
+ }
958
+ return `@media (min-width: ${current.startsWith}px) and (max-width: ${next.startsWith - 1}px)`;
959
+ }
960
+ class Writer {
961
+ constructor(size) {
962
+ this.data = new Uint8Array(size);
963
+ this.idx = 0;
964
+ this.size = size;
965
+ }
966
+ getData() {
967
+ if (this.idx !== this.size) throw new Error("Mismatch between size reserved and sized used");
968
+ return this.data.slice(0, this.idx);
969
+ }
970
+ writeUint8(value) {
971
+ this.data.set([value], this.idx);
972
+ this.idx += 1;
973
+ }
974
+ writeUint16(value) {
975
+ const arr = new Uint16Array(1);
976
+ arr[0] = value;
977
+ const buffer = new Uint8Array(arr.buffer);
978
+ this.data.set([buffer[1], buffer[0]], this.idx);
979
+ this.idx += 2;
980
+ }
981
+ writeUint8Array(value) {
982
+ this.data.set(value, this.idx);
983
+ this.idx += value.length;
984
+ }
985
+ }
986
+ const getExtradata = (avccBox) => {
987
+ let i;
988
+ let size = 7;
989
+ for (i = 0; i < avccBox.SPS.length; i += 1) {
990
+ size += 2 + avccBox.SPS[i].length;
991
+ }
992
+ for (i = 0; i < avccBox.PPS.length; i += 1) {
993
+ size += 2 + avccBox.PPS[i].length;
994
+ }
995
+ const writer = new Writer(size);
996
+ writer.writeUint8(avccBox.configurationVersion);
997
+ writer.writeUint8(avccBox.AVCProfileIndication);
998
+ writer.writeUint8(avccBox.profile_compatibility);
999
+ writer.writeUint8(avccBox.AVCLevelIndication);
1000
+ writer.writeUint8(avccBox.lengthSizeMinusOne + (63 << 2));
1001
+ writer.writeUint8(avccBox.nb_SPS_nalus + (7 << 5));
1002
+ for (i = 0; i < avccBox.SPS.length; i += 1) {
1003
+ writer.writeUint16(avccBox.SPS[i].length);
1004
+ writer.writeUint8Array(avccBox.SPS[i].nalu);
1005
+ }
1006
+ writer.writeUint8(avccBox.nb_PPS_nalus);
1007
+ for (i = 0; i < avccBox.PPS.length; i += 1) {
1008
+ writer.writeUint16(avccBox.PPS[i].length);
1009
+ writer.writeUint8Array(avccBox.PPS[i].nalu);
1010
+ }
1011
+ return writer.getData();
1012
+ };
1013
+ const decodeVideo = (src, emitFrame, { VideoDecoder: VideoDecoder2, EncodedVideoChunk: EncodedVideoChunk2, debug }) => new Promise((resolve, reject) => {
1014
+ if (debug) console.info("Decoding video from", src);
1015
+ try {
1016
+ const mp4boxfile = MP4Box__namespace.createFile();
1017
+ let codec;
1018
+ const decoder = new VideoDecoder2({
1019
+ output: (frame) => {
1020
+ createImageBitmap(frame, { resizeQuality: "low" }).then((bitmap) => {
1021
+ emitFrame(bitmap);
1022
+ frame.close();
1023
+ if (decoder.decodeQueueSize <= 0) {
1024
+ setTimeout(() => {
1025
+ if (decoder.state !== "closed") {
1026
+ decoder.close();
1027
+ resolve();
1028
+ }
1029
+ }, 500);
1030
+ }
1031
+ });
1032
+ },
1033
+ error: (e) => {
1034
+ console.error(e);
1035
+ reject(e);
1036
+ }
1037
+ });
1038
+ mp4boxfile.onReady = (info) => {
1039
+ if (info && info.videoTracks && info.videoTracks[0]) {
1040
+ [{ codec }] = info.videoTracks;
1041
+ if (debug) console.info("Video with codec:", codec);
1042
+ const avccBox = mp4boxfile.moov.traks[0].mdia.minf.stbl.stsd.entries[0].avcC;
1043
+ const extradata = getExtradata(avccBox);
1044
+ decoder.configure({ codec, description: extradata });
1045
+ mp4boxfile.setExtractionOptions(info.videoTracks[0].id);
1046
+ mp4boxfile.start();
1047
+ } else reject(new Error("URL provided is not a valid mp4 video file."));
1048
+ };
1049
+ mp4boxfile.onSamples = (track_id, ref, samples) => {
1050
+ for (let i = 0; i < samples.length; i += 1) {
1051
+ const sample = samples[i];
1052
+ const type = sample.is_sync ? "key" : "delta";
1053
+ const chunk = new EncodedVideoChunk2({
1054
+ type,
1055
+ timestamp: sample.cts,
1056
+ duration: sample.duration,
1057
+ data: sample.data
1058
+ });
1059
+ decoder.decode(chunk);
1060
+ }
1061
+ };
1062
+ fetch(src).then((res) => {
1063
+ const reader = res.body.getReader();
1064
+ let offset = 0;
1065
+ function appendBuffers({ done, value }) {
1066
+ if (done) {
1067
+ mp4boxfile.flush();
1068
+ return null;
1069
+ }
1070
+ const buf = value.buffer;
1071
+ buf.fileStart = offset;
1072
+ offset += buf.byteLength;
1073
+ mp4boxfile.appendBuffer(buf);
1074
+ return reader.read().then(appendBuffers);
1075
+ }
1076
+ return reader.read().then(appendBuffers);
1077
+ });
1078
+ } catch (e) {
1079
+ reject(e);
1080
+ }
1081
+ });
1082
+ const videoDecoder = (src, emitFrame, debug) => {
1083
+ if (typeof VideoDecoder === "function" && typeof EncodedVideoChunk === "function") {
1084
+ if (debug)
1085
+ console.info("WebCodecs is natively supported, using native version...");
1086
+ return decodeVideo(src, emitFrame, {
1087
+ VideoDecoder,
1088
+ EncodedVideoChunk,
1089
+ debug
1090
+ });
1091
+ }
1092
+ if (debug) console.info("WebCodecs is not available in this browser.");
1093
+ return Promise.resolve();
1094
+ };
1095
+ class ScrollPlaybackVideoManager {
1096
+ constructor(options) {
1097
+ this.currentTime = 0;
1098
+ this.targetTime = 0;
1099
+ this.canvas = null;
1100
+ this.context = null;
1101
+ this.frames = [];
1102
+ this.frameRate = 0;
1103
+ this.transitioning = false;
1104
+ this.debug = false;
1105
+ this.frameThreshold = 0.1;
1106
+ this.transitionSpeed = 10;
1107
+ this.useWebCodecs = true;
1108
+ this.resize = () => {
1109
+ if (this.debug) console.info("ScrollVideo resizing...");
1110
+ if (this.canvas) {
1111
+ this.setCoverStyle(this.canvas);
1112
+ } else if (this.video) {
1113
+ this.setCoverStyle(this.video);
1114
+ }
1115
+ this.paintCanvasFrame(Math.floor(this.currentTime * this.frameRate));
1116
+ };
1117
+ this.decodeVideo = () => {
1118
+ if (!this.video) return;
1119
+ if (this.useWebCodecs && this.video.src) {
1120
+ videoDecoder(
1121
+ this.video.src,
1122
+ (frame) => {
1123
+ this.frames.push(frame);
1124
+ },
1125
+ this.debug
1126
+ ).then(() => {
1127
+ if (!this.video || !this.container) return;
1128
+ if (this.frames.length === 0) {
1129
+ if (this.debug) console.error("No frames were received from webCodecs");
1130
+ return;
1131
+ }
1132
+ this.frameRate = this.frames.length / this.video.duration;
1133
+ if (this.debug) console.info("Received", this.frames.length, "frames");
1134
+ this.canvas = document.createElement("canvas");
1135
+ this.context = this.canvas.getContext("2d");
1136
+ this.video.style.display = "none";
1137
+ this.container.appendChild(this.canvas);
1138
+ this.paintCanvasFrame(Math.floor(this.currentTime * this.frameRate));
1139
+ }).catch(() => {
1140
+ if (this.debug) console.error("Error encountered while decoding video");
1141
+ this.frames = [];
1142
+ this.video.load();
1143
+ });
1144
+ }
1145
+ };
1146
+ this.resizeObserver = new ResizeObserver(() => {
1147
+ this.resize();
1148
+ });
1149
+ const {
1150
+ src,
1151
+ videoContainer
1152
+ } = options;
1153
+ if (typeof document !== "object") {
1154
+ console.error("ScrollVideo must be initiated in a DOM context");
1155
+ return;
1156
+ }
1157
+ if (!videoContainer) {
1158
+ console.error("scrollVideoContainer must be a valid DOM object");
1159
+ return;
1160
+ }
1161
+ if (!src) {
1162
+ console.error("Must provide valid video src to ScrollVideo");
1163
+ return;
1164
+ }
1165
+ this.container = typeof videoContainer === "string" ? document.getElementById(videoContainer) : videoContainer;
1166
+ this.resizeObserver.observe(this.container);
1167
+ this.video = document.createElement("video");
1168
+ this.video.src = src;
1169
+ this.video.preload = "auto";
1170
+ this.video.tabIndex = 0;
1171
+ this.video.playsInline = true;
1172
+ this.video.muted = true;
1173
+ this.video.pause();
1174
+ this.video.load();
1175
+ this.container.appendChild(this.video);
1176
+ const browserEngine = new UAParser().getEngine();
1177
+ this.isSafari = browserEngine.name === "WebKit";
1178
+ if (this.debug && this.isSafari) console.info("Safari browser detected");
1179
+ this.video.addEventListener("loadedmetadata", () => this.setTargetTimePercent(0, true), { once: true });
1180
+ this.video.addEventListener("progress", this.resize);
1181
+ this.decodeVideo();
1182
+ }
1183
+ setCoverStyle(el) {
1184
+ if (el && this.container) {
1185
+ el.style.position = "absolute";
1186
+ el.style.top = "50%";
1187
+ el.style.left = "50%";
1188
+ el.style.transform = "translate(-50%, -50%)";
1189
+ const { width: containerWidth, height: containerHeight } = this.container.getBoundingClientRect();
1190
+ const width = el.videoWidth || el.width;
1191
+ const height = el.videoHeight || el.height;
1192
+ if (containerWidth / containerHeight > width / height) {
1193
+ el.style.width = "100%";
1194
+ el.style.height = "auto";
1195
+ } else {
1196
+ el.style.height = "100%";
1197
+ el.style.width = "auto";
1198
+ }
1199
+ }
1200
+ }
1201
+ paintCanvasFrame(frameNum) {
1202
+ if (this.canvas) {
1203
+ const frameIdx = Math.min(frameNum, this.frames.length - 1);
1204
+ const currFrame = this.frames[frameIdx];
1205
+ if (currFrame && this.container) {
1206
+ if (this.debug) console.info("Painting frame", frameIdx);
1207
+ this.canvas.width = currFrame.width;
1208
+ this.canvas.height = currFrame.height;
1209
+ const { width, height } = this.container.getBoundingClientRect();
1210
+ this.resetCanvasDimensions(width, height, currFrame.width, currFrame.height);
1211
+ this.context.drawImage(currFrame, 0, 0, currFrame.width, currFrame.height);
1212
+ }
1213
+ }
1214
+ }
1215
+ transitionToTargetTime(jump) {
1216
+ if (!this.video) return;
1217
+ if (this.debug) console.info("Transitioning targetTime:", this.targetTime, "currentTime:", this.currentTime);
1218
+ if (isNaN(this.targetTime) || Math.abs(this.currentTime - this.targetTime) < this.frameThreshold) {
1219
+ this.video.pause();
1220
+ this.transitioning = false;
1221
+ return;
1222
+ }
1223
+ if (this.targetTime > this.video.duration) {
1224
+ this.targetTime = this.video.duration;
1225
+ }
1226
+ if (this.targetTime < 0) {
1227
+ this.targetTime = 0;
1228
+ }
1229
+ const transitionForward = this.targetTime - this.currentTime;
1230
+ if (this.canvas) {
1231
+ this.currentTime += transitionForward / (256 / this.transitionSpeed);
1232
+ if (jump) {
1233
+ this.currentTime = this.targetTime;
1234
+ }
1235
+ this.paintCanvasFrame(Math.floor(this.currentTime * this.frameRate));
1236
+ } else if (jump || this.isSafari || this.targetTime - this.currentTime < 0) {
1237
+ this.video.pause();
1238
+ this.currentTime += transitionForward / (64 / this.transitionSpeed);
1239
+ if (jump) {
1240
+ this.currentTime = this.targetTime;
1241
+ }
1242
+ this.video.currentTime = this.currentTime;
1243
+ } else {
1244
+ const playbackRate = Math.max(Math.min(transitionForward * 4, this.transitionSpeed, 16), 1);
1245
+ if (this.debug) console.info("ScrollVideo playbackRate:", playbackRate);
1246
+ if (!isNaN(playbackRate)) {
1247
+ this.video.playbackRate = playbackRate;
1248
+ this.video.play();
1249
+ }
1250
+ this.currentTime = this.video.currentTime;
1251
+ }
1252
+ if (typeof requestAnimationFrame === "function") {
1253
+ requestAnimationFrame(() => this.transitionToTargetTime(jump));
1254
+ }
1255
+ }
1256
+ resetCanvasDimensions(w, h, frameW, frameH) {
1257
+ if (!this.canvas) return;
1258
+ if (w / h > frameW / frameH) {
1259
+ this.canvas.style.width = "100%";
1260
+ this.canvas.style.height = "auto";
1261
+ } else {
1262
+ this.canvas.style.height = "100%";
1263
+ this.canvas.style.width = "auto";
1264
+ }
1265
+ }
1266
+ setTargetTimePercent(setPercentage, jump = true) {
1267
+ if (!this.video) return;
1268
+ this.targetTime = Math.max(Math.min(setPercentage, 1), 0) * (this.frames.length && this.frameRate ? this.frames.length / this.frameRate : this.video.duration);
1269
+ if (!jump && Math.abs(this.currentTime - this.targetTime) < this.frameThreshold) return;
1270
+ if (!jump && this.transitioning) return;
1271
+ if (!this.canvas && !this.video.paused) this.video.play();
1272
+ this.transitioning = true;
1273
+ this.transitionToTargetTime(jump);
1274
+ }
1275
+ destroy() {
1276
+ var _a;
1277
+ this.resizeObserver.unobserve(this.container);
1278
+ (_a = this.video) == null ? void 0 : _a.removeEventListener("progress", this.resize);
1279
+ if (this.debug) console.info("Destroying ScrollVideo");
1280
+ if (this.container) this.container.innerHTML = "";
1281
+ }
1282
+ }
1283
+ const wrapper = "ControlSlider-module__wrapper___sHEkd";
1284
+ const sliderItem = "ControlSlider-module__sliderItem___QQSkR";
1285
+ const sliderImage = "ControlSlider-module__sliderImage___9hRl-";
1286
+ const arrow = "ControlSlider-module__arrow___05ghY";
1287
+ const arrowVertical = "ControlSlider-module__arrowVertical___tBfVN";
1288
+ const nextArrow = "ControlSlider-module__nextArrow___-30Yc";
1289
+ const arrowInner = "ControlSlider-module__arrowInner___aEra3";
1290
+ const arrowIcon = "ControlSlider-module__arrowIcon___S4ztF";
1291
+ const arrowImg = "ControlSlider-module__arrowImg___2dwJW";
1292
+ const mirror = "ControlSlider-module__mirror___brd6U";
1293
+ const pagination = "ControlSlider-module__pagination___bicLF";
1294
+ const paginationInner = "ControlSlider-module__paginationInner___bT-P-";
1295
+ const paginationVertical = "ControlSlider-module__paginationVertical___zYqKw";
1296
+ const paginationItem = "ControlSlider-module__paginationItem___nTRbk";
1297
+ const dot = "ControlSlider-module__dot___p1Qun";
1298
+ const activeDot = "ControlSlider-module__activeDot___LHFaj";
1299
+ const paginationInsideBottom = "ControlSlider-module__paginationInsideBottom___R3FWn";
1300
+ const paginationInsideTop = "ControlSlider-module__paginationInsideTop___V-qb-";
1301
+ const paginationOutsideBottom = "ControlSlider-module__paginationOutsideBottom___14w8D";
1302
+ const paginationOutsideTop = "ControlSlider-module__paginationOutsideTop___SCLqB";
1303
+ const paginationInsideLeft = "ControlSlider-module__paginationInsideLeft___yOBRZ";
1304
+ const paginationInsideRight = "ControlSlider-module__paginationInsideRight___Rtt3o";
1305
+ const paginationOutsideLeft = "ControlSlider-module__paginationOutsideLeft___lahaw";
1306
+ const paginationOutsideRight = "ControlSlider-module__paginationOutsideRight___EtuQa";
1307
+ const imgWrapper = "ControlSlider-module__imgWrapper___UjEgB";
1308
+ const captionBlock = "ControlSlider-module__captionBlock___dJ6-j";
1309
+ const captionTextWrapper = "ControlSlider-module__captionTextWrapper___HFlpf";
1310
+ const captionText = "ControlSlider-module__captionText___uGBVc";
1311
+ const active = "ControlSlider-module__active___WZK4G";
1312
+ const withPointerEvents = "ControlSlider-module__withPointerEvents___t-18M";
1313
+ const topLeftAlignment = "ControlSlider-module__topLeftAlignment___zjnGM";
1314
+ const topCenterAlignment = "ControlSlider-module__topCenterAlignment___gD1xW";
1315
+ const topRightAlignment = "ControlSlider-module__topRightAlignment___NMapS";
1316
+ const middleLeftAlignment = "ControlSlider-module__middleLeftAlignment___OnUrY";
1317
+ const middleCenterAlignment = "ControlSlider-module__middleCenterAlignment___Tdkl0";
1318
+ const middleRightAlignment = "ControlSlider-module__middleRightAlignment___wEbfX";
1319
+ const bottomLeftAlignment = "ControlSlider-module__bottomLeftAlignment___cTP2-";
1320
+ const bottomCenterAlignment = "ControlSlider-module__bottomCenterAlignment___c54fB";
1321
+ const bottomRightAlignment = "ControlSlider-module__bottomRightAlignment___kEwrz";
1322
+ const clickOverlay = "ControlSlider-module__clickOverlay___DZA28";
1323
+ const contain = "ControlSlider-module__contain___pLyq7";
1324
+ const cover = "ControlSlider-module__cover___KdDat";
1325
+ const styles$3 = {
1326
+ wrapper,
1327
+ sliderItem,
1328
+ sliderImage,
1329
+ arrow,
1330
+ arrowVertical,
1331
+ nextArrow,
1332
+ arrowInner,
1333
+ arrowIcon,
1334
+ arrowImg,
1335
+ mirror,
1336
+ pagination,
1337
+ paginationInner,
1338
+ paginationVertical,
1339
+ paginationItem,
1340
+ dot,
1341
+ activeDot,
1342
+ paginationInsideBottom,
1343
+ paginationInsideTop,
1344
+ paginationOutsideBottom,
1345
+ paginationOutsideTop,
1346
+ paginationInsideLeft,
1347
+ paginationInsideRight,
1348
+ paginationOutsideLeft,
1349
+ paginationOutsideRight,
1350
+ imgWrapper,
1351
+ captionBlock,
1352
+ captionTextWrapper,
1353
+ captionText,
1354
+ active,
1355
+ withPointerEvents,
1356
+ topLeftAlignment,
1357
+ topCenterAlignment,
1358
+ topRightAlignment,
1359
+ middleLeftAlignment,
1360
+ middleCenterAlignment,
1361
+ middleRightAlignment,
1362
+ bottomLeftAlignment,
1363
+ bottomCenterAlignment,
1364
+ bottomRightAlignment,
1365
+ clickOverlay,
1366
+ contain,
1367
+ cover
1368
+ };
1369
+ const link$1 = "RichTextRenderer-module__link___BWeZ2";
1370
+ const styles$2 = {
1371
+ link: link$1
1372
+ };
1373
+ const RichTextRenderer = ({ content }) => {
1374
+ const getChildren = (children) => {
1375
+ return children.map((child, i) => {
1376
+ if (child.type === "link") {
1377
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { className: styles$2.link, href: child.value, target: child.target, children: getChildren(child.children) }, i);
1378
+ }
1379
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: getLeafCss(child), children: child.text }, i);
1380
+ });
1381
+ };
1382
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: content.map((block, i) => {
1383
+ const children = block.children;
1384
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: getChildren(children) }, i);
1385
+ }) });
1386
+ };
1387
+ function getLeafCss(leaf) {
1388
+ return {
1389
+ ...leaf.fontWeight && { fontWeight: leaf.fontWeight },
1390
+ ...leaf.fontStyle && { fontStyle: leaf.fontStyle },
1391
+ ...leaf.textDecoration && { textDecoration: leaf.textDecoration },
1392
+ ...leaf.textTransform && { textTransform: leaf.textTransform },
1393
+ ...leaf.fontVariant && { fontVariant: leaf.fontVariant },
1394
+ ...leaf.verticalAlign && {
1395
+ verticalAlign: leaf.verticalAlign,
1396
+ lineHeight: "0px"
1397
+ }
1398
+ };
1399
+ }
1400
+ function scalingValue(value, isEditor = false) {
1401
+ return isEditor ? `calc(var(--cntrl-article-width) * ${value})` : `${value * 100}vw`;
1402
+ }
1403
+ const svg = "SvgImage-module__svg___q3xE-";
1404
+ const img = "SvgImage-module__img___VsTm-";
1405
+ const styles$1 = {
1406
+ svg,
1407
+ img
1408
+ };
1409
+ const SvgImage = ({ url: url2, fill = "#000000", hoverFill = "#CCCCCC", className = "" }) => {
1410
+ const [supportsMask, setSupportsMask] = react.useState(true);
1411
+ react.useEffect(() => {
1412
+ if (typeof window !== "undefined" && window.CSS) {
1413
+ const supported = CSS.supports("mask-image", 'url("")') || CSS.supports("-webkit-mask-image", 'url("")');
1414
+ setSupportsMask(supported);
1415
+ }
1416
+ }, []);
1417
+ if (!url2.endsWith(".svg") || !supportsMask) {
1418
+ return /* @__PURE__ */ jsxRuntime.jsx("img", { src: url2, alt: "", className: cn(styles$1.img, className) });
1419
+ }
1420
+ return /* @__PURE__ */ jsxRuntime.jsx(
1421
+ "span",
1422
+ {
1423
+ "data-supports-mask": supportsMask,
1424
+ className: cn(styles$1.svg, className),
1425
+ style: {
1426
+ "--svg": `url(${url2})`,
1427
+ "--fill": fill,
1428
+ "--hover-fill": hoverFill
1429
+ }
1430
+ }
1431
+ );
1432
+ };
1433
+ const alignmentClassName = {
1434
+ "top-left": styles$3.topLeftAlignment,
1435
+ "top-center": styles$3.topCenterAlignment,
1436
+ "top-right": styles$3.topRightAlignment,
1437
+ "middle-left": styles$3.middleLeftAlignment,
1438
+ "middle-center": styles$3.middleCenterAlignment,
1439
+ "middle-right": styles$3.middleRightAlignment,
1440
+ "bottom-left": styles$3.bottomLeftAlignment,
1441
+ "bottom-center": styles$3.bottomCenterAlignment,
1442
+ "bottom-right": styles$3.bottomRightAlignment
1443
+ };
1444
+ function ControlSlider({ settings, content, styles: sliderStyles, isEditor }) {
1445
+ const [sliderRef, setSliderRef] = react.useState(null);
1446
+ const { widthSettings, fontSettings, letterSpacing, textAlign, wordSpacing, fontSizeLineHeight, textAppearance, color } = sliderStyles.caption;
1447
+ const [sliderDimensions, setSliderDimensions] = react.useState(void 0);
1448
+ const [wrapperRef, setWrapperRef] = react.useState(null);
1449
+ const [currentSlideIndex, setCurrentSlideIndex] = react.useState(0);
1450
+ const [key, setKey] = react.useState(0);
1451
+ const { direction, transition, controls, pagination: pagination2, caption, triggers } = settings;
1452
+ const prevSliderTypeRef = react.useRef(transition.type);
1453
+ const { x: controlsOffsetX, y: controlsOffsetY } = settings.controls.offset;
1454
+ const handleArrowClick = (dir) => {
1455
+ if (sliderRef) {
1456
+ sliderRef.go(dir);
1457
+ }
1458
+ };
1459
+ react.useEffect(() => {
1460
+ if (!wrapperRef) return;
1461
+ const observer = new ResizeObserver((entries) => {
1462
+ if (!sliderRef) return;
1463
+ const [wrapper2] = entries;
1464
+ setSliderDimensions({
1465
+ width: Math.round(wrapper2.contentRect.width),
1466
+ height: Math.round(wrapper2.contentRect.height)
1467
+ });
1468
+ });
1469
+ observer.observe(wrapperRef);
1470
+ return () => observer.unobserve(wrapperRef);
1471
+ }, [wrapperRef]);
1472
+ react.useEffect(() => {
1473
+ if (!sliderRef || prevSliderTypeRef.current === transition.type) return;
1474
+ setKey((prev) => prev + 1);
1475
+ prevSliderTypeRef.current = transition.type;
1476
+ }, [transition.type]);
1477
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(styles$3.wrapper, { [styles$3.editor]: isEditor }), ref: setWrapperRef, children: /* @__PURE__ */ jsxRuntime.jsxs(
1478
+ "div",
1479
+ {
1480
+ className: styles$3.sliderInner,
1481
+ style: {
1482
+ width: sliderDimensions ? sliderDimensions.width : "100%",
1483
+ height: sliderDimensions ? sliderDimensions.height : "100%",
1484
+ backgroundColor: transition.backgroundColor && transition.type === "fade in" ? transition.backgroundColor : "transparent"
1485
+ },
1486
+ children: [
1487
+ settings.caption.isActive && /* @__PURE__ */ jsxRuntime.jsx(
1488
+ "div",
1489
+ {
1490
+ className: cn(styles$3.captionBlock),
1491
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1492
+ "div",
1493
+ {
1494
+ className: styles$3.captionTextWrapper,
1495
+ children: content.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
1496
+ "div",
1497
+ {
1498
+ className: cn(styles$3.captionText, alignmentClassName[caption.alignment], {
1499
+ [styles$3.withPointerEvents]: index === currentSlideIndex && isEditor,
1500
+ [styles$3.active]: index === currentSlideIndex
1501
+ }),
1502
+ style: {
1503
+ fontFamily: fontSettings.fontFamily,
1504
+ fontWeight: fontSettings.fontWeight,
1505
+ fontStyle: fontSettings.fontStyle,
1506
+ width: widthSettings.sizing === "auto" ? "max-content" : scalingValue(widthSettings.width, isEditor),
1507
+ letterSpacing: scalingValue(letterSpacing, isEditor),
1508
+ wordSpacing: scalingValue(wordSpacing, isEditor),
1509
+ textAlign,
1510
+ fontSize: scalingValue(fontSizeLineHeight.fontSize, isEditor),
1511
+ lineHeight: scalingValue(fontSizeLineHeight.lineHeight, isEditor),
1512
+ textTransform: textAppearance.textTransform ?? "none",
1513
+ textDecoration: textAppearance.textDecoration ?? "none",
1514
+ fontVariant: textAppearance.fontVariant ?? "normal",
1515
+ color,
1516
+ transitionDuration: transition.duration ? `${Math.round(parseInt(transition.duration) / 2)}ms` : "500ms"
1517
+ },
1518
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1519
+ "div",
1520
+ {
1521
+ "data-styles": "caption",
1522
+ className: styles$3.captionTextInner,
1523
+ style: {
1524
+ "--link-hover-color": caption.hover,
1525
+ position: "relative",
1526
+ top: scalingValue(caption.offset.y, isEditor),
1527
+ left: scalingValue(caption.offset.x, isEditor)
1528
+ },
1529
+ children: /* @__PURE__ */ jsxRuntime.jsx(RichTextRenderer, { content: item.imageCaption })
1530
+ }
1531
+ )
1532
+ },
1533
+ index
1534
+ ))
1535
+ }
1536
+ )
1537
+ }
1538
+ ),
1539
+ /* @__PURE__ */ jsxRuntime.jsx(
1540
+ reactSplide.Splide,
1541
+ {
1542
+ onMove: (e) => {
1543
+ setCurrentSlideIndex(e.index);
1544
+ },
1545
+ ref: setSliderRef,
1546
+ options: {
1547
+ arrows: false,
1548
+ speed: transition.duration ? parseInt(transition.duration) : 500,
1549
+ autoplay: isEditor ? false : triggers.autoPlay !== null,
1550
+ ...triggers.autoPlay !== null && {
1551
+ interval: parseInt(triggers.autoPlay) * 1e3
1552
+ },
1553
+ direction: direction === "horiz" || transition.type === "fade in" ? "ltr" : "ttb",
1554
+ pagination: false,
1555
+ drag: triggers.triggersList.drag,
1556
+ perPage: 1,
1557
+ width: sliderDimensions ? sliderDimensions.width : "100%",
1558
+ height: sliderDimensions ? sliderDimensions.height : "100%",
1559
+ type: transition.type === "fade in" ? "fade" : "loop",
1560
+ rewind: true
1561
+ },
1562
+ children: content.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(reactSplide.SplideSlide, { children: /* @__PURE__ */ jsxRuntime.jsx(
1563
+ "div",
1564
+ {
1565
+ className: styles$3.sliderItem,
1566
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1567
+ "div",
1568
+ {
1569
+ className: styles$3.imgWrapper,
1570
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1571
+ "img",
1572
+ {
1573
+ className: cn(styles$3.sliderImage, {
1574
+ [styles$3.contain]: item.image.objectFit === "contain",
1575
+ [styles$3.cover]: item.image.objectFit === "cover"
1576
+ }),
1577
+ src: item.image.url,
1578
+ alt: item.image.name ?? ""
1579
+ }
1580
+ )
1581
+ }
1582
+ )
1583
+ }
1584
+ ) }, index))
1585
+ },
1586
+ key
1587
+ ),
1588
+ controls.isActive && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1589
+ /* @__PURE__ */ jsxRuntime.jsx(
1590
+ "div",
1591
+ {
1592
+ className: cn(styles$3.arrow, {
1593
+ [styles$3.arrowVertical]: direction === "vert"
1594
+ }),
1595
+ style: {
1596
+ color: controls.color,
1597
+ ["--arrow-hover-color"]: controls.hover
1598
+ },
1599
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1600
+ "button",
1601
+ {
1602
+ onClick: () => {
1603
+ handleArrowClick("-1");
1604
+ },
1605
+ className: styles$3.arrowInner,
1606
+ style: {
1607
+ transform: `translate(${scalingValue(controlsOffsetX, isEditor)}, ${scalingValue(controlsOffsetY * (direction === "horiz" ? 1 : -1), isEditor)}) scale(${settings.controls.scale / 100}) rotate(${direction === "horiz" ? "0deg" : "90deg"})`
1608
+ },
1609
+ children: [
1610
+ controls.arrowsImgUrl && /* @__PURE__ */ jsxRuntime.jsx(
1611
+ SvgImage,
1612
+ {
1613
+ url: controls.arrowsImgUrl,
1614
+ fill: controls.color,
1615
+ hoverFill: controls.hover,
1616
+ className: cn(styles$3.arrowImg, styles$3.mirror)
1617
+ }
1618
+ ),
1619
+ !controls.arrowsImgUrl && /* @__PURE__ */ jsxRuntime.jsx(ArrowIcon, { color: controls.color, className: cn(styles$3.arrowIcon, styles$3.arrowImg, styles$3.mirror) })
1620
+ ]
1621
+ }
1622
+ )
1623
+ }
1624
+ ),
1625
+ /* @__PURE__ */ jsxRuntime.jsx(
1626
+ "div",
1627
+ {
1628
+ className: cn(styles$3.arrow, styles$3.nextArrow, {
1629
+ [styles$3.arrowVertical]: direction === "vert"
1630
+ }),
1631
+ style: {
1632
+ color: controls.color,
1633
+ ["--arrow-hover-color"]: controls.hover
1634
+ },
1635
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1636
+ "button",
1637
+ {
1638
+ className: styles$3.arrowInner,
1639
+ onClick: () => handleArrowClick("+1"),
1640
+ style: {
1641
+ transform: `translate(${scalingValue(controlsOffsetX * (direction === "horiz" ? -1 : 1), isEditor)}, ${scalingValue(controlsOffsetY, isEditor)}) scale(${settings.controls.scale / 100}) rotate(${direction === "horiz" ? "0deg" : "90deg"})`
1642
+ },
1643
+ children: [
1644
+ controls.arrowsImgUrl && /* @__PURE__ */ jsxRuntime.jsx(
1645
+ SvgImage,
1646
+ {
1647
+ url: controls.arrowsImgUrl,
1648
+ fill: controls.color,
1649
+ hoverFill: controls.hover,
1650
+ className: styles$3.arrowImg
1651
+ }
1652
+ ),
1653
+ !controls.arrowsImgUrl && /* @__PURE__ */ jsxRuntime.jsx(ArrowIcon, { color: controls.color, className: cn(styles$3.arrowIcon, styles$3.arrowImg) })
1654
+ ]
1655
+ }
1656
+ )
1657
+ }
1658
+ )
1659
+ ] }),
1660
+ triggers.triggersList.click && /* @__PURE__ */ jsxRuntime.jsx(
1661
+ "div",
1662
+ {
1663
+ className: styles$3.clickOverlay,
1664
+ onClick: () => {
1665
+ if (sliderRef) {
1666
+ sliderRef.go("+1");
1667
+ }
1668
+ }
1669
+ }
1670
+ ),
1671
+ pagination2.isActive && /* @__PURE__ */ jsxRuntime.jsx(
1672
+ "div",
1673
+ {
1674
+ className: cn(styles$3.pagination, {
1675
+ [styles$3.paginationInsideBottom]: pagination2.position === "inside-1" && direction === "horiz",
1676
+ [styles$3.paginationInsideTop]: pagination2.position === "inside-2" && direction === "horiz",
1677
+ [styles$3.paginationOutsideBottom]: pagination2.position === "outside-1" && direction === "horiz",
1678
+ [styles$3.paginationOutsideTop]: pagination2.position === "outside-2" && direction === "horiz",
1679
+ [styles$3.paginationInsideLeft]: pagination2.position === "inside-1" && direction === "vert",
1680
+ [styles$3.paginationInsideRight]: pagination2.position === "inside-2" && direction === "vert",
1681
+ [styles$3.paginationOutsideLeft]: pagination2.position === "outside-1" && direction === "vert",
1682
+ [styles$3.paginationOutsideRight]: pagination2.position === "outside-2" && direction === "vert",
1683
+ [styles$3.paginationVertical]: direction === "vert"
1684
+ }),
1685
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1686
+ "div",
1687
+ {
1688
+ className: styles$3.paginationInner,
1689
+ style: {
1690
+ backgroundColor: pagination2.colors[2],
1691
+ transform: `scale(${pagination2.scale / 100}) translate(${scalingValue(pagination2.offset.x, isEditor)}, ${scalingValue(pagination2.offset.y, isEditor)}) rotate(${direction === "horiz" ? "0deg" : "90deg"})`
1692
+ },
1693
+ children: content.map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
1694
+ "button",
1695
+ {
1696
+ onClick: () => {
1697
+ if (sliderRef) {
1698
+ sliderRef.go(index);
1699
+ }
1700
+ },
1701
+ className: cn(styles$3.paginationItem),
1702
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1703
+ "div",
1704
+ {
1705
+ className: cn(styles$3.dot, {
1706
+ [styles$3.activeDot]: index === currentSlideIndex
1707
+ }),
1708
+ style: {
1709
+ backgroundColor: index === currentSlideIndex ? pagination2.colors[0] : pagination2.colors[1],
1710
+ ["--pagination-hover-color"]: pagination2.hover
1711
+ }
1712
+ }
1713
+ )
1714
+ },
1715
+ index
1716
+ ))
1717
+ }
1718
+ )
1719
+ }
1720
+ )
1721
+ ]
1722
+ }
1723
+ ) });
1724
+ }
1725
+ function ArrowIcon({ color, className }) {
1726
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 10 18", className, children: /* @__PURE__ */ jsxRuntime.jsx("g", { id: "Symbols", stroke: "none", strokeWidth: "1", fillRule: "evenodd", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M-3.70710678,4.29289322 C-3.34662282,3.93240926 -2.77939176,3.90467972 -2.38710056,4.20970461 L-2.29289322,4.29289322 L5,11.585 L12.2928932,4.29289322 C12.6533772,3.93240926 13.2206082,3.90467972 13.6128994,4.20970461 L13.7071068,4.29289322 C14.0675907,4.65337718 14.0953203,5.22060824 13.7902954,5.61289944 L13.7071068,5.70710678 L5.70710678,13.7071068 C5.34662282,14.0675907 4.77939176,14.0953203 4.38710056,13.7902954 L4.29289322,13.7071068 L-3.70710678,5.70710678 C-4.09763107,5.31658249 -4.09763107,4.68341751 -3.70710678,4.29289322 Z", id: "Shape-Copy", fill: color, transform: "translate(5, 9) rotate(-90) translate(-5, -9)" }) }) });
1727
+ }
1728
+ const ControlSliderComponent = {
1729
+ element: ControlSlider,
1730
+ id: "control-slider",
1731
+ name: "Slider",
1732
+ preview: {
1733
+ type: "video",
1734
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7EQ4ME6CP4KX7TJ4HPAXFEW.mp4"
1735
+ },
1736
+ defaultSize: {
1737
+ width: 400,
1738
+ height: 400
1739
+ },
1740
+ schema: {
1741
+ type: "object",
1742
+ properties: {
1743
+ settings: {
1744
+ layoutBased: true,
1745
+ type: "object",
1746
+ properties: {
1747
+ triggers: {
1748
+ name: "triggers",
1749
+ icon: "target",
1750
+ tooltip: "Triggers",
1751
+ type: "object",
1752
+ properties: {
1753
+ triggersList: {
1754
+ type: "object",
1755
+ display: {
1756
+ type: "toggle-ratio-group"
1757
+ },
1758
+ properties: {
1759
+ click: {
1760
+ type: "boolean"
1761
+ },
1762
+ drag: {
1763
+ type: "boolean"
1764
+ }
1765
+ }
1766
+ },
1767
+ autoPlay: {
1768
+ type: ["string", "null"],
1769
+ label: "Auto",
1770
+ display: {
1771
+ type: "step-selector"
1772
+ },
1773
+ enum: [null, "1s", "2s", "3s", "4s", "5s"]
1774
+ }
1775
+ }
1776
+ },
1777
+ direction: {
1778
+ name: "direction",
1779
+ icon: "horizontal-resize",
1780
+ tooltip: "Direction",
1781
+ type: "string",
1782
+ display: {
1783
+ type: "ratio-group"
1784
+ },
1785
+ enum: ["horiz", "vert"]
1786
+ },
1787
+ transition: {
1788
+ name: "transit",
1789
+ icon: "transition",
1790
+ tooltip: "Transition",
1791
+ type: "object",
1792
+ properties: {
1793
+ type: {
1794
+ type: "string",
1795
+ display: {
1796
+ type: "ratio-group"
1797
+ },
1798
+ enum: ["slide", "fade in"]
1799
+ },
1800
+ backgroundColor: {
1801
+ type: ["string", "null"],
1802
+ name: "BG Color",
1803
+ display: {
1804
+ visible: false,
1805
+ type: "settings-color-picker",
1806
+ format: "single"
1807
+ }
1808
+ },
1809
+ duration: {
1810
+ type: "string",
1811
+ label: "hourglass-icon",
1812
+ display: {
1813
+ type: "step-selector"
1814
+ },
1815
+ enum: ["100ms", "250ms", "500ms", "1000ms", "1500ms", "2000ms"]
1816
+ }
1817
+ }
1818
+ },
1819
+ controls: {
1820
+ name: "controls",
1821
+ icon: "controls",
1822
+ tooltip: "Controls",
1823
+ type: "object",
1824
+ properties: {
1825
+ isActive: {
1826
+ type: "boolean",
1827
+ display: {
1828
+ type: "setting-toggle"
1829
+ }
1830
+ },
1831
+ arrowsImgUrl: {
1832
+ type: ["string", "null"],
1833
+ display: {
1834
+ type: "settings-image-input"
1835
+ }
1836
+ },
1837
+ offset: {
1838
+ type: "object",
1839
+ display: {
1840
+ type: "offset-controls"
1841
+ },
1842
+ properties: {
1843
+ x: {
1844
+ type: "number"
1845
+ },
1846
+ y: {
1847
+ type: "number"
1848
+ }
1849
+ }
1850
+ },
1851
+ scale: {
1852
+ type: "number",
1853
+ name: "scale",
1854
+ min: 50,
1855
+ max: 600,
1856
+ display: {
1857
+ type: "range-control"
1858
+ }
1859
+ },
1860
+ color: {
1861
+ name: "color",
1862
+ type: "string",
1863
+ display: {
1864
+ type: "settings-color-picker",
1865
+ format: "single"
1866
+ }
1867
+ },
1868
+ hover: {
1869
+ name: "hover",
1870
+ type: "string",
1871
+ display: {
1872
+ type: "settings-color-picker",
1873
+ format: "single"
1874
+ }
1875
+ }
1876
+ }
1877
+ },
1878
+ pagination: {
1879
+ name: "nav",
1880
+ icon: "pagination",
1881
+ tooltip: "Navigation",
1882
+ type: "object",
1883
+ properties: {
1884
+ isActive: {
1885
+ type: "boolean",
1886
+ display: {
1887
+ type: "setting-toggle"
1888
+ }
1889
+ },
1890
+ position: {
1891
+ name: "nav position",
1892
+ display: {
1893
+ type: "socket",
1894
+ direction: "horizontal"
1895
+ },
1896
+ type: "string",
1897
+ enum: ["outside-1", "outside-2", "inside-1", "inside-2"]
1898
+ },
1899
+ offset: {
1900
+ type: "object",
1901
+ display: {
1902
+ type: "offset-controls"
1903
+ },
1904
+ properties: {
1905
+ x: {
1906
+ type: "number"
1907
+ },
1908
+ y: {
1909
+ type: "number"
1910
+ }
1911
+ }
1912
+ },
1913
+ scale: {
1914
+ type: "number",
1915
+ name: "scale",
1916
+ min: 10,
1917
+ max: 400,
1918
+ display: {
1919
+ type: "range-control"
1920
+ }
1921
+ },
1922
+ colors: {
1923
+ display: {
1924
+ type: "settings-color-picker",
1925
+ format: "multiple"
1926
+ },
1927
+ name: "color",
1928
+ type: "array",
1929
+ items: {
1930
+ type: "string"
1931
+ }
1932
+ },
1933
+ hover: {
1934
+ name: "hover",
1935
+ type: "string",
1936
+ display: {
1937
+ type: "settings-color-picker",
1938
+ format: "single"
1939
+ }
1940
+ }
1941
+ }
1942
+ },
1943
+ caption: {
1944
+ name: "Caption",
1945
+ icon: "text-icon",
1946
+ tooltip: "Caption",
1947
+ type: "object",
1948
+ properties: {
1949
+ isActive: {
1950
+ type: "boolean",
1951
+ display: {
1952
+ type: "setting-toggle"
1953
+ }
1954
+ },
1955
+ alignment: {
1956
+ name: "Alignment",
1957
+ type: "string",
1958
+ display: {
1959
+ type: "align-grid"
1960
+ },
1961
+ enum: ["top-left", "top-center", "top-right", "middle-left", "middle-center", "middle-right", "bottom-left", "bottom-center", "bottom-right"]
1962
+ },
1963
+ offset: {
1964
+ type: "object",
1965
+ display: {
1966
+ type: "offset-controls"
1967
+ },
1968
+ properties: {
1969
+ x: {
1970
+ type: "number"
1971
+ },
1972
+ y: {
1973
+ type: "number"
1974
+ }
1975
+ }
1976
+ },
1977
+ hover: {
1978
+ name: "hover",
1979
+ type: "string",
1980
+ display: {
1981
+ type: "settings-color-picker",
1982
+ format: "single"
1983
+ }
1984
+ }
1985
+ }
1986
+ }
1987
+ },
1988
+ default: {
1989
+ triggers: {
1990
+ triggersList: {
1991
+ click: false,
1992
+ drag: true
1993
+ },
1994
+ autoPlay: null
1995
+ },
1996
+ controls: {
1997
+ isActive: true,
1998
+ arrowsImgUrl: null,
1999
+ offset: {
2000
+ x: 0,
2001
+ y: 0
2002
+ },
2003
+ scale: 100,
2004
+ color: "#000000",
2005
+ hover: "#cccccc"
2006
+ },
2007
+ transition: {
2008
+ type: "slide",
2009
+ duration: "500ms",
2010
+ backgroundColor: null
2011
+ },
2012
+ pagination: {
2013
+ isActive: true,
2014
+ scale: 50,
2015
+ position: "outside-1",
2016
+ offset: {
2017
+ x: 0,
2018
+ y: 0
2019
+ },
2020
+ colors: ["#cccccc", "#cccccc", "#000000"],
2021
+ hover: "#cccccc"
2022
+ },
2023
+ direction: "horiz",
2024
+ caption: {
2025
+ offset: {
2026
+ x: 0,
2027
+ y: 0
2028
+ },
2029
+ isActive: true,
2030
+ alignment: "middle-center",
2031
+ hover: "#cccccc"
2032
+ }
2033
+ },
2034
+ displayRules: [
2035
+ {
2036
+ if: {
2037
+ name: "direction",
2038
+ value: "vert"
2039
+ },
2040
+ then: {
2041
+ name: "properties.pagination.properties.position.display.direction",
2042
+ value: "vertical"
2043
+ }
2044
+ },
2045
+ {
2046
+ if: {
2047
+ name: "transition.type",
2048
+ value: "fade in"
2049
+ },
2050
+ then: {
2051
+ name: "properties.transition.properties.backgroundColor.display.visible",
2052
+ value: true
2053
+ }
2054
+ }
2055
+ ]
2056
+ },
2057
+ content: {
2058
+ layoutBased: false,
2059
+ type: "array",
2060
+ items: {
2061
+ type: "object",
2062
+ properties: {
2063
+ image: {
2064
+ type: "object",
2065
+ display: {
2066
+ type: "media-input"
2067
+ },
2068
+ properties: {
2069
+ url: {
2070
+ type: "string"
2071
+ },
2072
+ name: {
2073
+ type: "string"
2074
+ },
2075
+ objectFit: {
2076
+ type: "string",
2077
+ enum: ["cover", "contain"]
2078
+ }
2079
+ },
2080
+ required: ["url", "name"]
2081
+ },
2082
+ imageCaption: {
2083
+ display: {
2084
+ type: "rich-text",
2085
+ placeholder: "Add Caption..."
2086
+ }
2087
+ },
2088
+ link: {
2089
+ type: "object",
2090
+ display: {
2091
+ type: "text-input",
2092
+ placeholder: "Add Caption..."
2093
+ },
2094
+ properties: {
2095
+ text: {
2096
+ type: "string"
2097
+ }
2098
+ }
2099
+ }
2100
+ },
2101
+ required: ["image"]
2102
+ },
2103
+ default: [
2104
+ {
2105
+ image: {
2106
+ objectFit: "cover",
2107
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERMHNP08T27H1649S67NZV.png",
2108
+ name: "Slider-1.png"
2109
+ },
2110
+ imageCaption: [
2111
+ {
2112
+ type: "paragraph",
2113
+ children: [{ text: "" }]
2114
+ }
2115
+ ]
2116
+ },
2117
+ {
2118
+ image: {
2119
+ objectFit: "cover",
2120
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERMTZA3RYMXKF0M095D6JD.png",
2121
+ name: "Slider-2.png"
2122
+ },
2123
+ imageCaption: [
2124
+ {
2125
+ type: "paragraph",
2126
+ children: [{ text: "" }]
2127
+ }
2128
+ ]
2129
+ },
2130
+ {
2131
+ image: {
2132
+ objectFit: "cover",
2133
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERMVSCMPVJBG2WF5KJZYHZ.png",
2134
+ name: "Slider-3.png"
2135
+ },
2136
+ imageCaption: [
2137
+ {
2138
+ type: "paragraph",
2139
+ children: [{ text: "" }]
2140
+ }
2141
+ ]
2142
+ }
2143
+ ]
2144
+ },
2145
+ styles: {
2146
+ layoutBased: true,
2147
+ type: "object",
2148
+ properties: {
2149
+ caption: {
2150
+ dataName: "caption",
2151
+ type: "object",
2152
+ properties: {
2153
+ fontSettings: {
2154
+ type: "object",
2155
+ display: {
2156
+ type: "font-settings"
2157
+ },
2158
+ properties: {
2159
+ fontFamily: {
2160
+ type: "string"
2161
+ },
2162
+ fontWeight: {
2163
+ type: "number"
2164
+ },
2165
+ fontStyle: {
2166
+ type: "string"
2167
+ }
2168
+ }
2169
+ },
2170
+ widthSettings: {
2171
+ display: {
2172
+ type: "text-width-control"
2173
+ },
2174
+ type: "object",
2175
+ properties: {
2176
+ width: {
2177
+ type: "number"
2178
+ },
2179
+ sizing: {
2180
+ type: "string",
2181
+ enum: ["auto", "manual"]
2182
+ }
2183
+ }
2184
+ },
2185
+ fontSizeLineHeight: {
2186
+ type: "object",
2187
+ display: {
2188
+ type: "font-size-line-height"
2189
+ },
2190
+ properties: {
2191
+ fontSize: {
2192
+ type: "number"
2193
+ },
2194
+ lineHeight: {
2195
+ type: "number"
2196
+ }
2197
+ }
2198
+ },
2199
+ letterSpacing: {
2200
+ display: {
2201
+ type: "letter-spacing-input"
2202
+ },
2203
+ type: "number"
2204
+ },
2205
+ wordSpacing: {
2206
+ display: {
2207
+ type: "word-spacing-input"
2208
+ },
2209
+ type: "number"
2210
+ },
2211
+ textAlign: {
2212
+ display: {
2213
+ type: "text-align-control"
2214
+ },
2215
+ type: "string",
2216
+ enum: ["left", "center", "right", "justify"]
2217
+ },
2218
+ textAppearance: {
2219
+ display: {
2220
+ type: "text-appearance"
2221
+ },
2222
+ properties: {
2223
+ textTransform: {
2224
+ type: "string",
2225
+ enum: ["none", "uppercase", "lowercase", "capitalize"]
2226
+ },
2227
+ textDecoration: {
2228
+ type: "string",
2229
+ enum: ["none", "underline"]
2230
+ },
2231
+ fontVariant: {
2232
+ type: "string",
2233
+ enum: ["normal", "small-caps"]
2234
+ }
2235
+ }
2236
+ },
2237
+ color: {
2238
+ display: {
2239
+ type: "style-panel-color-picker"
2240
+ },
2241
+ type: "string"
2242
+ }
2243
+ }
2244
+ }
2245
+ },
2246
+ default: {
2247
+ caption: {
2248
+ widthSettings: {
2249
+ width: 0.13,
2250
+ sizing: "auto"
2251
+ },
2252
+ fontSettings: {
2253
+ fontFamily: "Arial",
2254
+ fontWeight: 400,
2255
+ fontStyle: "normal"
2256
+ },
2257
+ fontSizeLineHeight: {
2258
+ fontSize: 0.02,
2259
+ lineHeight: 0.02
2260
+ },
2261
+ letterSpacing: 0,
2262
+ wordSpacing: 0,
2263
+ textAlign: "left",
2264
+ textAppearance: {
2265
+ textTransform: "none",
2266
+ textDecoration: "none",
2267
+ fontVariant: "normal"
2268
+ },
2269
+ color: "#000000"
2270
+ }
2271
+ }
2272
+ }
2273
+ },
2274
+ required: ["settings", "content", "styles"]
2275
+ }
2276
+ };
2277
+ const imageRevealSlider = "ImageRevealSlider-module__imageRevealSlider___UE5Ob";
2278
+ const image = "ImageRevealSlider-module__image___Qjt-e";
2279
+ const link = "ImageRevealSlider-module__link___N-iLG";
2280
+ const styles = {
2281
+ imageRevealSlider,
2282
+ image,
2283
+ link
2284
+ };
2285
+ function isMouseOverImage(mouseX, mouseY, placedImages) {
2286
+ for (const img2 of placedImages) {
2287
+ const imgEl = new Image();
2288
+ imgEl.src = img2.url;
2289
+ const imgWidth = img2.width ? Number.parseFloat(img2.width) : imgEl.naturalWidth;
2290
+ const imgHeight = imgEl.naturalHeight / imgEl.naturalWidth * imgWidth;
2291
+ const halfW = imgWidth / 2;
2292
+ const halfH = imgHeight / 2;
2293
+ if (mouseX >= img2.x - halfW && mouseX <= img2.x + halfW && mouseY >= img2.y - halfH && mouseY <= img2.y + halfH) {
2294
+ return true;
2295
+ }
2296
+ }
2297
+ return false;
2298
+ }
2299
+ function getImageSize(url2) {
2300
+ return new Promise((resolve) => {
2301
+ const img2 = new Image();
2302
+ img2.src = url2;
2303
+ img2.onload = () => {
2304
+ resolve({ width: img2.naturalWidth, height: img2.naturalHeight });
2305
+ };
2306
+ });
2307
+ }
2308
+ async function calculateImageWidthHeight(imgUrl, sizeType, customWidth, randomRange) {
2309
+ let width;
2310
+ let height;
2311
+ if (sizeType === "custom") {
2312
+ width = customWidth;
2313
+ const size = await getImageSize(imgUrl);
2314
+ height = size.height / size.width * width;
2315
+ } else if (sizeType === "random") {
2316
+ width = Math.random() * (randomRange.max - randomRange.min) + randomRange.min;
2317
+ const size = await getImageSize(imgUrl);
2318
+ height = size.height / size.width * width;
2319
+ } else {
2320
+ const size = await getImageSize(imgUrl);
2321
+ width = size.width;
2322
+ height = size.height;
2323
+ }
2324
+ return { width, height, finalWidth: `${width}px` };
2325
+ }
2326
+ function ImageRevealSlider({ settings, content, isEditor }) {
2327
+ const divRef = react.useRef(null);
2328
+ const [placedImages, setPlacedImages] = react.useState([]);
2329
+ const [counter, setCounter] = react.useState(0);
2330
+ const imageIdCounter = react.useRef(0);
2331
+ const defaultImageCount = 1;
2332
+ const { sizeType, imageWidth: customWidth, randomRangeImageWidth: randomRange } = settings.imageSize;
2333
+ const { revealPosition, visible, target } = settings.position;
2334
+ const { cursorType, defaultCursor, hoverCursor } = settings.cursor;
2335
+ const createNewImage = async (imgData, containerWidth, containerHeight, position = {}) => {
2336
+ const { width, height, finalWidth } = await calculateImageWidthHeight(
2337
+ imgData.image.url,
2338
+ sizeType,
2339
+ customWidth,
2340
+ randomRange
2341
+ );
2342
+ let x = 0, y = 0;
2343
+ if (revealPosition === "same") {
2344
+ x = containerWidth / 2;
2345
+ y = containerHeight / 2;
2346
+ } else {
2347
+ x = position.x ?? Math.random() * containerWidth;
2348
+ y = position.y ?? Math.random() * containerHeight;
2349
+ }
2350
+ const adjustedX = Math.min(Math.max(x, width / 2), containerWidth - width / 2);
2351
+ const adjustedY = Math.min(Math.max(y, height / 2), containerHeight - height / 2);
2352
+ return {
2353
+ id: imageIdCounter.current++,
2354
+ url: imgData.image.url,
2355
+ link: imgData.link,
2356
+ name: imgData.image.name,
2357
+ x: adjustedX,
2358
+ y: adjustedY,
2359
+ width: finalWidth
2360
+ };
2361
+ };
2362
+ const defaultContentUrls = react.useMemo(() => {
2363
+ const defaultContentLength = Math.min(content.length, defaultImageCount);
2364
+ return content.filter((_, i) => i < defaultContentLength).map((c) => c.image.url).join("-");
2365
+ }, [content]);
2366
+ react.useEffect(() => {
2367
+ if (!divRef.current || content.length === 0) return;
2368
+ const rect = divRef.current.getBoundingClientRect();
2369
+ const containerWidth = rect.width;
2370
+ const containerHeight = rect.height;
2371
+ const defaultPlaced = [];
2372
+ const placeImages = async () => {
2373
+ for (let i = 0; i < defaultImageCount && i < content.length; i++) {
2374
+ const imgData = content[i];
2375
+ const newImg = await createNewImage(imgData, containerWidth, containerHeight);
2376
+ defaultPlaced.push(newImg);
2377
+ }
2378
+ setPlacedImages(defaultPlaced);
2379
+ setCounter(defaultImageCount % content.length);
2380
+ };
2381
+ placeImages();
2382
+ }, [defaultContentUrls, sizeType, customWidth, randomRange, revealPosition]);
2383
+ react.useEffect(() => {
2384
+ if (visible === "last One") {
2385
+ setPlacedImages((prev) => prev.length > 0 ? [prev[prev.length - 1]] : []);
2386
+ }
2387
+ }, [visible]);
2388
+ const handleClick = async (e) => {
2389
+ if (!divRef.current) return;
2390
+ const rect = divRef.current.getBoundingClientRect();
2391
+ const clickX = e.clientX - rect.left;
2392
+ const clickY = e.clientY - rect.top;
2393
+ if (target === "image" && !isMouseOverImage(clickX, clickY, placedImages)) return;
2394
+ let x = 0, y = 0;
2395
+ if (revealPosition === "on Click") {
2396
+ x = clickX;
2397
+ y = clickY;
2398
+ } else if (revealPosition === "same") {
2399
+ x = rect.width / 2;
2400
+ y = rect.height / 2;
2401
+ } else {
2402
+ x = Math.random() * rect.width;
2403
+ y = Math.random() * rect.height;
2404
+ }
2405
+ const imgData = content[counter];
2406
+ const newImage = await createNewImage(imgData, rect.width, rect.height, { x, y });
2407
+ setPlacedImages((prev) => visible === "all" ? [...prev, newImage] : [newImage]);
2408
+ setCounter((prev) => prev >= content.length - 1 ? 0 : prev + 1);
2409
+ };
2410
+ return /* @__PURE__ */ jsxRuntime.jsx(
2411
+ "div",
2412
+ {
2413
+ ref: divRef,
2414
+ onClick: handleClick,
2415
+ className: styles.imageRevealSlider,
2416
+ style: { cursor: cursorType !== "system" && defaultCursor ? `url(${target === "area" ? hoverCursor : defaultCursor}), auto` : "default" },
2417
+ children: placedImages.map((img2) => /* @__PURE__ */ jsxRuntime.jsx(
2418
+ "div",
2419
+ {
2420
+ className: styles.wrapper,
2421
+ style: {
2422
+ top: `${img2.y}px`,
2423
+ left: `${img2.x}px`,
2424
+ position: "absolute",
2425
+ transform: "translate(-50%, -50%)",
2426
+ width: img2.width ?? "auto",
2427
+ height: "auto",
2428
+ cursor: cursorType !== "system" && hoverCursor ? `url(${hoverCursor}), auto` : "default"
2429
+ },
2430
+ children: target === "area" && img2.link ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: img2.link, target: "_blank", className: styles.link, children: /* @__PURE__ */ jsxRuntime.jsx(
2431
+ "img",
2432
+ {
2433
+ src: img2.url,
2434
+ alt: img2.name,
2435
+ className: styles.image
2436
+ },
2437
+ img2.id
2438
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx(
2439
+ "img",
2440
+ {
2441
+ src: img2.url,
2442
+ alt: img2.name,
2443
+ className: styles.image
2444
+ },
2445
+ img2.id
2446
+ )
2447
+ },
2448
+ img2.id
2449
+ ))
2450
+ }
2451
+ );
2452
+ }
2453
+ const ControlImageRevealSliderComponent = {
2454
+ element: ImageRevealSlider,
2455
+ id: "control-image-reveal",
2456
+ name: "Click Gallery",
2457
+ preview: {
2458
+ type: "video",
2459
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7EQ3WSW43JG5YMC8B2HTPKT.mp4"
2460
+ },
2461
+ defaultSize: {
2462
+ width: 700,
2463
+ height: 400
2464
+ },
2465
+ schema: {
2466
+ type: "object",
2467
+ properties: {
2468
+ settings: {
2469
+ layoutBased: true,
2470
+ type: "object",
2471
+ properties: {
2472
+ imageSize: {
2473
+ name: "IMG SIZE",
2474
+ icon: "size",
2475
+ tooltip: "IMG SIZE",
2476
+ type: "object",
2477
+ properties: {
2478
+ sizeType: {
2479
+ name: "sizeType",
2480
+ type: "string",
2481
+ display: {
2482
+ type: "ratio-group"
2483
+ },
2484
+ enum: ["as Is", "custom", "random"]
2485
+ },
2486
+ imageWidth: {
2487
+ type: "number",
2488
+ label: "W",
2489
+ display: {
2490
+ type: "numeric-input",
2491
+ visible: false
2492
+ }
2493
+ },
2494
+ randomRangeImageWidth: {
2495
+ type: "object",
2496
+ display: {
2497
+ type: "random-range-controls",
2498
+ visible: false
2499
+ },
2500
+ properties: {
2501
+ min: {
2502
+ type: "number"
2503
+ },
2504
+ max: {
2505
+ type: "number"
2506
+ }
2507
+ }
2508
+ }
2509
+ }
2510
+ },
2511
+ cursor: {
2512
+ name: "cursor",
2513
+ icon: "cursor",
2514
+ tooltip: "cursor",
2515
+ type: "object",
2516
+ properties: {
2517
+ cursorType: {
2518
+ name: "cursorType",
2519
+ type: "string",
2520
+ display: {
2521
+ type: "ratio-group"
2522
+ },
2523
+ enum: ["system", "custom"]
2524
+ },
2525
+ defaultCursor: {
2526
+ type: ["string", "null"],
2527
+ display: {
2528
+ type: "settings-image-input",
2529
+ title: "Default",
2530
+ visible: false
2531
+ }
2532
+ },
2533
+ hoverCursor: {
2534
+ type: ["string", "null"],
2535
+ display: {
2536
+ type: "settings-image-input",
2537
+ title: "Hover",
2538
+ visible: false
2539
+ }
2540
+ }
2541
+ }
2542
+ },
2543
+ position: {
2544
+ name: "position",
2545
+ icon: "transition",
2546
+ tooltip: "Position",
2547
+ type: "object",
2548
+ properties: {
2549
+ revealPosition: {
2550
+ type: "string",
2551
+ display: {
2552
+ type: "ratio-group"
2553
+ },
2554
+ enum: ["random", "same", "on Click"]
2555
+ },
2556
+ visible: {
2557
+ type: "string",
2558
+ display: {
2559
+ type: "ratio-group"
2560
+ },
2561
+ enum: ["all", "last One"]
2562
+ },
2563
+ target: {
2564
+ type: "string",
2565
+ display: {
2566
+ type: "ratio-group"
2567
+ },
2568
+ enum: ["area", "image"]
2569
+ }
2570
+ }
2571
+ }
2572
+ },
2573
+ default: {
2574
+ imageSize: {
2575
+ sizeType: "custom",
2576
+ imageWidth: 500,
2577
+ randomRangeImageWidth: {
2578
+ min: 100,
2579
+ max: 1e3
2580
+ }
2581
+ },
2582
+ cursor: {
2583
+ cursorType: "system",
2584
+ defaultCursor: null,
2585
+ hoverCursor: null
2586
+ },
2587
+ position: {
2588
+ revealPosition: "random",
2589
+ visible: "all",
2590
+ target: "area"
2591
+ }
2592
+ },
2593
+ displayRules: [
2594
+ {
2595
+ if: {
2596
+ name: "imageSize.sizeType",
2597
+ value: "custom"
2598
+ },
2599
+ then: {
2600
+ name: "properties.imageSize.properties.imageWidth.display.visible",
2601
+ value: true
2602
+ }
2603
+ },
2604
+ {
2605
+ if: {
2606
+ name: "imageSize.sizeType",
2607
+ value: "random"
2608
+ },
2609
+ then: {
2610
+ name: "properties.imageSize.properties.randomRangeImageWidth.display.visible",
2611
+ value: true
2612
+ }
2613
+ },
2614
+ {
2615
+ if: [
2616
+ { name: "position.target", value: "image" },
2617
+ { name: "cursor.cursorType", value: "custom" }
2618
+ ],
2619
+ then: {
2620
+ name: "properties.cursor.properties.defaultCursor.display.visible",
2621
+ value: true
2622
+ }
2623
+ },
2624
+ {
2625
+ if: {
2626
+ name: "cursor.cursorType",
2627
+ value: "custom"
2628
+ },
2629
+ then: {
2630
+ name: "properties.cursor.properties.hoverCursor.display.visible",
2631
+ value: true
2632
+ }
2633
+ }
2634
+ ]
2635
+ },
2636
+ content: {
2637
+ layoutBased: false,
2638
+ type: "array",
2639
+ items: {
2640
+ type: "object",
2641
+ properties: {
2642
+ image: {
2643
+ type: "object",
2644
+ display: {
2645
+ type: "media-input",
2646
+ isObjectFitEditable: false
2647
+ },
2648
+ properties: {
2649
+ url: {
2650
+ type: "string"
2651
+ },
2652
+ name: {
2653
+ type: "string"
2654
+ },
2655
+ objectFit: {
2656
+ type: "string",
2657
+ enum: ["cover", "contain"]
2658
+ }
2659
+ },
2660
+ required: ["url", "name"]
2661
+ },
2662
+ link: {
2663
+ type: "string",
2664
+ display: {
2665
+ type: "text-input",
2666
+ placeholder: "Enter link..."
2667
+ }
2668
+ }
2669
+ },
2670
+ required: ["image"]
2671
+ },
2672
+ default: [
2673
+ {
2674
+ image: {
2675
+ objectFit: "cover",
2676
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERQK9211QXBE9W284ZNKB8.png",
2677
+ name: "Slider-1.png"
2678
+ },
2679
+ link: ""
2680
+ },
2681
+ {
2682
+ image: {
2683
+ objectFit: "cover",
2684
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERQMFT72JD18WKP0Q2DVAT.png",
2685
+ name: "Slider-2.png"
2686
+ },
2687
+ link: ""
2688
+ },
2689
+ {
2690
+ image: {
2691
+ objectFit: "cover",
2692
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERQNEVRXPSRX5K1YTMJQY9.png",
2693
+ name: "Slider-3.png"
2694
+ },
2695
+ link: ""
2696
+ },
2697
+ {
2698
+ image: {
2699
+ objectFit: "cover",
2700
+ url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERQP84JKRDT7WNWDQZR4Y9.png",
2701
+ name: "Slider-4.png"
2702
+ },
2703
+ link: ""
2704
+ }
2705
+ ]
2706
+ }
2707
+ }
2708
+ }
2709
+ };
2710
+ const components = [
2711
+ ControlSliderComponent,
2712
+ ControlImageRevealSliderComponent
2713
+ ];
2714
+ exports.AnchorSide = AnchorSide;
2715
+ exports.AreaAnchor = AreaAnchor;
2716
+ exports.ArticleItemType = ArticleItemType;
2717
+ exports.CntrlClient = Client;
2718
+ exports.DimensionMode = DimensionMode;
2719
+ exports.FontFaceGenerator = FontFaceGenerator;
2720
+ exports.KeyframeType = KeyframeType;
2721
+ exports.PositionType = PositionType;
2722
+ exports.ScrollPlaybackVideoManager = ScrollPlaybackVideoManager;
2723
+ exports.SectionHeightMode = SectionHeightMode;
2724
+ exports.TextAlign = TextAlign;
2725
+ exports.TextDecoration = TextDecoration;
2726
+ exports.TextTransform = TextTransform;
2727
+ exports.VerticalAlign = VerticalAlign;
2728
+ exports.components = components;
2729
+ exports.getLayoutMediaQuery = getLayoutMediaQuery;
2730
+ exports.getLayoutStyles = getLayoutStyles;