@anywayseo/tools 2.6.0 → 3.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 (41) hide show
  1. package/dist/components/author-card/index.d.ts +7 -0
  2. package/dist/components/{author → base/author}/index.d.ts +3 -3
  3. package/dist/components/base/index.d.ts +1 -1
  4. package/dist/components/index.cjs +4 -3
  5. package/dist/components/index.d.ts +3 -2
  6. package/dist/components/index.mjs +10 -9
  7. package/dist/components/not-found/index.d.ts +3 -0
  8. package/dist/components/seo/index.d.ts +7 -12
  9. package/dist/components/seo/types.d.ts +6 -0
  10. package/dist/components/seo/utils.d.ts +2 -0
  11. package/dist/components/{expert-tip → tip}/index.d.ts +4 -4
  12. package/dist/i18n/index.cjs +1 -1
  13. package/dist/i18n/index.mjs +1 -1
  14. package/dist/{index-BqUBNm7v.mjs → index-25M8hPOF.mjs} +1 -6
  15. package/dist/{index-BEqFPNAt.js → index-Biz1dDqA.js} +12 -12
  16. package/dist/index-BuvY6WUO.mjs +27 -0
  17. package/dist/{index-D2APUOog.js → index-Cte2-g6s.js} +1 -6
  18. package/dist/index-D32PZCoe.js +1039 -0
  19. package/dist/{index-F6_fGeRI.mjs → index-DoBCANwf.mjs} +12 -12
  20. package/dist/{index-m97PmVsd.js → index-Sod4uKHB.js} +16 -7
  21. package/dist/{index-Ct1pg92K.mjs → index-VQ0_fg4m.mjs} +116 -98
  22. package/dist/index.cjs +7 -7
  23. package/dist/index.mjs +12 -12
  24. package/dist/providers/index.cjs +1 -1
  25. package/dist/providers/index.mjs +1 -1
  26. package/dist/providers/site-provider/index.d.ts +1 -2
  27. package/dist/types/components/how-to/index.d.ts +2 -2
  28. package/dist/types/components/image/index.d.ts +4 -0
  29. package/dist/types/content/author/index.d.ts +5 -4
  30. package/dist/types/content/index.d.ts +1 -0
  31. package/dist/types/content/seo/index.d.ts +4 -0
  32. package/dist/types/site/index.d.ts +8 -14
  33. package/dist/utils/index.cjs +1 -2
  34. package/dist/utils/index.d.ts +0 -1
  35. package/dist/utils/index.mjs +1 -2
  36. package/package.json +1 -1
  37. package/dist/components/base/expert/index.d.ts +0 -8
  38. package/dist/index-C-e_0aJJ.mjs +0 -18
  39. package/dist/index-qgcoV14g.js +0 -1021
  40. package/dist/utils/url/index.d.ts +0 -1
  41. /package/dist/components/base/{expert → author}/bio/index.d.ts +0 -0
