├── .gitignore ├── ListFormat.d.ts ├── README.md ├── components ├── experiment.tsx ├── list.tsx └── loading.tsx ├── experiment.ts ├── next-env.d.ts ├── next.config.mjs ├── package.json ├── pages ├── _document.tsx └── index.tsx ├── pnpm-lock.yaml ├── styled-jsx.d.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | 21 | # debug 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | # local env files 27 | .env.local 28 | .env.development.local 29 | .env.test.local 30 | .env.production.local 31 | -------------------------------------------------------------------------------- /ListFormat.d.ts: -------------------------------------------------------------------------------- 1 | type localeMatcher = 'lookup' | 'best fit' 2 | 3 | declare namespace Intl { 4 | /** https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat */ 5 | class ListFormat { 6 | public constructor(locales?: string | string[], options?: { 7 | localeMatcher?: localeMatcher, 8 | type?: 'conjunction' | 'disjunction' | 'unit', 9 | style?: 'long' | 'short' 10 | }) 11 | public static supportedLocalesOf(locales: string | string[], options?: {localeMatcher: localeMatcher}): string[] 12 | public format: (items: Iterable) => string 13 | public formatToParts: (list: string[]) => {type: 'element' | 'literal', value: string}[] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Discord Server Experiment Rollouts 2 | 3 | https://rollouts.advaith.io 4 | 5 | This is a site made with React and Next.js to display the current Discord server experiments and their rollouts. 6 | -------------------------------------------------------------------------------- /components/experiment.tsx: -------------------------------------------------------------------------------- 1 | import Swal from 'sweetalert2' 2 | import withReactContent from 'sweetalert2-react-content' 3 | import { type Experiment as Exp, Filter, FilterType, type Population } from '../experiment' 4 | 5 | const swal = withReactContent(Swal) 6 | const andList = new Intl.ListFormat('en') 7 | const orList = new Intl.ListFormat('en', { type: 'disjunction' }) 8 | 9 | const hubTypes = ['Default', 'High School', 'College'] 10 | 11 | function Population({ population, data }: { population: Population, data: Exp['data'] }) { 12 | let popTotal = 0 13 | return
14 | {population[1][0] && <> 15 |

Filter: {andList.format(population[1].map(f => parseFilter(f)))}

16 |
17 | } 18 | {population[0].map(bucket =>
0 ? '#46c46e' : '#ed4245'}}> 19 | {data.description.find(d => d.startsWith(`Treatment ${bucket[0]}`)) ?? (bucket[0] === -1 ? 'None' : `Unknown Treatment ${bucket[0]}`)}:{' '} 20 | {(() => { 21 | const sum = bucket[1].reduce((total, range) => total + range.e - range.s, 0) 22 | popTotal += sum 23 | return sum 24 | })() / 100}%{` `} 25 | ({bucket[1].map(range => `${range.s} - ${range.e}`).join(', ')}) 26 |
)} 27 |
{popTotal < 10_000 && <>{data.description[0]}: {(10_000 - popTotal)/100}%}
28 |
29 | } 30 | 31 | export default function Experiment({exp}: {exp: Exp}) { 32 | return
33 |

34 | {exp.data.title} 35 |

36 |

{exp.data.id}{exp.rollout[8] ? <> (Currently inactive - A/A mode) : null}

37 |
38 | {exp.rollout[3].map((pop, i) => )} 39 |
40 | {exp.rollout[5].length ? <> 41 |

Overrides Formatted:

42 | {exp.rollout[5].flat().map((pop, i) => )} 43 | : null} 44 | 65 | 66 | 95 |
96 | } 97 | 98 | const parseFilter = (f: Filter) => { 99 | if (f[0] === FilterType.Feature) return `Server has feature ${orList.format(f[1][0][1])}` 100 | if (f[0] === FilterType.IDRange) return `Server ID is in range ${f[1][0][1] ?? 0} - ${f[1][1][1]}` 101 | if (f[0] === FilterType.MemberCount) return `Server member count is ${f[1][1][1] ? `in range ${f[1][0][1] ?? 0} - ${f[1][1][1]}` : `${f[1][0][1]}+`}` 102 | if (f[0] === FilterType.ID) return `Server ID is ${orList.format(f[1][0][1])}` 103 | if (f[0] === FilterType.HubType) return `Server hub type is ${orList.format(f[1][0][1].map(t => hubTypes[t]))}` 104 | if (f[0] === FilterType.VanityURL) return `Server ${f[1][0][1] ? 'has' : 'does not have'} a vanity URL` 105 | if (f[0] === FilterType.RangeByHash) return `${f[1][1][1]/100}% of servers (hash key ${f[1][0][1]}, target ${f[1][1][1]})` 106 | return `Unknown filter type ${f[0]}` 107 | } 108 | -------------------------------------------------------------------------------- /components/list.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react' 2 | import useSWR from 'swr' 3 | import { Experiment as Exp } from '../experiment' 4 | import Experiment from './experiment' 5 | import Loading from './loading' 6 | 7 | export default function List() { 8 | const { data, error } = useSWR('https://api.rollouts.advaith.io', input => fetch(input).then(res => res.json())) 9 | 10 | useEffect(() => document.getElementById(location.hash.substring(1))?.scrollIntoView(), [data]) 11 | 12 | if (error) return An error occurred :( 13 | if (!data) return 14 | return <>{data.sort((a, b) => b.data.id.localeCompare(a.data.id)).map(exp => )} 15 | } 16 | -------------------------------------------------------------------------------- /components/loading.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | 3 | export default function Loading() { 4 | const [count, setCount] = useState(1) 5 | 6 | useEffect(() => { 7 | const interval = setInterval(() => setCount(count => count === 3 ? 1 : count + 1), 200) 8 | return () => clearInterval(interval) 9 | }, []) 10 | 11 | return Loading{'.'.repeat(count)} 12 | } 13 | -------------------------------------------------------------------------------- /experiment.ts: -------------------------------------------------------------------------------- 1 | export interface Experiment { 2 | data: { 3 | id: string 4 | type: 'guild' 5 | title: string 6 | description: string[] 7 | buckets: number[] 8 | hash: number 9 | } 10 | rollout: [ 11 | number, // hash 12 | string | null, // hash key 13 | number, // revision 14 | Population[], // populations 15 | { // overrides 16 | /** bucket */ b: number, 17 | /** server IDs */ k: string[] 18 | }[], 19 | [Population[]], // overrides formatted 20 | string | null, // holdout name 21 | number | null, // holdout bucket 22 | number, // aa mode 23 | ] 24 | } 25 | 26 | export type Population = [ 27 | [ 28 | number, //bucket 29 | { // rollout 30 | /** start */ s: number, 31 | /** end */ e: number 32 | }[] 33 | ][], 34 | Filter[] 35 | ] 36 | 37 | export enum FilterType { 38 | Feature = 1604612045, 39 | IDRange = 2404720969, 40 | MemberCount = 2918402255, 41 | ID = 3013771838, 42 | HubType = 4148745523, 43 | VanityURL = 188952590, 44 | RangeByHash = 2294888943 45 | } 46 | 47 | type FeatureFilter = [FilterType.Feature, [[number, string[]]]] 48 | type IDRangeFilter = [FilterType.IDRange, [[number, number | null], [number, number]]] 49 | type MemberCountFilter = [FilterType.MemberCount, [[number, number | null], [number, number]]] 50 | type IDFilter = [FilterType.ID, [[number, string[]]]] 51 | type HubTypeFilter = [FilterType.HubType, [[number, number[]]]] 52 | type VanityURLFilter = [FilterType.VanityURL, [[FilterType.VanityURL, boolean]]] 53 | type RangeByHashFilter = [FilterType.RangeByHash, [[number, number], [number, number]]] 54 | 55 | export type Filter = FeatureFilter | IDRangeFilter | MemberCountFilter | IDFilter | HubTypeFilter | VanityURLFilter | RangeByHashFilter 56 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/pages/api-reference/config/typescript for more information. 6 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | output: 'export' 5 | } 6 | 7 | export default nextConfig 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollouts", 3 | "scripts": { 4 | "dev": "next dev --turbopack", 5 | "build": "next build" 6 | }, 7 | "dependencies": { 8 | "next": "^15.1.6", 9 | "react": "^19.0.0", 10 | "react-dom": "^19.0.0", 11 | "sweetalert2": "^11.15.10", 12 | "sweetalert2-react-content": "^5.1.0", 13 | "swr": "^2.3.2" 14 | }, 15 | "devDependencies": { 16 | "@types/node": "^22.13.1", 17 | "@types/react": "^19.0.8", 18 | "styled-jsx": "^5.1.6", 19 | "typescript": "^5.7.3" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import Document, { Html, Head, Main, NextScript } from 'next/document' 2 | 3 | class MyDocument extends Document { 4 | render() { 5 | return ( 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | ) 14 | } 15 | } 16 | 17 | export default MyDocument 18 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head' 2 | import List from '../components/list' 3 | 4 | export default function Home() { 5 | return ( 6 |
7 | 8 | Discord Server Experiment Rollouts 9 | 10 | 11 | 12 | 13 |
14 |

