├── .dev.vars.example ├── .editorconfig ├── .gitignore ├── .prettierrc ├── .vscode └── settings.json ├── README.md ├── backups └── .gitignore ├── migrations ├── 0001_users_add_regip.sql ├── 0002_users_add_lastip.sql ├── 0003_grab_one_year.sql ├── 0NaN_create_deposits_table.sql ├── 0NaN_create_domains_table.sql ├── 0NaN_create_sessions_table.sql ├── 0NaN_create_user_resets_table.sql └── 0NaN_create_users_table.sql ├── package.json ├── src ├── Badwords.ts ├── d │ ├── Env.ts │ └── Models.ts ├── index.ts ├── lib │ ├── aes.ts │ ├── dnspod.ts │ ├── epusdt.ts │ ├── loginSession.ts │ ├── readRequestBody.ts │ ├── readRequestQuery.ts │ ├── recaptchaChallange.ts │ ├── sendmail.ts │ ├── totp.ts │ └── uuid.ts ├── pages │ └── dashboard │ │ └── logout.ts └── template │ ├── auth │ ├── login-mfa.html │ ├── login.html │ ├── mfa-recovery.html │ ├── register.html │ └── reset.html │ ├── common │ ├── auth │ │ ├── footer.html │ │ └── header.html │ ├── footer.html │ ├── header.html │ └── recaptcha.html │ ├── dashboard │ ├── common │ │ └── banner.html │ ├── credit.html │ ├── domains.html │ ├── index.html │ ├── livechat.html │ └── reg-domain.html │ ├── email │ ├── activation.html │ └── mfa-recovery.html │ ├── index.html │ ├── resources │ ├── 1.html │ ├── news.html │ ├── privacy.html │ ├── registrars.html │ ├── term-of-service.html │ └── use-cases.html │ ├── support │ └── report-abuse.html │ └── whois-lookup.html ├── tsconfig.json ├── wrangler.toml └── yarn.lock /.dev.vars.example: -------------------------------------------------------------------------------- 1 | APP_ENV="local" 2 | AES_KEY="" 3 | APP_URL="http://127.0.0.1:8787" 4 | DNSPOD_API_ID="" 5 | DNSPOD_API_TOKEN="" 6 | DNSPOD_DOMAIN_ID="" 7 | EPUSDT_API_KEY="" 8 | EPUSDT_API_URL="" 9 | RECAPTCHA_SECRET_KEY="" 10 | RECAPTCHA_SITE_KEY="" 11 | BREVO_PREFER="auto" 12 | BREVO=[ {"apiKey": "", "senderName": "No reply", "senderAddress": "**"}, {"apiKey": "", "senderName": "No reply", "senderAddress": "**"} ] 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = tab 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.yml] 12 | indent_style = space 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | 3 | logs 4 | _.log 5 | npm-debug.log_ 6 | yarn-debug.log* 7 | yarn-error.log* 8 | lerna-debug.log* 9 | .pnpm-debug.log* 10 | 11 | # Diagnostic reports (https://nodejs.org/api/report.html) 12 | 13 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 14 | 15 | # Runtime data 16 | 17 | pids 18 | _.pid 19 | _.seed 20 | \*.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | 28 | coverage 29 | \*.lcov 30 | 31 | # nyc test coverage 32 | 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 36 | 37 | .grunt 38 | 39 | # Bower dependency directory (https://bower.io/) 40 | 41 | bower_components 42 | 43 | # node-waf configuration 44 | 45 | .lock-wscript 46 | 47 | # Compiled binary addons (https://nodejs.org/api/addons.html) 48 | 49 | build/Release 50 | 51 | # Dependency directories 52 | 53 | node_modules/ 54 | jspm_packages/ 55 | 56 | # Snowpack dependency directory (https://snowpack.dev/) 57 | 58 | web_modules/ 59 | 60 | # TypeScript cache 61 | 62 | \*.tsbuildinfo 63 | 64 | # Optional npm cache directory 65 | 66 | .npm 67 | 68 | # Optional eslint cache 69 | 70 | .eslintcache 71 | 72 | # Optional stylelint cache 73 | 74 | .stylelintcache 75 | 76 | # Microbundle cache 77 | 78 | .rpt2_cache/ 79 | .rts2_cache_cjs/ 80 | .rts2_cache_es/ 81 | .rts2_cache_umd/ 82 | 83 | # Optional REPL history 84 | 85 | .node_repl_history 86 | 87 | # Output of 'npm pack' 88 | 89 | \*.tgz 90 | 91 | # Yarn Integrity file 92 | 93 | .yarn-integrity 94 | 95 | # dotenv environment variable files 96 | 97 | .env 98 | .env.development.local 99 | .env.test.local 100 | .env.production.local 101 | .env.local 102 | 103 | # parcel-bundler cache (https://parceljs.org/) 104 | 105 | .cache 106 | .parcel-cache 107 | 108 | # Next.js build output 109 | 110 | .next 111 | out 112 | 113 | # Nuxt.js build / generate output 114 | 115 | .nuxt 116 | dist 117 | 118 | # Gatsby files 119 | 120 | .cache/ 121 | 122 | # Comment in the public line in if your project uses Gatsby and not Next.js 123 | 124 | # https://nextjs.org/blog/next-9-1#public-directory-support 125 | 126 | # public 127 | 128 | # vuepress build output 129 | 130 | .vuepress/dist 131 | 132 | # vuepress v2.x temp and cache directory 133 | 134 | .temp 135 | .cache 136 | 137 | # Docusaurus cache and generated files 138 | 139 | .docusaurus 140 | 141 | # Serverless directories 142 | 143 | .serverless/ 144 | 145 | # FuseBox cache 146 | 147 | .fusebox/ 148 | 149 | # DynamoDB Local files 150 | 151 | .dynamodb/ 152 | 153 | # TernJS port file 154 | 155 | .tern-port 156 | 157 | # Stores VSCode versions used for testing VSCode extensions 158 | 159 | .vscode-test 160 | 161 | # yarn v2 162 | 163 | .yarn/cache 164 | .yarn/unplugged 165 | .yarn/build-state.yml 166 | .yarn/install-state.gz 167 | .pnp.\* 168 | 169 | # wrangler project 170 | 171 | .dev.vars 172 | .wrangler/ 173 | 174 | .DS_Store 175 | .bak 176 | Thumbs.db 177 | 178 | backup.sql 179 | backups -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 140, 3 | "singleQuote": true, 4 | "semi": true, 5 | "useTabs": true 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.indentSize": 2 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Opensource Domain-Name Registry 2 | 3 | An opensource domain-name registry based on cloudflare workers + d1 database + dnspod.com API! 4 | 5 | ## Nodejs + Yarn Install 6 | 7 | ``` 8 | yarn 9 | ``` 10 | 11 | ## Install wrangler 12 | 13 | https://developers.cloudflare.com/workers/wrangler/install-and-update/ 14 | 15 | 16 | ## Local development 17 | 18 | ``` 19 | wrangler d1 migrations apply DB 20 | ``` 21 | 22 | 23 | ``` 24 | yarn dev 25 | ``` 26 | 27 | 28 | ## Deploy to production 29 | 30 | ### D1 Database 31 | 32 | Create a database, import `migration/table.sql`. change db id and other informations in `wrangler.toml`. 33 | 34 | ### Workers 35 | 36 | Create a worker. 37 | 38 | import those variables into secrets: 39 | ``` 40 | APP_ENV="production" 41 | AES_KEY="random aes key" 42 | APP_URL="https://your-domain" 43 | DNSPOD_API_ID="get it at DNSPOD.com" 44 | DNSPOD_API_TOKEN="" 45 | DNSPOD_DOMAIN_ID="" 46 | EPUSDT_API_KEY="" 47 | EPUSDT_API_URL="" 48 | RECAPTCHA_SITE_KEY="get it at www.google.com/recaptcha" 49 | RECAPTCHA_SECRET_KEY="" 50 | BREVO_PREFER="auto" 51 | BREVO=[ {"apiKey": "get it at BREVO.com", "senderName": "No reply", "senderAddress": "**"}, {"apiKey": "get it at BREVO.com", "senderName": "No reply", "senderAddress": "**"} ] 52 | ``` 53 | 54 | ### Deploy 55 | 56 | 57 | and bash execute 58 | ``` 59 | yarn deploy 60 | ``` 61 | 62 | ## License 63 | 64 | MIT 65 | -------------------------------------------------------------------------------- /backups/.gitignore: -------------------------------------------------------------------------------- 1 | * -------------------------------------------------------------------------------- /migrations/0001_users_add_regip.sql: -------------------------------------------------------------------------------- 1 | -- Migration number: 0001 2024-06-25T18:14:17.868Z 2 | 3 | -- Add regip column to users table 4 | ALTER TABLE users ADD COLUMN regip VARCHAR(39); 5 | -- Add unique index 6 | CREATE UNIQUE INDEX users_regip ON users (regip); 7 | -------------------------------------------------------------------------------- /migrations/0002_users_add_lastip.sql: -------------------------------------------------------------------------------- 1 | -- Migration number: 0002 2024-06-25T18:19:54.313Z 2 | 3 | -- Add lastip column to users table 4 | ALTER TABLE users ADD COLUMN lastip VARCHAR(39); 5 | -- Add unique index 6 | CREATE UNIQUE INDEX lastip ON users (lastip); 7 | -------------------------------------------------------------------------------- /migrations/0003_grab_one_year.sql: -------------------------------------------------------------------------------- 1 | -- Migration number: 0003 2025-05-13T13:38:42.440Z 2 | 3 | CREATE TABLE [free_one_year] ("id" text PRIMARY KEY,"domain" text,"created_at"); 4 | -------------------------------------------------------------------------------- /migrations/0NaN_create_deposits_table.sql: -------------------------------------------------------------------------------- 1 | -- Migration number: 0NaN 2024-06-17T13:22:59.212Z 2 | CREATE TABLE [deposits] ("id" text PRIMARY KEY,"user_id" text,"amount" text,"usdt_address" text,"usdt_amount" text, `status` integer AFTER `amount` COMMENT "0:Unpaid 1:Paid", `created_at` integer, `paid_at` integer); 3 | CREATE INDEX idx_deposits_created_at ON deposits(created_at); 4 | CREATE INDEX idx_deposits_user_id ON deposits(user_id); 5 | CREATE INDEX idx_deposits_usdt_address ON deposits(usdt_address); 6 | CREATE INDEX idx_deposits_amount ON deposits(amount); 7 | CREATE INDEX idx_deposits_status ON deposits(status); 8 | CREATE INDEX idx_deposits_paid_at ON deposits(paid_at); 9 | -------------------------------------------------------------------------------- /migrations/0NaN_create_domains_table.sql: -------------------------------------------------------------------------------- 1 | -- Migration number: 0NaN 2024-06-17T13:21:24.687Z 2 | CREATE TABLE [domains] ("id" text PRIMARY KEY,"user_id" integer,"domain" text,"status" integer,"ns_servers" text,"expires_at" integer,"created_at" integer,"updated_at" integer, type text COMMENT "free: Free domain, vip: Paid domain"); 3 | CREATE UNIQUE INDEX idx_domains_domain ON domains(domain); 4 | CREATE INDEX idx_domains_status ON domains(status); 5 | CREATE INDEX idx_domains_expires_at ON domains(expires_at); 6 | CREATE INDEX idx_domains_created_at ON domains(created_at); 7 | CREATE INDEX idx_domains_type ON domains(type); 8 | -------------------------------------------------------------------------------- /migrations/0NaN_create_sessions_table.sql: -------------------------------------------------------------------------------- 1 | -- Migration number: 0NaN 2024-06-17T13:22:32.656Z 2 | CREATE TABLE [sessions] ("id" text PRIMARY KEY,"user_id" integer,"expires_at" integer); 3 | CREATE INDEX idx_sessions_user_id ON sessions(user_id); 4 | CREATE INDEX idx_sessions_expires_at ON sessions(expires_at); -------------------------------------------------------------------------------- /migrations/0NaN_create_user_resets_table.sql: -------------------------------------------------------------------------------- 1 | -- Migration number: 0NaN 2024-06-24T02:30:58.873Z 2 | CREATE TABLE [user_resets] ("id" text PRIMARY KEY,"user_id" text,"used_at" integer,"created_at" integer,"updated_at" integer); 3 | CREATE INDEX idx_user_resets_user_id ON user_resets(user_id); 4 | -------------------------------------------------------------------------------- /migrations/0NaN_create_users_table.sql: -------------------------------------------------------------------------------- 1 | -- Migration number: 0NaN 2024-06-17T13:20:58.873Z 2 | CREATE TABLE [users] ("id" text PRIMARY KEY,"email" text,"mfa_secret" text,"credit" integer DEFAULT 0,"total_spent" integer DEFAULT 0,"created_at" integer,"updated_at" integer); 3 | CREATE UNIQUE INDEX idx_users_email ON users(email); 4 | CREATE INDEX idx_users_mfa_secret ON users(mfa_secret); 5 | CREATE INDEX idx_users_created_at ON users(created_at); 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "registry", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "deploy": "wrangler deploy", 7 | "dev": "wrangler dev", 8 | "start": "wrangler dev", 9 | "db-backup-remote": "wrangler d1 export registry --remote --output=./backup.sql", 10 | "db-import-remote": "wrangler d1 execute --remote DB --file=backup.sql", 11 | "db-import-local": "wrangler d1 execute --local DB --file=backup.sql" 12 | }, 13 | "dependencies": {}, 14 | "devDependencies": { 15 | "@cloudflare/workers-types": "^v1.22.22", 16 | "itty-router": "v4.0.23", 17 | "wrangler": "4" 18 | }, 19 | "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" 20 | } 21 | -------------------------------------------------------------------------------- /src/Badwords.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | '@', 3 | 'www', 4 | 'nic', 5 | 'net', 6 | ]; 7 | -------------------------------------------------------------------------------- /src/d/Env.ts: -------------------------------------------------------------------------------- 1 | import { Sender } from "./Models"; 2 | 3 | export interface Env { 4 | // If you set another name in wrangler.toml as the value for 'binding', 5 | // replace "DB" with the variable name you defined. 6 | DB: D1Database; 7 | APP_ENV: 'dev' | 'production'; 8 | APP_URL: string; 9 | DNSPOD_API_ID: string; 10 | DNSPOD_API_TOKEN: string; 11 | DNSPOD_DOMAIN_ID: string; 12 | AES_KEY: string; 13 | EPUSDT_API_KEY: string; 14 | EPUSDT_API_URL: string; 15 | RECAPTCHA_SITE_KEY: string; 16 | RECAPTCHA_SECRET_KEY: string; 17 | BREVO: Sender[]; 18 | BREVO_PREFER: 1 | 2 | 'auto'; 19 | BREVO_API_KEY: string; 20 | MAIL_SENDER_ADDRESS: string; 21 | MAIL_SENDER_NAME: string; 22 | BREVO_API_KEY_2: string; 23 | MAIL_SENDER_ADDRESS_2: string; 24 | MAIL_SENDER_NAME_2: string; 25 | } 26 | -------------------------------------------------------------------------------- /src/d/Models.ts: -------------------------------------------------------------------------------- 1 | export enum DomainStatus { 2 | OK = 1, 3 | Pending, 4 | ClientHold, 5 | ServerHold, 6 | Redemption, 7 | PendingDelete, 8 | PendingTransfer, 9 | PendingUpdate, 10 | PendingRenewal, 11 | }; 12 | 13 | export const DomainStatusOK = 1; 14 | export const DomainStatusPending = 2; 15 | export const DomainStatusClientHold = 3; 16 | export const DomainStatusServerHold = 4; 17 | export const DomainStatusRedemption = 5; // w/i 30 18 | export const DomainStatusPendingDelete = 6; // w/i 60 19 | export const DomainStatusPendingTransfer = 7; 20 | export const DomainStatusPendingUpdate = 8; 21 | export const DomainStatusPendingRenewal = 9; 22 | 23 | type ValueOf = T[keyof T]; 24 | type ArrayElement = ArrayType extends readonly (infer ElementType)[] ? ElementType : never; 25 | 26 | export const DomainRenewPeriodOptions = [180, 365, 730, 1095]; 27 | export type DomainRenewPeriodOptions = [180, 365, 730, 1095]; 28 | export type DomainRenewPeriodOptionsType = ArrayElement; 29 | 30 | export interface Domain { 31 | id: string; 32 | user_id: string; 33 | domain: string; 34 | status: DomainStatus; 35 | ns_servers: string; 36 | type: 'free' | 'vip'; 37 | created_at: number; 38 | expires_at: number; 39 | updated_at: null | number; 40 | contact?: string; 41 | } 42 | 43 | export interface User { 44 | id: string; 45 | email: string; 46 | mfa_secret: string; 47 | credit: number; 48 | total_spent: number; 49 | created_at: number; 50 | updated_at: null | number; 51 | } 52 | 53 | export interface Sender { apiKey: string; senderName: string; senderAddress: string; }; 54 | -------------------------------------------------------------------------------- /src/lib/aes.ts: -------------------------------------------------------------------------------- 1 | export async function encryptData(key, data) { 2 | const iv = crypto.getRandomValues(new Uint8Array(12)); // Initialization Vector 3 | const encoder = new TextEncoder(); 4 | const encodedData = encoder.encode(data); 5 | 6 | const encryptedData = await crypto.subtle.encrypt( 7 | { 8 | name: "AES-GCM", 9 | iv: iv, 10 | }, 11 | await importKeyFromString(key, `encryptData()`), 12 | encodedData 13 | ); 14 | 15 | return { 16 | iv: iv, 17 | data: new Uint8Array(encryptedData), 18 | }; 19 | } 20 | 21 | export async function decryptData(key, encryptedData, iv) { 22 | const decryptedData = await crypto.subtle.decrypt( 23 | { 24 | name: "AES-GCM", 25 | iv: iv, 26 | }, 27 | await importKeyFromString(key, `decryptData()`), 28 | encryptedData 29 | ); 30 | 31 | const decoder = new TextDecoder(); 32 | return decoder.decode(decryptedData); 33 | } 34 | 35 | export function bufferToHex(buffer) { 36 | return [...new Uint8Array(buffer)] 37 | .map(b => b.toString(16).padStart(2, '0')) 38 | .join(''); 39 | } 40 | 41 | export function hexToBuffer(hexString) { 42 | if (hexString.length % 2 !== 0) { 43 | throw new Error("Invalid hex string"); 44 | } 45 | 46 | const buffer = new Uint8Array(hexString.length / 2); 47 | for (let i = 0; i < hexString.length; i += 2) { 48 | buffer[i / 2] = parseInt(hexString.substr(i, 2), 16); 49 | } 50 | return buffer; 51 | } 52 | 53 | export async function exportKeyToString(key) { 54 | const exportedKey = await crypto.subtle.exportKey('raw', key); 55 | return bufferToHex(exportedKey); 56 | } 57 | 58 | export async function importKeyFromString(keyString, caller) { 59 | const keyBuffer = hexToBuffer(keyString); 60 | const key = await crypto.subtle.importKey( 61 | 'raw', 62 | keyBuffer, 63 | { 64 | name: 'AES-GCM', 65 | }, 66 | true, 67 | ['encrypt', 'decrypt'] 68 | ); 69 | return key; 70 | } 71 | -------------------------------------------------------------------------------- /src/lib/dnspod.ts: -------------------------------------------------------------------------------- 1 | import { Env } from "../d/Env"; 2 | 3 | const apiBase = `https://api.dnspod.com` 4 | 5 | export async function createNsRecord(env: Env, subdomain: string, dnsservers: string[]): Promise { 6 | if (env.APP_ENV != 'production') { 7 | return true; 8 | } 9 | 10 | const url = `${apiBase}/Record.Create`; 11 | 12 | dnsservers.forEach(async (dnsserver, index) => { 13 | const json = await fetch(url, { 14 | method: 'POST', 15 | headers: { 16 | 'Content-Type': 'application/x-www-form-urlencoded', 17 | }, 18 | body: [ 19 | `login_token=${env.DNSPOD_API_ID},${env.DNSPOD_API_TOKEN}`, 20 | `format=json`, 21 | `domain_id=${env.DNSPOD_DOMAIN_ID}`, 22 | `sub_domain=${subdomain}`, 23 | `record_type=NS`, 24 | `value=${dnsserver}`, 25 | `record_line=default`, 26 | `ttl=3600`, 27 | ].join(`&`), 28 | }) 29 | }); 30 | 31 | return true; 32 | }; 33 | 34 | export async function getNsRecord(env: Env, subdomain: string): Promise { 35 | const url = `${apiBase}/Record.List` 36 | return await fetch(url, { 37 | method: 'POST', 38 | headers: { 39 | 'Content-Type': 'application/x-www-form-urlencoded', 40 | }, 41 | body: [ 42 | `login_token=${env.DNSPOD_API_ID},${env.DNSPOD_API_TOKEN}`, 43 | `format=json`, 44 | `domain_id=${env.DNSPOD_DOMAIN_ID}`, 45 | `sub_domain=${subdomain}`, 46 | `offset=0`, 47 | `length=500`, 48 | ].join(`&`), 49 | }) 50 | .then(res => <{records: any[]}> res.json()).then(json => json.records); 51 | }; 52 | 53 | 54 | export async function deleteNsRecord(env: Env, subdomain: string) { 55 | if (env.APP_ENV != 'production') { 56 | return true; 57 | } 58 | 59 | const records = await getNsRecord(env, subdomain); 60 | if (!records || typeof records.length === 'undefined') { 61 | return true; 62 | } 63 | records.forEach(async (record: any) => { 64 | const url = `${apiBase}/Record.Remove`; 65 | const json = await fetch(url, { 66 | method: 'POST', 67 | headers: { 68 | 'Content-Type': 'application/x-www-form-urlencoded', 69 | }, 70 | body: [ 71 | `login_token=${env.DNSPOD_API_ID},${env.DNSPOD_API_TOKEN}`, 72 | `format=json`, 73 | `domain_id=${env.DNSPOD_DOMAIN_ID}`, 74 | `record_id=${record.id}`, 75 | ].join(`&`), 76 | }) 77 | }) 78 | }; 79 | 80 | export async function updateNsRecord(env: Env, subdomain: string, dnsservers: string[]) { 81 | await deleteNsRecord(env, subdomain); 82 | return await createNsRecord(env, subdomain, dnsservers); 83 | }; 84 | 85 | -------------------------------------------------------------------------------- /src/lib/epusdt.ts: -------------------------------------------------------------------------------- 1 | class Epusdt { 2 | baseUrl: string; 3 | signKey: string; 4 | 5 | constructor(url: string, signKey: string) { 6 | this.baseUrl = url; 7 | this.signKey = signKey; 8 | } 9 | 10 | async sign(parameters: {[key: string]: string|number}, signKey: string): Promise { 11 | const keys = Object.keys(parameters).sort(); 12 | let sign = ''; 13 | let urls = ''; 14 | 15 | keys.forEach(key => { 16 | const val = parameters[key]; 17 | if (val === '' || key === 'signature') return; 18 | 19 | if (sign !== '') { 20 | sign += '&'; 21 | urls += '&'; 22 | } 23 | 24 | sign += `${key}=${val}`; 25 | urls += `${key}=${encodeURIComponent(val)}`; 26 | }); 27 | 28 | const data = new TextEncoder().encode(sign + signKey); 29 | const hashBuffer = await crypto.subtle.digest('MD5', data); 30 | const hashArray = Array.from(new Uint8Array(hashBuffer)); 31 | const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); 32 | return hashHex; 33 | } 34 | 35 | async makeCall(url: string, parameter: {[key: string]: string|number}): Promise { 36 | parameter.signature = await this.sign(parameter, this.signKey); 37 | try { 38 | const response = await fetch(this.baseUrl + url, { 39 | method: 'POST', 40 | headers: { 41 | 'Content-Type': 'application/json' 42 | }, 43 | body: JSON.stringify(parameter) 44 | }); 45 | 46 | const resp = <{status: Number; status_code: Number; message: string; data: any;}> await response.json(); 47 | 48 | if (response.status !== 200 || resp.status_code !== 200) { 49 | throw new Error(resp.message); 50 | } 51 | 52 | return resp.data; 53 | } catch (error) { 54 | throw new Error(`HTTP error: ${error.message}`); 55 | } 56 | } 57 | 58 | async createTransaction(orderNumber: string, cnyAmount: number, notifyUrl: string): Promise { 59 | const parameter = { 60 | order_id: orderNumber, 61 | amount: parseFloat(parseFloat( cnyAmount).toFixed(2)), 62 | notify_url: notifyUrl, 63 | redirect_url: notifyUrl 64 | }; 65 | 66 | return await this.makeCall('/api/v1/order/create-transaction', parameter); 67 | } 68 | 69 | async notify(request: Request, callback: (request: Request) => any): Promise { 70 | const json = await request.clone().json(); 71 | const assertSignature = await this.sign(json, this.signKey); 72 | const realSignature = json.signature; 73 | 74 | if (assertSignature !== realSignature) { 75 | throw new Error('Signature mismatch'); 76 | } 77 | 78 | const callbackResult = await callback(request); 79 | if (!callbackResult) { 80 | throw new Error('Callback processing failed'); 81 | } 82 | 83 | return 'ok'; 84 | } 85 | } 86 | 87 | export default Epusdt; 88 | -------------------------------------------------------------------------------- /src/lib/loginSession.ts: -------------------------------------------------------------------------------- 1 | import uuid from "./uuid"; 2 | 3 | const loginSession = async (request, db, user_id, type: string | 'json') => { 4 | let session_id = uuid(); 5 | let message: null|string = null; 6 | 7 | const cookie = request.headers.get('cookie'); 8 | if (cookie) { 9 | const matches = cookie.match(/session_id=([^\;]+)/); 10 | if (matches && matches[1]) { 11 | session_id = matches[1]; 12 | } 13 | } 14 | const expires_at = (new Date((new Date).getTime() + 86400 * 31 * 1000)).getTime(); 15 | const session = await db.prepare(`SELECT * FROM sessions WHERE id=?`).bind(session_id).first(); 16 | if (!session) { 17 | await db.prepare(`INSERT INTO sessions (id, user_id, expires_at) VALUES (?1, ?2, ?3)`).bind(session_id, user_id, expires_at).run(); 18 | 19 | } else { 20 | await db.prepare(`UPDATE sessions SET user_id=?2, expires_at=?3 WHERE id=?1`).bind(session_id, user_id, expires_at).run(); 21 | } 22 | 23 | if (message) { 24 | if (type === 'json') { 25 | return Response.json({ 26 | success: false, 27 | message, 28 | }); 29 | } else { 30 | return new Response(message, { 31 | headers: { 32 | 'Content-Type': `text/html`, 33 | }, 34 | }) 35 | } 36 | } 37 | 38 | if (type === 'json') { 39 | return Response.json({ 40 | success: true, 41 | message: 'OK', 42 | }, { 43 | headers: { 44 | 'Set-Cookie': `session_id=${session_id}; path=/; expires=${expires_at}`, 45 | }, 46 | }); 47 | } else { 48 | return new Response(` 49 | ${type} 50 | 53 | `, { 54 | headers: { 55 | 'Content-Type': `text/html`, 56 | 'Set-Cookie': `session_id=${session_id}; path=/; expires=${expires_at}`, 57 | }, 58 | }); 59 | } 60 | }; 61 | 62 | export default loginSession; -------------------------------------------------------------------------------- /src/lib/readRequestBody.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * readRequestBody reads in the incoming request body 3 | * Use await readRequestBody(..) in an async function to get the string 4 | * @param {Request} request the incoming request to read from 5 | */ 6 | export default async (request: Request): Promise => { 7 | request = request.clone(); 8 | const contentType = request.headers.get("content-type") || ''; 9 | if (contentType.includes("application/json")) { 10 | return await request.json(); 11 | } else if (contentType.includes("application/text")) { 12 | return request.text(); 13 | } else if (contentType.includes("text/html")) { 14 | return request.text(); 15 | } else if (contentType.includes("form")) { 16 | const formData = await request.formData(); 17 | const body = {}; 18 | for (const entry of formData.entries()) { 19 | body[entry[0]] = entry[1]; 20 | } 21 | return body; 22 | } else { 23 | // Perhaps some other type of data was submitted in the form 24 | // like an image, or some other binary data. 25 | return "a file"; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /src/lib/readRequestQuery.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * readRequestBody reads in the incoming request body 3 | * Use await readRequestBody(..) in an async function to get the string 4 | * @param {Request} request the incoming request to read from 5 | */ 6 | export default async (request: Request, key: string | void): Promise => { 7 | const query = {}; 8 | const searchParams = (new URL(request.clone().url)).searchParams; 9 | if (key) { 10 | return searchParams.get(key); 11 | } 12 | 13 | searchParams.forEach((varValue, varName) => { 14 | if (typeof query[varName] !== 'undefined' && varName.includes(`[`) && varName.includes(`]`)) { 15 | const key = varName.split(`[`)[1].replace(`]`, ``); 16 | if (key === ``) { 17 | query[varName].push(varValue); 18 | } 19 | if (typeof query[varName][key] === 'undefined') { 20 | let _varName = varName.split(`[`)[0]; 21 | query[_varName][key] = []; 22 | } 23 | query[varName][key].push(varValue); 24 | } else { 25 | query[varName] = varValue; 26 | } 27 | }); 28 | return query; 29 | }; 30 | -------------------------------------------------------------------------------- /src/lib/recaptchaChallange.ts: -------------------------------------------------------------------------------- 1 | import { Env } from '../d/Env.ts'; 2 | import readRequestBody from './readRequestBody.ts'; 3 | 4 | const recaptchaChallange = async function(env: Env, request: Request): Promise { 5 | return new Promise(async (resolve, reject) => { 6 | const body = await readRequestBody(request); 7 | const ip = request.headers.get('CF-Connecting-IP'); 8 | 9 | const formData = new FormData(); 10 | formData.append('secret', env.RECAPTCHA_SECRET_KEY); 11 | formData.append('response', body['g-recaptcha-response']); 12 | formData.append('remoteip', ip); 13 | 14 | const url = 'https://www.recaptcha.net/recaptcha/api/siteverify'; 15 | const result = await fetch(url, { 16 | body: formData, 17 | method: 'POST' 18 | }); 19 | 20 | const outcome = <{success: boolean;}> await result.json(); 21 | // this is the conditional block that you can customize to fit your specific use-case 22 | if (outcome.success) { 23 | return resolve(true); 24 | } else { 25 | return reject(outcome['error-codes'].join(',')); 26 | } 27 | }); 28 | }; 29 | 30 | export default recaptchaChallange; 31 | -------------------------------------------------------------------------------- /src/lib/sendmail.ts: -------------------------------------------------------------------------------- 1 | import { Env } from "../d/Env"; 2 | 3 | const sendmail = async (receiptEmail: string, mailSubject: string, mailBody: string, env: Env) => { 4 | const senders = (typeof env.BREVO === 'string' ? JSON.parse(env.BREVO) : env.BREVO); 5 | 6 | let seed: number; 7 | switch (env.BREVO_PREFER) { 8 | case "auto": 9 | seed = ~~(Math.random() * senders.length); 10 | break; 11 | 12 | default: 13 | seed = env.BREVO_PREFER; 14 | break; 15 | } 16 | 17 | const sender = senders[seed]; 18 | const url = 'https://api.brevo.com/v3/smtp/email'; 19 | const params = { 20 | sender: { 21 | name: sender.senderName, 22 | email: sender.senderAddress, 23 | }, 24 | to: [ 25 | { 26 | email: receiptEmail, 27 | name: null 28 | } 29 | ], 30 | subject: mailSubject, 31 | htmlContent: mailBody, 32 | }; 33 | 34 | const options = { 35 | method: 'POST', 36 | headers: { 37 | 'accept': 'application/json', 38 | 'api-key': sender.apiKey, 39 | 'content-type': 'application/json' 40 | }, 41 | body: JSON.stringify(params) 42 | }; 43 | 44 | try { 45 | const send = await fetch(url, options); 46 | const json = <{messageId: string; message: string;}> await send.json(); 47 | if (send.status === 201) { 48 | return json.messageId; 49 | } 50 | 51 | throw new Error(json.message); 52 | } catch (err) { 53 | throw err; 54 | } 55 | }; 56 | 57 | export default sendmail; 58 | -------------------------------------------------------------------------------- /src/lib/totp.ts: -------------------------------------------------------------------------------- 1 | export const validateTotp = async (token, secret): Promise => { 2 | const timeStep = 30; 3 | const tolerance = 1; 4 | const currentTime = Math.floor(Date.now() / 1000); 5 | 6 | for (let i = -tolerance; i <= tolerance; i++) { 7 | let timeCounter = Math.floor((currentTime + i * timeStep) / timeStep); 8 | let generatedToken = await generateToken(timeCounter, secret); 9 | if (generatedToken === token.toString()) { 10 | return true; 11 | } 12 | } 13 | 14 | return false; 15 | } 16 | 17 | export const generateToken = async (timeCounter, secret): Promise => { 18 | const timeCounterHex = timeCounter.toString(16).padStart(16, '0'); 19 | const keyHex = base32tohex(secret); 20 | const hmacHex = await jsSHA1HMAC(keyHex, timeCounterHex); 21 | const offset = parseInt(hmacHex.slice(-1), 16); 22 | const truncatedHash = parseInt(hmacHex.slice(offset * 2, offset * 2 + 8), 16) & 0x7fffffff; 23 | let generatedToken = (truncatedHash % 1000000).toString(); 24 | generatedToken = generatedToken.padStart(6, "0"); 25 | return generatedToken; 26 | } 27 | 28 | export const generateSecret = (length = 16) => { 29 | const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; 30 | let secret = ''; 31 | for (let i = 0; i < length; i++) { 32 | const randomIndex = Math.floor(Math.random() * alphabet.length); 33 | secret += alphabet[randomIndex]; 34 | } 35 | return secret; 36 | } 37 | 38 | const jsSHA1HMAC = async (keyHex, messageHex) => { 39 | const key = new Uint8Array(keyHex.match(/[\da-f]{2}/gi).map(h => parseInt(h, 16))); 40 | const message = new Uint8Array(messageHex.match(/[\da-f]{2}/gi).map(h => parseInt(h, 16))); 41 | 42 | const cryptoKey = await crypto.subtle.importKey( 43 | 'raw', 44 | key, 45 | { name: 'HMAC', hash: 'SHA-1' }, 46 | false, 47 | ['sign'] 48 | ); 49 | 50 | const signature = await crypto.subtle.sign('HMAC', cryptoKey, message); 51 | const signatureArray = new Uint8Array(signature); 52 | const hmacHex = Array.from(signatureArray).map(b => b.toString(16).padStart(2, '0')).join(''); 53 | return hmacHex; 54 | } 55 | 56 | const base32tohex = (base32: string): string => { 57 | var base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; 58 | var bits = ""; 59 | var hex = ""; 60 | 61 | for (var i = 0; i < base32.length; i++) { 62 | var val = base32chars.indexOf(base32.charAt(i).toUpperCase()); 63 | bits += leftpad(val.toString(2), 5, '0'); 64 | } 65 | 66 | for (var i = 0; i + 4 <= bits.length; i += 4) { 67 | var chunk = bits.substr(i, 4); 68 | hex = hex + parseInt(chunk, 2).toString(16); 69 | } 70 | return hex; 71 | } 72 | 73 | const leftpad = (str, len, pad): string => { 74 | if (len + 1 >= str.length) { 75 | str = Array(len + 1 - str.length).join(pad) + str; 76 | } 77 | return str; 78 | } 79 | -------------------------------------------------------------------------------- /src/lib/uuid.ts: -------------------------------------------------------------------------------- 1 | const uuid = () => { 2 | return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => 3 | (+c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> +c / 4).toString(16) 4 | ); 5 | }; 6 | 7 | export default uuid; -------------------------------------------------------------------------------- /src/pages/dashboard/logout.ts: -------------------------------------------------------------------------------- 1 | export default async (request: Request, db: D1Database, session_id: string | false) => { 2 | if (session_id) { 3 | await db.prepare(`DELETE FROM sessions WHERE id=?`).bind(session_id).run(); 4 | } 5 | 6 | return new Response( 7 | ``, 8 | { 9 | headers: { 10 | 'Content-type': 'text/html; charset=utf-8', 11 | 'Set-cookie': 'session_id=; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;', 12 | }, 13 | } 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /src/template/auth/login-mfa.html: -------------------------------------------------------------------------------- 1 | %%HEADER%% 2 | 3 |
4 | 5 | 6 | Com.Mp 7 |

