{"version":3,"file":"utils-A_8_kwJt.js","sources":["../../../src/utils/seo.tsx","../../../src/utils/accessibility.tsx"],"sourcesContent":["import React from \"react\";\nimport { Helmet } from \"react-helmet-async\";\n\ninterface SEOProps {\n title: string;\n description?: string;\n canonicalUrl?: string;\n ogType?: \"website\" | \"article\" | \"profile\";\n ogImage?: string;\n ogImageAlt?: string;\n twitterCard?: \"summary\" | \"summary_large_image\";\n noIndex?: boolean;\n structuredData?: object;\n keywords?: string[];\n}\n\n/**\n * SEO Component for managing all meta tags\n */\nexport const SEO: React.FC = ({\n title,\n description = \"11ic - Premier online casino gaming platform\",\n canonicalUrl,\n ogType = \"website\",\n ogImage = \"/og-image.jpg\",\n ogImageAlt = \"11ic Game\",\n twitterCard = \"summary_large_image\",\n noIndex = false,\n structuredData,\n keywords = [],\n}) => {\n const baseUrl = \"https://11icgamespk.com\";\n const fullCanonicalUrl = canonicalUrl ? `${baseUrl}${canonicalUrl}` : baseUrl;\n\n return (\n \n {/* Basic Meta Tags */}\n {`${title} | 11ic Game`}\n \n {keywords.length > 0 && (\n \n )}\n \n\n {/* Open Graph / Facebook */}\n \n \n \n \n \n \n\n {/* Twitter */}\n \n \n \n \n \n \n\n {/* No Index (if needed) */}\n {noIndex && }\n\n {/* Structured Data */}\n {structuredData && (\n \n )}\n \n );\n};\n\n/**\n * Generate structured data for rich results\n */\nexport const generateOrganizationSchema = () => {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"Organization\",\n name: \"11ic Game\",\n url: \"https://11icgamespk.com\",\n logo: \"https://11icgamespk.com/11ic-logo.png\",\n sameAs: [\n \"https://www.facebook.com/11ic\",\n \"https://www.twitter.com/11ic\",\n \"https://www.instagram.com/11ic\",\n ],\n contactPoint: {\n \"@type\": \"ContactPoint\",\n telephone: \"+92-000-0000000\",\n contactType: \"customer service\",\n },\n };\n};\n\n/**\n * Generate breadcrumb schema\n */\nexport const generateBreadcrumbSchema = (\n breadcrumbs: { name: string; url: string }[]\n) => {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: breadcrumbs.map((breadcrumb, index) => ({\n \"@type\": \"ListItem\",\n position: index + 1,\n name: breadcrumb.name,\n item: `https://11icgamespk.com${breadcrumb.url}`,\n })),\n };\n};\n\n/**\n * Generate JSON-LD for an article\n */\nexport const generateArticleSchema = (\n title: string,\n description: string,\n imageUrl: string,\n publishedDate: string,\n modifiedDate: string,\n authorName: string\n) => {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"Article\",\n headline: title,\n description: description,\n image: `https://11icgamespk.com${imageUrl}`,\n datePublished: publishedDate,\n dateModified: modifiedDate,\n author: {\n \"@type\": \"Person\",\n name: authorName,\n },\n publisher: {\n \"@type\": \"Organization\",\n name: \"11ic Game\",\n logo: {\n \"@type\": \"ImageObject\",\n url: \"https://11icgamespk.com/11ic-logo.png\",\n },\n },\n };\n};\n","import React, { useEffect, useRef } from \"react\";\n\n/**\n * Skip to content component for keyboard users\n */\nexport const SkipToContent: React.FC = () => {\n return (\n \n Skip to main content\n \n );\n};\n\n/**\n * Focus trap hook for modals and dialogs\n */\nexport const useFocusTrap = (isActive: boolean = true) => {\n const containerRef = useRef(null);\n\n useEffect(() => {\n if (!isActive || !containerRef.current) return;\n\n const containerElement = containerRef.current;\n const focusableElements = containerElement.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n\n const firstElement = focusableElements[0] as HTMLElement;\n const lastElement = focusableElements[\n focusableElements.length - 1\n ] as HTMLElement;\n\n const handleTabKey = (e: KeyboardEvent) => {\n if (e.key !== \"Tab\") return;\n\n // If shift + tab and on first element, move to last element\n if (e.shiftKey && document.activeElement === firstElement) {\n e.preventDefault();\n lastElement.focus();\n }\n // If tab and on last element, move to first element\n else if (!e.shiftKey && document.activeElement === lastElement) {\n e.preventDefault();\n firstElement.focus();\n }\n };\n\n // Focus the first element on mount\n if (firstElement) {\n firstElement.focus();\n }\n\n // Add keyboard event listener\n document.addEventListener(\"keydown\", handleTabKey);\n\n return () => {\n document.removeEventListener(\"keydown\", handleTabKey);\n };\n }, [isActive]);\n\n return containerRef;\n};\n\n/**\n * A hook to announce messages to screen readers\n */\nexport const useAnnouncement = () => {\n const [message, setMessage] = React.useState(\"\");\n const [target, setTarget] = React.useState<\"polite\" | \"assertive\">(\"polite\");\n\n const announce = (newMessage: string, isAssertive: boolean = false) => {\n setMessage(newMessage);\n setTarget(isAssertive ? \"assertive\" : \"polite\");\n };\n\n return {\n announce,\n AnnouncementRegion: () => (\n <>\n \n {target === \"polite\" ? message : \"\"}\n \n \n {target === \"assertive\" ? message : \"\"}\n \n \n ),\n };\n};\n\n/**\n * Utility function to get proper ARIA attributes for elements\n */\nexport const getAriaProps = (\n type: \"button\" | \"checkbox\" | \"dialog\" | \"tab\" | \"menu\",\n state: Record = {}\n) => {\n // Define the accepted props for accessibility attributes\n interface AriaProps {\n role?: string;\n \"aria-disabled\"?: boolean;\n \"aria-checked\"?: boolean;\n \"aria-modal\"?: boolean;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n \"aria-selected\"?: boolean;\n \"aria-controls\"?: string;\n \"aria-expanded\"?: boolean;\n \"aria-haspopup\"?: boolean | string;\n tabIndex?: number;\n }\n\n const baseProps: AriaProps = {};\n\n switch (type) {\n case \"button\":\n baseProps[\"role\"] = \"button\";\n baseProps[\"aria-disabled\"] = !!state.disabled;\n baseProps[\"tabIndex\"] = state.disabled ? -1 : 0;\n break;\n case \"checkbox\":\n baseProps[\"role\"] = \"checkbox\";\n baseProps[\"aria-checked\"] = !!state.checked;\n baseProps[\"tabIndex\"] = 0;\n break;\n case \"dialog\":\n baseProps[\"role\"] = \"dialog\";\n baseProps[\"aria-modal\"] = true;\n baseProps[\"aria-labelledby\"] = (state.labelledby as string) || \"\";\n baseProps[\"aria-describedby\"] = (state.describedby as string) || \"\";\n break;\n case \"tab\":\n baseProps[\"role\"] = \"tab\";\n baseProps[\"aria-selected\"] = !!state.selected;\n baseProps[\"tabIndex\"] = state.selected ? 0 : -1;\n baseProps[\"aria-controls\"] = (state.controls as string) || \"\";\n break;\n case \"menu\":\n baseProps[\"role\"] = \"menu\";\n baseProps[\"aria-expanded\"] = !!state.expanded;\n baseProps[\"aria-haspopup\"] = true;\n break;\n }\n\n return baseProps;\n};\n\n/**\n * A component for semantic heading levels\n */\nexport const Heading: React.FC<{\n level: 1 | 2 | 3 | 4 | 5 | 6;\n children: React.ReactNode;\n className?: string;\n id?: string;\n}> = ({ level, children, className = \"\", id }) => {\n // Dynamically render the correct heading level\n switch (level) {\n case 1:\n return (\n

\n {children}\n

\n );\n case 2:\n return (\n

\n {children}\n

\n );\n case 3:\n return (\n

\n {children}\n

\n );\n case 4:\n return (\n

\n {children}\n

\n );\n case 5:\n return (\n
\n {children}\n
\n );\n case 6:\n return (\n
\n {children}\n
\n );\n default:\n return (\n

\n {children}\n

\n );\n }\n};\n"],"names":["generateOrganizationSchema","SkipToContent","jsx"],"mappings":"kEA4EO,MAAMA,EAA6B,KACjC,CACL,WAAY,qBACZ,QAAS,eACT,KAAM,YACN,IAAK,0BACL,KAAM,wCACN,OAAQ,CACN,gCACA,+BACA,gCACF,EACA,aAAc,CACZ,QAAS,eACT,UAAW,kBACX,YAAa,kBAAA,CAEjB,GCxFWC,EAA0B,IAEnCC,EAAA,IAAC,IAAA,CACC,KAAK,gBACL,UAAU,4JACX,SAAA,sBAAA,CAED"}