15 | Discord Server Experiment Rollouts 16 |

17 | 18 | 19 | 20 |
21 | 22 |
23 | Created by advaith
24 | Not affiliated with Discord 25 |
26 | 27 | 83 | 84 | 109 |
110 | ) 111 | } 112 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | next: 12 | specifier: ^15.1.6 13 | version: 15.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 14 | react: 15 | specifier: ^19.0.0 16 | version: 19.0.0 17 | react-dom: 18 | specifier: ^19.0.0 19 | version: 19.0.0(react@19.0.0) 20 | sweetalert2: 21 | specifier: ^11.15.10 22 | version: 11.15.10 23 | sweetalert2-react-content: 24 | specifier: ^5.1.0 25 | version: 5.1.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sweetalert2@11.15.10) 26 | swr: 27 | specifier: ^2.3.2 28 | version: 2.3.2(react@19.0.0) 29 | devDependencies: 30 | '@types/node': 31 | specifier: ^22.13.1 32 | version: 22.13.1 33 | '@types/react': 34 | specifier: ^19.0.8 35 | version: 19.0.8 36 | styled-jsx: 37 | specifier: ^5.1.6 38 | version: 5.1.6(react@19.0.0) 39 | typescript: 40 | specifier: ^5.7.3 41 | version: 5.7.3 42 | 43 | packages: 44 | 45 | '@emnapi/runtime@1.3.1': 46 | resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} 47 | 48 | '@img/sharp-darwin-arm64@0.33.5': 49 | resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} 50 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 51 | cpu: [arm64] 52 | os: [darwin] 53 | 54 | '@img/sharp-darwin-x64@0.33.5': 55 | resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} 56 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 57 | cpu: [x64] 58 | os: [darwin] 59 | 60 | '@img/sharp-libvips-darwin-arm64@1.0.4': 61 | resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} 62 | cpu: [arm64] 63 | os: [darwin] 64 | 65 | '@img/sharp-libvips-darwin-x64@1.0.4': 66 | resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} 67 | cpu: [x64] 68 | os: [darwin] 69 | 70 | '@img/sharp-libvips-linux-arm64@1.0.4': 71 | resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} 72 | cpu: [arm64] 73 | os: [linux] 74 | 75 | '@img/sharp-libvips-linux-arm@1.0.5': 76 | resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} 77 | cpu: [arm] 78 | os: [linux] 79 | 80 | '@img/sharp-libvips-linux-s390x@1.0.4': 81 | resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} 82 | cpu: [s390x] 83 | os: [linux] 84 | 85 | '@img/sharp-libvips-linux-x64@1.0.4': 86 | resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} 87 | cpu: [x64] 88 | os: [linux] 89 | 90 | '@img/sharp-libvips-linuxmusl-arm64@1.0.4': 91 | resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} 92 | cpu: [arm64] 93 | os: [linux] 94 | 95 | '@img/sharp-libvips-linuxmusl-x64@1.0.4': 96 | resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} 97 | cpu: [x64] 98 | os: [linux] 99 | 100 | '@img/sharp-linux-arm64@0.33.5': 101 | resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} 102 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 103 | cpu: [arm64] 104 | os: [linux] 105 | 106 | '@img/sharp-linux-arm@0.33.5': 107 | resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} 108 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 109 | cpu: [arm] 110 | os: [linux] 111 | 112 | '@img/sharp-linux-s390x@0.33.5': 113 | resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} 114 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 115 | cpu: [s390x] 116 | os: [linux] 117 | 118 | '@img/sharp-linux-x64@0.33.5': 119 | resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} 120 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 121 | cpu: [x64] 122 | os: [linux] 123 | 124 | '@img/sharp-linuxmusl-arm64@0.33.5': 125 | resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} 126 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 127 | cpu: [arm64] 128 | os: [linux] 129 | 130 | '@img/sharp-linuxmusl-x64@0.33.5': 131 | resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} 132 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 133 | cpu: [x64] 134 | os: [linux] 135 | 136 | '@img/sharp-wasm32@0.33.5': 137 | resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} 138 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 139 | cpu: [wasm32] 140 | 141 | '@img/sharp-win32-ia32@0.33.5': 142 | resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} 143 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 144 | cpu: [ia32] 145 | os: [win32] 146 | 147 | '@img/sharp-win32-x64@0.33.5': 148 | resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} 149 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 150 | cpu: [x64] 151 | os: [win32] 152 | 153 | '@next/env@15.1.6': 154 | resolution: {integrity: sha512-d9AFQVPEYNr+aqokIiPLNK/MTyt3DWa/dpKveiAaVccUadFbhFEvY6FXYX2LJO2Hv7PHnLBu2oWwB4uBuHjr/w==} 155 | 156 | '@next/swc-darwin-arm64@15.1.6': 157 | resolution: {integrity: sha512-u7lg4Mpl9qWpKgy6NzEkz/w0/keEHtOybmIl0ykgItBxEM5mYotS5PmqTpo+Rhg8FiOiWgwr8USxmKQkqLBCrw==} 158 | engines: {node: '>= 10'} 159 | cpu: [arm64] 160 | os: [darwin] 161 | 162 | '@next/swc-darwin-x64@15.1.6': 163 | resolution: {integrity: sha512-x1jGpbHbZoZ69nRuogGL2MYPLqohlhnT9OCU6E6QFewwup+z+M6r8oU47BTeJcWsF2sdBahp5cKiAcDbwwK/lg==} 164 | engines: {node: '>= 10'} 165 | cpu: [x64] 166 | os: [darwin] 167 | 168 | '@next/swc-linux-arm64-gnu@15.1.6': 169 | resolution: {integrity: sha512-jar9sFw0XewXsBzPf9runGzoivajeWJUc/JkfbLTC4it9EhU8v7tCRLH7l5Y1ReTMN6zKJO0kKAGqDk8YSO2bg==} 170 | engines: {node: '>= 10'} 171 | cpu: [arm64] 172 | os: [linux] 173 | 174 | '@next/swc-linux-arm64-musl@15.1.6': 175 | resolution: {integrity: sha512-+n3u//bfsrIaZch4cgOJ3tXCTbSxz0s6brJtU3SzLOvkJlPQMJ+eHVRi6qM2kKKKLuMY+tcau8XD9CJ1OjeSQQ==} 176 | engines: {node: '>= 10'} 177 | cpu: [arm64] 178 | os: [linux] 179 | 180 | '@next/swc-linux-x64-gnu@15.1.6': 181 | resolution: {integrity: sha512-SpuDEXixM3PycniL4iVCLyUyvcl6Lt0mtv3am08sucskpG0tYkW1KlRhTgj4LI5ehyxriVVcfdoxuuP8csi3kQ==} 182 | engines: {node: '>= 10'} 183 | cpu: [x64] 184 | os: [linux] 185 | 186 | '@next/swc-linux-x64-musl@15.1.6': 187 | resolution: {integrity: sha512-L4druWmdFSZIIRhF+G60API5sFB7suTbDRhYWSjiw0RbE+15igQvE2g2+S973pMGvwN3guw7cJUjA/TmbPWTHQ==} 188 | engines: {node: '>= 10'} 189 | cpu: [x64] 190 | os: [linux] 191 | 192 | '@next/swc-win32-arm64-msvc@15.1.6': 193 | resolution: {integrity: sha512-s8w6EeqNmi6gdvM19tqKKWbCyOBvXFbndkGHl+c9YrzsLARRdCHsD9S1fMj8gsXm9v8vhC8s3N8rjuC/XrtkEg==} 194 | engines: {node: '>= 10'} 195 | cpu: [arm64] 196 | os: [win32] 197 | 198 | '@next/swc-win32-x64-msvc@15.1.6': 199 | resolution: {integrity: sha512-6xomMuu54FAFxttYr5PJbEfu96godcxBTRk1OhAvJq0/EnmFU/Ybiax30Snis4vdWZ9LGpf7Roy5fSs7v/5ROQ==} 200 | engines: {node: '>= 10'} 201 | cpu: [x64] 202 | os: [win32] 203 | 204 | '@swc/counter@0.1.3': 205 | resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} 206 | 207 | '@swc/helpers@0.5.15': 208 | resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} 209 | 210 | '@types/node@22.13.1': 211 | resolution: {integrity: sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==} 212 | 213 | '@types/react@19.0.8': 214 | resolution: {integrity: sha512-9P/o1IGdfmQxrujGbIMDyYaaCykhLKc0NGCtYcECNUr9UAaDe4gwvV9bR6tvd5Br1SG0j+PBpbKr2UYY8CwqSw==} 215 | 216 | busboy@1.6.0: 217 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} 218 | engines: {node: '>=10.16.0'} 219 | 220 | caniuse-lite@1.0.30001697: 221 | resolution: {integrity: sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ==} 222 | 223 | client-only@0.0.1: 224 | resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} 225 | 226 | color-convert@2.0.1: 227 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 228 | engines: {node: '>=7.0.0'} 229 | 230 | color-name@1.1.4: 231 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 232 | 233 | color-string@1.9.1: 234 | resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} 235 | 236 | color@4.2.3: 237 | resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} 238 | engines: {node: '>=12.5.0'} 239 | 240 | csstype@3.1.3: 241 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 242 | 243 | dequal@2.0.3: 244 | resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} 245 | engines: {node: '>=6'} 246 | 247 | detect-libc@2.0.3: 248 | resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} 249 | engines: {node: '>=8'} 250 | 251 | is-arrayish@0.3.2: 252 | resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} 253 | 254 | nanoid@3.3.8: 255 | resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} 256 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 257 | hasBin: true 258 | 259 | next@15.1.6: 260 | resolution: {integrity: sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==} 261 | engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} 262 | hasBin: true 263 | peerDependencies: 264 | '@opentelemetry/api': ^1.1.0 265 | '@playwright/test': ^1.41.2 266 | babel-plugin-react-compiler: '*' 267 | react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 268 | react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 269 | sass: ^1.3.0 270 | peerDependenciesMeta: 271 | '@opentelemetry/api': 272 | optional: true 273 | '@playwright/test': 274 | optional: true 275 | babel-plugin-react-compiler: 276 | optional: true 277 | sass: 278 | optional: true 279 | 280 | picocolors@1.1.1: 281 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 282 | 283 | postcss@8.4.31: 284 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} 285 | engines: {node: ^10 || ^12 || >=14} 286 | 287 | react-dom@19.0.0: 288 | resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} 289 | peerDependencies: 290 | react: ^19.0.0 291 | 292 | react@19.0.0: 293 | resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} 294 | engines: {node: '>=0.10.0'} 295 | 296 | scheduler@0.25.0: 297 | resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} 298 | 299 | semver@7.7.1: 300 | resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} 301 | engines: {node: '>=10'} 302 | hasBin: true 303 | 304 | sharp@0.33.5: 305 | resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} 306 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 307 | 308 | simple-swizzle@0.2.2: 309 | resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} 310 | 311 | source-map-js@1.2.1: 312 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 313 | engines: {node: '>=0.10.0'} 314 | 315 | streamsearch@1.1.0: 316 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} 317 | engines: {node: '>=10.0.0'} 318 | 319 | styled-jsx@5.1.6: 320 | resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} 321 | engines: {node: '>= 12.0.0'} 322 | peerDependencies: 323 | '@babel/core': '*' 324 | babel-plugin-macros: '*' 325 | react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' 326 | peerDependenciesMeta: 327 | '@babel/core': 328 | optional: true 329 | babel-plugin-macros: 330 | optional: true 331 | 332 | sweetalert2-react-content@5.1.0: 333 | resolution: {integrity: sha512-SBh41SdyHDY9NzwrIG6LACbClCMxIlEFP86tGVr/B4zGD4H2gGXB8o7UAJRc/RtBd/iQL9hIvuCAkrk0AgKEMA==} 334 | peerDependencies: 335 | react: ^18.0.0 || ^19.0.0 336 | react-dom: ^18.0.0 || ^19.0.0 337 | sweetalert2: ^11.0.0 338 | 339 | sweetalert2@11.15.10: 340 | resolution: {integrity: sha512-Sjiwcd5mWiz8X0JFkHsso2EPVQHrLCjVv+xR6Ry2LKf4KY6kSi4U5pM0Tgmn1c7SMfkyDqPal2NWqwj6vck8bw==} 341 | 342 | swr@2.3.2: 343 | resolution: {integrity: sha512-RosxFpiabojs75IwQ316DGoDRmOqtiAj0tg8wCcbEu4CiLZBs/a9QNtHV7TUfDXmmlgqij/NqzKq/eLelyv9xA==} 344 | peerDependencies: 345 | react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 346 | 347 | tslib@2.8.1: 348 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 349 | 350 | typescript@5.7.3: 351 | resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} 352 | engines: {node: '>=14.17'} 353 | hasBin: true 354 | 355 | undici-types@6.20.0: 356 | resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} 357 | 358 | use-sync-external-store@1.4.0: 359 | resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} 360 | peerDependencies: 361 | react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 362 | 363 | snapshots: 364 | 365 | '@emnapi/runtime@1.3.1': 366 | dependencies: 367 | tslib: 2.8.1 368 | optional: true 369 | 370 | '@img/sharp-darwin-arm64@0.33.5': 371 | optionalDependencies: 372 | '@img/sharp-libvips-darwin-arm64': 1.0.4 373 | optional: true 374 | 375 | '@img/sharp-darwin-x64@0.33.5': 376 | optionalDependencies: 377 | '@img/sharp-libvips-darwin-x64': 1.0.4 378 | optional: true 379 | 380 | '@img/sharp-libvips-darwin-arm64@1.0.4': 381 | optional: true 382 | 383 | '@img/sharp-libvips-darwin-x64@1.0.4': 384 | optional: true 385 | 386 | '@img/sharp-libvips-linux-arm64@1.0.4': 387 | optional: true 388 | 389 | '@img/sharp-libvips-linux-arm@1.0.5': 390 | optional: true 391 | 392 | '@img/sharp-libvips-linux-s390x@1.0.4': 393 | optional: true 394 | 395 | '@img/sharp-libvips-linux-x64@1.0.4': 396 | optional: true 397 | 398 | '@img/sharp-libvips-linuxmusl-arm64@1.0.4': 399 | optional: true 400 | 401 | '@img/sharp-libvips-linuxmusl-x64@1.0.4': 402 | optional: true 403 | 404 | '@img/sharp-linux-arm64@0.33.5': 405 | optionalDependencies: 406 | '@img/sharp-libvips-linux-arm64': 1.0.4 407 | optional: true 408 | 409 | '@img/sharp-linux-arm@0.33.5': 410 | optionalDependencies: 411 | '@img/sharp-libvips-linux-arm': 1.0.5 412 | optional: true 413 | 414 | '@img/sharp-linux-s390x@0.33.5': 415 | optionalDependencies: 416 | '@img/sharp-libvips-linux-s390x': 1.0.4 417 | optional: true 418 | 419 | '@img/sharp-linux-x64@0.33.5': 420 | optionalDependencies: 421 | '@img/sharp-libvips-linux-x64': 1.0.4 422 | optional: true 423 | 424 | '@img/sharp-linuxmusl-arm64@0.33.5': 425 | optionalDependencies: 426 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 427 | optional: true 428 | 429 | '@img/sharp-linuxmusl-x64@0.33.5': 430 | optionalDependencies: 431 | '@img/sharp-libvips-linuxmusl-x64': 1.0.4 432 | optional: true 433 | 434 | '@img/sharp-wasm32@0.33.5': 435 | dependencies: 436 | '@emnapi/runtime': 1.3.1 437 | optional: true 438 | 439 | '@img/sharp-win32-ia32@0.33.5': 440 | optional: true 441 | 442 | '@img/sharp-win32-x64@0.33.5': 443 | optional: true 444 | 445 | '@next/env@15.1.6': {} 446 | 447 | '@next/swc-darwin-arm64@15.1.6': 448 | optional: true 449 | 450 | '@next/swc-darwin-x64@15.1.6': 451 | optional: true 452 | 453 | '@next/swc-linux-arm64-gnu@15.1.6': 454 | optional: true 455 | 456 | '@next/swc-linux-arm64-musl@15.1.6': 457 | optional: true 458 | 459 | '@next/swc-linux-x64-gnu@15.1.6': 460 | optional: true 461 | 462 | '@next/swc-linux-x64-musl@15.1.6': 463 | optional: true 464 | 465 | '@next/swc-win32-arm64-msvc@15.1.6': 466 | optional: true 467 | 468 | '@next/swc-win32-x64-msvc@15.1.6': 469 | optional: true 470 | 471 | '@swc/counter@0.1.3': {} 472 | 473 | '@swc/helpers@0.5.15': 474 | dependencies: 475 | tslib: 2.8.1 476 | 477 | '@types/node@22.13.1': 478 | dependencies: 479 | undici-types: 6.20.0 480 | 481 | '@types/react@19.0.8': 482 | dependencies: 483 | csstype: 3.1.3 484 | 485 | busboy@1.6.0: 486 | dependencies: 487 | streamsearch: 1.1.0 488 | 489 | caniuse-lite@1.0.30001697: {} 490 | 491 | client-only@0.0.1: {} 492 | 493 | color-convert@2.0.1: 494 | dependencies: 495 | color-name: 1.1.4 496 | optional: true 497 | 498 | color-name@1.1.4: 499 | optional: true 500 | 501 | color-string@1.9.1: 502 | dependencies: 503 | color-name: 1.1.4 504 | simple-swizzle: 0.2.2 505 | optional: true 506 | 507 | color@4.2.3: 508 | dependencies: 509 | color-convert: 2.0.1 510 | color-string: 1.9.1 511 | optional: true 512 | 513 | csstype@3.1.3: {} 514 | 515 | dequal@2.0.3: {} 516 | 517 | detect-libc@2.0.3: 518 | optional: true 519 | 520 | is-arrayish@0.3.2: 521 | optional: true 522 | 523 | nanoid@3.3.8: {} 524 | 525 | next@15.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0): 526 | dependencies: 527 | '@next/env': 15.1.6 528 | '@swc/counter': 0.1.3 529 | '@swc/helpers': 0.5.15 530 | busboy: 1.6.0 531 | caniuse-lite: 1.0.30001697 532 | postcss: 8.4.31 533 | react: 19.0.0 534 | react-dom: 19.0.0(react@19.0.0) 535 | styled-jsx: 5.1.6(react@19.0.0) 536 | optionalDependencies: 537 | '@next/swc-darwin-arm64': 15.1.6 538 | '@next/swc-darwin-x64': 15.1.6 539 | '@next/swc-linux-arm64-gnu': 15.1.6 540 | '@next/swc-linux-arm64-musl': 15.1.6 541 | '@next/swc-linux-x64-gnu': 15.1.6 542 | '@next/swc-linux-x64-musl': 15.1.6 543 | '@next/swc-win32-arm64-msvc': 15.1.6 544 | '@next/swc-win32-x64-msvc': 15.1.6 545 | sharp: 0.33.5 546 | transitivePeerDependencies: 547 | - '@babel/core' 548 | - babel-plugin-macros 549 | 550 | picocolors@1.1.1: {} 551 | 552 | postcss@8.4.31: 553 | dependencies: 554 | nanoid: 3.3.8 555 | picocolors: 1.1.1 556 | source-map-js: 1.2.1 557 | 558 | react-dom@19.0.0(react@19.0.0): 559 | dependencies: 560 | react: 19.0.0 561 | scheduler: 0.25.0 562 | 563 | react@19.0.0: {} 564 | 565 | scheduler@0.25.0: {} 566 | 567 | semver@7.7.1: 568 | optional: true 569 | 570 | sharp@0.33.5: 571 | dependencies: 572 | color: 4.2.3 573 | detect-libc: 2.0.3 574 | semver: 7.7.1 575 | optionalDependencies: 576 | '@img/sharp-darwin-arm64': 0.33.5 577 | '@img/sharp-darwin-x64': 0.33.5 578 | '@img/sharp-libvips-darwin-arm64': 1.0.4 579 | '@img/sharp-libvips-darwin-x64': 1.0.4 580 | '@img/sharp-libvips-linux-arm': 1.0.5 581 | '@img/sharp-libvips-linux-arm64': 1.0.4 582 | '@img/sharp-libvips-linux-s390x': 1.0.4 583 | '@img/sharp-libvips-linux-x64': 1.0.4 584 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 585 | '@img/sharp-libvips-linuxmusl-x64': 1.0.4 586 | '@img/sharp-linux-arm': 0.33.5 587 | '@img/sharp-linux-arm64': 0.33.5 588 | '@img/sharp-linux-s390x': 0.33.5 589 | '@img/sharp-linux-x64': 0.33.5 590 | '@img/sharp-linuxmusl-arm64': 0.33.5 591 | '@img/sharp-linuxmusl-x64': 0.33.5 592 | '@img/sharp-wasm32': 0.33.5 593 | '@img/sharp-win32-ia32': 0.33.5 594 | '@img/sharp-win32-x64': 0.33.5 595 | optional: true 596 | 597 | simple-swizzle@0.2.2: 598 | dependencies: 599 | is-arrayish: 0.3.2 600 | optional: true 601 | 602 | source-map-js@1.2.1: {} 603 | 604 | streamsearch@1.1.0: {} 605 | 606 | styled-jsx@5.1.6(react@19.0.0): 607 | dependencies: 608 | client-only: 0.0.1 609 | react: 19.0.0 610 | 611 | sweetalert2-react-content@5.1.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sweetalert2@11.15.10): 612 | dependencies: 613 | react: 19.0.0 614 | react-dom: 19.0.0(react@19.0.0) 615 | sweetalert2: 11.15.10 616 | 617 | sweetalert2@11.15.10: {} 618 | 619 | swr@2.3.2(react@19.0.0): 620 | dependencies: 621 | dequal: 2.0.3 622 | react: 19.0.0 623 | use-sync-external-store: 1.4.0(react@19.0.0) 624 | 625 | tslib@2.8.1: {} 626 | 627 | typescript@5.7.3: {} 628 | 629 | undici-types@6.20.0: {} 630 | 631 | use-sync-external-store@1.4.0(react@19.0.0): 632 | dependencies: 633 | react: 19.0.0 634 | -------------------------------------------------------------------------------- /styled-jsx.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": false, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve", 20 | "incremental": true 21 | }, 22 | "include": [ 23 | "next-env.d.ts", 24 | "**/*.ts", 25 | "**/*.tsx" 26 | ], 27 | "exclude": [ 28 | "node_modules" 29 | ] 30 | } 31 | --------------------------------------------------------------------------------