Enter MFA code

8 | 9 |
10 | 11 | 12 |
13 |
14 | 15 | 16 | Recovery MFA? 17 |
18 | 19 | 20 |

© 2024

21 |
22 | 23 | %%FOOTER%% 24 | 25 | %%RECAPTCHA%% 26 | 89 | -------------------------------------------------------------------------------- /src/template/auth/login.html: -------------------------------------------------------------------------------- 1 | %%HEADER%% 2 |
3 | 4 | Com.Mp 5 |

Login / Register

6 | 7 |
8 | 9 | 10 |
11 | 12 | 13 |

© 2024

14 |
15 | %%FOOTER%% 16 | 17 | -------------------------------------------------------------------------------- /src/template/auth/mfa-recovery.html: -------------------------------------------------------------------------------- 1 | %%HEADER%% 2 | 3 | 4 | 9 | 10 |
11 | 12 | 13 | 14 | Com.Mp 15 |

Recovery MFA

16 | 17 |
18 | 19 | 20 |
21 |
22 | 23 | 24 |
25 | 26 |

© 2024

27 |
28 | %%FOOTER%% 29 | 30 | 31 | 32 | %%RECAPTCHA%% 33 | -------------------------------------------------------------------------------- /src/template/auth/register.html: -------------------------------------------------------------------------------- 1 | %%HEADER%% 2 | 3 | 4 | 9 | 10 | We have stopped user registration. see announcement 11 | -------------------------------------------------------------------------------- /src/template/auth/reset.html: -------------------------------------------------------------------------------- 1 | %%HEADER%% 2 |
3 | 4 | 5 | Com.Mp 6 |