@@ -0,0 +1,1039 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const react$1 = require("@chakra-ui/react");
4
+ const reactI18next = require("react-i18next");
5
+ const index = require("./index-Cte2-g6s.js");
6
+ const i18n = require("./index-Biz1dDqA.js");
7
+ require("@ctrl/tinycolor");
8
+ const react = require("react");
9
+ const icons = require("@chakra-ui/icons");
10
+ const index$1 = require("./index-IpSV-c71.js");
11
+ const react$2 = require("@mdx-js/react");
12
+ const index$2 = require("./index-BhsXlbd8.js");
13
+ const i18n$1 = require("i18next");
14
+ const gatsby = require("gatsby");
15
+ const Markdown = require("react-markdown");
16
+ const ONE_LINE_HEIGHT = 24;
17
+ const Bio = ({ content, maxLines = 1 }) => {
18
+ const ref = react.useRef(null);
19
+ const [showToggle, setShowToggle] = react.useState(false);
20
+ const [isExpanded, setIsExpanded] = react.useState(false);
21
+ const { t } = reactI18next.useTranslation("author");
22
+ react.useLayoutEffect(() => {
23
+ if (ref.current) {
24
+ const { scrollWidth, clientWidth, scrollHeight, clientHeight } = ref.current;
25
+ const isClamped = scrollWidth > clientWidth || scrollHeight > clientHeight;
26
+ setShowToggle(isClamped);
27
+ }
28
+ return () => {
29
+ setShowToggle(false);
30
+ };
31
+ }, []);
32
+ function handleClick() {
33
+ setIsExpanded((prev) => !prev);
34
+ }
35
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Box, { children: [
36
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Collapse, { in: isExpanded, startingHeight: ONE_LINE_HEIGHT * maxLines, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { ref, fontSize: "md", noOfLines: isExpanded ? void 0 : maxLines, children: content }) }),
37
+ showToggle && /* @__PURE__ */ jsxRuntime.jsx(react$1.Button, { size: "sm", variant: "link", colorScheme: "blue", onClick: handleClick, children: isExpanded ? t("action.collapse") : t("action.expand") })
38
+ ] });
39
+ };
40
+ const Author = ({ author, variant }) => {
41
+ const { name, role, bio, avatar } = author;
42
+ const imageComponent = typeof avatar === "string" ? /* @__PURE__ */ jsxRuntime.jsx(react$1.Image, { src: avatar, alt: name, rounded: "full" }) : avatar;
43
+ if (variant === "short") {
44
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Flex, { as: "article", align: "center", gap: 4, children: [
45
+ !!imageComponent && /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { w: 12, h: 12, children: imageComponent }),
46
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.Box, { fontWeight: "semibold", children: [
47
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { children: name }),
48
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { color: "gray.500", children: role })
49
+ ] })
50
+ ] });
51
+ }
52
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
53
+ !!imageComponent && /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { grow: 1, maxW: { base: 48, sm: 32 }, children: imageComponent }),
54
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { w: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.Stack, { children: [
55
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.Text, { fontSize: "lg", fontWeight: 600, children: [
56
+ name,
57
+ ", ",
58
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { as: "span", color: "gray.500", children: role })
59
+ ] }),
60
+ /* @__PURE__ */ jsxRuntime.jsx(Bio, { content: bio })
61
+ ] }) })
62
+ ] });
63
+ };
64
+ const Center = ({ children, ...boxProps }) => {
65
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Center, { ...boxProps, children });
66
+ };
67
+ const defaultColumns = { base: 1, sm: 2, md: 3, lg: 4, xl: 5 };
68
+ const Grid = ({ items, columns = defaultColumns, gap, render, getKey, ...boxProps }) => {
69
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.SimpleGrid, { as: "ul", columns, spacing: gap, p: 0, m: 0, listStyleType: "none", ...boxProps, children: items.map((item, index2) => /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { as: "li", children: render(item) }, getKey ? getKey(item) : index2)) });
70
+ };
71
+ const LinkButton = ({ label, url, width = "auto", ...boxProps }) => {
72
+ return /* @__PURE__ */ jsxRuntime.jsx(
73
+ react$1.Button,
74
+ {
75
+ as: react$1.Link,
76
+ href: url,
77
+ w: width,
78
+ bg: "brand.600",
79
+ textTransform: "uppercase",
80
+ _hover: { textDecoration: "none", bg: "brand.300" },
81
+ _active: { transform: "scale(0.95)" },
82
+ ...boxProps,
83
+ children: label
84
+ }
85
+ );
86
+ };
87
+ const ColorMap = {
88
+ light: "gray.200",
89
+ dark: "gray.700"
90
+ };
91
+ const PulseButton = ({ label, colorScheme = "light", to, onClick }) => {
92
+ return /* @__PURE__ */ jsxRuntime.jsx(
93
+ react$1.Button,
94
+ {
95
+ size: { base: "sm", md: "lg" },
96
+ color: ColorMap[colorScheme],
97
+ bgColor: "brand.500",
98
+ animation: `${index.Animation.pulse} 2s infinite linear`,
99
+ _hover: { bgColor: "brand.200", color: "gray.700" },
100
+ ...to ? { as: react$1.Link, href: to } : { onClick },
101
+ children: label
102
+ }
103
+ );
104
+ };
105
+ const AuthorCard = ({ author, ...boxProps }) => {
106
+ const { t } = reactI18next.useTranslation("author");
107
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Card, { as: "article", variant: "filled", ...boxProps, children: [
108
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.CardHeader, { pb: 0, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Heading, { size: "md", children: t("title") }) }),
109
+ /* @__PURE__ */ jsxRuntime.jsx(
110
+ react$1.CardBody,
111
+ {
112
+ display: "flex",
113
+ flexDirection: { base: "column", sm: "row" },
114
+ alignItems: { base: "center", sm: "flex-start" },
115
+ gap: 4,
116
+ children: /* @__PURE__ */ jsxRuntime.jsx(Author, { author, variant: "full" })
117
+ }
118
+ )
119
+ ] });
120
+ };
121
+ const BonusCardContent = ({ content }) => {
122
+ const { t } = reactI18next.useTranslation("author");
123
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Popover, { autoFocus: false, isLazy: true, lazyBehavior: "keepMounted", children: ({ isOpen }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
124
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.PopoverTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Button, { size: "sm", variant: "link", color: "white", children: isOpen ? t("action.collapse") : t("action.expand") }) }),
125
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(react$1.PopoverContent, { children: /* @__PURE__ */ jsxRuntime.jsx(react$1.PopoverBody, { children: Array.isArray(content) ? /* @__PURE__ */ jsxRuntime.jsx(react$1.Stack, { children: content.map((paragraph, index2) => /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { as: "span", children: paragraph }, index2)) }) : /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { children: content }) }) }) })
126
+ ] }) });
127
+ };
128
+ const BonusCardTitle = ({ content }) => {
129
+ return /* @__PURE__ */ jsxRuntime.jsx(
130
+ react$1.Text,
131
+ {
132
+ as: "h3",
133
+ display: "inline-block",
134
+ py: 1,
135
+ px: 2,
136
+ borderRadius: "md",
137
+ bg: "yellow",
138
+ color: "black",
139
+ fontWeight: "bold",
140
+ fontSize: "lg",
141
+ children: content
142
+ }
143
+ );
144
+ };
145
+ const BonusCard = ({ title, subtitle, content, link, image, className }) => {
146
+ return /* @__PURE__ */ jsxRuntime.jsxs(
147
+ react$1.Card,
148
+ {
149
+ as: "article",
150
+ h: "full",
151
+ color: "whiteAlpha.900",
152
+ bg: "linear-gradient(90deg, #3b1f47, #731d58)",
153
+ _before: image ? {
154
+ content: '""',
155
+ position: "absolute",
156
+ top: 0,
157
+ left: 0,
158
+ w: "100%",
159
+ h: "100%",
160
+ bgImage: `url(${image})`,
161
+ bgSize: "cover",
162
+ bgPosition: "center",
163
+ filter: "blur(0.05em) opacity(50%)",
164
+ zIndex: 0
165
+ } : void 0,
166
+ className,
167
+ children: [
168
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.CardBody, { as: "section", pb: 0, flex: 1, children: [
169
+ /* @__PURE__ */ jsxRuntime.jsx(BonusCardTitle, { content: title }),
170
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { fontSize: "2xl", fontWeight: "bold", my: 2, children: subtitle }),
171
+ /* @__PURE__ */ jsxRuntime.jsx(BonusCardContent, { content })
172
+ ] }),
173
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.CardFooter, { as: "footer", p: 4, children: /* @__PURE__ */ jsxRuntime.jsx(LinkButton, { ...link, width: "full" }) })
174
+ ]
175
+ }
176
+ );
177
+ };
178
+ const ContactForm = ({ ...boxProps }) => {
179
+ const toast = react$1.useToast();
180
+ const { t } = reactI18next.useTranslation("contactForm");
181
+ function handleSubmit(event) {
182
+ event.preventDefault();
183
+ const form = event.currentTarget;
184
+ const formData = new FormData(form);
185
+ const name = formData.get("name");
186
+ const email = formData.get("email");
187
+ const message = formData.get("message");
188
+ if (name && email && message) {
189
+ form.reset();
190
+ toast({
191
+ title: t("notification.title", { name }),
192
+ description: t("notification.description", { email }),
193
+ colorScheme: "brand",
194
+ status: "success",
195
+ duration: 5e3,
196
+ isClosable: true
197
+ });
198
+ } else {
199
+ console.error("Please fill out both fields");
200
+ }
201
+ }
202
+ return /* @__PURE__ */ jsxRuntime.jsx(
203
+ react$1.Box,
204
+ {
205
+ as: "form",
206
+ borderRadius: "lg",
207
+ p: 8,
208
+ color: react$1.useColorModeValue("gray.700", "whiteAlpha.900"),
209
+ bg: react$1.useColorModeValue("white", "gray.700"),
210
+ shadow: "base",
211
+ onSubmit: handleSubmit,
212
+ ...boxProps,
213
+ children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.VStack, { spacing: 4, children: [
214
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.FormControl, { isRequired: true, children: [
215
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.FormLabel, { children: t("field.name.label") }),
216
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.InputGroup, { children: [
217
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.InputLeftElement, { children: /* @__PURE__ */ jsxRuntime.jsx(
218
+ "svg",
219
+ {
220
+ xmlns: "http://www.w3.org/2000/svg",
221
+ width: "16",
222
+ height: "16",
223
+ fill: "currentColor",
224
+ className: "bi bi-person-fill",
225
+ viewBox: "0 0 16 16",
226
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6" })
227
+ }
228
+ ) }),
229
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Input, { type: "text", name: "name", placeholder: t("field.name.placeholder") })
230
+ ] })
231
+ ] }),
232
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.FormControl, { isRequired: true, children: [
233
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.FormLabel, { children: t("field.email.label") }),
234
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.InputGroup, { children: [
235
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.InputLeftElement, { children: /* @__PURE__ */ jsxRuntime.jsx(icons.EmailIcon, {}) }),
236
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Input, { type: "email", name: "email", placeholder: t("field.email.placeholder") })
237
+ ] })
238
+ ] }),
239
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.FormControl, { isRequired: true, children: [
240
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.FormLabel, { children: t("field.message.label") }),
241
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Textarea, { name: "message", placeholder: t("field.message.placeholder"), rows: 6, resize: "none" })
242
+ ] }),
243
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Button, { type: "submit", colorScheme: "brand", width: "full", children: t("action.send") })
244
+ ] })
245
+ }
246
+ );
247
+ };
248
+ const Faq = ({ items, ...boxProps }) => {
249
+ const { bgColor, color } = index$1.usePrimaryColors();
250
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Accordion, { allowToggle: true, ...boxProps, children: items.map(({ question, answer }) => {
251
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.AccordionItem, { border: 0, children: [
252
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { as: "h3", children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.AccordionButton, { _hover: { color, bgColor }, children: [
253
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { as: "span", flex: "1", textAlign: "left", fontWeight: "bold", children: question }),
254
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AccordionIcon, {})
255
+ ] }) }),
256
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AccordionPanel, { children: answer })
257
+ ] }, question);
258
+ }) });
259
+ };
260
+ const FeatureCard = ({ title, description }) => {
261
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Card, { as: "article", variant: "outline", textAlign: "center", h: "100%", children: [
262
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.CardHeader, { as: "header", display: "flex", alignItems: "center", justifyContent: "center", gap: 2, pb: 2, children: [
263
+ /* @__PURE__ */ jsxRuntime.jsx(icons.StarIcon, { w: 8, h: 8, color: "yellow.400" }),
264
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { fontWeight: 600, children: title }),
265
+ /* @__PURE__ */ jsxRuntime.jsx(icons.StarIcon, { w: 8, h: 8, color: "yellow.400" })
266
+ ] }),
267
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.CardBody, { as: "section", pt: 0, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { color: "gray.200", children: description }) })
268
+ ] });
269
+ };
270
+ const Features = ({ features, ...boxProps }) => {
271
+ return /* @__PURE__ */ jsxRuntime.jsx(
272
+ Grid,
273
+ {
274
+ items: features,
275
+ columns: { base: 1, md: 2, lg: 3 },
276
+ gap: 10,
277
+ getKey: ({ title }) => title,
278
+ render: (item) => /* @__PURE__ */ jsxRuntime.jsx(FeatureCard, { ...item }),
279
+ ...boxProps
280
+ }
281
+ );
282
+ };
283
+ const GameCard = ({ name, description, image, link, height = "auto" }) => {
284
+ return /* @__PURE__ */ jsxRuntime.jsxs(
285
+ react$1.LinkBox,
286
+ {
287
+ as: "article",
288
+ rounded: "md",
289
+ borderWidth: 1,
290
+ transition: "transform 0.2s ease",
291
+ cursor: link ? "pointer" : "default",
292
+ overflow: "hidden",
293
+ bg: "blackAlpha.200",
294
+ height,
295
+ _hover: { transform: "scale(1.1)" },
296
+ children: [
297
+ typeof image === "string" ? /* @__PURE__ */ jsxRuntime.jsx(react$1.Image, { src: image, alt: name, w: "100%", aspectRatio: "16/9", objectFit: "cover", objectPosition: "center" }) : !!image && /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { w: "100%", aspectRatio: "16/9", children: image }),
298
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.Box, { as: "section", rounded: "md", p: 4, children: [
299
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { as: "span", children: link ? /* @__PURE__ */ jsxRuntime.jsx(react$1.LinkOverlay, { href: link, children: name }) : name }),
300
+ !!description && /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { fontSize: "sm", color: "gray.600", children: description })
301
+ ] })
302
+ ]
303
+ }
304
+ );
305
+ };
306
+ const GameDemoContent = ({ src, isFullscreen, isLoaded, onLoad, onToggleFullscreen }) => {
307
+ const { t } = reactI18next.useTranslation("gameDemo");
308
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
309
+ /* @__PURE__ */ jsxRuntime.jsx(
310
+ react$1.Box,
311
+ {
312
+ as: "iframe",
313
+ src,
314
+ sandbox: "allow-scripts allow-same-origin",
315
+ loading: "lazy",
316
+ w: "100%",
317
+ h: "100%",
318
+ allowFullScreen: true,
319
+ onLoad,
320
+ children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: t("warning") })
321
+ }
322
+ ),
323
+ /* @__PURE__ */ jsxRuntime.jsx(
324
+ react$1.IconButton,
325
+ {
326
+ icon: isFullscreen ? /* @__PURE__ */ jsxRuntime.jsx(icons.CloseIcon, { w: 3, h: 3 }) : /* @__PURE__ */ jsxRuntime.jsx(icons.ExternalLinkIcon, { w: 4, h: 4 }),
327
+ size: "sm",
328
+ variant: "outline",
329
+ title: t(isFullscreen ? "action.deactivateFullscreen" : "action.activateFullscreen"),
330
+ "aria-label": "Fullscreen mode Toggle",
331
+ isRound: true,
332
+ disabled: !isLoaded,
333
+ position: "absolute",
334
+ top: 2,
335
+ left: 2,
336
+ border: "none",
337
+ color: "white",
338
+ _hover: { bgColor: "whiteAlpha.400" },
339
+ onClick: onToggleFullscreen
340
+ }
341
+ ),
342
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AbsoluteCenter, { children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Spinner, { size: "xl", thickness: "0.6rem", display: isLoaded ? "none" : "block", color: "brand.100" }) })
343
+ ] });
344
+ };
345
+ const GameDemoPreview = ({ image, alt, imageFit = "contain", onPlay }) => {
346
+ const { t } = reactI18next.useTranslation("gameDemo");
347
+ const imageComponent = typeof image === "string" ? /* @__PURE__ */ jsxRuntime.jsx(react$1.Image, { src: image, alt, objectFit: imageFit }) : image;
348
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
349
+ imageComponent,
350
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AbsoluteCenter, { children: /* @__PURE__ */ jsxRuntime.jsx(PulseButton, { label: t("action.playForFree"), onClick: onPlay }) })
351
+ ] });
352
+ };
353
+ const GameDemo = ({ name, src, previewImage, previewImageFit, ...boxProps }) => {
354
+ const [isRunning, setIsRunning] = react.useState(false);
355
+ const [isLoaded, setIsLoaded] = react.useState(false);
356
+ const { isOpen: isFullscreen, onToggle } = react$1.useDisclosure({ defaultIsOpen: false });
357
+ function handlePlay() {
358
+ setIsRunning(true);
359
+ }
360
+ function onLoad() {
361
+ setIsLoaded(true);
362
+ }
363
+ function handleToggleFullscreen() {
364
+ document.body.style.overflowY = isFullscreen ? "auto" : "hidden";
365
+ onToggle();
366
+ }
367
+ return /* @__PURE__ */ jsxRuntime.jsx(
368
+ react$1.Box,
369
+ {
370
+ as: "article",
371
+ display: "grid",
372
+ w: "100%",
373
+ aspectRatio: "16/9 auto",
374
+ ...isFullscreen ? { zIndex: 100, inset: 0, position: "fixed", h: "100dvh" } : { position: "relative" },
375
+ ...boxProps,
376
+ children: isRunning ? /* @__PURE__ */ jsxRuntime.jsx(
377
+ GameDemoContent,
378
+ {
379
+ src,
380
+ isFullscreen,
381
+ isLoaded,
382
+ onLoad,
383
+ onToggleFullscreen: handleToggleFullscreen
384
+ }
385
+ ) : /* @__PURE__ */ jsxRuntime.jsx(GameDemoPreview, { image: previewImage, alt: name, imageFit: previewImageFit, onPlay: handlePlay })
386
+ }
387
+ );
388
+ };
389
+ const GameInfoItem = ({ title, value }) => {
390
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Flex, { gap: 2, children: [
391
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.Text, { w: "50%", color: "gray.500", textTransform: "capitalize", children: [
392
+ title,
393
+ ":"
394
+ ] }),
395
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { w: "50%", textTransform: "capitalize", children: value })
396
+ ] });
397
+ };
398
+ const VISIBLE_LANGUAGE_NUMBER = 5;
399
+ function stringifyHasFeature(value) {
400
+ return i18n$1.t(`gameInfo:value.boolean.${value}`);
401
+ }
402
+ function stringifyVolatility(value) {
403
+ return i18n$1.t(`gameInfo:value.volatility.${value}`);
404
+ }
405
+ function stringifyArray(array) {
406
+ return array.join(", ");
407
+ }
408
+ function stringifyLanguageArray(languages) {
409
+ return languages.length > VISIBLE_LANGUAGE_NUMBER ? `${stringifyArray(languages.slice(0, VISIBLE_LANGUAGE_NUMBER))}, +${languages.length - VISIBLE_LANGUAGE_NUMBER}` : stringifyArray(languages);
410
+ }
411
+ function getGameInfoItemValue(key, value, currency) {
412
+ let formattedValue = "";
413
+ if (typeof value !== "string") {
414
+ if (key === i18n.GameCharacteristic.Rtp) {
415
+ formattedValue = index.formatNumber(value, { percent: "real", precision: 3 });
416
+ }
417
+ if (key === i18n.GameCharacteristic.MinBet || key === i18n.GameCharacteristic.MaxBet || key === i18n.GameCharacteristic.MaxWin) {
418
+ if (Array.isArray(currency)) {
419
+ const [primary, ...secondaries] = currency || ["USD"];
420
+ const primaryValue = index.formatNumber(value, { currency: primary });
421
+ formattedValue = secondaries.length ? `${primaryValue} (${secondaries.map((currency2) => index.getCurrencySymbol(currency2)).join(", ")})` : primaryValue;
422
+ } else {
423
+ formattedValue = index.formatNumber(value, { currency });
424
+ }
425
+ }
426
+ if (key === i18n.GameCharacteristic.Compatibility || key === i18n.GameCharacteristic.BonusFeatures) {
427
+ formattedValue = stringifyArray(value);
428
+ }
429
+ if (key === i18n.GameCharacteristic.Languages) {
430
+ formattedValue = stringifyLanguageArray(value);
431
+ }
432
+ if (typeof value === "boolean") {
433
+ formattedValue = stringifyHasFeature(value);
434
+ }
435
+ }
436
+ if (key === i18n.GameCharacteristic.ReleaseDate) {
437
+ formattedValue = index.formatDate({ value, options: { year: "numeric", month: "long" } });
438
+ }
439
+ if (key === i18n.GameCharacteristic.Volatility) {
440
+ formattedValue = stringifyVolatility(value);
441
+ }
442
+ if (!formattedValue) {
443
+ formattedValue = value.toLocaleString();
444
+ }
445
+ return formattedValue;
446
+ }
447
+ const GameInfo = ({ info }) => {
448
+ const { metadata } = index$2.useSiteContext();
449
+ const { currency } = metadata;
450
+ const { t } = reactI18next.useTranslation("gameInfo");
451
+ return /* @__PURE__ */ jsxRuntime.jsx(
452
+ react$1.Box,
453
+ {
454
+ as: "aside",
455
+ float: { base: "none", lg: "right" },
456
+ w: { base: "100%", lg: "xs" },
457
+ ml: { base: 0, lg: 4 },
458
+ mb: { base: 0, lg: 4 },
459
+ children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.Card, { as: "article", variant: "outline", h: "100%", p: 2, children: [
460
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.CardHeader, { as: "header", p: 0, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Heading, { as: "h2", fontSize: "xl", children: t("title") }) }),
461
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.CardBody, { as: "section", p: 0, children: Object.entries(info).map(([group, items]) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
462
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Divider, { my: 2 }),
463
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { fontWeight: "semibold", mb: 2, children: t(`group.${group}`) }),
464
+ Object.entries(items).map(([itemKey, itemValue]) => {
465
+ if (!itemValue) {
466
+ return null;
467
+ }
468
+ const feature = itemKey;
469
+ const value = getGameInfoItemValue(feature, itemValue, currency);
470
+ return /* @__PURE__ */ jsxRuntime.jsx(GameInfoItem, { title: t(`feature.${feature}`), value }, itemKey);
471
+ })
472
+ ] }, group)) })
473
+ ] })
474
+ }
475
+ );
476
+ };
477
+ const HowTo = ({ steps, ...boxProps }) => {
478
+ const { color, bgColor } = index$1.usePrimaryColors();
479
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.SimpleGrid, { as: "ol", columns: { base: 1, md: 2, lg: 3 }, gap: 4, p: 0, ...boxProps, children: steps.map(({ title, description, thumbnail }, index2) => /* @__PURE__ */ jsxRuntime.jsxs(react$1.Flex, { as: "li", alignItems: "flex-start", gap: 4, children: [
480
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Circle, { size: 12, bgColor, color, fontSize: "lg", fontWeight: "bold", children: String(index2 + 1) }),
481
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.Stack, { flex: 1, children: [
482
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { fontSize: "lg", fontWeight: "bold", children: title }),
483
+ typeof thumbnail === "string" ? /* @__PURE__ */ jsxRuntime.jsx(react$1.Image, { src: thumbnail, alt: title, aspectRatio: "16/9", objectFit: "cover" }) : thumbnail,
484
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { children: description })
485
+ ] })
486
+ ] }, index2)) });
487
+ };
488
+ const Container = ({ children }) => {
489
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Container, { maxW: "container.xl", children });
490
+ };
491
+ const Content = ({ children }) => {
492
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { as: "section", py: 4, children: /* @__PURE__ */ jsxRuntime.jsx(Container, { children }) });
493
+ };
494
+ const Logo = () => {
495
+ const { metadata } = index$2.useSiteContext();
496
+ const { logo } = metadata;
497
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { display: "flex", h: { base: 10, md: 14 }, overflow: "hidden", children: typeof logo === "string" ? /* @__PURE__ */ jsxRuntime.jsx(react$1.Image, { src: logo, alt: "Logo", objectFit: "contain" }) : logo });
498
+ };
499
+ const Brand$1 = ({ brand }) => {
500
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Box, { position: "relative", my: 2, py: 8, children: [
501
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Divider, {}),
502
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AbsoluteCenter, { display: "flex", bgColor: react$1.useColorModeValue("gray.50", "gray.900"), children: /* @__PURE__ */ jsxRuntime.jsx(gatsby.Link, { to: "/", children: brand }) })
503
+ ] });
504
+ };
505
+ const Copyright = () => {
506
+ const { metadata } = index$2.useSiteContext();
507
+ const { name: siteName } = metadata;
508
+ const { t } = reactI18next.useTranslation("footer");
509
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { as: "small", colorScheme: "gray", display: "flex", align: "center", justifyContent: "center", children: t("copyright", { year: index.getCurrentYear(), siteName }) });
510
+ };
511
+ const Disclaimer = () => {
512
+ const { metadata } = index$2.useSiteContext();
513
+ const { name: siteName } = metadata;
514
+ const { t } = reactI18next.useTranslation("footer");
515
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Text, { as: "small", colorScheme: "gray", fontSize: "sm", children: [
516
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { as: "span", fontWeight: "bold", color: "red.600", children: t("disclaimer.title") }),
517
+ t("disclaimer.description", { siteName })
518
+ ] });
519
+ };
520
+ const Extra = ({ children }) => {
521
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { as: "section", my: 2, children });
522
+ };
523
+ const Navigation$1 = ({ menu }) => {
524
+ return /* @__PURE__ */ jsxRuntime.jsx(
525
+ react$1.SimpleGrid,
526
+ {
527
+ as: "ul",
528
+ columns: { base: 1, sm: 2, md: 4 },
529
+ mt: 4,
530
+ mb: 6,
531
+ p: 0,
532
+ spacing: 4,
533
+ justifyItems: { base: "flex-start", md: "center" },
534
+ justifyContent: "space-between",
535
+ children: menu.map(({ path, label }, index2) => /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { as: "li", children: /* @__PURE__ */ jsxRuntime.jsx(
536
+ react$1.Text,
537
+ {
538
+ as: gatsby.Link,
539
+ to: path,
540
+ fontSize: "md",
541
+ fontWeight: "semibold",
542
+ colorScheme: "gray",
543
+ _hover: { textDecoration: "none", color: "brand.400" },
544
+ children: label
545
+ },
546
+ path
547
+ ) }, index2))
548
+ }
549
+ );
550
+ };
551
+ const Footer = () => {
552
+ var _a, _b, _c;
553
+ const { configs } = index$2.useSiteContext();
554
+ const navigation = ((_a = configs == null ? void 0 : configs.footer) == null ? void 0 : _a.navigation) ?? [];
555
+ const extra = (_b = configs == null ? void 0 : configs.footer) == null ? void 0 : _b.extra;
556
+ const showDisclaimer = ((_c = configs == null ? void 0 : configs.footer) == null ? void 0 : _c.showDisclaimer) ?? true;
557
+ const hasNavigation = !!navigation.length;
558
+ const hasExtra = !!extra;
559
+ return /* @__PURE__ */ jsxRuntime.jsx(
560
+ react$1.Box,
561
+ {
562
+ as: "footer",
563
+ bg: react$1.useColorModeValue("gray.50", "gray.900"),
564
+ color: react$1.useColorModeValue("gray.700", "gray.200"),
565
+ py: 4,
566
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Container, { children: [
567
+ hasNavigation && /* @__PURE__ */ jsxRuntime.jsx(Navigation$1, { menu: navigation }),
568
+ hasExtra && /* @__PURE__ */ jsxRuntime.jsx(Extra, { children: extra }),
569
+ showDisclaimer && /* @__PURE__ */ jsxRuntime.jsx(Disclaimer, {}),
570
+ /* @__PURE__ */ jsxRuntime.jsx(Brand$1, { brand: /* @__PURE__ */ jsxRuntime.jsx(Logo, {}) }),
571
+ /* @__PURE__ */ jsxRuntime.jsx(Copyright, {})
572
+ ] })
573
+ }
574
+ );
575
+ };
576
+ const Brand = ({ brand }) => {
577
+ return /* @__PURE__ */ jsxRuntime.jsx(gatsby.Link, { to: "/", children: brand });
578
+ };
579
+ const NavLink = react.forwardRef(({ path, label }, ref) => {
580
+ return /* @__PURE__ */ jsxRuntime.jsx(
581
+ react$1.Text,
582
+ {
583
+ ref,
584
+ as: gatsby.Link,
585
+ to: path,
586
+ p: 2,
587
+ fontWeight: "semibold",
588
+ _hover: { textDecoration: "none", color: "brand.400" },
589
+ children: label
590
+ }
591
+ );
592
+ });
593
+ NavLink.displayName = "NavLink";
594
+ const NavList$1 = ({ path, label, children }) => {
595
+ const background = react$1.useColorModeValue("white", "gray.800");
596
+ const backgroundHover = react$1.useColorModeValue("brand.50", "gray.900");
597
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Popover, { trigger: "hover", placement: "bottom-start", children: [
598
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.PopoverTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(
599
+ react$1.Text,
600
+ {
601
+ p: 2,
602
+ fontWeight: "semibold",
603
+ cursor: "pointer",
604
+ tabIndex: 0,
605
+ _hover: { textDecoration: "none", color: "brand.400" },
606
+ children: label
607
+ }
608
+ ) }),
609
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.PopoverContent, { p: 2, border: 0, minW: "sm", rounded: "xl", boxShadow: "xl", bg: background, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.List, { spacing: 2, p: 0, children: children == null ? void 0 : children.map((child, index2) => /* @__PURE__ */ jsxRuntime.jsx(react$1.ListItem, { rounded: "md", _hover: { bg: backgroundHover }, children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.Flex, { as: gatsby.Link, to: `${path}${child.path}`, p: 2, role: "group", children: [
610
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { fontWeight: 500, transition: "all .3s ease", _groupHover: { color: "brand.400" }, children: child.label }),
611
+ /* @__PURE__ */ jsxRuntime.jsx(
612
+ react$1.Flex,
613
+ {
614
+ flex: 1,
615
+ justify: "flex-end",
616
+ align: "center",
617
+ opacity: 0,
618
+ transition: "all .3s ease",
619
+ transform: "translateX(-10px)",
620
+ _groupHover: { opacity: 1, transform: "translateX(0)" },
621
+ children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Icon, { as: icons.ChevronRightIcon, color: "brand.400", w: 5, h: 5 })
622
+ }
623
+ )
624
+ ] }) }, index2)) }) })
625
+ ] });
626
+ };
627
+ const DesktopNavigation = ({ menu }) => {
628
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { as: "ul", role: "list", gap: 2, p: 0, display: { base: "none", md: "flex" }, children: menu.map((item, index2) => {
629
+ var _a;
630
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { as: "li", role: "listitem", children: ((_a = item.children) == null ? void 0 : _a.length) ? /* @__PURE__ */ jsxRuntime.jsx(NavList$1, { ...item }) : /* @__PURE__ */ jsxRuntime.jsx(NavLink, { ...item }) }, index2);
631
+ }) });
632
+ };
633
+ const CHEVRON_DOWN_ICON_SIZE = "1.5rem";
634
+ const NavList = ({ path, label, children, isExpanded, onExpand }) => {
635
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Stack, { flex: 1, children: [
636
+ /* @__PURE__ */ jsxRuntime.jsxs(
637
+ react$1.Flex,
638
+ {
639
+ as: "button",
640
+ p: 2,
641
+ pr: "3px",
642
+ align: "center",
643
+ justifyContent: "space-between",
644
+ _hover: { textDecoration: "none", color: "brand.400" },
645
+ onClick: onExpand,
646
+ children: [
647
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { isTruncated: true, fontWeight: 600, children: label }),
648
+ /* @__PURE__ */ jsxRuntime.jsx(
649
+ icons.ChevronDownIcon,
650
+ {
651
+ w: CHEVRON_DOWN_ICON_SIZE,
652
+ h: CHEVRON_DOWN_ICON_SIZE,
653
+ transform: isExpanded ? "rotate(180deg)" : "",
654
+ transition: "all .25s ease-in-out"
655
+ }
656
+ )
657
+ ]
658
+ }
659
+ ),
660
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Collapse, { in: isExpanded, transition: { enter: { ease: "easeIn" }, exit: { duration: 0.2 } }, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.List, { ml: 2, pl: 0, borderLeft: 1, borderStyle: "solid", borderColor: react$1.useColorModeValue("gray.200", "gray.700"), children: children == null ? void 0 : children.map((child, index2) => /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { as: "li", role: "listitem", children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { as: gatsby.Link, to: `${path}${child.path}`, p: 2, fontSize: "sm", children: child.label }) }, index2)) }) })
661
+ ] });
662
+ };
663
+ const CLOSE_ICON_SIZE = "0.75rem";
664
+ const HAMBURGER_ICON_SIZE = "1rem";
665
+ const MobileNavigation = ({ menu }) => {
666
+ const [expanded, setExpanded] = react.useState(null);
667
+ const { isOpen, onToggle } = react$1.useDisclosure();
668
+ const background = react$1.useColorModeValue("gray.50", "gray.900");
669
+ function handleExpand(index2) {
670
+ return () => {
671
+ setExpanded((prev) => prev === index2 ? null : index2);
672
+ };
673
+ }
674
+ function handleClick() {
675
+ setExpanded(null);
676
+ onToggle();
677
+ }
678
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Box, { display: { base: "block", md: "none" }, children: [
679
+ /* @__PURE__ */ jsxRuntime.jsx(
680
+ react$1.IconButton,
681
+ {
682
+ icon: isOpen ? /* @__PURE__ */ jsxRuntime.jsx(icons.CloseIcon, { w: CLOSE_ICON_SIZE, h: CLOSE_ICON_SIZE }) : /* @__PURE__ */ jsxRuntime.jsx(icons.HamburgerIcon, { w: HAMBURGER_ICON_SIZE, h: HAMBURGER_ICON_SIZE }),
683
+ size: "sm",
684
+ variant: "ghost",
685
+ "aria-label": `${isOpen ? "Close" : "Open"} navigation menu`,
686
+ "aria-expanded": isOpen,
687
+ onClick: handleClick
688
+ }
689
+ ),
690
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Collapse, { in: isOpen, animateOpacity: true, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { position: "absolute", top: 16, left: 0, right: 0, w: "100vw", px: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
691
+ react$1.List,
692
+ {
693
+ spacing: 2,
694
+ p: 2,
695
+ boxShadow: "md",
696
+ borderWidth: "1px",
697
+ borderColor: react$1.useColorModeValue("gray.200", "gray.700"),
698
+ borderRadius: "md",
699
+ bg: background,
700
+ children: menu.map((item, index2) => {
701
+ var _a;
702
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { as: "li", role: "listitem", children: ((_a = item.children) == null ? void 0 : _a.length) ? /* @__PURE__ */ jsxRuntime.jsx(NavList, { ...item, isExpanded: index2 === expanded, onExpand: handleExpand(index2) }) : /* @__PURE__ */ jsxRuntime.jsx(NavLink, { ...item }) }, index2);
703
+ })
704
+ }
705
+ ) }) })
706
+ ] });
707
+ };
708
+ const Navigation = ({ menu }) => {
709
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
710
+ /* @__PURE__ */ jsxRuntime.jsx(DesktopNavigation, { menu }),
711
+ /* @__PURE__ */ jsxRuntime.jsx(MobileNavigation, { menu })
712
+ ] });
713
+ };
714
+ const Header = () => {
715
+ var _a, _b;
716
+ const { configs } = index$2.useSiteContext();
717
+ const navigation = ((_a = configs == null ? void 0 : configs.header) == null ? void 0 : _a.navigation) ?? [];
718
+ const toolbar = (_b = configs == null ? void 0 : configs.header) == null ? void 0 : _b.toolbar;
719
+ const hasToolbar = !!toolbar;
720
+ const hasNavigation = !!navigation.length;
721
+ return /* @__PURE__ */ jsxRuntime.jsx(
722
+ react$1.Box,
723
+ {
724
+ as: "header",
725
+ position: "sticky",
726
+ top: 0,
727
+ bg: react$1.useColorModeValue("white", "gray.900"),
728
+ color: react$1.useColorModeValue("gray.700", "gray.200"),
729
+ boxShadow: "sm",
730
+ zIndex: 100,
731
+ children: /* @__PURE__ */ jsxRuntime.jsx(Container, { children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.Flex, { as: "nav", gap: 2, py: 2, children: [
732
+ /* @__PURE__ */ jsxRuntime.jsx(Brand, { brand: /* @__PURE__ */ jsxRuntime.jsx(Logo, {}) }),
733
+ (hasNavigation || hasToolbar) && /* @__PURE__ */ jsxRuntime.jsxs(
734
+ react$1.Flex,
735
+ {
736
+ as: "section",
737
+ flex: 1,
738
+ flexDir: { base: "row-reverse", md: "row" },
739
+ justifyContent: "end",
740
+ align: "center",
741
+ gap: 2,
742
+ children: [
743
+ hasNavigation && /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { flex: { base: 0, md: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(Navigation, { menu: navigation }) }),
744
+ hasToolbar && /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { gap: 2, flex: { base: 1, md: 0 }, justifyContent: "flex-end", children: toolbar })
745
+ ]
746
+ }
747
+ )
748
+ ] }) })
749
+ }
750
+ );
751
+ };
752
+ const Hero = ({ title, subtitle, content, link, image }) => {
753
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { as: "section", bg: "gray.900", children: /* @__PURE__ */ jsxRuntime.jsx(Container, { children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.Flex, { direction: { base: "column", md: "row" }, children: [
754
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { align: "center", justify: { base: "center", md: "flex-start" }, flex: 1, py: 8, pe: 8, children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.Stack, { spacing: 6, w: "full", maxW: "lg", children: [
755
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.Heading, { as: "h1", fontSize: { base: "3xl", md: "4xl", lg: "5xl" }, children: [
756
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.Text, { as: "span", display: "block", children: [
757
+ title,
758
+ " —"
759
+ ] }),
760
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { as: "span", display: "block", color: "brand.400", children: subtitle })
761
+ ] }),
762
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { fontSize: { base: "md", lg: "lg" }, color: "gray.500", children: content }),
763
+ !!link && /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { direction: { base: "column", md: "row" }, children: /* @__PURE__ */ jsxRuntime.jsx(LinkButton, { ...link }) })
764
+ ] }) }),
765
+ image && /* @__PURE__ */ jsxRuntime.jsx(react$1.Flex, { display: { base: "none", md: "flex" }, flex: 1, children: image })
766
+ ] }) }) });
767
+ };
768
+ const Main = ({ children }) => {
769
+ return /* @__PURE__ */ jsxRuntime.jsx(
770
+ react$1.Flex,
771
+ {
772
+ as: "main",
773
+ direction: "column",
774
+ flexGrow: 1,
775
+ bg: react$1.useColorModeValue("white", "gray.800"),
776
+ color: react$1.useColorModeValue("gray.700", "gray.200"),
777
+ children
778
+ }
779
+ );
780
+ };
781
+ const ScrollToTop = () => {
782
+ const [isVisible, setIsVisible] = react.useState(false);
783
+ react.useEffect(() => {
784
+ const toggleVisibility = () => {
785
+ setIsVisible(window.scrollY > 300);
786
+ };
787
+ window.addEventListener("scroll", toggleVisibility);
788
+ return () => {
789
+ window.removeEventListener("scroll", toggleVisibility);
790
+ };
791
+ }, []);
792
+ function handleClick() {
793
+ window.scrollTo({
794
+ top: 0,
795
+ behavior: "smooth"
796
+ });
797
+ }
798
+ return /* @__PURE__ */ jsxRuntime.jsx(
799
+ react$1.Box,
800
+ {
801
+ position: "fixed",
802
+ bottom: { base: 4, md: 8, lg: 16 },
803
+ right: { base: 4, md: 8, lg: 16 },
804
+ zIndex: "1000",
805
+ opacity: isVisible ? 1 : 0,
806
+ transform: isVisible ? "translateY(0)" : "translateY(0.5rem)",
807
+ transition: "opacity 0.4s ease, transform 0.4s ease",
808
+ pointerEvents: isVisible ? "auto" : "none",
809
+ children: /* @__PURE__ */ jsxRuntime.jsx(
810
+ react$1.IconButton,
811
+ {
812
+ "aria-label": "Scroll to top",
813
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronUpIcon, { w: 6, h: 6 }),
814
+ size: "lg",
815
+ shadow: "lg",
816
+ colorScheme: "brand",
817
+ isRound: true,
818
+ onClick: handleClick
819
+ }
820
+ )
821
+ }
822
+ );
823
+ };
824
+ const Layout = ({ children }) => {
825
+ const content = typeof children === "function" ? children({ Hero, Content }) : /* @__PURE__ */ jsxRuntime.jsx(Content, { children });
826
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Stack, { spacing: 0, position: "relative", w: "100%", minH: "100dvh", children: [
827
+ /* @__PURE__ */ jsxRuntime.jsx(Header, {}),
828
+ /* @__PURE__ */ jsxRuntime.jsx(Main, { children: content }),
829
+ /* @__PURE__ */ jsxRuntime.jsx(Footer, {}),
830
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollToTop, {})
831
+ ] });
832
+ };
833
+ const List = ({ items, bullet = "—", render, ...boxProps }) => {
834
+ return /* @__PURE__ */ jsxRuntime.jsx(react$1.List, { pl: 0, ml: 2, mb: 4, ...boxProps, children: items.map((item, index2) => /* @__PURE__ */ jsxRuntime.jsxs(react$1.ListItem, { display: "flex", gap: 1, children: [
835
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Box, { children: bullet }),
836
+ render ? render(item) : item
837
+ ] }, index2)) });
838
+ };
839
+ const NotFound = () => {
840
+ const { t } = reactI18next.useTranslation("pageNotFound");
841
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Stack, { gap: 4, children: [
842
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Heading, { as: "h1", children: t("title") }),
843
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.Text, { fontSize: "xl", children: [
844
+ t("description"),
845
+ " ",
846
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Button, { as: gatsby.Link, to: "/", variant: "link", colorScheme: "brand", fontSize: "xl", children: t("action") })
847
+ ] })
848
+ ] });
849
+ };
850
+ const TitleMap = {
851
+ pros: "advantages",
852
+ cons: "disadvantages"
853
+ };
854
+ const IconMap = {
855
+ pros: icons.CheckCircleIcon,
856
+ cons: icons.WarningIcon
857
+ };
858
+ const IconColorMap = {
859
+ pros: "green.500",
860
+ cons: "red.500"
861
+ };
862
+ const BgColorMap = {
863
+ pros: "green",
864
+ cons: "red"
865
+ };
866
+ const ProsConsCard = ({ itemType, items }) => {
867
+ const { t } = reactI18next.useTranslation("prosCons");
868
+ return /* @__PURE__ */ jsxRuntime.jsxs(
869
+ react$1.Card,
870
+ {
871
+ as: "article",
872
+ flex: 1,
873
+ p: 2,
874
+ bgColor: react$1.useColorModeValue(`${BgColorMap[itemType]}.100`, `${BgColorMap[itemType]}.800`),
875
+ children: [
876
+ /* @__PURE__ */ jsxRuntime.jsx(
877
+ react$1.CardHeader,
878
+ {
879
+ as: "header",
880
+ p: 2,
881
+ borderTopRadius: "md",
882
+ bgColor: react$1.useColorModeValue("whiteAlpha.800", "blackAlpha.800"),
883
+ children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Heading, { as: "h3", textTransform: "uppercase", fontSize: "xl", children: t(TitleMap[itemType]) })
884
+ }
885
+ ),
886
+ /* @__PURE__ */ jsxRuntime.jsx(
887
+ react$1.CardBody,
888
+ {
889
+ as: "section",
890
+ p: 2,
891
+ borderBottomRadius: "md",
892
+ bgColor: react$1.useColorModeValue("whiteAlpha.800", "blackAlpha.800"),
893
+ children: /* @__PURE__ */ jsxRuntime.jsx(react$1.List, { spacing: 4, p: 0, children: items.map(({ title, description }) => /* @__PURE__ */ jsxRuntime.jsxs(react$1.ListItem, { display: "flex", children: [
894
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.ListIcon, { as: IconMap[itemType], w: 6, h: 6, color: IconColorMap[itemType] }),
895
+ /* @__PURE__ */ jsxRuntime.jsxs(react$1.Text, { fontWeight: "semibold", fontSize: "md", children: [
896
+ title,
897
+ !!description && /* @__PURE__ */ jsxRuntime.jsxs(react$1.Text, { as: "span", fontWeight: "normal", children: [
898
+ ": ",
899
+ description
900
+ ] })
901
+ ] })
902
+ ] }, title)) })
903
+ }
904
+ )
905
+ ]
906
+ }
907
+ );
908
+ };
909
+ const ProsCons = ({ items, ...boxProps }) => {
910
+ const { pros, cons } = items;
911
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Flex, { as: "section", direction: { base: "column", md: "row" }, gap: 4, ...boxProps, children: [
912
+ /* @__PURE__ */ jsxRuntime.jsx(ProsConsCard, { itemType: "pros", items: pros }),
913
+ /* @__PURE__ */ jsxRuntime.jsx(ProsConsCard, { itemType: "cons", items: cons })
914
+ ] });
915
+ };
916
+ const RichTextRenderer = ({ content }) => {
917
+ const components = react$2.useMDXComponents();
918
+ return /* @__PURE__ */ jsxRuntime.jsx(Markdown, { components, children: content });
919
+ };
920
+ function replacePlaceholders(text, placeholders) {
921
+ Object.entries(placeholders).forEach(([placeholder, replacement]) => {
922
+ const regex = new RegExp(`{{${placeholder}}}`, "g");
923
+ text = text.replace(regex, replacement);
924
+ });
925
+ return text;
926
+ }
927
+ const Seo = ({ children, siteMetadata, title, description, lang }) => {
928
+ const { name: siteName, lang: defaultLang, seo } = siteMetadata;
929
+ const { title: defaultTitle, description: defaultDescription } = seo;
930
+ const placeholders = react.useMemo(
931
+ () => ({
932
+ siteName,
933
+ currentYear: index.getCurrentYear(),
934
+ currentMonth: index.getCurrentMonth()
935
+ }),
936
+ [siteName]
937
+ );
938
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
939
+ /* @__PURE__ */ jsxRuntime.jsx("html", { lang: lang ?? defaultLang }),
940
+ /* @__PURE__ */ jsxRuntime.jsx("title", { children: title ? typeof title === "string" ? replacePlaceholders(title, placeholders) : title(placeholders) : defaultTitle }),
941
+ /* @__PURE__ */ jsxRuntime.jsx(
942
+ "meta",
943
+ {
944
+ name: "description",
945
+ content: description ? typeof description === "string" ? replacePlaceholders(description, placeholders) : description(placeholders) : defaultDescription
946
+ }
947
+ ),
948
+ children
949
+ ] });
950
+ };
951
+ const Table = ({
952
+ columnNumber,
953
+ items,
954
+ caption,
955
+ bordered = false,
956
+ striped = true,
957
+ scrollable,
958
+ ...boxProps
959
+ }) => {
960
+ const headerItems = items.slice(0, columnNumber);
961
+ const bodyItems = items.slice(columnNumber);
962
+ return /* @__PURE__ */ jsxRuntime.jsx(
963
+ react$1.TableContainer,
964
+ {
965
+ border: bordered ? void 0 : "none",
966
+ ...scrollable ? { maxH: "50vh", overflowY: "auto" } : {},
967
+ ...boxProps,
968
+ children: /* @__PURE__ */ jsxRuntime.jsxs(react$1.Table, { variant: striped ? "striped" : "simple", children: [
969
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Thead, { ...scrollable ? { position: "sticky", top: 0, zIndex: 1, bg: "gray.800" } : {}, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Tr, { children: headerItems.map((item, index2) => /* @__PURE__ */ jsxRuntime.jsx(react$1.Th, { children: item }, index2)) }) }),
970
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Tbody, { children: Array.from({ length: Math.ceil(bodyItems.length / columnNumber) }, (_, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(react$1.Tr, { children: Array.from({ length: columnNumber }, (_2, colIndex) => /* @__PURE__ */ jsxRuntime.jsx(react$1.Td, { children: bodyItems[rowIndex * columnNumber + colIndex] || "" }, colIndex)) }, rowIndex)) }),
971
+ !!caption && /* @__PURE__ */ jsxRuntime.jsx(react$1.TableCaption, { children: caption })
972
+ ] })
973
+ }
974
+ );
975
+ };
976
+ const Tabs = ({ items, render, ...boxProps }) => {
977
+ const { tabs, panels } = react.useMemo(() => {
978
+ const tabs2 = [];
979
+ const panels2 = [];
980
+ items.forEach(({ content, ...tab }) => {
981
+ tabs2.push(tab);
982
+ panels2.push(content);
983
+ });
984
+ return { tabs: tabs2, panels: panels2 };
985
+ }, []);
986
+ return /* @__PURE__ */ jsxRuntime.jsxs(react$1.Tabs, { overflow: "hidden", colorScheme: "brand", ...boxProps, children: [
987
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.TabList, { overflow: "auto hidden", children: tabs.map(({ label, icon }, index2) => /* @__PURE__ */ jsxRuntime.jsx(react$1.Tab, { children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Text, { as: "h3", isTruncated: true, children: icon ? `${icon} ${label}` : label }) }, index2)) }),
988
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.TabPanels, { children: panels.map((panel, index2) => /* @__PURE__ */ jsxRuntime.jsx(react$1.TabPanel, { children: render ? render(panel) : panel }, index2)) })
989
+ ] });
990
+ };
991
+ const Tip = ({ tip, author = null, ...boxProps }) => {
992
+ return /* @__PURE__ */ jsxRuntime.jsxs(
993
+ react$1.Card,
994
+ {
995
+ variant: "filled",
996
+ p: 4,
997
+ borderLeft: "4px solid gray",
998
+ gap: 4,
999
+ _before: {
1000
+ content: '"❛❛"',
1001
+ position: "absolute",
1002
+ top: -8,
1003
+ left: -2,
1004
+ fontSize: "6rem",
1005
+ fontStyle: "italic",
1006
+ color: react$1.useColorModeValue("blackAlpha.300", "whiteAlpha.300")
1007
+ },
1008
+ ...boxProps,
1009
+ children: [
1010
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.CardBody, { as: "blockquote", p: 0, fontStyle: "italic", children: tip }),
1011
+ !!author && /* @__PURE__ */ jsxRuntime.jsx(react$1.CardFooter, { alignItems: "center", justify: "flex-end", p: 0, children: /* @__PURE__ */ jsxRuntime.jsx(Author, { author, variant: "short" }) })
1012
+ ]
1013
+ }
1014
+ );
1015
+ };
1016
+ exports.Author = Author;
1017
+ exports.AuthorCard = AuthorCard;
1018
+ exports.BonusCard = BonusCard;
1019
+ exports.Center = Center;
1020
+ exports.ContactForm = ContactForm;
1021
+ exports.Faq = Faq;
1022
+ exports.FeatureCard = FeatureCard;
1023
+ exports.Features = Features;
1024
+ exports.GameCard = GameCard;
1025
+ exports.GameDemo = GameDemo;
1026
+ exports.GameInfo = GameInfo;
1027
+ exports.Grid = Grid;
1028
+ exports.HowTo = HowTo;
1029
+ exports.Layout = Layout;
1030
+ exports.LinkButton = LinkButton;
1031
+ exports.List = List;
1032
+ exports.NotFound = NotFound;
1033
+ exports.ProsCons = ProsCons;
1034
+ exports.PulseButton = PulseButton;
1035
+ exports.RichTextRenderer = RichTextRenderer;
1036
+ exports.Seo = Seo;
1037
+ exports.Table = Table;
1038
+ exports.Tabs = Tabs;
1039
+ exports.Tip = Tip;