@anywayseo/tools 2.5.1 → 3.0.0

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