Reset MFA

7 | 8 |
9 | 10 | 11 |
12 | 13 | 14 |

© 2024

15 |
16 | %%FOOTER%% 17 | %%RECAPTCHA%% 18 | 19 | -------------------------------------------------------------------------------- /src/template/common/auth/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/template/common/auth/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Sign in 13 | 14 | 15 | 16 | 17 | 19 | 21 | 23 | 24 | 26 | 27 | 29 | 30 | 31 | 32 | 45 | 123 | 124 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 147 | 148 | 149 | 150 | 151 | 152 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 162 | 163 | 165 | 166 | 167 | 168 | 170 | 171 | 172 | 173 | 174 | 221 | 222 | 223 |
224 | -------------------------------------------------------------------------------- /src/template/common/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 40 | 41 | 42 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/template/common/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Get your Com.MP domain name for FREE! 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 33 | 114 | 126 | 131 | 132 | 133 | 134 | 135 | 136 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 146 | 147 | 149 | 150 | 151 | 152 | 154 | 155 | 156 | 157 | 158 | 205 | 206 | 207 | 208 | 209 | Check 210 | 212 | 213 | 214 | 215 | 216 |
217 |
218 |
219 | 220 | Com.Mp 221 | 222 | 223 | 235 |
236 | -------------------------------------------------------------------------------- /src/template/common/recaptcha.html: -------------------------------------------------------------------------------- 1 | 12 | 13 | 22 | 23 | 24 | 25 | 55 | -------------------------------------------------------------------------------- /src/template/dashboard/common/banner.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

