@verbaly/studio 0.71.0 → 0.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -26
- package/dist/cli.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/ui/assets/index-BzEEUpQG.js +3 -0
- package/dist/ui/index.html +1 -1
- package/package.json +5 -5
- package/dist/ui/assets/index-CEYBggaa.js +0 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["readJob"],"sources":["../src/http.ts","../src/triage.ts","../src/api.ts","../src/jobs.ts","../src/actions.ts","../src/history.ts","../src/assets.ts","../src/guard.ts","../src/server.ts"],"sourcesContent":["// A client mistake is not a server fault, so the status rides with the error, not a blanket 500.\nexport class HttpError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message.startsWith('[verbaly]') ? message : `[verbaly] ${message}`);\n this.status = status;\n this.name = 'HttpError';\n }\n}\n\nexport const badRequest = (message: string) => new HttpError(400, message);\n\n// The absolute path of someone's project is not the browser's business.\nexport function scrub(message: string, root: string): string {\n return root ? message.split(root).join('.') : message;\n}\n","import type { Catalog } from '@verbaly/compiler';\n\nexport type TriageSignal = 'divergent' | 'collision' | 'echo' | 'digits' | 'code' | 'url';\n\nexport interface TriageReason {\n signal: TriageSignal;\n text: string;\n}\n\nexport type TriageResult = Record<string, TriageReason[]>;\n\n// check() already caught the structure, so these only point at the few worth reading first.\nexport interface TriageInput {\n source: Catalog;\n target: Catalog;\n reviewed: ReviewedLocale[];\n}\n\n// the locale rides with the catalog because a reason that cannot name the language explains nothing\nexport interface ReviewedLocale {\n locale: string;\n catalog: Catalog;\n}\n\nconst DIGITS = /\\d[\\d.,]*/g;\nconst URLS = /https?:\\/\\/[^\\s<)\"']+/g;\nconst CODE = /<code>([^<]+)<\\/code>/g;\n\nfunction bag(text: string, re: RegExp, normalize?: (v: string) => string): string[] {\n const found = text.match(re) ?? [];\n return (normalize ? found.map(normalize) : found).sort();\n}\n\nfunction same(a: string[], b: string[]): boolean {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n}\n\n// A number or a url at the end of a clause takes the punctuation with it, and that is not a signal.\nconst trimPunct = (v: string) => v.replace(/[.,;:!?)\\]]+$/, '');\n// A separator is idiomatic (3.09 is 3,09 in Spanish); canonizing keeps 1.5 apart from 15.\nconst bareDigits = (v: string) => trimPunct(v).replaceAll(/[.,]/g, '.');\n\nfunction push(out: TriageResult, key: string, reason: TriageReason): void {\n (out[key] ??= []).push(reason);\n}\n\n// the column is three short lines, so a reason quotes the evidence and never the whole message\nfunction clip(text: string, max = 42): string {\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\nconst quote = (text: string, max?: number) => `\"${clip(text, max)}\"`;\n\n// what the source has and the translation does not, which is the half worth naming\nfunction lost(from: string[], to: string[]): string[] {\n const rest = [...to];\n const out: string[] = [];\n for (const item of from) {\n const at = rest.indexOf(item);\n if (at < 0) out.push(item);\n else rest.splice(at, 1);\n }\n return out;\n}\n\n// \"the numbers moved\" is a label; naming the one that moved is what saves the reader a diff\nfunction movedText(kind: string, from: string[], to: string[]): string {\n const gone = lost(from, to);\n const added = lost(to, from);\n if (gone.length && added.length) {\n return `the source ${kind} ${quote(gone[0]!)}, this one ${kind} ${quote(added[0]!)}`;\n }\n if (gone.length) return `the source ${kind} ${quote(gone[0]!)} and this one does not`;\n return `this one ${kind} ${quote(added[0]!)} and the source does not`;\n}\n\nexport function triage({ source, target, reviewed }: TriageInput): TriageResult {\n // null-prototype: a source text of \"__proto__\" or \"toString\" is a string, not a member of Object\n const out: TriageResult = Object.create(null);\n const keys = Object.keys(source);\n\n // One source text that two humans rendered two ways is ambiguous, so the machine had no chance.\n const bySource: Record<string, string[]> = Object.create(null);\n for (const key of keys) {\n const text = source[key]?.trim();\n if (text) (bySource[text] ??= []).push(key);\n }\n for (const [text, group] of Object.entries(bySource)) {\n if (group.length < 2) continue;\n\n // the first reviewed locale that disagreed with itself, and the two renderings it used\n let split: { locale: string; first: string; second: string } | undefined;\n for (const { locale, catalog } of reviewed) {\n const seen = [...new Set(group.map((k) => catalog[k]?.trim() ?? '').filter(Boolean))];\n if (seen.length > 1) {\n split = { locale, first: seen[0]!, second: seen[1]! };\n break;\n }\n }\n if (split) {\n for (const key of group) {\n push(out, key, {\n signal: 'divergent',\n text: `${split.locale} already says this two ways: ${quote(split.first, 32)} and ${quote(split.second, 32)}`,\n });\n }\n }\n\n // The same ambiguity seen from the result instead of from the history.\n const targets = new Set(group.map((key) => target[key]?.trim() ?? '').filter(Boolean));\n if (!split && targets.size > 1) {\n for (const key of group) {\n const mine = target[key]?.trim() ?? '';\n const other = group.find((k) => k !== key && (target[k]?.trim() ?? '') !== mine && target[k]?.trim());\n push(out, key, {\n signal: 'collision',\n text: other\n ? `${other} has the same source text and says ${quote(target[other]!.trim())}`\n : `${quote(text)} came back as two different translations`,\n });\n }\n }\n }\n\n for (const key of keys) {\n const src = source[key]?.trim() ?? '';\n const trg = target[key]?.trim() ?? '';\n if (!src || !trg) continue;\n\n // Only the locales with an opinion on this key vote: alone it fires on every do-not-translate.\n const voters = reviewed.filter(({ catalog }) => {\n const value = catalog[key]?.trim();\n return value !== undefined && value !== '';\n });\n if (trg === src && voters.length > 0 && voters.every(({ catalog }) => catalog[key]?.trim() !== src)) {\n const names = voters.map(({ locale }) => locale).join(' and ');\n push(out, key, { signal: 'echo', text: `still the source text, and ${names} did translate it` });\n }\n\n // a translation that adds a number is idiomatic (\"refresh\" is \"F5\"); one that changes it is not\n const srcDigits = bag(src, DIGITS, bareDigits);\n const trgDigits = bag(trg, DIGITS, bareDigits);\n if (srcDigits.length > 0 && !same(srcDigits, trgDigits)) {\n push(out, key, { signal: 'digits', text: movedText('says', srcDigits, trgDigits) });\n }\n const srcUrls = bag(src, URLS, trimPunct);\n const trgUrls = bag(trg, URLS, trimPunct);\n if (!same(srcUrls, trgUrls)) {\n push(out, key, { signal: 'url', text: movedText('links to', srcUrls, trgUrls) });\n }\n const srcCode = bag(src, CODE);\n const trgCode = bag(trg, CODE);\n if (!same(srcCode, trgCode)) {\n push(out, key, { signal: 'code', text: movedText('shows the code', srcCode, trgCode) });\n }\n }\n\n return out;\n}\n","import { existsSync } from 'node:fs';\nimport { relative } from 'node:path';\nimport {\n check,\n clearDrafts,\n collectOrigins,\n doctor,\n effectiveDrafts,\n extractProject,\n loadDrafts,\n loadState,\n markDrafts,\n readCatalog,\n readState,\n recordTranslations,\n saveDrafts,\n shippedCatalogs,\n status,\n targetLocales,\n validateMessage,\n validatePair,\n writeCatalog,\n} from '@verbaly/compiler';\nimport { STATE_FILE } from '@verbaly/compiler';\nimport type {\n Catalog,\n Catalogs,\n CheckResult,\n DoctorResult,\n Drafts,\n ResolvedConfig,\n StatusResult,\n} from '@verbaly/compiler';\nimport { badRequest } from './http';\nimport { triage, type TriageResult } from './triage';\n\nexport interface StudioProblem {\n scope: string;\n message: string;\n}\n\nexport interface StudioState {\n root: string;\n dir: string;\n sourceLocale: string;\n locales: string[];\n scanning: boolean;\n catalogs: Catalogs;\n origins: Record<string, string[]>;\n status: StatusResult;\n check: CheckResult;\n drafts: Drafts;\n triage: Record<string, TriageResult>;\n problems: StudioProblem[];\n}\n\n// A locale nobody can parse must not take the panel down: Studio is what you open to fix it.\nfunction readAll(cfg: ResolvedConfig): { catalogs: Catalogs; problems: StudioProblem[] } {\n const catalogs: Catalogs = {};\n const problems: StudioProblem[] = [];\n // an empty green panel and a wrong --root look identical, and only this line tells them apart\n if (!existsSync(cfg.dir)) {\n const dir = relative(cfg.root, cfg.dir).replaceAll('\\\\', '/');\n problems.push({ scope: dir, message: '[verbaly] no catalogs here, run npx verbaly init or check --root' });\n }\n for (const locale of cfg.locales) {\n try {\n catalogs[locale] = readCatalog(cfg, locale);\n } catch (error) {\n catalogs[locale] = {};\n problems.push({\n scope: locale,\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n return { catalogs, problems };\n}\n\n\n// check() reports the files a key was used in as absolute paths, origins already do not.\nfunction relativize(cfg: ResolvedConfig, result: CheckResult): CheckResult {\n const rel = (file: string): string => relative(cfg.root, file).replaceAll('\\\\', '/');\n return {\n ...result,\n unknown: result.unknown.map((entry) => ({ ...entry, files: entry.files.map(rel) })),\n extra: result.extra.map((entry) => ({ ...entry, files: entry.files.map(rel) })),\n collisions: result.collisions.map((entry) => ({\n ...entry,\n sites: entry.sites.map((at) => ({ ...at, file: rel(at.file) })),\n })),\n divergent: result.divergent.map((entry) => ({\n ...entry,\n code: { ...entry.code, file: rel(entry.code.file) },\n })),\n };\n}\n\n// One shot and unpaginated: the biggest catalog we know is past 1600 messages, instant locally.\nexport async function buildState(cfg: ResolvedConfig): Promise<StudioState> {\n const { catalogs, problems } = readAll(cfg);\n const registry = await extractProject(cfg);\n // a lock nobody can parse is the other file Studio is there to fix: it degrades like a catalog\n const { state: sidecar, problem } = readState(cfg);\n if (problem) problems.push({ scope: STATE_FILE, message: problem });\n const live = effectiveDrafts(sidecar.drafts, catalogs);\n const source = (catalogs[cfg.sourceLocale] ?? {}) as Catalog;\n const targets = targetLocales(cfg);\n\n for (const { file, message } of registry.parseErrors()) {\n problems.push({ scope: relative(cfg.root, file).replaceAll('\\\\', '/'), message });\n }\n\n const perLocale: Record<string, TriageResult> = {};\n for (const locale of targets) {\n perLocale[locale] = triage({\n source,\n target: (catalogs[locale] ?? {}) as Catalog,\n // a locale still carrying drafts has not been reviewed, so it cannot be the control\n reviewed: targets\n .filter((other) => other !== locale && !(live[other] ?? []).length)\n .map((other) => ({ locale: other, catalog: (catalogs[other] ?? {}) as Catalog })),\n });\n }\n\n return {\n root: cfg.root,\n dir: cfg.dir,\n sourceLocale: cfg.sourceLocale,\n locales: cfg.locales,\n // with include: [] nothing is scanned, so an empty origins map is off, not \"none found\"\n scanning: cfg.include.length > 0,\n catalogs,\n origins: await collectOrigins(cfg, registry),\n status: status(cfg, catalogs, registry, live, sidecar.fingerprints),\n check: relativize(cfg, check(cfg, catalogs, registry, sidecar.fingerprints)),\n drafts: live,\n triage: perLocale,\n problems,\n };\n}\n\nexport function health(cfg: ResolvedConfig): Promise<DoctorResult> {\n return doctor(cfg);\n}\n\nexport interface WriteMessageResult {\n locale: string;\n key: string;\n clearedDraft: boolean;\n}\n\n// A human wrote it, so it is reviewed and stamped for the text that ships, as import does.\nexport async function writeMessage(\n cfg: ResolvedConfig,\n locale: string,\n key: string,\n text: string,\n): Promise<WriteMessageResult> {\n if (locale === cfg.sourceLocale) {\n throw badRequest('the source text lives in your code, Studio never edits it');\n }\n if (!cfg.locales.includes(locale)) {\n throw badRequest(`${locale} is not one of this project's locales`);\n }\n // the review state is written after the catalog: an unreadable one stops the save before it\n const before = loadState(cfg);\n const catalogs = { [cfg.sourceLocale]: readCatalog(cfg, cfg.sourceLocale) };\n const registry = await extractProject(cfg);\n // checked against the text that ships, the one check reads every translation against\n const source = shippedCatalogs(cfg, catalogs, registry, { newKeys: false })[cfg.sourceLocale]!;\n // hasOwn, not `in`: `in` walks the prototype, so toString and __proto__ would pass this guard\n if (!Object.hasOwn(source, key)) {\n throw badRequest(`\"${key}\" is not in the source catalog, so Studio will not create it`);\n }\n // '' is untranslated everywhere else, so whitespace is that and not a translation to validate\n const value = text.trim() ? text : '';\n // the same two calls check() makes: validatePair alone misses a plural block with no other case\n const issues = value\n ? [...validateMessage(value, locale), ...validatePair(source[key] as string, value)]\n : [];\n const errors = issues.filter((issue) => issue.severity === 'error');\n if (errors.length) {\n throw badRequest(`${errors.map((issue) => issue.message).join('; ')}`);\n }\n\n const catalog = { ...readCatalog(cfg, locale), [key]: value };\n writeCatalog(cfg, locale, catalog);\n\n const clearedDraft = (before.drafts[locale] ?? []).includes(key);\n recordTranslations(cfg, source, [{ locale, entries: [{ key, text: value }], draft: false }]);\n return { locale, key, clearedDraft };\n}\n\nexport interface ApproveResult {\n locale: string;\n approved: number;\n keys: string[];\n}\n\n// The lock is re-read here: saveDrafts writes every locale, so a stale copy drops another's.\nexport function approve(cfg: ResolvedConfig, locale: string, keys?: string[]): ApproveResult {\n if (!cfg.locales.includes(locale)) {\n throw badRequest(`${locale} is not one of this project's locales`);\n }\n const drafts = loadDrafts(cfg);\n const had = drafts[locale] ?? [];\n // the keys it really cleared, because undo has to put back exactly those and nothing else\n const cleared = keys ? had.filter((key) => keys.includes(key)) : [...had];\n clearDrafts(drafts, locale, keys);\n saveDrafts(cfg, drafts);\n return { locale, approved: cleared.length, keys: cleared };\n}\n\n// Undo is not a nicety here: the flag records who wrote the text, so restoring it restores a fact.\nexport function unapprove(cfg: ResolvedConfig, locale: string, keys: string[]): ApproveResult {\n if (!cfg.locales.includes(locale)) {\n throw badRequest(`${locale} is not one of this project's locales`);\n }\n const drafts = loadDrafts(cfg);\n markDrafts(drafts, locale, keys);\n saveDrafts(cfg, drafts);\n return { locale, approved: keys.length, keys };\n}\n","import { badRequest, HttpError } from './http';\n\nexport type JobState = 'running' | 'done' | 'failed';\n\nexport interface Job {\n id: string;\n kind: 'translate';\n state: JobState;\n total: number;\n done: number;\n locale?: string;\n message?: string;\n result?: unknown;\n written?: number;\n kept?: number;\n}\n\n// One at a time, because two runs over the same catalogs is a race over the same files.\nlet current: Job | null = null;\nlet counter = 0;\n\nexport function running(): Job | null {\n return current?.state === 'running' ? current : null;\n}\n\nexport function read(id: string): Job {\n if (!current || current.id !== id) throw new HttpError(404, `no job called \"${id}\"`);\n return current;\n}\n\nexport function start(kind: Job['kind'], total: number): Job {\n if (running()) throw badRequest('a job is already running, wait for it or read its progress');\n counter += 1;\n current = { id: `${kind}-${counter}`, kind, state: 'running', total, done: 0 };\n return current;\n}\n\n// A batch that failed still finishes: the bar reports work attempted, and message says what broke.\nexport function advance(id: string, keys: number, locale: string, error?: string): void {\n if (current?.id !== id) return;\n current.done = Math.min(current.done + keys, current.total);\n current.locale = locale;\n if (error) current.message = error;\n}\n\n// A run that writes part of its work and then fails is a success for what it wrote, so both land.\nexport function finish(id: string, state: 'done' | 'failed', patch: Partial<Job> = {}): void {\n if (current?.id === id) Object.assign(current, patch, { state });\n}\n","import {\n collectOrigins,\n counted,\n extractProject,\n loadCatalogs,\n loadState,\n mergeTranslations,\n recordTranslations,\n resolveProvider,\n shippedCatalogs,\n syncProject,\n translateCatalogs,\n} from '@verbaly/compiler';\nimport type { ResolvedConfig, TranslationWrite } from '@verbaly/compiler';\nimport { badRequest } from './http';\nimport { advance, finish, start, type Job } from './jobs';\n\nexport interface ExtractResult {\n added: Record<string, string[]>;\n // only the source locale counts as new text: a target gains a blank for every gap it had\n found: number;\n // source texts the code wrote over, a hand edit in the catalog among them\n replaced: number;\n messages: number;\n // the lock could not be read or written: the catalogs were, its drafts and stamps were not\n stateProblem?: string;\n}\n\n// Local, fast and free, so it answers in the same request instead of becoming a job.\nexport async function runExtract(cfg: ResolvedConfig): Promise<ExtractResult> {\n if (!cfg.include.length) {\n throw badRequest('source scanning is off (include: []), so there is nothing to extract');\n }\n // the same path as the CLI: catalogs, types and the review state move together\n const result = await syncProject(cfg);\n return {\n added: result.added,\n found: result.added[cfg.sourceLocale]?.length ?? 0,\n replaced: result.replaced.length,\n messages: result.registry.messages().size,\n ...(result.stateProblem && { stateProblem: result.stateProblem }),\n };\n}\n\nexport interface Plan {\n pending: Record<string, string[]>;\n total: number;\n}\n\n// translate is the one command that spends money and minutes, so the panel always shows the bill.\nexport async function planTranslate(cfg: ResolvedConfig, locales?: string[]): Promise<Plan> {\n const provider = await resolveProvider(cfg);\n const catalogs = loadCatalogs(cfg);\n const result = await translateCatalogs(cfg, catalogs, provider, { locales, dryRun: true });\n const total = Object.values(result.pending).reduce((n, keys) => n + keys.length, 0);\n return { pending: result.pending, total };\n}\n\nexport async function startTranslate(cfg: ResolvedConfig, locales?: string[]): Promise<Job> {\n // a machine translation that lost its draft flag passes as reviewed: read the state first\n loadState(cfg);\n const provider = await resolveProvider(cfg);\n // the job carries its own denominator, so progress reads the same whether or not you asked first\n const plan = await planTranslate(cfg, locales);\n const job = start('translate', plan.total);\n const id = job.id;\n\n // the run outlives this request on purpose: the client asks the job how it is going\n void (async () => {\n try {\n const registry = await extractProject(cfg);\n // the provider reads the text that ships, which is the text its answer has to match\n const catalogs = shippedCatalogs(cfg, loadCatalogs(cfg), registry, { newKeys: false });\n const result = await translateCatalogs(cfg, catalogs, provider, {\n locales,\n batchSize: cfg.translate.batchSize,\n concurrency: cfg.translate.concurrency,\n retries: cfg.translate.retries,\n origins: await collectOrigins(cfg, registry),\n onProgress: (p) => advance(id, p.keys, p.locale, p.error),\n });\n // what a machine wrote stays a draft: the panel does not get to change that rule\n const writes: TranslationWrite[] = [];\n let written = 0;\n let kept = 0;\n for (const [locale, keys] of Object.entries(result.translated)) {\n const catalog = catalogs[locale] ?? {};\n const landed = mergeTranslations(cfg, locale, catalog, keys);\n writes.push({\n locale,\n draft: true,\n entries: landed.map((key) => ({ key, text: catalog[key]! })),\n });\n written += landed.length;\n kept += keys.length - landed.length;\n }\n recordTranslations(cfg, catalogs[cfg.sourceLocale] ?? {}, writes);\n // on a failure the panel shows only this line, so it says what landed and what did not\n const failed = result.failed[0];\n finish(id, failed ? 'failed' : 'done', {\n result,\n written,\n kept,\n message: failed\n ? `${counted(written, 'message')} translated, but ${counted(result.failed.length, 'batch', 'batches')} did not answer (${failed.error}): run it again for the rest`\n : undefined,\n });\n } catch (error) {\n finish(id, 'failed', { message: error instanceof Error ? error.message : String(error) });\n }\n })();\n\n return job;\n}\n","import { execFile, spawn } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { join, relative } from 'node:path';\nimport { parseCatalog, type Catalog, type ResolvedConfig } from '@verbaly/compiler';\n\nconst run = promisify(execFile);\n\nexport interface Commit {\n sha: string;\n author: string;\n date: string;\n subject: string;\n}\n\n// one field separator that no subject can contain, written as the escape and never as the byte\nconst FIELD = '\\u001f';\nconst FORMAT = `--format=%H${FIELD}%an${FIELD}%aI${FIELD}%s`;\n\n// the full sha is what git resolves without ambiguity, and seven characters is what a card shows\nexport function parseFullLog(stdout: string): Commit[] {\n const commits: Commit[] = [];\n for (const line of stdout.split('\\n')) {\n const [sha, author, date, ...rest] = line.split(FIELD);\n // a subject holds anything but a newline, so it is the last field and is rejoined\n if (!sha || !author || !date || !rest.length) continue;\n commits.push({ sha, author, date, subject: rest.join(FIELD) });\n }\n return commits;\n}\n\n// split out so the shape of a log line is tested without a repository and without writing one\nexport function parseLog(stdout: string): Commit[] {\n return parseFullLog(stdout).map((commit) => ({ ...commit, sha: commit.sha.slice(0, 7) }));\n}\n\n// git is asked, never assumed: no repository and no git both mean there is no history to show\nexport async function catalogHistory(cfg: ResolvedConfig, limit = 5): Promise<Commit[]> {\n const dir = relative(cfg.root, cfg.dir).replaceAll('\\\\', '/') || '.';\n try {\n const { stdout } = await run('git', ['log', `-n${limit}`, FORMAT, '--', dir], {\n cwd: cfg.root,\n timeout: 3000,\n windowsHide: true,\n });\n return parseLog(stdout);\n } catch {\n return [];\n }\n}\n\nexport interface Revision {\n commit: Commit;\n now: Catalog | undefined;\n before: Catalog | undefined;\n}\n\n// blame measured 26% wrong on verbaly-web: a sibling's comma rewrites a line, a value does not\nexport function attribute(\n revisions: Revision[],\n owners = new Map<string, Commit>(),\n): Map<string, Commit> {\n for (const { commit, now, before } of revisions) {\n if (!now || !before) continue;\n for (const key of new Set([...Object.keys(now), ...Object.keys(before)])) {\n if (!owners.has(key) && now[key] !== before[key]) owners.set(key, commit);\n }\n }\n return owners;\n}\n\n// a key can move in more than one catalog, so the answer is the newest of the per-file answers\nexport function mergeOwners(maps: Map<string, Commit>[]): Map<string, Commit> {\n const merged = new Map<string, Commit>();\n for (const map of maps) {\n for (const [key, commit] of map) {\n const held = merged.get(key);\n if (!held || Date.parse(commit.date) > Date.parse(held.date)) merged.set(key, commit);\n }\n }\n return merged;\n}\n\nconst BLOB = /^[0-9a-f]{40} \\w+ (\\d+)$/;\n\n// git cat-file --batch answers every revision in one process: a header line, then that many bytes\nfunction readBlobs(\n root: string,\n requests: string[],\n take: (index: number, body: string | null, blob: string) => void,\n): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn('git', ['cat-file', '--batch'], { cwd: root, windowsHide: true });\n // a killed batch leaves a half map, and a half map answers \"never committed\" for the rest\n const stop = setTimeout(() => {\n ok = false;\n child.kill();\n }, 20000);\n let pending: Buffer = Buffer.alloc(0);\n let index = 0;\n let ok = true;\n const fail = () => {\n ok = false;\n };\n child.on('error', fail);\n child.stdin.on('error', fail);\n child.stdout.on('data', (chunk: Buffer) => {\n pending = pending.length ? Buffer.concat([pending, chunk]) : chunk;\n for (;;) {\n const end = pending.indexOf(10);\n if (end < 0) break;\n const header = pending.toString('utf8', 0, end);\n const blob = BLOB.exec(header);\n // anything but a blob header is a revision git could not resolve, which is an answer too\n if (!blob) {\n take(index++, null, '');\n pending = pending.subarray(end + 1);\n continue;\n }\n const size = Number(blob[1]);\n if (pending.length < end + size + 2) break;\n take(index++, pending.toString('utf8', end + 1, end + 1 + size), header.slice(0, 40));\n pending = pending.subarray(end + size + 2);\n }\n });\n child.on('close', () => {\n clearTimeout(stop);\n resolve(ok);\n });\n child.stdin.end(requests.join('\\n') + '\\n');\n });\n}\n\nexport interface KeyHistory {\n owners: Map<string, Commit>;\n committed: Set<string>;\n ok: boolean;\n}\n\n// the window a local tool is willing to read: past this, the answer is \"older than what I read\"\nconst WINDOW = 200;\n\nasync function walkFile(root: string, file: string, limit: number) {\n const { stdout } = await run('git', ['log', `-n${limit}`, FORMAT, '--', file], {\n cwd: root,\n timeout: 5000,\n windowsHide: true,\n maxBuffer: 8_000_000,\n });\n const commits = parseFullLog(stdout);\n if (!commits.length) return { owners: new Map<string, Commit>(), head: [] as string[] };\n\n const owners = new Map<string, Commit>();\n let head: string[] = [];\n let waiting: Catalog | undefined;\n // only two flat catalogs are ever live, and the pair shares a blob, so one entry caches it\n let last: { blob: string; flat: Catalog | undefined } | null = null;\n const parse = (body: string | null, blob: string): Catalog | undefined => {\n if (body === null) return {};\n if (last && last.blob === blob) return last.flat;\n const flat = parseCatalog(body);\n last = { blob, flat };\n return flat;\n };\n\n const whole = await readBlobs(\n root,\n commits.flatMap((commit) => [`${commit.sha}:${file}`, `${commit.sha}^:${file}`]),\n (index, body, blob) => {\n const flat = parse(body, blob);\n if (index % 2 === 0) {\n waiting = flat;\n if (index === 0 && flat) head = Object.keys(flat);\n return;\n }\n const commit = commits[(index - 1) / 2];\n if (commit) attribute([{ commit, now: waiting, before: flat }], owners);\n waiting = undefined;\n },\n );\n if (!whole) throw new Error('[verbaly] git could not read every revision of this catalog');\n return { owners, head };\n}\n\n// The whole map at once, because a per-key query costs a git process and every row has a menu.\nexport async function catalogKeyHistory(\n cfg: ResolvedConfig,\n limit = WINDOW,\n): Promise<KeyHistory> {\n const maps: Map<string, Commit>[] = [];\n const committed = new Set<string>();\n let ok = false;\n for (const locale of cfg.locales) {\n const file = relative(cfg.root, join(cfg.dir, `${locale}.json`)).replaceAll('\\\\', '/');\n try {\n const walked = await walkFile(cfg.root, file, limit);\n maps.push(walked.owners);\n for (const key of walked.head) committed.add(key);\n ok = true;\n } catch {\n // one unreadable locale is not the end of the walk: the others still answer for their keys\n }\n }\n return { owners: mergeOwners(maps), committed, ok };\n}\n\nexport interface KeyCommit {\n key: string;\n commit: Commit | null;\n reason?: 'nogit' | 'uncommitted' | 'older';\n}\n\nconst walked = new Map<string, { head: string; history: KeyHistory }>();\n\nasync function headSha(root: string): Promise<string> {\n try {\n const { stdout } = await run('git', ['rev-parse', 'HEAD'], {\n cwd: root,\n timeout: 3000,\n windowsHide: true,\n });\n return stdout.trim();\n } catch {\n return '';\n }\n}\n\n// HEAD moving is the only thing that can change an answer, so it is what invalidates the walk\nasync function keyHistory(cfg: ResolvedConfig): Promise<KeyHistory> {\n const head = await headSha(cfg.root);\n const held = walked.get(cfg.root);\n if (held && held.head === head) return held.history;\n const history = await catalogKeyHistory(cfg);\n walked.set(cfg.root, { head, history });\n return history;\n}\n\nexport async function keyCommit(cfg: ResolvedConfig, key: string): Promise<KeyCommit> {\n const history = await keyHistory(cfg);\n if (!history.ok) return { key, commit: null, reason: 'nogit' };\n const commit = history.owners.get(key);\n // seven characters is what a person reads and pastes, and the walk needed the full one\n if (commit) return { key, commit: { ...commit, sha: commit.sha.slice(0, 7) } };\n return { key, commit: null, reason: history.committed.has(key) ? 'older' : 'uncommitted' };\n}\n","import { existsSync, readFileSync, statSync } from 'node:fs';\nimport { join, normalize, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n// the built panel sits beside the compiled server, so it is found relative to this file, never cwd\nconst UI = resolve(fileURLToPath(new URL('.', import.meta.url)), 'ui');\n\nconst TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.woff2': 'font/woff2',\n '.json': 'application/json; charset=utf-8',\n '.ico': 'image/x-icon',\n};\n\nexport interface Asset {\n body: Buffer;\n type: string;\n}\n\nexport const uiBuilt = (): boolean => existsSync(join(UI, 'index.html'));\n\n// A path is resolved and then checked to still be inside UI: ../ and an absolute one both land out.\nexport function readAsset(pathname: string): Asset | undefined {\n const wanted = pathname === '/' ? '/index.html' : pathname;\n const target = resolve(join(UI, normalize(wanted)));\n if (target !== UI && !target.startsWith(UI + (process.platform === 'win32' ? '\\\\' : '/'))) {\n return undefined;\n }\n if (!existsSync(target) || !statSync(target).isFile()) return undefined;\n const dot = target.lastIndexOf('.');\n return {\n body: readFileSync(target),\n type: TYPES[target.slice(dot).toLowerCase()] ?? 'application/octet-stream',\n };\n}\n","import { randomBytes, timingSafeEqual } from 'node:crypto';\n\nexport interface GuardOptions {\n port: number;\n token: string;\n}\n\n// A local server that writes files is reachable from any page the browser has open.\nexport function newToken(): string {\n return randomBytes(9).toString('base64url');\n}\n\n// Only the two names that resolve to this machine. A DNS rebind arrives with a foreign Host.\nexport function hostAllowed(host: string | undefined, port: number): boolean {\n // a browser omits the port when it is the scheme default, so :80 would 403 every real request\n const names = port === 80 ? ['127.0.0.1', 'localhost'] : [];\n return [`127.0.0.1:${port}`, `localhost:${port}`, ...names].includes(host ?? '');\n}\n\n// No Origin at all is a same-origin navigation or a curl, both fine; a foreign one never is.\nexport function originAllowed(origin: string | undefined, port: number): boolean {\n if (origin === undefined) return true;\n return origin === `http://127.0.0.1:${port}` || origin === `http://localhost:${port}`;\n}\n\n// Compared in constant time so the token cannot be guessed one character at a time.\nexport function tokenMatches(given: string | null, expected: string): boolean {\n if (given === null) return false;\n const a = Buffer.from(given);\n const b = Buffer.from(expected);\n return a.length === b.length && timingSafeEqual(a, b);\n}\n\nexport interface GuardVerdict {\n ok: boolean;\n status: number;\n reason: string;\n}\n\nconst PASS: GuardVerdict = { ok: true, status: 200, reason: '' };\n\nexport function guardRequest(\n headers: { host?: string; origin?: string },\n url: URL,\n { port, token }: GuardOptions,\n): GuardVerdict {\n if (!hostAllowed(headers.host, port)) {\n return { ok: false, status: 403, reason: '[verbaly] unexpected Host header' };\n }\n if (!originAllowed(headers.origin, port)) {\n return { ok: false, status: 403, reason: '[verbaly] cross-origin request' };\n }\n if (!tokenMatches(url.searchParams.get('t'), token)) {\n return { ok: false, status: 401, reason: '[verbaly] missing or wrong token, open the printed url' };\n }\n return PASS;\n}\n","import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport type { AddressInfo } from 'node:net';\nimport type { ResolvedConfig } from '@verbaly/compiler';\nimport { approve, buildState, health, unapprove, writeMessage } from './api';\nimport { planTranslate, runExtract, startTranslate } from './actions';\nimport { read as readJob, running } from './jobs';\nimport { catalogHistory, keyCommit } from './history';\nimport { readAsset, uiBuilt } from './assets';\nimport { guardRequest, newToken } from './guard';\nimport { HttpError, badRequest, scrub } from './http';\n\nexport interface StudioServer {\n server: Server;\n port: number;\n token: string;\n url: string;\n close: () => Promise<void>;\n}\n\nexport interface StartOptions {\n port?: number;\n token?: string;\n}\n\nconst DEFAULT_PORT = 4747;\nconst MAX_BODY = 1_000_000;\n\nfunction send(res: ServerResponse, status: number, body: unknown): void {\n res.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'cache-control': 'no-store',\n });\n res.end(JSON.stringify(body));\n}\n\nasync function readJson(req: IncomingMessage): Promise<Record<string, unknown>> {\n const chunks: Buffer[] = [];\n let size = 0;\n for await (const chunk of req) {\n size += (chunk as Buffer).length;\n if (size > MAX_BODY) throw new HttpError(413, 'request body too large');\n chunks.push(chunk as Buffer);\n }\n if (!chunks.length) return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(Buffer.concat(chunks).toString('utf8'));\n } catch {\n throw badRequest('body is not valid JSON');\n }\n // null and an array both pass typeof 'object', and reading .text off them is a 500\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw badRequest('body must be a JSON object');\n }\n return parsed as Record<string, unknown>;\n}\n\nfunction segment(raw: string | undefined, what: string): string {\n let value: string;\n try {\n value = decodeURIComponent(raw ?? '');\n } catch {\n throw badRequest(`the ${what} in the url is not valid percent-encoding`);\n }\n if (!value) throw badRequest(`the url is missing a ${what}`);\n return value;\n}\n\n// One page, JSON on every route: a framework would only add a dependency to a local tool.\nexport function createStudioApp(cfg: ResolvedConfig, port: number, token: string) {\n return async function handle(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // The url is built inside the try: `GET //` throws, and out here that would kill the process.\n try {\n let url: URL;\n try {\n url = new URL(req.url ?? '/', `http://127.0.0.1:${port}`);\n } catch {\n throw badRequest('the request target is not a valid url');\n }\n\n const api = url.pathname.startsWith('/api/');\n const verdict = guardRequest({ host: req.headers.host, origin: req.headers.origin }, url, {\n port,\n token,\n });\n // the panel files are the published npm package: only the project data needs a token\n if (!verdict.ok && (api || verdict.status !== 401)) {\n send(res, verdict.status, { error: verdict.reason });\n return;\n }\n\n if (!api && req.method === 'GET') {\n const asset = readAsset(url.pathname);\n if (asset) {\n res.writeHead(200, { 'content-type': asset.type, 'cache-control': 'no-store' });\n res.end(asset.body);\n return;\n }\n if (url.pathname === '/' && !uiBuilt()) {\n throw new HttpError(500, 'the panel is not in this install, so only /api/* answers here');\n }\n }\n\n if (req.method === 'GET' && url.pathname === '/api/state') {\n send(res, 200, await buildState(cfg));\n return;\n }\n if (req.method === 'GET' && url.pathname === '/api/history') {\n send(res, 200, { commits: await catalogHistory(cfg) });\n return;\n }\n if (req.method === 'GET' && url.pathname.startsWith('/api/commit/')) {\n const key = segment(url.pathname.slice('/api/commit/'.length), 'key');\n send(res, 200, await keyCommit(cfg, key));\n return;\n }\n if (req.method === 'GET' && url.pathname === '/api/health') {\n send(res, 200, await health(cfg));\n return;\n }\n if (req.method === 'PUT' && url.pathname.startsWith('/api/message/')) {\n const rest = url.pathname.slice('/api/message/'.length).split('/');\n const locale = segment(rest[0], 'locale');\n const key = segment(rest.slice(1).join('/'), 'key');\n const body = await readJson(req);\n if (typeof body.text !== 'string') throw badRequest('body needs a \"text\" string');\n send(res, 200, await writeMessage(cfg, locale, key, body.text));\n return;\n }\n if (req.method === 'POST' && url.pathname === '/api/approve') {\n const body = await readJson(req);\n if (typeof body.locale !== 'string') throw badRequest('body needs a \"locale\" string');\n const keys = Array.isArray(body.keys)\n ? body.keys.filter((k): k is string => typeof k === 'string')\n : undefined;\n if (body.undo === true) {\n if (!keys?.length) throw badRequest('undoing needs the \"keys\" it should put back');\n send(res, 200, unapprove(cfg, body.locale, keys));\n return;\n }\n send(res, 200, approve(cfg, body.locale, keys));\n return;\n }\n if (req.method === 'POST' && url.pathname === '/api/extract') {\n send(res, 200, await runExtract(cfg));\n return;\n }\n if (req.method === 'GET' && url.pathname === '/api/translate') {\n const locales = url.searchParams.getAll('locale');\n send(res, 200, await planTranslate(cfg, locales.length ? locales : undefined));\n return;\n }\n if (req.method === 'POST' && url.pathname === '/api/translate') {\n const body = await readJson(req);\n const locales = Array.isArray(body.locales)\n ? body.locales.filter((l): l is string => typeof l === 'string')\n : undefined;\n send(res, 200, await startTranslate(cfg, locales?.length ? locales : undefined));\n return;\n }\n // a reload loses the id, so the panel asks what is running rather than losing the bar\n if (req.method === 'GET' && url.pathname === '/api/job') {\n send(res, 200, running());\n return;\n }\n if (req.method === 'GET' && url.pathname.startsWith('/api/job/')) {\n send(res, 200, readJob(segment(url.pathname.slice('/api/job/'.length), 'job id')));\n return;\n }\n\n send(res, 404, { error: `[verbaly] no route for ${req.method} ${url.pathname}` });\n } catch (error) {\n const status = error instanceof HttpError ? error.status : 500;\n const message = error instanceof Error ? error.message : String(error);\n send(res, status, { error: scrub(message, cfg.root) });\n }\n };\n}\n\n// A busy port climbs instead of failing: this is a local tool, not a service on a fixed address.\nfunction listen(server: Server, port: number, attemptsLeft: number): Promise<number> {\n return new Promise((resolve, reject) => {\n const onError = (error: NodeJS.ErrnoException) => {\n if (error.code === 'EADDRINUSE' && attemptsLeft > 0) {\n server.removeListener('error', onError);\n resolve(listen(server, port + 1, attemptsLeft - 1));\n return;\n }\n reject(error);\n };\n server.once('error', onError);\n server.listen(port, '127.0.0.1', () => {\n server.removeListener('error', onError);\n // port 0 asks the system to pick, so the bound address is the only place the answer is\n const bound = server.address() as AddressInfo | string | null;\n resolve(typeof bound === 'object' && bound !== null ? bound.port : port);\n });\n });\n}\n\nexport async function startStudio(\n cfg: ResolvedConfig,\n options: StartOptions = {},\n): Promise<StudioServer> {\n const token = options.token ?? newToken();\n const server = createServer();\n // The handler is attached before listen so no request can arrive without one.\n let port = options.port ?? DEFAULT_PORT;\n server.on('request', (req, res) => void createStudioApp(cfg, port, token)(req, res));\n port = await listen(server, port, 20);\n\n return {\n server,\n port,\n token,\n url: `http://127.0.0.1:${port}/?t=${token}`,\n close: () =>\n new Promise<void>((resolve, reject) =>\n server.close((error) => (error ? reject(error) : resolve())),\n ),\n };\n}\n"],"mappings":";;;;;;;;;AACA,IAAa,YAAb,cAA+B,MAAM;CACnC;CAEA,YAAY,QAAgB,SAAiB;EAC3C,MAAM,QAAQ,WAAW,WAAW,IAAI,UAAU,aAAa,SAAS;EACxE,KAAK,SAAS;EACd,KAAK,OAAO;CACd;AACF;AAEA,MAAa,cAAc,YAAoB,IAAI,UAAU,KAAK,OAAO;AAGzE,SAAgB,MAAM,SAAiB,MAAsB;CAC3D,OAAO,OAAO,QAAQ,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI;AAChD;;;ACQA,MAAM,SAAS;AACf,MAAM,OAAO;AACb,MAAM,OAAO;AAEb,SAAS,IAAI,MAAc,IAAY,WAA6C;CAClF,MAAM,QAAQ,KAAK,MAAM,EAAE,KAAK,CAAC;CACjC,QAAQ,YAAY,MAAM,IAAI,SAAS,IAAI,MAAA,CAAO,KAAK;AACzD;AAEA,SAAS,KAAK,GAAa,GAAsB;CAC/C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,MAAM,EAAE,EAAE;AAC9D;AAGA,MAAM,aAAa,MAAc,EAAE,QAAQ,iBAAiB,EAAE;AAE9D,MAAM,cAAc,MAAc,UAAU,CAAC,CAAC,CAAC,WAAW,SAAS,GAAG;AAEtE,SAAS,KAAK,KAAmB,KAAa,QAA4B;CACxE,CAAC,IAAI,SAAS,CAAC,EAAA,CAAG,KAAK,MAAM;AAC/B;AAGA,SAAS,KAAK,MAAc,MAAM,IAAY;CAC5C,OAAO,KAAK,SAAS,MAAM,GAAG,KAAK,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK;AAC5D;AAEA,MAAM,SAAS,MAAc,QAAiB,IAAI,KAAK,MAAM,GAAG,EAAE;AAGlE,SAAS,KAAK,MAAgB,IAAwB;CACpD,MAAM,OAAO,CAAC,GAAG,EAAE;CACnB,MAAM,MAAgB,CAAC;CACvB,KAAK,MAAM,QAAQ,MAAM;EACvB,MAAM,KAAK,KAAK,QAAQ,IAAI;EAC5B,IAAI,KAAK,GAAG,IAAI,KAAK,IAAI;OACpB,KAAK,OAAO,IAAI,CAAC;CACxB;CACA,OAAO;AACT;AAGA,SAAS,UAAU,MAAc,MAAgB,IAAsB;CACrE,MAAM,OAAO,KAAK,MAAM,EAAE;CAC1B,MAAM,QAAQ,KAAK,IAAI,IAAI;CAC3B,IAAI,KAAK,UAAU,MAAM,QACvB,OAAO,cAAc,KAAK,GAAG,MAAM,KAAK,EAAG,EAAE,aAAa,KAAK,GAAG,MAAM,MAAM,EAAG;CAEnF,IAAI,KAAK,QAAQ,OAAO,cAAc,KAAK,GAAG,MAAM,KAAK,EAAG,EAAE;CAC9D,OAAO,YAAY,KAAK,GAAG,MAAM,MAAM,EAAG,EAAE;AAC9C;AAEA,SAAgB,OAAO,EAAE,QAAQ,QAAQ,YAAuC;CAE9E,MAAM,MAAoB,OAAO,OAAO,IAAI;CAC5C,MAAM,OAAO,OAAO,KAAK,MAAM;CAG/B,MAAM,WAAqC,OAAO,OAAO,IAAI;CAC7D,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,OAAO,OAAO,IAAI,EAAE,KAAK;EAC/B,IAAI,MAAM,CAAC,SAAS,UAAU,CAAC,EAAA,CAAG,KAAK,GAAG;CAC5C;CACA,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,GAAG;EACpD,IAAI,MAAM,SAAS,GAAG;EAGtB,IAAI;EACJ,KAAK,MAAM,EAAE,QAAQ,aAAa,UAAU;GAC1C,MAAM,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,KAAK,MAAM,QAAQ,EAAE,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC;GACpF,IAAI,KAAK,SAAS,GAAG;IACnB,QAAQ;KAAE;KAAQ,OAAO,KAAK;KAAK,QAAQ,KAAK;IAAI;IACpD;GACF;EACF;EACA,IAAI,OACF,KAAK,MAAM,OAAO,OAChB,KAAK,KAAK,KAAK;GACb,QAAQ;GACR,MAAM,GAAG,MAAM,OAAO,+BAA+B,MAAM,MAAM,OAAO,EAAE,EAAE,OAAO,MAAM,MAAM,QAAQ,EAAE;EAC3G,CAAC;EAKL,MAAM,UAAU,IAAI,IAAI,MAAM,KAAK,QAAQ,OAAO,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC,CAAC,OAAO,OAAO,CAAC;EACrF,IAAI,CAAC,SAAS,QAAQ,OAAO,GAC3B,KAAK,MAAM,OAAO,OAAO;GACvB,MAAM,OAAO,OAAO,IAAI,EAAE,KAAK,KAAK;GACpC,MAAM,QAAQ,MAAM,MAAM,MAAM,MAAM,QAAQ,OAAO,EAAE,EAAE,KAAK,KAAK,QAAQ,QAAQ,OAAO,EAAE,EAAE,KAAK,CAAC;GACpG,KAAK,KAAK,KAAK;IACb,QAAQ;IACR,MAAM,QACF,GAAG,MAAM,qCAAqC,MAAM,OAAO,MAAM,CAAE,KAAK,CAAC,MACzE,GAAG,MAAM,IAAI,EAAE;GACrB,CAAC;EACH;CAEJ;CAEA,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,MAAM,OAAO,IAAI,EAAE,KAAK,KAAK;EACnC,MAAM,MAAM,OAAO,IAAI,EAAE,KAAK,KAAK;EACnC,IAAI,CAAC,OAAO,CAAC,KAAK;EAGlB,MAAM,SAAS,SAAS,QAAQ,EAAE,cAAc;GAC9C,MAAM,QAAQ,QAAQ,IAAI,EAAE,KAAK;GACjC,OAAO,UAAU,KAAA,KAAa,UAAU;EAC1C,CAAC;EACD,IAAI,QAAQ,OAAO,OAAO,SAAS,KAAK,OAAO,OAAO,EAAE,cAAc,QAAQ,IAAI,EAAE,KAAK,MAAM,GAAG,GAEhG,KAAK,KAAK,KAAK;GAAE,QAAQ;GAAQ,MAAM,8BADzB,OAAO,KAAK,EAAE,aAAa,MAAM,CAAC,CAAC,KAAK,OACmB,EAAE;EAAmB,CAAC;EAIjG,MAAM,YAAY,IAAI,KAAK,QAAQ,UAAU;EAC7C,MAAM,YAAY,IAAI,KAAK,QAAQ,UAAU;EAC7C,IAAI,UAAU,SAAS,KAAK,CAAC,KAAK,WAAW,SAAS,GACpD,KAAK,KAAK,KAAK;GAAE,QAAQ;GAAU,MAAM,UAAU,QAAQ,WAAW,SAAS;EAAE,CAAC;EAEpF,MAAM,UAAU,IAAI,KAAK,MAAM,SAAS;EACxC,MAAM,UAAU,IAAI,KAAK,MAAM,SAAS;EACxC,IAAI,CAAC,KAAK,SAAS,OAAO,GACxB,KAAK,KAAK,KAAK;GAAE,QAAQ;GAAO,MAAM,UAAU,YAAY,SAAS,OAAO;EAAE,CAAC;EAEjF,MAAM,UAAU,IAAI,KAAK,IAAI;EAC7B,MAAM,UAAU,IAAI,KAAK,IAAI;EAC7B,IAAI,CAAC,KAAK,SAAS,OAAO,GACxB,KAAK,KAAK,KAAK;GAAE,QAAQ;GAAQ,MAAM,UAAU,kBAAkB,SAAS,OAAO;EAAE,CAAC;CAE1F;CAEA,OAAO;AACT;;;ACrGA,SAAS,QAAQ,KAAwE;CACvF,MAAM,WAAqB,CAAC;CAC5B,MAAM,WAA4B,CAAC;CAEnC,IAAI,CAAC,WAAW,IAAI,GAAG,GAAG;EACxB,MAAM,MAAM,SAAS,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,MAAM,GAAG;EAC5D,SAAS,KAAK;GAAE,OAAO;GAAK,SAAS;EAAmE,CAAC;CAC3G;CACA,KAAK,MAAM,UAAU,IAAI,SACvB,IAAI;EACF,SAAS,UAAU,YAAY,KAAK,MAAM;CAC5C,SAAS,OAAO;EACd,SAAS,UAAU,CAAC;EACpB,SAAS,KAAK;GACZ,OAAO;GACP,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EAChE,CAAC;CACH;CAEF,OAAO;EAAE;EAAU;CAAS;AAC9B;AAIA,SAAS,WAAW,KAAqB,QAAkC;CACzE,MAAM,OAAO,SAAyB,SAAS,IAAI,MAAM,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG;CACnF,OAAO;EACL,GAAG;EACH,SAAS,OAAO,QAAQ,KAAK,WAAW;GAAE,GAAG;GAAO,OAAO,MAAM,MAAM,IAAI,GAAG;EAAE,EAAE;EAClF,OAAO,OAAO,MAAM,KAAK,WAAW;GAAE,GAAG;GAAO,OAAO,MAAM,MAAM,IAAI,GAAG;EAAE,EAAE;EAC9E,YAAY,OAAO,WAAW,KAAK,WAAW;GAC5C,GAAG;GACH,OAAO,MAAM,MAAM,KAAK,QAAQ;IAAE,GAAG;IAAI,MAAM,IAAI,GAAG,IAAI;GAAE,EAAE;EAChE,EAAE;EACF,WAAW,OAAO,UAAU,KAAK,WAAW;GAC1C,GAAG;GACH,MAAM;IAAE,GAAG,MAAM;IAAM,MAAM,IAAI,MAAM,KAAK,IAAI;GAAE;EACpD,EAAE;CACJ;AACF;AAGA,eAAsB,WAAW,KAA2C;CAC1E,MAAM,EAAE,UAAU,aAAa,QAAQ,GAAG;CAC1C,MAAM,WAAW,MAAM,eAAe,GAAG;CAEzC,MAAM,EAAE,OAAO,SAAS,YAAY,UAAU,GAAG;CACjD,IAAI,SAAS,SAAS,KAAK;EAAE,OAAO;EAAY,SAAS;CAAQ,CAAC;CAClE,MAAM,OAAO,gBAAgB,QAAQ,QAAQ,QAAQ;CACrD,MAAM,SAAU,SAAS,IAAI,iBAAiB,CAAC;CAC/C,MAAM,UAAU,cAAc,GAAG;CAEjC,KAAK,MAAM,EAAE,MAAM,aAAa,SAAS,YAAY,GACnD,SAAS,KAAK;EAAE,OAAO,SAAS,IAAI,MAAM,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG;EAAG;CAAQ,CAAC;CAGlF,MAAM,YAA0C,CAAC;CACjD,KAAK,MAAM,UAAU,SACnB,UAAU,UAAU,OAAO;EACzB;EACA,QAAS,SAAS,WAAW,CAAC;EAE9B,UAAU,QACP,QAAQ,UAAU,UAAU,UAAU,EAAE,KAAK,UAAU,CAAC,EAAA,CAAG,MAAM,CAAC,CAClE,KAAK,WAAW;GAAE,QAAQ;GAAO,SAAU,SAAS,UAAU,CAAC;EAAc,EAAE;CACpF,CAAC;CAGH,OAAO;EACL,MAAM,IAAI;EACV,KAAK,IAAI;EACT,cAAc,IAAI;EAClB,SAAS,IAAI;EAEb,UAAU,IAAI,QAAQ,SAAS;EAC/B;EACA,SAAS,MAAM,eAAe,KAAK,QAAQ;EAC3C,QAAQ,OAAO,KAAK,UAAU,UAAU,MAAM,QAAQ,YAAY;EAClE,OAAO,WAAW,KAAK,MAAM,KAAK,UAAU,UAAU,QAAQ,YAAY,CAAC;EAC3E,QAAQ;EACR,QAAQ;EACR;CACF;AACF;AAEA,SAAgB,OAAO,KAA4C;CACjE,OAAO,OAAO,GAAG;AACnB;AASA,eAAsB,aACpB,KACA,QACA,KACA,MAC6B;CAC7B,IAAI,WAAW,IAAI,cACjB,MAAM,WAAW,2DAA2D;CAE9E,IAAI,CAAC,IAAI,QAAQ,SAAS,MAAM,GAC9B,MAAM,WAAW,GAAG,OAAO,sCAAsC;CAGnE,MAAM,SAAS,UAAU,GAAG;CAC5B,MAAM,WAAW,GAAG,IAAI,eAAe,YAAY,KAAK,IAAI,YAAY,EAAE;CAC1E,MAAM,WAAW,MAAM,eAAe,GAAG;CAEzC,MAAM,SAAS,gBAAgB,KAAK,UAAU,UAAU,EAAE,SAAS,MAAM,CAAC,CAAC,CAAC,IAAI;CAEhF,IAAI,CAAC,OAAO,OAAO,QAAQ,GAAG,GAC5B,MAAM,WAAW,IAAI,IAAI,6DAA6D;CAGxF,MAAM,QAAQ,KAAK,KAAK,IAAI,OAAO;CAKnC,MAAM,UAHS,QACX,CAAC,GAAG,gBAAgB,OAAO,MAAM,GAAG,GAAG,aAAa,OAAO,MAAgB,KAAK,CAAC,IACjF,CAAC,EAAA,CACiB,QAAQ,UAAU,MAAM,aAAa,OAAO;CAClE,IAAI,OAAO,QACT,MAAM,WAAW,GAAG,OAAO,KAAK,UAAU,MAAM,OAAO,CAAC,CAAC,KAAK,IAAI,GAAG;CAGvE,MAAM,UAAU;EAAE,GAAG,YAAY,KAAK,MAAM;GAAI,MAAM;CAAM;CAC5D,aAAa,KAAK,QAAQ,OAAO;CAEjC,MAAM,gBAAgB,OAAO,OAAO,WAAW,CAAC,EAAA,CAAG,SAAS,GAAG;CAC/D,mBAAmB,KAAK,QAAQ,CAAC;EAAE;EAAQ,SAAS,CAAC;GAAE;GAAK,MAAM;EAAM,CAAC;EAAG,OAAO;CAAM,CAAC,CAAC;CAC3F,OAAO;EAAE;EAAQ;EAAK;CAAa;AACrC;AASA,SAAgB,QAAQ,KAAqB,QAAgB,MAAgC;CAC3F,IAAI,CAAC,IAAI,QAAQ,SAAS,MAAM,GAC9B,MAAM,WAAW,GAAG,OAAO,sCAAsC;CAEnE,MAAM,SAAS,WAAW,GAAG;CAC7B,MAAM,MAAM,OAAO,WAAW,CAAC;CAE/B,MAAM,UAAU,OAAO,IAAI,QAAQ,QAAQ,KAAK,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG;CACxE,YAAY,QAAQ,QAAQ,IAAI;CAChC,WAAW,KAAK,MAAM;CACtB,OAAO;EAAE;EAAQ,UAAU,QAAQ;EAAQ,MAAM;CAAQ;AAC3D;AAGA,SAAgB,UAAU,KAAqB,QAAgB,MAA+B;CAC5F,IAAI,CAAC,IAAI,QAAQ,SAAS,MAAM,GAC9B,MAAM,WAAW,GAAG,OAAO,sCAAsC;CAEnE,MAAM,SAAS,WAAW,GAAG;CAC7B,WAAW,QAAQ,QAAQ,IAAI;CAC/B,WAAW,KAAK,MAAM;CACtB,OAAO;EAAE;EAAQ,UAAU,KAAK;EAAQ;CAAK;AAC/C;;;AC7MA,IAAI,UAAsB;AAC1B,IAAI,UAAU;AAEd,SAAgB,UAAsB;CACpC,OAAO,SAAS,UAAU,YAAY,UAAU;AAClD;AAEA,SAAgB,KAAK,IAAiB;CACpC,IAAI,CAAC,WAAW,QAAQ,OAAO,IAAI,MAAM,IAAI,UAAU,KAAK,kBAAkB,GAAG,EAAE;CACnF,OAAO;AACT;AAEA,SAAgB,MAAM,MAAmB,OAAoB;CAC3D,IAAI,QAAQ,GAAG,MAAM,WAAW,4DAA4D;CAC5F,WAAW;CACX,UAAU;EAAE,IAAI,GAAG,KAAK,GAAG;EAAW;EAAM,OAAO;EAAW;EAAO,MAAM;CAAE;CAC7E,OAAO;AACT;AAGA,SAAgB,QAAQ,IAAY,MAAc,QAAgB,OAAsB;CACtF,IAAI,SAAS,OAAO,IAAI;CACxB,QAAQ,OAAO,KAAK,IAAI,QAAQ,OAAO,MAAM,QAAQ,KAAK;CAC1D,QAAQ,SAAS;CACjB,IAAI,OAAO,QAAQ,UAAU;AAC/B;AAGA,SAAgB,OAAO,IAAY,OAA0B,QAAsB,CAAC,GAAS;CAC3F,IAAI,SAAS,OAAO,IAAI,OAAO,OAAO,SAAS,OAAO,EAAE,MAAM,CAAC;AACjE;;;ACnBA,eAAsB,WAAW,KAA6C;CAC5E,IAAI,CAAC,IAAI,QAAQ,QACf,MAAM,WAAW,sEAAsE;CAGzF,MAAM,SAAS,MAAM,YAAY,GAAG;CACpC,OAAO;EACL,OAAO,OAAO;EACd,OAAO,OAAO,MAAM,IAAI,aAAa,EAAE,UAAU;EACjD,UAAU,OAAO,SAAS;EAC1B,UAAU,OAAO,SAAS,SAAS,CAAC,CAAC;EACrC,GAAI,OAAO,gBAAgB,EAAE,cAAc,OAAO,aAAa;CACjE;AACF;AAQA,eAAsB,cAAc,KAAqB,SAAmC;CAC1F,MAAM,WAAW,MAAM,gBAAgB,GAAG;CAC1C,MAAM,WAAW,aAAa,GAAG;CACjC,MAAM,SAAS,MAAM,kBAAkB,KAAK,UAAU,UAAU;EAAE;EAAS,QAAQ;CAAK,CAAC;CACzF,MAAM,QAAQ,OAAO,OAAO,OAAO,OAAO,CAAC,CAAC,QAAQ,GAAG,SAAS,IAAI,KAAK,QAAQ,CAAC;CAClF,OAAO;EAAE,SAAS,OAAO;EAAS;CAAM;AAC1C;AAEA,eAAsB,eAAe,KAAqB,SAAkC;CAE1F,UAAU,GAAG;CACb,MAAM,WAAW,MAAM,gBAAgB,GAAG;CAG1C,MAAM,MAAM,MAAM,cAAa,MADZ,cAAc,KAAK,OAAO,EACd,CAAK,KAAK;CACzC,MAAM,KAAK,IAAI;CAGf,CAAM,YAAY;EAChB,IAAI;GACF,MAAM,WAAW,MAAM,eAAe,GAAG;GAEzC,MAAM,WAAW,gBAAgB,KAAK,aAAa,GAAG,GAAG,UAAU,EAAE,SAAS,MAAM,CAAC;GACrF,MAAM,SAAS,MAAM,kBAAkB,KAAK,UAAU,UAAU;IAC9D;IACA,WAAW,IAAI,UAAU;IACzB,aAAa,IAAI,UAAU;IAC3B,SAAS,IAAI,UAAU;IACvB,SAAS,MAAM,eAAe,KAAK,QAAQ;IAC3C,aAAa,MAAM,QAAQ,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK;GAC1D,CAAC;GAED,MAAM,SAA6B,CAAC;GACpC,IAAI,UAAU;GACd,IAAI,OAAO;GACX,KAAK,MAAM,CAAC,QAAQ,SAAS,OAAO,QAAQ,OAAO,UAAU,GAAG;IAC9D,MAAM,UAAU,SAAS,WAAW,CAAC;IACrC,MAAM,SAAS,kBAAkB,KAAK,QAAQ,SAAS,IAAI;IAC3D,OAAO,KAAK;KACV;KACA,OAAO;KACP,SAAS,OAAO,KAAK,SAAS;MAAE;MAAK,MAAM,QAAQ;KAAM,EAAE;IAC7D,CAAC;IACD,WAAW,OAAO;IAClB,QAAQ,KAAK,SAAS,OAAO;GAC/B;GACA,mBAAmB,KAAK,SAAS,IAAI,iBAAiB,CAAC,GAAG,MAAM;GAEhE,MAAM,SAAS,OAAO,OAAO;GAC7B,OAAO,IAAI,SAAS,WAAW,QAAQ;IACrC;IACA;IACA;IACA,SAAS,SACL,GAAG,QAAQ,SAAS,SAAS,EAAE,mBAAmB,QAAQ,OAAO,OAAO,QAAQ,SAAS,SAAS,EAAE,mBAAmB,OAAO,MAAM,gCACpI,KAAA;GACN,CAAC;EACH,SAAS,OAAO;GACd,OAAO,IAAI,UAAU,EAAE,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,CAAC;EAC1F;CACF,EAAA,CAAG;CAEH,OAAO;AACT;;;AC5GA,MAAM,MAAM,UAAU,QAAQ;AAU9B,MAAM,QAAQ;AACd,MAAM,SAAS,cAAc,MAAM,KAAK,MAAM,KAAK,MAAM;AAGzD,SAAgB,aAAa,QAA0B;CACrD,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,QAAQ,OAAO,MAAM,IAAI,GAAG;EACrC,MAAM,CAAC,KAAK,QAAQ,MAAM,GAAG,QAAQ,KAAK,MAAM,KAAK;EAErD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,QAAQ;EAC9C,QAAQ,KAAK;GAAE;GAAK;GAAQ;GAAM,SAAS,KAAK,KAAK,KAAK;EAAE,CAAC;CAC/D;CACA,OAAO;AACT;AAGA,SAAgB,SAAS,QAA0B;CACjD,OAAO,aAAa,MAAM,CAAC,CAAC,KAAK,YAAY;EAAE,GAAG;EAAQ,KAAK,OAAO,IAAI,MAAM,GAAG,CAAC;CAAE,EAAE;AAC1F;AAGA,eAAsB,eAAe,KAAqB,QAAQ,GAAsB;CACtF,MAAM,MAAM,SAAS,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,MAAM,GAAG,KAAK;CACjE,IAAI;EACF,MAAM,EAAE,WAAW,MAAM,IAAI,OAAO;GAAC;GAAO,KAAK;GAAS;GAAQ;GAAM;EAAG,GAAG;GAC5E,KAAK,IAAI;GACT,SAAS;GACT,aAAa;EACf,CAAC;EACD,OAAO,SAAS,MAAM;CACxB,QAAQ;EACN,OAAO,CAAC;CACV;AACF;AASA,SAAgB,UACd,WACA,yBAAS,IAAI,IAAoB,GACZ;CACrB,KAAK,MAAM,EAAE,QAAQ,KAAK,YAAY,WAAW;EAC/C,IAAI,CAAC,OAAO,CAAC,QAAQ;EACrB,KAAK,MAAM,uBAAO,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,GAAG,GAAG,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,GACrE,IAAI,CAAC,OAAO,IAAI,GAAG,KAAK,IAAI,SAAS,OAAO,MAAM,OAAO,IAAI,KAAK,MAAM;CAE5E;CACA,OAAO;AACT;AAGA,SAAgB,YAAY,MAAkD;CAC5E,MAAM,yBAAS,IAAI,IAAoB;CACvC,KAAK,MAAM,OAAO,MAChB,KAAK,MAAM,CAAC,KAAK,WAAW,KAAK;EAC/B,MAAM,OAAO,OAAO,IAAI,GAAG;EAC3B,IAAI,CAAC,QAAQ,KAAK,MAAM,OAAO,IAAI,IAAI,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,IAAI,KAAK,MAAM;CACtF;CAEF,OAAO;AACT;AAEA,MAAM,OAAO;AAGb,SAAS,UACP,MACA,UACA,MACkB;CAClB,OAAO,IAAI,SAAS,YAAY;EAC9B,MAAM,QAAQ,MAAM,OAAO,CAAC,YAAY,SAAS,GAAG;GAAE,KAAK;GAAM,aAAa;EAAK,CAAC;EAEpF,MAAM,OAAO,iBAAiB;GAC5B,KAAK;GACL,MAAM,KAAK;EACb,GAAG,GAAK;EACR,IAAI,UAAkB,OAAO,MAAM,CAAC;EACpC,IAAI,QAAQ;EACZ,IAAI,KAAK;EACT,MAAM,aAAa;GACjB,KAAK;EACP;EACA,MAAM,GAAG,SAAS,IAAI;EACtB,MAAM,MAAM,GAAG,SAAS,IAAI;EAC5B,MAAM,OAAO,GAAG,SAAS,UAAkB;GACzC,UAAU,QAAQ,SAAS,OAAO,OAAO,CAAC,SAAS,KAAK,CAAC,IAAI;GAC7D,SAAS;IACP,MAAM,MAAM,QAAQ,QAAQ,EAAE;IAC9B,IAAI,MAAM,GAAG;IACb,MAAM,SAAS,QAAQ,SAAS,QAAQ,GAAG,GAAG;IAC9C,MAAM,OAAO,KAAK,KAAK,MAAM;IAE7B,IAAI,CAAC,MAAM;KACT,KAAK,SAAS,MAAM,EAAE;KACtB,UAAU,QAAQ,SAAS,MAAM,CAAC;KAClC;IACF;IACA,MAAM,OAAO,OAAO,KAAK,EAAE;IAC3B,IAAI,QAAQ,SAAS,MAAM,OAAO,GAAG;IACrC,KAAK,SAAS,QAAQ,SAAS,QAAQ,MAAM,GAAG,MAAM,IAAI,IAAI,GAAG,OAAO,MAAM,GAAG,EAAE,CAAC;IACpF,UAAU,QAAQ,SAAS,MAAM,OAAO,CAAC;GAC3C;EACF,CAAC;EACD,MAAM,GAAG,eAAe;GACtB,aAAa,IAAI;GACjB,QAAQ,EAAE;EACZ,CAAC;EACD,MAAM,MAAM,IAAI,SAAS,KAAK,IAAI,IAAI,IAAI;CAC5C,CAAC;AACH;AASA,MAAM,SAAS;AAEf,eAAe,SAAS,MAAc,MAAc,OAAe;CACjE,MAAM,EAAE,WAAW,MAAM,IAAI,OAAO;EAAC;EAAO,KAAK;EAAS;EAAQ;EAAM;CAAI,GAAG;EAC7E,KAAK;EACL,SAAS;EACT,aAAa;EACb,WAAW;CACb,CAAC;CACD,MAAM,UAAU,aAAa,MAAM;CACnC,IAAI,CAAC,QAAQ,QAAQ,OAAO;EAAE,wBAAQ,IAAI,IAAoB;EAAG,MAAM,CAAC;CAAc;CAEtF,MAAM,yBAAS,IAAI,IAAoB;CACvC,IAAI,OAAiB,CAAC;CACtB,IAAI;CAEJ,IAAI,OAA2D;CAC/D,MAAM,SAAS,MAAqB,SAAsC;EACxE,IAAI,SAAS,MAAM,OAAO,CAAC;EAC3B,IAAI,QAAQ,KAAK,SAAS,MAAM,OAAO,KAAK;EAC5C,MAAM,OAAO,aAAa,IAAI;EAC9B,OAAO;GAAE;GAAM;EAAK;EACpB,OAAO;CACT;CAiBA,IAAI,CAAC,MAfe,UAClB,MACA,QAAQ,SAAS,WAAW,CAAC,GAAG,OAAO,IAAI,GAAG,QAAQ,GAAG,OAAO,IAAI,IAAI,MAAM,CAAC,IAC9E,OAAO,MAAM,SAAS;EACrB,MAAM,OAAO,MAAM,MAAM,IAAI;EAC7B,IAAI,QAAQ,MAAM,GAAG;GACnB,UAAU;GACV,IAAI,UAAU,KAAK,MAAM,OAAO,OAAO,KAAK,IAAI;GAChD;EACF;EACA,MAAM,SAAS,SAAS,QAAQ,KAAK;EACrC,IAAI,QAAQ,UAAU,CAAC;GAAE;GAAQ,KAAK;GAAS,QAAQ;EAAK,CAAC,GAAG,MAAM;EACtE,UAAU,KAAA;CACZ,CACF,GACY,MAAM,IAAI,MAAM,6DAA6D;CACzF,OAAO;EAAE;EAAQ;CAAK;AACxB;AAGA,eAAsB,kBACpB,KACA,QAAQ,QACa;CACrB,MAAM,OAA8B,CAAC;CACrC,MAAM,4BAAY,IAAI,IAAY;CAClC,IAAI,KAAK;CACT,KAAK,MAAM,UAAU,IAAI,SAAS;EAChC,MAAM,OAAO,SAAS,IAAI,MAAM,KAAK,IAAI,KAAK,GAAG,OAAO,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,GAAG;EACrF,IAAI;GACF,MAAM,SAAS,MAAM,SAAS,IAAI,MAAM,MAAM,KAAK;GACnD,KAAK,KAAK,OAAO,MAAM;GACvB,KAAK,MAAM,OAAO,OAAO,MAAM,UAAU,IAAI,GAAG;GAChD,KAAK;EACP,QAAQ,CAER;CACF;CACA,OAAO;EAAE,QAAQ,YAAY,IAAI;EAAG;EAAW;CAAG;AACpD;AAQA,MAAM,yBAAS,IAAI,IAAmD;AAEtE,eAAe,QAAQ,MAA+B;CACpD,IAAI;EACF,MAAM,EAAE,WAAW,MAAM,IAAI,OAAO,CAAC,aAAa,MAAM,GAAG;GACzD,KAAK;GACL,SAAS;GACT,aAAa;EACf,CAAC;EACD,OAAO,OAAO,KAAK;CACrB,QAAQ;EACN,OAAO;CACT;AACF;AAGA,eAAe,WAAW,KAA0C;CAClE,MAAM,OAAO,MAAM,QAAQ,IAAI,IAAI;CACnC,MAAM,OAAO,OAAO,IAAI,IAAI,IAAI;CAChC,IAAI,QAAQ,KAAK,SAAS,MAAM,OAAO,KAAK;CAC5C,MAAM,UAAU,MAAM,kBAAkB,GAAG;CAC3C,OAAO,IAAI,IAAI,MAAM;EAAE;EAAM;CAAQ,CAAC;CACtC,OAAO;AACT;AAEA,eAAsB,UAAU,KAAqB,KAAiC;CACpF,MAAM,UAAU,MAAM,WAAW,GAAG;CACpC,IAAI,CAAC,QAAQ,IAAI,OAAO;EAAE;EAAK,QAAQ;EAAM,QAAQ;CAAQ;CAC7D,MAAM,SAAS,QAAQ,OAAO,IAAI,GAAG;CAErC,IAAI,QAAQ,OAAO;EAAE;EAAK,QAAQ;GAAE,GAAG;GAAQ,KAAK,OAAO,IAAI,MAAM,GAAG,CAAC;EAAE;CAAE;CAC7E,OAAO;EAAE;EAAK,QAAQ;EAAM,QAAQ,QAAQ,UAAU,IAAI,GAAG,IAAI,UAAU;CAAc;AAC3F;;;AC9OA,MAAM,KAAK,QAAQ,cAAc,IAAI,IAAI,KAAK,YAAY,GAAG,CAAC,GAAG,IAAI;AAErE,MAAM,QAAgC;CACpC,SAAS;CACT,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,SAAS;CACT,QAAQ;AACV;AAOA,MAAa,gBAAyB,WAAW,KAAK,IAAI,YAAY,CAAC;AAGvE,SAAgB,UAAU,UAAqC;CAE7D,MAAM,SAAS,QAAQ,KAAK,IAAI,UADjB,aAAa,MAAM,gBAAgB,QACF,CAAC,CAAC;CAClD,IAAI,WAAW,MAAM,CAAC,OAAO,WAAW,MAAM,QAAQ,aAAa,UAAU,OAAO,IAAI,GACtF;CAEF,IAAI,CAAC,WAAW,MAAM,KAAK,CAAC,SAAS,MAAM,CAAC,CAAC,OAAO,GAAG,OAAO,KAAA;CAC9D,MAAM,MAAM,OAAO,YAAY,GAAG;CAClC,OAAO;EACL,MAAM,aAAa,MAAM;EACzB,MAAM,MAAM,OAAO,MAAM,GAAG,CAAC,CAAC,YAAY,MAAM;CAClD;AACF;;;AC7BA,SAAgB,WAAmB;CACjC,OAAO,YAAY,CAAC,CAAC,CAAC,SAAS,WAAW;AAC5C;AAGA,SAAgB,YAAY,MAA0B,MAAuB;CAE3E,MAAM,QAAQ,SAAS,KAAK,CAAC,aAAa,WAAW,IAAI,CAAC;CAC1D,OAAO;EAAC,aAAa;EAAQ,aAAa;EAAQ,GAAG;CAAK,CAAC,CAAC,SAAS,QAAQ,EAAE;AACjF;AAGA,SAAgB,cAAc,QAA4B,MAAuB;CAC/E,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,OAAO,WAAW,oBAAoB,UAAU,WAAW,oBAAoB;AACjF;AAGA,SAAgB,aAAa,OAAsB,UAA2B;CAC5E,IAAI,UAAU,MAAM,OAAO;CAC3B,MAAM,IAAI,OAAO,KAAK,KAAK;CAC3B,MAAM,IAAI,OAAO,KAAK,QAAQ;CAC9B,OAAO,EAAE,WAAW,EAAE,UAAU,gBAAgB,GAAG,CAAC;AACtD;AAQA,MAAM,OAAqB;CAAE,IAAI;CAAM,QAAQ;CAAK,QAAQ;AAAG;AAE/D,SAAgB,aACd,SACA,KACA,EAAE,MAAM,SACM;CACd,IAAI,CAAC,YAAY,QAAQ,MAAM,IAAI,GACjC,OAAO;EAAE,IAAI;EAAO,QAAQ;EAAK,QAAQ;CAAmC;CAE9E,IAAI,CAAC,cAAc,QAAQ,QAAQ,IAAI,GACrC,OAAO;EAAE,IAAI;EAAO,QAAQ;EAAK,QAAQ;CAAiC;CAE5E,IAAI,CAAC,aAAa,IAAI,aAAa,IAAI,GAAG,GAAG,KAAK,GAChD,OAAO;EAAE,IAAI;EAAO,QAAQ;EAAK,QAAQ;CAAyD;CAEpG,OAAO;AACT;;;AChCA,MAAM,eAAe;AACrB,MAAM,WAAW;AAEjB,SAAS,KAAK,KAAqB,QAAgB,MAAqB;CACtE,IAAI,UAAU,QAAQ;EACpB,gBAAgB;EAChB,iBAAiB;CACnB,CAAC;CACD,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC;AAC9B;AAEA,eAAe,SAAS,KAAwD;CAC9E,MAAM,SAAmB,CAAC;CAC1B,IAAI,OAAO;CACX,WAAW,MAAM,SAAS,KAAK;EAC7B,QAAS,MAAiB;EAC1B,IAAI,OAAO,UAAU,MAAM,IAAI,UAAU,KAAK,wBAAwB;EACtE,OAAO,KAAK,KAAe;CAC7B;CACA,IAAI,CAAC,OAAO,QAAQ,OAAO,CAAC;CAC5B,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,OAAO,OAAO,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC;CAC5D,QAAQ;EACN,MAAM,WAAW,wBAAwB;CAC3C;CAEA,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GACvE,MAAM,WAAW,4BAA4B;CAE/C,OAAO;AACT;AAEA,SAAS,QAAQ,KAAyB,MAAsB;CAC9D,IAAI;CACJ,IAAI;EACF,QAAQ,mBAAmB,OAAO,EAAE;CACtC,QAAQ;EACN,MAAM,WAAW,OAAO,KAAK,0CAA0C;CACzE;CACA,IAAI,CAAC,OAAO,MAAM,WAAW,wBAAwB,MAAM;CAC3D,OAAO;AACT;AAGA,SAAgB,gBAAgB,KAAqB,MAAc,OAAe;CAChF,OAAO,eAAe,OAAO,KAAsB,KAAoC;EAErF,IAAI;GACF,IAAI;GACJ,IAAI;IACF,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,oBAAoB,MAAM;GAC1D,QAAQ;IACN,MAAM,WAAW,uCAAuC;GAC1D;GAEA,MAAM,MAAM,IAAI,SAAS,WAAW,OAAO;GAC3C,MAAM,UAAU,aAAa;IAAE,MAAM,IAAI,QAAQ;IAAM,QAAQ,IAAI,QAAQ;GAAO,GAAG,KAAK;IACxF;IACA;GACF,CAAC;GAED,IAAI,CAAC,QAAQ,OAAO,OAAO,QAAQ,WAAW,MAAM;IAClD,KAAK,KAAK,QAAQ,QAAQ,EAAE,OAAO,QAAQ,OAAO,CAAC;IACnD;GACF;GAEA,IAAI,CAAC,OAAO,IAAI,WAAW,OAAO;IAChC,MAAM,QAAQ,UAAU,IAAI,QAAQ;IACpC,IAAI,OAAO;KACT,IAAI,UAAU,KAAK;MAAE,gBAAgB,MAAM;MAAM,iBAAiB;KAAW,CAAC;KAC9E,IAAI,IAAI,MAAM,IAAI;KAClB;IACF;IACA,IAAI,IAAI,aAAa,OAAO,CAAC,QAAQ,GACnC,MAAM,IAAI,UAAU,KAAK,+DAA+D;GAE5F;GAEA,IAAI,IAAI,WAAW,SAAS,IAAI,aAAa,cAAc;IACzD,KAAK,KAAK,KAAK,MAAM,WAAW,GAAG,CAAC;IACpC;GACF;GACA,IAAI,IAAI,WAAW,SAAS,IAAI,aAAa,gBAAgB;IAC3D,KAAK,KAAK,KAAK,EAAE,SAAS,MAAM,eAAe,GAAG,EAAE,CAAC;IACrD;GACF;GACA,IAAI,IAAI,WAAW,SAAS,IAAI,SAAS,WAAW,cAAc,GAAG;IAEnE,KAAK,KAAK,KAAK,MAAM,UAAU,KADnB,QAAQ,IAAI,SAAS,MAAM,EAAqB,GAAG,KAC3B,CAAG,CAAC;IACxC;GACF;GACA,IAAI,IAAI,WAAW,SAAS,IAAI,aAAa,eAAe;IAC1D,KAAK,KAAK,KAAK,MAAM,OAAO,GAAG,CAAC;IAChC;GACF;GACA,IAAI,IAAI,WAAW,SAAS,IAAI,SAAS,WAAW,eAAe,GAAG;IACpE,MAAM,OAAO,IAAI,SAAS,MAAM,EAAsB,CAAC,CAAC,MAAM,GAAG;IACjE,MAAM,SAAS,QAAQ,KAAK,IAAI,QAAQ;IACxC,MAAM,MAAM,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,KAAK;IAClD,MAAM,OAAO,MAAM,SAAS,GAAG;IAC/B,IAAI,OAAO,KAAK,SAAS,UAAU,MAAM,WAAW,8BAA4B;IAChF,KAAK,KAAK,KAAK,MAAM,aAAa,KAAK,QAAQ,KAAK,KAAK,IAAI,CAAC;IAC9D;GACF;GACA,IAAI,IAAI,WAAW,UAAU,IAAI,aAAa,gBAAgB;IAC5D,MAAM,OAAO,MAAM,SAAS,GAAG;IAC/B,IAAI,OAAO,KAAK,WAAW,UAAU,MAAM,WAAW,gCAA8B;IACpF,MAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,IAChC,KAAK,KAAK,QAAQ,MAAmB,OAAO,MAAM,QAAQ,IAC1D,KAAA;IACJ,IAAI,KAAK,SAAS,MAAM;KACtB,IAAI,CAAC,MAAM,QAAQ,MAAM,WAAW,+CAA6C;KACjF,KAAK,KAAK,KAAK,UAAU,KAAK,KAAK,QAAQ,IAAI,CAAC;KAChD;IACF;IACA,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,QAAQ,IAAI,CAAC;IAC9C;GACF;GACA,IAAI,IAAI,WAAW,UAAU,IAAI,aAAa,gBAAgB;IAC5D,KAAK,KAAK,KAAK,MAAM,WAAW,GAAG,CAAC;IACpC;GACF;GACA,IAAI,IAAI,WAAW,SAAS,IAAI,aAAa,kBAAkB;IAC7D,MAAM,UAAU,IAAI,aAAa,OAAO,QAAQ;IAChD,KAAK,KAAK,KAAK,MAAM,cAAc,KAAK,QAAQ,SAAS,UAAU,KAAA,CAAS,CAAC;IAC7E;GACF;GACA,IAAI,IAAI,WAAW,UAAU,IAAI,aAAa,kBAAkB;IAC9D,MAAM,OAAO,MAAM,SAAS,GAAG;IAC/B,MAAM,UAAU,MAAM,QAAQ,KAAK,OAAO,IACtC,KAAK,QAAQ,QAAQ,MAAmB,OAAO,MAAM,QAAQ,IAC7D,KAAA;IACJ,KAAK,KAAK,KAAK,MAAM,eAAe,KAAK,SAAS,SAAS,UAAU,KAAA,CAAS,CAAC;IAC/E;GACF;GAEA,IAAI,IAAI,WAAW,SAAS,IAAI,aAAa,YAAY;IACvD,KAAK,KAAK,KAAK,QAAQ,CAAC;IACxB;GACF;GACA,IAAI,IAAI,WAAW,SAAS,IAAI,SAAS,WAAW,WAAW,GAAG;IAChE,KAAK,KAAK,KAAKA,KAAQ,QAAQ,IAAI,SAAS,MAAM,CAAkB,GAAG,QAAQ,CAAC,CAAC;IACjF;GACF;GAEA,KAAK,KAAK,KAAK,EAAE,OAAO,0BAA0B,IAAI,OAAO,GAAG,IAAI,WAAW,CAAC;EAClF,SAAS,OAAO;GAGd,KAAK,KAFU,iBAAiB,YAAY,MAAM,SAAS,KAEzC,EAAE,OAAO,MADX,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAC3B,IAAI,IAAI,EAAE,CAAC;EACvD;CACF;AACF;AAGA,SAAS,OAAO,QAAgB,MAAc,cAAuC;CACnF,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,WAAW,UAAiC;GAChD,IAAI,MAAM,SAAS,gBAAgB,eAAe,GAAG;IACnD,OAAO,eAAe,SAAS,OAAO;IACtC,QAAQ,OAAO,QAAQ,OAAO,GAAG,eAAe,CAAC,CAAC;IAClD;GACF;GACA,OAAO,KAAK;EACd;EACA,OAAO,KAAK,SAAS,OAAO;EAC5B,OAAO,OAAO,MAAM,mBAAmB;GACrC,OAAO,eAAe,SAAS,OAAO;GAEtC,MAAM,QAAQ,OAAO,QAAQ;GAC7B,QAAQ,OAAO,UAAU,YAAY,UAAU,OAAO,MAAM,OAAO,IAAI;EACzE,CAAC;CACH,CAAC;AACH;AAEA,eAAsB,YACpB,KACA,UAAwB,CAAC,GACF;CACvB,MAAM,QAAQ,QAAQ,SAAS,SAAS;CACxC,MAAM,SAAS,aAAa;CAE5B,IAAI,OAAO,QAAQ,QAAQ;CAC3B,OAAO,GAAG,YAAY,KAAK,QAAQ,KAAK,gBAAgB,KAAK,MAAM,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC;CACnF,OAAO,MAAM,OAAO,QAAQ,MAAM,EAAE;CAEpC,OAAO;EACL;EACA;EACA;EACA,KAAK,oBAAoB,KAAK,MAAM;EACpC,aACE,IAAI,SAAe,SAAS,WAC1B,OAAO,OAAO,UAAW,QAAQ,OAAO,KAAK,IAAI,QAAQ,CAAE,CAC7D;CACJ;AACF"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["readJob"],"sources":["../src/http.ts","../src/triage.ts","../src/api.ts","../src/jobs.ts","../src/actions.ts","../src/history.ts","../src/assets.ts","../src/guard.ts","../src/server.ts"],"sourcesContent":["// A client mistake is not a server fault, so the status rides with the error, not a blanket 500.\nexport class HttpError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message.startsWith('[verbaly]') ? message : `[verbaly] ${message}`);\n this.status = status;\n this.name = 'HttpError';\n }\n}\n\nexport const badRequest = (message: string) => new HttpError(400, message);\n\n// The absolute path of someone's project is not the browser's business.\nexport function scrub(message: string, root: string): string {\n return root ? message.split(root).join('.') : message;\n}\n","import type { Catalog } from '@verbaly/compiler';\n\nexport type TriageSignal = 'divergent' | 'collision' | 'echo' | 'digits' | 'code' | 'url';\n\nexport interface TriageReason {\n signal: TriageSignal;\n text: string;\n}\n\nexport type TriageResult = Record<string, TriageReason[]>;\n\n// check() already caught the structure, so these only point at the few worth reading first.\nexport interface TriageInput {\n source: Catalog;\n target: Catalog;\n reviewed: ReviewedLocale[];\n}\n\n// the locale rides with the catalog because a reason that cannot name the language explains nothing\nexport interface ReviewedLocale {\n locale: string;\n catalog: Catalog;\n}\n\nconst DIGITS = /\\d[\\d.,]*/g;\nconst URLS = /https?:\\/\\/[^\\s<)\"']+/g;\nconst CODE = /<code>([^<]+)<\\/code>/g;\n\nfunction bag(text: string, re: RegExp, normalize?: (v: string) => string): string[] {\n const found = text.match(re) ?? [];\n return (normalize ? found.map(normalize) : found).sort();\n}\n\nfunction same(a: string[], b: string[]): boolean {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n}\n\n// A number or a url at the end of a clause takes the punctuation with it, and that is not a signal.\nconst trimPunct = (v: string) => v.replace(/[.,;:!?)\\]]+$/, '');\n// A separator is idiomatic (3.09 is 3,09 in Spanish); canonizing keeps 1.5 apart from 15.\nconst bareDigits = (v: string) => trimPunct(v).replaceAll(/[.,]/g, '.');\n\nfunction push(out: TriageResult, key: string, reason: TriageReason): void {\n (out[key] ??= []).push(reason);\n}\n\n// the column is three short lines, so a reason quotes the evidence and never the whole message\nfunction clip(text: string, max = 42): string {\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\nconst quote = (text: string, max?: number) => `\"${clip(text, max)}\"`;\n\n// what the source has and the translation does not, which is the half worth naming\nfunction lost(from: string[], to: string[]): string[] {\n const rest = [...to];\n const out: string[] = [];\n for (const item of from) {\n const at = rest.indexOf(item);\n if (at < 0) out.push(item);\n else rest.splice(at, 1);\n }\n return out;\n}\n\n// \"the numbers moved\" is a label; naming the one that moved is what saves the reader a diff\nfunction movedText(kind: string, from: string[], to: string[]): string {\n const gone = lost(from, to);\n const added = lost(to, from);\n if (gone.length && added.length) {\n return `the source ${kind} ${quote(gone[0]!)}, this one ${kind} ${quote(added[0]!)}`;\n }\n if (gone.length) return `the source ${kind} ${quote(gone[0]!)} and this one does not`;\n return `this one ${kind} ${quote(added[0]!)} and the source does not`;\n}\n\nexport function triage({ source, target, reviewed }: TriageInput): TriageResult {\n // null-prototype: a source text of \"__proto__\" or \"toString\" is a string, not a member of Object\n const out: TriageResult = Object.create(null);\n const keys = Object.keys(source);\n\n // One source text that two humans rendered two ways is ambiguous, so the machine had no chance.\n const bySource: Record<string, string[]> = Object.create(null);\n for (const key of keys) {\n const text = source[key]?.trim();\n if (text) (bySource[text] ??= []).push(key);\n }\n for (const [text, group] of Object.entries(bySource)) {\n if (group.length < 2) continue;\n\n // the first reviewed locale that disagreed with itself, and the two renderings it used\n let split: { locale: string; first: string; second: string } | undefined;\n for (const { locale, catalog } of reviewed) {\n const seen = [...new Set(group.map((k) => catalog[k]?.trim() ?? '').filter(Boolean))];\n if (seen.length > 1) {\n split = { locale, first: seen[0]!, second: seen[1]! };\n break;\n }\n }\n if (split) {\n for (const key of group) {\n push(out, key, {\n signal: 'divergent',\n text: `${split.locale} already says this two ways: ${quote(split.first, 32)} and ${quote(split.second, 32)}`,\n });\n }\n }\n\n // The same ambiguity seen from the result instead of from the history.\n const targets = new Set(group.map((key) => target[key]?.trim() ?? '').filter(Boolean));\n if (!split && targets.size > 1) {\n for (const key of group) {\n const mine = target[key]?.trim() ?? '';\n const other = group.find(\n (k) => k !== key && (target[k]?.trim() ?? '') !== mine && target[k]?.trim(),\n );\n push(out, key, {\n signal: 'collision',\n text: other\n ? `${other} has the same source text and says ${quote(target[other]!.trim())}`\n : `${quote(text)} came back as two different translations`,\n });\n }\n }\n }\n\n for (const key of keys) {\n const src = source[key]?.trim() ?? '';\n const trg = target[key]?.trim() ?? '';\n if (!src || !trg) continue;\n\n // Only the locales with an opinion on this key vote: alone it fires on every do-not-translate.\n const voters = reviewed.filter(({ catalog }) => {\n const value = catalog[key]?.trim();\n return value !== undefined && value !== '';\n });\n if (\n trg === src &&\n voters.length > 0 &&\n voters.every(({ catalog }) => catalog[key]?.trim() !== src)\n ) {\n const names = voters.map(({ locale }) => locale).join(' and ');\n push(out, key, {\n signal: 'echo',\n text: `still the source text, and ${names} did translate it`,\n });\n }\n\n // a translation that adds a number is idiomatic (\"refresh\" is \"F5\"); one that changes it is not\n const srcDigits = bag(src, DIGITS, bareDigits);\n const trgDigits = bag(trg, DIGITS, bareDigits);\n if (srcDigits.length > 0 && !same(srcDigits, trgDigits)) {\n push(out, key, { signal: 'digits', text: movedText('says', srcDigits, trgDigits) });\n }\n const srcUrls = bag(src, URLS, trimPunct);\n const trgUrls = bag(trg, URLS, trimPunct);\n if (!same(srcUrls, trgUrls)) {\n push(out, key, { signal: 'url', text: movedText('links to', srcUrls, trgUrls) });\n }\n const srcCode = bag(src, CODE);\n const trgCode = bag(trg, CODE);\n if (!same(srcCode, trgCode)) {\n push(out, key, { signal: 'code', text: movedText('shows the code', srcCode, trgCode) });\n }\n }\n\n return out;\n}\n","import { existsSync } from 'node:fs';\nimport { relative } from 'node:path';\nimport {\n check,\n clearDrafts,\n collectOrigins,\n doctor,\n effectiveDrafts,\n extractProject,\n loadDrafts,\n loadState,\n markDrafts,\n readCatalog,\n readState,\n recordTranslations,\n saveDrafts,\n shippedCatalogs,\n status,\n targetLocales,\n validateMessage,\n validatePair,\n writeCatalog,\n} from '@verbaly/compiler';\nimport { STATE_FILE } from '@verbaly/compiler';\nimport type {\n Catalog,\n Catalogs,\n CheckResult,\n DoctorResult,\n Drafts,\n ResolvedConfig,\n StatusResult,\n} from '@verbaly/compiler';\nimport { badRequest } from './http';\nimport { triage, type TriageResult } from './triage';\n\nexport interface StudioProblem {\n scope: string;\n message: string;\n}\n\nexport interface StudioState {\n root: string;\n dir: string;\n sourceLocale: string;\n locales: string[];\n scanning: boolean;\n catalogs: Catalogs;\n origins: Record<string, string[]>;\n status: StatusResult;\n check: CheckResult;\n drafts: Drafts;\n triage: Record<string, TriageResult>;\n problems: StudioProblem[];\n}\n\n// A locale nobody can parse must not take the panel down: Studio is what you open to fix it.\nfunction readAll(cfg: ResolvedConfig): { catalogs: Catalogs; problems: StudioProblem[] } {\n const catalogs: Catalogs = {};\n const problems: StudioProblem[] = [];\n // an empty green panel and a wrong --root look identical, and only this line tells them apart\n if (!existsSync(cfg.dir)) {\n const dir = relative(cfg.root, cfg.dir).replaceAll('\\\\', '/');\n problems.push({\n scope: dir,\n message: '[verbaly] no catalogs here, run npx verbaly init or check --root',\n });\n }\n for (const locale of cfg.locales) {\n try {\n catalogs[locale] = readCatalog(cfg, locale);\n } catch (error) {\n catalogs[locale] = {};\n problems.push({\n scope: locale,\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n return { catalogs, problems };\n}\n\n// check() reports the files a key was used in as absolute paths, origins already do not.\nfunction relativize(cfg: ResolvedConfig, result: CheckResult): CheckResult {\n const rel = (file: string): string => relative(cfg.root, file).replaceAll('\\\\', '/');\n return {\n ...result,\n unknown: result.unknown.map((entry) => ({ ...entry, files: entry.files.map(rel) })),\n extra: result.extra.map((entry) => ({ ...entry, files: entry.files.map(rel) })),\n collisions: result.collisions.map((entry) => ({\n ...entry,\n sites: entry.sites.map((at) => ({ ...at, file: rel(at.file) })),\n })),\n divergent: result.divergent.map((entry) => ({\n ...entry,\n code: { ...entry.code, file: rel(entry.code.file) },\n })),\n };\n}\n\n// One shot and unpaginated: the biggest catalog we know is past 1600 messages, instant locally.\nexport async function buildState(cfg: ResolvedConfig): Promise<StudioState> {\n const { catalogs, problems } = readAll(cfg);\n const registry = await extractProject(cfg);\n // a lock nobody can parse is the other file Studio is there to fix: it degrades like a catalog\n const { state: sidecar, problem } = readState(cfg);\n if (problem) problems.push({ scope: STATE_FILE, message: problem });\n const live = effectiveDrafts(sidecar.drafts, catalogs);\n const source = (catalogs[cfg.sourceLocale] ?? {}) as Catalog;\n const targets = targetLocales(cfg);\n\n for (const { file, message } of registry.parseErrors()) {\n problems.push({ scope: relative(cfg.root, file).replaceAll('\\\\', '/'), message });\n }\n\n const perLocale: Record<string, TriageResult> = {};\n for (const locale of targets) {\n perLocale[locale] = triage({\n source,\n target: (catalogs[locale] ?? {}) as Catalog,\n // a locale still carrying drafts has not been reviewed, so it cannot be the control\n reviewed: targets\n .filter((other) => other !== locale && !(live[other] ?? []).length)\n .map((other) => ({ locale: other, catalog: (catalogs[other] ?? {}) as Catalog })),\n });\n }\n\n return {\n root: cfg.root,\n dir: cfg.dir,\n sourceLocale: cfg.sourceLocale,\n locales: cfg.locales,\n // with include: [] nothing is scanned, so an empty origins map is off, not \"none found\"\n scanning: cfg.include.length > 0,\n catalogs,\n origins: await collectOrigins(cfg, registry),\n status: status(cfg, catalogs, registry, live, sidecar.fingerprints),\n check: relativize(cfg, check(cfg, catalogs, registry, sidecar.fingerprints)),\n drafts: live,\n triage: perLocale,\n problems,\n };\n}\n\nexport function health(cfg: ResolvedConfig): Promise<DoctorResult> {\n return doctor(cfg);\n}\n\nexport interface WriteMessageResult {\n locale: string;\n key: string;\n clearedDraft: boolean;\n}\n\n// A human wrote it, so it is reviewed and stamped for the text that ships, as import does.\nexport async function writeMessage(\n cfg: ResolvedConfig,\n locale: string,\n key: string,\n text: string,\n): Promise<WriteMessageResult> {\n if (locale === cfg.sourceLocale) {\n throw badRequest('the source text lives in your code, Studio never edits it');\n }\n if (!cfg.locales.includes(locale)) {\n throw badRequest(`${locale} is not one of this project's locales`);\n }\n // the review state is written after the catalog: an unreadable one stops the save before it\n const before = loadState(cfg);\n const catalogs = { [cfg.sourceLocale]: readCatalog(cfg, cfg.sourceLocale) };\n const registry = await extractProject(cfg);\n // checked against the text that ships, the one check reads every translation against\n const source = shippedCatalogs(cfg, catalogs, registry, { newKeys: false })[cfg.sourceLocale]!;\n // hasOwn, not `in`: `in` walks the prototype, so toString and __proto__ would pass this guard\n if (!Object.hasOwn(source, key)) {\n throw badRequest(`\"${key}\" is not in the source catalog, so Studio will not create it`);\n }\n // '' is untranslated everywhere else, so whitespace is that and not a translation to validate\n const value = text.trim() ? text : '';\n // the same two calls check() makes: validatePair alone misses a plural block with no other case\n const issues = value\n ? [...validateMessage(value, locale), ...validatePair(source[key] as string, value)]\n : [];\n const errors = issues.filter((issue) => issue.severity === 'error');\n if (errors.length) {\n throw badRequest(`${errors.map((issue) => issue.message).join('; ')}`);\n }\n\n const catalog = { ...readCatalog(cfg, locale), [key]: value };\n writeCatalog(cfg, locale, catalog);\n\n const clearedDraft = (before.drafts[locale] ?? []).includes(key);\n recordTranslations(cfg, source, [{ locale, entries: [{ key, text: value }], draft: false }]);\n return { locale, key, clearedDraft };\n}\n\nexport interface ApproveResult {\n locale: string;\n approved: number;\n keys: string[];\n}\n\n// The lock is re-read here: saveDrafts writes every locale, so a stale copy drops another's.\nexport function approve(cfg: ResolvedConfig, locale: string, keys?: string[]): ApproveResult {\n if (!cfg.locales.includes(locale)) {\n throw badRequest(`${locale} is not one of this project's locales`);\n }\n const drafts = loadDrafts(cfg);\n const had = drafts[locale] ?? [];\n // the keys it really cleared, because undo has to put back exactly those and nothing else\n const cleared = keys ? had.filter((key) => keys.includes(key)) : [...had];\n clearDrafts(drafts, locale, keys);\n saveDrafts(cfg, drafts);\n return { locale, approved: cleared.length, keys: cleared };\n}\n\n// Undo is not a nicety here: the flag records who wrote the text, so restoring it restores a fact.\nexport function unapprove(cfg: ResolvedConfig, locale: string, keys: string[]): ApproveResult {\n if (!cfg.locales.includes(locale)) {\n throw badRequest(`${locale} is not one of this project's locales`);\n }\n const drafts = loadDrafts(cfg);\n markDrafts(drafts, locale, keys);\n saveDrafts(cfg, drafts);\n return { locale, approved: keys.length, keys };\n}\n","import { badRequest, HttpError } from './http';\n\nexport type JobState = 'running' | 'done' | 'failed';\n\nexport interface Job {\n id: string;\n kind: 'translate';\n state: JobState;\n total: number;\n done: number;\n locale?: string;\n message?: string;\n result?: unknown;\n written?: number;\n kept?: number;\n}\n\n// One at a time, because two runs over the same catalogs is a race over the same files.\nlet current: Job | null = null;\nlet counter = 0;\n\nexport function running(): Job | null {\n return current?.state === 'running' ? current : null;\n}\n\nexport function read(id: string): Job {\n if (!current || current.id !== id) throw new HttpError(404, `no job called \"${id}\"`);\n return current;\n}\n\nexport function start(kind: Job['kind'], total: number): Job {\n if (running()) throw badRequest('a job is already running, wait for it or read its progress');\n counter += 1;\n current = { id: `${kind}-${counter}`, kind, state: 'running', total, done: 0 };\n return current;\n}\n\n// A batch that failed still finishes: the bar reports work attempted, and message says what broke.\nexport function advance(id: string, keys: number, locale: string, error?: string): void {\n if (current?.id !== id) return;\n current.done = Math.min(current.done + keys, current.total);\n current.locale = locale;\n if (error) current.message = error;\n}\n\n// A run that writes part of its work and then fails is a success for what it wrote, so both land.\nexport function finish(id: string, state: 'done' | 'failed', patch: Partial<Job> = {}): void {\n if (current?.id === id) Object.assign(current, patch, { state });\n}\n","import {\n collectOrigins,\n counted,\n extractProject,\n loadCatalogs,\n loadState,\n mergeTranslations,\n recordTranslations,\n resolveProvider,\n shippedCatalogs,\n syncProject,\n translateCatalogs,\n} from '@verbaly/compiler';\nimport type { ResolvedConfig, TranslationWrite } from '@verbaly/compiler';\nimport { badRequest } from './http';\nimport { advance, finish, start, type Job } from './jobs';\n\nexport interface ExtractResult {\n added: Record<string, string[]>;\n // only the source locale counts as new text: a target gains a blank for every gap it had\n found: number;\n // source texts the code wrote over, a hand edit in the catalog among them\n replaced: number;\n messages: number;\n // the lock could not be read or written: the catalogs were, its drafts and stamps were not\n stateProblem?: string;\n}\n\n// Local, fast and free, so it answers in the same request instead of becoming a job.\nexport async function runExtract(cfg: ResolvedConfig): Promise<ExtractResult> {\n if (!cfg.include.length) {\n throw badRequest('source scanning is off (include: []), so there is nothing to extract');\n }\n // the same path as the CLI: catalogs, types and the review state move together\n const result = await syncProject(cfg);\n return {\n added: result.added,\n found: result.added[cfg.sourceLocale]?.length ?? 0,\n replaced: result.replaced.length,\n messages: result.registry.messages().size,\n ...(result.stateProblem && { stateProblem: result.stateProblem }),\n };\n}\n\nexport interface Plan {\n pending: Record<string, string[]>;\n total: number;\n}\n\n// translate is the one command that spends money and minutes, so the panel always shows the bill.\nexport async function planTranslate(cfg: ResolvedConfig, locales?: string[]): Promise<Plan> {\n const provider = await resolveProvider(cfg);\n const catalogs = loadCatalogs(cfg);\n const result = await translateCatalogs(cfg, catalogs, provider, { locales, dryRun: true });\n const total = Object.values(result.pending).reduce((n, keys) => n + keys.length, 0);\n return { pending: result.pending, total };\n}\n\nexport async function startTranslate(cfg: ResolvedConfig, locales?: string[]): Promise<Job> {\n // a machine translation that lost its draft flag passes as reviewed: read the state first\n loadState(cfg);\n const provider = await resolveProvider(cfg);\n // the job carries its own denominator, so progress reads the same whether or not you asked first\n const plan = await planTranslate(cfg, locales);\n const job = start('translate', plan.total);\n const id = job.id;\n\n // the run outlives this request on purpose: the client asks the job how it is going\n void (async () => {\n try {\n const registry = await extractProject(cfg);\n // the provider reads the text that ships, which is the text its answer has to match\n const catalogs = shippedCatalogs(cfg, loadCatalogs(cfg), registry, { newKeys: false });\n const result = await translateCatalogs(cfg, catalogs, provider, {\n locales,\n batchSize: cfg.translate.batchSize,\n concurrency: cfg.translate.concurrency,\n retries: cfg.translate.retries,\n origins: await collectOrigins(cfg, registry),\n onProgress: (p) => advance(id, p.keys, p.locale, p.error),\n });\n // what a machine wrote stays a draft: the panel does not get to change that rule\n const writes: TranslationWrite[] = [];\n let written = 0;\n let kept = 0;\n for (const [locale, keys] of Object.entries(result.translated)) {\n const catalog = catalogs[locale] ?? {};\n const landed = mergeTranslations(cfg, locale, catalog, keys);\n writes.push({\n locale,\n draft: true,\n entries: landed.map((key) => ({ key, text: catalog[key]! })),\n });\n written += landed.length;\n kept += keys.length - landed.length;\n }\n recordTranslations(cfg, catalogs[cfg.sourceLocale] ?? {}, writes);\n // on a failure the panel shows only this line, so it says what landed and what did not\n const failed = result.failed[0];\n finish(id, failed ? 'failed' : 'done', {\n result,\n written,\n kept,\n message: failed\n ? `${counted(written, 'message')} translated, but ${counted(result.failed.length, 'batch', 'batches')} did not answer (${failed.error}): run it again for the rest`\n : undefined,\n });\n } catch (error) {\n finish(id, 'failed', { message: error instanceof Error ? error.message : String(error) });\n }\n })();\n\n return job;\n}\n","import { execFile, spawn } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { join, relative } from 'node:path';\nimport { parseCatalog, type Catalog, type ResolvedConfig } from '@verbaly/compiler';\n\nconst run = promisify(execFile);\n\nexport interface Commit {\n sha: string;\n author: string;\n date: string;\n subject: string;\n}\n\n// one field separator that no subject can contain, written as the escape and never as the byte\nconst FIELD = '\\u001f';\nconst FORMAT = `--format=%H${FIELD}%an${FIELD}%aI${FIELD}%s`;\n\n// the full sha is what git resolves without ambiguity, and seven characters is what a card shows\nexport function parseFullLog(stdout: string): Commit[] {\n const commits: Commit[] = [];\n for (const line of stdout.split('\\n')) {\n const [sha, author, date, ...rest] = line.split(FIELD);\n // a subject holds anything but a newline, so it is the last field and is rejoined\n if (!sha || !author || !date || !rest.length) continue;\n commits.push({ sha, author, date, subject: rest.join(FIELD) });\n }\n return commits;\n}\n\n// split out so the shape of a log line is tested without a repository and without writing one\nexport function parseLog(stdout: string): Commit[] {\n return parseFullLog(stdout).map((commit) => ({ ...commit, sha: commit.sha.slice(0, 7) }));\n}\n\n// git is asked, never assumed: no repository and no git both mean there is no history to show\nexport async function catalogHistory(cfg: ResolvedConfig, limit = 5): Promise<Commit[]> {\n const dir = relative(cfg.root, cfg.dir).replaceAll('\\\\', '/') || '.';\n try {\n const { stdout } = await run('git', ['log', `-n${limit}`, FORMAT, '--', dir], {\n cwd: cfg.root,\n timeout: 3000,\n windowsHide: true,\n });\n return parseLog(stdout);\n } catch {\n return [];\n }\n}\n\nexport interface Revision {\n commit: Commit;\n now: Catalog | undefined;\n before: Catalog | undefined;\n}\n\n// blame measured 26% wrong on verbaly-web: a sibling's comma rewrites a line, a value does not\nexport function attribute(\n revisions: Revision[],\n owners = new Map<string, Commit>(),\n): Map<string, Commit> {\n for (const { commit, now, before } of revisions) {\n if (!now || !before) continue;\n for (const key of new Set([...Object.keys(now), ...Object.keys(before)])) {\n if (!owners.has(key) && now[key] !== before[key]) owners.set(key, commit);\n }\n }\n return owners;\n}\n\n// a key can move in more than one catalog, so the answer is the newest of the per-file answers\nexport function mergeOwners(maps: Map<string, Commit>[]): Map<string, Commit> {\n const merged = new Map<string, Commit>();\n for (const map of maps) {\n for (const [key, commit] of map) {\n const held = merged.get(key);\n if (!held || Date.parse(commit.date) > Date.parse(held.date)) merged.set(key, commit);\n }\n }\n return merged;\n}\n\nconst BLOB = /^[0-9a-f]{40} \\w+ (\\d+)$/;\n\n// git cat-file --batch answers every revision in one process: a header line, then that many bytes\nfunction readBlobs(\n root: string,\n requests: string[],\n take: (index: number, body: string | null, blob: string) => void,\n): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn('git', ['cat-file', '--batch'], { cwd: root, windowsHide: true });\n // a killed batch leaves a half map, and a half map answers \"never committed\" for the rest\n const stop = setTimeout(() => {\n ok = false;\n child.kill();\n }, 20000);\n let pending: Buffer = Buffer.alloc(0);\n let index = 0;\n let ok = true;\n const fail = () => {\n ok = false;\n };\n child.on('error', fail);\n child.stdin.on('error', fail);\n child.stdout.on('data', (chunk: Buffer) => {\n pending = pending.length ? Buffer.concat([pending, chunk]) : chunk;\n for (;;) {\n const end = pending.indexOf(10);\n if (end < 0) break;\n const header = pending.toString('utf8', 0, end);\n const blob = BLOB.exec(header);\n // anything but a blob header is a revision git could not resolve, which is an answer too\n if (!blob) {\n take(index++, null, '');\n pending = pending.subarray(end + 1);\n continue;\n }\n const size = Number(blob[1]);\n if (pending.length < end + size + 2) break;\n take(index++, pending.toString('utf8', end + 1, end + 1 + size), header.slice(0, 40));\n pending = pending.subarray(end + size + 2);\n }\n });\n child.on('close', () => {\n clearTimeout(stop);\n resolve(ok);\n });\n child.stdin.end(requests.join('\\n') + '\\n');\n });\n}\n\nexport interface KeyHistory {\n owners: Map<string, Commit>;\n committed: Set<string>;\n ok: boolean;\n}\n\n// the window a local tool is willing to read: past this, the answer is \"older than what I read\"\nconst WINDOW = 200;\n\nasync function walkFile(root: string, file: string, limit: number) {\n const { stdout } = await run('git', ['log', `-n${limit}`, FORMAT, '--', file], {\n cwd: root,\n timeout: 5000,\n windowsHide: true,\n maxBuffer: 8_000_000,\n });\n const commits = parseFullLog(stdout);\n if (!commits.length) return { owners: new Map<string, Commit>(), head: [] as string[] };\n\n const owners = new Map<string, Commit>();\n let head: string[] = [];\n let waiting: Catalog | undefined;\n // only two flat catalogs are ever live, and the pair shares a blob, so one entry caches it\n let last: { blob: string; flat: Catalog | undefined } | null = null;\n const parse = (body: string | null, blob: string): Catalog | undefined => {\n if (body === null) return {};\n if (last && last.blob === blob) return last.flat;\n const flat = parseCatalog(body);\n last = { blob, flat };\n return flat;\n };\n\n const whole = await readBlobs(\n root,\n commits.flatMap((commit) => [`${commit.sha}:${file}`, `${commit.sha}^:${file}`]),\n (index, body, blob) => {\n const flat = parse(body, blob);\n if (index % 2 === 0) {\n waiting = flat;\n if (index === 0 && flat) head = Object.keys(flat);\n return;\n }\n const commit = commits[(index - 1) / 2];\n if (commit) attribute([{ commit, now: waiting, before: flat }], owners);\n waiting = undefined;\n },\n );\n if (!whole) throw new Error('[verbaly] git could not read every revision of this catalog');\n return { owners, head };\n}\n\n// The whole map at once, because a per-key query costs a git process and every row has a menu.\nexport async function catalogKeyHistory(cfg: ResolvedConfig, limit = WINDOW): Promise<KeyHistory> {\n const maps: Map<string, Commit>[] = [];\n const committed = new Set<string>();\n let ok = false;\n for (const locale of cfg.locales) {\n const file = relative(cfg.root, join(cfg.dir, `${locale}.json`)).replaceAll('\\\\', '/');\n try {\n const walked = await walkFile(cfg.root, file, limit);\n maps.push(walked.owners);\n for (const key of walked.head) committed.add(key);\n ok = true;\n } catch {\n // one unreadable locale is not the end of the walk: the others still answer for their keys\n }\n }\n return { owners: mergeOwners(maps), committed, ok };\n}\n\nexport interface KeyCommit {\n key: string;\n commit: Commit | null;\n reason?: 'nogit' | 'uncommitted' | 'older';\n}\n\nconst walked = new Map<string, { head: string; history: KeyHistory }>();\n\nasync function headSha(root: string): Promise<string> {\n try {\n const { stdout } = await run('git', ['rev-parse', 'HEAD'], {\n cwd: root,\n timeout: 3000,\n windowsHide: true,\n });\n return stdout.trim();\n } catch {\n return '';\n }\n}\n\n// HEAD moving is the only thing that can change an answer, so it is what invalidates the walk\nasync function keyHistory(cfg: ResolvedConfig): Promise<KeyHistory> {\n const head = await headSha(cfg.root);\n const held = walked.get(cfg.root);\n if (held && held.head === head) return held.history;\n const history = await catalogKeyHistory(cfg);\n walked.set(cfg.root, { head, history });\n return history;\n}\n\nexport async function keyCommit(cfg: ResolvedConfig, key: string): Promise<KeyCommit> {\n const history = await keyHistory(cfg);\n if (!history.ok) return { key, commit: null, reason: 'nogit' };\n const commit = history.owners.get(key);\n // seven characters is what a person reads and pastes, and the walk needed the full one\n if (commit) return { key, commit: { ...commit, sha: commit.sha.slice(0, 7) } };\n return { key, commit: null, reason: history.committed.has(key) ? 'older' : 'uncommitted' };\n}\n","import { existsSync, readFileSync, statSync } from 'node:fs';\nimport { join, normalize, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n// the built panel sits beside the compiled server, so it is found relative to this file, never cwd\nconst UI = resolve(fileURLToPath(new URL('.', import.meta.url)), 'ui');\n\nconst TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.woff2': 'font/woff2',\n '.json': 'application/json; charset=utf-8',\n '.ico': 'image/x-icon',\n};\n\nexport interface Asset {\n body: Buffer;\n type: string;\n}\n\nexport const uiBuilt = (): boolean => existsSync(join(UI, 'index.html'));\n\n// A path is resolved and then checked to still be inside UI: ../ and an absolute one both land out.\nexport function readAsset(pathname: string): Asset | undefined {\n const wanted = pathname === '/' ? '/index.html' : pathname;\n const target = resolve(join(UI, normalize(wanted)));\n if (target !== UI && !target.startsWith(UI + (process.platform === 'win32' ? '\\\\' : '/'))) {\n return undefined;\n }\n if (!existsSync(target) || !statSync(target).isFile()) return undefined;\n const dot = target.lastIndexOf('.');\n return {\n body: readFileSync(target),\n type: TYPES[target.slice(dot).toLowerCase()] ?? 'application/octet-stream',\n };\n}\n","import { randomBytes, timingSafeEqual } from 'node:crypto';\n\nexport interface GuardOptions {\n port: number;\n token: string;\n}\n\n// A local server that writes files is reachable from any page the browser has open.\nexport function newToken(): string {\n return randomBytes(9).toString('base64url');\n}\n\n// Only the two names that resolve to this machine. A DNS rebind arrives with a foreign Host.\nexport function hostAllowed(host: string | undefined, port: number): boolean {\n // a browser omits the port when it is the scheme default, so :80 would 403 every real request\n const names = port === 80 ? ['127.0.0.1', 'localhost'] : [];\n return [`127.0.0.1:${port}`, `localhost:${port}`, ...names].includes(host ?? '');\n}\n\n// No Origin at all is a same-origin navigation or a curl, both fine; a foreign one never is.\nexport function originAllowed(origin: string | undefined, port: number): boolean {\n if (origin === undefined) return true;\n return origin === `http://127.0.0.1:${port}` || origin === `http://localhost:${port}`;\n}\n\n// Compared in constant time so the token cannot be guessed one character at a time.\nexport function tokenMatches(given: string | null, expected: string): boolean {\n if (given === null) return false;\n const a = Buffer.from(given);\n const b = Buffer.from(expected);\n return a.length === b.length && timingSafeEqual(a, b);\n}\n\nexport interface GuardVerdict {\n ok: boolean;\n status: number;\n reason: string;\n}\n\nconst PASS: GuardVerdict = { ok: true, status: 200, reason: '' };\n\nexport function guardRequest(\n headers: { host?: string; origin?: string },\n url: URL,\n { port, token }: GuardOptions,\n): GuardVerdict {\n if (!hostAllowed(headers.host, port)) {\n return { ok: false, status: 403, reason: '[verbaly] unexpected Host header' };\n }\n if (!originAllowed(headers.origin, port)) {\n return { ok: false, status: 403, reason: '[verbaly] cross-origin request' };\n }\n if (!tokenMatches(url.searchParams.get('t'), token)) {\n return {\n ok: false,\n status: 401,\n reason: '[verbaly] missing or wrong token, open the printed url',\n };\n }\n return PASS;\n}\n","import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport type { AddressInfo } from 'node:net';\nimport type { ResolvedConfig } from '@verbaly/compiler';\nimport { approve, buildState, health, unapprove, writeMessage } from './api';\nimport { planTranslate, runExtract, startTranslate } from './actions';\nimport { read as readJob, running } from './jobs';\nimport { catalogHistory, keyCommit } from './history';\nimport { readAsset, uiBuilt } from './assets';\nimport { guardRequest, newToken } from './guard';\nimport { HttpError, badRequest, scrub } from './http';\n\nexport interface StudioServer {\n server: Server;\n port: number;\n token: string;\n url: string;\n close: () => Promise<void>;\n}\n\nexport interface StartOptions {\n port?: number;\n token?: string;\n}\n\nconst DEFAULT_PORT = 4747;\nconst MAX_BODY = 1_000_000;\n\nfunction send(res: ServerResponse, status: number, body: unknown): void {\n res.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'cache-control': 'no-store',\n });\n res.end(JSON.stringify(body));\n}\n\nasync function readJson(req: IncomingMessage): Promise<Record<string, unknown>> {\n const chunks: Buffer[] = [];\n let size = 0;\n for await (const chunk of req) {\n size += (chunk as Buffer).length;\n if (size > MAX_BODY) throw new HttpError(413, 'request body too large');\n chunks.push(chunk as Buffer);\n }\n if (!chunks.length) return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(Buffer.concat(chunks).toString('utf8'));\n } catch {\n throw badRequest('body is not valid JSON');\n }\n // null and an array both pass typeof 'object', and reading .text off them is a 500\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw badRequest('body must be a JSON object');\n }\n return parsed as Record<string, unknown>;\n}\n\nfunction segment(raw: string | undefined, what: string): string {\n let value: string;\n try {\n value = decodeURIComponent(raw ?? '');\n } catch {\n throw badRequest(`the ${what} in the url is not valid percent-encoding`);\n }\n if (!value) throw badRequest(`the url is missing a ${what}`);\n return value;\n}\n\n// One page, JSON on every route: a framework would only add a dependency to a local tool.\nexport function createStudioApp(cfg: ResolvedConfig, port: number, token: string) {\n return async function handle(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // The url is built inside the try: `GET //` throws, and out here that would kill the process.\n try {\n let url: URL;\n try {\n url = new URL(req.url ?? '/', `http://127.0.0.1:${port}`);\n } catch {\n throw badRequest('the request target is not a valid url');\n }\n\n const api = url.pathname.startsWith('/api/');\n const verdict = guardRequest({ host: req.headers.host, origin: req.headers.origin }, url, {\n port,\n token,\n });\n // the panel files are the published npm package: only the project data needs a token\n if (!verdict.ok && (api || verdict.status !== 401)) {\n send(res, verdict.status, { error: verdict.reason });\n return;\n }\n\n if (!api && req.method === 'GET') {\n const asset = readAsset(url.pathname);\n if (asset) {\n res.writeHead(200, { 'content-type': asset.type, 'cache-control': 'no-store' });\n res.end(asset.body);\n return;\n }\n if (url.pathname === '/' && !uiBuilt()) {\n throw new HttpError(500, 'the panel is not in this install, so only /api/* answers here');\n }\n }\n\n if (req.method === 'GET' && url.pathname === '/api/state') {\n send(res, 200, await buildState(cfg));\n return;\n }\n if (req.method === 'GET' && url.pathname === '/api/history') {\n send(res, 200, { commits: await catalogHistory(cfg) });\n return;\n }\n if (req.method === 'GET' && url.pathname.startsWith('/api/commit/')) {\n const key = segment(url.pathname.slice('/api/commit/'.length), 'key');\n send(res, 200, await keyCommit(cfg, key));\n return;\n }\n if (req.method === 'GET' && url.pathname === '/api/health') {\n send(res, 200, await health(cfg));\n return;\n }\n if (req.method === 'PUT' && url.pathname.startsWith('/api/message/')) {\n const rest = url.pathname.slice('/api/message/'.length).split('/');\n const locale = segment(rest[0], 'locale');\n const key = segment(rest.slice(1).join('/'), 'key');\n const body = await readJson(req);\n if (typeof body.text !== 'string') throw badRequest('body needs a \"text\" string');\n send(res, 200, await writeMessage(cfg, locale, key, body.text));\n return;\n }\n if (req.method === 'POST' && url.pathname === '/api/approve') {\n const body = await readJson(req);\n if (typeof body.locale !== 'string') throw badRequest('body needs a \"locale\" string');\n const keys = Array.isArray(body.keys)\n ? body.keys.filter((k): k is string => typeof k === 'string')\n : undefined;\n if (body.undo === true) {\n if (!keys?.length) throw badRequest('undoing needs the \"keys\" it should put back');\n send(res, 200, unapprove(cfg, body.locale, keys));\n return;\n }\n send(res, 200, approve(cfg, body.locale, keys));\n return;\n }\n if (req.method === 'POST' && url.pathname === '/api/extract') {\n send(res, 200, await runExtract(cfg));\n return;\n }\n if (req.method === 'GET' && url.pathname === '/api/translate') {\n const locales = url.searchParams.getAll('locale');\n send(res, 200, await planTranslate(cfg, locales.length ? locales : undefined));\n return;\n }\n if (req.method === 'POST' && url.pathname === '/api/translate') {\n const body = await readJson(req);\n const locales = Array.isArray(body.locales)\n ? body.locales.filter((l): l is string => typeof l === 'string')\n : undefined;\n send(res, 200, await startTranslate(cfg, locales?.length ? locales : undefined));\n return;\n }\n // a reload loses the id, so the panel asks what is running rather than losing the bar\n if (req.method === 'GET' && url.pathname === '/api/job') {\n send(res, 200, running());\n return;\n }\n if (req.method === 'GET' && url.pathname.startsWith('/api/job/')) {\n send(res, 200, readJob(segment(url.pathname.slice('/api/job/'.length), 'job id')));\n return;\n }\n\n send(res, 404, { error: `[verbaly] no route for ${req.method} ${url.pathname}` });\n } catch (error) {\n const status = error instanceof HttpError ? error.status : 500;\n const message = error instanceof Error ? error.message : String(error);\n send(res, status, { error: scrub(message, cfg.root) });\n }\n };\n}\n\n// A busy port climbs instead of failing: this is a local tool, not a service on a fixed address.\nfunction listen(server: Server, port: number, attemptsLeft: number): Promise<number> {\n return new Promise((resolve, reject) => {\n const onError = (error: NodeJS.ErrnoException) => {\n if (error.code === 'EADDRINUSE' && attemptsLeft > 0) {\n server.removeListener('error', onError);\n resolve(listen(server, port + 1, attemptsLeft - 1));\n return;\n }\n reject(error);\n };\n server.once('error', onError);\n server.listen(port, '127.0.0.1', () => {\n server.removeListener('error', onError);\n // port 0 asks the system to pick, so the bound address is the only place the answer is\n const bound = server.address() as AddressInfo | string | null;\n resolve(typeof bound === 'object' && bound !== null ? bound.port : port);\n });\n });\n}\n\nexport async function startStudio(\n cfg: ResolvedConfig,\n options: StartOptions = {},\n): Promise<StudioServer> {\n const token = options.token ?? newToken();\n const server = createServer();\n // The handler is attached before listen so no request can arrive without one.\n let port = options.port ?? DEFAULT_PORT;\n server.on('request', (req, res) => void createStudioApp(cfg, port, token)(req, res));\n port = await listen(server, port, 20);\n\n return {\n server,\n port,\n token,\n url: `http://127.0.0.1:${port}/?t=${token}`,\n close: () =>\n new Promise<void>((resolve, reject) =>\n server.close((error) => (error ? reject(error) : resolve())),\n ),\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=Array.isArray,t=Array.prototype.indexOf,n=Array.prototype.includes,r=Array.from,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyDescriptors,s=Object.prototype,c=Array.prototype,l=Object.getPrototypeOf,u=Object.isExtensible,d=()=>{};function f(e){for(var t=0;t<e.length;t++)e[t]()}function p(){var e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}var m=1024,h=2048,g=4096,_=8192,v=16384,y=32768,b=1<<25,x=65536,S=1<<19,ee=1<<20,C=1<<25,w=1<<21,te=1<<22,T=1<<23,ne=Symbol(`$state`),re=Symbol(`component`),ie=Symbol(``),ae=Symbol(`attributes`),oe=Symbol(`class`),se=Symbol(`style`),ce=Symbol(`text`),le=Symbol(`form reset`),E=new class extends Error{name=`StaleReactionError`;message="The reaction that called `getAbortSignal()` was re-run or destroyed"},ue=!!globalThis.document?.contentType&&globalThis.document.contentType.includes(`xml`),de={},D=Symbol(`uninitialized`),fe=`http://www.w3.org/1999/xhtml`;function pe(){console.warn(`https://svelte.dev/e/derived_inert`)}function me(e){console.warn(`https://svelte.dev/e/hydration_mismatch`)}function he(){console.warn(`https://svelte.dev/e/select_multiple_invalid_value`)}function ge(){console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`)}var O=!1;function _e(e){O=e}var k;function A(e){if(e===null)throw me(),de;return k=e}function ve(){return A(Qt(k))}function j(e){if(O){if(Qt(k)!==null)throw me(),de;k=e}}function ye(e=1){if(O){for(var t=e,n=k;t--;)n=Qt(n);k=n}}function be(e=!0){for(var t=0,n=k;;){if(n.nodeType===8){var r=n.data;if(r===`]`){if(t===0)return n;--t}else(r===`[`||r===`[!`||r[0]===`[`&&!isNaN(Number(r.slice(1))))&&(t+=1)}var i=Qt(n);e&&n.remove(),n=i}}function xe(e){if(!e||e.nodeType!==8)throw me(),de;return e.data}function Se(e){return e===this.v}function Ce(e,t){return e==e?e!==t||typeof e==`object`&&!!e||typeof e==`function`:t==t}function we(e){return!Ce(e,this.v)}function Te(e){throw Error(`https://svelte.dev/e/lifecycle_outside_component`)}function Ee(){throw Error(`https://svelte.dev/e/async_derived_orphan`)}function De(e,t,n){throw Error(`https://svelte.dev/e/each_key_duplicate`)}function Oe(e){throw Error(`https://svelte.dev/e/effect_in_teardown`)}function ke(){throw Error(`https://svelte.dev/e/effect_in_unowned_derived`)}function Ae(e){throw Error(`https://svelte.dev/e/effect_orphan`)}function je(){throw Error(`https://svelte.dev/e/effect_update_depth_exceeded`)}function Me(){throw Error(`https://svelte.dev/e/state_descriptors_fixed`)}function Ne(){throw Error(`https://svelte.dev/e/state_prototype_fixed`)}function Pe(){throw Error(`https://svelte.dev/e/state_unsafe_mutation`)}function Fe(){throw Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`)}var M=null;function Ie(e){M=e}function Le(e,t=!1,n){M={p:M,i:!1,c:null,e:null,s:e,x:null,r:U,l:null}}function Re(e){var t=M,n=t.e;if(n!==null){t.e=null;for(var r of n)pn(r)}return e!==void 0&&(t.x=e),t.i=!0,M=t.p,ze(e)}function ze(e={}){return i(e,re,{value:!0}),e}function Be(){return!0}var Ve=[];function He(){var e=Ve;Ve=[],f(e)}function Ue(e){if(Ve.length===0&&!_t){var t=Ve;queueMicrotask(()=>{t===Ve&&He()})}Ve.push(e)}function We(){for(;Ve.length>0;)He()}var Ge=~(h|g|m);function N(e,t){e.f=e.f&Ge|t}function Ke(e){e.f&512||e.deps===null?N(e,m):N(e,g)}function qe(e,t,n){e.f&2048?t.add(e):e.f&4096&&n.add(e),N(e,m)}function Je(e,t){if(t){let t=document.body;e.autofocus=!0,Ue(()=>{document.activeElement===t&&e.focus()})}}function Ye(e){O&&Zt(e)!==null&&en(e)}var Xe=!1;function Ze(){Xe||(Xe=!0,document.addEventListener(`reset`,e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(let t of e.target.elements)t[le]?.()})},{capture:!0}))}function Qe(e){var t=H,n=U;Fn(null),In(null);try{return e()}finally{Fn(t),In(n)}}function $e(e,t,n,r=n){e.addEventListener(t,()=>Qe(n));let i=e[le];e[le]=i?()=>{i(),r(!0)}:()=>r(!0),Ze()}function et(e,t,n,r){let i=Be()?it:st;var a=e.filter(e=>!e.settled),o=t.map(i);if(n.length===0&&a.length===0){r(o);return}var s=U,c=tt(),l=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(e=>e.promise)):null;function u(e){if(!(s.f&16384)){c();try{r([...o,...e])}catch(e){on(e,s)}nt()}}var d=rt();if(n.length===0){l.then(()=>u([])).finally(d);return}function f(){Promise.all(n.map(e=>ot(e))).then(u).catch(e=>on(e,s)).finally(d)}l?l.then(()=>{s.f&16384?d():(c(),f(),nt())}):f()}function tt(){var e=U,t=H,n=M,r=F;return function(i=!0){In(e),Fn(t),Ie(n),i&&!(e.f&16384)&&(r?.activate(),r?.apply())}}function nt(e=!0){In(null),Fn(null),Ie(null),e&&F?.deactivate()}function rt(){var e=U,t=e.b,n=F,r=!!t?.is_rendered();return t?.update_pending_count(1,n),n.increment(r,e),()=>{t?.update_pending_count(-1,n),n.decrement(r,e)}}function it(e){var t=2|h;return U!==null&&(U.f|=S),{ctx:M,deps:null,effects:null,equals:Se,f:t,fn:e,reactions:null,rv:0,v:D,wv:0,parent:U,ac:null}}var at=Symbol(`obsolete`);function ot(e,t,n){let r=U;r===null&&Ee();var i=void 0,a=Pt(D),o=!H,s=new Set;return gn(()=>{var t=U,n=p();i=n.promise;try{Promise.resolve(e()).then(n.resolve,e=>{e!==E&&n.reject(e)}).finally(nt)}catch(e){n.reject(e),nt()}var c=F;if(o){if(t.f&32768)var l=rt();if(r.b?.is_rendered())c.async_deriveds.get(t)?.reject(at);else for(let e of s.values())e.reject(at);s.add(n),c.async_deriveds.set(t,n)}let u=(e,t=void 0)=>{l?.(),s.delete(n),t!==at&&(c.activate(),t?(a.f|=T,Rt(a,t)):(a.f&8388608&&(a.f^=T),Rt(a,e)),c.deactivate())};n.promise.then(u,e=>u(null,e||`unknown`))}),dn(()=>{for(let e of s)e.reject(at)}),new Promise(e=>{function t(n){function r(){n===i?e(a):t(i)}n.then(r,r)}t(i)})}function P(e){let t=it(e);return Rn(t),t}function st(e){let t=it(e);return t.equals=we,t}function ct(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n<t.length;n+=1)Cn(t[n])}}function lt(e){var t,n=U,r=e.parent;if(!Mn&&r!==null&&e.v!==D&&r.f&24576)return pe(),e.v;In(r);try{ct(e),t=Xn(e)}finally{In(n)}return t}function ut(e){var t=lt(e);!e.equals(t)&&(e.wv=qn(),(!F?.is_fork||e.deps===null)&&(F===null?e.v=t:(F.capture(e,t,!0),mt?.capture(e,t,!0)),e.deps===null))?N(e,m):Mn||(ht===null?Ke(e):(un()||F?.is_fork)&&ht.set(e,t))}function dt(e){if(e.effects!==null)for(let t of e.effects)(t.teardown||t.ac)&&(t.teardown?.(),t.ac!==null&&Qe(()=>{t.ac.abort(E),t.ac=null}),t.fn!==null&&(t.teardown=d),$n(t,0),xn(t))}function ft(e){if(e.effects!==null)for(let t of e.effects)t.teardown&&t.fn!==null&&er(t)}var pt=null,F=null,mt=null,ht=null,gt=null,_t=!1,vt=!1,yt=null,bt=null,xt=0,St=1,Ct=class e{id=St++;#e=!1;linked=!0;#t=null;#n=null;async_deriveds=new Map;current=new Map;previous=new Map;#r=new Set;#i=new Set;#a=0;#o=new Map;#s=null;#c=[];#l=[];#u=new Set;#d=new Set;#f=new Map;#p=new Set;is_fork=!1;#m=!1;constructor(){pt===null?pt=this:(pt.#n=this,this.#t=pt),pt=this}#h(){if(this.is_fork)return!0;for(let n of this.#o.keys()){for(var e=n,t=!1;e.parent!==null;){if(this.#f.has(e)){t=!0;break}e=e.parent}if(!t)return!0}return!1}skip_effect(e){this.#f.has(e)||this.#f.set(e,{d:[],m:[]}),this.#p.delete(e)}unskip_effect(e,t=e=>this.schedule(e)){var n=this.#f.get(e);if(n){this.#f.delete(e);for(var r of n.d)N(r,h),t(r);for(r of n.m)N(r,g),t(r)}this.#p.add(e)}#g(){var e=[];for(let i of this.#c)if(!(i.f&16384||!(i.f&6144))){for(var t=i,n=!1;t.parent!==null;){t=t.parent;var r=t.f;if(r&96){if(!(r&1024)){n=!0;break}t.f^=m}}n||e.push(t)}return this.#c=[],e}#_(){this.#e=!0;for(let e of this.#u)this.#d.delete(e),N(e,h),this.schedule(e);for(let e of this.#d)N(e,g),this.schedule(e);this.apply();for(var t=yt=[],n=[],r=bt=[];this.#c.length>0;){xt++>1e3&&(this.#S(),Tt());for(let e of this.#g())try{this.#v(e,t,n)}catch(t){throw At(e),this.#h()||this.discard(),t}}if(F=null,r.length>0){var i=e.ensure();for(let e of r)i.schedule(e)}if(yt=null,bt=null,this.#h()){this.#x(n),this.#x(t);for(let[e,t]of this.#f)kt(e,t);r.length>0&&F.#_();return}let a=this.#y();if(a)this.#x(n),this.#x(t),a.#b(this);else{this.#u.clear(),this.#d.clear();for(let e of this.#r)e(this);this.#r.clear(),mt=this,Dt(n),Dt(t),mt=null,this.#s?.resolve();var o=F;if(this.#a===0&&(this.#c.length===0||o!==null)&&this.#S(),this.#c.length>0){if(o!==null){for(let e of this.#c)o.#c.push(e);this.#c=[]}else o=this}o!==null&&(Mt.clear(),o.#_())}}#v(e,t,n){e.f^=m;for(var r=e.first;r!==null;){var i=r.f,a=!!(i&96);if(!(a&&i&1024||i&8192||this.#f.has(r))&&r.fn!==null){a?r.f^=m:i&4?t.push(r):Jn(r)&&(i&16&&this.#d.add(r),er(r));var o=r.first;if(o!==null){r=o;continue}}for(;r!==null;){var s=r.next;if(s!==null){r=s;break}r=r.parent}}}#y(){for(var e=this.#t;e!==null;){if(!e.is_fork){for(let[t,[,n]]of this.current)if(e.current.has(t)&&!n)return e}e=e.#t}return null}#b(e){for(let[t,n]of e.current)!this.previous.has(t)&&e.previous.has(t)&&this.previous.set(t,e.previous.get(t)),this.current.set(t,n);for(let[t,n]of e.async_deriveds){let e=this.async_deriveds.get(t);e&&n.promise.then(e.resolve).catch(e.reject)}e.async_deriveds.clear(),this.transfer_effects(e.#u,e.#d);let t=e=>{var n=e.reactions;if(n!==null&&!(e.f&2&&!(e.f&6144)))for(let e of n){var r=e.f;if(r&2)t(e);else{var i=e;r&4194320&&!this.async_deriveds.has(i)&&(this.#d.delete(i),N(i,h),this.schedule(i))}}};for(let e of this.current.keys())t(e);this.oncommit(()=>e.discard()),e.#S(),F=this,this.#_()}#x(e){for(var t=0;t<e.length;t+=1)qe(e[t],this.#u,this.#d)}capture(e,t,n=!1){e.v!==D&&!this.previous.has(e)&&this.previous.set(e,e.v),e.f&8388608||(this.current.set(e,[t,n]),ht?.set(e,t)),this.is_fork||(e.v=t)}activate(){F=this}deactivate(){F=null,ht=null}flush(){try{vt=!0,F=this,this.#_()}finally{xt=0,gt=null,yt=null,bt=null,vt=!1,F=null,ht=null,Mt.clear()}}discard(){for(let e of this.#i)e(this);this.#i.clear();for(let e of this.async_deriveds.values())e.reject(at);this.#S(),this.#s?.resolve()}register_created_effect(e){this.#l.push(e)}increment(e,t){if(this.#a+=1,e){let e=this.#o.get(t)??0;this.#o.set(t,e+1)}}decrement(e,t){if(--this.#a,e){let e=this.#o.get(t)??0;e===1?this.#o.delete(t):this.#o.set(t,e-1)}this.#m||(this.#m=!0,Ue(()=>{this.#m=!1,this.linked&&this.flush()}))}transfer_effects(e,t){for(let t of e)this.#u.add(t);for(let e of t)this.#d.add(e);e.clear(),t.clear()}oncommit(e){this.#r.add(e)}ondiscard(e){this.#i.add(e)}settled(){return(this.#s??=p()).promise}static ensure(){if(F===null){let t=F=new e;!vt&&!_t&&Ue(()=>{t.#e||t.flush()})}return F}apply(){ht=null}schedule(e){gt=e,e.b?.is_pending&&e.f&16777228&&!(e.f&32768)?e.b.defer_effect(e):this.#c.push(e)}#S(){if(this.linked){var e=this.#t,t=this.#n;e===null||(e.#n=t),t===null?pt=e:t.#t=e,this.linked=!1}}};function wt(e){var t=_t,n=mt;mt=null,_t=!0;try{var r;for(e&&(wt(),r=e());;){if(We(),F===null)return r;F.flush()}}finally{_t=t,mt=n}}function Tt(){try{je()}catch(e){on(e,gt)}}var Et=null;function Dt(e){var t=e.length;if(t!==0){for(var n=0;n<t;){var r=e[n++];if(!(r.f&24576)&&Jn(r)&&(Et=new Set,er(r),r.deps===null&&r.first===null&&r.nodes===null&&r.teardown===null&&r.ac===null&&Tn(r),Et?.size>0)){Mt.clear();for(let e of Et){if(e.f&24576)continue;let t=[e],n=e.parent;for(;n!==null;)Et.has(n)&&(Et.delete(n),t.push(n)),n=n.parent;for(let e=t.length-1;e>=0;e--){let n=t[e];n.f&24576||er(n)}}Et.clear()}}Et=null}}function Ot(e){F.schedule(e)}function kt(e,t){if(!(e.f&32&&e.f&1024)){e.f&2048?t.d.push(e):e.f&4096&&t.m.push(e),N(e,m);for(var n=e.first;n!==null;)kt(n,t),n=n.next}}function At(e){N(e,m);for(var t=e.first;t!==null;)At(t),t=t.next}var jt=new Set,Mt=new Map,Nt=!1;function Pt(e,t){return{f:0,v:e,reactions:null,equals:Se,rv:0,wv:0}}function I(e,t){let n=Pt(e,t);return Rn(n),n}function Ft(e,t=!1,n=!0){let r=Pt(e);return t||(r.equals=we),r}function L(e,t,n=!1){return H!==null&&(!Pn||H.f&131072)&&Be()&&H.f&4325394&&(Ln===null||!Ln.has(e))&&Pe(),Rt(e,n?Ht(t):t,bt)}var It=null,Lt=0;function Rt(e,t,n=null){if(!e.equals(t)){Mn?Mt.set(e,t):Mt.has(e)||Mt.set(e,e.v);var r=Ct.ensure();if(r.capture(e,t),e.f&2){let t=e;e.f&2048&<(t),ht===null&&Ke(t)}e.wv=qn(),It=null,Lt=0,Vt(e,h,n),It=null,Be()&&U!==null&&U.f&1024&&!(U.f&96)&&(Vn===null?Hn([e]):Vn.push(e)),!r.is_fork&&jt.size>0&&!Nt&&zt()}return t}function zt(){Nt=!1;for(let e of jt){e.f&1024&&N(e,g);let t;try{t=Jn(e)}catch{t=!0}t&&er(e)}jt.clear()}function Bt(e){L(e,e.v+1)}function Vt(e,t,n){var r=e.reactions;if(r!==null){var i=Be(),a=r.length;if(Lt+=a,Lt>1e5&&It===null&&(It=new Set),It!==null){if(It.has(e))return;It.add(e)}for(var o=0;o<a;o++){var s=r[o],c=s.f;if(i||s!==U){var l=(c&h)===0;if(l&&N(s,t),c&131072)jt.add(s);else if(c&2){var u=s;ht?.delete(u),Vt(u,g,n)}else if(l){var d=s;c&16&&Et!==null&&Et.add(d),n===null?Ot(d):n.push(d)}}}}}function Ht(t){if(typeof t!=`object`||!t||ne in t||re in t)return t;let n=l(t);if(n!==s&&n!==c)return t;var r=new Map,i=e(t),o=I(0),u=null,d=Gn,f=e=>{if(Gn===d)return e();var t=H,n=Gn;Fn(null),Kn(d);var r=e();return Fn(t),Kn(n),r};return i&&r.set(`length`,I(t.length,u)),new Proxy(t,{defineProperty(e,t,n){(!(`value`in n)||n.configurable===!1||n.enumerable===!1||n.writable===!1)&&Me();var i=r.get(t);return i===void 0?f(()=>{var e=I(n.value,u);return r.set(t,e),e}):L(i,n.value,!0),!0},deleteProperty(e,t){var n=r.get(t);if(n===void 0){if(t in e){let e=f(()=>I(D,u));r.set(t,e),Bt(o)}}else L(n,D),Bt(o);return!0},get(e,n,i){if(n===ne)return t;var o=r.get(n),s=n in e;if(o===void 0&&(!s||a(e,n)?.writable)&&(o=f(()=>I(Ht(s?e[n]:D),u)),r.set(n,o)),o!==void 0){var c=W(o);return c===D?void 0:c}return Reflect.get(e,n,i)},getOwnPropertyDescriptor(e,t){this.has?.(e,t);var n=Reflect.getOwnPropertyDescriptor(e,t),i=r.get(t);if(i!==void 0){var a=W(i);if(a===D)return;if(n&&`value`in n)n.value=a;else return{enumerable:!0,configurable:!0,value:a,writable:!0}}return n},has(e,t){if(t===ne)return!0;var n=r.get(t),i=n!==void 0&&n.v!==D||Reflect.has(e,t);return(n!==void 0||U!==null&&(!i||a(e,t)?.writable))&&(n===void 0&&(n=f(()=>I(i?Ht(e[t]):D,u)),r.set(t,n)),W(n)===D)?!1:i},set(e,t,n,s){var c=r.get(t),l=t in e;if(i&&t===`length`)for(var d=n;d<c.v;d+=1){var p=r.get(d+``);p===void 0?d in e&&(p=f(()=>I(D,u)),r.set(d+``,p)):L(p,D)}if(c===void 0)(!l||a(e,t)?.writable)&&(c=f(()=>I(void 0,u)),L(c,Ht(n)),r.set(t,c));else{l=c.v!==D;var m=f(()=>Ht(n));L(c,m)}var h=Reflect.getOwnPropertyDescriptor(e,t);if(h?.set&&h.set.call(s,n),!l){if(i&&typeof t==`string`){var g=r.get(`length`),_=Number(t);Number.isInteger(_)&&_>=g.v&&L(g,_+1)}Bt(o)}return!0},ownKeys(e){W(o);var t=Reflect.ownKeys(e).filter(e=>{var t=r.get(e);return t===void 0||t.v!==D});for(var[n,i]of r)i.v!==D&&!(n in e)&&t.push(n);return t},setPrototypeOf(){Ne()}})}function Ut(e){try{if(typeof e==`object`&&e&&ne in e)return e[ne]}catch{}return e}function Wt(e,t){return Object.is(Ut(e),Ut(t))}var Gt,Kt,qt,Jt;function Yt(){if(Gt===void 0){Gt=window,Kt=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;qt=a(t,`firstChild`).get,Jt=a(t,`nextSibling`).get,u(e)&&(e[oe]=void 0,e[ae]=null,e[se]=void 0,e.__e=void 0),u(n)&&(n[ce]=void 0)}}function Xt(e=``){return document.createTextNode(e)}function Zt(e){return qt.call(e)}function Qt(e){return Jt.call(e)}function R(e,t){if(!O)return Zt(e);var n=Zt(k);if(n===null)n=k.appendChild(Xt());else if(t&&n.nodeType!==3){var r=Xt();return n?.before(r),A(r),r}return t&&rn(n),A(n),n}function $t(e,t=!1){if(!O){var n=Zt(e);return n instanceof Comment&&n.data===``?Qt(n):n}if(t){if(k?.nodeType!==3){var r=Xt();return k?.before(r),A(r),r}rn(k)}return k}function z(e,t=!1){if(!O)return Zt(e);var n=R(e,t);return j(e),n}function B(e,t=1,n=!1){let r=O?k:e;for(var i;t--;)i=r,r=Qt(r);if(!O)return r;if(n){if(r?.nodeType!==3){var a=Xt();return r===null?i?.after(a):r.before(a),A(a),a}rn(r)}return A(r),r}function en(e){e.textContent=``}function tn(){return!1}function nn(e,t,n){return t==null||t===`http://www.w3.org/1999/xhtml`?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function rn(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===3;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function an(e){var t=U;if(t===null)return H.f|=T,e;if(!(t.f&32768)&&!(t.f&4))throw e;on(e,t)}function on(e,t){if(e===de)throw e;if(!(t!==null&&t.f&16384)){for(;t!==null;){if(t.f&128&&!(t.f&33570816)){if(!(t.f&32768))throw e;try{t.b.error(e);return}catch(t){e=t}}t=t.parent}throw e}}function sn(e){U===null&&(H===null&&Ae(e),ke()),Mn&&Oe(e)}function cn(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function ln(e,t){var n=U;n!==null&&n.f&8192&&(e|=_);var r={ctx:M,deps:null,nodes:null,f:e|h|512,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};F?.register_created_effect(r);var i=r;if(e&4)yt===null?Ct.ensure().schedule(r):yt.push(r);else if(t!==null){try{er(r)}catch(e){throw Cn(r),e}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&!(i.f&524288)&&(i=i.first,e&16&&e&65536&&i!==null&&(i.f|=x))}if(i!==null&&(i.parent=n,n!==null&&cn(i,n),H!==null&&H.f&2&&!(e&64))){var a=H;(a.effects??=[]).push(i)}return r}function un(){return H!==null&&!Pn}function dn(e){let t=ln(8,null);return N(t,m),t.teardown=e,t}function fn(e){sn(`$effect`);var t=U.f;if(!H&&t&32&&M!==null&&!M.i){var n=M;(n.e??=[]).push(e)}else return pn(e)}function pn(e){return ln(4|ee,e)}function mn(e){Ct.ensure();let t=ln(64|S,e);return(e={})=>new Promise(n=>{e.outro?En(t,()=>{Cn(t),n(void 0)}):(Cn(t),n(void 0))})}function hn(e){return ln(4,e)}function gn(e){return ln(te|S,e)}function _n(e,t=0){return ln(8|t,e)}function V(e,t=[],n=[],r=[]){et(r,t,n,t=>{ln(8,()=>{e(...t.map(W))})})}function vn(e,t=0){return ln(16|t,e)}function yn(e){return ln(32|S,e)}function bn(e){var t=e.teardown;if(t!==null){let n=Mn,r=H;Nn(!0),Fn(null);try{t.call(null)}catch(t){on(t,e.parent)}finally{Nn(n),Fn(r)}}}function xn(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){let e=n.ac;e!==null&&Qe(()=>{e.abort(E)});var r=n.next;n.f&64?n.parent=null:Cn(n,t),n=r}}function Sn(e){for(var t=e.first;t!==null;){var n=t.next;t.f&32||Cn(t),t=n}}function Cn(e,t=!0){var n=!1;(t||e.f&262144)&&e.nodes!==null&&e.nodes.end!==null&&(wn(e.nodes.start,e.nodes.end),n=!0),e.f|=b,xn(e,t&&!n),$n(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)e.stop();bn(e),e.f^=b,e.f|=v;var i=e.parent;i!==null&&i.first!==null&&Tn(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function wn(e,t){for(;e!==null;){var n=e===t?null:Qt(e);e.remove(),e=n}}function Tn(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function En(e,t,n=!0){var r=[];e.f|=256,Dn(e,r,!0);var i=()=>{n&&Cn(e),t&&t()},a=r.length;if(a>0){var o=()=>--a||i();for(var s of r)s.out(o)}else i()}function Dn(e,t,n){if(!(e.f&8192)){e.f^=_;var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)(e.is_global||n)&&t.push(e);for(var i=e.first;i!==null;){var a=i.next;if(!(i.f&64)){var o=!!(i.f&65536)||!!(i.f&32)&&!!(e.f&16);Dn(i,t,o?n:!1)}i=a}}}function On(e){e.f&=-257,kn(e,!0)}function kn(e,t){if(!(e.f&256)&&e.f&8192){e.f^=_,e.f&1024||(N(e,h),Ct.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=!!(n.f&65536)||!!(n.f&32);kn(n,i?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(let e of a)(e.is_global||t)&&e.in()}}function An(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:Qt(n);t.append(n),n=i}}var jn=null,Mn=!1;function Nn(e){Mn=e}var H=null,Pn=!1;function Fn(e){H=e}var U=null;function In(e){U=e}var Ln=null;function Rn(e){H!==null&&(H.f&2097152||H.f&2)&&(Ln??=new Set).add(e)}var zn=null,Bn=0,Vn=null;function Hn(e){Vn=e}var Un=1,Wn=0,Gn=Wn;function Kn(e){Gn=e}function qn(){return++Un}function Jn(e){var t=e.f;if(t&2048)return!0;if(t&4096){for(var n=e.deps,r=n.length,i=0;i<r;i++){var a=n[i];if(Jn(a)&&ut(a),a.wv>e.wv)return!0}t&512&&ht===null&&N(e,m)}return!1}function Yn(e,t,n=!0){var r=e.reactions;if(r!==null&&!(Ln!==null&&Ln.has(e)))for(var i=0;i<r.length;i++){var a=r[i];a.f&2?Yn(a,t,!1):t===a&&(n?N(a,h):a.f&1024&&N(a,g),Ot(a))}}function Xn(e){var t=zn,n=Bn,r=Vn,i=H,a=Ln,o=M,s=Pn,c=Gn,l=e.f;zn=null,Bn=0,Vn=null,H=l&96?null:e,Ln=null,Ie(e.ctx),Pn=!1,Gn=++Wn,e.ac!==null&&(Qe(()=>{e.ac.abort(E)}),e.ac=null);try{e.f|=w;var u=e.fn,d=u();e.f|=y;var f=Zn(e);if(Be()&&Vn!==null&&!Pn&&f!==null&&!(e.f&6146))for(var p=0;p<Vn.length;p++)Yn(Vn[p],e);if(i!==null&&i!==e){if(Wn++,i.deps!==null)for(let e=0;e<n;e+=1)i.deps[e].rv=Wn;if(t!==null)for(let e of t)e.rv=Wn;Vn!==null&&(r===null?r=Vn:r.push(...Vn))}return e.f&8388608&&(e.f^=T),d}catch(t){return Zn(e),an(t)}finally{e.f^=w,zn=t,Bn=n,Vn=r,H=i,Ln=a,Ie(o),Pn=s,Gn=c}}function Zn(e){var t=e.deps,n=F?.is_fork;if(zn!==null){var r;if(n||$n(e,Bn),t!==null&&Bn>0)for(t.length=Bn+zn.length,r=0;r<zn.length;r++)t[Bn+r]=zn[r];else e.deps=t=zn;if(un()&&e.f&512)for(r=Bn;r<t.length;r++)(t[r].reactions??=[]).push(e)}else!n&&t!==null&&Bn<t.length&&($n(e,Bn),t.length=Bn);return t}function Qn(e,r){let i=r.reactions;if(i!==null){var a=t.call(i,e);if(a!==-1){var o=i.length-1;o===0?i=r.reactions=null:(i[a]=i[o],i.pop())}}if(i===null&&r.f&2&&(zn===null||!n.call(zn,r))){var s=r;s.f&512&&(s.f^=512),s.v!==D&&Ke(s),s.ac!==null&&Qe(()=>{s.ac.abort(E),s.ac=null,N(s,h)}),dt(s),$n(s,0)}}function $n(e,t){var n=e.deps;if(n!==null)for(var r=t;r<n.length;r++)Qn(e,n[r])}function er(e){var t=e.f;if(!(t&16384)){N(e,m);var n=U;U=e;try{t&16777232?Sn(e):xn(e),bn(e);var r=Xn(e);e.teardown=typeof r==`function`?r:null,e.wv=Un}finally{U=n}}}async function tr(){await Promise.resolve(),wt()}function W(e){var t=!!(e.f&2);if(jn?.add(e),H!==null&&!Pn&&!(U!==null&&U.f&16384)&&(Ln===null||!Ln.has(e))){var r=H.deps;if(H.f&2097152)e.rv<Wn&&(e.rv=Wn,zn===null&&r!==null&&r[Bn]===e?Bn++:zn===null?zn=[e]:zn.push(e));else{H.deps??=[],n.call(H.deps,e)||H.deps.push(e);var i=e.reactions;i===null?e.reactions=[H]:n.call(i,H)||i.push(H)}}if(Mn&&Mt.has(e))return Mt.get(e);if(t){var a=e;if(Mn){var o=a.v;return(!(a.f&1024)&&a.reactions!==null||rr(a))&&(o=lt(a)),Mt.set(a,o),o}var s=!(a.f&512)&&!Pn&&H!==null&&!!(H.f&512),c=(a.f&y)===0;Jn(a)&&(s&&(a.f|=512),ut(a)),s&&!c&&(ft(a),nr(a))}if(ht?.has(e))return ht.get(e);if(e.f&8388608)throw e.v;return e.v}function nr(e){if(e.f|=512,e.deps!==null)for(let r of e.deps){var t=r.reactions;t===null?r.reactions=[e]:n.call(t,e)||t.push(e),r.f&2&&!(r.f&512)&&(ft(r),nr(r))}}function rr(e){if(e.v===D)return!0;if(e.deps===null)return!1;for(let t of e.deps)if(Mt.has(t)||t.f&2&&rr(t))return!0;return!1}function ir(e){var t=Pn;try{return Pn=!0,e()}finally{Pn=t}}[...`allowfullscreen.async.autofocus.autoplay.checked.controls.default.disabled.formnovalidate.indeterminate.inert.ismap.loop.multiple.muted.nomodule.novalidate.open.playsinline.readonly.required.reversed.seamless.selected.webkitdirectory.defer.disablepictureinpicture.disableremoteplayback`.split(`.`)];var ar=[`touchstart`,`touchmove`];function or(e){return ar.includes(e)}var sr=Symbol(`events`),cr=new Set,lr=new Set;function ur(e,t,n,r={}){function i(e){if(r.capture||hr.call(t,e),!e.cancelBubble)return Qe(()=>n?.call(this,e))}return e.startsWith(`pointer`)||e.startsWith(`touch`)||e===`wheel`?(i.__removed=!1,Ue(()=>{i.__removed||t.addEventListener(e,i,r)})):t.addEventListener(e,i,r),i}function dr(e,t,n,r,i){var a={capture:r,passive:i},o=ur(e,t,n,a);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&dn(()=>{o.__removed=!0,t.removeEventListener(e,o,a)})}function G(e,t,n){(t[sr]??={})[e]=n}function fr(e){for(var t=0;t<e.length;t++)cr.add(e[t]);for(var n of lr)n(e)}var pr=null,mr=!1;function hr(e){var t=this,n=t.ownerDocument,r=e.type,a=e.composedPath?.()||[],o=a[0]||e.target;pr=e,mr||(mr=!0,setTimeout(()=>{mr=!1,pr=null}));var s=0,c=pr===e&&e[sr];if(c){var l=a.indexOf(c);if(l!==-1&&(t===document||t===window)){e[sr]=t;return}var u=a.indexOf(t);if(u===-1)return;l<=u&&(s=l)}if(o=a[s]||e.target,o!==t){i(e,`currentTarget`,{configurable:!0,get(){return o||n}});var d=H,f=U;Fn(null),In(null);try{for(var p,m=[];o!==null&&o!==t;){try{var h=o[sr]?.[r];h!=null&&(!o.disabled||e.target===o)&&h.call(o,e)}catch(e){p?m.push(e):p=e}if(e.cancelBubble)break;s++,o=s<a.length?a[s]:null}if(p){for(let e of m)queueMicrotask(()=>{throw e});throw p}}finally{e[sr]=t,delete e.currentTarget,Fn(d),In(f)}}}var gr=globalThis?.window?.trustedTypes&&globalThis.window.trustedTypes.createPolicy(`svelte-trusted-html`,{createHTML:e=>e});function _r(e){return gr?.createHTML(e)??e}function vr(e){var t=nn(`template`);return t.innerHTML=_r(e.replaceAll(`<!>`,`<!---->`)),t.content}function yr(e,t){var n=U;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function K(e,t){var n=!!(t&1),r=!!(t&2),i,a=!e.startsWith(`<!>`);return()=>{if(O)return yr(k,null),k;i===void 0&&(i=vr(a?e:`<!>`+e),n||(i=Zt(i)));var t=r||Kt?document.importNode(i,!0):i.cloneNode(!0);if(n){var o=Zt(t),s=t.lastChild;yr(o,s)}else yr(t,t);return t}}function br(e,t,n=`svg`){var r=!e.startsWith(`<!>`),i=!!(t&1),a=`<${n}>${r?e:`<!>`+e}</${n}>`,o;return()=>{if(O)return yr(k,null),k;if(!o){var e=Zt(vr(a));if(i)for(o=document.createDocumentFragment();Zt(e);)o.appendChild(Zt(e));else o=Zt(e)}var t=o.cloneNode(!0);if(i){var n=Zt(t),r=t.lastChild;yr(n,r)}else yr(t,t);return t}}function xr(e,t){return br(e,t,`svg`)}function Sr(e=``){if(!O){var t=Xt(e+``);return yr(t,t),t}var n=k;return n.nodeType===3?rn(n):(n.before(n=Xt()),A(n)),yr(n,n),n}function Cr(){if(O)return yr(k,null),k;var e=document.createDocumentFragment(),t=document.createComment(``),n=Xt();return e.append(t,n),yr(t,n),e}function q(e,t){if(O){var n=U;(!(n.f&32768)||n.nodes.end===null)&&(n.nodes.end=k),ve()}else e!==null&&e.before(t)}function wr(e){let t=0,n=Pt(0),r;return()=>{un()&&(W(n),_n(()=>(t===0&&(r=ir(()=>e(()=>Bt(n)))),t+=1,()=>{Ue(()=>{--t,t===0&&(r?.(),r=void 0,Bt(n))})})))}}var Tr=x|S;function Er(e,t,n,r){new Dr(e,t,n,r)}var Dr=class{parent;is_pending=!1;transform_error;#e;#t=O?k:null;#n;#r;#i;#a=null;#o=null;#s=null;#c=null;#l=0;#u=0;#d=!1;#f=new Set;#p=new Set;#m=null;#h=wr(()=>(this.#m=Pt(this.#l),()=>{this.#m=null}));constructor(e,t,n,r){this.#e=e,this.#n=t,this.#r=e=>{var t=U;t.b=this,t.f|=128,n(e)},this.parent=U.b,this.transform_error=r??this.parent?.transform_error??(e=>e),this.#i=vn(()=>{if(O){let e=xe(this.#t);ve();let t=e===`[!`;if(e.startsWith(`[?`)){let t=JSON.parse(e.slice(2));this.#_(t)}else t?this.#b():this.#g()}else this.#x()},Tr),O&&(this.#e=k)}#g(){try{this.#a=yn(()=>this.#r(this.#e))}catch(e){this.error(e)}}#_(e){let t=this.#n.failed,{reset:n,invoke_onerror:r}=this.#v(e);Ue(r),t&&(this.#s=yn(()=>{t(this.#e,()=>e,()=>n)}))}#v(e){var t=!1,n=!1;let r=()=>{this.#y()||(t?ge():(t=!0,n&&Fe(),this.#s!==null&&En(this.#s,()=>{this.#s=null}),this.#C(()=>{this.#x()})))};return{reset:r,invoke_onerror:()=>{if(!this.#y())try{n=!0,this.#n.onerror?.(e,r),n=!1}catch(e){on(e,this.#i&&this.#i.parent)}}}}#y(){return(this.#i.f&(v|b))!==0}#b(){let e=this.#n.pending;e&&(this.is_pending=!0,this.#o=yn(()=>e(this.#e)),Ue(()=>{if(!this.#y()){var e=this.#c=document.createDocumentFragment(),t=Xt(),n=!1;e.append(t),this.#a=this.#C(()=>{try{return yn(()=>this.#r(t))}catch(e){try{this.error(e),n=!0}catch(e){on(e,this.#i.parent)}return null}}),this.#a===null?(this.#c=null,n&&this.#S(F)):this.#u===0&&(this.#e.before(e),this.#c=null,En(this.#o,()=>{this.#o=null}),this.#S(F))}}))}#x(){try{if(this.is_pending=this.has_pending_snippet(),this.#u=0,this.#l=0,this.#a=yn(()=>{this.#r(this.#e)}),this.#u>0){var e=this.#c=document.createDocumentFragment();An(this.#a,e);let t=this.#n.pending;this.#o=yn(()=>t(this.#e))}else this.#S(F)}catch(e){this.error(e)}}#S(e){this.is_pending=!1,e.transfer_effects(this.#f,this.#p)}defer_effect(e){qe(e,this.#f,this.#p)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#n.pending}#C(e){var t=U,n=H,r=M;In(this.#i),Fn(this.#i),Ie(this.#i.ctx);try{return Ct.ensure(),e()}finally{In(t),Fn(n),Ie(r)}}#w(e,t){this.has_pending_snippet()?(this.#u+=e,this.#u===0&&(this.#S(t),this.#o&&En(this.#o,()=>{this.#o=null}),this.#c&&=(this.#e.before(this.#c),null))):this.parent&&this.parent.#w(e,t)}update_pending_count(e,t){this.#w(e,t),this.#l+=e,!(!this.#m||this.#d)&&(this.#d=!0,Ue(()=>{this.#d=!1,this.#m&&Rt(this.#m,this.#l)}))}get_effect_pending(){return this.#h(),W(this.#m)}error(e){if(e===de||!this.#n.onerror&&!this.#n.failed)throw e;F?.is_fork?(this.#a&&F.skip_effect(this.#a),this.#o&&F.skip_effect(this.#o),this.#s&&F.skip_effect(this.#s),F.oncommit(()=>{this.#y()||this.#T(e)})):this.#T(e)}#T(e){this.#a&&=(Cn(this.#a),null),this.#o&&=(Cn(this.#o),null),this.#s&&=(Cn(this.#s),null),O&&(A(this.#t),ye(),A(be()));let t=this.#n.failed,n=e=>{if(this.#y())return;let{reset:n,invoke_onerror:r}=this.#v(e);r(),t&&!this.#y()&&(this.#s=this.#C(()=>{try{return yn(()=>{var r=U;r.b=this,r.f|=128,t(this.#e,()=>e,()=>n)})}catch(e){return on(e,this.#i.parent),null}}))};Ue(()=>{if(!this.#y()){var t;try{t=this.transform_error(e)}catch(e){on(e,this.#i&&this.#i.parent);return}typeof t==`object`&&t&&typeof t.then==`function`?t.then(n,e=>on(e,this.#i&&this.#i.parent)):n(t)}})}};function J(e,t){var n=t==null?``:typeof t==`object`?`${t}`:t;n!==(e[ce]??=e.nodeValue)&&(e[ce]=n,e.nodeValue=`${n}`)}function Or(e,t){return Ar(e,t)}var kr=new Map;function Ar(e,{target:t,anchor:n,props:i={},events:a,context:o,intro:s=!0,transformError:c}){Yt();var l=void 0,u=mn(()=>{var s=n??t.appendChild(Xt());Er(s,{pending:()=>{}},t=>{Le({});var n=M;if(o&&(n.c=o),a&&(i.$$events=a),O&&yr(t,null),l=e(t,i)||ze(),O&&(U.nodes.end=k,k===null||k.nodeType!==8||k.data!==`]`))throw me(),de;Re()},c);var u=new Set,d=e=>{for(var n=0;n<e.length;n++){var r=e[n];if(!u.has(r)){u.add(r);var i=or(r);for(let e of[t,document]){var a=kr.get(e);a===void 0&&(a=new Map,kr.set(e,a));var o=a.get(r);o===void 0?(e.addEventListener(r,hr,{passive:i}),a.set(r,1)):a.set(r,o+1)}}}};return d(r(cr)),lr.add(d),()=>{for(var e of u)for(let n of[t,document]){var r=kr.get(n),i=r.get(e);--i==0?(n.removeEventListener(e,hr),r.delete(e),r.size===0&&kr.delete(n)):r.set(e,i)}lr.delete(d),s!==n&&s.parentNode?.removeChild(s)}});return jr.set(l,u),l}var jr=new WeakMap,Mr=class{anchor;#e=new Map;#t=new Map;#n=new Map;#r=new Set;#i=!0;constructor(e,t=!0){this.anchor=e,this.#i=t}#a=e=>{if(this.#e.has(e)){var t=this.#e.get(e),n=this.#t.get(t);if(n)On(n),this.#r.delete(t);else{var r=this.#n.get(t);r&&(On(r.effect),this.#t.set(t,r.effect),this.#n.delete(t),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),n=r.effect)}for(let[t,n]of this.#e){if(this.#e.delete(t),t===e)break;let r=this.#n.get(n);r&&(Cn(r.effect),this.#n.delete(n))}for(let[e,r]of this.#t){if(e===t||this.#r.has(e))continue;let i=()=>{if(Array.from(this.#e.values()).includes(e)){var t=document.createDocumentFragment();An(r,t),t.append(Xt()),this.#n.set(e,{effect:r,fragment:t})}else Cn(r);this.#r.delete(e),this.#t.delete(e)};this.#i||!n?(this.#r.add(e),En(r,i,!1)):i()}}};#o=e=>{this.#e.delete(e);let t=Array.from(this.#e.values());for(let[e,n]of this.#n)t.includes(e)||(Cn(n.effect),this.#n.delete(e))};ensure(e,t){var n=F,r=tn();if(t&&!this.#t.has(e)&&!this.#n.has(e)){if(r){var i=document.createDocumentFragment(),a=Xt();i.append(a),this.#n.set(e,{effect:yn(()=>t(a)),fragment:i})}else this.#t.set(e,yn(()=>t(this.anchor)))}if(this.#e.set(n,e),r){for(let[t,r]of this.#t)t===e?n.unskip_effect(r):n.skip_effect(r);for(let[t,r]of this.#n)t===e?n.unskip_effect(r.effect):n.skip_effect(r.effect);n.oncommit(this.#a),n.ondiscard(this.#o)}else O&&(this.anchor=k),this.#a(n)}};function Y(e,t,n=!1){var r;O&&(r=k,ve());var i=new Mr(e),a=n?x:0;function o(e,t){if(O){var n=xe(r);if(e!==parseInt(n.substring(1))){var a=be();A(a),i.anchor=a,_e(!1),i.ensure(e,t),_e(!0);return}}i.ensure(e,t)}vn(()=>{var e=!1;t((t,n=0)=>{e=!0,o(n,t)}),e||o(-1,null)},a)}function Nr(e,t){return t}function Pr(e,t,n){for(var i=[],a=t.length,o,s=t.length,c=0;c<a;c++){let n=t[c];En(n,()=>{if(o){if(o.pending.delete(n),o.done.add(n),o.pending.size===0){var t=e.outrogroups;Fr(e,r(o.done)),t.delete(o),t.size===0&&(e.outrogroups=null)}}else--s},!1)}if(s===0){var l=i.length===0&&n!==null&&e.pending.size===0;if(l){var u=n,d=u.parentNode;en(d),d.append(u),e.items.clear()}Fr(e,t,!l)}else o={pending:new Set(t),done:new Set},(e.outrogroups??=new Set).add(o)}function Fr(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(let t of e.pending.values())for(let n of t)r.add(e.items.get(n).e)}for(var i=0;i<t.length;i++){var a=t[i];r?.has(a)?(a.f|=C,An(a,document.createDocumentFragment())):Cn(t[i],n)}}var Ir;function X(t,n,i,a,o,s=null){var c=t,l=new Map;if(n&4){var u=t;c=O?A(Zt(u)):u.appendChild(Xt())}O&&ve();var d=null,f=st(()=>{var t=i();return e(t)?t:t==null?[]:r(t)}),p=new Map,m=!0;function h(e){if(!(_.effect.f&16384)){_.pending.delete(e);var t=W(f);_.fallback=d,Rr(_,t,c,n,a),d!==null&&(t.length===0?d.f&33554432?(d.f^=C,Br(d,null,c)):On(d):En(d,()=>{d=null}))}}function g(e){_.pending.delete(e)}var _={effect:vn(()=>{var e=W(f),t=e.length;let r=!1;O&&xe(c)===`[!`!=(t===0)&&(c=be(),A(c),_e(!1),r=!0);for(var u=new Set,_=F,v=tn(),y=0;y<t;y+=1){O&&k.nodeType===8&&k.data===`]`&&(c=k,r=!0,_e(!1));var b=e[y],x=a(b,y),S=m?null:l.get(x);S?(S.v&&Rt(S.v,b),S.i&&Rt(S.i,y),v&&_.unskip_effect(S.e)):(S=zr(l,m?c:Ir??=Xt(),b,x,y,o,n,i),m||(S.e.f|=C),l.set(x,S)),u.add(x)}if(t===0&&s&&!d&&(m?d=yn(()=>s(c)):(d=yn(()=>s(Ir??=Xt())),d.f|=C)),t>u.size&&De(``,``,``),O&&t>0&&A(be()),!m){if(p.set(_,u),v){for(let[e,t]of l)u.has(e)||_.skip_effect(t.e);_.oncommit(h),_.ondiscard(g)}else h(_)}r&&_e(!0),W(f)}),flags:n,items:l,pending:p,outrogroups:null,fallback:d};m=!1,O&&(c=k)}function Lr(e){for(;e!==null&&!(e.f&32);)e=e.next;return e}function Rr(e,t,n,i,a){var o=!!(i&8),s=t.length,c=e.items,l=Lr(e.effect.first),u,d=null,f,p=[],m=[],h,g,_,v;if(o)for(v=0;v<s;v+=1)h=t[v],g=a(h,v),_=c.get(g).e,_.f&33554432||(_.nodes?.a?.measure(),(f??=new Set).add(_));for(v=0;v<s;v+=1){if(h=t[v],g=a(h,v),_=c.get(g).e,e.outrogroups!==null)for(let t of e.outrogroups)t.pending.delete(_),t.done.delete(_);if(_.f&8192&&(On(_),o&&(_.nodes?.a?.unfix(),(f??=new Set).delete(_))),_.f&33554432){if(_.f^=C,_===l)Br(_,null,n);else{var y=d?d.next:l;_===e.effect.last&&(e.effect.last=_.prev),_.prev&&(_.prev.next=_.next),_.next&&(_.next.prev=_.prev),Vr(e,d,_),Vr(e,_,y),Br(_,y,n),d=_,p=[],m=[],l=Lr(d.next);continue}}if(_!==l){if(u!==void 0&&u.has(_)){if(p.length<m.length){var b=m[0],x;d=b.prev;var S=p[0],ee=p[p.length-1];for(x=0;x<p.length;x+=1)Br(p[x],b,n);for(x=0;x<m.length;x+=1)u.delete(m[x]);Vr(e,S.prev,ee.next),Vr(e,d,S),Vr(e,ee,b),l=b,d=ee,--v,p=[],m=[]}else u.delete(_),Br(_,l,n),Vr(e,_.prev,_.next),Vr(e,_,d===null?e.effect.first:d.next),Vr(e,d,_),d=_;continue}for(p=[],m=[];l!==null&&l!==_;)(u??=new Set).add(l),m.push(l),l=Lr(l.next);if(l===null)continue}_.f&33554432||p.push(_),d=_,l=Lr(_.next)}if(e.outrogroups!==null){for(let t of e.outrogroups)t.pending.size===0&&(Fr(e,r(t.done)),e.outrogroups?.delete(t));e.outrogroups.size===0&&(e.outrogroups=null)}if(l!==null||u!==void 0){var w=[];if(u!==void 0)for(_ of u)_.f&8192||w.push(_);for(;l!==null;)!(l.f&8192)&&l!==e.fallback&&w.push(l),l=Lr(l.next);var te=w.length;if(te>0){var T=i&4&&s===0?n:null;if(o){for(v=0;v<te;v+=1)w[v].nodes?.a?.measure();for(v=0;v<te;v+=1)w[v].nodes?.a?.fix()}Pr(e,w,T)}}o&&Ue(()=>{if(f!==void 0)for(_ of f)_.nodes?.a?.apply()})}function zr(e,t,n,r,i,a,o,s){var c=o&1?o&16?Pt(n):Ft(n,!1,!1):null,l=o&2?Pt(i):null;return{v:c,i:l,e:yn(()=>(a(t,c??n,l??i,s),()=>{e.delete(r)}))}}function Br(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,a=t&&!(t.f&33554432)?t.nodes.start:n;r!==null;){var o=Qt(r);if(a.before(r),r===i)return;r=o}}function Vr(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function Hr(e,t,...n){var r=new Mr(e);vn(()=>{let e=t()??null;r.ensure(e,e&&(t=>e(t,...n)))},x)}var Ur=[...`
|
|
2
|
+
\r\f\xA0\v`];function Wr(e,t,n){var r=e==null?``:``+e;if(t&&(r=r?r+` `+t:t),n){for(var i of Object.keys(n))if(n[i])r=r?r+` `+i:i;else if(r.length)for(var a=i.length,o=0;(o=r.indexOf(i,o))>=0;){var s=o+a;(o===0||Ur.includes(r[o-1]))&&(s===r.length||Ur.includes(r[s]))?r=(o===0?``:r.substring(0,o))+r.substring(s+1):o=s}}return r===``?null:r}function Gr(e,t=!1){var n=t?` !important;`:`;`,r=``;for(var i of Object.keys(e)){var a=e[i];a!=null&&a!==``&&(r+=` `+i+`: `+a+n)}return r}function Kr(e){return e[0]!==`-`||e[1]!==`-`?e.toLowerCase():e}function qr(e,t){if(t){var n=``,r,i;if(Array.isArray(t)?(r=t[0],i=t[1]):r=t,e){e=String(e).replaceAll(/\/\*.*?\*\//g,``).trim();var a=!1,o=0,s=!1,c=[];r&&c.push(...Object.keys(r).map(Kr)),i&&c.push(...Object.keys(i).map(Kr));var l=0,u=-1;let t=e.length;for(var d=0;d<t;d++){var f=e[d];if(s?f===`/`&&e[d-1]===`*`&&(s=!1):a?a===f&&(a=!1):f===`/`&&e[d+1]===`*`?s=!0:f===`"`||f===`'`?a=f:f===`(`?o++:f===`)`&&o--,!s&&a===!1&&o===0){if(f===`:`&&u===-1)u=d;else if(f===`;`||d===t-1){if(u!==-1){var p=Kr(e.substring(l,u).trim());if(!c.includes(p)){f!==`;`&&d++;var m=e.substring(l,d).trim();n+=` `+m+`;`}}l=d+1,u=-1}}}}return r&&(n+=Gr(r)),i&&(n+=Gr(i,!0)),n=n.trim(),n===``?null:n}return e==null?null:String(e)}function Jr(e,t,n,r,i,a){var o=e[oe];if(O||o!==n||o===void 0){var s=Wr(n,r,a);(!O||s!==e.getAttribute(`class`))&&(s==null?e.removeAttribute(`class`):t?e.className=s:e.setAttribute(`class`,s)),e[oe]=n}else if(a&&i!==a)for(var c in a){var l=!!a[c];(i==null||l!==!!i[c])&&e.classList.toggle(c,l)}return a}function Yr(e,t={},n,r){for(var i in n){var a=n[i];t[i]!==a&&(n[i]==null?e.style.removeProperty(i):e.style.setProperty(i,a,r))}}function Xr(e,t,n,r){var i=e[se];if(O||i!==t){var a=qr(t,r);(!O||a!==e.getAttribute(`style`))&&(a==null?e.removeAttribute(`style`):e.style.cssText=a),e[se]=t}else r&&(Array.isArray(r)?(Yr(e,n?.[0],r[0]),Yr(e,n?.[1],r[1],`important`)):Yr(e,n,r));return r}function Zr(e,t){t?e.hasAttribute(`selected`)||e.setAttribute(`selected`,``):e.removeAttribute(`selected`)}function Qr(t,n){var r=t.__defaultValue,i=t.multiple,a=i?r??[]:null;if(!i||e(a)){var o=t.selectedIndex,s=n&&i?new Set(t.selectedOptions):null;for(var c of t.options){var l=ti(c);Zr(c,i?a.includes(l):Wt(l,r))}if(n){if(s!==null)for(c of t.options){var u=s.has(c);c.selected!==u&&(c.selected=u)}else t.selectedIndex!==o&&(t.selectedIndex=o)}}}function $r(t,n,r=!1){if(t.multiple){if(n==null)return;if(!e(n))return he();for(var i of t.options)i.selected=n.includes(ti(i))}else{for(i of t.options)if(Wt(ti(i),n)){i.selected=!0;return}(!r||n!==void 0)&&(t.selectedIndex=-1)}}function ei(e){var t=new MutationObserver(t=>{t.every(ni)||(`__defaultValue`in e&&Qr(e,!1),`__value`in e&&$r(e,e.__value))});t.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`value`]}),dn(()=>{t.disconnect()})}function ti(e){return`__value`in e?e.__value:e.value}function ni(e){if(e.target.closest(`selectedcontent`)!==null)return!0;if(e.type===`childList`){var t=[...e.addedNodes,...e.removedNodes];return t.length>0&&t.every(e=>e.nodeName===`SELECTEDCONTENT`)}return!1}var ri=Symbol(`is custom element`),ii=Symbol(`is html`),ai=ue?`link`:`LINK`;function oi(e){if(O){var t=!1,n=()=>{if(!t){if(t=!0,e.hasAttribute(`value`)){var n=e.value;Z(e,`value`,null),e.value=n}if(e.hasAttribute(`checked`)){var r=e.checked;Z(e,`checked`,null),e.checked=r}}};e[le]=n,Ue(n),Ze()}}function si(e,t){var n=ci(e);n.checked!==(n.checked=t??void 0)&&(e.checked=t)}function Z(e,t,n,r){var i=ci(e);O&&(i[t]=e.getAttribute(t),t===`src`||t===`srcset`||t===`href`&&e.nodeName===ai)||i[t]!==(i[t]=n)&&(t===`loading`&&(e[ie]=n),n==null?e.removeAttribute(t):typeof n!=`string`&&ui(e).has(t)?e[t]=n:e.setAttribute(t,n))}function ci(e){return e[ae]??={[ri]:e.nodeName.includes(`-`),[ii]:e.namespaceURI===fe}}var li=new Map;function ui(e){var t=e.getAttribute(`is`)||e.nodeName,n=li.get(t);if(n)return n;li.set(t,n=new Set);for(var r,i=e,a=Element.prototype;a!==i;){for(var s in r=o(i),r)r[s].set&&s!==`innerHTML`&&s!==`textContent`&&s!==`innerText`&&n.add(s);i=l(i)}return n}function di(e,t,n=t){var r=new WeakSet;$e(e,`input`,async i=>{var a=i?e.defaultValue:e.value;if(a=fi(e)?pi(a):a,n(a),F!==null&&r.add(F),await tr(),a!==(a=t())){var o=e.selectionStart,s=e.selectionEnd,c=e.value.length;if(e.value=a??``,s!==null){var l=e.value.length;o===s&&s===c&&l>c?(e.selectionStart=l,e.selectionEnd=l):(e.selectionStart=o,e.selectionEnd=Math.min(s,l))}}}),(O&&e.defaultValue!==e.value||ir(t)==null&&e.value)&&(n(fi(e)?pi(e.value):e.value),F!==null&&r.add(F)),_n(()=>{var n=t();if(e===document.activeElement){var i=F;if(r.has(i))return}fi(e)&&n===pi(e.value)||(e.type!==`date`||n||e.value)&&n!==e.value&&(e.value=n??``)})}function fi(e){var t=e.type;return t===`number`||t===`range`}function pi(e){return e===``?null:+e}function mi(e,t){return e===t||e?.[ne]===t}function hi(e=ze(),t,n,r){var i=M.r,a=U;return hn(()=>{var o,s;return _n(()=>{o=s,s=r?.()||[],ir(()=>{mi(n(...s),e)||(t(e,...s),o&&mi(n(...o),e)&&t(null,...o))})}),()=>{let r=a;for(;r!==i&&r.parent!==null&&r.parent.f&33554432;)r=r.parent;let o=()=>{s&&mi(n(...s),e)&&t(null,...s)},c=r.teardown;r.teardown=()=>{o(),c?.()}}}),e}function gi(e){M===null&&Te(`onMount`),fn(()=>{let t=ir(e);if(typeof t==`function`)return t})}typeof window<`u`&&((window.__svelte??={}).v??=new Set).add(`5`);var _i=xr(`<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m3.4 8.4 3 3 6.2-6.8"></path></svg>`),vi=xr(`<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M8 4v5"></path><path d="M8 12h.01"></path></svg>`),yi=xr(`<svg viewBox="0 0 16 16" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M4 4l8 8M12 4l-8 8"></path></svg>`),bi=K(`<span class="fix svelte-1grjtup"> </span>`),xi=K(`<li class="svelte-1grjtup"><span class="mark svelte-1grjtup" aria-hidden="true"><!></span> <span class="body svelte-1grjtup"><b class="svelte-1grjtup"> </b> <span class="msg svelte-1grjtup"> </span> <!></span> <span class="sr svelte-1grjtup"> </span></li>`),Si=K(`<section class="health svelte-1grjtup" aria-label="Health"><header class="svelte-1grjtup"><h2 class="svelte-1grjtup"> </h2> <p class="svelte-1grjtup">This is the same check <code>npx verbaly doctor</code> runs, read out loud. It looks at your
|
|
3
|
+
settings, your catalogs and the way your build is wired, and it never changes anything.</p> <button class="close svelte-1grjtup">Back to the messages</button></header> <ul class="svelte-1grjtup"></ul></section>`);function Ci(e,t){Le(t,!0);let n={config:`Your settings`,cli:`The verbaly command`,catalogs:`Your catalogs`,locales:`The names of your languages`,routing:`Where the language lives in your urls`,plugin:`The piece that wires your build`,types:`The generated types`,sources:`Reading your code`,orphans:`Keys nothing in your code uses`,extras:`Keys only a translation has`,bundle:`What the browser downloads`,translations:`The translations themselves`},r=P(()=>t.entries.filter(e=>e.level!==`ok`).length);var i=Si(),a=R(i),o=R(a),s=z(o,!0),c=B(o,4);j(a);var l=B(a,2);X(l,21,()=>t.entries,Nr,(e,t)=>{var r=xi(),i=R(r),a=R(i),o=e=>{q(e,_i())},s=e=>{q(e,vi())},c=e=>{q(e,yi())};Y(a,e=>{W(t).level===`ok`?e(o):W(t).level===`warn`?e(s,1):e(c,-1)}),j(i);var l=B(i,2),u=R(l),d=z(u,!0),f=B(u,2),p=z(f,!0),m=B(f,2),h=e=>{var n=bi(),r=z(n,!0);V(()=>J(r,W(t).fix)),q(e,n)};Y(m,e=>{W(t).fix&&e(h)}),j(l);var g=z(B(l,2),!0);j(r),V(()=>{Z(r,`data-level`,W(t).level),J(d,n[W(t).check]??W(t).check),J(p,W(t).message),J(g,W(t).level)}),q(e,r)}),j(l),j(i),V(()=>J(s,t.ok?`Nothing is broken`:`${W(r)} of ${t.entries.length} need you`)),G(`click`,c,function(...e){t.onClose?.apply(this,e)}),q(e,i),Re()}fr([`click`]);var wi=new Set;function Ti(e){wi.has(e)||(wi.add(e),console.warn(`[verbaly] ${e}`))}var Ei=200,Di=new Map;function Oi(e,t,n,r){let i=e.get(t);if(!i){e.size>=Ei&&e.delete(e.keys().next().value);try{i=r(n)}catch{let e=n.replace(/_/g,`-`);try{i=r(e)}catch{i=r(e=void 0)}Ti(`"${n}" is not a locale tag, so Intl reads it as ${e??`its default locale`}`)}e.set(t,i)}return i}function ki(e){return Oi(Di,e,e,e=>new Intl.DisplayNames(e,{type:`language`}))}function Ai(e,t=e){try{return ki(t).of(e)??e}catch{return e}}var ji=/(^|[^{])\{\s*[a-zA-Z0-9_]+\s*,\s*(?:plural|selectordinal|select|number|date|time)\b/;function Mi(e){return ji.test(e)}function Ni(e){let t=0,n=()=>e.charAt(t),r=()=>{for(;t<e.length&&/\s/.test(n());)t++},i=()=>{let r=``;for(;t<e.length&&/[a-zA-Z0-9_]/.test(n());)r+=e[t++];return r};function a(r){let i=[],a=``,c=()=>{a&&i.push({kind:`text`,value:a}),a=``};for(;t<e.length;){let e=n();if(e===`}`)break;e===`{`?(c(),i.push(s())):e===`#`&&r?(c(),i.push({kind:`hash`}),t++):e===`'`?a+=o():(a+=e,t++)}return c(),i}function o(){if(t++,n()===`'`)return t++,`'`;let r=n();if(r!==`{`&&r!==`}`&&r!==`#`)return`'`;let i=``;for(;t<e.length;){if(n()===`'`){if(e.charAt(t+1)===`'`){i+=`'`,t+=2;continue}return t++,i}i+=e[t++]}return i}function s(){t++,r();let o=i();if(r(),n()===`}`)return t++,{kind:`param`,name:o};n()===`,`&&t++,r();let s=i(),u={kind:`param`,name:o};if(s===`number`||s===`date`||s===`time`){r();let i=``;if(n()===`,`){for(t++,r();t<e.length&&n()!==`}`&&n()!==`,`;)i+=e[t++];i=i.trim()}return s===`number`?u.format=i===`integer`||i===`percent`||i===`currency`?i:`number`:(u.format=s,i&&(u.arg=i)),l(),u}if(s===`plural`||s===`selectordinal`||s===`select`){s===`selectordinal`&&(u.ordinal=!0);let i=[];if(r(),n()===`,`&&t++,r(),s!==`select`&&e.startsWith(`offset:`,t)){for(t+=7,r();t<e.length&&/[0-9]/.test(n());)t++;r()}for(;t<e.length&&n()!==`}`;){let e=c();if(r(),n()!==`{`)break;t++;let o=a(s!==`select`);n()===`}`&&t++,i.push([e,o]),r()}return n()===`}`&&t++,u.variants=i,u}return l(),u}function c(){if(n()===`=`){let r=`=`;for(t++;t<e.length&&/[0-9]/.test(n());)r+=e[t++];return r}let r=``;for(;t<e.length&&!/[\s{]/.test(n());)r+=e[t++];return r}function l(){for(;t<e.length&&n()!==`}`;)t++;n()===`}`&&t++}return a(!1)}var Pi=new Map,Fi=5e3;function Ii(e,t){let n=Pi.get(e);if(!n){if(Mi(e)){if(!t)return Li(e);n=t(e)}else n=Ri(e,!1);Pi.size>=Fi&&Pi.delete(Pi.keys().next().value),Pi.set(e,n)}return n}function Li(e){return Ti(`a message uses ICU syntax and no ICU parser is loaded: set icu: true in your verbaly config, or pass icu to createVerbaly`),[{kind:`text`,value:e}]}function Ri(e,t){let n=[],r=``,i=0,a=()=>{r&&n.push({kind:`text`,value:r}),r=``};for(;i<e.length;){let o=e[i];if(o===`{`){if(e[i+1]===`{`){r+=`{`,i+=2;continue}let t=Bi(e,i);if(t<0){r+=e.slice(i);break}a(),n.push(Vi(e.slice(i+1,t))),i=t+1}else o===`}`&&e[i+1]===`}`?(r+=`}`,i+=2):t&&o===`#`?e[i+1]===`#`?(r+=`#`,i+=2):(a(),n.push({kind:`hash`}),i+=1):(r+=o,i+=1)}return a(),n}var zi;function Bi(e,t,n){zi=n;let r=0,i=t;for(;i<e.length;){let t=e[i];if(t===`{`){if(e[i+1]===`{`){i+=2;continue}r+=1}else if(t===`}`){if(e[i+1]===`}`&&!(n&&r>1)){i+=2;continue}if(--r,r===0)return i}i+=1}return n?-1:Bi(e,t,!0)}function Vi(e){let t=Hi(e),n=(t[0]??``).trim();if(!n)return{kind:`text`,value:`{${e}}`};let r=n.indexOf(`:`),i=(r<0?n:n.slice(0,r)).trim();if(!i)return{kind:`text`,value:`{${e}}`};let a={kind:`param`,name:i};if(r>=0){let e=n.slice(r+1).trim(),t=e.indexOf(`/`);a.format=(t<0?e:e.slice(0,t)).trim(),t>=0&&(a.arg=e.slice(t+1).trim())}if(t.length>1){a.variants=[];for(let e of t.slice(1)){let t=e.indexOf(`:`);if(t<0)continue;let n=e.slice(0,t).trim(),r=e.slice(t+1).trim();n&&a.variants.push([n,Ri(r,!0)])}}return a}function Hi(e){let t=[],n=``,r=0,i=0;for(;i<e.length;){let a=e[i];if(a===`{`){if(e[i+1]===`{`){n+=`{{`,i+=2;continue}r+=1,n+=a}else if(a===`}`){if(e[i+1]===`}`&&!(zi&&r>0)){n+=`}}`,i+=2;continue}--r,n+=a}else if(a===`|`&&r===0){if(e[i+1]===`|`){n+=`|`,i+=2;continue}t.push(n),n=``}else n+=a;i+=1}return t.push(n),t}var Ui=/<(\/?)([a-zA-Z][\w-]*)\s*(\/?)>/g,Wi=/^(?:br|wbr)$/,Gi=/&(?:(lt|gt|amp)|#(\d+)|#[xX]([0-9a-fA-F]+));/g,Ki={lt:`<`,gt:`>`,amp:`&`},qi=e=>e.replace(Gi,(e,t,n,r)=>{if(t)return Ki[t];let i=n?parseInt(n,10):parseInt(r,16);return i<=1114111?String.fromCodePoint(i):e});function Ji(e){Ui.lastIndex=0;let t=[],n=[],r=()=>n.length?n[n.length-1].children:t,i=e=>{e&&r().push(qi(e))},a=0,o;for(;(o=Ui.exec(e))!==null;){let[t,s,c,l]=o;if(i(e.slice(a,o.index)),a=o.index+t.length,l||Wi.test(c))s||r().push({name:c,children:[]});else if(s){if(n.length&&n[n.length-1].name===c){let e=n.pop();r().push(e)}else i(t)}else n.push({name:c,children:[]})}for(i(e.slice(a));n.length;){let e=n.pop();r().push(...e.children)}return t}var Yi={done:{short:`ready`,long:`ready`},draft:{short:`unread`,long:`written by a machine, nobody has read it`},missing:{short:`missing`,long:`missing, so your visitor sees the source language`},broken:{short:`breaks`,long:`breaks your site`}},Xi={all:`everything`,missing:`missing`,draft:`unread`,broken:`breaks your site`,look:`worth a look`,clean:`nothing odd`},Zi={divergent:`the source says this two ways`,collision:`came back as two translations`,echo:`still identical to the source`,digits:`the numbers moved`,url:`a link changed`,code:`a code span changed`},Q={open:`More for this message`,close:`Close`,edit:`Edit here`,copyKey:`Copy the key`,copySource:`Copy the source text`,commit:`The commit that changed it`,origins:`Where it is used`,reading:`reading your history`,nogit:`no git here`,uncommitted:`not committed yet`,older:`not in recent commits`,scanOff:`include: [] is off`,noFiles:`no file in your code uses it`,more:e=>`and ${e} more`,copiedKey:`The key is on your clipboard.`,copiedSource:`The source text is on your clipboard.`,copiedSha:`The commit is on your clipboard.`,noClipboard:`Your browser would not let the panel write to the clipboard.`,nothingToEdit:`Tick a language in the rail and this message has a line to edit.`},Qi={cap:`Group`,all:`every group`,none:`Your keys have no groups yet.`,hint:`A key like nav.home belongs to nav.`},$i=`Undo`,ea={find:`Find new text`,findWhy:`Reads your code and adds what your catalogs do not have yet.`,translate:`Translate what is missing`,translateWhy:`Calls your provider, so it costs money and takes minutes.`,cancel:`Not now`,working:`Reading your code`,running:`Translating`,nothingNew:`Nothing new: your catalogs already have every message your code uses.`,nothingMissing:`Nothing missing in the languages you ticked.`,pickFirst:`Tick a language to translate it.`,onlyLocale:`This project has one language, so there is nothing to translate into.`,scanOff:`Source scanning is off in your config, so there is nothing to read.`,kept:e=>`${e===1?`One was`:`${e} were`} written by someone else while it ran, so ${e===1?`it keeps its text`:`they keep their text`}.`},ta={noCatalogs:`No messages yet. Studio reads the catalogs in your project, and there are none here.`,oneLocale:`One language is all you have, so there is nothing to compare it against yet.`,oneLocaleFix:`Add another one to your config and it shows up in the rail.`,pickOne:`Tick a language in the rail to see its translations.`,noMatch:`Nothing matches. Every message here is in the state you asked for.`};function na(e){return`${e} ${e===1?`message`:`messages`}`}var ra={broken:{one:`translation breaks your site`,many:`translations break your site`},missing:{one:`message is missing`,many:`messages are missing`},draft:{one:`translation nobody has read`,many:`translations nobody has read`},undefined:{one:`key your code calls has no message`,many:`keys your code calls have no message`},extra:{one:`key only a translation has`,many:`keys only a translation has`}},ia={broken:`It lost a parameter or a tag, so the sentence would ship incomplete.`,missing:`Your visitor sees the source language until one is written.`,draft:`A machine wrote it and nobody has looked. It is already on your site.`,undefined:`Nothing defines it, so the build fails and the raw key would reach your page.`,extra:`Your source catalog lacks it, so it is dead weight, or a raw key if your code reads it.`},aa={here:`Overview`,clear:`Nothing is waiting for you.`,clearWhy:`Every language is complete and the build passes.`,project:`Project`,healthy:`Healthy`,problems:`Needs a look`,checks:`checks`,history:`Last changes to your catalogs`,noHistory:`No git history for your catalog directory.`,countMessages:`Messages`,countLocales:`Languages`,open:`Open`},oa={label:`Search your messages`,scope:`Searches your text in every language, never the key.`,none:`Nothing has that text, in any language.`,oneHit:`1 message`,hits:e=>`${e} messages`,moveKeys:`move`,openKeys:`open`,closeKeys:`close`,close:`Close`,placeholder:`Search the text, not the key`},$={mark:`Look`,live:`They are already on your site.`,written:e=>`A machine wrote ${e===1?`one of them`:`${e} of them`} and nobody has read ${e===1?`it`:`them`} yet.`,sound:`Nothing is broken: the check your build runs passes on this language.`,broken:e=>`${e} ${e===1?`breaks`:`break`} your site, so ${e===1?`it is`:`they are`} first.`,flagged:e=>`${e} ${e===1?`is`:`are`} worth reading before the rest, so ${e===1?`it is`:`they are`} at the top.`,clean:`Nothing in them looks off to me.`,approve:e=>`Mark all of ${e} as read`,approveSub:e=>`${e} unread, and it undoes`,nothingUnread:`Every one of them has been read.`,chipAll:`Everything`,chipLook:`Look`,chipClean:`Nothing odd`,rest:e=>`${e} more with nothing odd. They are below and you do not need to read them.`,order:`Sorted by what is worth reading first`},sa=K(`<span> </span>`),ca=K(`<li><button><span> </span> <!></button></li>`),la=K(`<button class="read svelte-l3e5c7"> <span class="n svelte-l3e5c7"> </span></button>`),ua=K(`<li><label><input type="checkbox" class="svelte-l3e5c7"/> <span class="meta svelte-l3e5c7"><span class="name svelte-l3e5c7"> <code class="svelte-l3e5c7"> </code></span> <span class="state svelte-l3e5c7"><b class="svelte-l3e5c7"> </b><!></span></span></label> <!></li>`),da=K(`<p class="undo svelte-l3e5c7"><span> </span> <button class="svelte-l3e5c7"> </button></p>`),fa=K(`<option> </option>`),pa=K(`<h2 class="cap svelte-l3e5c7"> </h2> <select class="groups svelte-l3e5c7"><option> </option><!></select>`,1),ma=K(`<li><button type="button"><span> </span> <span class="count svelte-l3e5c7"> </span></button></li>`),ha=K(`<nav class="rail svelte-l3e5c7" aria-label="Languages and filters"><ul class="views svelte-l3e5c7"></ul> <!> <h2 class="cap svelte-l3e5c7">Languages</h2> <ul class="langs svelte-l3e5c7"></ul> <!> <!> <h2 class="cap svelte-l3e5c7">Show</h2> <ul class="filters svelte-l3e5c7"></ul></nav>`);function ga(e,t){Le(t,!0);let n=[{id:`overview`,label:`Overview`},{id:`messages`,label:`Messages`},{id:`health`,label:`Health`}],r=[`all`,`look`,`clean`,`missing`,`draft`,`broken`];function i(e){if(e.source)return[`the one you write`];let t=[];return e.broken&&t.push(`${e.broken} ${e.broken===1?`breaks`:`break`} your site`),e.missing&&t.push(`${e.missing} missing`),e.draft&&t.push(`${e.draft} nobody has read`),t.length?t:[`all read`]}function a(e){let t=i(e);return{lead:t[0],rest:t.slice(1).join(` · `)}}function o(e){return e.source?`done`:e.broken?`broken`:e.missing?`missing`:e.draft?`draft`:`done`}var s=ha(),c=R(s);X(c,21,()=>n,e=>e.id,(e,n)=>{var r=ca(),i=R(r);let a;var o=R(i),s=z(o,!0),c=B(o,2),l=e=>{var n=sa();let r;var i=z(n,!0);V(()=>{r=Jr(n,1,`bad svelte-l3e5c7`,null,r,{clean:!t.checks.bad}),J(i,t.checks.bad||`ok`)}),q(e,n)};Y(c,e=>{W(n).id===`health`&&t.checks&&e(l)}),j(i),j(r),V(()=>{a=Jr(i,1,`nav svelte-l3e5c7`,null,a,{on:t.view===W(n).id}),Z(i,`aria-current`,t.view===W(n).id?`page`:void 0),J(s,W(n).label)}),G(`click`,i,()=>t.onView(W(n).id)),q(e,r)}),j(c);var l=B(c,2);Hr(l,()=>t.actions);var u=B(l,4);X(u,21,()=>t.health,e=>e.locale,(e,n,r,i)=>{let s=P(()=>a(W(n)));var c=ua(),l=R(c);let u;var d=R(l);oi(d);var f=B(d,2),p=R(f),m=R(p),h=z(B(m),!0);j(p);var g=B(p,2),_=R(g),v=z(_,!0),y=B(_),b=e=>{var t=Sr();V(()=>J(t,` · ${W(s).rest??``}`)),q(e,t)};Y(y,e=>{W(s).rest&&e(b)}),j(g),j(f),j(l);var x=B(l,2),S=e=>{var r=la(),i=R(r),a=z(B(i),!0);j(r),V(()=>{J(i,`Mark as read `),J(a,W(n).draft)}),G(`click`,r,()=>t.onRead(W(n).locale)),q(e,r)};Y(x,e=>{!W(n).source&&W(n).draft>0&&e(S)}),j(c),V((e,t,r)=>{u=Jr(l,1,`lang svelte-l3e5c7`,null,u,{source:W(n).source}),si(d,e),d.disabled=W(n).source,J(m,`${t??``} `),J(h,W(n).locale),Z(g,`data-state`,r),J(v,W(s).lead)},[()=>t.shown.includes(W(n).locale),()=>Ai(W(n).locale),()=>o(W(n))]),G(`change`,d,()=>t.onToggle(W(n).locale)),q(e,c)}),j(u);var d=B(u,2),f=e=>{var n=da(),r=R(n),i=z(r),a=B(r,2),o=z(a,!0);j(n),V(()=>{J(i,`${t.pending.keys.length??``} in ${t.pending.locale??``} marked as read`),J(o,$i)}),G(`click`,a,function(...e){t.onUndo?.apply(this,e)}),q(e,n)};Y(d,e=>{t.pending&&e(f)});var p=B(d,2),m=e=>{var n=pa(),r=$t(n),i=z(r,!0),a=B(r,2),o=R(a),s=z(o,!0);o.value=o.__value=``,X(B(o),17,()=>t.groups,e=>e.name,(e,t)=>{var n=fa(),r=z(n),i={};V(()=>{J(r,`${W(t).name??``} (${W(t).total??``})${W(t).broken+W(t).missing+W(t).draft>0?` · ${W(t).broken+W(t).missing+W(t).draft} to do`:``}`),i!==(i=W(t).name)&&(n.value=(n.__value=i)??``)}),q(e,n)}),j(a);var c;ei(a),V(()=>{J(i,Qi.cap),Z(a,`aria-label`,Qi.cap),J(s,Qi.all),c!==(c=t.group??``)&&(a.value=(a.__value=c)??``,$r(a,c))}),G(`change`,a,e=>t.onGroup(e.currentTarget.value||null)),q(e,n)};Y(p,e=>{t.groups.length&&e(m)});var h=B(p,4);X(h,20,()=>r,e=>e,(e,n)=>{var r=ma(),i=R(r);let a;var o=R(i),s=z(o,!0),c=z(B(o,2),!0);j(i),j(r),V(()=>{a=Jr(i,1,`svelte-l3e5c7`,null,a,{on:t.state===n}),J(s,Xi[n]),J(c,t.counts[n]??0)}),G(`click`,i,()=>t.onState(n)),q(e,r)}),j(h),j(s),q(e,s),Re()}fr([`click`,`change`]);var _a=xr(`<svg viewBox="0 0 22 22" width="15" height="15" aria-hidden="true"><path d="M5 11h12" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path></svg>`),va=xr(`<svg viewBox="0 0 22 22" width="15" height="15" aria-hidden="true" fill="none"><path d="M6 12.5 11 7l5 5.5" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"></path><path d="M11 8v7" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"></path></svg>`),ya=xr(`<svg viewBox="0 0 22 22" width="15" height="15" aria-hidden="true" fill="none"><path d="M4.5 12.5c1.6-2.2 3.2-2.2 4.8 0s3.2 2.2 4.8 0 3.2-2.2 4.8 0" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"></path></svg>`),ba=xr(`<svg viewBox="0 0 22 22" width="15" height="15" aria-hidden="true"><path d="M11 6v6.4" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path><circle cx="11" cy="16" r="1.2" fill="currentColor"></circle></svg>`),xa=K(`<!> <span class="sr svelte-1fu82r1"> </span>`,1);function Sa(e,t){let n={done:`translated`,draft:`written by a machine`,missing:`not translated, shows in your source language`,broken:`breaks your site`};var r=xa(),i=$t(r),a=e=>{q(e,_a())},o=e=>{q(e,va())},s=e=>{q(e,ya())},c=e=>{q(e,ba())};Y(i,e=>{t.state===`done`?e(a):t.state===`missing`?e(o,1):t.state===`draft`?e(s,2):e(c,-1)});var l=z(B(i,2),!0);V(()=>J(l,n[t.state])),q(e,r)}function Ca(e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0}function wa(e,t=``,n=Object.create(null)){for(let[r,i]of Object.entries(e)){let e=t?`${t}.${r}`:r;typeof i==`string`?n[e]=i:i&&typeof i==`object`&&!Array.isArray(i)&&wa(i,e,n)}return n}function Ta(e){let t={};for(let n of e.locales)t[n]=wa(e.catalogs[n]??{});let n=new Map;for(let t of e.check.broken)t.severity===`error`&&n.set(`${t.locale}\u0000${t.key}`,t.issue);let r=new Map;for(let[t,n]of Object.entries(e.drafts))r.set(t,new Set(n));let i=t[e.sourceLocale]??{},a=e.locales.filter(t=>t!==e.sourceLocale),o=Object.keys(i).map(o=>({key:o,source:i[o]??``,origins:Ca(e.origins,o)??[],cells:a.map(i=>{let a=Ca(t[i],o)??``,s=n.get(`${i}\u0000${o}`);return{locale:i,text:a,state:s?`broken`:a?r.get(i)?.has(o)?`draft`:`done`:`missing`,issue:s,reasons:Ca(e.triage?.[i],o)??[]}})}));return{root:e.root,scanning:e.scanning,sourceLocale:e.sourceLocale,locales:e.locales,rows:o,undefined:e.check.unknown??[],extra:e.check.extra??[],problems:e.problems}}function Ea(e){return e.locales.map(t=>{let n=e.rows.length;if(t===e.sourceLocale)return{locale:t,source:!0,total:n,done:n,draft:0,missing:0,broken:0};let r={done:0,draft:0,missing:0,broken:0};for(let n of e.rows){let e=n.cells.find(e=>e.locale===t);e&&r[e.state]++}return{locale:t,source:!1,total:n,...r}})}function Da(e,t){Object.assign(e,Ta(t))}function Oa(e,t,n){return e.rows.length?e.locales.length<2?`oneLocale`:t.length?n.length?null:`noMatch`:`pickOne`:`noCatalogs`}function ka(e,t){return e?t.length?null:`noFiles`:`scanOff`}function Aa(e){let t=e.indexOf(`.`);return t>0?e.slice(0,t):null}function ja(e,t){let n=new Set(t),r=new Map;for(let t of e){let e=Aa(t.key);if(e===null)continue;let i=r.get(e)??{name:e,total:0,broken:0,missing:0,draft:0};i.total+=1;for(let e of t.cells)n.has(e.locale)&&e.state!==`done`&&(i[e.state]+=1);r.set(e,i)}return[...r.values()].sort((e,t)=>e.name<t.name?-1:1)}function Ma(e,t){let n=t.text.trim().toLowerCase(),r=new Set(t.locales);return e.filter(e=>{let i=e.cells.filter(e=>r.has(e.locale));return t.state===`look`&&!i.some(e=>e.reasons.length)||t.state===`clean`&&i.some(e=>e.reasons.length)||t.state!==`all`&&t.state!==`look`&&t.state!==`clean`&&!i.some(e=>e.state===t.state)||t.group&&Aa(e.key)!==t.group?!1:!n||e.source.toLowerCase().includes(n)?!0:i.some(e=>e.text.toLowerCase().includes(n))})}var Na=[`broken`,`missing`,`draft`,`done`];function Pa(e){for(let t of Na)if(e.cells.some(e=>e.state===t))return t;return`done`}function Fa(e,t,n=40){let r=t.trim().toLowerCase();if(!r)return[];let i=[];for(let t of e.rows){let a=[];t.source.toLowerCase().includes(r)&&a.push(e.sourceLocale);for(let e of t.cells)e.text.toLowerCase().includes(r)&&a.push(e.locale);if(!a.length)continue;let o=a[0],s=o===e.sourceLocale?t.source:t.cells.find(e=>e.locale===o)?.text??``;if(i.push({key:t.key,group:Aa(t.key),source:t.source,locales:a,text:s,state:Pa(t)}),i.length===n)break}return i}function Ia(e,t){let n=t.trim(),r=e.toLowerCase().indexOf(n.toLowerCase());return r<0?[e,``,``]:[e.slice(0,r),e.slice(r,r+n.length),e.slice(r+n.length)]}function La(e,t){let n=[],r=[];for(let i of e)(i.cells.find(e=>e.locale===t)?.reasons.length?n:r).push(i);return{rows:[...n,...r],flagged:n.length}}function Ra(e,t){let n=e.cells.find(e=>e.locale===t);return n?.reasons.length?n.reasons.map(e=>e.text).join(`. `):null}var za=K(`<li> </li>`),Ba=K(`<ul class="files svelte-1dg5efm"></ul>`),Va=K(`<div class="menu svelte-1dg5efm" role="menu" tabindex="-1"><button class="mi svelte-1dg5efm" role="menuitem"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="svelte-1dg5efm"><path d="m9 7-5 5 5 5"></path><path d="m15 7 5 5-5 5"></path></svg> <i class="svelte-1dg5efm"> </i></button> <button class="mi svelte-1dg5efm" role="menuitem"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="svelte-1dg5efm"><path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8Z"></path><path d="M14 3v5h5"></path></svg> <i class="svelte-1dg5efm"> </i></button> <button class="mi svelte-1dg5efm" role="menuitem"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="svelte-1dg5efm"><path d="M20 15a2 2 0 0 1-2 2H8l-4 3V6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2Z"></path></svg> </button> <div class="msep svelte-1dg5efm"></div> <button class="mi svelte-1dg5efm" role="menuitem"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="svelte-1dg5efm"><circle cx="12" cy="12" r="8"></circle><path d="M12 7.5V12l3 1.8"></path></svg> <i class="svelte-1dg5efm"> </i></button> <button class="mi svelte-1dg5efm" role="menuitem"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="svelte-1dg5efm"><path d="M14 5h5v5"></path><path d="m19 5-8 8"></path><path d="M18 14v4a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h4"></path></svg> <i class="svelte-1dg5efm"> </i></button> <!></div>`);function Ha(e,t){Le(t,!0);let n=I(void 0),r=I(Ht({top:-9999,left:-9999})),i=I(null),a=I(!1),o=P(()=>ka(t.scanning,t.row.origins)),s=P(()=>W(i)===null?Q.reading:W(i).commit?W(i).commit.sha:Q[W(i).reason??`nogit`]);function c(){let e=t.anchor.getBoundingClientRect(),i=W(n)?.offsetHeight??0,a=e.bottom+6,o=a+i>window.innerHeight?Math.max(8,e.top-i-6):a,s=Math.min(Math.max(8,e.right-308),window.innerWidth-308-8);L(r,{top:o,left:s},!0)}function l(e){let t=document.createElement(`textarea`);t.value=e,t.setAttribute(`readonly`,``),t.style.cssText=`position:fixed;top:-1000px;opacity:0`,document.body.append(t),t.select();let n=!1;try{n=document.execCommand(`copy`)}catch{n=!1}return t.remove(),n}async function u(e,n){let r=!1;try{await navigator.clipboard.writeText(e),r=!0}catch{r=l(e)}t.onNote(r?n:Q.noClipboard),t.onClose(),t.anchor.focus()}function d(){return[...W(n)?.querySelectorAll(`[role="menuitem"]`)??[]]}function f(e){if(e.key===`Escape`||e.key===`Tab`){t.onClose(),t.anchor.focus();return}let n=e.key===`ArrowDown`?1:e.key===`ArrowUp`?-1:0;if(!n)return;e.preventDefault();let r=d();r[(r.indexOf(document.activeElement)+n+r.length)%r.length]?.focus()}async function p(){L(a,!W(a)),await tr(),c()}gi(()=>{let e=!0;c(),d()[0]?.focus(),t.onCommit(t.row.key).then(n=>{e&&L(i,n??{key:t.row.key,commit:null,reason:`nogit`},!0)});let n=()=>t.onClose();return window.addEventListener(`scroll`,n,!0),window.addEventListener(`resize`,n),()=>{e=!1,window.removeEventListener(`scroll`,n,!0),window.removeEventListener(`resize`,n)}});function m(e){let r=e.target;!W(n)?.contains(r)&&!t.anchor.contains(r)&&t.onClose()}var h=Va();dr(`pointerdown`,Gt,m);var g=R(h),_=B(R(g)),v=z(B(_),!0);j(g);var y=B(g,2),b=B(R(y)),x=z(B(b),!0);j(y);var S=B(y,2),ee=B(R(S));j(S);var C=B(S,4),w=B(R(C)),te=z(B(w),!0);j(C);var T=B(C,2),ne=B(R(T)),re=z(B(ne),!0);j(T);var ie=B(T,2),ae=e=>{var n=Ba();X(n,20,()=>t.row.origins,e=>e,(e,t)=>{var n=za(),r=z(n,!0);V(()=>J(r,t)),q(e,n)}),j(n),q(e,n)};Y(ie,e=>{W(a)&&W(o)===null&&e(ae)}),j(h),hi(h,e=>L(n,e),()=>W(n)),V(e=>{Z(h,`aria-label`,Q.open),Xr(h,`top:${W(r).top??``}px;left:${W(r).left??``}px`),Z(g,`aria-disabled`,t.locale===null),J(_,` ${Q.edit??``}`),J(v,t.locale??``),J(b,` ${Q.copyKey??``}`),J(x,t.row.key),J(ee,` ${Q.copySource??``}`),Z(C,`aria-disabled`,!W(i)?.commit),Z(C,`title`,e),J(w,` ${Q.commit??``}`),J(te,W(s)),Z(T,`aria-disabled`,W(o)!==null),Z(T,`aria-expanded`,W(o)===null?W(a):void 0),J(ne,` ${Q.origins??``}`),J(re,W(o)?Q[W(o)]:t.row.origins.length>1?`${t.row.origins[0]} +${t.row.origins.length-1}`:t.row.origins[0])},[()=>W(i)?.commit?`${W(i).commit.subject} · ${W(i).commit.author} · ${W(i).commit.date.slice(0,10)}`:void 0]),G(`keydown`,h,f),G(`click`,g,()=>t.locale===null?t.onNote(Q.nothingToEdit):t.onEdit()),G(`click`,y,()=>u(t.row.key,Q.copiedKey)),G(`click`,S,()=>u(t.row.source,Q.copiedSource)),G(`click`,C,()=>W(i)?.commit&&u(W(i).commit.sha,Q.copiedSha)),G(`click`,T,()=>W(o)===null&&p()),q(e,h),Re()}fr([`keydown`,`click`]);function Ua(e,t){for(let n of e)if(n.kind===`param`&&n.name){t.has(n.name)||t.set(n.name,new Set);for(let[e,r]of n.variants??[])t.get(n.name).add(e),Ua(r,t)}}function Wa(e){let t=new Map;try{Ua(Ii(e,Ni),t)}catch{}return t}function Ga(e,t){for(let n of e)typeof n!=`string`&&(t.push(n.name),Ga(n.children,t))}function Ka(e){let t=[];try{Ga(Ji(e),t)}catch{return t}return t}function qa(e){let t=new Map;for(let n of e)t.set(n,(t.get(n)??0)+1);return t}var Ja=e=>e.length===1?e[0]:`${e.slice(0,-1).join(`, `)} and ${e.at(-1)}`;function Ya(e,t){let n=Wa(e),r=Wa(t),i=[...new Set([...n.keys(),...r.keys()])].sort().map(e=>({name:e,inSource:n.has(e),inTarget:r.has(e)})),a=[],o=i.filter(e=>e.inSource&&!e.inTarget).map(e=>`{${e.name}}`),s=i.filter(e=>!e.inSource&&e.inTarget).map(e=>`{${e.name}}`);o.length&&a.push(`${Ja(o)} is missing, so its value never reaches the text`),s.length&&a.push(`${Ja(s)} is not in the source, so it renders as literal text`);for(let[e,t]of r)t.size&&!t.has(`other`)&&a.push(`the block for {${e}} has no "other" case, so some counts render empty`);let c=qa(Ka(e)),l=qa(Ka(t));for(let[e,t]of c)(l.get(e)??0)<t&&a.push(`<${e}> is missing from the translation`);for(let[e,t]of l)(c.get(e)??0)<t&&a.push(`<${e}> is not in the source message`);return{params:i,problems:a}}var Xa=K(`<span class="ojo svelte-2clsr"> </span>`),Za=K(`<span class="rmark svelte-2clsr"><!></span>`),Qa=K(`<span class="tile svelte-2clsr"><!></span>`),$a=K(`<span> </span>`),eo=K(`<span class="vmsg svelte-2clsr"> </span>`),to=K(`<span class="tl edit svelte-2clsr"><span class="disc svelte-2clsr"> </span> <textarea class="tf svelte-2clsr" rows="2"></textarea></span> <span class="editbar svelte-2clsr"><!> <!> <!> <button class="btn sm svelte-2clsr"> </button> <button class="btn sm quiet svelte-2clsr">Cancel</button> <span class="keys svelte-2clsr">Enter saves · Esc closes</span></span>`,1),no=K(`<button class="tv svelte-2clsr"> </button>`),ro=K(`<button class="tv none svelte-2clsr"> </button>`),io=K(`<span class="sig svelte-2clsr"> </span>`),ao=K(`<span class="tl svelte-2clsr"><span class="disc svelte-2clsr"> </span> <!> <!></span>`),oo=K(`<span class="why svelte-2clsr"> </span>`),so=K(`<article><!> <span class="row-t svelte-2clsr"><span class="src svelte-2clsr"> </span> <!></span> <!> <span><button class="ga svelte-2clsr" aria-haspopup="menu"><svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" aria-hidden="true"><circle cx="5.5" cy="12" r="1.4"></circle><circle cx="12" cy="12" r="1.4"></circle><circle cx="18.5" cy="12" r="1.4"></circle></svg></button></span></article> <!>`,1);function co(e,t){Le(t,!0);let n=I(void 0),r=P(()=>t.why!==void 0),i=P(()=>t.row.cells.filter(e=>t.shown.includes(e.locale))),a=P(()=>[`broken`,`missing`,`draft`,`done`].find(e=>W(i).some(t=>t.state===e))??`done`),o=I(``),s=I(!1),c=I(null),l=P(()=>Ya(t.row.source,W(o))),u=e=>`${e.locale} ${t.row.key}`;function d(e){L(o,e.text,!0),L(c,null),t.onEdit(u(e))}async function f(e){W(s)||(L(s,!0),L(c,await t.onSave(e.locale,t.row.key,W(o)),!0),L(s,!1),W(c)||t.onEdit(null))}function p(e,n){e.key===`Escape`&&t.onEdit(null),e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),f(n))}var m=so(),h=$t(m);let g;var _=R(h),v=e=>{var n=Za(),r=R(n),i=e=>{var t=Xa(),n=z(t,!0);V(()=>J(n,$.mark)),q(e,t)};Y(r,e=>{t.why&&e(i)}),j(n),q(e,n)},y=e=>{var t=Qa();Sa(R(t),{get state(){return W(a)}}),j(t),V(()=>Z(t,`data-state`,W(a))),q(e,t)};Y(_,e=>{W(r)?e(v):e(y,-1)});var b=B(_,2),x=R(b),S=z(x,!0);X(B(x,2),17,()=>W(i),e=>e.locale,(e,n)=>{var i=Cr(),a=$t(i),m=e=>{var r=to(),i=$t(r),a=R(i),u=z(a,!0),d=B(a,2);Ye(d),Je(d,!0),j(i);var m=B(i,2),h=R(m);X(h,17,()=>W(l).params,e=>e.name,(e,t)=>{var n=$a();let r;var i=z(n);V(()=>{r=Jr(n,1,`pm svelte-2clsr`,null,r,{gone:W(t).inSource&&!W(t).inTarget}),J(i,`${W(t).inSource&&!W(t).inTarget?`+`:``}{${W(t).name??``}}`)}),q(e,n)});var g=B(h,2);X(g,16,()=>W(l).problems,e=>e,(e,t)=>{var n=eo(),r=z(n,!0);V(()=>J(r,t)),q(e,n)});var _=B(g,2),v=e=>{var t=eo(),n=z(t,!0);V(()=>J(n,W(c))),q(e,t)};Y(_,e=>{W(c)&&!W(l).problems.length&&e(v)});var y=B(_,2),b=z(y,!0),x=B(y,2);ye(2),j(m),V(()=>{Z(a,`data-state`,W(n).state),J(u,W(n).locale),Z(d,`aria-label`,`Translation for ${W(n).locale??``}`),y.disabled=W(s),J(b,W(s)?`Saving`:`Save`)}),G(`keydown`,d,e=>p(e,W(n))),di(d,()=>W(o),e=>L(o,e)),G(`click`,y,()=>f(W(n))),G(`click`,x,()=>t.onEdit(null)),q(e,r)},h=P(()=>t.editing===u(W(n))),g=e=>{var t=ao(),i=R(t),a=z(i,!0),o=B(i,2),s=e=>{var t=no(),r=z(t,!0);V(()=>{Z(t,`title`,W(n).text),J(r,W(n).text)}),G(`click`,t,()=>d(W(n))),q(e,t)},c=e=>{var t=ro(),r=z(t,!0);V(()=>J(r,Yi.missing.long)),G(`click`,t,()=>d(W(n))),q(e,t)};Y(o,e=>{W(n).text?e(s):e(c,-1)});var l=B(o,2),u=e=>{var t=Cr();X($t(t),17,()=>W(n).reasons,e=>e.signal,(e,t)=>{var n=io(),r=z(n,!0);V(()=>{Z(n,`title`,W(t).text),J(r,Zi[W(t).signal]??W(t).signal)}),q(e,n)}),q(e,t)};Y(l,e=>{W(r)||e(u)}),j(t),V(()=>{Z(i,`data-state`,W(n).state),J(a,W(n).locale)}),q(e,t)};Y(a,e=>{W(h)?e(m):e(g,-1)}),q(e,i)}),j(b);var ee=B(b,2),C=e=>{var n=oo(),r=z(n,!0);V(()=>J(r,t.why??``)),q(e,n)};Y(ee,e=>{W(r)&&e(C)});var w=B(ee,2);let te;var T=R(w);hi(T,e=>L(n,e),()=>W(n)),j(w),j(h);var ne=B(h,2),re=e=>{{let r=P(()=>W(i)[0]?.locale??null);Ha(e,{get row(){return t.row},get locale(){return W(r)},get scanning(){return t.scanning},get anchor(){return W(n)},get onNote(){return t.onNote},get onCommit(){return t.onCommit},onEdit:()=>{t.onMenu(!1),W(i)[0]&&d(W(i)[0])},onClose:()=>t.onMenu(!1)})}};Y(ne,e=>{t.menu&&W(n)&&e(re)}),V(e=>{g=Jr(h,1,`row svelte-2clsr`,null,g,{open:e,flagged:W(r)&&!!t.why}),Z(h,`data-worst`,W(a)),Z(h,`data-key`,t.row.key),J(S,t.row.source),te=Jr(w,1,`row-go svelte-2clsr`,null,te,{held:t.menu}),Z(T,`aria-expanded`,t.menu),Z(T,`aria-label`,Q.open)},[()=>W(i).some(e=>t.editing===u(e))]),G(`click`,T,()=>t.onMenu(!t.menu)),q(e,m),Re()}fr([`keydown`,`click`]);var lo=K(`<button> <b class="svelte-1u5fzi5"> </b></button>`),uo=K(`<header class="langbar svelte-1u5fzi5"><div class="text svelte-1u5fzi5"><h2 class="svelte-1u5fzi5"> </h2> <p class="live svelte-1u5fzi5"><span class="disc svelte-1u5fzi5"> </span> <b class="svelte-1u5fzi5"> </b></p> <p class="why svelte-1u5fzi5"> </p></div> <div class="go svelte-1u5fzi5"><button class="btn svelte-1u5fzi5"> </button> <span class="sub svelte-1u5fzi5"> </span></div></header> <div class="chips svelte-1u5fzi5"></div>`,1);function fo(e,t){Le(t,!0);let n=P(()=>Ai(t.locale)),r=P(()=>[t.unread>0?$.written(t.unread):$.nothingUnread,t.broken>0?$.broken(t.broken):$.sound,t.flagged>0?$.flagged(t.flagged):$.clean].join(` `)),i=P(()=>[{id:`all`,label:$.chipAll,n:t.total},{id:`look`,label:$.chipLook,n:t.flagged},{id:`clean`,label:$.chipClean,n:t.total-t.flagged}]);var a=uo(),o=$t(a),s=R(o),c=R(s),l=z(c,!0),u=B(c,2),d=R(u),f=z(d,!0),p=B(d),m=z(B(p),!0);j(u);var h=z(B(u,2),!0);j(s);var g=B(s,2),_=R(g),v=z(_,!0),y=z(B(_,2),!0);j(g),j(o);var b=B(o,2);X(b,21,()=>W(i),e=>e.id,(e,n)=>{var r=lo();let i;var a=R(r),o=z(B(a),!0);j(r),V(()=>{i=Jr(r,1,`pill svelte-1u5fzi5`,null,i,{on:t.chip===W(n).id,look:W(n).id===`look`}),Z(r,`aria-pressed`,t.chip===W(n).id),J(a,`${W(n).label??``} `),J(o,W(n).n)}),G(`click`,r,()=>t.onChip(W(n).id)),q(e,r)}),j(b),V((e,i,a)=>{J(l,W(n)),J(f,t.locale),J(p,`${e??``}. `),J(m,$.live),J(h,W(r)),_.disabled=t.unread===0,J(v,i),J(y,a)},[()=>na(t.total),()=>$.approve(W(n)),()=>t.unread>0?$.approveSub(t.unread):$.nothingUnread]),G(`click`,_,function(...e){t.onApprove?.apply(this,e)}),q(e,a),Re()}fr([`click`]);var po=K(`<div class="bill svelte-a18sfu"><p class="lede svelte-a18sfu"> </p> <p class="why svelte-a18sfu"> </p> <div class="pair svelte-a18sfu"><button class="go svelte-a18sfu"> </button> <button class="plain svelte-a18sfu"> </button></div></div>`),mo=K(`<div class="bill svelte-a18sfu"><p class="lede svelte-a18sfu"> </p> <div class="track svelte-a18sfu"><span class="fill svelte-a18sfu"></span></div> <p class="why svelte-a18sfu"> </p></div>`),ho=K(`<button class="act svelte-a18sfu"><span class="name svelte-a18sfu"> </span> <span class="why svelte-a18sfu"> </span></button> <button class="act svelte-a18sfu"><span class="name svelte-a18sfu"> </span> <span class="why svelte-a18sfu"> </span></button>`,1),go=K(`<p> </p>`),_o=K(`<section class="acts svelte-a18sfu" aria-label="Commands"><h2 class="cap svelte-a18sfu">Commands</h2> <!> <!></section>`);function vo(e,t){Le(t,!0);let n=I(Ht({at:`idle`})),r=P(()=>W(n).at===`finding`||W(n).at===`planning`||W(n).at===`running`);function i(e,t=!1){L(n,{at:`said`,text:e,bad:t},!0)}async function a(){L(n,{at:`finding`},!0);let e=await t.api.extract();if(e.error||!e.value)return i(e.error??`no answer`,!0);let{found:r}=e.value;if(!r)return i(ea.nothingNew);let a=`${na(r)} your code uses and your catalogs did not have`;await t.onDone(a),i(a)}async function o(){L(n,{at:`planning`},!0);let e=await t.api.plan(t.shown);if(e.error||!e.value)return i(e.error??`no answer`,!0);if(!e.value.total)return i(ea.nothingMissing);L(n,{at:`plan`,plan:e.value},!0)}async function s(e){let r=await t.api.job(e);if(r.error||!r.value)return i(r.error??`no answer`,!0);let a=r.value;if(a.state===`running`){L(n,{at:`running`,job:a},!0);return}let o=`${na(a.written??a.done)} translated, unread until you read them`,s=a.kept?`${o}. ${ea.kept(a.kept)}`:o;await t.onDone(s),i(a.state===`failed`?a.message??`the run failed`:s,a.state===`failed`)}async function c(){let e=await t.api.translate(t.shown);if(e.error||!e.value)return i(e.error??`no answer`,!0);L(n,{at:`running`,job:e.value},!0)}gi(()=>{t.api.job().then(e=>{e.value&&W(n).at===`idle`&&L(n,{at:`running`,job:e.value},!0)})}),fn(()=>{if(W(n).at!==`running`)return;let e=W(n).job.id,t=setInterval(()=>void s(e),1e3);return()=>clearInterval(t)});let l=P(()=>t.targets?t.shown.length?ea.translateWhy:ea.pickFirst:ea.onlyLocale),u=P(()=>W(n).at===`running`&&W(n).job.total?W(n).job.done/W(n).job.total:0);var d=_o(),f=B(R(d),2),p=e=>{var t=po(),r=R(t),i=z(r),a=B(r,2),o=z(a,!0),s=B(a,2),l=R(s),u=z(l,!0),d=B(l,2),f=z(d,!0);j(s),j(t),V((e,t)=>{J(i,`${e??``} in ${t??``}`),J(o,ea.translateWhy),J(u,ea.translate),J(f,ea.cancel)},[()=>na(W(n).plan.total),()=>Object.keys(W(n).plan.pending).join(`, `)]),G(`click`,l,c),G(`click`,d,()=>L(n,{at:`idle`},!0)),q(e,t)},m=e=>{var t=mo(),r=R(t),i=z(r),a=B(r,2),o=z(a),s=z(B(a,2));j(t),V(e=>{J(i,`${ea.running??``} ${W(n).job.locale??``??``}`),Xr(o,`width: ${e??``}%`),J(s,`${W(n).job.done??``} of ${W(n).job.total??``}`)},[()=>Math.round(W(u)*100)]),q(e,t)},h=e=>{var i=ho(),s=$t(i),c=R(s),u=z(c,!0),d=z(B(c,2),!0);j(s);var f=B(s,2),p=R(f),m=z(p,!0),h=z(B(p,2),!0);j(f),V(()=>{s.disabled=W(r)||!t.scanning,J(u,W(n).at===`finding`?ea.working:ea.find),J(d,t.scanning?ea.findWhy:ea.scanOff),f.disabled=W(r)||!t.shown.length,J(m,ea.translate),J(h,W(l))}),G(`click`,s,a),G(`click`,f,o),q(e,i)};Y(f,e=>{W(n).at===`plan`?e(p):W(n).at===`running`?e(m,1):e(h,-1)});var g=B(f,2),_=e=>{var t=go();let r;var i=z(t,!0);V(()=>{r=Jr(t,1,`said svelte-a18sfu`,null,r,{bad:W(n).bad}),J(i,W(n).text)}),q(e,t)};Y(g,e=>{W(n).at===`said`&&e(_)}),j(d),q(e,d),Re()}fr([`click`]);var yo=K(`<h2 class="svelte-1qmtve8"> </h2>`),bo=K(`<h2 class="svelte-1qmtve8"> </h2> <p class="svelte-1qmtve8"> </p>`,1),xo=K(`<code class="keys svelte-1qmtve8"> </code>`),So=K(`<button class="svelte-1qmtve8"> </button>`),Co=K(`<div class="job svelte-1qmtve8"><span class="tile svelte-1qmtve8"><!></span> <span class="what svelte-1qmtve8"><b class="svelte-1qmtve8"> </b> <span class="svelte-1qmtve8"> </span> <!></span> <!></div>`),wo=K(`<p class="empty svelte-1qmtve8">…</p>`),To=K(`<p class="empty svelte-1qmtve8"> </p>`),Eo=K(`<p class="commit svelte-1qmtve8"><code class="svelte-1qmtve8"> </code> <span class="svelte-1qmtve8"><b class="svelte-1qmtve8"> </b><span class="svelte-1qmtve8"> </span></span></p>`),Do=K(`<main class="overview svelte-1qmtve8"><header class="svelte-1qmtve8"><span class="chip svelte-1qmtve8"> </span> <!></header> <div class="cols svelte-1qmtve8"><section class="jobs svelte-1qmtve8" aria-label="What needs you"></section> <aside class="side svelte-1qmtve8"><div class="card svelte-1qmtve8"><button class="ring svelte-1qmtve8"><b class="svelte-1qmtve8"> </b> <strong class="svelte-1qmtve8"> </strong> <span class="svelte-1qmtve8"> </span></button> <p class="kv svelte-1qmtve8"><b class="svelte-1qmtve8"> </b><strong class="svelte-1qmtve8"> </strong></p> <p class="kv svelte-1qmtve8"><b class="svelte-1qmtve8"> </b><strong class="svelte-1qmtve8"> </strong></p></div> <div class="card svelte-1qmtve8"><p class="head svelte-1qmtve8"> </p> <!></div></aside></div></main>`);function Oo(e,t){Le(t,!0);let n={broken:`broken`,missing:`missing`,draft:`draft`,undefined:`broken`,extra:`missing`},r=new Set([`undefined`,`extra`]),i=P(()=>t.health.filter(e=>!e.source)),a=P(()=>{let e=e=>W(i).reduce((t,n)=>t+e(n),0);return[{id:`broken`,n:e(e=>e.broken)},{id:`missing`,n:e(e=>e.missing)},{id:`draft`,n:e(e=>e.draft)},{id:`undefined`,n:t.undefinedKeys.length},{id:`extra`,n:t.extraKeys.length}].filter(e=>e.n>0)}),o=P(()=>W(a).reduce((e,t)=>e+t.n,0)),s=new Intl.RelativeTimeFormat(void 0,{numeric:`auto`});function c(e){let t=Math.round((Date.parse(e)-Date.now())/864e5);return t>-1?s.format(0,`day`):t>-31?s.format(t,`day`):s.format(Math.round(t/30),`month`)}var l=Do(),u=R(l),d=R(u),f=z(d,!0),p=B(d,2),m=e=>{var t=yo(),n=z(t);V(()=>J(n,`${W(o)??``} ${W(o)===1?`thing is`:`things are`} waiting for you.`)),q(e,t)},h=e=>{var t=bo(),n=$t(t),r=z(n,!0),i=z(B(n,2),!0);V(()=>{J(r,aa.clear),J(i,aa.clearWhy)}),q(e,t)};Y(p,e=>{W(o)>0?e(m):e(h,-1)}),j(u);var g=B(u,2),_=R(g);X(_,21,()=>W(a),e=>e.id,(e,i)=>{var a=Co(),o=R(a);Sa(R(o),{get state(){return n[W(i).id]}}),j(o);var s=B(o,2),c=R(s),l=z(c),u=B(c,2),d=z(u,!0),f=B(u,2),p=e=>{var n=xo(),r=z(n,!0);V(e=>J(r,e),[()=>t.undefinedKeys.slice(0,3).map(e=>e.key).join(` · `)]),q(e,n)},m=e=>{var n=xo(),r=z(n,!0);V(e=>J(r,e),[()=>t.extraKeys.slice(0,3).map(e=>`${e.key} (${e.locale})`).join(` · `)]),q(e,n)};Y(f,e=>{W(i).id===`undefined`?e(p):W(i).id===`extra`&&e(m,1)}),j(s);var h=B(s,2),g=e=>{var n=So(),r=z(n,!0);V(()=>J(r,aa.open)),G(`click`,n,()=>t.onFilter(W(i).id)),q(e,n)},_=P(()=>!r.has(W(i).id));Y(h,e=>{W(_)&&e(g)}),j(a),V(()=>{Z(o,`data-state`,n[W(i).id]),J(l,`${W(i).n??``} ${(W(i).n===1?ra[W(i).id].one:ra[W(i).id].many)??``}`),J(d,ia[W(i).id])}),q(e,a)}),j(_);var v=B(_,2),y=R(v),b=R(y),x=R(b),S=z(x,!0),ee=B(x,2),C=z(ee,!0),w=z(B(ee,2),!0);j(b);var te=B(b,2),T=R(te),ne=z(T,!0),re=z(B(T),!0);j(te);var ie=B(te,2),ae=R(ie),oe=z(ae,!0),se=z(B(ae),!0);j(ie),j(y);var ce=B(y,2),le=R(ce),E=z(le,!0),ue=B(le,2),de=e=>{q(e,wo())},D=e=>{var t=To(),n=z(t,!0);V(()=>J(n,aa.noHistory)),q(e,t)},fe=e=>{var n=Cr();X($t(n),17,()=>t.commits,e=>e.sha,(e,t)=>{var n=Eo(),r=R(n),i=z(r,!0),a=B(r,2),o=R(a),s=z(o,!0),l=z(B(o));j(a),j(n),V(e=>{J(i,W(t).sha),J(s,W(t).subject),J(l,`${W(t).author??``} · ${e??``}`)},[()=>c(W(t).date)]),q(e,n)}),q(e,n)};Y(ue,e=>{t.commits===null?e(de):t.commits.length===0?e(D,1):e(fe,-1)}),j(ce),j(v),j(g),j(l),V(()=>{J(f,aa.here),b.disabled=!t.checks,J(S,aa.project),J(C,t.checks&&t.checks.ok===t.checks.total?aa.healthy:aa.problems),J(w,t.checks?`${t.checks.ok} of ${t.checks.total} ${aa.checks}`:`…`),J(ne,aa.countMessages),J(re,t.total),J(oe,aa.countLocales),J(se,t.locales.length),J(E,aa.history)}),G(`click`,b,function(...e){t.onHealth?.apply(this,e)}),q(e,l),Re()}fr([`click`]);var ko=K(`<p class="none svelte-1xn1b0j"> </p>`),Ao=K(`<span class="group svelte-1xn1b0j"> </span>`),jo=K(`<span class="src svelte-1xn1b0j"> </span>`),Mo=K(`<b class="disc svelte-1xn1b0j"> </b>`),No=K(`<li><button><span class="tile svelte-1xn1b0j"><!></span> <span class="what svelte-1xn1b0j"><span class="found svelte-1xn1b0j"> <mark class="svelte-1xn1b0j"> </mark> </span> <!> <!></span> <span class="where svelte-1xn1b0j"></span></button></li>`),Po=K(`<ul class="svelte-1xn1b0j"></ul>`),Fo=K(`<div class="sheet svelte-1xn1b0j" role="dialog"><p class="head svelte-1xn1b0j"><span> </span> <b class="svelte-1xn1b0j"> </b></p> <!> <p class="keys svelte-1xn1b0j"><kbd class="svelte-1xn1b0j">↑</kbd><kbd class="svelte-1xn1b0j">↓</kbd> <kbd class="svelte-1xn1b0j">enter</kbd> <kbd class="svelte-1xn1b0j">esc</kbd> <button class="close svelte-1xn1b0j"> </button></p></div>`);function Io(e,t){Le(t,!0);let n=I(0);fn(()=>{t.query,L(n,0)});function r(e){t.hits.length&&L(n,(W(n)+e+t.hits.length)%t.hits.length)}function i(){let e=t.hits[W(n)];e&&t.onPick(e.key)}var a={move:r,choose:i},o=Fo(),s=R(o),c=R(s),l=z(c,!0),u=z(B(c,2),!0);j(s);var d=B(s,2),f=e=>{var t=ko(),n=z(t,!0);V(()=>J(n,oa.none)),q(e,t)},p=e=>{var r=Po();X(r,23,()=>t.hits,e=>e.key,(e,r,i)=>{let a=P(()=>Ia(W(r).text,t.query));var o=No(),s=R(o);let c;var l=R(s);Sa(R(l),{get state(){return W(r).state}}),j(l);var u=B(l,2),d=R(u),f=R(d,!0),p=B(f),m=z(p,!0),h=B(p,1,!0);j(d);var g=B(d,2),_=e=>{var t=Ao(),n=z(t,!0);V(()=>J(n,W(r).group)),q(e,t)};Y(g,e=>{W(r).group&&e(_)});var v=B(g,2),y=e=>{var t=jo(),n=z(t,!0);V(()=>J(n,W(r).source)),q(e,t)},b=P(()=>!W(r).locales.includes(t.sourceLocale));Y(v,e=>{W(b)&&e(y)}),j(u);var x=B(u,2);X(x,20,()=>W(r).locales,e=>e,(e,t)=>{var n=Mo(),r=z(n,!0);V(()=>J(r,t)),q(e,n)}),j(x),j(s),j(o),V(()=>{c=Jr(s,1,`hit svelte-1xn1b0j`,null,c,{on:W(i)===W(n)}),Z(l,`data-state`,W(r).state),J(f,W(a)[0]),J(m,W(a)[1]),J(h,W(a)[2])}),G(`click`,s,()=>t.onPick(W(r).key)),q(e,o)}),j(r),q(e,r)};Y(d,e=>{t.hits.length===0?e(f):e(p,-1)});var m=B(d,2),h=B(R(m),2),g=B(h,2),_=B(g,2),v=B(_),y=z(v,!0);return j(m),j(o),V(e=>{Z(o,`aria-label`,oa.label),J(l,oa.scope),J(u,e),J(h,`${oa.moveKeys??``} `),J(g,`${oa.openKeys??``} `),J(_,`${oa.closeKeys??``} `),J(y,oa.close)},[()=>t.hits.length===1?oa.oneHit:oa.hits(t.hits.length)]),G(`click`,v,function(...e){t.onClose?.apply(this,e)}),q(e,o),Re(a)}fr([`click`]);var Lo=K(`<li><code> </code> </li>`),Ro=K(`<ul class="problems svelte-1xn7ig5"></ul>`),zo=K(`<p class="note svelte-1xn7ig5"> </p>`),Bo=K(`<!> <!>`,1),Vo=K(`<div class="lens svelte-1xn7ig5"><!> <main class="table svelte-1xn7ig5"><!></main></div>`),Ho=K(`Saved in <code> </code>`,1),Uo=K(`<p class="snack svelte-1xn7ig5" role="status"><svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="svelte-1xn7ig5"><path d="m3.4 8.4 3 3 6.2-6.8"></path></svg> <!> <button class="svelte-1xn7ig5">Dismiss</button></p>`),Wo=K(`<div class="shell svelte-1xn7ig5"><header class="bar svelte-1xn7ig5"><span class="brand svelte-1xn7ig5">verbaly <b class="svelte-1xn7ig5">studio</b></span> <input class="search svelte-1xn7ig5" type="search"/> <span class="root svelte-1xn7ig5"> </span></header> <!> <!> <div class="body svelte-1xn7ig5"><!> <!></div> <!></div>`);function Go(e,t){Le(t,!0);let n=I(null),r=I(null),i=I(null),a=I(`overview`),o=I(null),s=I(null),c=I(null),l=new Map;async function u(e){let n=l.get(e);if(n)return n;let i=await t.api.commit(e);return i.error||!i.value?(L(r,{text:i.error??`[verbaly] the server sent no answer`,file:``},!0),null):(l.set(e,i.value),i.value)}function d(e){e===`health`?f():L(a,e,!0)}async function f(){L(a,`health`);let e=await t.api.health();e.error?L(r,{text:e.error,file:``},!0):e.value&&L(o,e.value,!0)}fn(()=>{t.api.health().then(e=>{e.value&&L(o,e.value,!0)}),t.api.history().then(e=>{L(s,e.value?.commits??[],!0)})});function p(e){L(y,W(x),!0),L(_,e,!0),L(a,`messages`)}async function m(e){let a=await t.api.state();if(a.error||!a.value){L(r,{text:a.error??`[verbaly] the server sent no state`,file:``},!0);return}L(n,null),L(i,null),L(c,null),l.clear(),Da(t.panel,a.value),L(r,{text:e,file:``},!0);let s=await t.api.health();s.value&&L(o,s.value,!0)}async function h(e,n,a){let o=await t.api.setRead(e,n,a);if(o.error){L(r,{text:o.error,file:``},!0);return}let s=new Set(o.value?.keys??[]);for(let n of t.panel.rows){if(!s.has(n.key))continue;let t=n.cells.find(t=>t.locale===e);t?.text&&(t.state=a?`draft`:`done`)}L(i,a?null:{locale:e,keys:o.value?.keys??[]},!0)}async function g(e,n,i){let a=await t.api.save(e,n,i);if(a.error)return a.error;let o=t.panel.rows.find(e=>e.key===n)?.cells.find(t=>t.locale===e);return o&&(o.text=i,o.state=i?`done`:`missing`,o.issue=void 0),L(r,{text:i,file:`${e}.json`},!0),null}let _=I(`all`),v=I(``),y=I(null),b=I(null),x=P(()=>t.panel.locales.filter(e=>e!==t.panel.sourceLocale)),S=P(()=>W(y)??W(x).slice(0,1)),ee=P(()=>Ea(t.panel)),C=P(()=>W(S).length===1?W(S)[0]:null),w=P(()=>W(C)?W(ee).find(e=>e.locale===W(C)):void 0),te=P(()=>W(C)?t.panel.rows.filter(e=>Ra(e,W(C))!==null).length:0),T=P(()=>W(_)===`look`?`look`:W(_)===`clean`?`clean`:W(_)===`all`?`all`:null),ne=P(()=>Fa(t.panel,W(v))),re=I(void 0),ie=I(void 0),ae=I(null),oe=P(()=>ja(t.panel.rows,W(S))),se=P(()=>{let e=Ma(t.panel.rows,{text:``,state:W(_),locales:W(S),group:W(b)});return W(C)?La(e,W(C)).rows:e}),ce=P(()=>Oa(t.panel,W(S),W(se))),le=P(()=>{let e={all:0,look:0,clean:0,missing:0,draft:0,broken:0};for(let n of[`all`,`look`,`clean`,`missing`,`draft`,`broken`])e[n]=Ma(t.panel.rows,{text:``,state:n,locales:W(S),group:W(b)}).length;return e}),E=I(60);fn(()=>{W(_),W(S),W(b),L(E,60)});function ue(e){L(v,``),L(_,`all`),L(b,null),L(y,W(x),!0),L(a,`messages`),L(ae,e,!0)}fn(()=>{if(!W(ae))return;let e=W(ae),t=W(se).findIndex(t=>t.key===e);t<0?L(ae,null):t+1>W(E)?L(E,t+1):(L(ae,null),tr().then(()=>{document.querySelector(`[data-key="${CSS.escape(e)}"]`)?.scrollIntoView({block:`center`})}))});function de(e){(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()===`k`?(e.preventDefault(),W(ie)?.focus(),W(ie)?.select()):W(v)&&(e.key===`Escape`?(L(v,``),W(ie)?.blur()):e.key===`ArrowDown`?(e.preventDefault(),W(re)?.move(1)):e.key===`ArrowUp`?(e.preventDefault(),W(re)?.move(-1)):e.key===`Enter`&&(e.preventDefault(),W(re)?.choose()))}function D(e){let t=e.currentTarget;t.scrollTop+t.clientHeight>t.scrollHeight-600&&W(E)<W(se).length&&L(E,W(E)+60)}function fe(e){L(y,W(S).includes(e)?W(S).filter(t=>t!==e):[...W(S),e],!0)}var pe=Wo();dr(`keydown`,Gt,de);var me=R(pe),he=B(R(me),2);oi(he),hi(he,e=>L(ie,e),()=>W(ie));var ge=B(he,2),O=z(ge,!0);j(me);var _e=B(me,2),k=e=>{var n=Ro();X(n,21,()=>t.panel.problems,e=>e.scope+e.message,(e,t)=>{var n=Lo(),r=R(n),i=z(r,!0),a=B(r);j(n),V(()=>{J(i,W(t).scope),J(a,` ${W(t).message??``}`)}),q(e,n)}),j(n),q(e,n)};Y(_e,e=>{t.panel.problems.length&&e(k)});var A=B(_e,2),ve=e=>{hi(Io(e,{get query(){return W(v)},get hits(){return W(ne)},get sourceLocale(){return t.panel.sourceLocale},onPick:ue,onClose:()=>L(v,``)}),e=>L(re,e,!0),()=>W(re))};Y(A,e=>{W(v)&&e(ve)});var ye=B(A,2),be=R(ye);{let e=e=>{vo(e,{get api(){return t.api},get scanning(){return t.panel.scanning},get targets(){return W(x).length},get shown(){return W(S)},onDone:m})},n=P(()=>W(o)?{bad:W(o).entries.filter(e=>e.level!==`ok`).length}:null);ga(be,{get health(){return W(ee)},get shown(){return W(S)},get state(){return W(_)},get counts(){return W(le)},get pending(){return W(i)},get checks(){return W(n)},onToggle:fe,onState:e=>L(_,e,!0),onRead:e=>h(e,void 0,!1),onUndo:()=>W(i)&&h(W(i).locale,W(i).keys,!0),get view(){return W(a)},onView:d,get groups(){return W(oe)},get group(){return W(b)},onGroup:e=>L(b,e,!0),actions:e,$$slots:{actions:!0}})}var xe=B(be,2),Se=e=>{{let n=P(()=>W(o)?{ok:W(o).entries.filter(e=>e.level===`ok`).length,total:W(o).entries.length}:null);Oo(e,{get health(){return W(ee)},get undefinedKeys(){return t.panel.undefined},get extraKeys(){return t.panel.extra},get locales(){return t.panel.locales},get total(){return t.panel.rows.length},get checks(){return W(n)},get commits(){return W(s)},onFilter:p,onHealth:f})}},Ce=e=>{{let t=P(()=>W(o)?.entries??[]),n=P(()=>W(o)?.ok??!0);Ci(e,{get entries(){return W(t)},get ok(){return W(n)},onClose:()=>L(a,`overview`)})}},we=e=>{var i=Vo(),a=R(i),o=e=>{fo(e,{get locale(){return W(C)},get total(){return t.panel.rows.length},get unread(){return W(w).draft},get broken(){return W(w).broken},get flagged(){return W(te)},get chip(){return W(T)},onChip:e=>L(_,e,!0),onApprove:()=>h(W(C),void 0,!1)})};Y(a,e=>{W(C)&&W(w)&&!W(ce)&&e(o)});var s=B(a,2),l=R(s),d=e=>{var t=zo(),n=z(t);V(()=>J(n,`${ta[W(ce)]??``}${W(ce)===`oneLocale`?` ${ta.oneLocaleFix}`:``}`)),q(e,t)},f=e=>{var i=Bo(),a=$t(i);X(a,17,()=>W(se).slice(0,W(E)),e=>e.key,(e,i)=>{{let a=P(()=>W(C)?Ra(W(i),W(C)):void 0),o=P(()=>W(c)===W(i).key);co(e,{get row(){return W(i)},get shown(){return W(S)},get editing(){return W(n)},onEdit:e=>L(n,e,!0),onSave:g,get why(){return W(a)},get scanning(){return t.panel.scanning},get menu(){return W(o)},onMenu:e=>L(c,e?W(i).key:null,!0),onNote:e=>L(r,{text:e,file:``},!0),onCommit:u})}});var o=B(a,2),s=e=>{var t=zo(),n=z(t,!0);V(e=>J(n,e),[()=>W(C)?$.rest(W(se).length-W(E)):`${W(se).length-W(E)} more below`]),q(e,t)};Y(o,e=>{W(E)<W(se).length&&e(s)}),q(e,i)};Y(l,e=>{W(ce)?e(d):e(f,-1)}),j(s),j(i),dr(`scroll`,s,D),q(e,i)};Y(xe,e=>{W(a)===`overview`?e(Se):W(a)===`health`?e(Ce,1):e(we,-1)}),j(ye);var Te=B(ye,2),Ee=e=>{var t=Uo(),n=B(R(t),2),i=e=>{var t=Ho(),n=z(B($t(t)),!0);V(()=>J(n,W(r).file)),q(e,t)},a=e=>{var t=Sr();V(()=>J(t,W(r).text)),q(e,t)};Y(n,e=>{W(r).file?e(i):e(a,-1)});var o=B(n,2);j(t),G(`click`,o,()=>L(r,null)),q(e,t)};Y(Te,e=>{W(r)&&e(Ee)}),j(pe),V(()=>{Z(he,`placeholder`,oa.placeholder),Z(he,`aria-label`,oa.placeholder),Z(ge,`title`,t.panel.root),J(O,t.panel.root)}),di(he,()=>W(v),e=>L(v,e)),q(e,pe),Re()}fr([`click`]);async function Ko(e,t,n){let r=t.includes(`?`)?`&`:`?`,i;try{i=await fetch(`${t}${r}t=${encodeURIComponent(e)}`,{...n,headers:n?.body===void 0?void 0:{"content-type":`application/json`},body:n?.body===void 0?void 0:JSON.stringify(n.body)})}catch{return{error:`[verbaly] the studio server is not answering, is it still running?`}}let a=await i.json().catch(()=>({}));return i.ok?{value:a}:{error:a.error??`[verbaly] the server answered ${i.status}`}}function qo(e){return{state:()=>Ko(e,`/api/state`),health:()=>Ko(e,`/api/health`),history:()=>Ko(e,`/api/history`),commit:t=>Ko(e,`/api/commit/${encodeURIComponent(t)}`),save:(t,n,r)=>Ko(e,`/api/message/${encodeURIComponent(t)}/${encodeURIComponent(n)}`,{method:`PUT`,body:{text:r}}),setRead:(t,n,r)=>Ko(e,`/api/approve`,{method:`POST`,body:{locale:t,keys:n,undo:r}}),extract:()=>Ko(e,`/api/extract`,{method:`POST`}),plan:t=>{let n=t.map(e=>`locale=${encodeURIComponent(e)}`).join(`&`);return Ko(e,`/api/translate${n?`?${n}`:``}`)},translate:t=>Ko(e,`/api/translate`,{method:`POST`,body:{locales:t}}),job:t=>Ko(e,t?`/api/job/${encodeURIComponent(t)}`:`/api/job`)}}function Jo(e){return Ht(Ta(e))}var Yo=new URLSearchParams(location.search).get(`t`)??``;async function Xo(){let e=document.getElementById(`app`),t=qo(Yo),n=await t.state();n.error||!n.value?e.textContent=n.error??`[verbaly] the server sent no state`:Or(Go,{target:e,props:{panel:Jo(n.value),api:t}})}Xo();
|
package/dist/ui/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>Verbaly Studio</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-BzEEUpQG.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-C9E7gq0Q.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|