Join our Telegram group!

5 |
6 |
7 | -------------------------------------------------------------------------------- /src/template/dashboard/credit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Com.MP Dashboard 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 114 | 115 | 116 | 117 | 118 | 119 | 121 | 123 | 124 | 125 | 127 | 128 | 129 | 130 | 177 | 178 | 179 | 224 | 225 | 236 | 237 |
238 | %%BANNER%% 239 | 240 |
241 |
My credit
242 |
243 | $ %%USER.CREDIT%% 244 | 245 | 246 |
247 |
248 |
249 | 250 | 274 | 275 | 298 | 299 | 300 | 301 | 302 | 303 | 347 | 348 | %%LIVECHAT%% 349 | 350 | 351 | -------------------------------------------------------------------------------- /src/template/dashboard/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Com.MP Dashboard 11 | 12 | 13 | 15 | 17 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 37 | 38 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 124 | 125 | 126 | 127 | 128 | 129 | 131 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 186 | 187 | 188 | 229 | 230 | 241 | 242 |
243 |
244 | 246 |
247 |

Bootstrap

248 | Since 2011 249 |
250 |
251 | 252 |
253 |
Recent updates
254 |
255 | 258 | Placeholder 259 | 32x32 260 | 261 |

262 | @username 263 | Some representative placeholder content, with some information about this user. Imagine this being 264 | some sort of status update, perhaps? 265 |

266 |
267 |
268 | 271 | Placeholder 272 | 32x32 273 | 274 |

275 | @username 276 | Some more representative placeholder content, related to this other user. Another status update, 277 | perhaps. 278 |

279 |
280 |
281 | 284 | Placeholder 285 | 32x32 286 | 287 |

288 | @username 289 | This user also gets some representative placeholder content. Maybe they did something interesting, 290 | and you really want to highlight this in the recent updates. 291 |

292 |
293 | 294 | All updates 295 | 296 |
297 | 298 |
299 |
Suggestions
300 |
301 | 304 | Placeholder 305 | 32x32 306 | 307 |
308 |
309 | Full Name 310 | Follow 311 |
312 | @username 313 |
314 |
315 |
316 | 319 | Placeholder 320 | 32x32 321 | 322 |
323 |
324 | Full Name 325 | Follow 326 |
327 | @username 328 |
329 |
330 |
331 | 334 | Placeholder 335 | 32x32 336 | 337 |
338 |
339 | Full Name 340 | Follow 341 |
342 | @username 343 |
344 |
345 | 346 | All suggestions 347 | 348 |
349 |
350 | 351 | 352 | 353 | %%LIVECHAT%% 354 | 355 | 356 | -------------------------------------------------------------------------------- /src/template/dashboard/livechat.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/template/dashboard/reg-domain.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Com.MP Dashboard 11 | 12 | 13 | 15 | 17 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 37 | 38 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 128 | 129 | 130 | 131 | 132 | 133 | 135 | 137 | 138 | 139 | 141 | 142 | 143 | 144 | 191 | 192 | 193 | 234 | 235 | 247 | 248 |
249 | %%BANNER%% 250 | 251 |
252 |
Register Domain(s)
253 |
254 |
255 |
256 | 257 | 261 |
262 |
263 | 264 | 268 |
269 |
270 | 271 |
272 |
273 |
274 |
275 |
276 | 277 | 278 | 279 | 280 | %%RECAPTCHA%% 281 | 282 | 353 | %%LIVECHAT%% 354 | 355 | 356 | -------------------------------------------------------------------------------- /src/template/email/activation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 |
9 |

10 |

Hello %%EMAIL%%,

11 |


12 |

This is an activation email for your registry.com.mp account!

13 |

Click the link below to activate your account within 24 hours before it gets expired:

14 |

Activate

15 |


16 |

If you did not request this email, please ignore it.

17 |

Thank you,

18 |

The registry.com.mp Team

19 |


20 |


21 |

If your inbox didn't render the activation link correctly, please copy the link below to browser to activate:

22 |

23 | %%ACTIVATION_LINK%% 24 |

25 |
26 |
27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /src/template/email/mfa-recovery.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 |
9 |

10 |

Hello %%EMAIL%%,

11 |


12 |

This is an email to help your recover your registry.com.mp account's MFA!

13 |

Click the link below to reset your account within 24 hours before it gets expired:

14 |

Reset MFA

15 |


16 |

If you did not request this email, please ignore it.

17 |

Thank you,

18 |

The registry.com.mp Team

19 |


20 |


21 |

If your inbox didn't render the activation link correctly, please copy the link below to browser to activate:

22 |

23 | %%RESET_LINK%% 24 |

25 |
26 |
27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /src/template/index.html: -------------------------------------------------------------------------------- 1 | %%HEADER%% 2 | 3 |
4 |

Get your Com.Mp for FREE!

6 |
7 |

8 | We offer you low-cost, easy, and powerful domain name service! 9 | We're happy to serve any user wants domain for cheap! So we're 10 | willing to offer your first one ten for FREE ($0.00)! And 11 | we guarantee here, no any additional charges in the future! 12 |

13 | 21 |
22 |
23 |
24 | Example image 27 |
28 |
29 |
30 |
31 |

Pricing

32 |

Quickly build an effective pricing table for your potential 33 | customers with this Bootstrap example. It’s built with default Bootstrap components and utilities 34 | with little customization.

35 |
36 |
37 | 38 |
39 |
40 |
41 |
42 |
43 |

Free

44 |
45 |
46 |

$0/mo

48 |
    49 |
  • Limited-domain allowed
  • 50 |
  • 3rd-party DNS Server only
  • 51 |
  • Ticket support
  • 52 |
  • Help center access
  • 53 |
  • Renews in 50 days before expiring
  • 54 |
55 | Register a Com.Mp for FREE 58 |
59 |
60 |
61 |
62 |
63 |
64 |

Enterprise

65 |
66 |
67 |

$0.99/year per Com.Mp

70 |
    71 |
  • Multi-domains allowed(Pay as you go & Deposit 72 | required)
  • 73 |
  • 3rd-party DNS Server + Managed DNS
  • 74 |
  • Ticket/Livechat support
  • 75 |
  • Help center access
  • 76 |
  • Renews automatically(Deposit required)
  • 77 |
78 | Enable my eligibility 80 |
81 |
82 |
83 |
84 | 85 |

Compare plans

86 | 87 |
88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 104 | 109 | 110 | 111 | 112 | 113 | 116 | 117 | 118 | 119 | 120 | 123 | 124 | 125 | 126 | 127 | 130 | 131 | 132 | 133 | 134 | 137 | 138 | 139 | 140 | 141 | 144 | 145 | 146 |
FreeEnterprise
3rd party DNS 100 | 101 | 102 | 103 | 105 | 106 | 107 | 108 |
Multiple Domains allowed 114 | 115 |
Teams 121 | 122 |
Permissions ACL 128 | 129 |
Sharing 135 | 136 |
Managed DNS 142 | 143 |
147 |
148 |
149 | 150 | %%FOOTER%% -------------------------------------------------------------------------------- /src/template/resources/1.html: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /src/template/resources/news.html: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /src/template/resources/privacy.html: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /src/template/resources/registrars.html: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /src/template/resources/term-of-service.html: -------------------------------------------------------------------------------- 1 | %%HEADER%% 2 |
3 |

Legal Information

4 |

5 | Our Terms of Service have been written in order to protect our clients and ourselves to ensure we deliver a stable, 6 | reliable product and quality network. We ask that you read our policies so that you can assist us in keeping our 7 | servers and network free of abuse, which will ensure quality performance for everyone. 8 |

9 |

10 | When you sign up for any of our services, you are agreeing to our terms of service. Although we will do our best to 11 | work with our customers in the event of a breach of policy and abusively taking advantage of our services in any 12 | form, we will also take a firm line when necessary to protect our company, our other customers, and network. 13 |

14 |

15 | Clients of [Com.mp Registry], including but not limited to Resellers, Dedicated Server Clients, Shared 16 | Hosting Clients, and Domain Registration Clients, are required to agree and conform to the following terms of 17 | service (TOS) and acceptable use policies. Violations of these policies may result in loss of service and/or other 18 | disciplinary action. 19 |

20 |
21 |

Reasonable Control

22 |

23 | We are not responsible for any delay in performing or failure to perform any obligation to you as a result of any 24 | matter beyond our reasonable control. 25 |

26 |
27 |

Domain Name

28 |

29 | Generally. If requested by You, [Com.mp Registry] will, as agent for You, apply for the 30 | domain name as requested by You ("Requested Domain Name"). 31 |

32 |

33 | Domain registration. If You choose to register a domain name(s) through [Com.mp Registry], You 34 | acknowledge and agree that: 35 |

36 |
    37 |
  • You will pay the correct registration fee(s) to register the domain name(s) with the applicable domain name 38 | registrar.
  • 39 |
  • During the order process of domain registration, [Com.mp Registry] may not be able to determine if 40 | the domain is classified as a "Premium Domain."
  • 41 |
  • The prices indicated or displayed in the website are for the Standard Domains or Non-premium Domains.
  • 42 |
  • 43 | Should you have ordered a Premium Domain, [Com.mp Registry] will communicate with You immediately to 44 | choose one option stated below to settle the transaction: 45 |
    1. You will pay for the difference between the paid amount and the correct price of the domain. 46 |
    2. You will change the ordered domain name. 47 |
    3. You will cancel the order and the amount will be refunded. 48 |
    [Com.mp Registry] has the right to cancel the order if You are not able to make a decision 49 | within the business day. 50 |
  • 51 |
  • 52 | Domain Registration does not offer refund(s) for domain name registration(s) for any reason, including 53 | misspelling of the domain name. 54 |
  • 55 |
56 |

57 | Domain Terms. By registering a domain name(s) through [Com.mp] Registry, You 58 | acknowledge and agree to the terms and conditions of the respective domain registry. 59 |

60 |

61 | None Guaranteed Domain Registration. [Com.mp Registry] does not guarantee that it will 62 | be successful in its application for the Requested Domain Name. 63 |

64 |

65 | Domain Expiration. Your Domain Name will become expired and may cause Your web site to become 66 | inaccessible on and after the expiry date if the Domain Name is not renewed on or before the expiry date. You shall 67 | renew the domain name at Your own cost and expense. In the event You failed to renew the domain name and caused the 68 | domain name to be expired or not being able to renew, You shall not make any claim or compensation from [Com.mp 69 | Registry]. 70 |

71 |

72 | Domain Redemption Period is an extra grace period hold by the registrar. It is imposed by the 73 | Registry and was instigated by ICANN in order to allow You a little more time to renew their domain name(s). To 74 | renew a Domain Name that falls under Domain Redemption Period, a Domain Redemption Fee may apply. 75 |

76 |

77 | None Guaranteed Renewal. [Com.mp Registry] does not guarantee that it will be 78 | successful in its application for the Requested Domain Name Renewal of Domain Name that is expired or falls under 79 | Domain Redemption Period. Domain Redemption Period. 80 |

81 |
82 |

Privacy Policy

83 |

84 | Because protecting your privacy is very important to [Com.mp] Registry, we operate our web site under 85 | the following guidelines to safeguard your personally identifiable information: 86 |

87 |

88 | [Com.mp Registry] policies and procedures for handling customer information have been created with the 89 | understanding that Internet technologies are still evolving and that Internet business methods are continuing to 90 | evolve to meet the needs and opportunities of the changing technologies. As a result, [Com.mp Registry 91 | ] policies and procedures are subject to change. 92 |

93 |
94 |

How does [Com.mp Registry] collect information from you?

95 |

96 | [Com.mp Registry] collects information from you when you send it to [Com.mp Registry 97 | ] directly by filling out forms on [Com.mp Registry] Website (including any application you may make for 98 | Services or the Software), corresponding with [Com.mp Registry] by e-mail, writing to [Com.mp Registry] by post, or 99 | speaking to [Com.mp Registry] by telephone. [Com.mp Registry] also collects information from you when you browse the 100 | Website and use the Software, as set out in detail 101 | below. Some of the methods [Com.mp Registry] uses to collect data are automated and will take effect 102 | automatically as you navigate the Website and/or use the Software. 103 |

104 |
105 |

What information does [Com.mp Registry] collect?

106 |

Personal Information.

107 |

108 | Personal information means any information relating to an identified or identifiable natural person; an identifiable 109 | natural person is one who can be identified, directly or indirectly, by reference to an identifier such as a name, 110 | an identification number, location data, an online identifier or to one or more factors specific to the physical, 111 | physiological, genetic, mental, economic, cultural or social identity of that natural person ("Personal 112 | Information"). 113 |

114 |

115 | [Com.mp Registry] may collect the following Personal Information from you: name, address, date of birth, 116 | telephone number, postal address, e-mail address, IP address, information about the type of browser you use, your 117 | operating system, the screen resolution of your browser, your ISP, which pages you view on the Website and the time 118 | and duration of your visits to the Website, credit card number (in the case of direct customers) and, if applicable, 119 | company name, postal address, telephone number, e-mail address, national identification number, passport number, 120 | credit card number or tax ID number as well as similar information concerning technical contacts, marketing 121 | contacts, and executive contacts within your company or organisation. 122 |

123 |

User Communications.

124 |

125 | If you communicate with [Com.mp] Registry, [Com.mp Registry] may collect information 126 | relating to that communication whether it takes the form of e-mail, letter, forum posting, testimonials or any other 127 | form of communication between you and [Com.mp Registry] or submitted by you to the Website 128 | (collectively, "User Communications"). 129 |

130 |

Server Information.

131 |

132 | If you use one of [Com.mp Registry]'s services such as [Com.mp Registry]'s Web Hosting, 133 | Dedicated Server, VPS, Domain Name or SSL, [Com.mp Registry] may collect certain information concerning 134 | such services and concerning the server upon which the services operates. This information includes without 135 | limitation: (a) the licensed or unlicensed status of the software used under the services; (b) the source from which 136 | the license for the software was obtained (i.e., [Com.mp Registry] or an [Com.mp Registry 137 | ] affiliate); or (c) information about the server upon which the software is installed including (i) the public IP 138 | address, (ii) the operating system and (iii) the use of any virtualization technologies on such server ((a) through 139 | (c) collectively, "Server Information")). Additionally, "Server Information" may also include information collected 140 | by [Com.mp Registry] from time to time concerning which features of the software are most often used in 141 | order to improve and make adjustments to the software; and information collected from you by [Com.mp Registry] in 142 | the event that you request technical support services including without limitation, IP addresses, 143 | usernames and passwords necessary to login to SSH, the directory of the server upon which you installed the software 144 | and any affected accounts including email accounts, MySQL accounts and other accounts. 145 |

146 |

Non-Personal Information.

147 |

148 | [Com.mp Registry] also collects data in a form that does not, on its own, permit direct association with 149 | any specific individual. [Com.mp Registry] may collect, use, transfer, and disclose non-personal 150 | information for any purpose. 151 |

152 |
153 |

What information does [Com.mp Registry] collect if you're under the age of 13?

154 |

155 | By Default, [Com.mp Registry] does not knowingly collect Personal Information about children under the 156 | age of 13. If [Com.mp Registry] becomes aware that it has inadvertently collected Personal Information 157 | about children under the age of 13, it will take steps to delete the information as soon as possible, except where 158 | [Com.mp Registry] is required by applicable law to keep it. 159 |

160 |

161 | Where [Com.mp Registry] knows a child is above the age of 13, but considered a minor under applicable 162 | law, [Com.mp Registry] will obtain parental/guardian consent prior to using that child's Personal 163 | Information. 164 |

165 |
166 |

How does [Com.mp Registry] use and store the information it collects?

167 |

168 | As a general matter, [Com.mp Registry] may use the Personal Information you disclose to [Com.mp Registry] to improve 169 | and provide the Website, the Services and [Com.mp Registry]'s other 170 | products and services, and for the specific purpose that you gave [Com.mp Registry] your Personal 171 | Information. More specific details on how [Com.mp Registry] uses your information follows below. 172 |

173 |

174 | [Com.mp Registry] may use Personal Information to create and authenticate your account, to process 175 | transactions you request such as domain name registration in order to perform any transaction you have entered into 176 | with [Com.mp] Registry, to provide you with customer and technical support and to communicate with you 177 | about your account and [Com.mp Registry]'s products and services. 178 |

179 |

180 | The Personal Information you provide to [Com.mp Registry] allows [Com.mp Registry] to 181 | provide you with the newsletters and mailing lists that you have signed up for with [Com.mp] Registry. 182 | If you do not want to be on [Com.mp Registry]'s mailing list, you can opt out at any time by changing 183 | your settings in your 'My Details' page within the client area. 184 |

185 |

186 | [Com.mp Registry] may also use Personal Information to offer, market or advertise to you [Com.mp Registry] products 187 | and services. While such [Com.mp Registry] products and services may 188 | reference, incorporate or include third-party products and services, [Com.mp Registry] will not use your 189 | Personal Information to independently offer, market or advertise third-party products and services unless [Com.mp 190 | Registry] first obtains your consent to do so. 191 |

192 |

193 | From time to time, [Com.mp Registry] may use your Personal Information to send important notices, such 194 | as important product updates and communications about purchases as well as changes to [Com.mp Registry]'s terms, 195 | conditions, and policies. Because this information is important for your interaction with [Com.mp Registry] you may 196 | not opt out of receiving these communications. 197 |

198 |

199 | [Com.mp Registry] may also use your Personal Information for any other legal purpose stated in this 200 | Privacy Policy, and any other purpose for which you have given [Com.mp Registry] express consent. 201 |

202 |

203 | Where you consent to [Com.mp Registry] doing so, [Com.mp Registry] may use your Personal 204 | Information to send you direct marketing communications. Should you ever choose to 'opt out' of receiving such 205 | communications, [Com.mp Registry] may retain your Personal Information on file to ensure that [Com.mp Registry] does 206 | not continue to target you with communications of the type that you have asked [Com.mp Registry] to cease sending to 207 | you. 208 |

209 |

210 | [Com.mp Registry] limits the use of Personal Information to the purposes identified in this Privacy 211 | Policy and for which you have provided explicit consent. In accordance with established policies and procedures, 212 | [Com.mp Registry] retains Personal Information only for as long as necessary to fulfil the stated 213 | purposes, unless it is required by law for a different period or [Com.mp Registry] has the consent of 214 | the individual. 215 |

216 |

217 | In accordance with established policies and procedures, [Com.mp Registry] will periodically destroy or 218 | erase any Personal Information that is no longer needed. 219 |

220 |

221 | [Com.mp Registry] may use User Communications in the same way as [Com.mp Registry] uses 222 | Personal Information. If you communicate with [Com.mp Registry] for a particular purpose, [Com.mp Registry] may use 223 | your User Communications for that purpose. For example, if you contact [Com.mp Registry] for technical support, 224 | [Com.mp Registry] may use your communications to provide 225 | technical support to you. 226 |

227 |

228 | [Com.mp Registry] may use Server Information to provide you with technical support services and to 229 | maintain, evaluate, improve and provide [Com.mp Registry] products and services. [Com.mp Registry] may also use such 230 | information to investigate unlicensed (and therefore unauthorised) uses of [Com.mp Registry]'s software. 231 |

232 |
233 |

Where is your Personal Information stored?

234 |

235 | Your peronal data may be transferred to and stored at our office and associated datacenters and by 236 | accepting our terms of service, you are explicitly consenting to this transfer and storage taking place. We will 237 | take all steps reasonably necessary to ensure that your personal information is treated securely and in accordance 238 | with this privacy policy. 239 |

240 |
241 |

How does [Com.mp Registry] protect your Data Security?

242 |

243 | Your peronal data may be transferred to and stored at our office and associated datacenters and by 244 | accepting our terms of service, you are explicitly consenting to this transfer and storage taking place. We will 245 | take all steps reasonably necessary to ensure that your personal information is treated securely and in accordance 246 | with this privacy policy. 247 |

248 |
249 |

How can I modify my personal information?

250 |

251 | You may modify your personal information by creating a Support ticket to make the request or update from the Domain 252 | Registration Client Area System. 253 |

254 |

255 | If you have registered a domain name with [Com.mp Registry] and wish to change the any Contact Details 256 | to another company or change any other registration information, you should create a Support ticket and provide the 257 | information to be changed. 258 |

259 |

260 | [Com.mp Registry] provides you with full access to your domain account by sending you your own username 261 | and password. It is important to note that your domain name registration information is made publicly available in 262 | the registry of domain names. In the event you lose your domain password, you can create a Support ticket and we 263 | will re-send the password to the email address on the domain registration record. In the event you lose your 264 | password and the email address on record with Domain Registrar is no longer valid, a direct request to Domain 265 | Registrar is required, therefore it is important to keep your Domain Registrar email address current as well as your 266 | email address with [Com.mp] Registry. 267 |

268 |
269 |

Will [Com.mp Registry] Ever Send Me Direct Mailings?

270 |

271 | From time to time, [Com.mp Registry] may send you information about various products and services that 272 | may be of interest. We will not send you information of this type without specifically allowing you to "opt out" of 273 | such mailings. You can opt out by sending an e-mail to legal@registry.com.mp, however by doing so, you 274 | may miss important communication regarding your service. 275 |

276 |

277 | In addition, if you are an [Com.mp Registry] reseller, [Com.mp Registry] and/or its partners 278 | and advertisers may from time to time send you newsletters, promotional material, and other mailings. You can opt 279 | out by sending an e-mail to legal@registry.com.mp. 280 |

281 |
282 |

How Do I Protect My Personal Information In Public Forums?

283 |

284 | [Com.mp Registry] may offer interactive forums, such as message boards and chat. You should be aware 285 | that when you voluntarily disclose Personal Information to other users or to third parties on the [Com.mp Registry] 286 | system, through e-mail, or outside of the [Com.mp Registry] system, that 287 | information can be collected and used by others and may result in unsolicited messages from other members or third 288 | parties. While [Com.mp Registry] strives to protect your Personal Information, [Com.mp Registry] cannot guarantee 289 | the security of any information that you transmit to [Com.mp] Registry, and 290 | you are solely responsible for maintaining the secrecy of any passwords or other account information. 291 |

292 |
293 |

Information and access to your Personal Information

294 |

295 | Based on what you have told [Com.mp] Registry, [Com.mp Registry] tries to ensure that your 296 | contact information and preferences are accurate, complete, and up to date. You have the right to request access to 297 | and rectification or erasure of Personal Information or restriction of processing concerning your Personal 298 | Information or to object to processing as well as the right to data portability. [Com.mp Registry] will 299 | comply with erasure requests as long as [Com.mp Registry] is not required to retain the Personal 300 | Information by law and does not need to retain it for its legitimate business purposes. [Com.mp Registry] may 301 | decline to process requests that are frivolous/vexatious, jeopardise the privacy of others, are 302 | extremely impractical, or for which access is not otherwise required by local law. Access, correction, or deletion 303 | requests can be made by emailing legal@registry.com.mp. 304 |

305 |
306 |

Your Rights

307 |

308 | As a Data Subject you have a number of rights in relation to your Personal Information. These include your rights: 309 |

310 |

311 | To ask [Com.mp Registry] to confirm what (if any) Personal Information [Com.mp Registry 312 | ] holds relating to you and how that data is processed and used by [Com.mp Registry ](often referred to as 313 | a 'Subject Access Request'); 314 |

315 |

316 | To have [Com.mp Registry] rectify Personal Information which [Com.mp Registry] holds about 317 | you that is inaccurate; 318 |

319 |

320 | To have [Com.mp Registry] erase Personal Information which relates to you if it is no longer necessary 321 | for [Com.mp Registry] to continue to process it, or if [Com.mp Registry] has no lawful basis 322 | to store, process or retain it (though [Com.mp Registry] does have rights to refuse these requests in 323 | certain situations); 324 |

325 |

326 | To object to [Com.mp Registry] processing your Personal Information; 327 |

328 |

329 | To be informed about the existence of any automated decision making and profiling of your Personal Information, and 330 | where appropriate, be provided with meaningful information about the logic involved, as well as the significance and 331 | the envisaged consequences of such processing that affects you; 332 |

333 |

334 | To have [Com.mp Registry] provide you with a copy of your Personal Information for transfer to an 335 | alternative provider of similar services. 336 |

337 |

338 | Should you ever wish to exercise one or more of these rights you should contact [Com.mp Registry] at 339 | legal@registry.com.mp. 340 |

341 |
342 |

Third party websites

343 |

344 | [Com.mp Registry] Website may, from time to time, contain links to and from the websites of [Com.mp Registry] 345 | partner networks, advertisers and affiliates. If you follow a link to any of these websites, 346 | please note that these websites have their own privacy policies and that [Com.mp Registry] does not 347 | accept any responsibility or liability for these policies. Please check these policies before you submit any 348 | Personal Information to these websites. 349 |

350 |
351 |

Does [Com.mp Registry] use cookies and web beacons?

352 |

Cookies

353 |

354 | Yes, [Com.mp Registry] uses cookies to distinguish you from other users of the Website and to improve 355 | your overall experience. When you use the Website, certain information may be stored locally on your device using 356 | 'cookies' or similar technologies such as objects stored in the device's local storage. A cookie is a small text 357 | file used to store limited information about the user of the device. They help [Com.mp Registry] to 358 | identify how [Com.mp Registry]'s users use the Website, and so that [Com.mp Registry] can 359 | continue to develop and improve it. 360 |

361 |

362 | Cookies do this by storing information about your preferences on your device, including the device model, 363 | manufacturer, screen resolution, device capabilities, service provider, country and city location data. [Com.mp 364 | Registry] uses the following types of cookies: 365 |

366 |

367 | Strictly necessary: These cookies enable [Com.mp Registry]'s Website to function correctly and deliver 368 | the services and products you have requested. 369 |

370 |

371 | Performance & Functionality: These cookies are used to enhance the performance and functionality of [Com.mp 372 | Registry]'s Website but are non-essential to their use (for example, [Com.mp Registry] uses 373 | cookies to remember your preferences on the Website). However, without these cookies, certain functionality may 374 | become unavailable. 375 |

376 |

377 | Analytical: These cookies collect information that is used either in aggregate form to help [Com.mp Registry] 378 | understand how the Website is being used or to help [Com.mp Registry] customise the Website 379 | for you. In particular [Com.mp Registry] uses the Google analytics cookies. For more information about 380 | Google's privacy policy, please visit https://www.google.com/intl/en/policies/. If you do not wish to allow the use 381 | of Google Analytics cookies at all, Google provides an opt-out plug-in for most common website browsers 382 | https://tools.google.com/dlpage/gaoptout. 383 |

384 |

385 | By using the Service, you accept the use of cookies in accordance with this Privacy Policy. 386 |

387 |

Your cookie choices

388 |

389 | You have the right to choose whether to accept or refuse cookies and similar technologies. You can exercise this 390 | choice by not accepting the Terms of Service and this Privacy Policy, however, please note that if you choose to do 391 | so, you will not be able to use the Service. 392 |

393 |

394 | For more information about what cookies are and your rights to control cookies, please visit the third party 395 | educational resource www.allaboutcookies.org. 396 |

397 |
398 |

What About Privacy On Sites That [Com.mp Registry] Links To?

399 |

400 | [Com.mp Registry] may provide links to its partners and other Internet sites. These sites have separate 401 | data and privacy practices independent of [Com.mp] Registry, and [Com.mp Registry] disclaims 402 | any responsibility or liability for their policies or actions. 403 |

404 |
405 |

How does [Com.mp Registry] disclose the Personal Information it collects?

406 |

407 | [Com.mp Registry] will not otherwise disclose its customers' personal and account information unless 408 | [Com.mp Registry] has reason to believe that disclosing such information is necessary to identify, make 409 | contact with, or bring legal action against someone who may be causing harm or interfering with the rights or 410 | property of [Com.mp] Registry, [Com.mp Registry] customers, or others, or where [Com.mp Registry] has a good faith 411 | belief that the law requires such disclosure. 412 |

413 |

414 | [Com.mp Registry] cannot be responsible for protecting your Personal Information if you share such 415 | information in publicly available sections of the Website such as the user forums or testimonials section. You 416 | should use your own judgment in disclosing this information on the Website. 417 |

418 |

419 | [Com.mp Registry] also will not, except for reasons stated below, disclose to third parties the contents 420 | of any electronic mail or other electronic communications that [Com.mp Registry] stores or transmits for 421 | its customers. The circumstances under which [Com.mp Registry] will disclose such electronic customer 422 | communications are when: 423 |

424 |
    425 |
  • it is necessary in order to provide service to the customer;
  • 426 |
  • it is necessary to protect the legitimate interests of [Com.mp Registry] and its customers;
  • 427 |
  • it is required to cooperate with interception orders, warrants, or other legal process that [Com.mp Registry] 428 | determines in its sole discretion to be valid and enforceable; and
  • 429 |
  • it is necessary to provide to a law enforcement agency when the contents are inadvertently obtained by [Com.mp 430 | Registry] and appear to pertain to the commission of a crime.
  • 431 |
432 |

433 | [Com.mp Registry] disclaims any intention to censor, edit or engage in ongoing review or surveillance of 434 | communications stored on or transmitted through its facilities by customers or others. [Com.mp Registry 435 | ] will, however, review, delete or block access to communications that may harm [Com.mp] Registry, its 436 | customers or third parties. The grounds on which [Com.mp Registry] may take such action include, but are 437 | not limited to, actual or potential violations of [Com.mp Registry] policies. 438 |

439 |

440 | In the event that [Com.mp Registry] is purchased by another company, merges with another company or has 441 | a substantial portion of its assets purchased by another company, [Com.mp Registry] may share your 442 | Personal Information with that company. In such an event, [Com.mp Registry] will notify you in 443 | accordance with the notice provisions of the Terms of Use. 444 |

445 |

446 | [Com.mp Registry] may disclose your Personal Information to affiliated third parties and third party 447 | suppliers or service providers that assist [Com.mp Registry] in providing, maintaining, valuating, and 448 | improving the Website, the Services and any other [Com.mp Registry] products and services. [Com.mp Registry] may 449 | disclose your Personal Information to affiliated third parties for the purposes of 450 | offering, marketing or advertising [Com.mp Registry] products and services to you (such [Com.mp Registry] products 451 | and services may reference, incorporate or include third-party products and 452 | services). In such an event, [Com.mp Registry] will take reasonable measures to prevent such affiliated 453 | third parties from using your Personal Information for other purposes. 454 |

455 |
456 |

Question about this Privacy Policy?

457 |

458 | With effect from 25 May 2018, the General Data Protection Regulation (GDPR) enters force. Your rights under that new 459 | regulation are explained at https://ico.org.uk/for-organisations/data-protection-reform/overview-of-the-gdpr/. 460 | Details of how you can exercise those rights are set out in 'Your Rights'. [Com.mp Registry] have 461 | largely factored GDPR into this Privacy Policy but if you think [Com.mp Registry] has failed to do so in 462 | any way, please notify [Com.mp Registry] at gdpr@registry.com.mp. 463 |

464 |
465 |
466 | %%FOOTER%% 467 | -------------------------------------------------------------------------------- /src/template/resources/use-cases.html: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /src/template/support/report-abuse.html: -------------------------------------------------------------------------------- 1 | %%HEADER%% 2 |
3 |

Report abuse

4 |

If you see any malicious link or any abuse situation in <anydomain>.com.mp, please fill this form, or send the abuse report email to report@registry.com.mp

5 |

We will suspend the domain name after confirm the abuse.

6 |
7 | 8 |
9 | 40 | 41 |
42 | 43 |
44 |
45 | %%FOOTER%% 46 | 47 | %%RECAPTCHA%% 48 | 49 | 71 | -------------------------------------------------------------------------------- /src/template/whois-lookup.html: -------------------------------------------------------------------------------- 1 | %%HEADER%% 2 |
3 |

WHOIS Lookup

4 |
5 | 6 |
7 |
8 |
9 |
10 | 11 | 12 |
13 | 14 |
15 | 16 |
17 | 18 | 54 |
55 | 56 | 86 | 87 | %%FOOTER%% 88 | 89 | %%RECAPTCHA%% 90 | 91 | 92 | 186 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "NodeNext", 5 | "moduleResolution": "NodeNext", 6 | "allowImportingTsExtensions": true, 7 | "lib": [ 8 | "esnext" 9 | ], 10 | "types": [ 11 | "@cloudflare/workers-types" 12 | ] 13 | } 14 | } -------------------------------------------------------------------------------- /wrangler.toml: -------------------------------------------------------------------------------- 1 | name = "registry" 2 | main = "src/index.ts" 3 | compatibility_date = "2024-05-27" 4 | workers_dev = true 5 | 6 | [[d1_databases]] 7 | binding = "DB" 8 | database_name = "db" 9 | database_id = "f08680dd-36cd-4a0f-8578-be508b5c0e2a" 10 | migrations_dir = "migrations" 11 | 12 | [triggers] 13 | crons = ["0 0 * * *"] 14 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@cloudflare/kv-asset-handler@0.4.0": 6 | version "0.4.0" 7 | resolved "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.0.tgz#a8588c6a2e89bb3e87fb449295a901c9f6d3e1bf" 8 | integrity sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA== 9 | dependencies: 10 | mime "^3.0.0" 11 | 12 | "@cloudflare/unenv-preset@2.3.1": 13 | version "2.3.1" 14 | resolved "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.3.1.tgz#63c6af2b92adf904f25a10e3957df0db7f161622" 15 | integrity sha512-Xq57Qd+ADpt6hibcVBO0uLG9zzRgyRhfCUgBT9s+g3+3Ivg5zDyVgLFy40ES1VdNcu8rPNSivm9A+kGP5IVaPg== 16 | 17 | "@cloudflare/workerd-darwin-64@1.20250507.0": 18 | version "1.20250507.0" 19 | resolved "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20250507.0.tgz#f203bcae9d345752bb7222b442752671067a6472" 20 | integrity sha512-xC+8hmQuOUUNCVT9DWpLMfxhR4Xs4kI8v7Bkybh4pzGC85moH6fMfCBNaP0YQCNAA/BR56aL/AwfvMVGskTK/A== 21 | 22 | "@cloudflare/workerd-darwin-arm64@1.20250507.0": 23 | version "1.20250507.0" 24 | resolved "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20250507.0.tgz#27d3f9eff78fa7f1f15dab2156cf3abed986f5ce" 25 | integrity sha512-Oynff5H8yM4trfUFaKdkOvPV3jac8mg7QC19ILZluCVgLx/JGEVLEJ7do1Na9rLqV8CK4gmUXPrUMX7uerhQgg== 26 | 27 | "@cloudflare/workerd-linux-64@1.20250507.0": 28 | version "1.20250507.0" 29 | resolved "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20250507.0.tgz#aa02ce64ae41b4e44b40c6ca317ba43dd6b6d87c" 30 | integrity sha512-/HAA+Zg/R7Q/Smyl835FUFKjotZN1UzN9j/BHBd0xKmKov97QkXAX8gsyGnyKqRReIOinp8x/8+UebTICR7VJw== 31 | 32 | "@cloudflare/workerd-linux-arm64@1.20250507.0": 33 | version "1.20250507.0" 34 | resolved "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20250507.0.tgz#61aff7cc6fd356f923006dca557770371e66a187" 35 | integrity sha512-NMPibSdOYeycU0IrKkgOESFJQy7dEpHvuatZxQxlT+mIQK0INzI3irp2kKxhF99s25kPC4p+xg9bU3ugTrs3VQ== 36 | 37 | "@cloudflare/workerd-windows-64@1.20250507.0": 38 | version "1.20250507.0" 39 | resolved "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20250507.0.tgz#86066dd5de0574c9a9cffa49867a8a1729c3eda0" 40 | integrity sha512-c91fhNP8ufycdIDqjVyKTqeb4ewkbAYXFQbLreMVgh4LLQQPDDEte8wCdmaFy5bIL0M9d85PpdCq51RCzq/FaQ== 41 | 42 | "@cloudflare/workers-types@^v1.22.22": 43 | version "1.20231121.0" 44 | resolved "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-1.20231121.0.tgz#be805ed150e5b0d97d83426b378a2b4edc4755e2" 45 | integrity sha512-5IOo8mTRbkW7HCQDEbX9cqHHQ3md+soLLNyZnd2OFRVMaBIpo/0VLfcxvqC4s+eSKgTgkwjaK8nTs4ARPLfEOA== 46 | 47 | "@cspotcode/source-map-support@0.8.1": 48 | version "0.8.1" 49 | resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" 50 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== 51 | dependencies: 52 | "@jridgewell/trace-mapping" "0.3.9" 53 | 54 | "@emnapi/runtime@^1.2.0": 55 | version "1.4.3" 56 | resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz#c0564665c80dc81c448adac23f9dfbed6c838f7d" 57 | integrity sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ== 58 | dependencies: 59 | tslib "^2.4.0" 60 | 61 | "@esbuild/aix-ppc64@0.25.4": 62 | version "0.25.4" 63 | resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz#830d6476cbbca0c005136af07303646b419f1162" 64 | integrity sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q== 65 | 66 | "@esbuild/android-arm64@0.25.4": 67 | version "0.25.4" 68 | resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz#d11d4fc299224e729e2190cacadbcc00e7a9fd67" 69 | integrity sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A== 70 | 71 | "@esbuild/android-arm@0.25.4": 72 | version "0.25.4" 73 | resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz#5660bd25080553dd2a28438f2a401a29959bd9b1" 74 | integrity sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ== 75 | 76 | "@esbuild/android-x64@0.25.4": 77 | version "0.25.4" 78 | resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz#18ddde705bf984e8cd9efec54e199ac18bc7bee1" 79 | integrity sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ== 80 | 81 | "@esbuild/darwin-arm64@0.25.4": 82 | version "0.25.4" 83 | resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz#b0b7fb55db8fc6f5de5a0207ae986eb9c4766e67" 84 | integrity sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g== 85 | 86 | "@esbuild/darwin-x64@0.25.4": 87 | version "0.25.4" 88 | resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz#e6813fdeba0bba356cb350a4b80543fbe66bf26f" 89 | integrity sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A== 90 | 91 | "@esbuild/freebsd-arm64@0.25.4": 92 | version "0.25.4" 93 | resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz#dc11a73d3ccdc308567b908b43c6698e850759be" 94 | integrity sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ== 95 | 96 | "@esbuild/freebsd-x64@0.25.4": 97 | version "0.25.4" 98 | resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz#91da08db8bd1bff5f31924c57a81dab26e93a143" 99 | integrity sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ== 100 | 101 | "@esbuild/linux-arm64@0.25.4": 102 | version "0.25.4" 103 | resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz#efc15e45c945a082708f9a9f73bfa8d4db49728a" 104 | integrity sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ== 105 | 106 | "@esbuild/linux-arm@0.25.4": 107 | version "0.25.4" 108 | resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz#9b93c3e54ac49a2ede6f906e705d5d906f6db9e8" 109 | integrity sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ== 110 | 111 | "@esbuild/linux-ia32@0.25.4": 112 | version "0.25.4" 113 | resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz#be8ef2c3e1d99fca2d25c416b297d00360623596" 114 | integrity sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ== 115 | 116 | "@esbuild/linux-loong64@0.25.4": 117 | version "0.25.4" 118 | resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz#b0840a2707c3fc02eec288d3f9defa3827cd7a87" 119 | integrity sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA== 120 | 121 | "@esbuild/linux-mips64el@0.25.4": 122 | version "0.25.4" 123 | resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz#2a198e5a458c9f0e75881a4e63d26ba0cf9df39f" 124 | integrity sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg== 125 | 126 | "@esbuild/linux-ppc64@0.25.4": 127 | version "0.25.4" 128 | resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz#64f4ae0b923d7dd72fb860b9b22edb42007cf8f5" 129 | integrity sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag== 130 | 131 | "@esbuild/linux-riscv64@0.25.4": 132 | version "0.25.4" 133 | resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz#fb2844b11fdddd39e29d291c7cf80f99b0d5158d" 134 | integrity sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA== 135 | 136 | "@esbuild/linux-s390x@0.25.4": 137 | version "0.25.4" 138 | resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz#1466876e0aa3560c7673e63fdebc8278707bc750" 139 | integrity sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g== 140 | 141 | "@esbuild/linux-x64@0.25.4": 142 | version "0.25.4" 143 | resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz#c10fde899455db7cba5f11b3bccfa0e41bf4d0cd" 144 | integrity sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA== 145 | 146 | "@esbuild/netbsd-arm64@0.25.4": 147 | version "0.25.4" 148 | resolved "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz#02e483fbcbe3f18f0b02612a941b77be76c111a4" 149 | integrity sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ== 150 | 151 | "@esbuild/netbsd-x64@0.25.4": 152 | version "0.25.4" 153 | resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz#ec401fb0b1ed0ac01d978564c5fc8634ed1dc2ed" 154 | integrity sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw== 155 | 156 | "@esbuild/openbsd-arm64@0.25.4": 157 | version "0.25.4" 158 | resolved "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz#f272c2f41cfea1d91b93d487a51b5c5ca7a8c8c4" 159 | integrity sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A== 160 | 161 | "@esbuild/openbsd-x64@0.25.4": 162 | version "0.25.4" 163 | resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz#2e25950bc10fa9db1e5c868e3d50c44f7c150fd7" 164 | integrity sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw== 165 | 166 | "@esbuild/sunos-x64@0.25.4": 167 | version "0.25.4" 168 | resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz#cd596fa65a67b3b7adc5ecd52d9f5733832e1abd" 169 | integrity sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q== 170 | 171 | "@esbuild/win32-arm64@0.25.4": 172 | version "0.25.4" 173 | resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz#b4dbcb57b21eeaf8331e424c3999b89d8951dc88" 174 | integrity sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ== 175 | 176 | "@esbuild/win32-ia32@0.25.4": 177 | version "0.25.4" 178 | resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz#410842e5d66d4ece1757634e297a87635eb82f7a" 179 | integrity sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg== 180 | 181 | "@esbuild/win32-x64@0.25.4": 182 | version "0.25.4" 183 | resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz#0b17ec8a70b2385827d52314c1253160a0b9bacc" 184 | integrity sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ== 185 | 186 | "@fastify/busboy@^2.0.0": 187 | version "2.1.1" 188 | resolved "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" 189 | integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== 190 | 191 | "@img/sharp-darwin-arm64@0.33.5": 192 | version "0.33.5" 193 | resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz#ef5b5a07862805f1e8145a377c8ba6e98813ca08" 194 | integrity sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ== 195 | optionalDependencies: 196 | "@img/sharp-libvips-darwin-arm64" "1.0.4" 197 | 198 | "@img/sharp-darwin-x64@0.33.5": 199 | version "0.33.5" 200 | resolved "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz#e03d3451cd9e664faa72948cc70a403ea4063d61" 201 | integrity sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q== 202 | optionalDependencies: 203 | "@img/sharp-libvips-darwin-x64" "1.0.4" 204 | 205 | "@img/sharp-libvips-darwin-arm64@1.0.4": 206 | version "1.0.4" 207 | resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz#447c5026700c01a993c7804eb8af5f6e9868c07f" 208 | integrity sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg== 209 | 210 | "@img/sharp-libvips-darwin-x64@1.0.4": 211 | version "1.0.4" 212 | resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz#e0456f8f7c623f9dbfbdc77383caa72281d86062" 213 | integrity sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ== 214 | 215 | "@img/sharp-libvips-linux-arm64@1.0.4": 216 | version "1.0.4" 217 | resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz#979b1c66c9a91f7ff2893556ef267f90ebe51704" 218 | integrity sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA== 219 | 220 | "@img/sharp-libvips-linux-arm@1.0.5": 221 | version "1.0.5" 222 | resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz#99f922d4e15216ec205dcb6891b721bfd2884197" 223 | integrity sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g== 224 | 225 | "@img/sharp-libvips-linux-s390x@1.0.4": 226 | version "1.0.4" 227 | resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz#f8a5eb1f374a082f72b3f45e2fb25b8118a8a5ce" 228 | integrity sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA== 229 | 230 | "@img/sharp-libvips-linux-x64@1.0.4": 231 | version "1.0.4" 232 | resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz#d4c4619cdd157774906e15770ee119931c7ef5e0" 233 | integrity sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw== 234 | 235 | "@img/sharp-libvips-linuxmusl-arm64@1.0.4": 236 | version "1.0.4" 237 | resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz#166778da0f48dd2bded1fa3033cee6b588f0d5d5" 238 | integrity sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA== 239 | 240 | "@img/sharp-libvips-linuxmusl-x64@1.0.4": 241 | version "1.0.4" 242 | resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz#93794e4d7720b077fcad3e02982f2f1c246751ff" 243 | integrity sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw== 244 | 245 | "@img/sharp-linux-arm64@0.33.5": 246 | version "0.33.5" 247 | resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz#edb0697e7a8279c9fc829a60fc35644c4839bb22" 248 | integrity sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA== 249 | optionalDependencies: 250 | "@img/sharp-libvips-linux-arm64" "1.0.4" 251 | 252 | "@img/sharp-linux-arm@0.33.5": 253 | version "0.33.5" 254 | resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz#422c1a352e7b5832842577dc51602bcd5b6f5eff" 255 | integrity sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ== 256 | optionalDependencies: 257 | "@img/sharp-libvips-linux-arm" "1.0.5" 258 | 259 | "@img/sharp-linux-s390x@0.33.5": 260 | version "0.33.5" 261 | resolved "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz#f5c077926b48e97e4a04d004dfaf175972059667" 262 | integrity sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q== 263 | optionalDependencies: 264 | "@img/sharp-libvips-linux-s390x" "1.0.4" 265 | 266 | "@img/sharp-linux-x64@0.33.5": 267 | version "0.33.5" 268 | resolved "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz#d806e0afd71ae6775cc87f0da8f2d03a7c2209cb" 269 | integrity sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA== 270 | optionalDependencies: 271 | "@img/sharp-libvips-linux-x64" "1.0.4" 272 | 273 | "@img/sharp-linuxmusl-arm64@0.33.5": 274 | version "0.33.5" 275 | resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz#252975b915894fb315af5deea174651e208d3d6b" 276 | integrity sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g== 277 | optionalDependencies: 278 | "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" 279 | 280 | "@img/sharp-linuxmusl-x64@0.33.5": 281 | version "0.33.5" 282 | resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz#3f4609ac5d8ef8ec7dadee80b560961a60fd4f48" 283 | integrity sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw== 284 | optionalDependencies: 285 | "@img/sharp-libvips-linuxmusl-x64" "1.0.4" 286 | 287 | "@img/sharp-wasm32@0.33.5": 288 | version "0.33.5" 289 | resolved "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz#6f44f3283069d935bb5ca5813153572f3e6f61a1" 290 | integrity sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg== 291 | dependencies: 292 | "@emnapi/runtime" "^1.2.0" 293 | 294 | "@img/sharp-win32-ia32@0.33.5": 295 | version "0.33.5" 296 | resolved "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz#1a0c839a40c5351e9885628c85f2e5dfd02b52a9" 297 | integrity sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ== 298 | 299 | "@img/sharp-win32-x64@0.33.5": 300 | version "0.33.5" 301 | resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz#56f00962ff0c4e0eb93d34a047d29fa995e3e342" 302 | integrity sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg== 303 | 304 | "@jridgewell/resolve-uri@^3.0.3": 305 | version "3.1.2" 306 | resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" 307 | integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== 308 | 309 | "@jridgewell/sourcemap-codec@^1.4.10": 310 | version "1.4.15" 311 | resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" 312 | integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== 313 | 314 | "@jridgewell/trace-mapping@0.3.9": 315 | version "0.3.9" 316 | resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" 317 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== 318 | dependencies: 319 | "@jridgewell/resolve-uri" "^3.0.3" 320 | "@jridgewell/sourcemap-codec" "^1.4.10" 321 | 322 | acorn-walk@8.3.2: 323 | version "8.3.2" 324 | resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" 325 | integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== 326 | 327 | acorn@8.14.0: 328 | version "8.14.0" 329 | resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" 330 | integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== 331 | 332 | as-table@^1.0.36: 333 | version "1.0.55" 334 | resolved "https://registry.npmjs.org/as-table/-/as-table-1.0.55.tgz#dc984da3937745de902cea1d45843c01bdbbec4f" 335 | integrity sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ== 336 | dependencies: 337 | printable-characters "^1.0.42" 338 | 339 | blake3-wasm@2.1.5: 340 | version "2.1.5" 341 | resolved "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz#b22dbb84bc9419ed0159caa76af4b1b132e6ba52" 342 | integrity sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g== 343 | 344 | color-convert@^2.0.1: 345 | version "2.0.1" 346 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 347 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 348 | dependencies: 349 | color-name "~1.1.4" 350 | 351 | color-name@^1.0.0, color-name@~1.1.4: 352 | version "1.1.4" 353 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 354 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 355 | 356 | color-string@^1.9.0: 357 | version "1.9.1" 358 | resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" 359 | integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== 360 | dependencies: 361 | color-name "^1.0.0" 362 | simple-swizzle "^0.2.2" 363 | 364 | color@^4.2.3: 365 | version "4.2.3" 366 | resolved "https://registry.npmjs.org/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" 367 | integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== 368 | dependencies: 369 | color-convert "^2.0.1" 370 | color-string "^1.9.0" 371 | 372 | cookie@^0.7.1: 373 | version "0.7.2" 374 | resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" 375 | integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== 376 | 377 | data-uri-to-buffer@^2.0.0: 378 | version "2.0.2" 379 | resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz#d296973d5a4897a5dbe31716d118211921f04770" 380 | integrity sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA== 381 | 382 | defu@^6.1.4: 383 | version "6.1.4" 384 | resolved "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" 385 | integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== 386 | 387 | detect-libc@^2.0.3: 388 | version "2.0.4" 389 | resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz#f04715b8ba815e53b4d8109655b6508a6865a7e8" 390 | integrity sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA== 391 | 392 | esbuild@0.25.4: 393 | version "0.25.4" 394 | resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz#bb9a16334d4ef2c33c7301a924b8b863351a0854" 395 | integrity sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q== 396 | optionalDependencies: 397 | "@esbuild/aix-ppc64" "0.25.4" 398 | "@esbuild/android-arm" "0.25.4" 399 | "@esbuild/android-arm64" "0.25.4" 400 | "@esbuild/android-x64" "0.25.4" 401 | "@esbuild/darwin-arm64" "0.25.4" 402 | "@esbuild/darwin-x64" "0.25.4" 403 | "@esbuild/freebsd-arm64" "0.25.4" 404 | "@esbuild/freebsd-x64" "0.25.4" 405 | "@esbuild/linux-arm" "0.25.4" 406 | "@esbuild/linux-arm64" "0.25.4" 407 | "@esbuild/linux-ia32" "0.25.4" 408 | "@esbuild/linux-loong64" "0.25.4" 409 | "@esbuild/linux-mips64el" "0.25.4" 410 | "@esbuild/linux-ppc64" "0.25.4" 411 | "@esbuild/linux-riscv64" "0.25.4" 412 | "@esbuild/linux-s390x" "0.25.4" 413 | "@esbuild/linux-x64" "0.25.4" 414 | "@esbuild/netbsd-arm64" "0.25.4" 415 | "@esbuild/netbsd-x64" "0.25.4" 416 | "@esbuild/openbsd-arm64" "0.25.4" 417 | "@esbuild/openbsd-x64" "0.25.4" 418 | "@esbuild/sunos-x64" "0.25.4" 419 | "@esbuild/win32-arm64" "0.25.4" 420 | "@esbuild/win32-ia32" "0.25.4" 421 | "@esbuild/win32-x64" "0.25.4" 422 | 423 | exit-hook@2.2.1: 424 | version "2.2.1" 425 | resolved "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz#007b2d92c6428eda2b76e7016a34351586934593" 426 | integrity sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw== 427 | 428 | exsolve@^1.0.4: 429 | version "1.0.5" 430 | resolved "https://registry.npmjs.org/exsolve/-/exsolve-1.0.5.tgz#1f5b6b4fe82ad6b28a173ccb955a635d77859dcf" 431 | integrity sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg== 432 | 433 | fsevents@~2.3.2: 434 | version "2.3.3" 435 | resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" 436 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 437 | 438 | get-source@^2.0.12: 439 | version "2.0.12" 440 | resolved "https://registry.npmjs.org/get-source/-/get-source-2.0.12.tgz#0b47d57ea1e53ce0d3a69f4f3d277eb8047da944" 441 | integrity sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w== 442 | dependencies: 443 | data-uri-to-buffer "^2.0.0" 444 | source-map "^0.6.1" 445 | 446 | glob-to-regexp@0.4.1: 447 | version "0.4.1" 448 | resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" 449 | integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== 450 | 451 | is-arrayish@^0.3.1: 452 | version "0.3.2" 453 | resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" 454 | integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== 455 | 456 | itty-router@v4.0.23: 457 | version "4.0.23" 458 | resolved "https://registry.npmjs.org/itty-router/-/itty-router-4.0.23.tgz#44bb79134567773d3356e9972913e8fd6ed8a7a0" 459 | integrity sha512-tP1NI8PVK43vWlBnIPqj47ni5FDSczFviA4wgBznscndo8lEvBA+pO3DD1rNbIQPcZhprr775iUTunyGvQMcBw== 460 | 461 | mime@^3.0.0: 462 | version "3.0.0" 463 | resolved "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" 464 | integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== 465 | 466 | miniflare@4.20250507.0: 467 | version "4.20250507.0" 468 | resolved "https://registry.npmjs.org/miniflare/-/miniflare-4.20250507.0.tgz#64b5d4290baaaea8b4e4ff7dfaf4d77b8246477d" 469 | integrity sha512-EgbQRt/Hnr8HCmW2J/4LRNE3yOzJTdNd98XJ8gnGXFKcimXxUFPiWP3k1df+ZPCtEHp6cXxi8+jP7v9vuIbIsg== 470 | dependencies: 471 | "@cspotcode/source-map-support" "0.8.1" 472 | acorn "8.14.0" 473 | acorn-walk "8.3.2" 474 | exit-hook "2.2.1" 475 | glob-to-regexp "0.4.1" 476 | stoppable "1.1.0" 477 | undici "^5.28.5" 478 | workerd "1.20250507.0" 479 | ws "8.18.0" 480 | youch "3.3.4" 481 | zod "3.22.3" 482 | 483 | mustache@^4.2.0: 484 | version "4.2.0" 485 | resolved "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" 486 | integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== 487 | 488 | ohash@^2.0.11: 489 | version "2.0.11" 490 | resolved "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz#60b11e8cff62ca9dee88d13747a5baa145f5900b" 491 | integrity sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ== 492 | 493 | path-to-regexp@6.3.0: 494 | version "6.3.0" 495 | resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4" 496 | integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== 497 | 498 | pathe@^2.0.3: 499 | version "2.0.3" 500 | resolved "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716" 501 | integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== 502 | 503 | printable-characters@^1.0.42: 504 | version "1.0.42" 505 | resolved "https://registry.npmjs.org/printable-characters/-/printable-characters-1.0.42.tgz#3f18e977a9bd8eb37fcc4ff5659d7be90868b3d8" 506 | integrity sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ== 507 | 508 | semver@^7.6.3: 509 | version "7.7.2" 510 | resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" 511 | integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== 512 | 513 | sharp@^0.33.5: 514 | version "0.33.5" 515 | resolved "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz#13e0e4130cc309d6a9497596715240b2ec0c594e" 516 | integrity sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw== 517 | dependencies: 518 | color "^4.2.3" 519 | detect-libc "^2.0.3" 520 | semver "^7.6.3" 521 | optionalDependencies: 522 | "@img/sharp-darwin-arm64" "0.33.5" 523 | "@img/sharp-darwin-x64" "0.33.5" 524 | "@img/sharp-libvips-darwin-arm64" "1.0.4" 525 | "@img/sharp-libvips-darwin-x64" "1.0.4" 526 | "@img/sharp-libvips-linux-arm" "1.0.5" 527 | "@img/sharp-libvips-linux-arm64" "1.0.4" 528 | "@img/sharp-libvips-linux-s390x" "1.0.4" 529 | "@img/sharp-libvips-linux-x64" "1.0.4" 530 | "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" 531 | "@img/sharp-libvips-linuxmusl-x64" "1.0.4" 532 | "@img/sharp-linux-arm" "0.33.5" 533 | "@img/sharp-linux-arm64" "0.33.5" 534 | "@img/sharp-linux-s390x" "0.33.5" 535 | "@img/sharp-linux-x64" "0.33.5" 536 | "@img/sharp-linuxmusl-arm64" "0.33.5" 537 | "@img/sharp-linuxmusl-x64" "0.33.5" 538 | "@img/sharp-wasm32" "0.33.5" 539 | "@img/sharp-win32-ia32" "0.33.5" 540 | "@img/sharp-win32-x64" "0.33.5" 541 | 542 | simple-swizzle@^0.2.2: 543 | version "0.2.2" 544 | resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" 545 | integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== 546 | dependencies: 547 | is-arrayish "^0.3.1" 548 | 549 | source-map@^0.6.1: 550 | version "0.6.1" 551 | resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 552 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 553 | 554 | stacktracey@^2.1.8: 555 | version "2.1.8" 556 | resolved "https://registry.npmjs.org/stacktracey/-/stacktracey-2.1.8.tgz#bf9916020738ce3700d1323b32bd2c91ea71199d" 557 | integrity sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw== 558 | dependencies: 559 | as-table "^1.0.36" 560 | get-source "^2.0.12" 561 | 562 | stoppable@1.1.0: 563 | version "1.1.0" 564 | resolved "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b" 565 | integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== 566 | 567 | tslib@^2.4.0: 568 | version "2.8.1" 569 | resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" 570 | integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== 571 | 572 | ufo@^1.5.4: 573 | version "1.6.1" 574 | resolved "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b" 575 | integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA== 576 | 577 | undici@^5.28.5: 578 | version "5.29.0" 579 | resolved "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz#419595449ae3f2cdcba3580a2e8903399bd1f5a3" 580 | integrity sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg== 581 | dependencies: 582 | "@fastify/busboy" "^2.0.0" 583 | 584 | unenv@2.0.0-rc.15: 585 | version "2.0.0-rc.15" 586 | resolved "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.15.tgz#7fe427b6634f00bda1ade4fecdbc6b2dd7af63be" 587 | integrity sha512-J/rEIZU8w6FOfLNz/hNKsnY+fFHWnu9MH4yRbSZF3xbbGHovcetXPs7sD+9p8L6CeNC//I9bhRYAOsBt2u7/OA== 588 | dependencies: 589 | defu "^6.1.4" 590 | exsolve "^1.0.4" 591 | ohash "^2.0.11" 592 | pathe "^2.0.3" 593 | ufo "^1.5.4" 594 | 595 | workerd@1.20250507.0: 596 | version "1.20250507.0" 597 | resolved "https://registry.npmjs.org/workerd/-/workerd-1.20250507.0.tgz#a159414e6f4ee16844feb95f667bf60737b7ecde" 598 | integrity sha512-OXaGjEh5THT9iblwWIyPrYBoaPe/d4zN03Go7/w8CmS8sma7//O9hjbk43sboWkc89taGPmU0/LNyZUUiUlHeQ== 599 | optionalDependencies: 600 | "@cloudflare/workerd-darwin-64" "1.20250507.0" 601 | "@cloudflare/workerd-darwin-arm64" "1.20250507.0" 602 | "@cloudflare/workerd-linux-64" "1.20250507.0" 603 | "@cloudflare/workerd-linux-arm64" "1.20250507.0" 604 | "@cloudflare/workerd-windows-64" "1.20250507.0" 605 | 606 | wrangler@4: 607 | version "4.14.4" 608 | resolved "https://registry.npmjs.org/wrangler/-/wrangler-4.14.4.tgz#2c81e084babe3e0e8f01d477c9db171156dbb4e0" 609 | integrity sha512-HIdOdiMIcJV5ymw80RKsr3Uzen/p1kRX4jnCEmR2XVeoEhV2Qw6GABxS5WMTlSES2/vEX0Y+ezUAdsprcUhJ5g== 610 | dependencies: 611 | "@cloudflare/kv-asset-handler" "0.4.0" 612 | "@cloudflare/unenv-preset" "2.3.1" 613 | blake3-wasm "2.1.5" 614 | esbuild "0.25.4" 615 | miniflare "4.20250507.0" 616 | path-to-regexp "6.3.0" 617 | unenv "2.0.0-rc.15" 618 | workerd "1.20250507.0" 619 | optionalDependencies: 620 | fsevents "~2.3.2" 621 | sharp "^0.33.5" 622 | 623 | ws@8.18.0: 624 | version "8.18.0" 625 | resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" 626 | integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== 627 | 628 | youch@3.3.4: 629 | version "3.3.4" 630 | resolved "https://registry.npmjs.org/youch/-/youch-3.3.4.tgz#f13ee0966846c6200e7fb9ece89306d95df5e489" 631 | integrity sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg== 632 | dependencies: 633 | cookie "^0.7.1" 634 | mustache "^4.2.0" 635 | stacktracey "^2.1.8" 636 | 637 | zod@3.22.3: 638 | version "3.22.3" 639 | resolved "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz#2fbc96118b174290d94e8896371c95629e87a060" 640 | integrity sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug== 641 | --------------------------------------------------------------------------------