@innspel/react-native 0.3.1 → 0.4.1

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/InnspelProvider.tsx","../src/skjermbilde.ts","../src/tema.ts","../src/generated/tokens.ts","../src/widget/Widget.tsx","../src/widget/Felt.tsx","../src/widget/primitiver.tsx","../src/widget/tekster.ts","../src/widget/Valg.tsx","../src/widget/KjenteFeil.tsx","../src/widget/Kvittering.tsx","../src/widget/MineInnspill.tsx","../src/widget/status.ts","../src/widget/Skjermbilde.tsx","../src/InnspelPrivate.tsx","../src/program/InnspelProgram.tsx","../src/program/Aksept.tsx","../src/program/periode.ts","../src/lagring.ts"],"sourcesContent":["import type { InnspelClient, OpenFeedbackOptions } from '@innspel/core';\nimport React, { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react';\nimport { View } from 'react-native';\nimport { createPrivateRegistry, SkjermbildeContext, type ScreenshotAdapter, type SkjermbildeKontekst, type ViewRef } from './skjermbilde.js';\nimport { byggTema, TemaProvider, type PartialTheme } from './tema.js';\nimport { Widget } from './widget/Widget.js';\n\ninterface InnspelKontekst {\n client: InnspelClient;\n /** Åpner widgeten. Samme som `client.openFeedback()`. */\n open: (options?: OpenFeedbackOptions) => Promise<void>;\n close: () => void;\n}\n\nconst Kontekst = createContext<InnspelKontekst | null>(null);\n\n/**\n * Pakk appen i denne, og widgeten finnes.\n *\n * Provideren gjør fire ting: den registrerer visningen hos kjernen (så\n * `client.openFeedback()` virker hvor som helst i appen, også utenfor React),\n * den holder temaet, den rendrer selve arket — og den pakker vertsappen i én\n * `View` med referanse, som er det skjermbildet tas av (K4). Modalen ligger\n * utenfor den viewen og kommer aldri med på bildet.\n *\n * @example\n * ```tsx\n * const innspel = init({ … });\n *\n * export default function App() {\n * return (\n * <InnspelProvider client={innspel} screenshot={createScreenshotAdapter(captureRef)}>\n * <MinApp />\n * </InnspelProvider>\n * );\n * }\n * ```\n */\nexport function InnspelProvider({\n client,\n children,\n theme,\n colorScheme = 'dark',\n tenantName,\n screenshot,\n}: {\n client: InnspelClient;\n children?: React.ReactNode;\n /** Vertens egne tokens. Alt som utelates faller tilbake på Innspels tema. */\n theme?: PartialTheme;\n colorScheme?: 'dark' | 'light';\n /** Navnet som står på svaret i «Mine innspill» — leietakerens, ikke Innspels. */\n tenantName?: string;\n /**\n * Fangst av skjermbilde, typisk `createScreenshotAdapter(captureRef)` fra\n * react-native-view-shot. Uten den finnes ikke skjermbilde-steget (DD-26) —\n * og det finnes uansett ikke når `screenshotsEnabled` er av (K18).\n */\n screenshot?: ScreenshotAdapter;\n}) {\n const [synlig, setSynlig] = useState(false);\n const [apneOpsjoner, setApneOpsjoner] = useState<OpenFeedbackOptions | undefined>();\n const registrert = useRef(false);\n const rootRef = useRef<ViewRef | null>(null);\n const privat = useMemo(createPrivateRegistry, []);\n\n const open = useCallback(\n async (options?: OpenFeedbackOptions) => {\n setApneOpsjoner(options);\n setSynlig(true);\n },\n [],\n );\n\n const close = useCallback(() => setSynlig(false), []);\n\n // Registreres én gang. Kjernen kaller `presenter.open()` fra\n // `client.openFeedback()`, som er veien inn for kode som ikke er en\n // React-komponent — en navigasjonshandler, en krasjlytter hos verten.\n if (!registrert.current) {\n client.registerPresenter({ open });\n registrert.current = true;\n }\n\n const tema = useMemo(() => byggTema(theme, colorScheme), [theme, colorScheme]);\n const verdi = useMemo<InnspelKontekst>(() => ({ client, open, close }), [client, open, close]);\n const skjermbilde = useMemo<SkjermbildeKontekst>(\n () => ({ adapter: screenshot ?? null, rootRef, privat }),\n [screenshot, privat],\n );\n\n return (\n <Kontekst.Provider value={verdi}>\n <SkjermbildeContext.Provider value={skjermbilde}>\n <TemaProvider value={tema}>\n <View ref={rootRef} collapsable={false} style={{ flex: 1 }} testID=\"innspel-rot\">\n {children}\n </View>\n <Widget\n client={client}\n synlig={synlig}\n {...(apneOpsjoner ? { apneOpsjoner } : {})}\n {...(tenantName ? { tenantName } : {})}\n onLukk={close}\n />\n </TemaProvider>\n </SkjermbildeContext.Provider>\n </Kontekst.Provider>\n );\n}\n\n/**\n * Klienten og `open` fra nærmeste {@link InnspelProvider}.\n *\n * Kaster utenfor provideren i stedet for å gi `null`: en knapp som stille ikke\n * gjør noe er verre enn en feil under utvikling (tech-decisions.md, «Feil bruk\n * feiler høyt og tidlig»).\n */\nexport function useInnspel(): InnspelKontekst {\n const k = useContext(Kontekst);\n if (!k) {\n throw new Error(\n '[innspel] useInnspel() ble kalt utenfor <InnspelProvider>. Pakk appen din i den — se README.md.',\n );\n }\n return k;\n}\n","import type { MaskRect } from '@innspel/core';\nimport { createContext, useContext, type ComponentRef, type RefObject } from 'react';\nimport { Image, type View } from 'react-native';\n\n/** Host-elementet bak en `View` — det som kan måles og fanges. RN 0.87: `View` er en funksjonskomponent, så typen hentes herfra. */\nexport type ViewRef = ComponentRef<typeof View>;\n\n/**\n * Fangst av skjermbilde er det ene stedet widgeten trenger noe React Native\n * ikke har innebygd. Pakken tar INGEN avhengighet på det (K19, samme mønster som\n * `createStorage`): verten sender inn `captureRef` fra `react-native-view-shot`,\n * og uten adapter finnes ikke skjermbilde-steget (DD-26) — ikke som en grå\n * knapp, det finnes ikke.\n *\n * Alt som rører plattformen går gjennom adapteren, også måling og fillesing, så\n * widgeten kan testes med en fake og maskeringen bevises uten native kode.\n */\n\nexport interface ScreenshotCapture {\n /** Fil-URI fra fangsten. Forlater aldri enheten før den er maskert og rekomponert. */\n uri: string;\n /** Bitmapens størrelse i piksler. */\n width: number;\n height: number;\n}\n\nexport interface CaptureOptions {\n format: 'jpg' | 'png';\n /** 0–1, kun JPEG. */\n quality: number;\n}\n\nexport interface ScreenshotAdapter {\n /** Fanger viewen bak referansen til en fil. Kalles ved «Legg ved skjermbilde» (K4), og igjen på forhåndsvisningen for å rekomponere. */\n capture(ref: RefObject<ViewRef | null>, options: CaptureOptions): Promise<ScreenshotCapture>;\n /** Viewens rektangel i vinduskoordinater, i punkter. Null når den ikke er montert. */\n measure(ref: RefObject<ViewRef | null>): Promise<MaskRect | null>;\n /** Leser en fangst som Blob for opplasting. */\n read(uri: string): Promise<Blob>;\n}\n\n/** Signaturen til `captureRef` i react-native-view-shot — det eneste verten trenger å sende inn. */\nexport type CaptureRefFn = (\n ref: RefObject<ViewRef | null> | ViewRef,\n options: { format: 'jpg' | 'png'; quality: number; result: 'tmpfile' },\n) => Promise<string>;\n\n/**\n * Lager adapteren av vertens `captureRef`. Dimensjonene hentes med `Image.getSize`,\n * målingen med `measureInWindow`, og fila leses med `fetch(uri).blob()` — alt fra\n * React Native selv.\n *\n * @example\n * ```tsx\n * import { captureRef } from 'react-native-view-shot';\n * <InnspelProvider client={innspel} screenshot={createScreenshotAdapter(captureRef)}>\n * ```\n */\nexport function createScreenshotAdapter(captureRef: CaptureRefFn): ScreenshotAdapter {\n return {\n async capture(ref, options) {\n const uri = await captureRef(ref, { format: options.format, quality: options.quality, result: 'tmpfile' });\n const { width, height } = await new Promise<{ width: number; height: number }>((resolve, reject) =>\n Image.getSize(uri, (w, h) => resolve({ width: w, height: h }), reject),\n );\n return { uri, width, height };\n },\n measure(ref) {\n return new Promise((resolve) => {\n const view = ref.current;\n if (!view) return resolve(null);\n view.measureInWindow((x, y, width, height) => resolve({ x, y, width, height }));\n });\n },\n async read(uri) {\n const res = await fetch(uri);\n return res.blob();\n },\n };\n}\n\n/**\n * Private views (DD-39): det verten har merket med `<InnspelPrivate>`. Registeret\n * lever i provideren; widgeten måler hver av dem i fangstøyeblikket og legger en\n * maske brukeren ikke kan fjerne.\n */\nexport interface PrivateRegistry {\n register(ref: RefObject<ViewRef | null>): () => void;\n refs(): ReadonlyArray<RefObject<ViewRef | null>>;\n}\n\nexport function createPrivateRegistry(): PrivateRegistry {\n const alle = new Set<RefObject<ViewRef | null>>();\n return {\n register(ref) {\n alle.add(ref);\n return () => {\n alle.delete(ref);\n };\n },\n refs: () => [...alle],\n };\n}\n\nexport interface SkjermbildeKontekst {\n adapter: ScreenshotAdapter | null;\n /** Vertsappen — det som fanges. Modalen ligger utenfor og kommer aldri med. */\n rootRef: RefObject<ViewRef | null>;\n privat: PrivateRegistry;\n}\n\nexport const SkjermbildeContext = createContext<SkjermbildeKontekst | null>(null);\n\nexport function useSkjermbilde(): SkjermbildeKontekst | null {\n return useContext(SkjermbildeContext);\n}\n","import { createContext, useContext } from 'react';\nimport { light, t, type InnspelColors, type InnspelTheme } from './generated/tokens.js';\n\n/**\n * Widgeten lever INNE i vertsappen (DD-21) og skal arve dens flate. Verten\n * sender et delvis tema; alt den ikke sender faller tilbake på Innspels eget\n * (M0.4), som er generert fra `theme/theme.ts` og målt mot WCAG AA.\n *\n * Ingen hex-verdi, px-verdi eller fontstørrelse skrives i en komponent — alt\n * hentes herfra (CLAUDE.md, «Styling»). `fontFamily` finnes ikke: systemfonten\n * er standard i React Native, og å sette den ville brutt med vertsappen.\n */\n\n/**\n * De genererte tokenene er `as const`, så `t.touch` har typen `48` og ikke\n * `number`. Det er riktig for KILDEN — den skal ikke kunne endres ved et uhell\n * — men gjør temaet umulig å overstyre: verten ville måttet sende nøyaktig 48.\n * Denne typen åpner verdiene uten å åpne nøkkelsettet: en vert kan bytte en\n * farge, men ikke finne på en ny.\n */\nexport type Tema = Omit<\n InnspelTheme,\n 'color' | 'space' | 'radius' | 'font' | 'lineHeight' | 'motion' | 'touch' | 'screenPadding' | 'hairline'\n> & {\n color: Record<keyof InnspelColors, string>;\n space: Record<keyof InnspelTheme['space'], number>;\n radius: Record<keyof InnspelTheme['radius'], number>;\n font: Record<keyof InnspelTheme['font'], number>;\n lineHeight: Record<keyof InnspelTheme['lineHeight'], number>;\n motion: Record<keyof InnspelTheme['motion'], number>;\n touch: number;\n screenPadding: number;\n hairline: number;\n};\n\nexport type PartialTheme = {\n color?: Partial<Tema['color']>;\n} & Partial<Omit<Tema, 'color'>>;\n\n/**\n * Fletter vertens tokens over Innspels egne.\n *\n * @param vertens Delvis tema fra `<InnspelProvider theme={…}>`.\n * @param palett `dark` er standard: widgeten åpnes oftest over en app i mørk\n * modus, og et lyst ark over en mørk app blender.\n */\nexport function byggTema(vertens?: PartialTheme, palett: 'dark' | 'light' = 'dark'): Tema {\n const bunn = (palett === 'light' ? light : t) as unknown as Tema;\n if (!vertens) return bunn;\n\n return {\n ...bunn,\n ...vertens,\n color: { ...bunn.color, ...vertens.color },\n };\n}\n\nconst TemaContext = createContext<Tema>(t as unknown as Tema);\n\nexport const TemaProvider = TemaContext.Provider;\n\n/** Tokenene som gjelder her. Bruk ALDRI en literal farge eller avstand i stedet. */\nexport function useTema(): Tema {\n return useContext(TemaContext);\n}\n","/**\n * tokens.ts — GENERERT fra theme/theme.ts (avtrykk e9fb0cf68373).\n * Rediger aldri denne filen. Endre temaet i kilden og kjør\n * `node scripts/generate-tokens.ts`, som CI verifiserer med `--check`.\n *\n * Tokenene @innspel/react-native faller tilbake på når verten ikke sender egne.\n * Widgeten lever inne i vertsappen og skal arve dens flate (DD-21); dette er\n * bunnen, ikke fasiten.\n *\n * 72 kontrastpar er målt mot WCAG AA i begge paletter, og generatoren\n * nekter å skrive hvis ett faller under kravet. Farge bærer aldri mening alene\n * — hver status har ikon og tekstetikett (DD-08).\n *\n * fontFamily finnes ikke her med vilje: systemfonten er standard i React\n * Native, og å sette den ville brutt med vertsappen.\n */\n\n/** Mørk palett — fallback når verten ikke sender egne tokens. */\nexport const t = {\n color: {\n bg: \"#111417\",\n surface: \"#1A1E22\",\n surfaceRaised: \"#232830\",\n border: \"#2E343B\",\n borderStrong: \"#3D444D\",\n borderInteractive: \"#7C8894\",\n textPrimary: \"#F2F4F6\",\n textSecondary: \"#B4BCC5\",\n textMuted: \"#8D96A1\",\n textDisabled: \"#5A626B\",\n actionPrimary: \"#5AD3E2\",\n onActionPrimary: \"#04252A\",\n actionSecondaryBorder: \"#7C8894\",\n actionSecondaryText: \"#F2F4F6\",\n brand: \"#5AD3E2\",\n onBrand: \"#04252A\",\n brandFill: \"#0E7C8C\",\n onBrandFill: \"#FFFFFF\",\n brandBg: \"#0C2A30\",\n danger: \"#FF7A8C\",\n dangerFill: \"#C4001F\",\n onDangerFill: \"#FFFFFF\",\n dangerBg: \"#2C1116\",\n success: \"#3ED88A\",\n onSuccess: \"#062015\",\n successBg: \"#0E2A1E\",\n warning: \"#FFC24D\",\n onWarning: \"#2A1C02\",\n warningBg: \"#2C2107\",\n info: \"#5CC0FF\",\n onInfo: \"#04222F\",\n infoBg: \"#0E2531\",\n neutral: \"#A3ACB6\",\n onNeutral: \"#111417\",\n neutralBg: \"#242A31\",\n scrim: \"rgba(0, 0, 0, 0.72)\",\n },\n space: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n },\n radius: {\n sm: 6,\n md: 8,\n lg: 12,\n pill: 999,\n },\n font: {\n h1: 24,\n h2: 21,\n h3: 18,\n body: 16,\n small: 13,\n tiny: 11,\n },\n lineHeight: {\n h1: 30,\n h2: 27,\n h3: 24,\n body: 24,\n small: 18,\n tiny: 16,\n },\n weight: {\n regular: \"400\",\n medium: \"500\",\n semibold: \"600\",\n bold: \"700\",\n },\n motion: {\n fast: 120,\n base: 200,\n slow: 320,\n },\n touch: 48,\n screenPadding: 24,\n hairline: 1,\n} as const;\n\n/** Lys palett. */\nexport const light = {\n color: {\n bg: \"#F6F7F9\",\n surface: \"#FFFFFF\",\n surfaceRaised: \"#EDEFF3\",\n border: \"#D2D7DE\",\n borderStrong: \"#B9C0C9\",\n borderInteractive: \"#6F7883\",\n textPrimary: \"#14181D\",\n textSecondary: \"#454D57\",\n textMuted: \"#5C6470\",\n textDisabled: \"#9AA2AD\",\n actionPrimary: \"#0A6673\",\n onActionPrimary: \"#FFFFFF\",\n actionSecondaryBorder: \"#6F7883\",\n actionSecondaryText: \"#14181D\",\n brand: \"#0A6673\",\n onBrand: \"#FFFFFF\",\n brandFill: \"#0A6673\",\n onBrandFill: \"#FFFFFF\",\n brandBg: \"#E0F0F2\",\n danger: \"#B3001B\",\n dangerFill: \"#B3001B\",\n onDangerFill: \"#FFFFFF\",\n dangerBg: \"#FCE8EA\",\n success: \"#04693C\",\n onSuccess: \"#FFFFFF\",\n successBg: \"#E4F4EC\",\n warning: \"#7A5200\",\n onWarning: \"#FFFFFF\",\n warningBg: \"#FBF1DE\",\n info: \"#00588F\",\n onInfo: \"#FFFFFF\",\n infoBg: \"#E4F0F8\",\n neutral: \"#5C6470\",\n onNeutral: \"#FFFFFF\",\n neutralBg: \"#EEF0F3\",\n scrim: \"rgba(10, 14, 18, 0.45)\",\n },\n space: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n },\n radius: {\n sm: 6,\n md: 8,\n lg: 12,\n pill: 999,\n },\n font: {\n h1: 24,\n h2: 21,\n h3: 18,\n body: 16,\n small: 13,\n tiny: 11,\n },\n lineHeight: {\n h1: 30,\n h2: 27,\n h3: 24,\n body: 24,\n small: 18,\n tiny: 16,\n },\n weight: {\n regular: \"400\",\n medium: \"500\",\n semibold: \"600\",\n bold: \"700\",\n },\n motion: {\n fast: 120,\n base: 200,\n slow: 320,\n },\n touch: 48,\n screenPadding: 24,\n hairline: 1,\n} as const;\n\n/** Innspillets statuser. `fg`/`bg` er TOKENNAVN og slås opp i den aktive paletten. Nøklene er Submissions.SubmissionStatus i contracts/. */\nexport const submissionStatus = {\n ny: {\n statusType: \"reviewing\",\n ikon: \"ellipse-outline\",\n etikett: { feil: \"Mottatt\", onske: \"Mottatt\" },\n fg: \"textSecondary\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n vurderes: {\n statusType: \"reviewing\",\n ikon: \"hourglass-outline\",\n etikett: { feil: \"Vurderes\", onske: \"Vurderes\" },\n fg: \"info\",\n bg: \"infoBg\",\n variant: \"outline\",\n },\n planlagt: {\n statusType: \"active\",\n ikon: \"calendar-outline\",\n etikett: { feil: \"Planlagt\", onske: \"Planlagt\" },\n fg: \"brand\",\n bg: \"brandBg\",\n variant: \"outline\",\n },\n bygges: {\n statusType: \"active\",\n ikon: \"construct-outline\",\n etikett: { feil: \"Retter nå\", onske: \"Bygger\" },\n fg: \"brand\",\n bg: \"brandBg\",\n variant: \"filled\",\n },\n kjent_feil: {\n statusType: \"active\",\n ikon: \"warning-outline\",\n etikett: { feil: \"Kjent feil\", onske: \"Kjent feil\" },\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n levert: {\n statusType: \"complete\",\n ikon: \"checkmark-circle-outline\",\n etikett: { feil: \"Rettet\", onske: \"Levert\" },\n fg: \"success\",\n bg: \"successBg\",\n variant: \"outline\",\n },\n avvist: {\n statusType: \"closed\",\n ikon: \"close-circle-outline\",\n etikett: { feil: \"Avvist\", onske: \"Avvist\" },\n fg: \"danger\",\n bg: \"dangerBg\",\n variant: \"outline\",\n },\n duplikat: {\n statusType: \"closed\",\n ikon: \"git-merge-outline\",\n etikett: { feil: \"Slått sammen\", onske: \"Slått sammen\" },\n fg: \"neutral\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n} as const;\n\n/** Programmets statuser. Nøklene er Programs.ProgramStatus i contracts/. */\nexport const programStatus = {\n utkast: {\n ikon: \"create-outline\",\n etikett: \"Utkast\",\n fg: \"textSecondary\",\n bg: \"neutralBg\",\n variant: \"dashed\",\n },\n aapen: {\n ikon: \"ellipse-outline\",\n etikett: \"Åpen — invitasjoner kan sendes\",\n fg: \"info\",\n bg: \"infoBg\",\n variant: \"outline\",\n },\n aktiv: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Aktiv\",\n fg: \"success\",\n bg: \"successBg\",\n variant: \"outline\",\n },\n avsluttes: {\n ikon: \"time-outline\",\n etikett: \"Avsluttes — oppfølginger går ut\",\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n avsluttet: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Avsluttet — rapport fryst\",\n fg: \"neutral\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n avbrutt: {\n ikon: \"close-circle\",\n etikett: \"Avbrutt\",\n fg: \"onDangerFill\",\n bg: \"dangerFill\",\n variant: \"filled\",\n },\n} as const;\n\n/** Kjent feil-statusene (M2.4). Nøklene er KnownIssues.KnownIssueStatus i contracts/; «fikset» heter «Rettet» (DD-22). */\nexport const knownIssueStatus = {\n aktiv: {\n ikon: \"warning-outline\",\n etikett: \"Aktiv\",\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n fikset: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Rettet\",\n fg: \"success\",\n bg: \"successBg\",\n variant: \"dashed\",\n },\n} as const;\n\n/** Skjermbilde-maskering. Faste signalfarger, uavhengig av palett (DD-39, DD-40). Vedlegg er M1.3. */\nexport const screenRules = {\n brushFill: \"#E5007D\",\n autoMaskFill: \"#101114\",\n autoMaskStroke: \"#E5007D\",\n previewBackdrop: \"#000000\",\n brushWidth: 28,\n textBlurRadius: 24,\n} as const;\n\n/** Formen widgeten tar imot. Verten sender et delvis tema; resten faller tilbake hit. */\nexport type InnspelTheme = typeof t;\nexport type InnspelColors = InnspelTheme['color'];\n","import {\n InnspelApiError,\n InnspelQueueFullError,\n type AttachmentInput,\n type InnspelClient,\n type KnownIssueCard,\n type MaskRect,\n type MySubmission,\n type OpenFeedbackOptions,\n type PatternFinding,\n} from '@innspel/core';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Modal, Pressable, Text, View } from 'react-native';\nimport { useSkjermbilde, type ScreenshotCapture, type ViewRef } from '../skjermbilde.js';\nimport { useTema } from '../tema.js';\nimport { Felt } from './Felt.js';\nimport { Valg } from './Valg.js';\nimport { KjenteFeil } from './KjenteFeil.js';\nimport { Kvittering, type KvitteringArt } from './Kvittering.js';\nimport { MineInnspill } from './MineInnspill.js';\nimport { Skjermbilde } from './Skjermbilde.js';\nimport { Banner, Btn } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\nexport type Steg = 'valg' | 'kjenteFeil' | 'felt' | 'skjermbilde' | 'kvittering' | 'mine';\n\n/** JPEG med denne kvaliteten holder et 3×-skjermbilde godt under 5 MB (K9) og gjør uskarphet irreversibel i praksis. */\nconst FANGST = { format: 'jpg', quality: 0.85 } as const;\n\n/**\n * Widgeten. Ett ark over vertsappen — aldri en flytende knapp over innhold\n * (DD-21).\n *\n * **DD-47, og hvorfor det står her og ikke i en TODO:** arket er en dialog og\n * oppfører seg som en. `<Modal>` gir fokusfellen; `onRequestClose` er\n * Android-tilbake og ESC på tastatur; `accessibilityViewIsModal` skjuler\n * vertsappen for skjermlesere på iOS; kvitteringen er en live-region. Sentrys\n * crash-modal mangler alle fire (issue #23288, #9291) — den er leverandøren som\n * dokumenterer både løsningen og mangelen.\n *\n * **Flyten er ikke symmetrisk.** Feilsporet møter kjente feil FØR feltet: den\n * som står i en feil skal slippe å skrive noe hvis svaret allerede finnes.\n * Ønskesporet møter dem ETTER: et ønske må formuleres før det kan sammenlignes.\n *\n * **Skjermbildet (2f, K4):** tas først når innsenderen trykker, aldri ved åpning.\n * Steget finnes bare når leietakeren har skjermbilde på OG verten har gitt en\n * adapter (DD-26). Private views måles i fangstøyeblikket (DD-39). Det som\n * lastes opp er komposittet av forhåndsvisningen med maskene — rå-URI-en går\n * aldri videre. Teksten sendes først; bildet kan feile alene (DD-42).\n */\nexport function Widget({\n client,\n synlig,\n apneOpsjoner,\n onLukk,\n tenantName,\n}: {\n client: InnspelClient;\n synlig: boolean;\n apneOpsjoner?: OpenFeedbackOptions;\n onLukk: () => void;\n tenantName?: string;\n}) {\n const tema = useTema();\n const skjermbilde = useSkjermbilde();\n const previewRef = useRef<ViewRef | null>(null);\n\n const [steg, setSteg] = useState<Steg>('valg');\n const [spor, setSpor] = useState<'feil' | 'onske'>('feil');\n const [verdi, setVerdi] = useState('');\n const [kort, setKort] = useState<KnownIssueCard[]>([]);\n const [lasterKort, setLasterKort] = useState(false);\n const [lenketTil, setLenketTil] = useState<KnownIssueCard | undefined>();\n const [funn, setFunn] = useState<PatternFinding[]>([]);\n const [fjernede, setFjernede] = useState<string[]>([]);\n const [sender, setSender] = useState(false);\n const [feil, setFeil] = useState<string | undefined>();\n const [kvittering, setKvittering] = useState<{ art: KvitteringArt; nr?: string; vedlegg?: 'feilet' | 'forkastet' }>();\n const [mine, setMine] = useState<MySubmission[]>([]);\n const [lasterMine, setLasterMine] = useState(false);\n\n // Skjermbildet: rå fangst til forhåndsvisning, private views i rotens punkter,\n // og det ferdige, maskerte vedlegget som sendes med teksten.\n const [bilde, setBilde] = useState<ScreenshotCapture | undefined>();\n const [automasker, setAutomasker] = useState<MaskRect[]>([]);\n const [rotStorrelse, setRotStorrelse] = useState({ width: 1, height: 1 });\n const [komponerer, setKomponerer] = useState(false);\n const [vedlegg, setVedlegg] = useState<AttachmentInput | undefined>();\n\n // Leietakerens grenser: startverdiene fra init(), oppdatert fra plattformen ved åpning (M2.5).\n const [innstillinger, setInnstillinger] = useState({ ...client.settings });\n\n // DD-26: steget finnes ikke uten begge. Aldri en deaktivert knapp.\n const skjermbildeMulig = innstillinger.screenshotsEnabled && skjermbilde?.adapter != null;\n\n const nullstill = useCallback(() => {\n setSteg('valg');\n setSpor('feil');\n setVerdi('');\n setKort([]);\n setLenketTil(undefined);\n setFunn([]);\n setFjernede([]);\n setFeil(undefined);\n setKvittering(undefined);\n setBilde(undefined);\n setAutomasker([]);\n setVedlegg(undefined);\n setKomponerer(false);\n }, []);\n\n const lukk = useCallback(() => {\n onLukk();\n nullstill();\n }, [onLukk, nullstill]);\n\n // Køen tømmes når widgeten ÅPNES — aldri ved oppstart (DD-41). Resultatet\n // vises ikke: en flush som lykkes er ikke en hendelse innsenderen ba om.\n useEffect(() => {\n if (!synlig) return;\n client.track({ name: 'widget_opened' });\n void client.queue.flush().catch(() => undefined);\n // Konfigurasjonen er et tilbud: svarer den, oppdateres grensene; ellers står de.\n void client.loadSettings().then((s) => setInnstillinger({ ...s })).catch(() => undefined);\n\n if (apneOpsjoner?.track) velgSpor(apneOpsjoner.track);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [synlig]);\n\n const hentKort = useCallback(async () => {\n setLasterKort(true);\n try {\n const q = apneOpsjoner?.screen ? { screen: apneOpsjoner.screen } : {};\n setKort(await client.knownIssues.for(q));\n } finally {\n setLasterKort(false);\n }\n }, [client, apneOpsjoner?.screen]);\n\n const velgSpor = useCallback(\n async (valgt: 'feil' | 'onske') => {\n setSpor(valgt);\n client.track({ name: 'track_selected', type: valgt });\n\n if (valgt === 'onske') {\n // Ønskesporet skriver først; sammenligningen kommer etterpå.\n setSteg('felt');\n return;\n }\n\n setSteg('kjenteFeil');\n await hentKort();\n },\n [client, hentKort],\n );\n\n // Treffene er et tilbud, aldri en sperre (wireframe 2c): er lista tom når\n // oppslaget er ferdig, hoppes skjermen over — rett til feltet, ingen melding.\n useEffect(() => {\n if (steg === 'kjenteFeil' && !lasterKort && kort.length === 0) setSteg('felt');\n }, [steg, lasterKort, kort.length]);\n\n const endreTekst = useCallback(\n (v: string) => {\n setVerdi(v);\n setFunn(client.scanText(v));\n },\n [client],\n );\n\n /**\n * «Legg ved skjermbilde» (K4): fangsten skjer HER, ved trykket, av vertsappen\n * bak arket. Private views måles i samme øyeblikk (DD-39) og regnes om til\n * rotens punkter. Feiler fangsten, kan innsenderen sende uten.\n */\n const taSkjermbilde = useCallback(async () => {\n if (!skjermbilde?.adapter) return;\n const { adapter, rootRef, privat } = skjermbilde;\n setFeil(undefined);\n try {\n const fangst = await adapter.capture(rootRef, FANGST);\n const rot = await adapter.measure(rootRef);\n const private_ = await Promise.all(privat.refs().map((r) => adapter.measure(r)));\n if (rot) {\n setRotStorrelse({ width: rot.width, height: rot.height });\n setAutomasker(\n private_\n .filter((r): r is MaskRect => r !== null)\n .map((r) => ({ x: r.x - rot.x, y: r.y - rot.y, width: r.width, height: r.height })),\n );\n } else {\n setRotStorrelse({ width: fangst.width, height: fangst.height });\n setAutomasker([]);\n }\n setBilde(fangst);\n setSteg('skjermbilde');\n } catch {\n setFeil(tekst.skjermbildeFeilet);\n }\n }, [skjermbilde]);\n\n /**\n * «Legg ved og fortsett»: forhåndsvisningen MED maskene fanges på nytt, og det\n * er komposittet som blir vedlegget. Rå-URI-en brukes aldri etter dette.\n */\n const leggVedBilde = useCallback(async () => {\n if (!skjermbilde?.adapter) return;\n setKomponerer(true);\n try {\n const komposit = await skjermbilde.adapter.capture(previewRef, FANGST);\n const body = await skjermbilde.adapter.read(komposit.uri);\n setVedlegg({ mime: 'image/jpeg', body, width: komposit.width, height: komposit.height });\n setBilde(undefined);\n setSteg('felt');\n } catch {\n setFeil(tekst.skjermbildeFeilet);\n setSteg('felt');\n } finally {\n setKomponerer(false);\n }\n }, [skjermbilde]);\n\n const fjernBilde = useCallback(() => {\n setBilde(undefined);\n setAutomasker([]);\n setVedlegg(undefined);\n setSteg('felt');\n }, []);\n\n const send = useCallback(async () => {\n // Ønskesporet: feltet fører til kjente feil-sjekken, ikke rett til sending.\n if (spor === 'onske' && steg === 'felt' && kort.length === 0 && !lasterKort) {\n setSteg('kjenteFeil');\n await hentKort();\n return;\n }\n\n setSender(true);\n setFeil(undefined);\n try {\n const res = await client.capture({\n type: spor,\n text: verdi,\n ...(vedlegg ? { attachment: vedlegg } : {}),\n ...(spor === 'feil' && lenketTil ? { relatedKnownIssueId: lenketTil.id } : {}),\n ...(fjernede.length ? { context: fjernetKontekst(client, fjernede) } : {}),\n } as never);\n\n if (res.status === 'queued') {\n setKvittering({ art: 'kø', ...(res.attachment ? { vedlegg: 'forkastet' as const } : {}) });\n } else {\n setKvittering({\n art: spor,\n nr: res.submission.id,\n ...(res.attachment?.status === 'failed' ? { vedlegg: 'feilet' as const } : {}),\n });\n }\n setSteg('kvittering');\n } catch (e) {\n // Teksten mistes ALDRI: den står i feltet, og årsaken er i klartekst.\n if (e instanceof InnspelQueueFullError) setFeil(e.userMessage);\n else if (e instanceof InnspelApiError) setFeil(e.message);\n else setFeil('tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, spor, steg, verdi, vedlegg, lenketTil, fjernede, kort.length, lasterKort, hentKort]);\n\n const jaOgsa = useCallback(\n async (k: KnownIssueCard) => {\n setSender(true);\n try {\n const res = await client.knownIssues.confirm(k.id);\n setKvittering({ art: 'jaOgsa', nr: res.id });\n setSteg('kvittering');\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n },\n [client],\n );\n\n const visMine = useCallback(async () => {\n setSteg('mine');\n setLasterMine(true);\n try {\n setMine(await client.subjects.submissions());\n } catch {\n setMine([]);\n } finally {\n setLasterMine(false);\n }\n }, [client]);\n\n return (\n <Modal\n visible={synlig}\n transparent\n animationType=\"slide\"\n // Android-tilbake og ESC. Uten den er dialogen en felle (DD-47).\n onRequestClose={lukk}\n accessibilityViewIsModal\n >\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end' }}>\n <View\n testID=\"innspel-widget\"\n accessibilityViewIsModal\n accessibilityRole=\"none\"\n style={{\n backgroundColor: tema.color.bg,\n borderTopLeftRadius: tema.radius.lg * 2,\n borderTopRightRadius: tema.radius.lg * 2,\n padding: tema.screenPadding,\n gap: tema.space.md,\n maxHeight: '92%',\n minHeight: '60%',\n }}\n >\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>\n {steg === 'skjermbilde' ? (\n <Btn variant=\"ghost\" testID=\"tilbake\" ikon=\"←\" label={tekst.tilbake} onPress={fjernBilde} />\n ) : steg !== 'valg' && steg !== 'kvittering' ? (\n <Btn variant=\"ghost\" testID=\"tilbake\" ikon=\"←\" label={tekst.tilbake} onPress={nullstill} />\n ) : (\n <View />\n )}\n <Pressable\n testID=\"lukk\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.lukk}\n onPress={lukk}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.body }}>✕</Text>\n </Pressable>\n </View>\n\n {feil ? <Banner live ikon=\"⚠\" tone=\"danger\" children={tekst.sendefeilBanner(feil)} /> : null}\n\n {steg === 'valg' ? (\n <>\n <Valg onVelg={velgSpor} />\n <Btn variant=\"ghost\" testID=\"mine-innspill\" ikon=\"📋\" label={tekst.mineTittel} onPress={visMine} />\n </>\n ) : null}\n\n {steg === 'kjenteFeil' ? (\n <KjenteFeil\n kort={kort}\n spor={spor}\n laster={lasterKort}\n onJaOgsa={jaOgsa}\n onLigner={(k) => {\n setLenketTil(k);\n setSteg('felt');\n }}\n onNei={() => (spor === 'onske' ? void send() : setSteg('felt'))}\n />\n ) : null}\n\n {steg === 'felt' ? (\n <Felt\n spor={spor}\n verdi={verdi}\n onEndre={endreTekst}\n minTextLength={innstillinger.minTextLength}\n textMaxLength={innstillinger.textMaxLength}\n kontekst={client.context}\n fjernedeFelter={fjernede}\n onFjernKontekst={(f) => setFjernede((x) => [...x, f])}\n {...(lenketTil ? { lenketTil, onFjernLenke: () => setLenketTil(undefined) } : {})}\n funn={funn}\n onSend={send}\n sender={sender}\n {...(skjermbildeMulig ? { onSkjermbilde: taSkjermbilde } : {})}\n harVedlegg={vedlegg !== undefined}\n onFjernVedlegg={fjernBilde}\n />\n ) : null}\n\n {steg === 'skjermbilde' && bilde ? (\n <Skjermbilde\n bilde={bilde}\n automaskerRot={automasker}\n rotStorrelse={rotStorrelse}\n previewRef={previewRef}\n komponerer={komponerer}\n onFjern={fjernBilde}\n onLeggVed={leggVedBilde}\n />\n ) : null}\n\n {steg === 'kvittering' && kvittering ? (\n <Kvittering\n art={kvittering.art}\n {...(kvittering.nr ? { saksnummer: kvittering.nr } : {})}\n {...(kvittering.vedlegg ? { vedlegg: kvittering.vedlegg } : {})}\n onLukk={lukk}\n />\n ) : null}\n\n {steg === 'mine' ? (\n <MineInnspill\n rader={mine}\n laster={lasterMine}\n {...(tenantName ? { tenantName } : {})}\n onNytt={nullstill}\n />\n ) : null}\n </View>\n </View>\n </Modal>\n );\n}\n\n/**\n * Konteksten uten linjene innsenderen har fjernet (DD-05). Et fjernet felt\n * settes til `undefined` — det er slik kjernen (0.2.1) skiller «fjern» fra\n * «behold fra init»; å bare utelate nøkkelen ville fylt feltet igjen. Feltene\n * er en lukket hviteliste, så det som ikke står i `client.context` finnes ikke\n * å fjerne.\n */\nfunction fjernetKontekst(client: InnspelClient, fjernede: string[]) {\n const ut: Record<string, unknown> = {};\n for (const k of Object.keys(client.context)) {\n if (k !== 'sdkVersion' && fjernede.includes(k)) ut[k] = undefined;\n }\n return ut;\n}\n","import type { ContextInput, KnownIssueCard, PatternFinding } from '@innspel/core';\nimport React, { useMemo, useState } from 'react';\nimport { Pressable, Text, TextInput, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Btn, H, Hint } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2d + 2e — feltet og kontekstlinja. Ett felt, ingenting annet.\n *\n * DD-44: send er inaktiv under `minTextLength` (standard 10), og det er det\n * ENESTE kravet. Ingen kategori, ingen alvorlighet, ingen reproduksjonsfelt.\n * 2h i wireframen er ikke en skjerm — den er fraværet av felter her.\n *\n * DD-45: placeholderen stiller to spørsmål i feilsporet.\n *\n * DD-46: mønstervarselet vises FØR sending og fjerner aldri noe selv.\n * «Fjern» og «Behold» er innsenderens valg; teksten endres bare ved «Fjern».\n *\n * DD-05: konteksten er synlig og kan fjernes linje for linje. Den er en lukket\n * hviteliste (K5) — det som ikke står der, finnes ikke å fjerne.\n */\nexport function Felt({\n spor,\n verdi,\n onEndre,\n minTextLength,\n textMaxLength,\n kontekst,\n fjernedeFelter,\n onFjernKontekst,\n lenketTil,\n onFjernLenke,\n funn,\n onSend,\n sender,\n onSkjermbilde,\n harVedlegg,\n onFjernVedlegg,\n}: {\n spor: 'feil' | 'onske';\n verdi: string;\n onEndre: (v: string) => void;\n minTextLength: number;\n textMaxLength: number;\n kontekst: ContextInput & { sdkVersion: string };\n fjernedeFelter: string[];\n onFjernKontekst: (felt: string) => void;\n lenketTil?: KnownIssueCard;\n onFjernLenke?: () => void;\n funn: PatternFinding[];\n onSend: () => void;\n sender?: boolean;\n /**\n * «Legg ved skjermbilde» (2f, K4). Utelatt = steget finnes ikke (DD-26): leietakeren\n * har skjermbilde av, eller verten ga ingen adapter. Aldri en deaktivert knapp.\n */\n onSkjermbilde?: () => void;\n /** Et maskert skjermbilde ligger klart og sendes etter teksten (DD-42). */\n harVedlegg?: boolean;\n onFjernVedlegg?: () => void;\n}) {\n const tema = useTema();\n const [apen, setApen] = useState(false);\n const [beholdt, setBeholdt] = useState<string[]>([]);\n\n const brukt = verdi.length;\n const forKort = brukt < minTextLength;\n const full = brukt >= textMaxLength;\n // Telleren dukker opp ved 80 % — ikke før. En teller fra første tegn gjør\n // lengden til oppgaven i stedet for innholdet.\n const visTeller = brukt >= textMaxLength * 0.8;\n\n const uavklart = funn.find((f) => !beholdt.includes(f.match));\n\n const linjer = useMemo(() => {\n const etiketter: Record<string, string> = {\n screen: 'Skjerm',\n appVersion: 'Appversjon',\n platform: 'Plattform',\n os: 'OS',\n build: 'Bygg',\n locale: 'Språk',\n };\n return Object.entries(etiketter)\n .map(([felt, etikett]) => {\n const verdi = (kontekst as unknown as Record<string, string | undefined>)[felt];\n return verdi && !fjernedeFelter.includes(felt) ? { felt, etikett, verdi } : null;\n })\n .filter((x): x is { felt: string; etikett: string; verdi: string } => x !== null);\n }, [kontekst, fjernedeFelter]);\n\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n {lenketTil ? (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderInteractive,\n borderRadius: tema.radius.pill,\n paddingLeft: tema.space.md,\n paddingRight: tema.space.xs,\n }}\n >\n <Text style={{ flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }}>\n {tekst.lenketTil(lenketTil.title)}\n </Text>\n <Pressable\n testID=\"fjern-lenke\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.fjernLenke}\n onPress={onFjernLenke}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>✕</Text>\n </Pressable>\n </View>\n ) : null}\n\n {uavklart ? (\n <View\n style={{\n gap: tema.space.sm,\n backgroundColor: tema.color.warningBg,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n }}\n >\n <Text\n accessibilityRole=\"alert\"\n accessibilityLiveRegion=\"polite\"\n style={{\n color: tema.color.warning,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n fontWeight: tema.weight.medium,\n }}\n >\n {tekst.monsterSpm[uavklart.kind]}\n </Text>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n <Btn\n grow\n variant=\"secondary\"\n testID=\"monster-fjern\"\n label={tekst.monsterFjern}\n onPress={() => onEndre(verdi.slice(0, uavklart.start) + verdi.slice(uavklart.end))}\n />\n <Btn\n grow\n variant=\"ghost\"\n testID=\"monster-behold\"\n label={tekst.monsterBehold}\n onPress={() => setBeholdt((b) => [...b, uavklart.match])}\n />\n </View>\n <Hint>{tekst.monsterForklaring}</Hint>\n </View>\n ) : null}\n\n <H>{spor === 'onske' ? tekst.feltLabelOnske : tekst.feltLabelFeil}</H>\n\n <TextInput\n testID=\"innspill-tekst\"\n accessibilityLabel={spor === 'onske' ? tekst.feltLabelOnske : tekst.feltLabelFeil}\n value={verdi}\n onChangeText={onEndre}\n maxLength={textMaxLength}\n multiline\n numberOfLines={4}\n placeholder={spor === 'onske' ? tekst.placeholderOnske : tekst.placeholderFeil}\n placeholderTextColor={tema.color.textMuted}\n style={{\n backgroundColor: tema.color.surfaceRaised,\n borderWidth: tema.hairline,\n borderColor: full ? tema.color.warning : tema.color.borderStrong,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n minHeight: tema.touch * 2,\n textAlignVertical: 'top',\n }}\n />\n\n {visTeller ? (\n <Text\n testID=\"teller\"\n accessibilityLiveRegion={full ? 'assertive' : 'polite'}\n style={{\n alignSelf: 'flex-end',\n color: full ? tema.color.warning : tema.color.textMuted,\n fontSize: tema.font.small,\n }}\n >\n {brukt} / {textMaxLength}\n {full ? tekst.tellerFull : ''}\n </Text>\n ) : null}\n\n {/* 2f — opt-in per innsending. Bildet tas først ved trykk (K4). */}\n {harVedlegg ? (\n <View\n testID=\"vedlegg-chip\"\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderInteractive,\n borderRadius: tema.radius.pill,\n paddingLeft: tema.space.md,\n paddingRight: tema.space.xs,\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.small }}>\n 📷\n </Text>\n <Text style={{ flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }}>{tekst.skjermbildeLagtVed}</Text>\n <Pressable\n testID=\"fjern-vedlegg\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.fjernSkjermbilde}\n onPress={onFjernVedlegg}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>✕</Text>\n </Pressable>\n </View>\n ) : onSkjermbilde ? (\n <Btn\n variant=\"secondary\"\n testID=\"legg-ved-skjermbilde\"\n ikon=\"📷\"\n label={tekst.leggVedSkjermbilde}\n hint={tekst.leggVedHint}\n onPress={onSkjermbilde}\n />\n ) : null}\n\n {/* 2e — synlig, ikke skjult (DD-05) */}\n <View style={{ borderTopWidth: tema.hairline, borderTopColor: tema.color.border, paddingTop: tema.space.sm }}>\n <Pressable\n testID=\"kontekst-bryter\"\n accessibilityRole=\"button\"\n accessibilityState={{ expanded: apen }}\n accessibilityLabel={`${tekst.kontekstLinje}${apen ? '' : tekst.kontekstVis}`}\n onPress={() => setApen((a) => !a)}\n style={{ minHeight: tema.touch, justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>\n {apen ? '▴' : '▾'} {tekst.kontekstLinje}\n {apen ? '' : tekst.kontekstVis}\n </Text>\n </Pressable>\n\n {apen ? (\n <View>\n {linjer.map((l) => (\n <View\n key={l.felt}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch,\n borderBottomWidth: tema.hairline,\n borderBottomColor: tema.color.border,\n }}\n >\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, minWidth: tema.touch * 2 }}>\n {l.etikett}\n </Text>\n <Text style={{ flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }}>{l.verdi}</Text>\n <Pressable\n testID={`fjern-${l.felt}`}\n accessibilityRole=\"button\"\n accessibilityLabel={`${tekst.kontekstFjern} ${l.etikett.toLowerCase()} fra innsendingen`}\n onPress={() => onFjernKontekst(l.felt)}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>\n ✕ {tekst.kontekstFjern}\n </Text>\n </Pressable>\n </View>\n ))}\n <View style={{ paddingTop: tema.space.sm }}>\n <Hint>{tekst.kontekstAldri}</Hint>\n </View>\n </View>\n ) : null}\n </View>\n\n <View style={{ flex: 1, justifyContent: 'flex-end' }}>\n <Btn\n testID=\"send\"\n label={spor === 'onske' && !forKort ? tekst.nesteOnske : tekst.send}\n disabled={forKort || sender}\n hint={forKort ? tekst.forKort(minTextLength) : harVedlegg ? tekst.sendHintMedBilde : undefined}\n onPress={onSend}\n />\n </View>\n </View>\n );\n}\n","import React from 'react';\nimport { Pressable, Text, View, type StyleProp, type ViewStyle } from 'react-native';\nimport { useTema } from '../tema.js';\n\n/**\n * Primitivene widgeten er bygget av. Alt visuelt kommer fra tema-tokens —\n * ingen hex, ingen px, ingen fontstørrelse skrives her (CLAUDE.md, «Styling»).\n *\n * Minste trykkflate er `skala.touch` (48). Den er ikke en anbefaling: den er\n * grønt-kriterium for widgeten, og en knapp under målet er en feil.\n */\n\ntype Variant = 'primary' | 'secondary' | 'ghost' | 'danger';\n\nexport function Btn({\n label,\n onPress,\n variant = 'primary',\n ikon,\n hint,\n disabled,\n accessibilityLabel,\n grow,\n testID,\n}: {\n label: string;\n onPress?: () => void;\n variant?: Variant;\n ikon?: string;\n hint?: string;\n disabled?: boolean;\n accessibilityLabel?: string;\n grow?: boolean;\n testID?: string;\n}) {\n const tema = useTema();\n const c = tema.color;\n\n const bakgrunn =\n variant === 'primary' ? c.actionPrimary : variant === 'secondary' ? c.surfaceRaised : 'transparent';\n const tekstfarge =\n variant === 'primary' ? c.onActionPrimary : variant === 'danger' ? c.danger : c.actionSecondaryText;\n const kant = variant === 'ghost' ? 'transparent' : variant === 'primary' ? c.actionPrimary : c.actionSecondaryBorder;\n\n return (\n <View style={grow ? { flex: 1 } : undefined}>\n <Pressable\n testID={testID}\n accessibilityRole=\"button\"\n // Hintet er synlig tekst OG del av etiketten: en skjermleserbruker skal\n // få vite hvorfor knappen er inaktiv uten å lete etter teksten under.\n accessibilityLabel={accessibilityLabel ?? (hint ? `${label}. ${hint}` : label)}\n accessibilityState={{ disabled: !!disabled }}\n disabled={disabled}\n onPress={onPress}\n style={{\n minHeight: tema.touch,\n borderRadius: tema.radius.md,\n borderWidth: tema.hairline,\n borderColor: kant,\n backgroundColor: disabled ? c.surface : bakgrunn,\n paddingHorizontal: tema.space.md,\n alignItems: 'center',\n justifyContent: 'center',\n flexDirection: 'row',\n gap: tema.space.sm,\n opacity: disabled ? 0.6 : 1,\n }}\n >\n {ikon ? (\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.body }}>\n {ikon}\n </Text>\n ) : null}\n <Text\n style={{\n color: disabled ? c.textDisabled : tekstfarge,\n fontSize: tema.font.body,\n fontWeight: tema.weight.semibold,\n }}\n >\n {label}\n </Text>\n </Pressable>\n {hint ? <Hint>{hint}</Hint> : null}\n </View>\n );\n}\n\nexport function H({ children, sub }: { children: string; sub?: string }) {\n const tema = useTema();\n return (\n <View style={{ gap: tema.space.xs }}>\n <Text\n accessibilityRole=\"header\"\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.h2,\n lineHeight: tema.lineHeight.h2,\n fontWeight: tema.weight.semibold,\n }}\n >\n {children}\n </Text>\n {sub ? (\n <Text\n style={{\n color: tema.color.textSecondary,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {sub}\n </Text>\n ) : null}\n </View>\n );\n}\n\nexport function Hint({ children }: { children: React.ReactNode }) {\n const tema = useTema();\n return (\n <Text\n style={{\n color: tema.color.textMuted,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {children}\n </Text>\n );\n}\n\nexport function Card({\n children,\n dashed,\n style,\n}: {\n children: React.ReactNode;\n dashed?: boolean;\n style?: StyleProp<ViewStyle>;\n}) {\n const tema = useTema();\n return (\n <View\n style={[\n {\n backgroundColor: tema.color.surface,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.border,\n borderStyle: dashed ? 'dashed' : 'solid',\n padding: tema.space.md,\n gap: tema.space.sm,\n },\n style,\n ]}\n >\n {children}\n </View>\n );\n}\n\n/**\n * Status som ikon + etikett. Fargen er et TILLEGG, aldri bæreren: to av\n * palettens statusfarger er målt til under 1,5 i innbyrdes kontrast, så\n * etiketten er det som faktisk skiller dem (DD-08).\n */\nexport function StatusPill({\n ikon,\n etikett,\n farge,\n}: {\n ikon: string;\n etikett: string;\n farge: 'info' | 'success' | 'warning' | 'neutral' | 'danger';\n}) {\n const tema = useTema();\n return (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.xs,\n alignSelf: 'flex-start',\n paddingHorizontal: tema.space.sm,\n paddingVertical: tema.space.xs,\n borderRadius: tema.radius.pill,\n backgroundColor: tema.color[`${farge}Bg` as keyof typeof tema.color],\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.small }}>\n {ikon}\n </Text>\n <Text style={{ color: tema.color[farge], fontSize: tema.font.small, fontWeight: tema.weight.medium }}>\n {etikett}\n </Text>\n </View>\n );\n}\n\n/**\n * Varsel. Rollen ligger på `Text`, ikke på containeren: `accessible` på en\n * container sluker barna som egne fokusstopp (`tdd-contract-validation`).\n */\nexport function Banner({\n ikon,\n tone,\n children,\n live,\n}: {\n ikon: string;\n tone: 'info' | 'warning' | 'danger' | 'success';\n children: string;\n live?: boolean;\n}) {\n const tema = useTema();\n return (\n <View\n style={{\n flexDirection: 'row',\n gap: tema.space.sm,\n backgroundColor: tema.color[`${tone}Bg` as keyof typeof tema.color],\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.body }}>\n {ikon}\n </Text>\n <Text\n accessibilityRole=\"alert\"\n accessibilityLiveRegion={live ? 'polite' : 'none'}\n style={{\n flex: 1,\n color: tema.color[tone],\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {children}\n </Text>\n </View>\n );\n}\n","/**\n * Hver streng innsenderen ser, ett sted.\n *\n * Ordlyden er ikke fri: den er tegnet i `design/wireframes/innsending-widget.jsx`\n * og bundet av beslutninger. Løftene under er DD-08 og skal stå ORDRETT likt i\n * SDK-et og i panelet — en innsender som får «Svar innen 3. desember» i appen og\n * noe annet i portalen har fått to løfter.\n *\n * Norsk bokmål. Ingen leietakernavn: strengen som nevner avsenderen tar navnet\n * som parameter, siden pakken skal kunne brukes av hvem som helst.\n */\nexport const tekst = {\n // 2b — første valg\n valgTittel: 'Hva gjelder det?',\n valgUnder: 'Ett valg. Vi spør aldri om kategori eller alvorlighet.',\n sporFeil: 'Noe virker ikke',\n sporFeilUnder: 'Feilsporet — kontekst legges ved',\n sporOnske: 'Jeg ønsker meg noe',\n sporOnskeUnder: 'Ønskesporet — aldri spørsmål om reproduksjon',\n\n // 2c — kjente feil (DD-29, DD-30)\n kjenteFeilTittelFeil: 'Er det dette du ser?',\n kjenteFeilUnderFeil: '«Ja» registrerer deg på saken. «Ligner» sender ditt eget med lenke.',\n kjenteFeilTittelOnske: 'Har noen ønsket dette?',\n kjenteFeilUnderOnske: 'Ett trykk legger deg til på ønsket — ingen ny sak.',\n svarJa: 'Ja, jeg også',\n svarLigner: 'Ligner, men ikke helt',\n svarNei: 'Nei, det er noe annet',\n omvei: 'Omvei:',\n rettesI: (versjon: string) => `Rettes i ${versjon}`,\n rettetI: (versjon: string) => `Rettet i ${versjon}`,\n\n // 2d + 2e — feltet og kontekstlinja\n feltLabelFeil: 'Din feil',\n feltLabelOnske: 'Ditt ønske',\n /** DD-45: to spørsmål i feilsporet. Kilde: Sentry «What's the bug? What did you expect?» */\n placeholderFeil: 'Hva skjedde? Hva forventet du?',\n placeholderOnske: 'Hva ønsker du deg?',\n send: 'Send',\n nesteOnske: 'Neste — sjekk om noen har ønsket dette',\n /** DD-44: minimum tegn er det ENESTE kravet. */\n forKort: (min: number) => `Minst ${min} tegn. Ingenting annet er obligatorisk.`,\n tellerFull: ' — kort og konkret holder',\n kontekstLinje: 'Legges ved: skjerm, appversjon, plattform, OS',\n kontekstVis: ' — Vis',\n kontekstFjern: 'Fjern',\n kontekstAldri:\n 'Aldri: navn, e-post, telefon, posisjon eller det som står på skjermen.',\n lenketTil: (tittel: string) => `Lenket til: «${tittel}»`,\n fjernLenke: 'Fjern lenken til den kjente feilen',\n\n // 2f — skjermbilde (K4, DD-39, DD-40, DD-42)\n leggVedSkjermbilde: 'Legg ved skjermbilde',\n leggVedHint: 'Bildet tas først når du trykker — du ser det før det sendes.',\n skjermbildeTittel: 'Se over bildet',\n skjermbildeUnder: 'Bildet ble tatt da du trykket. Det du maskerer, ser vi aldri.',\n maskering: 'Maskering',\n maskerFelt: 'Masker felt',\n tegnOver: 'Tegn over',\n maskerAllTekst: 'Masker all tekst',\n maskertAvAppen: 'Maskert av appen',\n maskertAvAppenHint: 'Registrert privat view. Penselen kan ikke oppheve den.',\n dittStrok: '▲ ditt strøk — maskert (kan angres med ett trykk)',\n allTekstHint: 'Hele bildet er gjort uskarpt så tekst ikke kan leses. Layouten er synlig.',\n fjernBildet: 'Fjern bildet',\n leggVedOgFortsett: 'Legg ved og fortsett',\n leggVedHintDD42: 'Teksten sendes først; bildet lastes opp for seg.',\n skjermbildeLagtVed: 'Skjermbilde lagt ved — maskert',\n fjernSkjermbilde: 'Fjern skjermbildet',\n sendHintMedBilde: 'Teksten sendes først; bildet lastes opp for seg.',\n skjermbildeFeilet: 'kunne ikke ta skjermbilde. Du kan sende uten.',\n skjermbildeA11y: (auto: number, egne: number, uskarpt: boolean) =>\n `Forhåndsvisning av skjermbildet. ${auto ? `${auto} felt maskert av appen og kan ikke avmaskeres. ` : ''}${egne ? `${egne} felt maskert av deg. ` : ''}${uskarpt ? 'All tekst er gjort uskarp. ' : ''}Trykk for å maskere et felt, dra for å tegne over.`,\n\n // DD-46 — mønstervarsel. Aldri stille redaksjon.\n monsterSpm: {\n email: 'Dette ser ut som en e-postadresse. Vil du fjerne den?',\n phone: 'Dette ser ut som et telefonnummer. Vil du fjerne det?',\n card: 'Dette ser ut som et kortnummer. Vil du fjerne det?',\n ip: 'Dette ser ut som en IP-adresse. Vil du fjerne den?',\n token: 'Dette ser ut som en tilgangsnøkkel. Vil du fjerne den?',\n },\n monsterFjern: 'Fjern',\n monsterBehold: 'Behold',\n monsterForklaring: 'Teksten endres bare hvis du trykker Fjern. Vi fjerner aldri noe stille.',\n\n // 2g — kvittering\n kvitteringSendt: 'Sendt',\n kvitteringRegistrert: 'Registrert',\n kvitteringFeil: 'Du får beskjed når den er rettet, eller hvis vi trenger mer.',\n kvitteringOnske:\n 'Vurderes innen 90 dager. Du får et personlig svar — også hvis det er nei.',\n kvitteringJaOgsa: 'Du får beskjed når den er rettet.',\n saksnummer: (nr: string) => `Saksnummer ${nr} — vis dette hvis du spør support.`,\n tilbakeTilAppen: 'Tilbake til appen',\n /** DD-42: saken er sendt, bildet kom ikke med — aldri en blokkert innsending. */\n kvitteringVedleggFeilet: 'Sendt — skjermbildet kunne ikke legges ved',\n tekstenErLagret: 'Teksten din er lagret.',\n vedleggFeiletBanner: 'Bildet ble ikke lastet opp. Saken er sendt uten det — vil du, kan du sende et nytt innspill med bilde.',\n saksnummerUtenVedlegg: (nr: string) => `Saksnummer ${nr} · uten vedlegg`,\n\n // 2i — tilstander\n offlineTittel: 'Ingen nett',\n offlineBanner:\n 'Ingen nett. Lagres og sendes automatisk — du ser det under «Mine innspill» til det er sendt.',\n offlineLagre: 'Lagre — sendes automatisk',\n /** DD-41: et skjermbilde køes aldri. */\n offlineUtenBilde: 'Skjermbilde kan ikke legges ved uten nett. Teksten sendes; bildet ble ikke lagret.',\n sendefeilBanner: (arsak: string) => `Kunne ikke sende: ${arsak} Teksten din er beholdt.`,\n provIgjen: 'Prøv igjen',\n\n // 2j — mine innspill\n mineTittel: 'Mine innspill',\n mineUnder: 'Status og hva du kan vente deg — samme løfte som i kvitteringen.',\n mineTom: 'Du har ikke sendt noe ennå.',\n mineIkkeSendt: 'Ikke sendt ennå',\n mineSak: (nr: string) => `Sak ${nr}`,\n svarFra: (leietaker: string) => `Svar fra ${leietaker}`,\n svarFraGenerisk: 'Svar',\n sendNytt: 'Send nytt innspill',\n\n // 3a — invitasjonsbanneret (DD-12)\n invitasjonRegion: 'Invitasjon til betaprogram',\n invitasjonHva: (navn: string) => `Vil du teste «${navn}»?`,\n invitasjonKontakter: (maks: number) =>\n `Vi tar kontakt maks ${maks} ganger. Du kan gå ut når som helst.`,\n lesMer: 'Les mer og bli med',\n avvisInvitasjon: 'Avvis invitasjonen',\n\n // 3b — aksepten (DD-13, DD-32, DD-37)\n akseptHva: 'Hva testes',\n /** DD-32: tallene på én linje, FØR forklaringen — N oppgaver · ca. M min hver · dato–dato · maks K kontakter. */\n akseptTall: (oppgaver: number, minutter: number, periode: string, kontakter: number) =>\n `${oppgaver} oppgaver · ca. ${minutter} min hver · ${periode} · maks ${kontakter} kontakter`,\n akseptOppgaver: 'Hva vi ber om',\n akseptOppgaveTid: (minutter: number) => `ca. ${minutter} min`,\n akseptKjenteFeil: (antall: number) => `Kjente feil (${antall})`,\n akseptKjenteFeilUnder: 'Disse trenger du ikke melde — vi vet om dem.',\n akseptInnsamling: 'Hva som samles inn',\n akseptInnsamlingTekst:\n 'Skjerm, appversjon, plattform, OS og hva du svarer. Aldri navn, e-post, telefon eller posisjon.',\n akseptVilkar: 'Les vilkårene (åpnes i nettleser)',\n akseptVilkarHint: 'Bare en lenke. Ingen avkryssing, ingen signatur — «Bli med» binder deg ikke til noe.',\n akseptIngenVilkar:\n 'Ingen vilkår, ingen avtale — plattformen kjenner ikke navnet ditt og kan ikke inngå én.',\n akseptUtgang: 'Du kan gå ut når som helst — herfra.',\n bliMed: 'Bli med',\n bliMedHint: 'Samtykket gjelder bare dette programmet.',\n /** DD-12: tokenet er engangs og kom i leietakerens egen kanal — plattformen sender aldri. */\n bliMedUtenToken: 'Åpne lenken vi sendte deg for å bli med.',\n akseptFeil: (arsak: string) => `Kunne ikke bli med: ${arsak}`,\n\n // 3c (M3.1-delen) — deltakelsen og «Gå ut» (DD-36)\n deltakelseRegion: 'Ditt betaprogram',\n deltakelsePeriode: (periode: string, brukt: number, maks: number) =>\n `${periode} · ${brukt} av ${maks} kontakter brukt`,\n deltakelseOppgaverKommer: 'Oppgavene kan gjøres når det passer deg.',\n gaaUt: 'Gå ut av programmet',\n gaaUtTittel: 'Gå ut av programmet?',\n gaaUtTekst: (navn: string) =>\n `Du tas ut av testgruppen med en gang. «${navn}» slås av for deg, og vi tar ikke kontakt igjen. Det du allerede har svart, beholdes.`,\n bliVaerende: 'Bli værende',\n gaaUtBekreft: 'Gå ut',\n\n // Felles\n tilbake: 'Tilbake',\n lukk: 'Lukk',\n venterPaaNett: 'Venter på nett — sendes automatisk',\n} as const;\n\n/**\n * Løftet per status (DD-08). Samme streng i SDK og panel. Det eneste tidsløftet\n * er svarfristen som DATO (DD-28) — aldri «innen X dager», som ville betydd noe\n * nytt hver gang innsenderen leser det.\n */\nexport const lofte = {\n venterNett: 'Sendes automatisk når du er på nett — kvitteringen kommer da.',\n vurderes: (frist: string) => `Svar innen ${frist} — også hvis det er nei.`,\n vurderesUtenFrist: 'Du får svar — også hvis det er nei.',\n bygges: 'Du får beskjed når den er rettet.',\n planlagt: 'Du får beskjed når den er rettet.',\n rettet: 'Ferdig. Ser du feilen igjen, send et nytt innspill.',\n levert: 'Ferdig. Takk for ønsket.',\n ny: 'Vi har fått den. Du hører fra oss.',\n kjentFeil: 'Kjent feil. Du får beskjed når den er rettet.',\n duplikat: 'Slått sammen med et innspill som ligner.',\n avvist: 'Vi har svart på denne.',\n} as const;\n","import React from 'react';\nimport { Pressable, Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { H } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2b — første valg. To flater, hele nedre halvdel, ikon og tekst.\n *\n * DD-02: ALDRI et tredje valg, og aldri spørsmål om kategori eller\n * alvorlighet. Valget her styrer alt etterpå: feilsporet får kjente feil FØR\n * feltet og kan bære koblingsnøkler, ønskesporet får dem etter og kan ikke.\n */\nexport function Valg({ onVelg }: { onVelg: (spor: 'feil' | 'onske') => void }) {\n const tema = useTema();\n\n const flate = (spor: 'feil' | 'onske', ikon: string, label: string, under: string) => (\n <Pressable\n testID={`spor-${spor}`}\n accessibilityRole=\"button\"\n accessibilityLabel={`${label}. ${under}`}\n onPress={() => onVelg(spor)}\n style={{\n flex: 1,\n minHeight: tema.touch * 3,\n backgroundColor: tema.color.surface,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderStrong,\n borderRadius: tema.radius.lg,\n alignItems: 'center',\n justifyContent: 'center',\n gap: tema.space.sm,\n padding: tema.space.md,\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.h1 }}>\n {ikon}\n </Text>\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.h3,\n fontWeight: tema.weight.semibold,\n textAlign: 'center',\n }}\n >\n {label}\n </Text>\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, textAlign: 'center' }}>\n {under}\n </Text>\n </Pressable>\n );\n\n return (\n <View style={{ flex: 1, gap: tema.space.lg }}>\n <H sub={tekst.valgUnder}>{tekst.valgTittel}</H>\n <View style={{ flex: 1, justifyContent: 'flex-end' }}>\n <View style={{ flexDirection: 'row', gap: tema.space.md }}>\n {flate('feil', '🐞', tekst.sporFeil, tekst.sporFeilUnder)}\n {flate('onske', '💡', tekst.sporOnske, tekst.sporOnskeUnder)}\n </View>\n </View>\n </View>\n );\n}\n","import type { KnownIssueCard } from '@innspel/core';\nimport React from 'react';\nimport { ActivityIndicator, Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Btn, Card, H, StatusPill } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2c — kjente feil. Differensiatoren: vises FØR feltet i feilsporet, ETTER i\n * ønskesporet.\n *\n * DD-29 gir kortet TRE svar, ikke to: «Ja, jeg også» (Reach +1, ingen ny sak) ·\n * «Ligner, men ikke helt» (eget innspill med lenke, uten tvunget match) · «Nei,\n * det er noe annet» (vanlig innsending). Det midterste er hele poenget — uten\n * det tvinger man et valg mellom å bli talt feil og å ikke bli talt.\n *\n * Tilgjengelighet: kortet er IKKE én knapp. Tre svar må være tre fokusstopp,\n * og `accessible` på kortcontaineren ville slukt dem. I stedet bærer hver\n * knapp kortets tittel i etiketten, så en skjermleserbruker som lander på «Ja,\n * jeg også» vet hvilken feil svaret gjelder. Se `docs/sdk`-notatet i PR-en:\n * `tdd-contract-validation` sa «ett kort = én knapp», skrevet før DD-29.\n *\n * Treffene er et tilbud, aldri en sperre: feiler oppslaget eller er lista tom,\n * hoppes skjermen over uten melding. Det håndteres i Widget, ikke her.\n */\nexport function KjenteFeil({\n kort,\n spor,\n laster,\n onJaOgsa,\n onLigner,\n onNei,\n}: {\n kort: KnownIssueCard[];\n spor: 'feil' | 'onske';\n laster?: boolean;\n onJaOgsa: (k: KnownIssueCard) => void;\n onLigner: (k: KnownIssueCard) => void;\n onNei: () => void;\n}) {\n const tema = useTema();\n\n if (laster) {\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n <H sub={spor === 'onske' ? tekst.kjenteFeilUnderOnske : tekst.kjenteFeilUnderFeil}>\n {spor === 'onske' ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil}\n </H>\n <ActivityIndicator accessibilityLabel=\"Sjekker kjente feil\" color={tema.color.textSecondary} />\n </View>\n );\n }\n\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n <H sub={spor === 'onske' ? tekst.kjenteFeilUnderOnske : tekst.kjenteFeilUnderFeil}>\n {spor === 'onske' ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil}\n </H>\n\n {kort.map((k) => {\n // DD-30: «Rettes i X» når aktiv, «Rettet i X» når fikset.\n const versjon = k.fixedIn\n ? k.status === 'fikset'\n ? tekst.rettetI(k.fixedIn)\n : tekst.rettesI(k.fixedIn)\n : undefined;\n const kontekst = versjon ? `${k.title}. ${versjon}` : k.title;\n\n return (\n <Card key={k.id}>\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: tema.weight.medium,\n }}\n >\n {k.title}\n </Text>\n\n {k.workaround ? (\n <Text\n style={{\n color: tema.color.textSecondary,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {tekst.omvei} {k.workaround}\n </Text>\n ) : null}\n\n {versjon ? (\n <StatusPill\n ikon={k.status === 'fikset' ? '✓' : '🔧'}\n etikett={versjon}\n farge={k.status === 'fikset' ? 'success' : 'info'}\n />\n ) : null}\n\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n <Btn\n grow\n testID={`ja-ogsa-${k.id}`}\n label={tekst.svarJa}\n accessibilityLabel={`${tekst.svarJa}. ${kontekst}`}\n onPress={() => onJaOgsa(k)}\n />\n <Btn\n grow\n variant=\"secondary\"\n testID={`ligner-${k.id}`}\n label={tekst.svarLigner}\n accessibilityLabel={`${tekst.svarLigner}. ${kontekst}`}\n onPress={() => onLigner(k)}\n />\n </View>\n </Card>\n );\n })}\n\n <Btn variant=\"secondary\" testID=\"nei-noe-annet\" label={tekst.svarNei} onPress={onNei} />\n </View>\n );\n}\n","import React from 'react';\nimport { Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, H, Hint } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\nexport type KvitteringArt = 'feil' | 'onske' | 'jaOgsa' | 'kø';\n\n/**\n * 2g — kvitteringen. Den LOVER noe, per spor (DD-07), og saksnummeret er der\n * så innsenderen kan vise til det hos support.\n *\n * Ingen «vurder appen». Ingen oppfordring til å dele. Innsenderen har nettopp\n * gjort oss en tjeneste — å be om en til er å ta betalt for den.\n *\n * DD-42: feilet vedlegget, er saken likevel sendt. Overskriften sier det rett\n * ut, løftet står, og saksnummeret merkes «uten vedlegg». Køet offline med et\n * skjermbilde: teksten sendes senere, bildet ble aldri køet (DD-41).\n *\n * DD-47: `accessibilityLiveRegion` og rolle `alert` på TEKSTEN, slik at en\n * skjermleser leser kvitteringen når den kommer, uten at brukeren må lete.\n */\nexport function Kvittering({\n art,\n saksnummer,\n vedlegg,\n onLukk,\n}: {\n art: KvitteringArt;\n saksnummer?: string;\n /** `feilet`: teksten er lagret, bildet kom ikke med. `forkastet`: køet offline uten bilde. */\n vedlegg?: 'feilet' | 'forkastet';\n onLukk: () => void;\n}) {\n const tema = useTema();\n\n const innhold = {\n feil: { h: tekst.kvitteringSendt, p: tekst.kvitteringFeil },\n onske: { h: tekst.kvitteringSendt, p: tekst.kvitteringOnske },\n jaOgsa: { h: tekst.kvitteringRegistrert, p: tekst.kvitteringJaOgsa },\n // Køet offline: kvitteringen kan IKKE love svar på noe som ikke er sendt\n // (DD-41 presiserer DD-07). Den lover bare at det sendes.\n kø: { h: tekst.offlineTittel, p: tekst.offlineBanner },\n }[art];\n\n const overskrift = vedlegg === 'feilet' ? tekst.kvitteringVedleggFeilet : innhold.h;\n const brodtekst = vedlegg === 'feilet' ? `${tekst.tekstenErLagret} ${innhold.p}` : innhold.p;\n\n return (\n <View style={{ flex: 1, justifyContent: 'center', gap: tema.space.lg }}>\n <View style={{ alignItems: 'center', gap: tema.space.md }}>\n <Text\n accessibilityElementsHidden\n importantForAccessibility=\"no\"\n style={{ fontSize: tema.font.h1 * 2, color: art === 'kø' ? tema.color.neutral : tema.color.success }}\n >\n {art === 'kø' ? '⇅' : '✓'}\n </Text>\n\n <H>{overskrift}</H>\n\n {vedlegg === 'feilet' ? <Banner ikon=\"⚠\" tone=\"warning\" children={tekst.vedleggFeiletBanner} /> : null}\n {vedlegg === 'forkastet' ? <Banner ikon=\"📷\" tone=\"info\" children={tekst.offlineUtenBilde} /> : null}\n\n <Text\n testID=\"kvittering-tekst\"\n accessibilityRole=\"alert\"\n accessibilityLiveRegion=\"polite\"\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n textAlign: 'center',\n }}\n >\n {brodtekst}\n </Text>\n\n {saksnummer ? (\n <Hint>{vedlegg === 'feilet' ? tekst.saksnummerUtenVedlegg(saksnummer) : tekst.saksnummer(saksnummer)}</Hint>\n ) : null}\n </View>\n\n <Btn testID=\"tilbake-til-appen\" label={tekst.tilbakeTilAppen} onPress={onLukk} />\n </View>\n );\n}\n","import type { MySubmission } from '@innspel/core';\nimport React from 'react';\nimport { ActivityIndicator, ScrollView, Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Btn, Card, H, Hint, StatusPill } from './primitiver.js';\nimport { statusVisning, venterVisning } from './status.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2j — «Mine innspill» (DD-27).\n *\n * To ting skjer her som ikke skjer noe annet sted:\n *\n * - **Offline-køen er synlig** (DD-41). Raden som venter på nett står øverst,\n * uten saksnummer, med «Venter på nett — sendes automatisk». Shake er den\n * eneste leverandøren som viser dette til brukeren; alle andre skjuler køen,\n * og en usynlig kø er ikke til å skille fra tapt tekst.\n * - **Svaret står under saken**, ordrett som i panelet. Innsenderen skal ikke\n * måtte lete etter svaret i en e-post som aldri kom — plattformen sender\n * ingen e-post (K14).\n */\nexport function MineInnspill({\n rader,\n laster,\n tenantName,\n onNytt,\n}: {\n rader: MySubmission[];\n laster?: boolean;\n tenantName?: string;\n onNytt: () => void;\n}) {\n const tema = useTema();\n\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n <H sub={tekst.mineUnder}>{tekst.mineTittel}</H>\n\n {laster ? (\n <ActivityIndicator accessibilityLabel=\"Henter innspillene dine\" color={tema.color.textSecondary} />\n ) : rader.length === 0 ? (\n <Hint>{tekst.mineTom}</Hint>\n ) : (\n <ScrollView style={{ flex: 1 }} contentContainerStyle={{ gap: tema.space.sm }}>\n {rader.map((rad) => {\n const venter = rad.pending === true;\n const v = venter ? venterVisning : statusVisning(rad.status, rad.type, rad.deadlineAt);\n const nokkel = venter ? rad.clientRef : rad.id;\n const svar = venter ? undefined : rad.reply;\n\n return (\n <Card key={nokkel} dashed={venter}>\n <Hint>\n {venter ? tekst.mineIkkeSendt : tekst.mineSak(rad.id)} ·{' '}\n {rad.type === 'onske' ? 'ønske' : 'feil'}\n </Hint>\n\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n }}\n >\n {rad.text}\n </Text>\n\n <View style={{ gap: tema.space.xs }}>\n <StatusPill ikon={v.ikon} etikett={v.etikett} farge={v.farge} />\n <Hint>{v.lofte}</Hint>\n </View>\n\n {svar ? (\n <View\n style={{\n borderLeftWidth: tema.hairline * 2,\n borderLeftColor: tema.color.brand,\n paddingLeft: tema.space.sm,\n gap: tema.space.xs,\n }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>\n {tenantName ? tekst.svarFra(tenantName) : tekst.svarFraGenerisk}\n </Text>\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {svar.text}\n </Text>\n </View>\n ) : null}\n </Card>\n );\n })}\n </ScrollView>\n )}\n\n <Btn testID=\"send-nytt\" label={tekst.sendNytt} onPress={onNytt} />\n </View>\n );\n}\n","import type { SubmissionStatus, SubmissionStatusView, SubmissionType } from '@innspel/core';\nimport { lofte, tekst } from './tekster.js';\n\n/**\n * DD-22: `complete` heter «Rettet» i feilsporet og «Levert» i ønskesporet —\n * samme maskinstatus, to navn. Klienten velger navnet; serveren gjør det ikke.\n *\n * DD-08 / «Styling» i CLAUDE.md: **farge bærer aldri mening alene.** Hver status\n * har ikon OG tekstetikett. `brand ↔ info` og `brand ↔ danger` er målt til under\n * 1,5 i kontrast mot hverandre av tema-generatoren — to statuser er altså ikke\n * skillbare på farge for alle, og etiketten er det som faktisk bærer meningen.\n */\nexport interface StatusVisning {\n ikon: string;\n etikett: string;\n /** Tokennavn i den aktive paletten, ikke en farge. */\n farge: 'info' | 'success' | 'warning' | 'neutral' | 'danger';\n lofte: string;\n}\n\nconst IKON: Record<SubmissionStatus | 'venterNett', string> = {\n ny: '⏱',\n vurderes: '⏱',\n planlagt: '📅',\n bygges: '🔧',\n levert: '✓',\n kjent_feil: '👁',\n duplikat: '✕',\n avvist: '✕',\n venterNett: '⏳',\n};\n\n/** Norsk dato uten klokkeslett — fristen er en dato, ikke et tidspunkt (DD-28). */\nexport function formaterFrist(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n return new Intl.DateTimeFormat('nb-NO', { day: 'numeric', month: 'long' }).format(d);\n}\n\n/**\n * Oversetter en innsending til det innsenderen skal se.\n *\n * @param status Maskinens status fra kontrakten.\n * @param type Sporet — avgjør «Rettet» mot «Levert» (DD-22).\n * @param deadlineAt Svarfristen, satt kun i `vurderes`.\n */\nexport function statusVisning(\n status: SubmissionStatus,\n type: SubmissionType,\n deadlineAt?: string,\n): StatusVisning {\n switch (status) {\n case 'ny':\n return { ikon: IKON.ny, etikett: 'Mottatt', farge: 'neutral', lofte: lofte.ny };\n case 'vurderes':\n return {\n ikon: IKON.vurderes,\n etikett: 'Vurderes',\n farge: 'warning',\n lofte: deadlineAt ? lofte.vurderes(formaterFrist(deadlineAt)) : lofte.vurderesUtenFrist,\n };\n case 'planlagt':\n return { ikon: IKON.planlagt, etikett: 'Planlagt', farge: 'success', lofte: lofte.planlagt };\n case 'bygges':\n return { ikon: IKON.bygges, etikett: 'Retter nå', farge: 'info', lofte: lofte.bygges };\n case 'levert':\n return type === 'onske'\n ? { ikon: IKON.levert, etikett: 'Levert', farge: 'success', lofte: lofte.levert }\n : { ikon: IKON.levert, etikett: 'Rettet', farge: 'success', lofte: lofte.rettet };\n case 'kjent_feil':\n return {\n ikon: IKON.kjent_feil,\n etikett: 'Kjent, ikke planlagt',\n farge: 'neutral',\n lofte: lofte.kjentFeil,\n };\n case 'duplikat':\n return { ikon: IKON.duplikat, etikett: 'Slått sammen', farge: 'neutral', lofte: lofte.duplikat };\n case 'avvist':\n return { ikon: IKON.avvist, etikett: 'Avvist', farge: 'danger', lofte: lofte.avvist };\n }\n}\n\n/** Raden som venter på nett (DD-41). Den har ingen saksnummer og intet løfte om svar. */\nexport const venterVisning: StatusVisning = {\n ikon: IKON.venterNett,\n etikett: 'Venter på nett',\n farge: 'neutral',\n lofte: lofte.venterNett,\n};\n\n/**\n * Etikett for en hel rad, brukt som skjermleserens sammendrag. Ikonet er\n * `aria-hidden` i UI-et, så etiketten må bære alt.\n */\nexport function radEtikett(rad: SubmissionStatusView): string {\n const v = statusVisning(rad.status, rad.type, rad.deadlineAt);\n const spor = rad.type === 'onske' ? 'ønske' : 'feil';\n return `${tekst.mineSak(rad.id)}, ${spor}: ${rad.text}. Status ${v.etikett.toLowerCase()}. ${v.lofte}`;\n}\n","import { skaler, strokTilRekter, treffer, trykkTilRekt, type MaskPoint, type MaskRect } from '@innspel/core';\nimport React, { useCallback, useMemo, useRef, useState, type RefObject } from 'react';\nimport { Image, Pressable, Text, View, type GestureResponderEvent, type LayoutChangeEvent } from 'react-native';\nimport { screenRules } from '../generated/tokens.js';\nimport type { ScreenshotCapture, ViewRef } from '../skjermbilde.js';\nimport { useTema } from '../tema.js';\nimport { Btn, H, Hint } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\nexport type MaskVerktoy = 'felt' | 'pensel';\n\n/**\n * 2f — skjermbildet, tatt ved trykk og forhåndsvist (K4). Tre likestilte\n * maskeringsveier (DD-40): «Masker felt» (ett trykk legger en boks), «Tegn over»\n * (fingerstrøk) og «Masker all tekst» (heldekkende uskarphet — se DD-40,\n * presisert for RN). Private views (DD-39) ligger der FØR innsenderen ser bildet,\n * merket «Maskert av appen», og kan ikke fjernes. Egne masker fjernes med ett\n * trykk på dem.\n *\n * Maskeringen skjer i bitmapen ved komposisjon: bildet vises med maskeringslagene\n * over, og «Legg ved og fortsett» fanger denne viewen på nytt. Det er komposittet\n * som lastes opp — rå-URI-en forlater aldri widgeten.\n *\n * Fargene her er `screenRules`: det ene stedet temaet ikke gjelder, fordi\n * maskene må være synlige uansett hva skjermbildet selv inneholder.\n */\nexport function Skjermbilde({\n bilde,\n automaskerRot,\n rotStorrelse,\n previewRef,\n komponerer,\n onFjern,\n onLeggVed,\n}: {\n bilde: ScreenshotCapture;\n /** Private views i vertsappens punkter (relativt til rot-viewen). */\n automaskerRot: MaskRect[];\n rotStorrelse: { width: number; height: number };\n previewRef: RefObject<ViewRef | null>;\n komponerer: boolean;\n onFjern: () => void;\n onLeggVed: () => void;\n}) {\n const tema = useTema();\n const [verktoy, setVerktoy] = useState<MaskVerktoy>('pensel');\n const [allTekst, setAllTekst] = useState(false);\n const [egne, setEgne] = useState<MaskRect[]>([]);\n const [ramme, setRamme] = useState<{ width: number; height: number } | null>(null);\n const strok = useRef<MaskPoint[]>([]);\n\n // Bildet tilpasses rammen med bevart sideforhold; alt annet regnes i visningens punkter.\n const visning = useMemo(() => {\n if (!ramme) return null;\n const s = Math.min(ramme.width / bilde.width, ramme.height / bilde.height);\n return { width: Math.floor(bilde.width * s), height: Math.floor(bilde.height * s) };\n }, [ramme, bilde.width, bilde.height]);\n\n const automasker = useMemo(\n () => (visning ? automaskerRot.map((r) => skaler(r, rotStorrelse, visning)) : []),\n [automaskerRot, rotStorrelse, visning],\n );\n\n const onLayout = useCallback((e: LayoutChangeEvent) => {\n const { width, height } = e.nativeEvent.layout;\n setRamme({ width, height });\n }, []);\n\n const punkt = (e: GestureResponderEvent): MaskPoint => ({ x: e.nativeEvent.locationX, y: e.nativeEvent.locationY });\n\n const onGrant = (e: GestureResponderEvent) => {\n if (!visning) return;\n const p = punkt(e);\n // Ett trykk på en egen maske angrer den (wireframe 2f). Private views rører den aldri.\n const treff = egne.findIndex((r) => treffer(p, r));\n if (treff >= 0) {\n setEgne((x) => x.filter((_, i) => i !== treff));\n return;\n }\n if (verktoy === 'felt') {\n const r = trykkTilRekt(p, { width: tema.touch * 4, height: tema.touch }, visning);\n if (r) setEgne((x) => [...x, r]);\n return;\n }\n strok.current = [p];\n };\n\n const onMove = (e: GestureResponderEvent) => {\n if (verktoy !== 'pensel' || strok.current.length === 0) return;\n strok.current.push(punkt(e));\n };\n\n const onRelease = () => {\n if (verktoy !== 'pensel' || !visning || strok.current.length === 0) return;\n const rekter = strokTilRekter(strok.current, screenRules.brushWidth, visning);\n strok.current = [];\n if (rekter.length) setEgne((x) => [...x, ...rekter]);\n };\n\n const knapp = (id: MaskVerktoy | 'allTekst', ikon: string, label: string) => {\n const valgt = id === 'allTekst' ? allTekst : verktoy === id && !allTekst;\n return (\n <Pressable\n key={id}\n testID={`verktoy-${id}`}\n accessibilityRole=\"button\"\n accessibilityLabel={label}\n accessibilityState={{ selected: valgt }}\n onPress={() => (id === 'allTekst' ? setAllTekst((a) => !a) : setVerktoy(id))}\n style={{\n flex: 1,\n minHeight: tema.touch,\n alignItems: 'center',\n justifyContent: 'center',\n gap: tema.space.xs,\n padding: tema.space.xs,\n borderRadius: tema.radius.md,\n borderWidth: tema.hairline,\n borderColor: tema.color.actionSecondaryBorder,\n borderBottomWidth: valgt ? tema.hairline * 2 : tema.hairline,\n borderBottomColor: valgt ? tema.color.textPrimary : tema.color.actionSecondaryBorder,\n backgroundColor: valgt ? tema.color.surfaceRaised : 'transparent',\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.body }}>\n {ikon}\n </Text>\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.small,\n fontWeight: valgt ? tema.weight.semibold : tema.weight.regular,\n }}\n >\n {label}\n </Text>\n </Pressable>\n );\n };\n\n const a11y = tekst.skjermbildeA11y(automasker.length, egne.length, allTekst);\n\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n <H sub={tekst.skjermbildeUnder}>{tekst.skjermbildeTittel}</H>\n\n <View accessibilityRole=\"toolbar\" accessibilityLabel={tekst.maskering} style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {knapp('felt', '▣', tekst.maskerFelt)}\n {knapp('pensel', '✎', tekst.tegnOver)}\n {knapp('allTekst', '▦', tekst.maskerAllTekst)}\n </View>\n\n <View\n testID=\"skjermbilde-ramme\"\n onLayout={onLayout}\n style={{\n flex: 1,\n minHeight: tema.touch * 5,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: screenRules.previewBackdrop,\n borderRadius: tema.radius.md,\n overflow: 'hidden',\n }}\n >\n {visning ? (\n <View\n ref={previewRef}\n collapsable={false}\n testID=\"forhandsvisning\"\n accessibilityRole=\"image\"\n accessibilityLabel={a11y}\n onStartShouldSetResponder={() => !komponerer}\n onMoveShouldSetResponder={() => !komponerer}\n onResponderGrant={onGrant}\n onResponderMove={onMove}\n onResponderRelease={onRelease}\n onResponderTerminate={onRelease}\n style={{ width: visning.width, height: visning.height, backgroundColor: screenRules.previewBackdrop }}\n >\n <Image\n testID=\"skjermbilde-bilde\"\n source={{ uri: bilde.uri }}\n blurRadius={allTekst ? screenRules.textBlurRadius : 0}\n style={{ width: visning.width, height: visning.height }}\n accessibilityIgnoresInvertColors\n />\n\n {automasker.map((r, i) => (\n <View\n key={`auto-${i}`}\n testID={`automask-${i}`}\n pointerEvents=\"none\"\n style={{\n position: 'absolute',\n left: r.x,\n top: r.y,\n width: r.width,\n height: r.height,\n backgroundColor: screenRules.autoMaskFill,\n borderWidth: tema.hairline * 2,\n borderColor: screenRules.autoMaskStroke,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {!komponerer ? (\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }} numberOfLines={1}>\n 🔒 {tekst.maskertAvAppen}\n </Text>\n ) : null}\n </View>\n ))}\n\n {egne.map((r, i) => (\n <View\n key={`egen-${i}`}\n testID={`maske-${i}`}\n pointerEvents=\"none\"\n style={{ position: 'absolute', left: r.x, top: r.y, width: r.width, height: r.height, backgroundColor: screenRules.brushFill }}\n />\n ))}\n </View>\n ) : null}\n </View>\n\n {automasker.length ? <Hint>🔒 {tekst.maskertAvAppenHint}</Hint> : null}\n {egne.length ? <Hint>{tekst.dittStrok}</Hint> : null}\n {allTekst ? <Hint>{tekst.allTekstHint}</Hint> : null}\n\n <View style={{ gap: tema.space.sm }}>\n <Btn variant=\"danger\" testID=\"fjern-bildet\" ikon=\"🗑\" label={tekst.fjernBildet} onPress={onFjern} disabled={komponerer} />\n <Btn testID=\"legg-ved\" label={tekst.leggVedOgFortsett} onPress={onLeggVed} disabled={komponerer || !visning} hint={tekst.leggVedHintDD42} />\n </View>\n </View>\n );\n}\n","import React, { useEffect, useRef } from 'react';\nimport { View, type StyleProp, type ViewStyle } from 'react-native';\nimport { useSkjermbilde, type ViewRef } from './skjermbilde.js';\n\n/**\n * Merk det som aldri skal være med på et skjermbilde (DD-39): navn i en liste,\n * et kontonummer, en samtale. Pakk det inn, og widgeten maskerer det FØR\n * innsenderen ser forhåndsvisningen — som «Maskert av appen», og penselen kan\n * ikke oppheve det. Din kode er sannheten, ikke brukerens presisjon.\n *\n * Uten skjermbilde-adapter gjør komponenten ingenting utover å rendre barna.\n *\n * @example\n * ```tsx\n * <InnspelPrivate><Text>{bruker.navn}</Text></InnspelPrivate>\n * ```\n */\nexport function InnspelPrivate({ children, style }: { children?: React.ReactNode; style?: StyleProp<ViewStyle> }) {\n const ref = useRef<ViewRef | null>(null);\n const kontekst = useSkjermbilde();\n const registrer = kontekst?.privat.register;\n\n useEffect(() => {\n if (!registrer) return;\n return registrer(ref);\n }, [registrer]);\n\n // collapsable={false}: Android slår ellers sammen en View uten stil med\n // forelderen, og da finnes det ingenting å måle.\n return (\n <View ref={ref} collapsable={false} style={style} testID=\"innspel-privat\">\n {children}\n </View>\n );\n}\n","import { InnspelApiError, type MyPrograms, type ParticipationView, type ProgramView } from '@innspel/core';\nimport React, { useCallback, useEffect, useState } from 'react';\nimport { Modal, Pressable, Text, View } from 'react-native';\nimport { useInnspel } from '../InnspelProvider.js';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, Card, H, Hint } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\nimport { Aksept } from './Aksept.js';\nimport { periode } from './periode.js';\n\n/**\n * Betaprogrammet i vertsappen: 3a banneret, 3b aksepten og deltakelsen med\n * «Gå ut» (DD-36). Sett den der vertsappen vil ha invitasjonen — typisk øverst\n * på hjemskjermen. Uten invitasjon og uten deltakelse rendrer den INGENTING;\n * det er wireframens «tom → fanen skjules helt», ikke en tom tilstand.\n *\n * **Tokenet kommer fra verten** (DD-12). Plattformen sender aldri invitasjonen:\n * leietakeren får `program.invitation_created` med tokenet, løser pseudonymet til\n * sin egen bruker og sender lenken i sin egen kanal. Verten fanger tokenet fra\n * dyplenken og gir det hit. Uten det viser banneret fortsatt invitasjonen — men\n * «Bli med» er inaktiv, med lenken forklart, i stedet for å feile ved trykk.\n *\n * Oppgavene, «Hvordan gikk det?» og oppfølgingene er M3.2.\n *\n * @example\n * ```tsx\n * <InnspelProgram invitationToken={tokenFraDyplenke} />\n * ```\n */\nexport function InnspelProgram({\n invitationToken,\n onEndring,\n}: {\n /** Engangs-tokenet fra leietakerens egen kanal, typisk fanget fra en dyplenke. */\n invitationToken?: string;\n /** Kalles når testeren blir med eller går ut — for vertens egen navigasjon. */\n onEndring?: (deltakelse: ParticipationView | null) => void;\n}) {\n const { client } = useInnspel();\n const tema = useTema();\n\n const [mine, setMine] = useState<MyPrograms | undefined>();\n const [deltakelse, setDeltakelse] = useState<ParticipationView | undefined>();\n const [viserAksept, setViserAksept] = useState(false);\n const [viserGaaUt, setViserGaaUt] = useState(false);\n const [avvist, setAvvist] = useState(false);\n const [sender, setSender] = useState(false);\n const [feil, setFeil] = useState<string | undefined>();\n\n // Anonym modus har ingen programmer, og skal ikke spørre: kallet ville blitt\n // 401 uansett, og et kall som alltid feiler er ikke en tilstand — det er støy.\n useEffect(() => {\n if (client.isAnonymous) return;\n let levende = true;\n void client.programs\n .list()\n .then((svar) => {\n if (!levende) return;\n setMine(svar);\n // Aktiv deltakelse er det som vises; trukket kommer aldri tilbake fra listen.\n setDeltakelse(svar.participations.find((p) => p.status !== 'trukket'));\n })\n // Programmet er et tilbud, aldri en sperre: svarer ikke kallet, finnes\n // banneret ikke — vertsappen står uendret.\n .catch(() => undefined);\n return () => {\n levende = false;\n };\n }, [client]);\n\n const bliMed = useCallback(async () => {\n if (!invitationToken) return;\n setSender(true);\n setFeil(undefined);\n try {\n const ny = await client.programs.accept(invitationToken);\n setDeltakelse(ny);\n setViserAksept(false);\n onEndring?.(ny);\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, invitationToken, onEndring]);\n\n const gaaUt = useCallback(async () => {\n if (!deltakelse) return;\n setSender(true);\n try {\n await client.programs.withdraw(deltakelse.id);\n setDeltakelse(undefined);\n setViserGaaUt(false);\n onEndring?.(null);\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, deltakelse, onEndring]);\n\n // Deltakelsen vinner over invitasjonen: har man sagt ja, er banneret ferdig.\n const invitasjon = deltakelse ? undefined : mine?.invitations[0];\n const program: ProgramView | undefined = deltakelse?.program ?? invitasjon?.program;\n\n if (!program) return null;\n\n if (deltakelse) {\n return (\n <View testID=\"program-deltakelse\" accessibilityLabel={tekst.deltakelseRegion} style={{ gap: tema.space.sm }}>\n <Card>\n <H sub={tekst.deltakelsePeriode(periode(program.opensAt, program.closesAt), deltakelse.contactsSent, program.maxContacts)}>\n {program.name}\n </H>\n <Hint>{tekst.deltakelseOppgaverKommer}</Hint>\n {/* DD-36: «Gå ut» er ALLTID synlig — aldri gjemt bak en meny eller under rullefeltet. */}\n <Btn variant=\"ghost\" testID=\"gaa-ut\" ikon=\"🚪\" label={tekst.gaaUt} onPress={() => setViserGaaUt(true)} />\n </Card>\n\n {viserGaaUt ? (\n <Modal visible transparent animationType=\"fade\" onRequestClose={() => setViserGaaUt(false)} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end', padding: tema.space.md }}>\n <View\n testID=\"gaa-ut-dialog\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.surface,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderStrong,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <H>{tekst.gaaUtTittel}</H>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {tekst.gaaUtTekst(program.name)}\n </Text>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {/* «Bli værende» står først: utgangen er et valg, ikke en felle med en angreknapp. */}\n <Btn grow variant=\"secondary\" testID=\"bli-vaerende\" label={tekst.bliVaerende} onPress={() => setViserGaaUt(false)} />\n <Btn grow variant=\"danger\" testID=\"bekreft-gaa-ut\" ikon=\"🚪\" label={tekst.gaaUtBekreft} disabled={sender} onPress={() => void gaaUt()} />\n </View>\n </View>\n </View>\n </Modal>\n ) : null}\n </View>\n );\n }\n\n if (!invitasjon || avvist) return null;\n\n return (\n <>\n <View\n testID=\"program-banner\"\n accessibilityLabel={tekst.invitasjonRegion}\n style={{\n backgroundColor: tema.color.brandBg,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.brand,\n padding: tema.space.md,\n gap: tema.space.sm,\n }}\n >\n <View style={{ flexDirection: 'row', gap: tema.space.sm, alignItems: 'flex-start' }}>\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.h3 }}>\n 🧪\n </Text>\n <View style={{ flex: 1, gap: tema.space.xs }}>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {tekst.invitasjonHva(program.name)}\n </Text>\n <Hint>{tekst.invitasjonKontakter(program.maxContacts)}</Hint>\n </View>\n {/* Avvisbart: invitasjonen er et tilbud. Den kommer tilbake ved neste oppstart, aldri som mas i samme økt. */}\n <Pressable\n testID=\"avvis-invitasjon\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.avvisInvitasjon}\n onPress={() => setAvvist(true)}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.body }}>✕</Text>\n </Pressable>\n </View>\n {feil && !viserAksept ? <Banner live ikon=\"⚠\" tone=\"danger\" children={tekst.akseptFeil(feil)} /> : null}\n <Btn variant=\"secondary\" testID=\"les-mer\" label={tekst.lesMer} onPress={() => setViserAksept(true)} />\n </View>\n\n {viserAksept ? (\n <Aksept\n program={program}\n harToken={!!invitationToken}\n sender={sender}\n {...(feil ? { feil } : {})}\n onBliMed={() => void bliMed()}\n onLukk={() => setViserAksept(false)}\n />\n ) : null}\n </>\n );\n}\n","import type { ProgramView } from '@innspel/core';\nimport React from 'react';\nimport { Linking, Modal, Pressable, ScrollView, Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, Card, H, Hint, StatusPill } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\nimport { minutterPerOppgave, periode } from './periode.js';\n\n/**\n * 3b — aksepten. Én skjerm i fast rekkefølge (DD-13) med TALLENE øverst (DD-32):\n * N oppgaver × M minutter, dato til dato, maks K kontakter. Oppgavene står HER,\n * ikke i en e-post etterpå, og kjente feil er hele lista — testeren skal slippe\n * å melde det vi vet om.\n *\n * Vilkår er en LENKE, aldri en avkryssing (DD-37); ved forpliktelsesfri form\n * (tvunget når leietakeren har mindreårige brukere, K37) finnes ingen vilkår ut\n * over at man kan gå ut når som helst.\n *\n * «Bli med» krever tokenet leietakeren sendte i sin egen kanal (DD-12).\n * Plattformen sender aldri, og tokenet finnes ikke i `programs.list()` — uten\n * det verten har fanget fra dyplenken er knappen inaktiv, med lenken forklart.\n */\nexport function Aksept({\n program,\n harToken,\n sender,\n feil,\n onBliMed,\n onLukk,\n}: {\n program: ProgramView;\n harToken: boolean;\n sender: boolean;\n feil?: string;\n onBliMed: () => void;\n onLukk: () => void;\n}) {\n const tema = useTema();\n const tall = tekst.akseptTall(\n program.tasks.length,\n minutterPerOppgave(program.tasks),\n periode(program.opensAt, program.closesAt),\n program.maxContacts,\n );\n\n return (\n <Modal visible transparent animationType=\"slide\" onRequestClose={onLukk} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end' }}>\n <View\n testID=\"program-aksept\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.bg,\n borderTopLeftRadius: tema.radius.lg * 2,\n borderTopRightRadius: tema.radius.lg * 2,\n padding: tema.screenPadding,\n gap: tema.space.md,\n maxHeight: '92%',\n minHeight: '60%',\n }}\n >\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>\n <Btn variant=\"ghost\" testID=\"aksept-tilbake\" ikon=\"←\" label={tekst.tilbake} onPress={onLukk} />\n <View />\n </View>\n\n {feil ? <Banner live ikon=\"⚠\" tone=\"danger\" children={tekst.akseptFeil(feil)} /> : null}\n\n <ScrollView contentContainerStyle={{ gap: tema.space.md }}>\n <H sub={tekst.akseptHva}>{program.name}</H>\n\n {/* DD-32: tallene på én linje, før forklaringen. */}\n <Text\n accessibilityRole=\"text\"\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: tema.weight.semibold,\n }}\n >\n {tall}\n </Text>\n\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {program.hypothesis}\n </Text>\n\n <Card>\n <H>{tekst.akseptOppgaver}</H>\n {program.tasks.map((o) => (\n <View key={o.id} style={{ gap: tema.space.xs }}>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {o.title}\n </Text>\n <Hint>\n {tekst.akseptOppgaveTid(o.estimatedMinutes)}\n {o.screenHint ? ` · ${o.screenHint}` : ''}\n </Hint>\n </View>\n ))}\n </Card>\n\n {program.knownIssues.length > 0 ? (\n <Card>\n <H sub={tekst.akseptKjenteFeilUnder}>{tekst.akseptKjenteFeil(program.knownIssues.length)}</H>\n {program.knownIssues.map((k) => (\n <View key={k.id} style={{ gap: tema.space.xs }}>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {k.title}\n </Text>\n {k.workaround ? (\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {tekst.omvei} {k.workaround}\n </Text>\n ) : null}\n {k.fixedIn ? (\n <StatusPill\n ikon={k.status === 'fikset' ? '✓' : '🔧'}\n etikett={k.status === 'fikset' ? tekst.rettetI(k.fixedIn) : tekst.rettesI(k.fixedIn)}\n farge={k.status === 'fikset' ? 'success' : 'info'}\n />\n ) : null}\n </View>\n ))}\n </Card>\n ) : null}\n\n <Card>\n <H sub={tekst.akseptInnsamlingTekst}>{tekst.akseptInnsamling}</H>\n <Hint>{tekst.kontekstAldri}</Hint>\n </Card>\n\n {/* DD-37: lenke, aldri avkryssing — og ingen vilkår i forpliktelsesfri form. */}\n {program.termsUrl && !program.commitmentFree ? (\n <View style={{ gap: tema.space.xs }}>\n <Pressable\n testID=\"vilkar-lenke\"\n accessibilityRole=\"link\"\n accessibilityLabel={tekst.akseptVilkar}\n onPress={() => void Linking.openURL(String(program.termsUrl))}\n style={{ minHeight: tema.touch, justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, textDecorationLine: 'underline' }}>\n 🔗 {tekst.akseptVilkar}\n </Text>\n </Pressable>\n <Hint>{tekst.akseptVilkarHint}</Hint>\n </View>\n ) : (\n <Hint>{tekst.akseptIngenVilkar}</Hint>\n )}\n\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n 🚪 {tekst.akseptUtgang}\n </Text>\n </ScrollView>\n\n <Btn\n testID=\"bli-med\"\n label={tekst.bliMed}\n disabled={!harToken || sender}\n hint={harToken ? tekst.bliMedHint : tekst.bliMedUtenToken}\n onPress={onBliMed}\n />\n </View>\n </View>\n </Modal>\n );\n}\n","/**\n * Datoene testeren ser i aksepten (DD-32): «10.–24. oktober», eller med begge\n * måneder når perioden krysser et månedsskifte. Norsk bokmål, ingen klokkeslett —\n * et program varer i dager, og et tidspunkt ville lovet en presisjon som ikke finnes.\n */\nconst MANEDER = [\n 'januar',\n 'februar',\n 'mars',\n 'april',\n 'mai',\n 'juni',\n 'juli',\n 'august',\n 'september',\n 'oktober',\n 'november',\n 'desember',\n] as const;\n\nexport function periode(opensAt: string, closesAt: string): string {\n const fra = new Date(opensAt);\n const til = new Date(closesAt);\n if (Number.isNaN(fra.getTime()) || Number.isNaN(til.getTime())) return '';\n\n const sammeManed = fra.getMonth() === til.getMonth() && fra.getFullYear() === til.getFullYear();\n return sammeManed\n ? `${fra.getDate()}.–${til.getDate()}. ${MANEDER[til.getMonth()]}`\n : `${fra.getDate()}. ${MANEDER[fra.getMonth()]} – ${til.getDate()}. ${MANEDER[til.getMonth()]}`;\n}\n\n/** Anslått tid per oppgave, avrundet. Obligatorisk ved opprettelse (DD-32), så lista er aldri tom her. */\nexport function minutterPerOppgave(tasks: ReadonlyArray<{ estimatedMinutes: number }>): number {\n if (tasks.length === 0) return 0;\n return Math.round(tasks.reduce((sum, t) => sum + t.estimatedMinutes, 0) / tasks.length);\n}\n","import type { InnspelStorage } from '@innspel/core';\n\n/**\n * Formen på lagringspakkene i React Native-økosystemet: AsyncStorage, MMKV med\n * async-fasade, expo-secure-store. Alle tre har disse tre metodene.\n */\nexport interface AsyncStorageLike {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n}\n\n/**\n * Lager en {@link InnspelStorage} av vertens egen lagringspakke.\n *\n * Pakken tar ingen avhengighet på AsyncStorage eller MMKV med vilje: verten har\n * som regel én av dem allerede, og to kopier av samme lagring i én app er verre\n * enn litt oppsett. Send inn den du bruker:\n *\n * @example\n * ```ts\n * import AsyncStorage from '@react-native-async-storage/async-storage';\n * const storage = createStorage(AsyncStorage);\n * ```\n *\n * Det eneste som lagres er offline-køen (DD-41) — aldri feedback-tokenet, aldri\n * en install- eller enhets-ID (K20). Lagringen trenger derfor ikke være kryptert.\n */\nexport function createStorage(pakke: AsyncStorageLike): InnspelStorage {\n return {\n get: (key) => pakke.getItem(key),\n set: (key, value) => pakke.setItem(key, value),\n remove: (key) => pakke.removeItem(key),\n };\n}\n\n/**\n * Lagring i minne. Køen overlever da ikke at appen lukkes, så den er til\n * utvikling og test — ikke til produksjon. `InnspelProvider` sier fra i\n * konsollen hvis den brukes uten at det er sagt eksplisitt.\n */\nexport function createMemoryStorage(): InnspelStorage {\n const rader = new Map<string, string>();\n return {\n get: async (key) => rader.get(key) ?? null,\n set: async (key, value) => {\n rader.set(key, value);\n },\n remove: async (key) => {\n rader.delete(key);\n },\n };\n}\n"],"mappings":";AACA,SAAgB,iBAAAA,gBAAe,eAAAC,cAAa,cAAAC,aAAY,WAAAC,UAAS,UAAAC,SAAQ,YAAAC,iBAAgB;AACzF,SAAS,QAAAC,aAAY;;;ACDrB,SAAS,eAAe,kBAAqD;AAC7E,SAAS,aAAwB;AAwD1B,SAAS,wBAAwB,YAA6C;AACnF,SAAO;AAAA,IACL,MAAM,QAAQ,KAAK,SAAS;AAC1B,YAAM,MAAM,MAAM,WAAW,KAAK,EAAE,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,SAAS,QAAQ,UAAU,CAAC;AACzG,YAAM,EAAE,OAAO,OAAO,IAAI,MAAM,IAAI;AAAA,QAA2C,CAAC,SAAS,WACvF,MAAM,QAAQ,KAAK,CAAC,GAAG,MAAM,QAAQ,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC,GAAG,MAAM;AAAA,MACvE;AACA,aAAO,EAAE,KAAK,OAAO,OAAO;AAAA,IAC9B;AAAA,IACA,QAAQ,KAAK;AACX,aAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,cAAM,OAAO,IAAI;AACjB,YAAI,CAAC,KAAM,QAAO,QAAQ,IAAI;AAC9B,aAAK,gBAAgB,CAAC,GAAG,GAAG,OAAO,WAAW,QAAQ,EAAE,GAAG,GAAG,OAAO,OAAO,CAAC,CAAC;AAAA,MAChF,CAAC;AAAA,IACH;AAAA,IACA,MAAM,KAAK,KAAK;AACd,YAAM,MAAM,MAAM,MAAM,GAAG;AAC3B,aAAO,IAAI,KAAK;AAAA,IAClB;AAAA,EACF;AACF;AAYO,SAAS,wBAAyC;AACvD,QAAM,OAAO,oBAAI,IAA+B;AAChD,SAAO;AAAA,IACL,SAAS,KAAK;AACZ,WAAK,IAAI,GAAG;AACZ,aAAO,MAAM;AACX,aAAK,OAAO,GAAG;AAAA,MACjB;AAAA,IACF;AAAA,IACA,MAAM,MAAM,CAAC,GAAG,IAAI;AAAA,EACtB;AACF;AASO,IAAM,qBAAqB,cAA0C,IAAI;AAEzE,SAAS,iBAA6C;AAC3D,SAAO,WAAW,kBAAkB;AACtC;;;ACnHA,SAAS,iBAAAC,gBAAe,cAAAC,mBAAkB;;;ACkBnC,IAAM,IAAI;AAAA,EACf,OAAO;AAAA,IACL,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,aAAa;AAAA,IACb,eAAe;AAAA,IACf,WAAW;AAAA,IACX,cAAc;AAAA,IACd,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,uBAAuB;AAAA,IACvB,qBAAqB;AAAA,IACrB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,IACV,SAAS;AAAA,IACT,WAAW;AAAA,IACX,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,WAAW;AAAA,IACX,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,WAAW;AAAA,IACX,OAAO;AAAA,EACT;AAAA,EACA,OAAO;AAAA,IACL,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,KAAK;AAAA,EACP;AAAA,EACA,QAAQ;AAAA,IACN,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,EACR;AAAA,EACA,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,YAAY;AAAA,IACV,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,EACP,eAAe;AAAA,EACf,UAAU;AACZ;AAGO,IAAM,QAAQ;AAAA,EACnB,OAAO;AAAA,IACL,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,aAAa;AAAA,IACb,eAAe;AAAA,IACf,WAAW;AAAA,IACX,cAAc;AAAA,IACd,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,uBAAuB;AAAA,IACvB,qBAAqB;AAAA,IACrB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,IACV,SAAS;AAAA,IACT,WAAW;AAAA,IACX,WAAW;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,IACX,WAAW;AAAA,IACX,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,WAAW;AAAA,IACX,OAAO;AAAA,EACT;AAAA,EACA,OAAO;AAAA,IACL,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,KAAK;AAAA,EACP;AAAA,EACA,QAAQ;AAAA,IACN,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,EACR;AAAA,EACA,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,YAAY;AAAA,IACV,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,EACP,eAAe;AAAA,EACf,UAAU;AACZ;AAuIO,IAAM,cAAc;AAAA,EACzB,WAAW;AAAA,EACX,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,gBAAgB;AAClB;;;AD3RO,SAAS,SAAS,SAAwB,SAA2B,QAAc;AACxF,QAAM,OAAQ,WAAW,UAAU,QAAQ;AAC3C,MAAI,CAAC,QAAS,QAAO;AAErB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,OAAO,EAAE,GAAG,KAAK,OAAO,GAAG,QAAQ,MAAM;AAAA,EAC3C;AACF;AAEA,IAAM,cAAcC,eAAoB,CAAoB;AAErD,IAAM,eAAe,YAAY;AAGjC,SAAS,UAAgB;AAC9B,SAAOC,YAAW,WAAW;AAC/B;;;AEhEA;AAAA,EACE;AAAA,EACA;AAAA,OAQK;AACP,SAAgB,eAAAC,cAAa,WAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AAChE,SAAS,OAAO,aAAAC,YAAW,QAAAC,OAAM,QAAAC,aAAY;;;ACX7C,SAAgB,SAAS,gBAAgB;AACzC,SAAS,aAAAC,YAAW,QAAAC,OAAM,WAAW,QAAAC,aAAY;;;ACFjD,OAAkB;AAClB,SAAS,WAAW,MAAM,YAA4C;AA6ChE,SAwBI,KAxBJ;AAhCC,SAAS,IAAI;AAAA,EAClB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAUG;AACD,QAAM,OAAO,QAAQ;AACrB,QAAM,IAAI,KAAK;AAEf,QAAM,WACJ,YAAY,YAAY,EAAE,gBAAgB,YAAY,cAAc,EAAE,gBAAgB;AACxF,QAAM,aACJ,YAAY,YAAY,EAAE,kBAAkB,YAAY,WAAW,EAAE,SAAS,EAAE;AAClF,QAAM,OAAO,YAAY,UAAU,gBAAgB,YAAY,YAAY,EAAE,gBAAgB,EAAE;AAE/F,SACE,qBAAC,QAAK,OAAO,OAAO,EAAE,MAAM,EAAE,IAAI,QAChC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,mBAAkB;AAAA,QAGlB,oBAAoB,uBAAuB,OAAO,GAAG,KAAK,KAAK,IAAI,KAAK;AAAA,QACxE,oBAAoB,EAAE,UAAU,CAAC,CAAC,SAAS;AAAA,QAC3C;AAAA,QACA;AAAA,QACA,OAAO;AAAA,UACL,WAAW,KAAK;AAAA,UAChB,cAAc,KAAK,OAAO;AAAA,UAC1B,aAAa,KAAK;AAAA,UAClB,aAAa;AAAA,UACb,iBAAiB,WAAW,EAAE,UAAU;AAAA,UACxC,mBAAmB,KAAK,MAAM;AAAA,UAC9B,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,eAAe;AAAA,UACf,KAAK,KAAK,MAAM;AAAA,UAChB,SAAS,WAAW,MAAM;AAAA,QAC5B;AAAA,QAEC;AAAA,iBACC,oBAAC,QAAK,6BAA2B,MAAC,2BAA0B,MAAK,OAAO,EAAE,UAAU,KAAK,KAAK,KAAK,GAChG,gBACH,IACE;AAAA,UACJ;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,OAAO,WAAW,EAAE,eAAe;AAAA,gBACnC,UAAU,KAAK,KAAK;AAAA,gBACpB,YAAY,KAAK,OAAO;AAAA,cAC1B;AAAA,cAEC;AAAA;AAAA,UACH;AAAA;AAAA;AAAA,IACF;AAAA,IACC,OAAO,oBAAC,QAAM,gBAAK,IAAU;AAAA,KAChC;AAEJ;AAEO,SAAS,EAAE,EAAE,UAAU,IAAI,GAAuC;AACvE,QAAM,OAAO,QAAQ;AACrB,SACE,qBAAC,QAAK,OAAO,EAAE,KAAK,KAAK,MAAM,GAAG,GAChC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,mBAAkB;AAAA,QAClB,OAAO;AAAA,UACL,OAAO,KAAK,MAAM;AAAA,UAClB,UAAU,KAAK,KAAK;AAAA,UACpB,YAAY,KAAK,WAAW;AAAA,UAC5B,YAAY,KAAK,OAAO;AAAA,QAC1B;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,IACC,MACC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,OAAO,KAAK,MAAM;AAAA,UAClB,UAAU,KAAK,KAAK;AAAA,UACpB,YAAY,KAAK,WAAW;AAAA,QAC9B;AAAA,QAEC;AAAA;AAAA,IACH,IACE;AAAA,KACN;AAEJ;AAEO,SAAS,KAAK,EAAE,SAAS,GAAkC;AAChE,QAAM,OAAO,QAAQ;AACrB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,OAAO,KAAK,MAAM;AAAA,QAClB,UAAU,KAAK,KAAK;AAAA,QACpB,YAAY,KAAK,WAAW;AAAA,MAC9B;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEO,SAAS,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,OAAO,QAAQ;AACrB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL;AAAA,UACE,iBAAiB,KAAK,MAAM;AAAA,UAC5B,cAAc,KAAK,OAAO;AAAA,UAC1B,aAAa,KAAK;AAAA,UAClB,aAAa,KAAK,MAAM;AAAA,UACxB,aAAa,SAAS,WAAW;AAAA,UACjC,SAAS,KAAK,MAAM;AAAA,UACpB,KAAK,KAAK,MAAM;AAAA,QAClB;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAOO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,OAAO,QAAQ;AACrB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,KAAK,KAAK,MAAM;AAAA,QAChB,WAAW;AAAA,QACX,mBAAmB,KAAK,MAAM;AAAA,QAC9B,iBAAiB,KAAK,MAAM;AAAA,QAC5B,cAAc,KAAK,OAAO;AAAA,QAC1B,iBAAiB,KAAK,MAAM,GAAG,KAAK,IAA+B;AAAA,MACrE;AAAA,MAEA;AAAA,4BAAC,QAAK,6BAA2B,MAAC,2BAA0B,MAAK,OAAO,EAAE,UAAU,KAAK,KAAK,MAAM,GACjG,gBACH;AAAA,QACA,oBAAC,QAAK,OAAO,EAAE,OAAO,KAAK,MAAM,KAAK,GAAG,UAAU,KAAK,KAAK,OAAO,YAAY,KAAK,OAAO,OAAO,GAChG,mBACH;AAAA;AAAA;AAAA,EACF;AAEJ;AAMO,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,OAAO,QAAQ;AACrB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,eAAe;AAAA,QACf,KAAK,KAAK,MAAM;AAAA,QAChB,iBAAiB,KAAK,MAAM,GAAG,IAAI,IAA+B;AAAA,QAClE,cAAc,KAAK,OAAO;AAAA,QAC1B,SAAS,KAAK,MAAM;AAAA,MACtB;AAAA,MAEA;AAAA,4BAAC,QAAK,6BAA2B,MAAC,2BAA0B,MAAK,OAAO,EAAE,UAAU,KAAK,KAAK,KAAK,GAChG,gBACH;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,mBAAkB;AAAA,YAClB,yBAAyB,OAAO,WAAW;AAAA,YAC3C,OAAO;AAAA,cACL,MAAM;AAAA,cACN,OAAO,KAAK,MAAM,IAAI;AAAA,cACtB,UAAU,KAAK,KAAK;AAAA,cACpB,YAAY,KAAK,WAAW;AAAA,YAC9B;AAAA,YAEC;AAAA;AAAA,QACH;AAAA;AAAA;AAAA,EACF;AAEJ;;;AC1OO,IAAM,QAAQ;AAAA;AAAA,EAEnB,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,UAAU;AAAA,EACV,eAAe;AAAA,EACf,WAAW;AAAA,EACX,gBAAgB;AAAA;AAAA,EAGhB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS,CAAC,YAAoB,YAAY,OAAO;AAAA,EACjD,SAAS,CAAC,YAAoB,YAAY,OAAO;AAAA;AAAA,EAGjD,eAAe;AAAA,EACf,gBAAgB;AAAA;AAAA,EAEhB,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,MAAM;AAAA,EACN,YAAY;AAAA;AAAA,EAEZ,SAAS,CAAC,QAAgB,SAAS,GAAG;AAAA,EACtC,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,aAAa;AAAA,EACb,eAAe;AAAA,EACf,eACE;AAAA,EACF,WAAW,CAAC,WAAmB,mBAAgB,MAAM;AAAA,EACrD,YAAY;AAAA;AAAA,EAGZ,oBAAoB;AAAA,EACpB,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,WAAW;AAAA,EACX,cAAc;AAAA,EACd,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB,CAAC,MAAc,MAAc,YAC5C,uCAAoC,OAAO,GAAG,IAAI,oDAAoD,EAAE,GAAG,OAAO,GAAG,IAAI,2BAA2B,EAAE,GAAG,UAAU,gCAAgC,EAAE;AAAA;AAAA,EAGvM,YAAY;AAAA,IACV,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,OAAO;AAAA,EACT;AAAA,EACA,cAAc;AAAA,EACd,eAAe;AAAA,EACf,mBAAmB;AAAA;AAAA,EAGnB,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,iBACE;AAAA,EACF,kBAAkB;AAAA,EAClB,YAAY,CAAC,OAAe,cAAc,EAAE;AAAA,EAC5C,iBAAiB;AAAA;AAAA,EAEjB,yBAAyB;AAAA,EACzB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,uBAAuB,CAAC,OAAe,cAAc,EAAE;AAAA;AAAA,EAGvD,eAAe;AAAA,EACf,eACE;AAAA,EACF,cAAc;AAAA;AAAA,EAEd,kBAAkB;AAAA,EAClB,iBAAiB,CAAC,UAAkB,qBAAqB,KAAK;AAAA,EAC9D,WAAW;AAAA;AAAA,EAGX,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,SAAS;AAAA,EACT,eAAe;AAAA,EACf,SAAS,CAAC,OAAe,OAAO,EAAE;AAAA,EAClC,SAAS,CAAC,cAAsB,YAAY,SAAS;AAAA,EACrD,iBAAiB;AAAA,EACjB,UAAU;AAAA;AAAA,EAGV,kBAAkB;AAAA,EAClB,eAAe,CAAC,SAAiB,oBAAiB,IAAI;AAAA,EACtD,qBAAqB,CAAC,SACpB,uBAAuB,IAAI;AAAA,EAC7B,QAAQ;AAAA,EACR,iBAAiB;AAAA;AAAA,EAGjB,WAAW;AAAA;AAAA,EAEX,YAAY,CAAC,UAAkB,UAAkBC,UAAiB,cAChE,GAAG,QAAQ,sBAAmB,QAAQ,kBAAeA,QAAO,cAAW,SAAS;AAAA,EAClF,gBAAgB;AAAA,EAChB,kBAAkB,CAAC,aAAqB,OAAO,QAAQ;AAAA,EACvD,kBAAkB,CAAC,WAAmB,gBAAgB,MAAM;AAAA,EAC5D,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,uBACE;AAAA,EACF,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,mBACE;AAAA,EACF,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,YAAY;AAAA;AAAA,EAEZ,iBAAiB;AAAA,EACjB,YAAY,CAAC,UAAkB,uBAAuB,KAAK;AAAA;AAAA,EAG3D,kBAAkB;AAAA,EAClB,mBAAmB,CAACA,UAAiB,OAAe,SAClD,GAAGA,QAAO,SAAM,KAAK,OAAO,IAAI;AAAA,EAClC,0BAA0B;AAAA,EAC1B,OAAO;AAAA,EACP,aAAa;AAAA,EACb,YAAY,CAAC,SACX,6CAA0C,IAAI;AAAA,EAChD,aAAa;AAAA,EACb,cAAc;AAAA;AAAA,EAGd,SAAS;AAAA,EACT,MAAM;AAAA,EACN,eAAe;AACjB;AAOO,IAAM,QAAQ;AAAA,EACnB,YAAY;AAAA,EACZ,UAAU,CAAC,UAAkB,cAAc,KAAK;AAAA,EAChD,mBAAmB;AAAA,EACnB,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AACV;;;AF5FQ,SAaE,OAAAC,MAbF,QAAAC,aAAA;AAzED,SAAS,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAsBG;AACD,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAmB,CAAC,CAAC;AAEnD,QAAM,QAAQ,MAAM;AACpB,QAAM,UAAU,QAAQ;AACxB,QAAM,OAAO,SAAS;AAGtB,QAAM,YAAY,SAAS,gBAAgB;AAE3C,QAAM,WAAW,KAAK,KAAK,CAAC,MAAM,CAAC,QAAQ,SAAS,EAAE,KAAK,CAAC;AAE5D,QAAM,SAAS,QAAQ,MAAM;AAC3B,UAAM,YAAoC;AAAA,MACxC,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AACA,WAAO,OAAO,QAAQ,SAAS,EAC5B,IAAI,CAAC,CAAC,MAAM,OAAO,MAAM;AACxB,YAAMC,SAAS,SAA2D,IAAI;AAC9E,aAAOA,UAAS,CAAC,eAAe,SAAS,IAAI,IAAI,EAAE,MAAM,SAAS,OAAAA,OAAM,IAAI;AAAA,IAC9E,CAAC,EACA,OAAO,CAAC,MAA6D,MAAM,IAAI;AAAA,EACpF,GAAG,CAAC,UAAU,cAAc,CAAC;AAE7B,SACE,gBAAAD,MAACE,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,GACxC;AAAA,gBACC,gBAAAF;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,eAAe;AAAA,UACf,YAAY;AAAA,UACZ,KAAK,KAAK,MAAM;AAAA,UAChB,WAAW,KAAK;AAAA,UAChB,aAAa,KAAK;AAAA,UAClB,aAAa,KAAK,MAAM;AAAA,UACxB,cAAc,KAAK,OAAO;AAAA,UAC1B,aAAa,KAAK,MAAM;AAAA,UACxB,cAAc,KAAK,MAAM;AAAA,QAC3B;AAAA,QAEA;AAAA,0BAAAH,KAACI,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,OAAO,KAAK,MAAM,aAAa,UAAU,KAAK,KAAK,MAAM,GAC9E,gBAAM,UAAU,UAAU,KAAK,GAClC;AAAA,UACA,gBAAAJ;AAAA,YAACK;AAAA,YAAA;AAAA,cACC,QAAO;AAAA,cACP,mBAAkB;AAAA,cAClB,oBAAoB,MAAM;AAAA,cAC1B,SAAS;AAAA,cACT,OAAO,EAAE,UAAU,KAAK,OAAO,WAAW,KAAK,OAAO,YAAY,UAAU,gBAAgB,SAAS;AAAA,cAErG,0BAAAL,KAACI,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,eAAe,UAAU,KAAK,KAAK,MAAM,GAAG,oBAAC;AAAA;AAAA,UAChF;AAAA;AAAA;AAAA,IACF,IACE;AAAA,IAEH,WACC,gBAAAH;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,KAAK,KAAK,MAAM;AAAA,UAChB,iBAAiB,KAAK,MAAM;AAAA,UAC5B,cAAc,KAAK,OAAO;AAAA,UAC1B,SAAS,KAAK,MAAM;AAAA,QACtB;AAAA,QAEA;AAAA,0BAAAH;AAAA,YAACI;AAAA,YAAA;AAAA,cACC,mBAAkB;AAAA,cAClB,yBAAwB;AAAA,cACxB,OAAO;AAAA,gBACL,OAAO,KAAK,MAAM;AAAA,gBAClB,UAAU,KAAK,KAAK;AAAA,gBACpB,YAAY,KAAK,WAAW;AAAA,gBAC5B,YAAY,KAAK,OAAO;AAAA,cAC1B;AAAA,cAEC,gBAAM,WAAW,SAAS,IAAI;AAAA;AAAA,UACjC;AAAA,UACA,gBAAAH,MAACE,OAAA,EAAK,OAAO,EAAE,eAAe,OAAO,KAAK,KAAK,MAAM,GAAG,GACtD;AAAA,4BAAAH;AAAA,cAAC;AAAA;AAAA,gBACC,MAAI;AAAA,gBACJ,SAAQ;AAAA,gBACR,QAAO;AAAA,gBACP,OAAO,MAAM;AAAA,gBACb,SAAS,MAAM,QAAQ,MAAM,MAAM,GAAG,SAAS,KAAK,IAAI,MAAM,MAAM,SAAS,GAAG,CAAC;AAAA;AAAA,YACnF;AAAA,YACA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAI;AAAA,gBACJ,SAAQ;AAAA,gBACR,QAAO;AAAA,gBACP,OAAO,MAAM;AAAA,gBACb,SAAS,MAAM,WAAW,CAAC,MAAM,CAAC,GAAG,GAAG,SAAS,KAAK,CAAC;AAAA;AAAA,YACzD;AAAA,aACF;AAAA,UACA,gBAAAA,KAAC,QAAM,gBAAM,mBAAkB;AAAA;AAAA;AAAA,IACjC,IACE;AAAA,IAEJ,gBAAAA,KAAC,KAAG,mBAAS,UAAU,MAAM,iBAAiB,MAAM,eAAc;AAAA,IAElE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,oBAAoB,SAAS,UAAU,MAAM,iBAAiB,MAAM;AAAA,QACpE,OAAO;AAAA,QACP,cAAc;AAAA,QACd,WAAW;AAAA,QACX,WAAS;AAAA,QACT,eAAe;AAAA,QACf,aAAa,SAAS,UAAU,MAAM,mBAAmB,MAAM;AAAA,QAC/D,sBAAsB,KAAK,MAAM;AAAA,QACjC,OAAO;AAAA,UACL,iBAAiB,KAAK,MAAM;AAAA,UAC5B,aAAa,KAAK;AAAA,UAClB,aAAa,OAAO,KAAK,MAAM,UAAU,KAAK,MAAM;AAAA,UACpD,cAAc,KAAK,OAAO;AAAA,UAC1B,SAAS,KAAK,MAAM;AAAA,UACpB,OAAO,KAAK,MAAM;AAAA,UAClB,UAAU,KAAK,KAAK;AAAA,UACpB,YAAY,KAAK,WAAW;AAAA,UAC5B,WAAW,KAAK,QAAQ;AAAA,UACxB,mBAAmB;AAAA,QACrB;AAAA;AAAA,IACF;AAAA,IAEC,YACC,gBAAAC;AAAA,MAACG;AAAA,MAAA;AAAA,QACC,QAAO;AAAA,QACP,yBAAyB,OAAO,cAAc;AAAA,QAC9C,OAAO;AAAA,UACL,WAAW;AAAA,UACX,OAAO,OAAO,KAAK,MAAM,UAAU,KAAK,MAAM;AAAA,UAC9C,UAAU,KAAK,KAAK;AAAA,QACtB;AAAA,QAEC;AAAA;AAAA,UAAM;AAAA,UAAI;AAAA,UACV,OAAO,MAAM,aAAa;AAAA;AAAA;AAAA,IAC7B,IACE;AAAA,IAGH,aACC,gBAAAH;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,QAAO;AAAA,QACP,OAAO;AAAA,UACL,eAAe;AAAA,UACf,YAAY;AAAA,UACZ,KAAK,KAAK,MAAM;AAAA,UAChB,WAAW,KAAK;AAAA,UAChB,aAAa,KAAK;AAAA,UAClB,aAAa,KAAK,MAAM;AAAA,UACxB,cAAc,KAAK,OAAO;AAAA,UAC1B,aAAa,KAAK,MAAM;AAAA,UACxB,cAAc,KAAK,MAAM;AAAA,QAC3B;AAAA,QAEA;AAAA,0BAAAH,KAACI,OAAA,EAAK,6BAA2B,MAAC,2BAA0B,MAAK,OAAO,EAAE,UAAU,KAAK,KAAK,MAAM,GAAG,uBAEvG;AAAA,UACA,gBAAAJ,KAACI,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,OAAO,KAAK,MAAM,aAAa,UAAU,KAAK,KAAK,MAAM,GAAI,gBAAM,oBAAmB;AAAA,UAC9G,gBAAAJ;AAAA,YAACK;AAAA,YAAA;AAAA,cACC,QAAO;AAAA,cACP,mBAAkB;AAAA,cAClB,oBAAoB,MAAM;AAAA,cAC1B,SAAS;AAAA,cACT,OAAO,EAAE,UAAU,KAAK,OAAO,WAAW,KAAK,OAAO,YAAY,UAAU,gBAAgB,SAAS;AAAA,cAErG,0BAAAL,KAACI,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,eAAe,UAAU,KAAK,KAAK,MAAM,GAAG,oBAAC;AAAA;AAAA,UAChF;AAAA;AAAA;AAAA,IACF,IACE,gBACF,gBAAAJ;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,QAAO;AAAA,QACP,MAAK;AAAA,QACL,OAAO,MAAM;AAAA,QACb,MAAM,MAAM;AAAA,QACZ,SAAS;AAAA;AAAA,IACX,IACE;AAAA,IAGJ,gBAAAC,MAACE,OAAA,EAAK,OAAO,EAAE,gBAAgB,KAAK,UAAU,gBAAgB,KAAK,MAAM,QAAQ,YAAY,KAAK,MAAM,GAAG,GACzG;AAAA,sBAAAH;AAAA,QAACK;AAAA,QAAA;AAAA,UACC,QAAO;AAAA,UACP,mBAAkB;AAAA,UAClB,oBAAoB,EAAE,UAAU,KAAK;AAAA,UACrC,oBAAoB,GAAG,MAAM,aAAa,GAAG,OAAO,KAAK,MAAM,WAAW;AAAA,UAC1E,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;AAAA,UAChC,OAAO,EAAE,WAAW,KAAK,OAAO,gBAAgB,SAAS;AAAA,UAEzD,0BAAAJ,MAACG,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,eAAe,UAAU,KAAK,KAAK,MAAM,GACvE;AAAA,mBAAO,WAAM;AAAA,YAAI;AAAA,YAAE,MAAM;AAAA,YACzB,OAAO,KAAK,MAAM;AAAA,aACrB;AAAA;AAAA,MACF;AAAA,MAEC,OACC,gBAAAH,MAACE,OAAA,EACE;AAAA,eAAO,IAAI,CAAC,MACX,gBAAAF;AAAA,UAACE;AAAA,UAAA;AAAA,YAEC,OAAO;AAAA,cACL,eAAe;AAAA,cACf,YAAY;AAAA,cACZ,KAAK,KAAK,MAAM;AAAA,cAChB,WAAW,KAAK;AAAA,cAChB,mBAAmB,KAAK;AAAA,cACxB,mBAAmB,KAAK,MAAM;AAAA,YAChC;AAAA,YAEA;AAAA,8BAAAH,KAACI,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,WAAW,UAAU,KAAK,KAAK,OAAO,UAAU,KAAK,QAAQ,EAAE,GAC7F,YAAE,SACL;AAAA,cACA,gBAAAJ,KAACI,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,OAAO,KAAK,MAAM,aAAa,UAAU,KAAK,KAAK,MAAM,GAAI,YAAE,OAAM;AAAA,cAC7F,gBAAAJ;AAAA,gBAACK;AAAA,gBAAA;AAAA,kBACC,QAAQ,SAAS,EAAE,IAAI;AAAA,kBACvB,mBAAkB;AAAA,kBAClB,oBAAoB,GAAG,MAAM,aAAa,IAAI,EAAE,QAAQ,YAAY,CAAC;AAAA,kBACrE,SAAS,MAAM,gBAAgB,EAAE,IAAI;AAAA,kBACrC,OAAO,EAAE,UAAU,KAAK,OAAO,WAAW,KAAK,OAAO,YAAY,UAAU,gBAAgB,SAAS;AAAA,kBAErG,0BAAAJ,MAACG,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,eAAe,UAAU,KAAK,KAAK,MAAM,GAAG;AAAA;AAAA,oBACxE,MAAM;AAAA,qBACX;AAAA;AAAA,cACF;AAAA;AAAA;AAAA,UAxBK,EAAE;AAAA,QAyBT,CACD;AAAA,QACD,gBAAAJ,KAACG,OAAA,EAAK,OAAO,EAAE,YAAY,KAAK,MAAM,GAAG,GACvC,0BAAAH,KAAC,QAAM,gBAAM,eAAc,GAC7B;AAAA,SACF,IACE;AAAA,OACN;AAAA,IAEA,gBAAAA,KAACG,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,gBAAgB,WAAW,GACjD,0BAAAH;AAAA,MAAC;AAAA;AAAA,QACC,QAAO;AAAA,QACP,OAAO,SAAS,WAAW,CAAC,UAAU,MAAM,aAAa,MAAM;AAAA,QAC/D,UAAU,WAAW;AAAA,QACrB,MAAM,UAAU,MAAM,QAAQ,aAAa,IAAI,aAAa,MAAM,mBAAmB;AAAA,QACrF,SAAS;AAAA;AAAA,IACX,GACF;AAAA,KACF;AAEJ;;;AGvTA,OAAkB;AAClB,SAAS,aAAAM,YAAW,QAAAC,OAAM,QAAAC,aAAY;AAgBlC,SAkBE,OAAAC,MAlBF,QAAAC,aAAA;AAJG,SAAS,KAAK,EAAE,OAAO,GAAiD;AAC7E,QAAM,OAAO,QAAQ;AAErB,QAAM,QAAQ,CAAC,MAAwB,MAAc,OAAe,UAClE,gBAAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,QAAQ,QAAQ,IAAI;AAAA,MACpB,mBAAkB;AAAA,MAClB,oBAAoB,GAAG,KAAK,KAAK,KAAK;AAAA,MACtC,SAAS,MAAM,OAAO,IAAI;AAAA,MAC1B,OAAO;AAAA,QACL,MAAM;AAAA,QACN,WAAW,KAAK,QAAQ;AAAA,QACxB,iBAAiB,KAAK,MAAM;AAAA,QAC5B,aAAa,KAAK;AAAA,QAClB,aAAa,KAAK,MAAM;AAAA,QACxB,cAAc,KAAK,OAAO;AAAA,QAC1B,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,KAAK,KAAK,MAAM;AAAA,QAChB,SAAS,KAAK,MAAM;AAAA,MACtB;AAAA,MAEA;AAAA,wBAAAF,KAACG,OAAA,EAAK,6BAA2B,MAAC,2BAA0B,MAAK,OAAO,EAAE,UAAU,KAAK,KAAK,GAAG,GAC9F,gBACH;AAAA,QACA,gBAAAH;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,OAAO,KAAK,MAAM;AAAA,cAClB,UAAU,KAAK,KAAK;AAAA,cACpB,YAAY,KAAK,OAAO;AAAA,cACxB,WAAW;AAAA,YACb;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QACA,gBAAAH,KAACG,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,WAAW,UAAU,KAAK,KAAK,OAAO,WAAW,SAAS,GACxF,iBACH;AAAA;AAAA;AAAA,EACF;AAGF,SACE,gBAAAF,MAACG,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,GACzC;AAAA,oBAAAJ,KAAC,KAAE,KAAK,MAAM,WAAY,gBAAM,YAAW;AAAA,IAC3C,gBAAAA,KAACI,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,gBAAgB,WAAW,GACjD,0BAAAH,MAACG,OAAA,EAAK,OAAO,EAAE,eAAe,OAAO,KAAK,KAAK,MAAM,GAAG,GACrD;AAAA,YAAM,QAAQ,aAAM,MAAM,UAAU,MAAM,aAAa;AAAA,MACvD,MAAM,SAAS,aAAM,MAAM,WAAW,MAAM,cAAc;AAAA,OAC7D,GACF;AAAA,KACF;AAEJ;;;AChEA,OAAkB;AAClB,SAAS,mBAAmB,QAAAC,OAAM,QAAAC,aAAY;AA0CxC,SACE,OAAAC,MADF,QAAAC,aAAA;AAnBC,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOG;AACD,QAAM,OAAO,QAAQ;AAErB,MAAI,QAAQ;AACV,WACE,gBAAAA,MAACC,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,GACzC;AAAA,sBAAAF,KAAC,KAAE,KAAK,SAAS,UAAU,MAAM,uBAAuB,MAAM,qBAC3D,mBAAS,UAAU,MAAM,wBAAwB,MAAM,sBAC1D;AAAA,MACA,gBAAAA,KAAC,qBAAkB,oBAAmB,uBAAsB,OAAO,KAAK,MAAM,eAAe;AAAA,OAC/F;AAAA,EAEJ;AAEA,SACE,gBAAAC,MAACC,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,GACzC;AAAA,oBAAAF,KAAC,KAAE,KAAK,SAAS,UAAU,MAAM,uBAAuB,MAAM,qBAC3D,mBAAS,UAAU,MAAM,wBAAwB,MAAM,sBAC1D;AAAA,IAEC,KAAK,IAAI,CAAC,MAAM;AAEf,YAAM,UAAU,EAAE,UACd,EAAE,WAAW,WACX,MAAM,QAAQ,EAAE,OAAO,IACvB,MAAM,QAAQ,EAAE,OAAO,IACzB;AACJ,YAAM,WAAW,UAAU,GAAG,EAAE,KAAK,KAAK,OAAO,KAAK,EAAE;AAExD,aACE,gBAAAC,MAAC,QACC;AAAA,wBAAAD;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,OAAO,KAAK,MAAM;AAAA,cAClB,UAAU,KAAK,KAAK;AAAA,cACpB,YAAY,KAAK,WAAW;AAAA,cAC5B,YAAY,KAAK,OAAO;AAAA,YAC1B;AAAA,YAEC,YAAE;AAAA;AAAA,QACL;AAAA,QAEC,EAAE,aACD,gBAAAF;AAAA,UAACE;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,OAAO,KAAK,MAAM;AAAA,cAClB,UAAU,KAAK,KAAK;AAAA,cACpB,YAAY,KAAK,WAAW;AAAA,YAC9B;AAAA,YAEC;AAAA,oBAAM;AAAA,cAAM;AAAA,cAAE,EAAE;AAAA;AAAA;AAAA,QACnB,IACE;AAAA,QAEH,UACC,gBAAAH;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,EAAE,WAAW,WAAW,WAAM;AAAA,YACpC,SAAS;AAAA,YACT,OAAO,EAAE,WAAW,WAAW,YAAY;AAAA;AAAA,QAC7C,IACE;AAAA,QAEJ,gBAAAC,MAACC,OAAA,EAAK,OAAO,EAAE,eAAe,OAAO,KAAK,KAAK,MAAM,GAAG,GACtD;AAAA,0BAAAF;AAAA,YAAC;AAAA;AAAA,cACC,MAAI;AAAA,cACJ,QAAQ,WAAW,EAAE,EAAE;AAAA,cACvB,OAAO,MAAM;AAAA,cACb,oBAAoB,GAAG,MAAM,MAAM,KAAK,QAAQ;AAAA,cAChD,SAAS,MAAM,SAAS,CAAC;AAAA;AAAA,UAC3B;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAI;AAAA,cACJ,SAAQ;AAAA,cACR,QAAQ,UAAU,EAAE,EAAE;AAAA,cACtB,OAAO,MAAM;AAAA,cACb,oBAAoB,GAAG,MAAM,UAAU,KAAK,QAAQ;AAAA,cACpD,SAAS,MAAM,SAAS,CAAC;AAAA;AAAA,UAC3B;AAAA,WACF;AAAA,WAhDS,EAAE,EAiDb;AAAA,IAEJ,CAAC;AAAA,IAED,gBAAAA,KAAC,OAAI,SAAQ,aAAY,QAAO,iBAAgB,OAAO,MAAM,SAAS,SAAS,OAAO;AAAA,KACxF;AAEJ;;;AC7HA,OAAkB;AAClB,SAAS,QAAAI,OAAM,QAAAC,aAAY;AAiDrB,SACE,OAAAC,MADF,QAAAC,aAAA;AA5BC,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,OAAO,QAAQ;AAErB,QAAM,UAAU;AAAA,IACd,MAAM,EAAE,GAAG,MAAM,iBAAiB,GAAG,MAAM,eAAe;AAAA,IAC1D,OAAO,EAAE,GAAG,MAAM,iBAAiB,GAAG,MAAM,gBAAgB;AAAA,IAC5D,QAAQ,EAAE,GAAG,MAAM,sBAAsB,GAAG,MAAM,iBAAiB;AAAA;AAAA;AAAA,IAGnE,SAAI,EAAE,GAAG,MAAM,eAAe,GAAG,MAAM,cAAc;AAAA,EACvD,EAAE,GAAG;AAEL,QAAM,aAAa,YAAY,WAAW,MAAM,0BAA0B,QAAQ;AAClF,QAAM,YAAY,YAAY,WAAW,GAAG,MAAM,eAAe,IAAI,QAAQ,CAAC,KAAK,QAAQ;AAE3F,SACE,gBAAAA,MAACC,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,gBAAgB,UAAU,KAAK,KAAK,MAAM,GAAG,GACnE;AAAA,oBAAAD,MAACC,OAAA,EAAK,OAAO,EAAE,YAAY,UAAU,KAAK,KAAK,MAAM,GAAG,GACtD;AAAA,sBAAAF;AAAA,QAACG;AAAA,QAAA;AAAA,UACC,6BAA2B;AAAA,UAC3B,2BAA0B;AAAA,UAC1B,OAAO,EAAE,UAAU,KAAK,KAAK,KAAK,GAAG,OAAO,QAAQ,UAAO,KAAK,MAAM,UAAU,KAAK,MAAM,QAAQ;AAAA,UAElG,kBAAQ,UAAO,WAAM;AAAA;AAAA,MACxB;AAAA,MAEA,gBAAAH,KAAC,KAAG,sBAAW;AAAA,MAEd,YAAY,WAAW,gBAAAA,KAAC,UAAO,MAAK,UAAI,MAAK,WAAU,UAAU,MAAM,qBAAqB,IAAK;AAAA,MACjG,YAAY,cAAc,gBAAAA,KAAC,UAAO,MAAK,aAAK,MAAK,QAAO,UAAU,MAAM,kBAAkB,IAAK;AAAA,MAEhG,gBAAAA;AAAA,QAACG;AAAA,QAAA;AAAA,UACC,QAAO;AAAA,UACP,mBAAkB;AAAA,UAClB,yBAAwB;AAAA,UACxB,OAAO;AAAA,YACL,OAAO,KAAK,MAAM;AAAA,YAClB,UAAU,KAAK,KAAK;AAAA,YACpB,YAAY,KAAK,WAAW;AAAA,YAC5B,WAAW;AAAA,UACb;AAAA,UAEC;AAAA;AAAA,MACH;AAAA,MAEC,aACC,gBAAAH,KAAC,QAAM,sBAAY,WAAW,MAAM,sBAAsB,UAAU,IAAI,MAAM,WAAW,UAAU,GAAE,IACnG;AAAA,OACN;AAAA,IAEA,gBAAAA,KAAC,OAAI,QAAO,qBAAoB,OAAO,MAAM,iBAAiB,SAAS,QAAQ;AAAA,KACjF;AAEJ;;;ACrFA,OAAkB;AAClB,SAAS,qBAAAI,oBAAmB,YAAY,QAAAC,OAAM,QAAAC,aAAY;;;ACkB1D,IAAM,OAAwD;AAAA,EAC5D,IAAI;AAAA,EACJ,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,YAAY;AACd;AAGO,SAAS,cAAc,KAAqB;AACjD,QAAM,IAAI,IAAI,KAAK,GAAG;AACtB,MAAI,OAAO,MAAM,EAAE,QAAQ,CAAC,EAAG,QAAO;AACtC,SAAO,IAAI,KAAK,eAAe,SAAS,EAAE,KAAK,WAAW,OAAO,OAAO,CAAC,EAAE,OAAO,CAAC;AACrF;AASO,SAAS,cACd,QACA,MACA,YACe;AACf,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,EAAE,MAAM,KAAK,IAAI,SAAS,WAAW,OAAO,WAAW,OAAO,MAAM,GAAG;AAAA,IAChF,KAAK;AACH,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,SAAS;AAAA,QACT,OAAO;AAAA,QACP,OAAO,aAAa,MAAM,SAAS,cAAc,UAAU,CAAC,IAAI,MAAM;AAAA,MACxE;AAAA,IACF,KAAK;AACH,aAAO,EAAE,MAAM,KAAK,UAAU,SAAS,YAAY,OAAO,WAAW,OAAO,MAAM,SAAS;AAAA,IAC7F,KAAK;AACH,aAAO,EAAE,MAAM,KAAK,QAAQ,SAAS,gBAAa,OAAO,QAAQ,OAAO,MAAM,OAAO;AAAA,IACvF,KAAK;AACH,aAAO,SAAS,UACZ,EAAE,MAAM,KAAK,QAAQ,SAAS,UAAU,OAAO,WAAW,OAAO,MAAM,OAAO,IAC9E,EAAE,MAAM,KAAK,QAAQ,SAAS,UAAU,OAAO,WAAW,OAAO,MAAM,OAAO;AAAA,IACpF,KAAK;AACH,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,SAAS;AAAA,QACT,OAAO;AAAA,QACP,OAAO,MAAM;AAAA,MACf;AAAA,IACF,KAAK;AACH,aAAO,EAAE,MAAM,KAAK,UAAU,SAAS,mBAAgB,OAAO,WAAW,OAAO,MAAM,SAAS;AAAA,IACjG,KAAK;AACH,aAAO,EAAE,MAAM,KAAK,QAAQ,SAAS,UAAU,OAAO,UAAU,OAAO,MAAM,OAAO;AAAA,EACxF;AACF;AAGO,IAAM,gBAA+B;AAAA,EAC1C,MAAM,KAAK;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO,MAAM;AACf;;;ADrDM,gBAAAC,MAgBU,QAAAC,aAhBV;AAfC,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,OAAO,QAAQ;AAErB,SACE,gBAAAA,MAACC,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,GACzC;AAAA,oBAAAF,KAAC,KAAE,KAAK,MAAM,WAAY,gBAAM,YAAW;AAAA,IAE1C,SACC,gBAAAA,KAACG,oBAAA,EAAkB,oBAAmB,2BAA0B,OAAO,KAAK,MAAM,eAAe,IAC/F,MAAM,WAAW,IACnB,gBAAAH,KAAC,QAAM,gBAAM,SAAQ,IAErB,gBAAAA,KAAC,cAAW,OAAO,EAAE,MAAM,EAAE,GAAG,uBAAuB,EAAE,KAAK,KAAK,MAAM,GAAG,GACzE,gBAAM,IAAI,CAAC,QAAQ;AAClB,YAAM,SAAS,IAAI,YAAY;AAC/B,YAAM,IAAI,SAAS,gBAAgB,cAAc,IAAI,QAAQ,IAAI,MAAM,IAAI,UAAU;AACrF,YAAM,SAAS,SAAS,IAAI,YAAY,IAAI;AAC5C,YAAM,OAAO,SAAS,SAAY,IAAI;AAEtC,aACE,gBAAAC,MAAC,QAAkB,QAAQ,QACzB;AAAA,wBAAAA,MAAC,QACE;AAAA,mBAAS,MAAM,gBAAgB,MAAM,QAAQ,IAAI,EAAE;AAAA,UAAE;AAAA,UAAG;AAAA,UACxD,IAAI,SAAS,UAAU,aAAU;AAAA,WACpC;AAAA,QAEA,gBAAAD;AAAA,UAACI;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,OAAO,KAAK,MAAM;AAAA,cAClB,UAAU,KAAK,KAAK;AAAA,cACpB,YAAY,KAAK,WAAW;AAAA,YAC9B;AAAA,YAEC,cAAI;AAAA;AAAA,QACP;AAAA,QAEA,gBAAAH,MAACC,OAAA,EAAK,OAAO,EAAE,KAAK,KAAK,MAAM,GAAG,GAChC;AAAA,0BAAAF,KAAC,cAAW,MAAM,EAAE,MAAM,SAAS,EAAE,SAAS,OAAO,EAAE,OAAO;AAAA,UAC9D,gBAAAA,KAAC,QAAM,YAAE,OAAM;AAAA,WACjB;AAAA,QAEC,OACC,gBAAAC;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,iBAAiB,KAAK,WAAW;AAAA,cACjC,iBAAiB,KAAK,MAAM;AAAA,cAC5B,aAAa,KAAK,MAAM;AAAA,cACxB,KAAK,KAAK,MAAM;AAAA,YAClB;AAAA,YAEA;AAAA,8BAAAF,KAACI,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,eAAe,UAAU,KAAK,KAAK,MAAM,GACvE,uBAAa,MAAM,QAAQ,UAAU,IAAI,MAAM,iBAClD;AAAA,cACA,gBAAAJ;AAAA,gBAACI;AAAA,gBAAA;AAAA,kBACC,OAAO;AAAA,oBACL,OAAO,KAAK,MAAM;AAAA,oBAClB,UAAU,KAAK,KAAK;AAAA,oBACpB,YAAY,KAAK,WAAW;AAAA,kBAC9B;AAAA,kBAEC,eAAK;AAAA;AAAA,cACR;AAAA;AAAA;AAAA,QACF,IACE;AAAA,WA3CK,MA4CX;AAAA,IAEJ,CAAC,GACH;AAAA,IAGF,gBAAAJ,KAAC,OAAI,QAAO,aAAY,OAAO,MAAM,UAAU,SAAS,QAAQ;AAAA,KAClE;AAEJ;;;AExGA,SAAS,QAAQ,gBAAgB,SAAS,oBAAmD;AAC7F,SAAgB,aAAa,WAAAK,UAAS,QAAQ,YAAAC,iBAAgC;AAC9E,SAAS,SAAAC,QAAO,aAAAC,YAAW,QAAAC,OAAM,QAAAC,aAAgE;AAoG3F,SAsBE,OAAAC,MAtBF,QAAAC,aAAA;AA5EC,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GASG;AACD,QAAM,OAAO,QAAQ;AACrB,QAAM,CAAC,SAAS,UAAU,IAAIC,UAAsB,QAAQ;AAC5D,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,KAAK;AAC9C,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAqB,CAAC,CAAC;AAC/C,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAmD,IAAI;AACjF,QAAM,QAAQ,OAAoB,CAAC,CAAC;AAGpC,QAAM,UAAUC,SAAQ,MAAM;AAC5B,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,IAAI,KAAK,IAAI,MAAM,QAAQ,MAAM,OAAO,MAAM,SAAS,MAAM,MAAM;AACzE,WAAO,EAAE,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC,GAAG,QAAQ,KAAK,MAAM,MAAM,SAAS,CAAC,EAAE;AAAA,EACpF,GAAG,CAAC,OAAO,MAAM,OAAO,MAAM,MAAM,CAAC;AAErC,QAAM,aAAaA;AAAA,IACjB,MAAO,UAAU,cAAc,IAAI,CAAC,MAAM,OAAO,GAAG,cAAc,OAAO,CAAC,IAAI,CAAC;AAAA,IAC/E,CAAC,eAAe,cAAc,OAAO;AAAA,EACvC;AAEA,QAAM,WAAW,YAAY,CAAC,MAAyB;AACrD,UAAM,EAAE,OAAO,OAAO,IAAI,EAAE,YAAY;AACxC,aAAS,EAAE,OAAO,OAAO,CAAC;AAAA,EAC5B,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ,CAAC,OAAyC,EAAE,GAAG,EAAE,YAAY,WAAW,GAAG,EAAE,YAAY,UAAU;AAEjH,QAAM,UAAU,CAAC,MAA6B;AAC5C,QAAI,CAAC,QAAS;AACd,UAAM,IAAI,MAAM,CAAC;AAEjB,UAAM,QAAQ,KAAK,UAAU,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC;AACjD,QAAI,SAAS,GAAG;AACd,cAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,CAAC;AAC9C;AAAA,IACF;AACA,QAAI,YAAY,QAAQ;AACtB,YAAM,IAAI,aAAa,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,QAAQ,KAAK,MAAM,GAAG,OAAO;AAChF,UAAI,EAAG,SAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;AAC/B;AAAA,IACF;AACA,UAAM,UAAU,CAAC,CAAC;AAAA,EACpB;AAEA,QAAM,SAAS,CAAC,MAA6B;AAC3C,QAAI,YAAY,YAAY,MAAM,QAAQ,WAAW,EAAG;AACxD,UAAM,QAAQ,KAAK,MAAM,CAAC,CAAC;AAAA,EAC7B;AAEA,QAAM,YAAY,MAAM;AACtB,QAAI,YAAY,YAAY,CAAC,WAAW,MAAM,QAAQ,WAAW,EAAG;AACpE,UAAM,SAAS,eAAe,MAAM,SAAS,YAAY,YAAY,OAAO;AAC5E,UAAM,UAAU,CAAC;AACjB,QAAI,OAAO,OAAQ,SAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC;AAAA,EACrD;AAEA,QAAM,QAAQ,CAAC,IAA8B,MAAc,UAAkB;AAC3E,UAAM,QAAQ,OAAO,aAAa,WAAW,YAAY,MAAM,CAAC;AAChE,WACE,gBAAAF;AAAA,MAACG;AAAA,MAAA;AAAA,QAEC,QAAQ,WAAW,EAAE;AAAA,QACrB,mBAAkB;AAAA,QAClB,oBAAoB;AAAA,QACpB,oBAAoB,EAAE,UAAU,MAAM;AAAA,QACtC,SAAS,MAAO,OAAO,aAAa,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,WAAW,EAAE;AAAA,QAC1E,OAAO;AAAA,UACL,MAAM;AAAA,UACN,WAAW,KAAK;AAAA,UAChB,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,KAAK,KAAK,MAAM;AAAA,UAChB,SAAS,KAAK,MAAM;AAAA,UACpB,cAAc,KAAK,OAAO;AAAA,UAC1B,aAAa,KAAK;AAAA,UAClB,aAAa,KAAK,MAAM;AAAA,UACxB,mBAAmB,QAAQ,KAAK,WAAW,IAAI,KAAK;AAAA,UACpD,mBAAmB,QAAQ,KAAK,MAAM,cAAc,KAAK,MAAM;AAAA,UAC/D,iBAAiB,QAAQ,KAAK,MAAM,gBAAgB;AAAA,QACtD;AAAA,QAEA;AAAA,0BAAAJ,KAACK,OAAA,EAAK,6BAA2B,MAAC,2BAA0B,MAAK,OAAO,EAAE,UAAU,KAAK,KAAK,KAAK,GAChG,gBACH;AAAA,UACA,gBAAAL;AAAA,YAACK;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,gBACL,OAAO,KAAK,MAAM;AAAA,gBAClB,UAAU,KAAK,KAAK;AAAA,gBACpB,YAAY,QAAQ,KAAK,OAAO,WAAW,KAAK,OAAO;AAAA,cACzD;AAAA,cAEC;AAAA;AAAA,UACH;AAAA;AAAA;AAAA,MAhCK;AAAA,IAiCP;AAAA,EAEJ;AAEA,QAAM,OAAO,MAAM,gBAAgB,WAAW,QAAQ,KAAK,QAAQ,QAAQ;AAE3E,SACE,gBAAAJ,MAACK,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,GACzC;AAAA,oBAAAN,KAAC,KAAE,KAAK,MAAM,kBAAmB,gBAAM,mBAAkB;AAAA,IAEzD,gBAAAC,MAACK,OAAA,EAAK,mBAAkB,WAAU,oBAAoB,MAAM,WAAW,OAAO,EAAE,eAAe,OAAO,KAAK,KAAK,MAAM,GAAG,GACtH;AAAA,YAAM,QAAQ,UAAK,MAAM,UAAU;AAAA,MACnC,MAAM,UAAU,UAAK,MAAM,QAAQ;AAAA,MACnC,MAAM,YAAY,UAAK,MAAM,cAAc;AAAA,OAC9C;AAAA,IAEA,gBAAAN;AAAA,MAACM;AAAA,MAAA;AAAA,QACC,QAAO;AAAA,QACP;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,WAAW,KAAK,QAAQ;AAAA,UACxB,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,iBAAiB,YAAY;AAAA,UAC7B,cAAc,KAAK,OAAO;AAAA,UAC1B,UAAU;AAAA,QACZ;AAAA,QAEC,oBACC,gBAAAL;AAAA,UAACK;AAAA,UAAA;AAAA,YACC,KAAK;AAAA,YACL,aAAa;AAAA,YACb,QAAO;AAAA,YACP,mBAAkB;AAAA,YAClB,oBAAoB;AAAA,YACpB,2BAA2B,MAAM,CAAC;AAAA,YAClC,0BAA0B,MAAM,CAAC;AAAA,YACjC,kBAAkB;AAAA,YAClB,iBAAiB;AAAA,YACjB,oBAAoB;AAAA,YACpB,sBAAsB;AAAA,YACtB,OAAO,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,iBAAiB,YAAY,gBAAgB;AAAA,YAEpG;AAAA,8BAAAN;AAAA,gBAACO;AAAA,gBAAA;AAAA,kBACC,QAAO;AAAA,kBACP,QAAQ,EAAE,KAAK,MAAM,IAAI;AAAA,kBACzB,YAAY,WAAW,YAAY,iBAAiB;AAAA,kBACpD,OAAO,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO;AAAA,kBACtD,kCAAgC;AAAA;AAAA,cAClC;AAAA,cAEC,WAAW,IAAI,CAAC,GAAG,MAClB,gBAAAP;AAAA,gBAACM;AAAA,gBAAA;AAAA,kBAEC,QAAQ,YAAY,CAAC;AAAA,kBACrB,eAAc;AAAA,kBACd,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,MAAM,EAAE;AAAA,oBACR,KAAK,EAAE;AAAA,oBACP,OAAO,EAAE;AAAA,oBACT,QAAQ,EAAE;AAAA,oBACV,iBAAiB,YAAY;AAAA,oBAC7B,aAAa,KAAK,WAAW;AAAA,oBAC7B,aAAa,YAAY;AAAA,oBACzB,YAAY;AAAA,oBACZ,gBAAgB;AAAA,kBAClB;AAAA,kBAEC,WAAC,aACA,gBAAAL,MAACI,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,eAAe,UAAU,KAAK,KAAK,MAAM,GAAG,eAAe,GAAG;AAAA;AAAA,oBACzF,MAAM;AAAA,qBACZ,IACE;AAAA;AAAA,gBApBC,QAAQ,CAAC;AAAA,cAqBhB,CACD;AAAA,cAEA,KAAK,IAAI,CAAC,GAAG,MACZ,gBAAAL;AAAA,gBAACM;AAAA,gBAAA;AAAA,kBAEC,QAAQ,SAAS,CAAC;AAAA,kBAClB,eAAc;AAAA,kBACd,OAAO,EAAE,UAAU,YAAY,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,EAAE,OAAO,QAAQ,EAAE,QAAQ,iBAAiB,YAAY,UAAU;AAAA;AAAA,gBAHxH,QAAQ,CAAC;AAAA,cAIhB,CACD;AAAA;AAAA;AAAA,QACH,IACE;AAAA;AAAA,IACN;AAAA,IAEC,WAAW,SAAS,gBAAAL,MAAC,QAAK;AAAA;AAAA,MAAI,MAAM;AAAA,OAAmB,IAAU;AAAA,IACjE,KAAK,SAAS,gBAAAD,KAAC,QAAM,gBAAM,WAAU,IAAU;AAAA,IAC/C,WAAW,gBAAAA,KAAC,QAAM,gBAAM,cAAa,IAAU;AAAA,IAEhD,gBAAAC,MAACK,OAAA,EAAK,OAAO,EAAE,KAAK,KAAK,MAAM,GAAG,GAChC;AAAA,sBAAAN,KAAC,OAAI,SAAQ,UAAS,QAAO,gBAAe,MAAK,aAAK,OAAO,MAAM,aAAa,SAAS,SAAS,UAAU,YAAY;AAAA,MACxH,gBAAAA,KAAC,OAAI,QAAO,YAAW,OAAO,MAAM,mBAAmB,SAAS,WAAW,UAAU,cAAc,CAAC,SAAS,MAAM,MAAM,iBAAiB;AAAA,OAC5I;AAAA,KACF;AAEJ;;;AToFU,SAsBE,UApBE,OAAAQ,MAFJ,QAAAC,aAAA;AArSV,IAAM,SAAS,EAAE,QAAQ,OAAO,SAAS,KAAK;AAuBvC,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,OAAO,QAAQ;AACrB,QAAM,cAAc,eAAe;AACnC,QAAM,aAAaC,QAAuB,IAAI;AAE9C,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAe,MAAM;AAC7C,QAAM,CAAC,MAAM,OAAO,IAAIA,UAA2B,MAAM;AACzD,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAS,EAAE;AACrC,QAAM,CAAC,MAAM,OAAO,IAAIA,UAA2B,CAAC,CAAC;AACrD,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,KAAK;AAClD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAqC;AACvE,QAAM,CAAC,MAAM,OAAO,IAAIA,UAA2B,CAAC,CAAC;AACrD,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAmB,CAAC,CAAC;AACrD,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,KAAK;AAC1C,QAAM,CAAC,MAAM,OAAO,IAAIA,UAA6B;AACrD,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAgF;AACpH,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAyB,CAAC,CAAC;AACnD,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,KAAK;AAIlD,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwC;AAClE,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAqB,CAAC,CAAC;AAC3D,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAS,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC;AACxE,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,KAAK;AAClD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAsC;AAGpE,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,EAAE,GAAG,OAAO,SAAS,CAAC;AAGzE,QAAM,mBAAmB,cAAc,sBAAsB,aAAa,WAAW;AAErF,QAAM,YAAYC,aAAY,MAAM;AAClC,YAAQ,MAAM;AACd,YAAQ,MAAM;AACd,aAAS,EAAE;AACX,YAAQ,CAAC,CAAC;AACV,iBAAa,MAAS;AACtB,YAAQ,CAAC,CAAC;AACV,gBAAY,CAAC,CAAC;AACd,YAAQ,MAAS;AACjB,kBAAc,MAAS;AACvB,aAAS,MAAS;AAClB,kBAAc,CAAC,CAAC;AAChB,eAAW,MAAS;AACpB,kBAAc,KAAK;AAAA,EACrB,GAAG,CAAC,CAAC;AAEL,QAAM,OAAOA,aAAY,MAAM;AAC7B,WAAO;AACP,cAAU;AAAA,EACZ,GAAG,CAAC,QAAQ,SAAS,CAAC;AAItB,YAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AACb,WAAO,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACtC,SAAK,OAAO,MAAM,MAAM,EAAE,MAAM,MAAM,MAAS;AAE/C,SAAK,OAAO,aAAa,EAAE,KAAK,CAAC,MAAM,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,MAAM,MAAS;AAExF,QAAI,cAAc,MAAO,UAAS,aAAa,KAAK;AAAA,EAEtD,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,WAAWA,aAAY,YAAY;AACvC,kBAAc,IAAI;AAClB,QAAI;AACF,YAAM,IAAI,cAAc,SAAS,EAAE,QAAQ,aAAa,OAAO,IAAI,CAAC;AACpE,cAAQ,MAAM,OAAO,YAAY,IAAI,CAAC,CAAC;AAAA,IACzC,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,MAAM,CAAC;AAEjC,QAAM,WAAWA;AAAA,IACf,OAAO,UAA4B;AACjC,cAAQ,KAAK;AACb,aAAO,MAAM,EAAE,MAAM,kBAAkB,MAAM,MAAM,CAAC;AAEpD,UAAI,UAAU,SAAS;AAErB,gBAAQ,MAAM;AACd;AAAA,MACF;AAEA,cAAQ,YAAY;AACpB,YAAM,SAAS;AAAA,IACjB;AAAA,IACA,CAAC,QAAQ,QAAQ;AAAA,EACnB;AAIA,YAAU,MAAM;AACd,QAAI,SAAS,gBAAgB,CAAC,cAAc,KAAK,WAAW,EAAG,SAAQ,MAAM;AAAA,EAC/E,GAAG,CAAC,MAAM,YAAY,KAAK,MAAM,CAAC;AAElC,QAAM,aAAaA;AAAA,IACjB,CAAC,MAAc;AACb,eAAS,CAAC;AACV,cAAQ,OAAO,SAAS,CAAC,CAAC;AAAA,IAC5B;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAOA,QAAM,gBAAgBA,aAAY,YAAY;AAC5C,QAAI,CAAC,aAAa,QAAS;AAC3B,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,YAAQ,MAAS;AACjB,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM;AACpD,YAAM,MAAM,MAAM,QAAQ,QAAQ,OAAO;AACzC,YAAM,WAAW,MAAM,QAAQ,IAAI,OAAO,KAAK,EAAE,IAAI,CAAC,MAAM,QAAQ,QAAQ,CAAC,CAAC,CAAC;AAC/E,UAAI,KAAK;AACP,wBAAgB,EAAE,OAAO,IAAI,OAAO,QAAQ,IAAI,OAAO,CAAC;AACxD;AAAA,UACE,SACG,OAAO,CAAC,MAAqB,MAAM,IAAI,EACvC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,IAAI,GAAG,GAAG,EAAE,IAAI,IAAI,GAAG,OAAO,EAAE,OAAO,QAAQ,EAAE,OAAO,EAAE;AAAA,QACtF;AAAA,MACF,OAAO;AACL,wBAAgB,EAAE,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,CAAC;AAC9D,sBAAc,CAAC,CAAC;AAAA,MAClB;AACA,eAAS,MAAM;AACf,cAAQ,aAAa;AAAA,IACvB,QAAQ;AACN,cAAQ,MAAM,iBAAiB;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAMhB,QAAM,eAAeA,aAAY,YAAY;AAC3C,QAAI,CAAC,aAAa,QAAS;AAC3B,kBAAc,IAAI;AAClB,QAAI;AACF,YAAM,WAAW,MAAM,YAAY,QAAQ,QAAQ,YAAY,MAAM;AACrE,YAAM,OAAO,MAAM,YAAY,QAAQ,KAAK,SAAS,GAAG;AACxD,iBAAW,EAAE,MAAM,cAAc,MAAM,OAAO,SAAS,OAAO,QAAQ,SAAS,OAAO,CAAC;AACvF,eAAS,MAAS;AAClB,cAAQ,MAAM;AAAA,IAChB,QAAQ;AACN,cAAQ,MAAM,iBAAiB;AAC/B,cAAQ,MAAM;AAAA,IAChB,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,aAAaA,aAAY,MAAM;AACnC,aAAS,MAAS;AAClB,kBAAc,CAAC,CAAC;AAChB,eAAW,MAAS;AACpB,YAAQ,MAAM;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,OAAOA,aAAY,YAAY;AAEnC,QAAI,SAAS,WAAW,SAAS,UAAU,KAAK,WAAW,KAAK,CAAC,YAAY;AAC3E,cAAQ,YAAY;AACpB,YAAM,SAAS;AACf;AAAA,IACF;AAEA,cAAU,IAAI;AACd,YAAQ,MAAS;AACjB,QAAI;AACF,YAAM,MAAM,MAAM,OAAO,QAAQ;AAAA,QAC/B,MAAM;AAAA,QACN,MAAM;AAAA,QACN,GAAI,UAAU,EAAE,YAAY,QAAQ,IAAI,CAAC;AAAA,QACzC,GAAI,SAAS,UAAU,YAAY,EAAE,qBAAqB,UAAU,GAAG,IAAI,CAAC;AAAA,QAC5E,GAAI,SAAS,SAAS,EAAE,SAAS,gBAAgB,QAAQ,QAAQ,EAAE,IAAI,CAAC;AAAA,MAC1E,CAAU;AAEV,UAAI,IAAI,WAAW,UAAU;AAC3B,sBAAc,EAAE,KAAK,SAAM,GAAI,IAAI,aAAa,EAAE,SAAS,YAAqB,IAAI,CAAC,EAAG,CAAC;AAAA,MAC3F,OAAO;AACL,sBAAc;AAAA,UACZ,KAAK;AAAA,UACL,IAAI,IAAI,WAAW;AAAA,UACnB,GAAI,IAAI,YAAY,WAAW,WAAW,EAAE,SAAS,SAAkB,IAAI,CAAC;AAAA,QAC9E,CAAC;AAAA,MACH;AACA,cAAQ,YAAY;AAAA,IACtB,SAAS,GAAG;AAEV,UAAI,aAAa,sBAAuB,SAAQ,EAAE,WAAW;AAAA,eACpD,aAAa,gBAAiB,SAAQ,EAAE,OAAO;AAAA,UACnD,SAAQ,uBAAuB;AAAA,IACtC,UAAE;AACA,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,QAAQ,MAAM,MAAM,OAAO,SAAS,WAAW,UAAU,KAAK,QAAQ,YAAY,QAAQ,CAAC;AAE/F,QAAM,SAASA;AAAA,IACb,OAAO,MAAsB;AAC3B,gBAAU,IAAI;AACd,UAAI;AACF,cAAM,MAAM,MAAM,OAAO,YAAY,QAAQ,EAAE,EAAE;AACjD,sBAAc,EAAE,KAAK,UAAU,IAAI,IAAI,GAAG,CAAC;AAC3C,gBAAQ,YAAY;AAAA,MACtB,SAAS,GAAG;AACV,gBAAQ,aAAa,kBAAkB,EAAE,UAAU,uBAAuB;AAAA,MAC5E,UAAE;AACA,kBAAU,KAAK;AAAA,MACjB;AAAA,IACF;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,UAAUA,aAAY,YAAY;AACtC,YAAQ,MAAM;AACd,kBAAc,IAAI;AAClB,QAAI;AACF,cAAQ,MAAM,OAAO,SAAS,YAAY,CAAC;AAAA,IAC7C,QAAQ;AACN,cAAQ,CAAC,CAAC;AAAA,IACZ,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,SACE,gBAAAJ;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,aAAW;AAAA,MACX,eAAc;AAAA,MAEd,gBAAgB;AAAA,MAChB,0BAAwB;AAAA,MAExB,0BAAAA,KAACK,OAAA,EAAK,OAAO,EAAE,MAAM,GAAG,iBAAiB,KAAK,MAAM,OAAO,gBAAgB,WAAW,GACpF,0BAAAJ;AAAA,QAACI;AAAA,QAAA;AAAA,UACC,QAAO;AAAA,UACP,0BAAwB;AAAA,UACxB,mBAAkB;AAAA,UAClB,OAAO;AAAA,YACL,iBAAiB,KAAK,MAAM;AAAA,YAC5B,qBAAqB,KAAK,OAAO,KAAK;AAAA,YACtC,sBAAsB,KAAK,OAAO,KAAK;AAAA,YACvC,SAAS,KAAK;AAAA,YACd,KAAK,KAAK,MAAM;AAAA,YAChB,WAAW;AAAA,YACX,WAAW;AAAA,UACb;AAAA,UAEA;AAAA,4BAAAJ,MAACI,OAAA,EAAK,OAAO,EAAE,eAAe,OAAO,gBAAgB,iBAAiB,YAAY,SAAS,GACxF;AAAA,uBAAS,gBACR,gBAAAL,KAAC,OAAI,SAAQ,SAAQ,QAAO,WAAU,MAAK,UAAI,OAAO,MAAM,SAAS,SAAS,YAAY,IACxF,SAAS,UAAU,SAAS,eAC9B,gBAAAA,KAAC,OAAI,SAAQ,SAAQ,QAAO,WAAU,MAAK,UAAI,OAAO,MAAM,SAAS,SAAS,WAAW,IAEzF,gBAAAA,KAACK,OAAA,EAAK;AAAA,cAER,gBAAAL;AAAA,gBAACM;AAAA,gBAAA;AAAA,kBACC,QAAO;AAAA,kBACP,mBAAkB;AAAA,kBAClB,oBAAoB,MAAM;AAAA,kBAC1B,SAAS;AAAA,kBACT,OAAO,EAAE,UAAU,KAAK,OAAO,WAAW,KAAK,OAAO,YAAY,UAAU,gBAAgB,SAAS;AAAA,kBAErG,0BAAAN,KAACO,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,eAAe,UAAU,KAAK,KAAK,KAAK,GAAG,oBAAC;AAAA;AAAA,cAC/E;AAAA,eACF;AAAA,YAEC,OAAO,gBAAAP,KAAC,UAAO,MAAI,MAAC,MAAK,UAAI,MAAK,UAAS,UAAU,MAAM,gBAAgB,IAAI,GAAG,IAAK;AAAA,YAEvF,SAAS,SACR,gBAAAC,MAAA,YACE;AAAA,8BAAAD,KAAC,QAAK,QAAQ,UAAU;AAAA,cACxB,gBAAAA,KAAC,OAAI,SAAQ,SAAQ,QAAO,iBAAgB,MAAK,aAAK,OAAO,MAAM,YAAY,SAAS,SAAS;AAAA,eACnG,IACE;AAAA,YAEH,SAAS,eACR,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA,QAAQ;AAAA,gBACR,UAAU;AAAA,gBACV,UAAU,CAAC,MAAM;AACf,+BAAa,CAAC;AACd,0BAAQ,MAAM;AAAA,gBAChB;AAAA,gBACA,OAAO,MAAO,SAAS,UAAU,KAAK,KAAK,IAAI,QAAQ,MAAM;AAAA;AAAA,YAC/D,IACE;AAAA,YAEH,SAAS,SACR,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA,SAAS;AAAA,gBACT,eAAe,cAAc;AAAA,gBAC7B,eAAe,cAAc;AAAA,gBAC7B,UAAU,OAAO;AAAA,gBACjB,gBAAgB;AAAA,gBAChB,iBAAiB,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;AAAA,gBACnD,GAAI,YAAY,EAAE,WAAW,cAAc,MAAM,aAAa,MAAS,EAAE,IAAI,CAAC;AAAA,gBAC/E;AAAA,gBACA,QAAQ;AAAA,gBACR;AAAA,gBACC,GAAI,mBAAmB,EAAE,eAAe,cAAc,IAAI,CAAC;AAAA,gBAC5D,YAAY,YAAY;AAAA,gBACxB,gBAAgB;AAAA;AAAA,YAClB,IACE;AAAA,YAEH,SAAS,iBAAiB,QACzB,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA,eAAe;AAAA,gBACf;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,SAAS;AAAA,gBACT,WAAW;AAAA;AAAA,YACb,IACE;AAAA,YAEH,SAAS,gBAAgB,aACxB,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK,WAAW;AAAA,gBACf,GAAI,WAAW,KAAK,EAAE,YAAY,WAAW,GAAG,IAAI,CAAC;AAAA,gBACrD,GAAI,WAAW,UAAU,EAAE,SAAS,WAAW,QAAQ,IAAI,CAAC;AAAA,gBAC7D,QAAQ;AAAA;AAAA,YACV,IACE;AAAA,YAEH,SAAS,SACR,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACP,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,gBACpC,QAAQ;AAAA;AAAA,YACV,IACE;AAAA;AAAA;AAAA,MACN,GACF;AAAA;AAAA,EACF;AAEJ;AASA,SAAS,gBAAgB,QAAuB,UAAoB;AAClE,QAAM,KAA8B,CAAC;AACrC,aAAW,KAAK,OAAO,KAAK,OAAO,OAAO,GAAG;AAC3C,QAAI,MAAM,gBAAgB,SAAS,SAAS,CAAC,EAAG,IAAG,CAAC,IAAI;AAAA,EAC1D;AACA,SAAO;AACT;;;AJhVQ,SACE,OAAAQ,MADF,QAAAC,aAAA;AAhFR,IAAM,WAAWC,eAAsC,IAAI;AAwBpD,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AACF,GAcG;AACD,QAAM,CAAC,QAAQ,SAAS,IAAIC,UAAS,KAAK;AAC1C,QAAM,CAAC,cAAc,eAAe,IAAIA,UAA0C;AAClF,QAAM,aAAaC,QAAO,KAAK;AAC/B,QAAM,UAAUA,QAAuB,IAAI;AAC3C,QAAM,SAASC,SAAQ,uBAAuB,CAAC,CAAC;AAEhD,QAAM,OAAOC;AAAA,IACX,OAAO,YAAkC;AACvC,sBAAgB,OAAO;AACvB,gBAAU,IAAI;AAAA,IAChB;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,QAAQA,aAAY,MAAM,UAAU,KAAK,GAAG,CAAC,CAAC;AAKpD,MAAI,CAAC,WAAW,SAAS;AACvB,WAAO,kBAAkB,EAAE,KAAK,CAAC;AACjC,eAAW,UAAU;AAAA,EACvB;AAEA,QAAM,OAAOD,SAAQ,MAAM,SAAS,OAAO,WAAW,GAAG,CAAC,OAAO,WAAW,CAAC;AAC7E,QAAM,QAAQA,SAAyB,OAAO,EAAE,QAAQ,MAAM,MAAM,IAAI,CAAC,QAAQ,MAAM,KAAK,CAAC;AAC7F,QAAM,cAAcA;AAAA,IAClB,OAAO,EAAE,SAAS,cAAc,MAAM,SAAS,OAAO;AAAA,IACtD,CAAC,YAAY,MAAM;AAAA,EACrB;AAEA,SACE,gBAAAL,KAAC,SAAS,UAAT,EAAkB,OAAO,OACxB,0BAAAA,KAAC,mBAAmB,UAAnB,EAA4B,OAAO,aAClC,0BAAAC,MAAC,gBAAa,OAAO,MACnB;AAAA,oBAAAD,KAACO,OAAA,EAAK,KAAK,SAAS,aAAa,OAAO,OAAO,EAAE,MAAM,EAAE,GAAG,QAAO,eAChE,UACH;AAAA,IACA,gBAAAP;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACC,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,QACvC,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,QACpC,QAAQ;AAAA;AAAA,IACV;AAAA,KACF,GACF,GACF;AAEJ;AASO,SAAS,aAA8B;AAC5C,QAAM,IAAIQ,YAAW,QAAQ;AAC7B,MAAI,CAAC,GAAG;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;Ac9HA,SAAgB,aAAAC,YAAW,UAAAC,eAAc;AACzC,SAAS,QAAAC,cAA4C;AA6BjD,gBAAAC,aAAA;AAbG,SAAS,eAAe,EAAE,UAAU,MAAM,GAAiE;AAChH,QAAM,MAAMC,QAAuB,IAAI;AACvC,QAAM,WAAW,eAAe;AAChC,QAAM,YAAY,UAAU,OAAO;AAEnC,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,UAAW;AAChB,WAAO,UAAU,GAAG;AAAA,EACtB,GAAG,CAAC,SAAS,CAAC;AAId,SACE,gBAAAF,MAACG,QAAA,EAAK,KAAU,aAAa,OAAO,OAAc,QAAO,kBACtD,UACH;AAEJ;;;AClCA,SAAS,mBAAAC,wBAAkF;AAC3F,SAAgB,eAAAC,cAAa,aAAAC,YAAW,YAAAC,iBAAgB;AACxD,SAAS,SAAAC,QAAO,aAAAC,YAAW,QAAAC,QAAM,QAAAC,cAAY;;;ACD7C,OAAkB;AAClB,SAAS,SAAS,SAAAC,QAAO,aAAAC,YAAW,cAAAC,aAAY,QAAAC,OAAM,QAAAC,cAAY;;;ACGlE,IAAM,UAAU;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,QAAQ,SAAiB,UAA0B;AACjE,QAAM,MAAM,IAAI,KAAK,OAAO;AAC5B,QAAM,MAAM,IAAI,KAAK,QAAQ;AAC7B,MAAI,OAAO,MAAM,IAAI,QAAQ,CAAC,KAAK,OAAO,MAAM,IAAI,QAAQ,CAAC,EAAG,QAAO;AAEvE,QAAM,aAAa,IAAI,SAAS,MAAM,IAAI,SAAS,KAAK,IAAI,YAAY,MAAM,IAAI,YAAY;AAC9F,SAAO,aACH,GAAG,IAAI,QAAQ,CAAC,UAAK,IAAI,QAAQ,CAAC,KAAK,QAAQ,IAAI,SAAS,CAAC,CAAC,KAC9D,GAAG,IAAI,QAAQ,CAAC,KAAK,QAAQ,IAAI,SAAS,CAAC,CAAC,WAAM,IAAI,QAAQ,CAAC,KAAK,QAAQ,IAAI,SAAS,CAAC,CAAC;AACjG;AAGO,SAAS,mBAAmB,OAA4D;AAC7F,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,SAAO,KAAK,MAAM,MAAM,OAAO,CAAC,KAAKC,OAAM,MAAMA,GAAE,kBAAkB,CAAC,IAAI,MAAM,MAAM;AACxF;;;AD0BU,SACE,OAAAC,OADF,QAAAC,cAAA;AAvCH,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOG;AACD,QAAM,OAAO,QAAQ;AACrB,QAAM,OAAO,MAAM;AAAA,IACjB,QAAQ,MAAM;AAAA,IACd,mBAAmB,QAAQ,KAAK;AAAA,IAChC,QAAQ,QAAQ,SAAS,QAAQ,QAAQ;AAAA,IACzC,QAAQ;AAAA,EACV;AAEA,SACE,gBAAAD,MAACE,QAAA,EAAM,SAAO,MAAC,aAAW,MAAC,eAAc,SAAQ,gBAAgB,QAAQ,0BAAwB,MAC/F,0BAAAF,MAACG,QAAA,EAAK,OAAO,EAAE,MAAM,GAAG,iBAAiB,KAAK,MAAM,OAAO,gBAAgB,WAAW,GACpF,0BAAAF;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,QAAO;AAAA,MACP,0BAAwB;AAAA,MACxB,OAAO;AAAA,QACL,iBAAiB,KAAK,MAAM;AAAA,QAC5B,qBAAqB,KAAK,OAAO,KAAK;AAAA,QACtC,sBAAsB,KAAK,OAAO,KAAK;AAAA,QACvC,SAAS,KAAK;AAAA,QACd,KAAK,KAAK,MAAM;AAAA,QAChB,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,MAEA;AAAA,wBAAAF,OAACE,QAAA,EAAK,OAAO,EAAE,eAAe,OAAO,gBAAgB,iBAAiB,YAAY,SAAS,GACzF;AAAA,0BAAAH,MAAC,OAAI,SAAQ,SAAQ,QAAO,kBAAiB,MAAK,UAAI,OAAO,MAAM,SAAS,SAAS,QAAQ;AAAA,UAC7F,gBAAAA,MAACG,QAAA,EAAK;AAAA,WACR;AAAA,QAEC,OAAO,gBAAAH,MAAC,UAAO,MAAI,MAAC,MAAK,UAAI,MAAK,UAAS,UAAU,MAAM,WAAW,IAAI,GAAG,IAAK;AAAA,QAEnF,gBAAAC,OAACG,aAAA,EAAW,uBAAuB,EAAE,KAAK,KAAK,MAAM,GAAG,GACtD;AAAA,0BAAAJ,MAAC,KAAE,KAAK,MAAM,WAAY,kBAAQ,MAAK;AAAA,UAGvC,gBAAAA;AAAA,YAACK;AAAA,YAAA;AAAA,cACC,mBAAkB;AAAA,cAClB,OAAO;AAAA,gBACL,OAAO,KAAK,MAAM;AAAA,gBAClB,UAAU,KAAK,KAAK;AAAA,gBACpB,YAAY,KAAK,WAAW;AAAA,gBAC5B,YAAY,KAAK,OAAO;AAAA,cAC1B;AAAA,cAEC;AAAA;AAAA,UACH;AAAA,UAEA,gBAAAL,MAACK,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,aAAa,UAAU,KAAK,KAAK,MAAM,YAAY,KAAK,WAAW,KAAK,GACtG,kBAAQ,YACX;AAAA,UAEA,gBAAAJ,OAAC,QACC;AAAA,4BAAAD,MAAC,KAAG,gBAAM,gBAAe;AAAA,YACxB,QAAQ,MAAM,IAAI,CAAC,MAClB,gBAAAC,OAACE,QAAA,EAAgB,OAAO,EAAE,KAAK,KAAK,MAAM,GAAG,GAC3C;AAAA,8BAAAH,MAACK,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,aAAa,UAAU,KAAK,KAAK,MAAM,YAAY,KAAK,WAAW,KAAK,GACtG,YAAE,OACL;AAAA,cACA,gBAAAJ,OAAC,QACE;AAAA,sBAAM,iBAAiB,EAAE,gBAAgB;AAAA,gBACzC,EAAE,aAAa,SAAM,EAAE,UAAU,KAAK;AAAA,iBACzC;AAAA,iBAPS,EAAE,EAQb,CACD;AAAA,aACH;AAAA,UAEC,QAAQ,YAAY,SAAS,IAC5B,gBAAAA,OAAC,QACC;AAAA,4BAAAD,MAAC,KAAE,KAAK,MAAM,uBAAwB,gBAAM,iBAAiB,QAAQ,YAAY,MAAM,GAAE;AAAA,YACxF,QAAQ,YAAY,IAAI,CAAC,MACxB,gBAAAC,OAACE,QAAA,EAAgB,OAAO,EAAE,KAAK,KAAK,MAAM,GAAG,GAC3C;AAAA,8BAAAH,MAACK,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,aAAa,UAAU,KAAK,KAAK,OAAO,YAAY,KAAK,WAAW,MAAM,GACxG,YAAE,OACL;AAAA,cACC,EAAE,aACD,gBAAAJ,OAACI,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,eAAe,UAAU,KAAK,KAAK,OAAO,YAAY,KAAK,WAAW,MAAM,GAC1G;AAAA,sBAAM;AAAA,gBAAM;AAAA,gBAAE,EAAE;AAAA,iBACnB,IACE;AAAA,cACH,EAAE,UACD,gBAAAL;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAM,EAAE,WAAW,WAAW,WAAM;AAAA,kBACpC,SAAS,EAAE,WAAW,WAAW,MAAM,QAAQ,EAAE,OAAO,IAAI,MAAM,QAAQ,EAAE,OAAO;AAAA,kBACnF,OAAO,EAAE,WAAW,WAAW,YAAY;AAAA;AAAA,cAC7C,IACE;AAAA,iBAfK,EAAE,EAgBb,CACD;AAAA,aACH,IACE;AAAA,UAEJ,gBAAAC,OAAC,QACC;AAAA,4BAAAD,MAAC,KAAE,KAAK,MAAM,uBAAwB,gBAAM,kBAAiB;AAAA,YAC7D,gBAAAA,MAAC,QAAM,gBAAM,eAAc;AAAA,aAC7B;AAAA,UAGC,QAAQ,YAAY,CAAC,QAAQ,iBAC5B,gBAAAC,OAACE,QAAA,EAAK,OAAO,EAAE,KAAK,KAAK,MAAM,GAAG,GAChC;AAAA,4BAAAH;AAAA,cAACM;AAAA,cAAA;AAAA,gBACC,QAAO;AAAA,gBACP,mBAAkB;AAAA,gBAClB,oBAAoB,MAAM;AAAA,gBAC1B,SAAS,MAAM,KAAK,QAAQ,QAAQ,OAAO,QAAQ,QAAQ,CAAC;AAAA,gBAC5D,OAAO,EAAE,WAAW,KAAK,OAAO,gBAAgB,SAAS;AAAA,gBAEzD,0BAAAL,OAACI,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,aAAa,UAAU,KAAK,KAAK,MAAM,oBAAoB,YAAY,GAAG;AAAA;AAAA,kBACrG,MAAM;AAAA,mBACZ;AAAA;AAAA,YACF;AAAA,YACA,gBAAAL,MAAC,QAAM,gBAAM,kBAAiB;AAAA,aAChC,IAEA,gBAAAA,MAAC,QAAM,gBAAM,mBAAkB;AAAA,UAGjC,gBAAAC,OAACI,OAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,aAAa,UAAU,KAAK,KAAK,MAAM,YAAY,KAAK,WAAW,KAAK,GAAG;AAAA;AAAA,YACtG,MAAM;AAAA,aACZ;AAAA,WACF;AAAA,QAEA,gBAAAL;AAAA,UAAC;AAAA;AAAA,YACC,QAAO;AAAA,YACP,OAAO,MAAM;AAAA,YACb,UAAU,CAAC,YAAY;AAAA,YACvB,MAAM,WAAW,MAAM,aAAa,MAAM;AAAA,YAC1C,SAAS;AAAA;AAAA,QACX;AAAA;AAAA;AAAA,EACF,GACF,GACF;AAEJ;;;AD3DQ,SA4CJ,YAAAO,WA3CM,OAAAC,OADF,QAAAC,cAAA;AAjFD,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AACF,GAKG;AACD,QAAM,EAAE,OAAO,IAAI,WAAW;AAC9B,QAAM,OAAO,QAAQ;AAErB,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAiC;AACzD,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAwC;AAC5E,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,KAAK;AACpD,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,KAAK;AAClD,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,KAAK;AAC1C,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,KAAK;AAC1C,QAAM,CAAC,MAAM,OAAO,IAAIA,UAA6B;AAIrD,EAAAC,WAAU,MAAM;AACd,QAAI,OAAO,YAAa;AACxB,QAAI,UAAU;AACd,SAAK,OAAO,SACT,KAAK,EACL,KAAK,CAAC,SAAS;AACd,UAAI,CAAC,QAAS;AACd,cAAQ,IAAI;AAEZ,oBAAc,KAAK,eAAe,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS,CAAC;AAAA,IACvE,CAAC,EAGA,MAAM,MAAM,MAAS;AACxB,WAAO,MAAM;AACX,gBAAU;AAAA,IACZ;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,SAASC,aAAY,YAAY;AACrC,QAAI,CAAC,gBAAiB;AACtB,cAAU,IAAI;AACd,YAAQ,MAAS;AACjB,QAAI;AACF,YAAM,KAAK,MAAM,OAAO,SAAS,OAAO,eAAe;AACvD,oBAAc,EAAE;AAChB,qBAAe,KAAK;AACpB,kBAAY,EAAE;AAAA,IAChB,SAAS,GAAG;AACV,cAAQ,aAAaC,mBAAkB,EAAE,UAAU,uBAAuB;AAAA,IAC5E,UAAE;AACA,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,QAAQ,iBAAiB,SAAS,CAAC;AAEvC,QAAM,QAAQD,aAAY,YAAY;AACpC,QAAI,CAAC,WAAY;AACjB,cAAU,IAAI;AACd,QAAI;AACF,YAAM,OAAO,SAAS,SAAS,WAAW,EAAE;AAC5C,oBAAc,MAAS;AACvB,oBAAc,KAAK;AACnB,kBAAY,IAAI;AAAA,IAClB,SAAS,GAAG;AACV,cAAQ,aAAaC,mBAAkB,EAAE,UAAU,uBAAuB;AAAA,IAC5E,UAAE;AACA,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,QAAQ,YAAY,SAAS,CAAC;AAGlC,QAAM,aAAa,aAAa,SAAY,MAAM,YAAY,CAAC;AAC/D,QAAM,UAAmC,YAAY,WAAW,YAAY;AAE5E,MAAI,CAAC,QAAS,QAAO;AAErB,MAAI,YAAY;AACd,WACE,gBAAAJ,OAACK,QAAA,EAAK,QAAO,sBAAqB,oBAAoB,MAAM,kBAAkB,OAAO,EAAE,KAAK,KAAK,MAAM,GAAG,GACxG;AAAA,sBAAAL,OAAC,QACC;AAAA,wBAAAD,MAAC,KAAE,KAAK,MAAM,kBAAkB,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,GAAG,WAAW,cAAc,QAAQ,WAAW,GACrH,kBAAQ,MACX;AAAA,QACA,gBAAAA,MAAC,QAAM,gBAAM,0BAAyB;AAAA,QAEtC,gBAAAA,MAAC,OAAI,SAAQ,SAAQ,QAAO,UAAS,MAAK,aAAK,OAAO,MAAM,OAAO,SAAS,MAAM,cAAc,IAAI,GAAG;AAAA,SACzG;AAAA,MAEC,aACC,gBAAAA,MAACO,QAAA,EAAM,SAAO,MAAC,aAAW,MAAC,eAAc,QAAO,gBAAgB,MAAM,cAAc,KAAK,GAAG,0BAAwB,MAClH,0BAAAP,MAACM,QAAA,EAAK,OAAO,EAAE,MAAM,GAAG,iBAAiB,KAAK,MAAM,OAAO,gBAAgB,YAAY,SAAS,KAAK,MAAM,GAAG,GAC5G,0BAAAL;AAAA,QAACK;AAAA,QAAA;AAAA,UACC,QAAO;AAAA,UACP,0BAAwB;AAAA,UACxB,OAAO;AAAA,YACL,iBAAiB,KAAK,MAAM;AAAA,YAC5B,cAAc,KAAK,OAAO;AAAA,YAC1B,aAAa,KAAK;AAAA,YAClB,aAAa,KAAK,MAAM;AAAA,YACxB,SAAS,KAAK,MAAM;AAAA,YACpB,KAAK,KAAK,MAAM;AAAA,UAClB;AAAA,UAEA;AAAA,4BAAAN,MAAC,KAAG,gBAAM,aAAY;AAAA,YACtB,gBAAAA,MAACQ,QAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,aAAa,UAAU,KAAK,KAAK,MAAM,YAAY,KAAK,WAAW,KAAK,GACtG,gBAAM,WAAW,QAAQ,IAAI,GAChC;AAAA,YACA,gBAAAP,OAACK,QAAA,EAAK,OAAO,EAAE,eAAe,OAAO,KAAK,KAAK,MAAM,GAAG,GAEtD;AAAA,8BAAAN,MAAC,OAAI,MAAI,MAAC,SAAQ,aAAY,QAAO,gBAAe,OAAO,MAAM,aAAa,SAAS,MAAM,cAAc,KAAK,GAAG;AAAA,cACnH,gBAAAA,MAAC,OAAI,MAAI,MAAC,SAAQ,UAAS,QAAO,kBAAiB,MAAK,aAAK,OAAO,MAAM,cAAc,UAAU,QAAQ,SAAS,MAAM,KAAK,MAAM,GAAG;AAAA,eACzI;AAAA;AAAA;AAAA,MACF,GACF,GACF,IACE;AAAA,OACN;AAAA,EAEJ;AAEA,MAAI,CAAC,cAAc,OAAQ,QAAO;AAElC,SACE,gBAAAC,OAAAF,WAAA,EACE;AAAA,oBAAAE;AAAA,MAACK;AAAA,MAAA;AAAA,QACC,QAAO;AAAA,QACP,oBAAoB,MAAM;AAAA,QAC1B,OAAO;AAAA,UACL,iBAAiB,KAAK,MAAM;AAAA,UAC5B,cAAc,KAAK,OAAO;AAAA,UAC1B,aAAa,KAAK;AAAA,UAClB,aAAa,KAAK,MAAM;AAAA,UACxB,SAAS,KAAK,MAAM;AAAA,UACpB,KAAK,KAAK,MAAM;AAAA,QAClB;AAAA,QAEA;AAAA,0BAAAL,OAACK,QAAA,EAAK,OAAO,EAAE,eAAe,OAAO,KAAK,KAAK,MAAM,IAAI,YAAY,aAAa,GAChF;AAAA,4BAAAN,MAACQ,QAAA,EAAK,6BAA2B,MAAC,2BAA0B,MAAK,OAAO,EAAE,UAAU,KAAK,KAAK,GAAG,GAAG,uBAEpG;AAAA,YACA,gBAAAP,OAACK,QAAA,EAAK,OAAO,EAAE,MAAM,GAAG,KAAK,KAAK,MAAM,GAAG,GACzC;AAAA,8BAAAN,MAACQ,QAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,aAAa,UAAU,KAAK,KAAK,MAAM,YAAY,KAAK,WAAW,KAAK,GACtG,gBAAM,cAAc,QAAQ,IAAI,GACnC;AAAA,cACA,gBAAAR,MAAC,QAAM,gBAAM,oBAAoB,QAAQ,WAAW,GAAE;AAAA,eACxD;AAAA,YAEA,gBAAAA;AAAA,cAACS;AAAA,cAAA;AAAA,gBACC,QAAO;AAAA,gBACP,mBAAkB;AAAA,gBAClB,oBAAoB,MAAM;AAAA,gBAC1B,SAAS,MAAM,UAAU,IAAI;AAAA,gBAC7B,OAAO,EAAE,UAAU,KAAK,OAAO,WAAW,KAAK,OAAO,YAAY,UAAU,gBAAgB,SAAS;AAAA,gBAErG,0BAAAT,MAACQ,QAAA,EAAK,OAAO,EAAE,OAAO,KAAK,MAAM,eAAe,UAAU,KAAK,KAAK,KAAK,GAAG,oBAAC;AAAA;AAAA,YAC/E;AAAA,aACF;AAAA,UACC,QAAQ,CAAC,cAAc,gBAAAR,MAAC,UAAO,MAAI,MAAC,MAAK,UAAI,MAAK,UAAS,UAAU,MAAM,WAAW,IAAI,GAAG,IAAK;AAAA,UACnG,gBAAAA,MAAC,OAAI,SAAQ,aAAY,QAAO,WAAU,OAAO,MAAM,QAAQ,SAAS,MAAM,eAAe,IAAI,GAAG;AAAA;AAAA;AAAA,IACtG;AAAA,IAEC,cACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,UAAU,CAAC,CAAC;AAAA,QACZ;AAAA,QACC,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,QACxB,UAAU,MAAM,KAAK,OAAO;AAAA,QAC5B,QAAQ,MAAM,eAAe,KAAK;AAAA;AAAA,IACpC,IACE;AAAA,KACN;AAEJ;;;AGhLO,SAAS,cAAc,OAAyC;AACrE,SAAO;AAAA,IACL,KAAK,CAAC,QAAQ,MAAM,QAAQ,GAAG;AAAA,IAC/B,KAAK,CAAC,KAAK,UAAU,MAAM,QAAQ,KAAK,KAAK;AAAA,IAC7C,QAAQ,CAAC,QAAQ,MAAM,WAAW,GAAG;AAAA,EACvC;AACF;AAOO,SAAS,sBAAsC;AACpD,QAAM,QAAQ,oBAAI,IAAoB;AACtC,SAAO;AAAA,IACL,KAAK,OAAO,QAAQ,MAAM,IAAI,GAAG,KAAK;AAAA,IACtC,KAAK,OAAO,KAAK,UAAU;AACzB,YAAM,IAAI,KAAK,KAAK;AAAA,IACtB;AAAA,IACA,QAAQ,OAAO,QAAQ;AACrB,YAAM,OAAO,GAAG;AAAA,IAClB;AAAA,EACF;AACF;","names":["createContext","useCallback","useContext","useMemo","useRef","useState","View","createContext","useContext","createContext","useContext","useCallback","useRef","useState","Pressable","Text","View","Pressable","Text","View","periode","jsx","jsxs","verdi","View","Text","Pressable","Pressable","Text","View","jsx","jsxs","Pressable","Text","View","Text","View","jsx","jsxs","View","Text","Text","View","jsx","jsxs","View","Text","ActivityIndicator","Text","View","jsx","jsxs","View","ActivityIndicator","Text","useMemo","useState","Image","Pressable","Text","View","jsx","jsxs","useState","useMemo","Pressable","Text","View","Image","jsx","jsxs","useRef","useState","useCallback","View","Pressable","Text","jsx","jsxs","createContext","useState","useRef","useMemo","useCallback","View","useContext","useEffect","useRef","View","jsx","useRef","useEffect","View","InnspelApiError","useCallback","useEffect","useState","Modal","Pressable","Text","View","Modal","Pressable","ScrollView","Text","View","t","jsx","jsxs","Modal","View","ScrollView","Text","Pressable","Fragment","jsx","jsxs","useState","useEffect","useCallback","InnspelApiError","View","Modal","Text","Pressable"]}
1
+ {"version":3,"sources":["../src/InnspelProvider.tsx","../src/skjermbilde.ts","../src/tema.ts","../src/generated/tokens.ts","../src/widget/Widget.tsx","../src/widget/Felt.tsx","../src/widget/primitiver.tsx","../src/widget/tekster.ts","../src/widget/Valg.tsx","../src/widget/KjenteFeil.tsx","../src/widget/Kvittering.tsx","../src/widget/MineInnspill.tsx","../src/widget/status.ts","../src/widget/Skjermbilde.tsx","../src/InnspelPrivate.tsx","../src/program/InnspelProgram.tsx","../src/program/Aksept.tsx","../src/program/periode.ts","../src/program/HvordanGikkDet.tsx","../src/program/Oppfolging.tsx","../src/program/Oppgaver.tsx","../src/lagring.ts"],"sourcesContent":["import type { InnspelClient, OpenFeedbackOptions } from '@innspel/core';\nimport React, { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react';\nimport { View } from 'react-native';\nimport { createPrivateRegistry, SkjermbildeContext, type ScreenshotAdapter, type SkjermbildeKontekst, type ViewRef } from './skjermbilde.js';\nimport { byggTema, TemaProvider, type PartialTheme } from './tema.js';\nimport { Widget } from './widget/Widget.js';\n\ninterface InnspelKontekst {\n client: InnspelClient;\n /** Åpner widgeten. Samme som `client.openFeedback()`. */\n open: (options?: OpenFeedbackOptions) => Promise<void>;\n close: () => void;\n}\n\nconst Kontekst = createContext<InnspelKontekst | null>(null);\n\n/**\n * Pakk appen i denne, og widgeten finnes.\n *\n * Provideren gjør fire ting: den registrerer visningen hos kjernen (så\n * `client.openFeedback()` virker hvor som helst i appen, også utenfor React),\n * den holder temaet, den rendrer selve arket — og den pakker vertsappen i én\n * `View` med referanse, som er det skjermbildet tas av (K4). Modalen ligger\n * utenfor den viewen og kommer aldri med på bildet.\n *\n * @example\n * ```tsx\n * const innspel = init({ … });\n *\n * export default function App() {\n * return (\n * <InnspelProvider client={innspel} screenshot={createScreenshotAdapter(captureRef)}>\n * <MinApp />\n * </InnspelProvider>\n * );\n * }\n * ```\n */\nexport function InnspelProvider({\n client,\n children,\n theme,\n colorScheme = 'dark',\n tenantName,\n screenshot,\n}: {\n client: InnspelClient;\n children?: React.ReactNode;\n /** Vertens egne tokens. Alt som utelates faller tilbake på Innspels tema. */\n theme?: PartialTheme;\n colorScheme?: 'dark' | 'light';\n /** Navnet som står på svaret i «Mine innspill» — leietakerens, ikke Innspels. */\n tenantName?: string;\n /**\n * Fangst av skjermbilde, typisk `createScreenshotAdapter(captureRef)` fra\n * react-native-view-shot. Uten den finnes ikke skjermbilde-steget (DD-26) —\n * og det finnes uansett ikke når `screenshotsEnabled` er av (K18).\n */\n screenshot?: ScreenshotAdapter;\n}) {\n const [synlig, setSynlig] = useState(false);\n const [apneOpsjoner, setApneOpsjoner] = useState<OpenFeedbackOptions | undefined>();\n const registrert = useRef(false);\n const rootRef = useRef<ViewRef | null>(null);\n const privat = useMemo(createPrivateRegistry, []);\n\n const open = useCallback(\n async (options?: OpenFeedbackOptions) => {\n setApneOpsjoner(options);\n setSynlig(true);\n },\n [],\n );\n\n const close = useCallback(() => setSynlig(false), []);\n\n // Registreres én gang. Kjernen kaller `presenter.open()` fra\n // `client.openFeedback()`, som er veien inn for kode som ikke er en\n // React-komponent — en navigasjonshandler, en krasjlytter hos verten.\n if (!registrert.current) {\n client.registerPresenter({ open });\n registrert.current = true;\n }\n\n const tema = useMemo(() => byggTema(theme, colorScheme), [theme, colorScheme]);\n const verdi = useMemo<InnspelKontekst>(() => ({ client, open, close }), [client, open, close]);\n const skjermbilde = useMemo<SkjermbildeKontekst>(\n () => ({ adapter: screenshot ?? null, rootRef, privat }),\n [screenshot, privat],\n );\n\n return (\n <Kontekst.Provider value={verdi}>\n <SkjermbildeContext.Provider value={skjermbilde}>\n <TemaProvider value={tema}>\n <View ref={rootRef} collapsable={false} style={{ flex: 1 }} testID=\"innspel-rot\">\n {children}\n </View>\n <Widget\n client={client}\n synlig={synlig}\n {...(apneOpsjoner ? { apneOpsjoner } : {})}\n {...(tenantName ? { tenantName } : {})}\n onLukk={close}\n />\n </TemaProvider>\n </SkjermbildeContext.Provider>\n </Kontekst.Provider>\n );\n}\n\n/**\n * Klienten og `open` fra nærmeste {@link InnspelProvider}.\n *\n * Kaster utenfor provideren i stedet for å gi `null`: en knapp som stille ikke\n * gjør noe er verre enn en feil under utvikling (tech-decisions.md, «Feil bruk\n * feiler høyt og tidlig»).\n */\nexport function useInnspel(): InnspelKontekst {\n const k = useContext(Kontekst);\n if (!k) {\n throw new Error(\n '[innspel] useInnspel() ble kalt utenfor <InnspelProvider>. Pakk appen din i den — se README.md.',\n );\n }\n return k;\n}\n","import type { MaskRect } from '@innspel/core';\nimport { createContext, useContext, type ComponentRef, type RefObject } from 'react';\nimport { Image, type View } from 'react-native';\n\n/** Host-elementet bak en `View` — det som kan måles og fanges. RN 0.87: `View` er en funksjonskomponent, så typen hentes herfra. */\nexport type ViewRef = ComponentRef<typeof View>;\n\n/**\n * Fangst av skjermbilde er det ene stedet widgeten trenger noe React Native\n * ikke har innebygd. Pakken tar INGEN avhengighet på det (K19, samme mønster som\n * `createStorage`): verten sender inn `captureRef` fra `react-native-view-shot`,\n * og uten adapter finnes ikke skjermbilde-steget (DD-26) — ikke som en grå\n * knapp, det finnes ikke.\n *\n * Alt som rører plattformen går gjennom adapteren, også måling og fillesing, så\n * widgeten kan testes med en fake og maskeringen bevises uten native kode.\n */\n\nexport interface ScreenshotCapture {\n /** Fil-URI fra fangsten. Forlater aldri enheten før den er maskert og rekomponert. */\n uri: string;\n /** Bitmapens størrelse i piksler. */\n width: number;\n height: number;\n}\n\nexport interface CaptureOptions {\n format: 'jpg' | 'png';\n /** 0–1, kun JPEG. */\n quality: number;\n}\n\nexport interface ScreenshotAdapter {\n /** Fanger viewen bak referansen til en fil. Kalles ved «Legg ved skjermbilde» (K4), og igjen på forhåndsvisningen for å rekomponere. */\n capture(ref: RefObject<ViewRef | null>, options: CaptureOptions): Promise<ScreenshotCapture>;\n /** Viewens rektangel i vinduskoordinater, i punkter. Null når den ikke er montert. */\n measure(ref: RefObject<ViewRef | null>): Promise<MaskRect | null>;\n /** Leser en fangst som Blob for opplasting. */\n read(uri: string): Promise<Blob>;\n}\n\n/** Signaturen til `captureRef` i react-native-view-shot — det eneste verten trenger å sende inn. */\nexport type CaptureRefFn = (\n ref: RefObject<ViewRef | null> | ViewRef,\n options: { format: 'jpg' | 'png'; quality: number; result: 'tmpfile' },\n) => Promise<string>;\n\n/**\n * Lager adapteren av vertens `captureRef`. Dimensjonene hentes med `Image.getSize`,\n * målingen med `measureInWindow`, og fila leses med `fetch(uri).blob()` — alt fra\n * React Native selv.\n *\n * @example\n * ```tsx\n * import { captureRef } from 'react-native-view-shot';\n * <InnspelProvider client={innspel} screenshot={createScreenshotAdapter(captureRef)}>\n * ```\n */\nexport function createScreenshotAdapter(captureRef: CaptureRefFn): ScreenshotAdapter {\n return {\n async capture(ref, options) {\n const uri = await captureRef(ref, { format: options.format, quality: options.quality, result: 'tmpfile' });\n const { width, height } = await new Promise<{ width: number; height: number }>((resolve, reject) =>\n Image.getSize(uri, (w, h) => resolve({ width: w, height: h }), reject),\n );\n return { uri, width, height };\n },\n measure(ref) {\n return new Promise((resolve) => {\n const view = ref.current;\n if (!view) return resolve(null);\n view.measureInWindow((x, y, width, height) => resolve({ x, y, width, height }));\n });\n },\n async read(uri) {\n const res = await fetch(uri);\n return res.blob();\n },\n };\n}\n\n/**\n * Private views (DD-39): det verten har merket med `<InnspelPrivate>`. Registeret\n * lever i provideren; widgeten måler hver av dem i fangstøyeblikket og legger en\n * maske brukeren ikke kan fjerne.\n */\nexport interface PrivateRegistry {\n register(ref: RefObject<ViewRef | null>): () => void;\n refs(): ReadonlyArray<RefObject<ViewRef | null>>;\n}\n\nexport function createPrivateRegistry(): PrivateRegistry {\n const alle = new Set<RefObject<ViewRef | null>>();\n return {\n register(ref) {\n alle.add(ref);\n return () => {\n alle.delete(ref);\n };\n },\n refs: () => [...alle],\n };\n}\n\nexport interface SkjermbildeKontekst {\n adapter: ScreenshotAdapter | null;\n /** Vertsappen — det som fanges. Modalen ligger utenfor og kommer aldri med. */\n rootRef: RefObject<ViewRef | null>;\n privat: PrivateRegistry;\n}\n\nexport const SkjermbildeContext = createContext<SkjermbildeKontekst | null>(null);\n\nexport function useSkjermbilde(): SkjermbildeKontekst | null {\n return useContext(SkjermbildeContext);\n}\n","import { createContext, useContext } from 'react';\nimport { light, t, type InnspelColors, type InnspelTheme } from './generated/tokens.js';\n\n/**\n * Widgeten lever INNE i vertsappen (DD-21) og skal arve dens flate. Verten\n * sender et delvis tema; alt den ikke sender faller tilbake på Innspels eget\n * (M0.4), som er generert fra `theme/theme.ts` og målt mot WCAG AA.\n *\n * Ingen hex-verdi, px-verdi eller fontstørrelse skrives i en komponent — alt\n * hentes herfra (CLAUDE.md, «Styling»). `fontFamily` finnes ikke: systemfonten\n * er standard i React Native, og å sette den ville brutt med vertsappen.\n */\n\n/**\n * De genererte tokenene er `as const`, så `t.touch` har typen `48` og ikke\n * `number`. Det er riktig for KILDEN — den skal ikke kunne endres ved et uhell\n * — men gjør temaet umulig å overstyre: verten ville måttet sende nøyaktig 48.\n * Denne typen åpner verdiene uten å åpne nøkkelsettet: en vert kan bytte en\n * farge, men ikke finne på en ny.\n */\nexport type Tema = Omit<\n InnspelTheme,\n 'color' | 'space' | 'radius' | 'font' | 'lineHeight' | 'motion' | 'touch' | 'screenPadding' | 'hairline'\n> & {\n color: Record<keyof InnspelColors, string>;\n space: Record<keyof InnspelTheme['space'], number>;\n radius: Record<keyof InnspelTheme['radius'], number>;\n font: Record<keyof InnspelTheme['font'], number>;\n lineHeight: Record<keyof InnspelTheme['lineHeight'], number>;\n motion: Record<keyof InnspelTheme['motion'], number>;\n touch: number;\n screenPadding: number;\n hairline: number;\n};\n\nexport type PartialTheme = {\n color?: Partial<Tema['color']>;\n} & Partial<Omit<Tema, 'color'>>;\n\n/**\n * Fletter vertens tokens over Innspels egne.\n *\n * @param vertens Delvis tema fra `<InnspelProvider theme={…}>`.\n * @param palett `dark` er standard: widgeten åpnes oftest over en app i mørk\n * modus, og et lyst ark over en mørk app blender.\n */\nexport function byggTema(vertens?: PartialTheme, palett: 'dark' | 'light' = 'dark'): Tema {\n const bunn = (palett === 'light' ? light : t) as unknown as Tema;\n if (!vertens) return bunn;\n\n return {\n ...bunn,\n ...vertens,\n color: { ...bunn.color, ...vertens.color },\n };\n}\n\nconst TemaContext = createContext<Tema>(t as unknown as Tema);\n\nexport const TemaProvider = TemaContext.Provider;\n\n/** Tokenene som gjelder her. Bruk ALDRI en literal farge eller avstand i stedet. */\nexport function useTema(): Tema {\n return useContext(TemaContext);\n}\n","/**\n * tokens.ts — GENERERT fra theme/theme.ts (avtrykk e9fb0cf68373).\n * Rediger aldri denne filen. Endre temaet i kilden og kjør\n * `node scripts/generate-tokens.ts`, som CI verifiserer med `--check`.\n *\n * Tokenene @innspel/react-native faller tilbake på når verten ikke sender egne.\n * Widgeten lever inne i vertsappen og skal arve dens flate (DD-21); dette er\n * bunnen, ikke fasiten.\n *\n * 72 kontrastpar er målt mot WCAG AA i begge paletter, og generatoren\n * nekter å skrive hvis ett faller under kravet. Farge bærer aldri mening alene\n * — hver status har ikon og tekstetikett (DD-08).\n *\n * fontFamily finnes ikke her med vilje: systemfonten er standard i React\n * Native, og å sette den ville brutt med vertsappen.\n */\n\n/** Mørk palett — fallback når verten ikke sender egne tokens. */\nexport const t = {\n color: {\n bg: \"#111417\",\n surface: \"#1A1E22\",\n surfaceRaised: \"#232830\",\n border: \"#2E343B\",\n borderStrong: \"#3D444D\",\n borderInteractive: \"#7C8894\",\n textPrimary: \"#F2F4F6\",\n textSecondary: \"#B4BCC5\",\n textMuted: \"#8D96A1\",\n textDisabled: \"#5A626B\",\n actionPrimary: \"#5AD3E2\",\n onActionPrimary: \"#04252A\",\n actionSecondaryBorder: \"#7C8894\",\n actionSecondaryText: \"#F2F4F6\",\n brand: \"#5AD3E2\",\n onBrand: \"#04252A\",\n brandFill: \"#0E7C8C\",\n onBrandFill: \"#FFFFFF\",\n brandBg: \"#0C2A30\",\n danger: \"#FF7A8C\",\n dangerFill: \"#C4001F\",\n onDangerFill: \"#FFFFFF\",\n dangerBg: \"#2C1116\",\n success: \"#3ED88A\",\n onSuccess: \"#062015\",\n successBg: \"#0E2A1E\",\n warning: \"#FFC24D\",\n onWarning: \"#2A1C02\",\n warningBg: \"#2C2107\",\n info: \"#5CC0FF\",\n onInfo: \"#04222F\",\n infoBg: \"#0E2531\",\n neutral: \"#A3ACB6\",\n onNeutral: \"#111417\",\n neutralBg: \"#242A31\",\n scrim: \"rgba(0, 0, 0, 0.72)\",\n },\n space: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n },\n radius: {\n sm: 6,\n md: 8,\n lg: 12,\n pill: 999,\n },\n font: {\n h1: 24,\n h2: 21,\n h3: 18,\n body: 16,\n small: 13,\n tiny: 11,\n },\n lineHeight: {\n h1: 30,\n h2: 27,\n h3: 24,\n body: 24,\n small: 18,\n tiny: 16,\n },\n weight: {\n regular: \"400\",\n medium: \"500\",\n semibold: \"600\",\n bold: \"700\",\n },\n motion: {\n fast: 120,\n base: 200,\n slow: 320,\n },\n touch: 48,\n screenPadding: 24,\n hairline: 1,\n} as const;\n\n/** Lys palett. */\nexport const light = {\n color: {\n bg: \"#F6F7F9\",\n surface: \"#FFFFFF\",\n surfaceRaised: \"#EDEFF3\",\n border: \"#D2D7DE\",\n borderStrong: \"#B9C0C9\",\n borderInteractive: \"#6F7883\",\n textPrimary: \"#14181D\",\n textSecondary: \"#454D57\",\n textMuted: \"#5C6470\",\n textDisabled: \"#9AA2AD\",\n actionPrimary: \"#0A6673\",\n onActionPrimary: \"#FFFFFF\",\n actionSecondaryBorder: \"#6F7883\",\n actionSecondaryText: \"#14181D\",\n brand: \"#0A6673\",\n onBrand: \"#FFFFFF\",\n brandFill: \"#0A6673\",\n onBrandFill: \"#FFFFFF\",\n brandBg: \"#E0F0F2\",\n danger: \"#B3001B\",\n dangerFill: \"#B3001B\",\n onDangerFill: \"#FFFFFF\",\n dangerBg: \"#FCE8EA\",\n success: \"#04693C\",\n onSuccess: \"#FFFFFF\",\n successBg: \"#E4F4EC\",\n warning: \"#7A5200\",\n onWarning: \"#FFFFFF\",\n warningBg: \"#FBF1DE\",\n info: \"#00588F\",\n onInfo: \"#FFFFFF\",\n infoBg: \"#E4F0F8\",\n neutral: \"#5C6470\",\n onNeutral: \"#FFFFFF\",\n neutralBg: \"#EEF0F3\",\n scrim: \"rgba(10, 14, 18, 0.45)\",\n },\n space: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n },\n radius: {\n sm: 6,\n md: 8,\n lg: 12,\n pill: 999,\n },\n font: {\n h1: 24,\n h2: 21,\n h3: 18,\n body: 16,\n small: 13,\n tiny: 11,\n },\n lineHeight: {\n h1: 30,\n h2: 27,\n h3: 24,\n body: 24,\n small: 18,\n tiny: 16,\n },\n weight: {\n regular: \"400\",\n medium: \"500\",\n semibold: \"600\",\n bold: \"700\",\n },\n motion: {\n fast: 120,\n base: 200,\n slow: 320,\n },\n touch: 48,\n screenPadding: 24,\n hairline: 1,\n} as const;\n\n/** Innspillets statuser. `fg`/`bg` er TOKENNAVN og slås opp i den aktive paletten. Nøklene er Submissions.SubmissionStatus i contracts/. */\nexport const submissionStatus = {\n ny: {\n statusType: \"reviewing\",\n ikon: \"ellipse-outline\",\n etikett: { feil: \"Mottatt\", onske: \"Mottatt\" },\n fg: \"textSecondary\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n vurderes: {\n statusType: \"reviewing\",\n ikon: \"hourglass-outline\",\n etikett: { feil: \"Vurderes\", onske: \"Vurderes\" },\n fg: \"info\",\n bg: \"infoBg\",\n variant: \"outline\",\n },\n planlagt: {\n statusType: \"active\",\n ikon: \"calendar-outline\",\n etikett: { feil: \"Planlagt\", onske: \"Planlagt\" },\n fg: \"brand\",\n bg: \"brandBg\",\n variant: \"outline\",\n },\n bygges: {\n statusType: \"active\",\n ikon: \"construct-outline\",\n etikett: { feil: \"Retter nå\", onske: \"Bygger\" },\n fg: \"brand\",\n bg: \"brandBg\",\n variant: \"filled\",\n },\n kjent_feil: {\n statusType: \"active\",\n ikon: \"warning-outline\",\n etikett: { feil: \"Kjent feil\", onske: \"Kjent feil\" },\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n levert: {\n statusType: \"complete\",\n ikon: \"checkmark-circle-outline\",\n etikett: { feil: \"Rettet\", onske: \"Levert\" },\n fg: \"success\",\n bg: \"successBg\",\n variant: \"outline\",\n },\n avvist: {\n statusType: \"closed\",\n ikon: \"close-circle-outline\",\n etikett: { feil: \"Avvist\", onske: \"Avvist\" },\n fg: \"danger\",\n bg: \"dangerBg\",\n variant: \"outline\",\n },\n duplikat: {\n statusType: \"closed\",\n ikon: \"git-merge-outline\",\n etikett: { feil: \"Slått sammen\", onske: \"Slått sammen\" },\n fg: \"neutral\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n} as const;\n\n/** Programmets statuser. Nøklene er Programs.ProgramStatus i contracts/. */\nexport const programStatus = {\n utkast: {\n ikon: \"create-outline\",\n etikett: \"Utkast\",\n fg: \"textSecondary\",\n bg: \"neutralBg\",\n variant: \"dashed\",\n },\n aapen: {\n ikon: \"ellipse-outline\",\n etikett: \"Åpen — invitasjoner kan sendes\",\n fg: \"info\",\n bg: \"infoBg\",\n variant: \"outline\",\n },\n aktiv: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Aktiv\",\n fg: \"success\",\n bg: \"successBg\",\n variant: \"outline\",\n },\n avsluttes: {\n ikon: \"time-outline\",\n etikett: \"Avsluttes — oppfølginger går ut\",\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n avsluttet: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Avsluttet — rapport fryst\",\n fg: \"neutral\",\n bg: \"neutralBg\",\n variant: \"outline\",\n },\n avbrutt: {\n ikon: \"close-circle\",\n etikett: \"Avbrutt\",\n fg: \"onDangerFill\",\n bg: \"dangerFill\",\n variant: \"filled\",\n },\n} as const;\n\n/** Kjent feil-statusene (M2.4). Nøklene er KnownIssues.KnownIssueStatus i contracts/; «fikset» heter «Rettet» (DD-22). */\nexport const knownIssueStatus = {\n aktiv: {\n ikon: \"warning-outline\",\n etikett: \"Aktiv\",\n fg: \"warning\",\n bg: \"warningBg\",\n variant: \"outline\",\n },\n fikset: {\n ikon: \"checkmark-circle-outline\",\n etikett: \"Rettet\",\n fg: \"success\",\n bg: \"successBg\",\n variant: \"dashed\",\n },\n} as const;\n\n/** Skjermbilde-maskering. Faste signalfarger, uavhengig av palett (DD-39, DD-40). Vedlegg er M1.3. */\nexport const screenRules = {\n brushFill: \"#E5007D\",\n autoMaskFill: \"#101114\",\n autoMaskStroke: \"#E5007D\",\n previewBackdrop: \"#000000\",\n brushWidth: 28,\n textBlurRadius: 24,\n} as const;\n\n/** Formen widgeten tar imot. Verten sender et delvis tema; resten faller tilbake hit. */\nexport type InnspelTheme = typeof t;\nexport type InnspelColors = InnspelTheme['color'];\n","import {\n InnspelApiError,\n InnspelQueueFullError,\n type AttachmentInput,\n type InnspelClient,\n type KnownIssueCard,\n type MaskRect,\n type MySubmission,\n type OpenFeedbackOptions,\n type PatternFinding,\n} from '@innspel/core';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Modal, Pressable, Text, View } from 'react-native';\nimport { useSkjermbilde, type ScreenshotCapture, type ViewRef } from '../skjermbilde.js';\nimport { useTema } from '../tema.js';\nimport { Felt } from './Felt.js';\nimport { Valg } from './Valg.js';\nimport { KjenteFeil } from './KjenteFeil.js';\nimport { Kvittering, type KvitteringArt } from './Kvittering.js';\nimport { MineInnspill } from './MineInnspill.js';\nimport { Skjermbilde } from './Skjermbilde.js';\nimport { Banner, Btn } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\nexport type Steg = 'valg' | 'kjenteFeil' | 'felt' | 'skjermbilde' | 'kvittering' | 'mine';\n\n/** JPEG med denne kvaliteten holder et 3×-skjermbilde godt under 5 MB (K9) og gjør uskarphet irreversibel i praksis. */\nconst FANGST = { format: 'jpg', quality: 0.85 } as const;\n\n/**\n * Widgeten. Ett ark over vertsappen — aldri en flytende knapp over innhold\n * (DD-21).\n *\n * **DD-47, og hvorfor det står her og ikke i en TODO:** arket er en dialog og\n * oppfører seg som en. `<Modal>` gir fokusfellen; `onRequestClose` er\n * Android-tilbake og ESC på tastatur; `accessibilityViewIsModal` skjuler\n * vertsappen for skjermlesere på iOS; kvitteringen er en live-region. Sentrys\n * crash-modal mangler alle fire (issue #23288, #9291) — den er leverandøren som\n * dokumenterer både løsningen og mangelen.\n *\n * **Flyten er ikke symmetrisk.** Feilsporet møter kjente feil FØR feltet: den\n * som står i en feil skal slippe å skrive noe hvis svaret allerede finnes.\n * Ønskesporet møter dem ETTER: et ønske må formuleres før det kan sammenlignes.\n *\n * **Skjermbildet (2f, K4):** tas først når innsenderen trykker, aldri ved åpning.\n * Steget finnes bare når leietakeren har skjermbilde på OG verten har gitt en\n * adapter (DD-26). Private views måles i fangstøyeblikket (DD-39). Det som\n * lastes opp er komposittet av forhåndsvisningen med maskene — rå-URI-en går\n * aldri videre. Teksten sendes først; bildet kan feile alene (DD-42).\n */\nexport function Widget({\n client,\n synlig,\n apneOpsjoner,\n onLukk,\n tenantName,\n}: {\n client: InnspelClient;\n synlig: boolean;\n apneOpsjoner?: OpenFeedbackOptions;\n onLukk: () => void;\n tenantName?: string;\n}) {\n const tema = useTema();\n const skjermbilde = useSkjermbilde();\n const previewRef = useRef<ViewRef | null>(null);\n\n const [steg, setSteg] = useState<Steg>('valg');\n const [spor, setSpor] = useState<'feil' | 'onske'>('feil');\n const [verdi, setVerdi] = useState('');\n const [kort, setKort] = useState<KnownIssueCard[]>([]);\n const [lasterKort, setLasterKort] = useState(false);\n const [lenketTil, setLenketTil] = useState<KnownIssueCard | undefined>();\n const [funn, setFunn] = useState<PatternFinding[]>([]);\n const [fjernede, setFjernede] = useState<string[]>([]);\n const [sender, setSender] = useState(false);\n const [feil, setFeil] = useState<string | undefined>();\n const [kvittering, setKvittering] = useState<{ art: KvitteringArt; nr?: string; vedlegg?: 'feilet' | 'forkastet' }>();\n const [mine, setMine] = useState<MySubmission[]>([]);\n const [lasterMine, setLasterMine] = useState(false);\n\n // Skjermbildet: rå fangst til forhåndsvisning, private views i rotens punkter,\n // og det ferdige, maskerte vedlegget som sendes med teksten.\n const [bilde, setBilde] = useState<ScreenshotCapture | undefined>();\n const [automasker, setAutomasker] = useState<MaskRect[]>([]);\n const [rotStorrelse, setRotStorrelse] = useState({ width: 1, height: 1 });\n const [komponerer, setKomponerer] = useState(false);\n const [vedlegg, setVedlegg] = useState<AttachmentInput | undefined>();\n\n // Leietakerens grenser: startverdiene fra init(), oppdatert fra plattformen ved åpning (M2.5).\n const [innstillinger, setInnstillinger] = useState({ ...client.settings });\n\n // DD-26: steget finnes ikke uten begge. Aldri en deaktivert knapp.\n const skjermbildeMulig = innstillinger.screenshotsEnabled && skjermbilde?.adapter != null;\n\n const nullstill = useCallback(() => {\n setSteg('valg');\n setSpor('feil');\n setVerdi('');\n setKort([]);\n setLenketTil(undefined);\n setFunn([]);\n setFjernede([]);\n setFeil(undefined);\n setKvittering(undefined);\n setBilde(undefined);\n setAutomasker([]);\n setVedlegg(undefined);\n setKomponerer(false);\n }, []);\n\n const lukk = useCallback(() => {\n onLukk();\n nullstill();\n }, [onLukk, nullstill]);\n\n // Køen tømmes når widgeten ÅPNES — aldri ved oppstart (DD-41). Resultatet\n // vises ikke: en flush som lykkes er ikke en hendelse innsenderen ba om.\n useEffect(() => {\n if (!synlig) return;\n client.track({ name: 'widget_opened' });\n void client.queue.flush().catch(() => undefined);\n // Konfigurasjonen er et tilbud: svarer den, oppdateres grensene; ellers står de.\n void client.loadSettings().then((s) => setInnstillinger({ ...s })).catch(() => undefined);\n\n if (apneOpsjoner?.track) velgSpor(apneOpsjoner.track);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [synlig]);\n\n const hentKort = useCallback(async () => {\n setLasterKort(true);\n try {\n const q = apneOpsjoner?.screen ? { screen: apneOpsjoner.screen } : {};\n setKort(await client.knownIssues.for(q));\n } finally {\n setLasterKort(false);\n }\n }, [client, apneOpsjoner?.screen]);\n\n const velgSpor = useCallback(\n async (valgt: 'feil' | 'onske') => {\n setSpor(valgt);\n client.track({ name: 'track_selected', type: valgt });\n\n if (valgt === 'onske') {\n // Ønskesporet skriver først; sammenligningen kommer etterpå.\n setSteg('felt');\n return;\n }\n\n setSteg('kjenteFeil');\n await hentKort();\n },\n [client, hentKort],\n );\n\n // Treffene er et tilbud, aldri en sperre (wireframe 2c): er lista tom når\n // oppslaget er ferdig, hoppes skjermen over — rett til feltet, ingen melding.\n useEffect(() => {\n if (steg === 'kjenteFeil' && !lasterKort && kort.length === 0) setSteg('felt');\n }, [steg, lasterKort, kort.length]);\n\n const endreTekst = useCallback(\n (v: string) => {\n setVerdi(v);\n setFunn(client.scanText(v));\n },\n [client],\n );\n\n /**\n * «Legg ved skjermbilde» (K4): fangsten skjer HER, ved trykket, av vertsappen\n * bak arket. Private views måles i samme øyeblikk (DD-39) og regnes om til\n * rotens punkter. Feiler fangsten, kan innsenderen sende uten.\n */\n const taSkjermbilde = useCallback(async () => {\n if (!skjermbilde?.adapter) return;\n const { adapter, rootRef, privat } = skjermbilde;\n setFeil(undefined);\n try {\n const fangst = await adapter.capture(rootRef, FANGST);\n const rot = await adapter.measure(rootRef);\n const private_ = await Promise.all(privat.refs().map((r) => adapter.measure(r)));\n if (rot) {\n setRotStorrelse({ width: rot.width, height: rot.height });\n setAutomasker(\n private_\n .filter((r): r is MaskRect => r !== null)\n .map((r) => ({ x: r.x - rot.x, y: r.y - rot.y, width: r.width, height: r.height })),\n );\n } else {\n setRotStorrelse({ width: fangst.width, height: fangst.height });\n setAutomasker([]);\n }\n setBilde(fangst);\n setSteg('skjermbilde');\n } catch {\n setFeil(tekst.skjermbildeFeilet);\n }\n }, [skjermbilde]);\n\n /**\n * «Legg ved og fortsett»: forhåndsvisningen MED maskene fanges på nytt, og det\n * er komposittet som blir vedlegget. Rå-URI-en brukes aldri etter dette.\n */\n const leggVedBilde = useCallback(async () => {\n if (!skjermbilde?.adapter) return;\n setKomponerer(true);\n try {\n const komposit = await skjermbilde.adapter.capture(previewRef, FANGST);\n const body = await skjermbilde.adapter.read(komposit.uri);\n setVedlegg({ mime: 'image/jpeg', body, width: komposit.width, height: komposit.height });\n setBilde(undefined);\n setSteg('felt');\n } catch {\n setFeil(tekst.skjermbildeFeilet);\n setSteg('felt');\n } finally {\n setKomponerer(false);\n }\n }, [skjermbilde]);\n\n const fjernBilde = useCallback(() => {\n setBilde(undefined);\n setAutomasker([]);\n setVedlegg(undefined);\n setSteg('felt');\n }, []);\n\n const send = useCallback(async () => {\n // Ønskesporet: feltet fører til kjente feil-sjekken, ikke rett til sending.\n if (spor === 'onske' && steg === 'felt' && kort.length === 0 && !lasterKort) {\n setSteg('kjenteFeil');\n await hentKort();\n return;\n }\n\n setSender(true);\n setFeil(undefined);\n try {\n const res = await client.capture({\n type: spor,\n text: verdi,\n ...(vedlegg ? { attachment: vedlegg } : {}),\n ...(spor === 'feil' && lenketTil ? { relatedKnownIssueId: lenketTil.id } : {}),\n ...(fjernede.length ? { context: fjernetKontekst(client, fjernede) } : {}),\n } as never);\n\n if (res.status === 'queued') {\n setKvittering({ art: 'kø', ...(res.attachment ? { vedlegg: 'forkastet' as const } : {}) });\n } else {\n setKvittering({\n art: spor,\n nr: res.submission.id,\n ...(res.attachment?.status === 'failed' ? { vedlegg: 'feilet' as const } : {}),\n });\n }\n setSteg('kvittering');\n } catch (e) {\n // Teksten mistes ALDRI: den står i feltet, og årsaken er i klartekst.\n if (e instanceof InnspelQueueFullError) setFeil(e.userMessage);\n else if (e instanceof InnspelApiError) setFeil(e.message);\n else setFeil('tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, spor, steg, verdi, vedlegg, lenketTil, fjernede, kort.length, lasterKort, hentKort]);\n\n const jaOgsa = useCallback(\n async (k: KnownIssueCard) => {\n setSender(true);\n try {\n const res = await client.knownIssues.confirm(k.id);\n setKvittering({ art: 'jaOgsa', nr: res.id });\n setSteg('kvittering');\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n },\n [client],\n );\n\n const visMine = useCallback(async () => {\n setSteg('mine');\n setLasterMine(true);\n try {\n setMine(await client.subjects.submissions());\n } catch {\n setMine([]);\n } finally {\n setLasterMine(false);\n }\n }, [client]);\n\n return (\n <Modal\n visible={synlig}\n transparent\n animationType=\"slide\"\n // Android-tilbake og ESC. Uten den er dialogen en felle (DD-47).\n onRequestClose={lukk}\n accessibilityViewIsModal\n >\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end' }}>\n <View\n testID=\"innspel-widget\"\n accessibilityViewIsModal\n accessibilityRole=\"none\"\n style={{\n backgroundColor: tema.color.bg,\n borderTopLeftRadius: tema.radius.lg * 2,\n borderTopRightRadius: tema.radius.lg * 2,\n padding: tema.screenPadding,\n gap: tema.space.md,\n maxHeight: '92%',\n minHeight: '60%',\n }}\n >\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>\n {steg === 'skjermbilde' ? (\n <Btn variant=\"ghost\" testID=\"tilbake\" ikon=\"←\" label={tekst.tilbake} onPress={fjernBilde} />\n ) : steg !== 'valg' && steg !== 'kvittering' ? (\n <Btn variant=\"ghost\" testID=\"tilbake\" ikon=\"←\" label={tekst.tilbake} onPress={nullstill} />\n ) : (\n <View />\n )}\n <Pressable\n testID=\"lukk\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.lukk}\n onPress={lukk}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.body }}>✕</Text>\n </Pressable>\n </View>\n\n {feil ? <Banner live ikon=\"⚠\" tone=\"danger\" children={tekst.sendefeilBanner(feil)} /> : null}\n\n {steg === 'valg' ? (\n <>\n <Valg onVelg={velgSpor} />\n <Btn variant=\"ghost\" testID=\"mine-innspill\" ikon=\"📋\" label={tekst.mineTittel} onPress={visMine} />\n </>\n ) : null}\n\n {steg === 'kjenteFeil' ? (\n <KjenteFeil\n kort={kort}\n spor={spor}\n laster={lasterKort}\n onJaOgsa={jaOgsa}\n onLigner={(k) => {\n setLenketTil(k);\n setSteg('felt');\n }}\n onNei={() => (spor === 'onske' ? void send() : setSteg('felt'))}\n />\n ) : null}\n\n {steg === 'felt' ? (\n <Felt\n spor={spor}\n verdi={verdi}\n onEndre={endreTekst}\n minTextLength={innstillinger.minTextLength}\n textMaxLength={innstillinger.textMaxLength}\n kontekst={client.context}\n fjernedeFelter={fjernede}\n onFjernKontekst={(f) => setFjernede((x) => [...x, f])}\n {...(lenketTil ? { lenketTil, onFjernLenke: () => setLenketTil(undefined) } : {})}\n funn={funn}\n onSend={send}\n sender={sender}\n {...(skjermbildeMulig ? { onSkjermbilde: taSkjermbilde } : {})}\n harVedlegg={vedlegg !== undefined}\n onFjernVedlegg={fjernBilde}\n />\n ) : null}\n\n {steg === 'skjermbilde' && bilde ? (\n <Skjermbilde\n bilde={bilde}\n automaskerRot={automasker}\n rotStorrelse={rotStorrelse}\n previewRef={previewRef}\n komponerer={komponerer}\n onFjern={fjernBilde}\n onLeggVed={leggVedBilde}\n />\n ) : null}\n\n {steg === 'kvittering' && kvittering ? (\n <Kvittering\n art={kvittering.art}\n {...(kvittering.nr ? { saksnummer: kvittering.nr } : {})}\n {...(kvittering.vedlegg ? { vedlegg: kvittering.vedlegg } : {})}\n onLukk={lukk}\n />\n ) : null}\n\n {steg === 'mine' ? (\n <MineInnspill\n rader={mine}\n laster={lasterMine}\n {...(tenantName ? { tenantName } : {})}\n onNytt={nullstill}\n />\n ) : null}\n </View>\n </View>\n </Modal>\n );\n}\n\n/**\n * Konteksten uten linjene innsenderen har fjernet (DD-05). Et fjernet felt\n * settes til `undefined` — det er slik kjernen (0.2.1) skiller «fjern» fra\n * «behold fra init»; å bare utelate nøkkelen ville fylt feltet igjen. Feltene\n * er en lukket hviteliste, så det som ikke står i `client.context` finnes ikke\n * å fjerne.\n */\nfunction fjernetKontekst(client: InnspelClient, fjernede: string[]) {\n const ut: Record<string, unknown> = {};\n for (const k of Object.keys(client.context)) {\n if (k !== 'sdkVersion' && fjernede.includes(k)) ut[k] = undefined;\n }\n return ut;\n}\n","import type { ContextInput, KnownIssueCard, PatternFinding } from '@innspel/core';\nimport React, { useMemo, useState } from 'react';\nimport { Pressable, Text, TextInput, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Btn, H, Hint } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2d + 2e — feltet og kontekstlinja. Ett felt, ingenting annet.\n *\n * DD-44: send er inaktiv under `minTextLength` (standard 10), og det er det\n * ENESTE kravet. Ingen kategori, ingen alvorlighet, ingen reproduksjonsfelt.\n * 2h i wireframen er ikke en skjerm — den er fraværet av felter her.\n *\n * DD-45: placeholderen stiller to spørsmål i feilsporet.\n *\n * DD-46: mønstervarselet vises FØR sending og fjerner aldri noe selv.\n * «Fjern» og «Behold» er innsenderens valg; teksten endres bare ved «Fjern».\n *\n * DD-05: konteksten er synlig og kan fjernes linje for linje. Den er en lukket\n * hviteliste (K5) — det som ikke står der, finnes ikke å fjerne.\n */\nexport function Felt({\n spor,\n verdi,\n onEndre,\n minTextLength,\n textMaxLength,\n kontekst,\n fjernedeFelter,\n onFjernKontekst,\n lenketTil,\n onFjernLenke,\n funn,\n onSend,\n sender,\n onSkjermbilde,\n harVedlegg,\n onFjernVedlegg,\n}: {\n spor: 'feil' | 'onske';\n verdi: string;\n onEndre: (v: string) => void;\n minTextLength: number;\n textMaxLength: number;\n kontekst: ContextInput & { sdkVersion: string };\n fjernedeFelter: string[];\n onFjernKontekst: (felt: string) => void;\n lenketTil?: KnownIssueCard;\n onFjernLenke?: () => void;\n funn: PatternFinding[];\n onSend: () => void;\n sender?: boolean;\n /**\n * «Legg ved skjermbilde» (2f, K4). Utelatt = steget finnes ikke (DD-26): leietakeren\n * har skjermbilde av, eller verten ga ingen adapter. Aldri en deaktivert knapp.\n */\n onSkjermbilde?: () => void;\n /** Et maskert skjermbilde ligger klart og sendes etter teksten (DD-42). */\n harVedlegg?: boolean;\n onFjernVedlegg?: () => void;\n}) {\n const tema = useTema();\n const [apen, setApen] = useState(false);\n const [beholdt, setBeholdt] = useState<string[]>([]);\n\n const brukt = verdi.length;\n const forKort = brukt < minTextLength;\n const full = brukt >= textMaxLength;\n // Telleren dukker opp ved 80 % — ikke før. En teller fra første tegn gjør\n // lengden til oppgaven i stedet for innholdet.\n const visTeller = brukt >= textMaxLength * 0.8;\n\n const uavklart = funn.find((f) => !beholdt.includes(f.match));\n\n const linjer = useMemo(() => {\n const etiketter: Record<string, string> = {\n screen: 'Skjerm',\n appVersion: 'Appversjon',\n platform: 'Plattform',\n os: 'OS',\n build: 'Bygg',\n locale: 'Språk',\n };\n return Object.entries(etiketter)\n .map(([felt, etikett]) => {\n const verdi = (kontekst as unknown as Record<string, string | undefined>)[felt];\n return verdi && !fjernedeFelter.includes(felt) ? { felt, etikett, verdi } : null;\n })\n .filter((x): x is { felt: string; etikett: string; verdi: string } => x !== null);\n }, [kontekst, fjernedeFelter]);\n\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n {lenketTil ? (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderInteractive,\n borderRadius: tema.radius.pill,\n paddingLeft: tema.space.md,\n paddingRight: tema.space.xs,\n }}\n >\n <Text style={{ flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }}>\n {tekst.lenketTil(lenketTil.title)}\n </Text>\n <Pressable\n testID=\"fjern-lenke\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.fjernLenke}\n onPress={onFjernLenke}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>✕</Text>\n </Pressable>\n </View>\n ) : null}\n\n {uavklart ? (\n <View\n style={{\n gap: tema.space.sm,\n backgroundColor: tema.color.warningBg,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n }}\n >\n <Text\n accessibilityRole=\"alert\"\n accessibilityLiveRegion=\"polite\"\n style={{\n color: tema.color.warning,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n fontWeight: tema.weight.medium,\n }}\n >\n {tekst.monsterSpm[uavklart.kind]}\n </Text>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n <Btn\n grow\n variant=\"secondary\"\n testID=\"monster-fjern\"\n label={tekst.monsterFjern}\n onPress={() => onEndre(verdi.slice(0, uavklart.start) + verdi.slice(uavklart.end))}\n />\n <Btn\n grow\n variant=\"ghost\"\n testID=\"monster-behold\"\n label={tekst.monsterBehold}\n onPress={() => setBeholdt((b) => [...b, uavklart.match])}\n />\n </View>\n <Hint>{tekst.monsterForklaring}</Hint>\n </View>\n ) : null}\n\n <H>{spor === 'onske' ? tekst.feltLabelOnske : tekst.feltLabelFeil}</H>\n\n <TextInput\n testID=\"innspill-tekst\"\n accessibilityLabel={spor === 'onske' ? tekst.feltLabelOnske : tekst.feltLabelFeil}\n value={verdi}\n onChangeText={onEndre}\n maxLength={textMaxLength}\n multiline\n numberOfLines={4}\n placeholder={spor === 'onske' ? tekst.placeholderOnske : tekst.placeholderFeil}\n placeholderTextColor={tema.color.textMuted}\n style={{\n backgroundColor: tema.color.surfaceRaised,\n borderWidth: tema.hairline,\n borderColor: full ? tema.color.warning : tema.color.borderStrong,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n minHeight: tema.touch * 2,\n textAlignVertical: 'top',\n }}\n />\n\n {visTeller ? (\n <Text\n testID=\"teller\"\n accessibilityLiveRegion={full ? 'assertive' : 'polite'}\n style={{\n alignSelf: 'flex-end',\n color: full ? tema.color.warning : tema.color.textMuted,\n fontSize: tema.font.small,\n }}\n >\n {brukt} / {textMaxLength}\n {full ? tekst.tellerFull : ''}\n </Text>\n ) : null}\n\n {/* 2f — opt-in per innsending. Bildet tas først ved trykk (K4). */}\n {harVedlegg ? (\n <View\n testID=\"vedlegg-chip\"\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderInteractive,\n borderRadius: tema.radius.pill,\n paddingLeft: tema.space.md,\n paddingRight: tema.space.xs,\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.small }}>\n 📷\n </Text>\n <Text style={{ flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }}>{tekst.skjermbildeLagtVed}</Text>\n <Pressable\n testID=\"fjern-vedlegg\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.fjernSkjermbilde}\n onPress={onFjernVedlegg}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>✕</Text>\n </Pressable>\n </View>\n ) : onSkjermbilde ? (\n <Btn\n variant=\"secondary\"\n testID=\"legg-ved-skjermbilde\"\n ikon=\"📷\"\n label={tekst.leggVedSkjermbilde}\n hint={tekst.leggVedHint}\n onPress={onSkjermbilde}\n />\n ) : null}\n\n {/* 2e — synlig, ikke skjult (DD-05) */}\n <View style={{ borderTopWidth: tema.hairline, borderTopColor: tema.color.border, paddingTop: tema.space.sm }}>\n <Pressable\n testID=\"kontekst-bryter\"\n accessibilityRole=\"button\"\n accessibilityState={{ expanded: apen }}\n accessibilityLabel={`${tekst.kontekstLinje}${apen ? '' : tekst.kontekstVis}`}\n onPress={() => setApen((a) => !a)}\n style={{ minHeight: tema.touch, justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>\n {apen ? '▴' : '▾'} {tekst.kontekstLinje}\n {apen ? '' : tekst.kontekstVis}\n </Text>\n </Pressable>\n\n {apen ? (\n <View>\n {linjer.map((l) => (\n <View\n key={l.felt}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n minHeight: tema.touch,\n borderBottomWidth: tema.hairline,\n borderBottomColor: tema.color.border,\n }}\n >\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, minWidth: tema.touch * 2 }}>\n {l.etikett}\n </Text>\n <Text style={{ flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }}>{l.verdi}</Text>\n <Pressable\n testID={`fjern-${l.felt}`}\n accessibilityRole=\"button\"\n accessibilityLabel={`${tekst.kontekstFjern} ${l.etikett.toLowerCase()} fra innsendingen`}\n onPress={() => onFjernKontekst(l.felt)}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>\n ✕ {tekst.kontekstFjern}\n </Text>\n </Pressable>\n </View>\n ))}\n <View style={{ paddingTop: tema.space.sm }}>\n <Hint>{tekst.kontekstAldri}</Hint>\n </View>\n </View>\n ) : null}\n </View>\n\n <View style={{ flex: 1, justifyContent: 'flex-end' }}>\n <Btn\n testID=\"send\"\n label={spor === 'onske' && !forKort ? tekst.nesteOnske : tekst.send}\n disabled={forKort || sender}\n hint={forKort ? tekst.forKort(minTextLength) : harVedlegg ? tekst.sendHintMedBilde : undefined}\n onPress={onSend}\n />\n </View>\n </View>\n );\n}\n","import React from 'react';\nimport { Pressable, Text, View, type StyleProp, type ViewStyle } from 'react-native';\nimport { useTema } from '../tema.js';\n\n/**\n * Primitivene widgeten er bygget av. Alt visuelt kommer fra tema-tokens —\n * ingen hex, ingen px, ingen fontstørrelse skrives her (CLAUDE.md, «Styling»).\n *\n * Minste trykkflate er `skala.touch` (48). Den er ikke en anbefaling: den er\n * grønt-kriterium for widgeten, og en knapp under målet er en feil.\n */\n\ntype Variant = 'primary' | 'secondary' | 'ghost' | 'danger';\n\nexport function Btn({\n label,\n onPress,\n variant = 'primary',\n ikon,\n hint,\n disabled,\n accessibilityLabel,\n grow,\n testID,\n}: {\n label: string;\n onPress?: () => void;\n variant?: Variant;\n ikon?: string;\n hint?: string;\n disabled?: boolean;\n accessibilityLabel?: string;\n grow?: boolean;\n testID?: string;\n}) {\n const tema = useTema();\n const c = tema.color;\n\n const bakgrunn =\n variant === 'primary' ? c.actionPrimary : variant === 'secondary' ? c.surfaceRaised : 'transparent';\n const tekstfarge =\n variant === 'primary' ? c.onActionPrimary : variant === 'danger' ? c.danger : c.actionSecondaryText;\n const kant = variant === 'ghost' ? 'transparent' : variant === 'primary' ? c.actionPrimary : c.actionSecondaryBorder;\n\n return (\n <View style={grow ? { flex: 1 } : undefined}>\n <Pressable\n testID={testID}\n accessibilityRole=\"button\"\n // Hintet er synlig tekst OG del av etiketten: en skjermleserbruker skal\n // få vite hvorfor knappen er inaktiv uten å lete etter teksten under.\n accessibilityLabel={accessibilityLabel ?? (hint ? `${label}. ${hint}` : label)}\n accessibilityState={{ disabled: !!disabled }}\n disabled={disabled}\n onPress={onPress}\n style={{\n minHeight: tema.touch,\n borderRadius: tema.radius.md,\n borderWidth: tema.hairline,\n borderColor: kant,\n backgroundColor: disabled ? c.surface : bakgrunn,\n paddingHorizontal: tema.space.md,\n alignItems: 'center',\n justifyContent: 'center',\n flexDirection: 'row',\n gap: tema.space.sm,\n opacity: disabled ? 0.6 : 1,\n }}\n >\n {ikon ? (\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.body }}>\n {ikon}\n </Text>\n ) : null}\n <Text\n style={{\n color: disabled ? c.textDisabled : tekstfarge,\n fontSize: tema.font.body,\n fontWeight: tema.weight.semibold,\n }}\n >\n {label}\n </Text>\n </Pressable>\n {hint ? <Hint>{hint}</Hint> : null}\n </View>\n );\n}\n\nexport function H({ children, sub }: { children: string; sub?: string }) {\n const tema = useTema();\n return (\n <View style={{ gap: tema.space.xs }}>\n <Text\n accessibilityRole=\"header\"\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.h2,\n lineHeight: tema.lineHeight.h2,\n fontWeight: tema.weight.semibold,\n }}\n >\n {children}\n </Text>\n {sub ? (\n <Text\n style={{\n color: tema.color.textSecondary,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {sub}\n </Text>\n ) : null}\n </View>\n );\n}\n\nexport function Hint({ children }: { children: React.ReactNode }) {\n const tema = useTema();\n return (\n <Text\n style={{\n color: tema.color.textMuted,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {children}\n </Text>\n );\n}\n\nexport function Card({\n children,\n dashed,\n style,\n}: {\n children: React.ReactNode;\n dashed?: boolean;\n style?: StyleProp<ViewStyle>;\n}) {\n const tema = useTema();\n return (\n <View\n style={[\n {\n backgroundColor: tema.color.surface,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.border,\n borderStyle: dashed ? 'dashed' : 'solid',\n padding: tema.space.md,\n gap: tema.space.sm,\n },\n style,\n ]}\n >\n {children}\n </View>\n );\n}\n\n/**\n * Status som ikon + etikett. Fargen er et TILLEGG, aldri bæreren: to av\n * palettens statusfarger er målt til under 1,5 i innbyrdes kontrast, så\n * etiketten er det som faktisk skiller dem (DD-08).\n */\nexport function StatusPill({\n ikon,\n etikett,\n farge,\n}: {\n ikon: string;\n etikett: string;\n farge: 'info' | 'success' | 'warning' | 'neutral' | 'danger';\n}) {\n const tema = useTema();\n return (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.xs,\n alignSelf: 'flex-start',\n paddingHorizontal: tema.space.sm,\n paddingVertical: tema.space.xs,\n borderRadius: tema.radius.pill,\n backgroundColor: tema.color[`${farge}Bg` as keyof typeof tema.color],\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.small }}>\n {ikon}\n </Text>\n <Text style={{ color: tema.color[farge], fontSize: tema.font.small, fontWeight: tema.weight.medium }}>\n {etikett}\n </Text>\n </View>\n );\n}\n\n/**\n * Varsel. Rollen ligger på `Text`, ikke på containeren: `accessible` på en\n * container sluker barna som egne fokusstopp (`tdd-contract-validation`).\n */\nexport function Banner({\n ikon,\n tone,\n children,\n live,\n}: {\n ikon: string;\n tone: 'info' | 'warning' | 'danger' | 'success';\n children: string;\n live?: boolean;\n}) {\n const tema = useTema();\n return (\n <View\n style={{\n flexDirection: 'row',\n gap: tema.space.sm,\n backgroundColor: tema.color[`${tone}Bg` as keyof typeof tema.color],\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.body }}>\n {ikon}\n </Text>\n <Text\n accessibilityRole=\"alert\"\n accessibilityLiveRegion={live ? 'polite' : 'none'}\n style={{\n flex: 1,\n color: tema.color[tone],\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {children}\n </Text>\n </View>\n );\n}\n","/**\n * Hver streng innsenderen ser, ett sted.\n *\n * Ordlyden er ikke fri: den er tegnet i `design/wireframes/innsending-widget.jsx`\n * og bundet av beslutninger. Løftene under er DD-08 og skal stå ORDRETT likt i\n * SDK-et og i panelet — en innsender som får «Svar innen 3. desember» i appen og\n * noe annet i portalen har fått to løfter.\n *\n * Norsk bokmål. Ingen leietakernavn: strengen som nevner avsenderen tar navnet\n * som parameter, siden pakken skal kunne brukes av hvem som helst.\n */\nexport const tekst = {\n // 2b — første valg\n valgTittel: 'Hva gjelder det?',\n valgUnder: 'Ett valg. Vi spør aldri om kategori eller alvorlighet.',\n sporFeil: 'Noe virker ikke',\n sporFeilUnder: 'Feilsporet — kontekst legges ved',\n sporOnske: 'Jeg ønsker meg noe',\n sporOnskeUnder: 'Ønskesporet — aldri spørsmål om reproduksjon',\n\n // 2c — kjente feil (DD-29, DD-30)\n kjenteFeilTittelFeil: 'Er det dette du ser?',\n kjenteFeilUnderFeil: '«Ja» registrerer deg på saken. «Ligner» sender ditt eget med lenke.',\n kjenteFeilTittelOnske: 'Har noen ønsket dette?',\n kjenteFeilUnderOnske: 'Ett trykk legger deg til på ønsket — ingen ny sak.',\n svarJa: 'Ja, jeg også',\n svarLigner: 'Ligner, men ikke helt',\n svarNei: 'Nei, det er noe annet',\n omvei: 'Omvei:',\n rettesI: (versjon: string) => `Rettes i ${versjon}`,\n rettetI: (versjon: string) => `Rettet i ${versjon}`,\n\n // 2d + 2e — feltet og kontekstlinja\n feltLabelFeil: 'Din feil',\n feltLabelOnske: 'Ditt ønske',\n /** DD-45: to spørsmål i feilsporet. Kilde: Sentry «What's the bug? What did you expect?» */\n placeholderFeil: 'Hva skjedde? Hva forventet du?',\n placeholderOnske: 'Hva ønsker du deg?',\n send: 'Send',\n nesteOnske: 'Neste — sjekk om noen har ønsket dette',\n /** DD-44: minimum tegn er det ENESTE kravet. */\n forKort: (min: number) => `Minst ${min} tegn. Ingenting annet er obligatorisk.`,\n tellerFull: ' — kort og konkret holder',\n kontekstLinje: 'Legges ved: skjerm, appversjon, plattform, OS',\n kontekstVis: ' — Vis',\n kontekstFjern: 'Fjern',\n kontekstAldri:\n 'Aldri: navn, e-post, telefon, posisjon eller det som står på skjermen.',\n lenketTil: (tittel: string) => `Lenket til: «${tittel}»`,\n fjernLenke: 'Fjern lenken til den kjente feilen',\n\n // 2f — skjermbilde (K4, DD-39, DD-40, DD-42)\n leggVedSkjermbilde: 'Legg ved skjermbilde',\n leggVedHint: 'Bildet tas først når du trykker — du ser det før det sendes.',\n skjermbildeTittel: 'Se over bildet',\n skjermbildeUnder: 'Bildet ble tatt da du trykket. Det du maskerer, ser vi aldri.',\n maskering: 'Maskering',\n maskerFelt: 'Masker felt',\n tegnOver: 'Tegn over',\n maskerAllTekst: 'Masker all tekst',\n maskertAvAppen: 'Maskert av appen',\n maskertAvAppenHint: 'Registrert privat view. Penselen kan ikke oppheve den.',\n dittStrok: '▲ ditt strøk — maskert (kan angres med ett trykk)',\n allTekstHint: 'Hele bildet er gjort uskarpt så tekst ikke kan leses. Layouten er synlig.',\n fjernBildet: 'Fjern bildet',\n leggVedOgFortsett: 'Legg ved og fortsett',\n leggVedHintDD42: 'Teksten sendes først; bildet lastes opp for seg.',\n skjermbildeLagtVed: 'Skjermbilde lagt ved — maskert',\n fjernSkjermbilde: 'Fjern skjermbildet',\n sendHintMedBilde: 'Teksten sendes først; bildet lastes opp for seg.',\n skjermbildeFeilet: 'kunne ikke ta skjermbilde. Du kan sende uten.',\n skjermbildeA11y: (auto: number, egne: number, uskarpt: boolean) =>\n `Forhåndsvisning av skjermbildet. ${auto ? `${auto} felt maskert av appen og kan ikke avmaskeres. ` : ''}${egne ? `${egne} felt maskert av deg. ` : ''}${uskarpt ? 'All tekst er gjort uskarp. ' : ''}Trykk for å maskere et felt, dra for å tegne over.`,\n\n // DD-46 — mønstervarsel. Aldri stille redaksjon.\n monsterSpm: {\n email: 'Dette ser ut som en e-postadresse. Vil du fjerne den?',\n phone: 'Dette ser ut som et telefonnummer. Vil du fjerne det?',\n card: 'Dette ser ut som et kortnummer. Vil du fjerne det?',\n ip: 'Dette ser ut som en IP-adresse. Vil du fjerne den?',\n token: 'Dette ser ut som en tilgangsnøkkel. Vil du fjerne den?',\n },\n monsterFjern: 'Fjern',\n monsterBehold: 'Behold',\n monsterForklaring: 'Teksten endres bare hvis du trykker Fjern. Vi fjerner aldri noe stille.',\n\n // 2g — kvittering\n kvitteringSendt: 'Sendt',\n kvitteringRegistrert: 'Registrert',\n kvitteringFeil: 'Du får beskjed når den er rettet, eller hvis vi trenger mer.',\n kvitteringOnske:\n 'Vurderes innen 90 dager. Du får et personlig svar — også hvis det er nei.',\n kvitteringJaOgsa: 'Du får beskjed når den er rettet.',\n saksnummer: (nr: string) => `Saksnummer ${nr} — vis dette hvis du spør support.`,\n tilbakeTilAppen: 'Tilbake til appen',\n /** DD-42: saken er sendt, bildet kom ikke med — aldri en blokkert innsending. */\n kvitteringVedleggFeilet: 'Sendt — skjermbildet kunne ikke legges ved',\n tekstenErLagret: 'Teksten din er lagret.',\n vedleggFeiletBanner: 'Bildet ble ikke lastet opp. Saken er sendt uten det — vil du, kan du sende et nytt innspill med bilde.',\n saksnummerUtenVedlegg: (nr: string) => `Saksnummer ${nr} · uten vedlegg`,\n\n // 2i — tilstander\n offlineTittel: 'Ingen nett',\n offlineBanner:\n 'Ingen nett. Lagres og sendes automatisk — du ser det under «Mine innspill» til det er sendt.',\n offlineLagre: 'Lagre — sendes automatisk',\n /** DD-41: et skjermbilde køes aldri. */\n offlineUtenBilde: 'Skjermbilde kan ikke legges ved uten nett. Teksten sendes; bildet ble ikke lagret.',\n sendefeilBanner: (arsak: string) => `Kunne ikke sende: ${arsak} Teksten din er beholdt.`,\n provIgjen: 'Prøv igjen',\n\n // 2j — mine innspill\n mineTittel: 'Mine innspill',\n mineUnder: 'Status og hva du kan vente deg — samme løfte som i kvitteringen.',\n mineTom: 'Du har ikke sendt noe ennå.',\n mineIkkeSendt: 'Ikke sendt ennå',\n mineSak: (nr: string) => `Sak ${nr}`,\n svarFra: (leietaker: string) => `Svar fra ${leietaker}`,\n svarFraGenerisk: 'Svar',\n sendNytt: 'Send nytt innspill',\n\n // 3a — invitasjonsbanneret (DD-12)\n invitasjonRegion: 'Invitasjon til betaprogram',\n invitasjonHva: (navn: string) => `Vil du teste «${navn}»?`,\n invitasjonKontakter: (maks: number) =>\n `Vi tar kontakt maks ${maks} ganger. Du kan gå ut når som helst.`,\n lesMer: 'Les mer og bli med',\n avvisInvitasjon: 'Avvis invitasjonen',\n\n // 3b — aksepten (DD-13, DD-32, DD-37)\n akseptHva: 'Hva testes',\n /** DD-32: tallene på én linje, FØR forklaringen — N oppgaver · ca. M min hver · dato–dato · maks K kontakter. */\n akseptTall: (oppgaver: number, minutter: number, periode: string, kontakter: number) =>\n `${oppgaver} oppgaver · ca. ${minutter} min hver · ${periode} · maks ${kontakter} kontakter`,\n akseptOppgaver: 'Hva vi ber om',\n akseptOppgaveTid: (minutter: number) => `ca. ${minutter} min`,\n akseptKjenteFeil: (antall: number) => `Kjente feil (${antall})`,\n akseptKjenteFeilUnder: 'Disse trenger du ikke melde — vi vet om dem.',\n akseptInnsamling: 'Hva som samles inn',\n akseptInnsamlingTekst:\n 'Skjerm, appversjon, plattform, OS og hva du svarer. Aldri navn, e-post, telefon eller posisjon.',\n akseptVilkar: 'Les vilkårene (åpnes i nettleser)',\n akseptVilkarHint: 'Bare en lenke. Ingen avkryssing, ingen signatur — «Bli med» binder deg ikke til noe.',\n akseptIngenVilkar:\n 'Ingen vilkår, ingen avtale — plattformen kjenner ikke navnet ditt og kan ikke inngå én.',\n akseptUtgang: 'Du kan gå ut når som helst — herfra.',\n bliMed: 'Bli med',\n bliMedHint: 'Samtykket gjelder bare dette programmet.',\n /** DD-12: tokenet er engangs og kom i leietakerens egen kanal — plattformen sender aldri. */\n bliMedUtenToken: 'Åpne lenken vi sendte deg for å bli med.',\n akseptFeil: (arsak: string) => `Kunne ikke bli med: ${arsak}`,\n\n // 3c (M3.1-delen) — deltakelsen og «Gå ut» (DD-36)\n deltakelseRegion: 'Ditt betaprogram',\n deltakelsePeriode: (periode: string, brukt: number, maks: number) =>\n `${periode} · ${brukt} av ${maks} kontakter brukt`,\n deltakelseOppgaverKommer: 'Oppgavene kan gjøres når det passer deg.',\n gaaUt: 'Gå ut av programmet',\n gaaUtTittel: 'Gå ut av programmet?',\n gaaUtTekst: (navn: string) =>\n `Du tas ut av testgruppen med en gang. «${navn}» slås av for deg, og vi tar ikke kontakt igjen. Det du allerede har svart, beholdes.`,\n bliVaerende: 'Bli værende',\n gaaUtBekreft: 'Gå ut',\n\n // 3c (M3.2) — oppgavene og «Hvordan gikk det?»: tre lukkede valg, aldri en skala\n oppgaverTittel: 'Oppgavene',\n oppgaveIkkeBegynt: 'Ikke begynt',\n oppgaveGjort: 'Gjort',\n oppgaveGjortLabel: (tittel: string) => `Gjort: ${tittel}`,\n oppgaveGjortMed: (utfall: string) => `Gjort · ${utfall}`,\n hvordanGikkDet: 'Hvordan gikk det?',\n utfallFungerte: 'Fungerte',\n utfallDelvis: 'Delvis',\n utfallIkke: 'Ikke',\n setningLabel: 'Vil du si én setning om det? (valgfritt)',\n setningPlaceholder: 'Kopien kom, men rullesjefen manglet på torsdag.',\n lagre: 'Lagre',\n lagreHint: 'Ferdig — ingen flere spørsmål nå.',\n /** Etter «Ikke»: feilsporet er vertens — plattformen navigerer aldri selv. */\n meldFeil: 'Meld det som feil',\n meldFeilHint: 'Gikk det ikke? Et innspill hjelper oss å finne ut hvorfor.',\n svarFeil: (arsak: string) => `Kunne ikke lagre svaret: ${arsak}`,\n\n // 3d (M3.2) — oppfølgingskortene (DD-34): arten avgjør knappene\n oppfolgingRegion: 'Oppfølging fra betaprogrammet',\n oppfolgingKontakt: (nr: number, maks: number) => `Kontakt ${nr} av ${maks} · tar under ett minutt`,\n oppfolgingPaaminnelseHint: (nr: number, maks: number) => `Kontakt ${nr} av ${maks} · planlagt påminnelse`,\n oppfolgingUtgangHint: (nr: number, maks: number) => `Kontakt ${nr} av ${maks} · den siste vi sender`,\n senere: 'Senere',\n svarNaa: 'Svar nå',\n aapneOppgavene: 'Åpne oppgavene',\n\n // Felles\n tilbake: 'Tilbake',\n lukk: 'Lukk',\n venterPaaNett: 'Venter på nett — sendes automatisk',\n} as const;\n\n/**\n * Løftet per status (DD-08). Samme streng i SDK og panel. Det eneste tidsløftet\n * er svarfristen som DATO (DD-28) — aldri «innen X dager», som ville betydd noe\n * nytt hver gang innsenderen leser det.\n */\nexport const lofte = {\n venterNett: 'Sendes automatisk når du er på nett — kvitteringen kommer da.',\n vurderes: (frist: string) => `Svar innen ${frist} — også hvis det er nei.`,\n vurderesUtenFrist: 'Du får svar — også hvis det er nei.',\n bygges: 'Du får beskjed når den er rettet.',\n planlagt: 'Du får beskjed når den er rettet.',\n rettet: 'Ferdig. Ser du feilen igjen, send et nytt innspill.',\n levert: 'Ferdig. Takk for ønsket.',\n ny: 'Vi har fått den. Du hører fra oss.',\n kjentFeil: 'Kjent feil. Du får beskjed når den er rettet.',\n duplikat: 'Slått sammen med et innspill som ligner.',\n avvist: 'Vi har svart på denne.',\n} as const;\n","import React from 'react';\nimport { Pressable, Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { H } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2b — første valg. To flater, hele nedre halvdel, ikon og tekst.\n *\n * DD-02: ALDRI et tredje valg, og aldri spørsmål om kategori eller\n * alvorlighet. Valget her styrer alt etterpå: feilsporet får kjente feil FØR\n * feltet og kan bære koblingsnøkler, ønskesporet får dem etter og kan ikke.\n */\nexport function Valg({ onVelg }: { onVelg: (spor: 'feil' | 'onske') => void }) {\n const tema = useTema();\n\n const flate = (spor: 'feil' | 'onske', ikon: string, label: string, under: string) => (\n <Pressable\n testID={`spor-${spor}`}\n accessibilityRole=\"button\"\n accessibilityLabel={`${label}. ${under}`}\n onPress={() => onVelg(spor)}\n style={{\n flex: 1,\n minHeight: tema.touch * 3,\n backgroundColor: tema.color.surface,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderStrong,\n borderRadius: tema.radius.lg,\n alignItems: 'center',\n justifyContent: 'center',\n gap: tema.space.sm,\n padding: tema.space.md,\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.h1 }}>\n {ikon}\n </Text>\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.h3,\n fontWeight: tema.weight.semibold,\n textAlign: 'center',\n }}\n >\n {label}\n </Text>\n <Text style={{ color: tema.color.textMuted, fontSize: tema.font.small, textAlign: 'center' }}>\n {under}\n </Text>\n </Pressable>\n );\n\n return (\n <View style={{ flex: 1, gap: tema.space.lg }}>\n <H sub={tekst.valgUnder}>{tekst.valgTittel}</H>\n <View style={{ flex: 1, justifyContent: 'flex-end' }}>\n <View style={{ flexDirection: 'row', gap: tema.space.md }}>\n {flate('feil', '🐞', tekst.sporFeil, tekst.sporFeilUnder)}\n {flate('onske', '💡', tekst.sporOnske, tekst.sporOnskeUnder)}\n </View>\n </View>\n </View>\n );\n}\n","import type { KnownIssueCard } from '@innspel/core';\nimport React from 'react';\nimport { ActivityIndicator, Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Btn, Card, H, StatusPill } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2c — kjente feil. Differensiatoren: vises FØR feltet i feilsporet, ETTER i\n * ønskesporet.\n *\n * DD-29 gir kortet TRE svar, ikke to: «Ja, jeg også» (Reach +1, ingen ny sak) ·\n * «Ligner, men ikke helt» (eget innspill med lenke, uten tvunget match) · «Nei,\n * det er noe annet» (vanlig innsending). Det midterste er hele poenget — uten\n * det tvinger man et valg mellom å bli talt feil og å ikke bli talt.\n *\n * Tilgjengelighet: kortet er IKKE én knapp. Tre svar må være tre fokusstopp,\n * og `accessible` på kortcontaineren ville slukt dem. I stedet bærer hver\n * knapp kortets tittel i etiketten, så en skjermleserbruker som lander på «Ja,\n * jeg også» vet hvilken feil svaret gjelder. Se `docs/sdk`-notatet i PR-en:\n * `tdd-contract-validation` sa «ett kort = én knapp», skrevet før DD-29.\n *\n * Treffene er et tilbud, aldri en sperre: feiler oppslaget eller er lista tom,\n * hoppes skjermen over uten melding. Det håndteres i Widget, ikke her.\n */\nexport function KjenteFeil({\n kort,\n spor,\n laster,\n onJaOgsa,\n onLigner,\n onNei,\n}: {\n kort: KnownIssueCard[];\n spor: 'feil' | 'onske';\n laster?: boolean;\n onJaOgsa: (k: KnownIssueCard) => void;\n onLigner: (k: KnownIssueCard) => void;\n onNei: () => void;\n}) {\n const tema = useTema();\n\n if (laster) {\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n <H sub={spor === 'onske' ? tekst.kjenteFeilUnderOnske : tekst.kjenteFeilUnderFeil}>\n {spor === 'onske' ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil}\n </H>\n <ActivityIndicator accessibilityLabel=\"Sjekker kjente feil\" color={tema.color.textSecondary} />\n </View>\n );\n }\n\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n <H sub={spor === 'onske' ? tekst.kjenteFeilUnderOnske : tekst.kjenteFeilUnderFeil}>\n {spor === 'onske' ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil}\n </H>\n\n {kort.map((k) => {\n // DD-30: «Rettes i X» når aktiv, «Rettet i X» når fikset.\n const versjon = k.fixedIn\n ? k.status === 'fikset'\n ? tekst.rettetI(k.fixedIn)\n : tekst.rettesI(k.fixedIn)\n : undefined;\n const kontekst = versjon ? `${k.title}. ${versjon}` : k.title;\n\n return (\n <Card key={k.id}>\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: tema.weight.medium,\n }}\n >\n {k.title}\n </Text>\n\n {k.workaround ? (\n <Text\n style={{\n color: tema.color.textSecondary,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {tekst.omvei} {k.workaround}\n </Text>\n ) : null}\n\n {versjon ? (\n <StatusPill\n ikon={k.status === 'fikset' ? '✓' : '🔧'}\n etikett={versjon}\n farge={k.status === 'fikset' ? 'success' : 'info'}\n />\n ) : null}\n\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n <Btn\n grow\n testID={`ja-ogsa-${k.id}`}\n label={tekst.svarJa}\n accessibilityLabel={`${tekst.svarJa}. ${kontekst}`}\n onPress={() => onJaOgsa(k)}\n />\n <Btn\n grow\n variant=\"secondary\"\n testID={`ligner-${k.id}`}\n label={tekst.svarLigner}\n accessibilityLabel={`${tekst.svarLigner}. ${kontekst}`}\n onPress={() => onLigner(k)}\n />\n </View>\n </Card>\n );\n })}\n\n <Btn variant=\"secondary\" testID=\"nei-noe-annet\" label={tekst.svarNei} onPress={onNei} />\n </View>\n );\n}\n","import React from 'react';\nimport { Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, H, Hint } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\nexport type KvitteringArt = 'feil' | 'onske' | 'jaOgsa' | 'kø';\n\n/**\n * 2g — kvitteringen. Den LOVER noe, per spor (DD-07), og saksnummeret er der\n * så innsenderen kan vise til det hos support.\n *\n * Ingen «vurder appen». Ingen oppfordring til å dele. Innsenderen har nettopp\n * gjort oss en tjeneste — å be om en til er å ta betalt for den.\n *\n * DD-42: feilet vedlegget, er saken likevel sendt. Overskriften sier det rett\n * ut, løftet står, og saksnummeret merkes «uten vedlegg». Køet offline med et\n * skjermbilde: teksten sendes senere, bildet ble aldri køet (DD-41).\n *\n * DD-47: `accessibilityLiveRegion` og rolle `alert` på TEKSTEN, slik at en\n * skjermleser leser kvitteringen når den kommer, uten at brukeren må lete.\n */\nexport function Kvittering({\n art,\n saksnummer,\n vedlegg,\n onLukk,\n}: {\n art: KvitteringArt;\n saksnummer?: string;\n /** `feilet`: teksten er lagret, bildet kom ikke med. `forkastet`: køet offline uten bilde. */\n vedlegg?: 'feilet' | 'forkastet';\n onLukk: () => void;\n}) {\n const tema = useTema();\n\n const innhold = {\n feil: { h: tekst.kvitteringSendt, p: tekst.kvitteringFeil },\n onske: { h: tekst.kvitteringSendt, p: tekst.kvitteringOnske },\n jaOgsa: { h: tekst.kvitteringRegistrert, p: tekst.kvitteringJaOgsa },\n // Køet offline: kvitteringen kan IKKE love svar på noe som ikke er sendt\n // (DD-41 presiserer DD-07). Den lover bare at det sendes.\n kø: { h: tekst.offlineTittel, p: tekst.offlineBanner },\n }[art];\n\n const overskrift = vedlegg === 'feilet' ? tekst.kvitteringVedleggFeilet : innhold.h;\n const brodtekst = vedlegg === 'feilet' ? `${tekst.tekstenErLagret} ${innhold.p}` : innhold.p;\n\n return (\n <View style={{ flex: 1, justifyContent: 'center', gap: tema.space.lg }}>\n <View style={{ alignItems: 'center', gap: tema.space.md }}>\n <Text\n accessibilityElementsHidden\n importantForAccessibility=\"no\"\n style={{ fontSize: tema.font.h1 * 2, color: art === 'kø' ? tema.color.neutral : tema.color.success }}\n >\n {art === 'kø' ? '⇅' : '✓'}\n </Text>\n\n <H>{overskrift}</H>\n\n {vedlegg === 'feilet' ? <Banner ikon=\"⚠\" tone=\"warning\" children={tekst.vedleggFeiletBanner} /> : null}\n {vedlegg === 'forkastet' ? <Banner ikon=\"📷\" tone=\"info\" children={tekst.offlineUtenBilde} /> : null}\n\n <Text\n testID=\"kvittering-tekst\"\n accessibilityRole=\"alert\"\n accessibilityLiveRegion=\"polite\"\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n textAlign: 'center',\n }}\n >\n {brodtekst}\n </Text>\n\n {saksnummer ? (\n <Hint>{vedlegg === 'feilet' ? tekst.saksnummerUtenVedlegg(saksnummer) : tekst.saksnummer(saksnummer)}</Hint>\n ) : null}\n </View>\n\n <Btn testID=\"tilbake-til-appen\" label={tekst.tilbakeTilAppen} onPress={onLukk} />\n </View>\n );\n}\n","import type { MySubmission } from '@innspel/core';\nimport React from 'react';\nimport { ActivityIndicator, ScrollView, Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Btn, Card, H, Hint, StatusPill } from './primitiver.js';\nimport { statusVisning, venterVisning } from './status.js';\nimport { tekst } from './tekster.js';\n\n/**\n * 2j — «Mine innspill» (DD-27).\n *\n * To ting skjer her som ikke skjer noe annet sted:\n *\n * - **Offline-køen er synlig** (DD-41). Raden som venter på nett står øverst,\n * uten saksnummer, med «Venter på nett — sendes automatisk». Shake er den\n * eneste leverandøren som viser dette til brukeren; alle andre skjuler køen,\n * og en usynlig kø er ikke til å skille fra tapt tekst.\n * - **Svaret står under saken**, ordrett som i panelet. Innsenderen skal ikke\n * måtte lete etter svaret i en e-post som aldri kom — plattformen sender\n * ingen e-post (K14).\n */\nexport function MineInnspill({\n rader,\n laster,\n tenantName,\n onNytt,\n}: {\n rader: MySubmission[];\n laster?: boolean;\n tenantName?: string;\n onNytt: () => void;\n}) {\n const tema = useTema();\n\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n <H sub={tekst.mineUnder}>{tekst.mineTittel}</H>\n\n {laster ? (\n <ActivityIndicator accessibilityLabel=\"Henter innspillene dine\" color={tema.color.textSecondary} />\n ) : rader.length === 0 ? (\n <Hint>{tekst.mineTom}</Hint>\n ) : (\n <ScrollView style={{ flex: 1 }} contentContainerStyle={{ gap: tema.space.sm }}>\n {rader.map((rad) => {\n const venter = rad.pending === true;\n const v = venter ? venterVisning : statusVisning(rad.status, rad.type, rad.deadlineAt);\n const nokkel = venter ? rad.clientRef : rad.id;\n const svar = venter ? undefined : rad.reply;\n\n return (\n <Card key={nokkel} dashed={venter}>\n <Hint>\n {venter ? tekst.mineIkkeSendt : tekst.mineSak(rad.id)} ·{' '}\n {rad.type === 'onske' ? 'ønske' : 'feil'}\n </Hint>\n\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n }}\n >\n {rad.text}\n </Text>\n\n <View style={{ gap: tema.space.xs }}>\n <StatusPill ikon={v.ikon} etikett={v.etikett} farge={v.farge} />\n <Hint>{v.lofte}</Hint>\n </View>\n\n {svar ? (\n <View\n style={{\n borderLeftWidth: tema.hairline * 2,\n borderLeftColor: tema.color.brand,\n paddingLeft: tema.space.sm,\n gap: tema.space.xs,\n }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>\n {tenantName ? tekst.svarFra(tenantName) : tekst.svarFraGenerisk}\n </Text>\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.small,\n lineHeight: tema.lineHeight.small,\n }}\n >\n {svar.text}\n </Text>\n </View>\n ) : null}\n </Card>\n );\n })}\n </ScrollView>\n )}\n\n <Btn testID=\"send-nytt\" label={tekst.sendNytt} onPress={onNytt} />\n </View>\n );\n}\n","import type { SubmissionStatus, SubmissionStatusView, SubmissionType } from '@innspel/core';\nimport { lofte, tekst } from './tekster.js';\n\n/**\n * DD-22: `complete` heter «Rettet» i feilsporet og «Levert» i ønskesporet —\n * samme maskinstatus, to navn. Klienten velger navnet; serveren gjør det ikke.\n *\n * DD-08 / «Styling» i CLAUDE.md: **farge bærer aldri mening alene.** Hver status\n * har ikon OG tekstetikett. `brand ↔ info` og `brand ↔ danger` er målt til under\n * 1,5 i kontrast mot hverandre av tema-generatoren — to statuser er altså ikke\n * skillbare på farge for alle, og etiketten er det som faktisk bærer meningen.\n */\nexport interface StatusVisning {\n ikon: string;\n etikett: string;\n /** Tokennavn i den aktive paletten, ikke en farge. */\n farge: 'info' | 'success' | 'warning' | 'neutral' | 'danger';\n lofte: string;\n}\n\nconst IKON: Record<SubmissionStatus | 'venterNett', string> = {\n ny: '⏱',\n vurderes: '⏱',\n planlagt: '📅',\n bygges: '🔧',\n levert: '✓',\n kjent_feil: '👁',\n duplikat: '✕',\n avvist: '✕',\n venterNett: '⏳',\n};\n\n/** Norsk dato uten klokkeslett — fristen er en dato, ikke et tidspunkt (DD-28). */\nexport function formaterFrist(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n return new Intl.DateTimeFormat('nb-NO', { day: 'numeric', month: 'long' }).format(d);\n}\n\n/**\n * Oversetter en innsending til det innsenderen skal se.\n *\n * @param status Maskinens status fra kontrakten.\n * @param type Sporet — avgjør «Rettet» mot «Levert» (DD-22).\n * @param deadlineAt Svarfristen, satt kun i `vurderes`.\n */\nexport function statusVisning(\n status: SubmissionStatus,\n type: SubmissionType,\n deadlineAt?: string,\n): StatusVisning {\n switch (status) {\n case 'ny':\n return { ikon: IKON.ny, etikett: 'Mottatt', farge: 'neutral', lofte: lofte.ny };\n case 'vurderes':\n return {\n ikon: IKON.vurderes,\n etikett: 'Vurderes',\n farge: 'warning',\n lofte: deadlineAt ? lofte.vurderes(formaterFrist(deadlineAt)) : lofte.vurderesUtenFrist,\n };\n case 'planlagt':\n return { ikon: IKON.planlagt, etikett: 'Planlagt', farge: 'success', lofte: lofte.planlagt };\n case 'bygges':\n return { ikon: IKON.bygges, etikett: 'Retter nå', farge: 'info', lofte: lofte.bygges };\n case 'levert':\n return type === 'onske'\n ? { ikon: IKON.levert, etikett: 'Levert', farge: 'success', lofte: lofte.levert }\n : { ikon: IKON.levert, etikett: 'Rettet', farge: 'success', lofte: lofte.rettet };\n case 'kjent_feil':\n return {\n ikon: IKON.kjent_feil,\n etikett: 'Kjent, ikke planlagt',\n farge: 'neutral',\n lofte: lofte.kjentFeil,\n };\n case 'duplikat':\n return { ikon: IKON.duplikat, etikett: 'Slått sammen', farge: 'neutral', lofte: lofte.duplikat };\n case 'avvist':\n return { ikon: IKON.avvist, etikett: 'Avvist', farge: 'danger', lofte: lofte.avvist };\n }\n}\n\n/** Raden som venter på nett (DD-41). Den har ingen saksnummer og intet løfte om svar. */\nexport const venterVisning: StatusVisning = {\n ikon: IKON.venterNett,\n etikett: 'Venter på nett',\n farge: 'neutral',\n lofte: lofte.venterNett,\n};\n\n/**\n * Etikett for en hel rad, brukt som skjermleserens sammendrag. Ikonet er\n * `aria-hidden` i UI-et, så etiketten må bære alt.\n */\nexport function radEtikett(rad: SubmissionStatusView): string {\n const v = statusVisning(rad.status, rad.type, rad.deadlineAt);\n const spor = rad.type === 'onske' ? 'ønske' : 'feil';\n return `${tekst.mineSak(rad.id)}, ${spor}: ${rad.text}. Status ${v.etikett.toLowerCase()}. ${v.lofte}`;\n}\n","import { skaler, strokTilRekter, treffer, trykkTilRekt, type MaskPoint, type MaskRect } from '@innspel/core';\nimport React, { useCallback, useMemo, useRef, useState, type RefObject } from 'react';\nimport { Image, Pressable, Text, View, type GestureResponderEvent, type LayoutChangeEvent } from 'react-native';\nimport { screenRules } from '../generated/tokens.js';\nimport type { ScreenshotCapture, ViewRef } from '../skjermbilde.js';\nimport { useTema } from '../tema.js';\nimport { Btn, H, Hint } from './primitiver.js';\nimport { tekst } from './tekster.js';\n\nexport type MaskVerktoy = 'felt' | 'pensel';\n\n/**\n * 2f — skjermbildet, tatt ved trykk og forhåndsvist (K4). Tre likestilte\n * maskeringsveier (DD-40): «Masker felt» (ett trykk legger en boks), «Tegn over»\n * (fingerstrøk) og «Masker all tekst» (heldekkende uskarphet — se DD-40,\n * presisert for RN). Private views (DD-39) ligger der FØR innsenderen ser bildet,\n * merket «Maskert av appen», og kan ikke fjernes. Egne masker fjernes med ett\n * trykk på dem.\n *\n * Maskeringen skjer i bitmapen ved komposisjon: bildet vises med maskeringslagene\n * over, og «Legg ved og fortsett» fanger denne viewen på nytt. Det er komposittet\n * som lastes opp — rå-URI-en forlater aldri widgeten.\n *\n * Fargene her er `screenRules`: det ene stedet temaet ikke gjelder, fordi\n * maskene må være synlige uansett hva skjermbildet selv inneholder.\n */\nexport function Skjermbilde({\n bilde,\n automaskerRot,\n rotStorrelse,\n previewRef,\n komponerer,\n onFjern,\n onLeggVed,\n}: {\n bilde: ScreenshotCapture;\n /** Private views i vertsappens punkter (relativt til rot-viewen). */\n automaskerRot: MaskRect[];\n rotStorrelse: { width: number; height: number };\n previewRef: RefObject<ViewRef | null>;\n komponerer: boolean;\n onFjern: () => void;\n onLeggVed: () => void;\n}) {\n const tema = useTema();\n const [verktoy, setVerktoy] = useState<MaskVerktoy>('pensel');\n const [allTekst, setAllTekst] = useState(false);\n const [egne, setEgne] = useState<MaskRect[]>([]);\n const [ramme, setRamme] = useState<{ width: number; height: number } | null>(null);\n const strok = useRef<MaskPoint[]>([]);\n\n // Bildet tilpasses rammen med bevart sideforhold; alt annet regnes i visningens punkter.\n const visning = useMemo(() => {\n if (!ramme) return null;\n const s = Math.min(ramme.width / bilde.width, ramme.height / bilde.height);\n return { width: Math.floor(bilde.width * s), height: Math.floor(bilde.height * s) };\n }, [ramme, bilde.width, bilde.height]);\n\n const automasker = useMemo(\n () => (visning ? automaskerRot.map((r) => skaler(r, rotStorrelse, visning)) : []),\n [automaskerRot, rotStorrelse, visning],\n );\n\n const onLayout = useCallback((e: LayoutChangeEvent) => {\n const { width, height } = e.nativeEvent.layout;\n setRamme({ width, height });\n }, []);\n\n const punkt = (e: GestureResponderEvent): MaskPoint => ({ x: e.nativeEvent.locationX, y: e.nativeEvent.locationY });\n\n const onGrant = (e: GestureResponderEvent) => {\n if (!visning) return;\n const p = punkt(e);\n // Ett trykk på en egen maske angrer den (wireframe 2f). Private views rører den aldri.\n const treff = egne.findIndex((r) => treffer(p, r));\n if (treff >= 0) {\n setEgne((x) => x.filter((_, i) => i !== treff));\n return;\n }\n if (verktoy === 'felt') {\n const r = trykkTilRekt(p, { width: tema.touch * 4, height: tema.touch }, visning);\n if (r) setEgne((x) => [...x, r]);\n return;\n }\n strok.current = [p];\n };\n\n const onMove = (e: GestureResponderEvent) => {\n if (verktoy !== 'pensel' || strok.current.length === 0) return;\n strok.current.push(punkt(e));\n };\n\n const onRelease = () => {\n if (verktoy !== 'pensel' || !visning || strok.current.length === 0) return;\n const rekter = strokTilRekter(strok.current, screenRules.brushWidth, visning);\n strok.current = [];\n if (rekter.length) setEgne((x) => [...x, ...rekter]);\n };\n\n const knapp = (id: MaskVerktoy | 'allTekst', ikon: string, label: string) => {\n const valgt = id === 'allTekst' ? allTekst : verktoy === id && !allTekst;\n return (\n <Pressable\n key={id}\n testID={`verktoy-${id}`}\n accessibilityRole=\"button\"\n accessibilityLabel={label}\n accessibilityState={{ selected: valgt }}\n onPress={() => (id === 'allTekst' ? setAllTekst((a) => !a) : setVerktoy(id))}\n style={{\n flex: 1,\n minHeight: tema.touch,\n alignItems: 'center',\n justifyContent: 'center',\n gap: tema.space.xs,\n padding: tema.space.xs,\n borderRadius: tema.radius.md,\n borderWidth: tema.hairline,\n borderColor: tema.color.actionSecondaryBorder,\n borderBottomWidth: valgt ? tema.hairline * 2 : tema.hairline,\n borderBottomColor: valgt ? tema.color.textPrimary : tema.color.actionSecondaryBorder,\n backgroundColor: valgt ? tema.color.surfaceRaised : 'transparent',\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.body }}>\n {ikon}\n </Text>\n <Text\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.small,\n fontWeight: valgt ? tema.weight.semibold : tema.weight.regular,\n }}\n >\n {label}\n </Text>\n </Pressable>\n );\n };\n\n const a11y = tekst.skjermbildeA11y(automasker.length, egne.length, allTekst);\n\n return (\n <View style={{ flex: 1, gap: tema.space.md }}>\n <H sub={tekst.skjermbildeUnder}>{tekst.skjermbildeTittel}</H>\n\n <View accessibilityRole=\"toolbar\" accessibilityLabel={tekst.maskering} style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {knapp('felt', '▣', tekst.maskerFelt)}\n {knapp('pensel', '✎', tekst.tegnOver)}\n {knapp('allTekst', '▦', tekst.maskerAllTekst)}\n </View>\n\n <View\n testID=\"skjermbilde-ramme\"\n onLayout={onLayout}\n style={{\n flex: 1,\n minHeight: tema.touch * 5,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: screenRules.previewBackdrop,\n borderRadius: tema.radius.md,\n overflow: 'hidden',\n }}\n >\n {visning ? (\n <View\n ref={previewRef}\n collapsable={false}\n testID=\"forhandsvisning\"\n accessibilityRole=\"image\"\n accessibilityLabel={a11y}\n onStartShouldSetResponder={() => !komponerer}\n onMoveShouldSetResponder={() => !komponerer}\n onResponderGrant={onGrant}\n onResponderMove={onMove}\n onResponderRelease={onRelease}\n onResponderTerminate={onRelease}\n style={{ width: visning.width, height: visning.height, backgroundColor: screenRules.previewBackdrop }}\n >\n <Image\n testID=\"skjermbilde-bilde\"\n source={{ uri: bilde.uri }}\n blurRadius={allTekst ? screenRules.textBlurRadius : 0}\n style={{ width: visning.width, height: visning.height }}\n accessibilityIgnoresInvertColors\n />\n\n {automasker.map((r, i) => (\n <View\n key={`auto-${i}`}\n testID={`automask-${i}`}\n pointerEvents=\"none\"\n style={{\n position: 'absolute',\n left: r.x,\n top: r.y,\n width: r.width,\n height: r.height,\n backgroundColor: screenRules.autoMaskFill,\n borderWidth: tema.hairline * 2,\n borderColor: screenRules.autoMaskStroke,\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {!komponerer ? (\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }} numberOfLines={1}>\n 🔒 {tekst.maskertAvAppen}\n </Text>\n ) : null}\n </View>\n ))}\n\n {egne.map((r, i) => (\n <View\n key={`egen-${i}`}\n testID={`maske-${i}`}\n pointerEvents=\"none\"\n style={{ position: 'absolute', left: r.x, top: r.y, width: r.width, height: r.height, backgroundColor: screenRules.brushFill }}\n />\n ))}\n </View>\n ) : null}\n </View>\n\n {automasker.length ? <Hint>🔒 {tekst.maskertAvAppenHint}</Hint> : null}\n {egne.length ? <Hint>{tekst.dittStrok}</Hint> : null}\n {allTekst ? <Hint>{tekst.allTekstHint}</Hint> : null}\n\n <View style={{ gap: tema.space.sm }}>\n <Btn variant=\"danger\" testID=\"fjern-bildet\" ikon=\"🗑\" label={tekst.fjernBildet} onPress={onFjern} disabled={komponerer} />\n <Btn testID=\"legg-ved\" label={tekst.leggVedOgFortsett} onPress={onLeggVed} disabled={komponerer || !visning} hint={tekst.leggVedHintDD42} />\n </View>\n </View>\n );\n}\n","import React, { useEffect, useRef } from 'react';\nimport { View, type StyleProp, type ViewStyle } from 'react-native';\nimport { useSkjermbilde, type ViewRef } from './skjermbilde.js';\n\n/**\n * Merk det som aldri skal være med på et skjermbilde (DD-39): navn i en liste,\n * et kontonummer, en samtale. Pakk det inn, og widgeten maskerer det FØR\n * innsenderen ser forhåndsvisningen — som «Maskert av appen», og penselen kan\n * ikke oppheve det. Din kode er sannheten, ikke brukerens presisjon.\n *\n * Uten skjermbilde-adapter gjør komponenten ingenting utover å rendre barna.\n *\n * @example\n * ```tsx\n * <InnspelPrivate><Text>{bruker.navn}</Text></InnspelPrivate>\n * ```\n */\nexport function InnspelPrivate({ children, style }: { children?: React.ReactNode; style?: StyleProp<ViewStyle> }) {\n const ref = useRef<ViewRef | null>(null);\n const kontekst = useSkjermbilde();\n const registrer = kontekst?.privat.register;\n\n useEffect(() => {\n if (!registrer) return;\n return registrer(ref);\n }, [registrer]);\n\n // collapsable={false}: Android slår ellers sammen en View uten stil med\n // forelderen, og da finnes det ingenting å måle.\n return (\n <View ref={ref} collapsable={false} style={style} testID=\"innspel-privat\">\n {children}\n </View>\n );\n}\n","import {\n InnspelApiError,\n type FollowUpView,\n type MyPrograms,\n type ParticipationView,\n type ProgramTask,\n type ProgramView,\n type TaskOutcome,\n} from '@innspel/core';\nimport React, { useCallback, useEffect, useState } from 'react';\nimport { Modal, Pressable, Text, View } from 'react-native';\nimport { useInnspel } from '../InnspelProvider.js';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, Card, H, Hint } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\nimport { Aksept } from './Aksept.js';\nimport { HvordanGikkDet } from './HvordanGikkDet.js';\nimport { Oppfolging } from './Oppfolging.js';\nimport { Oppgaver } from './Oppgaver.js';\nimport { periode } from './periode.js';\n\ntype Dialog = { type: 'oppgave'; task: ProgramTask } | { type: 'oppfolging'; oppfolging: FollowUpView };\n\n/**\n * Betaprogrammet i vertsappen: 3a banneret, 3b aksepten og deltakelsen med\n * «Gå ut» (DD-36). Sett den der vertsappen vil ha invitasjonen — typisk øverst\n * på hjemskjermen. Uten invitasjon og uten deltakelse rendrer den INGENTING;\n * det er wireframens «tom → fanen skjules helt», ikke en tom tilstand.\n *\n * **Tokenet kommer fra verten** (DD-12). Plattformen sender aldri invitasjonen:\n * leietakeren får `program.invitation_created` med tokenet, løser pseudonymet til\n * sin egen bruker og sender lenken i sin egen kanal. Verten fanger tokenet fra\n * dyplenken og gir det hit. Uten det viser banneret fortsatt invitasjonen — men\n * «Bli med» er inaktiv, med lenken forklart, i stedet for å feile ved trykk.\n *\n * Deltakelsen (3c) viser oppgavene med «Gjort» → «Hvordan gikk det?» (tre lukkede\n * valg og en setning, aldri en skala) og oppfølgingskortene (3d, DD-34), der arten\n * avgjør knappene. «Ikke» tilbyr å melde feilen — til verten via `onMeldFeil`, fordi\n * feilsporet og navigasjonen er vertens.\n *\n * @example\n * ```tsx\n * <InnspelProgram invitationToken={tokenFraDyplenke} />\n * ```\n */\nexport function InnspelProgram({\n invitationToken,\n onEndring,\n onMeldFeil,\n}: {\n /** Engangs-tokenet fra leietakerens egen kanal, typisk fanget fra en dyplenke. */\n invitationToken?: string;\n /** Kalles når testeren blir med eller går ut — for vertens egen navigasjon. */\n onEndring?: (deltakelse: ParticipationView | null) => void;\n /** Kalles når testeren vil melde at en oppgave ikke gikk — verten åpner feilsporet med oppgaven som kontekst. Utelatt = tilbudet vises ikke. */\n onMeldFeil?: (task: ProgramTask) => void;\n}) {\n const { client } = useInnspel();\n const tema = useTema();\n\n const [mine, setMine] = useState<MyPrograms | undefined>();\n const [deltakelse, setDeltakelse] = useState<ParticipationView | undefined>();\n const [viserAksept, setViserAksept] = useState(false);\n const [viserGaaUt, setViserGaaUt] = useState(false);\n const [avvist, setAvvist] = useState(false);\n const [sender, setSender] = useState(false);\n const [feil, setFeil] = useState<string | undefined>();\n const [dialog, setDialog] = useState<Dialog | undefined>();\n const [svarFeil, setSvarFeil] = useState<string | undefined>();\n const [lagtBort, setLagtBort] = useState<ReadonlySet<string>>(new Set());\n const [meldFeilFor, setMeldFeilFor] = useState<ProgramTask | undefined>();\n\n const leggBort = useCallback((id: string) => setLagtBort((s) => new Set([...s, id])), []);\n\n // «Lagre» i «Hvordan gikk det?»: én dialog, to mål. Fullføringen legges på deltakelsen\n // så raden viser svaret straks; et svar på oppfølging tar kortet ut av lista.\n const lagreSvar = useCallback(\n async (outcome: TaskOutcome, text: string | undefined) => {\n if (!dialog || !deltakelse) return;\n setSender(true);\n setSvarFeil(undefined);\n try {\n if (dialog.type === 'oppgave') {\n const ny = await client.programs.completeTask(dialog.task.id, { outcome, ...(text ? { text } : {}) });\n setDeltakelse({ ...deltakelse, completions: [...deltakelse.completions, ny] });\n if (outcome === 'ikke' && onMeldFeil) setMeldFeilFor(dialog.task);\n } else {\n await client.programs.respond(dialog.oppfolging.id, { outcome, ...(text ? { text } : {}) });\n setMine((m) => (m ? { ...m, pendingFollowUps: m.pendingFollowUps.filter((f) => f.id !== dialog.oppfolging.id) } : m));\n }\n setDialog(undefined);\n } catch (e) {\n setSvarFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n },\n [client, deltakelse, dialog, onMeldFeil],\n );\n\n // Anonym modus har ingen programmer, og skal ikke spørre: kallet ville blitt\n // 401 uansett, og et kall som alltid feiler er ikke en tilstand — det er støy.\n useEffect(() => {\n if (client.isAnonymous) return;\n let levende = true;\n void client.programs\n .list()\n .then((svar) => {\n if (!levende) return;\n setMine(svar);\n // Aktiv deltakelse er det som vises; trukket kommer aldri tilbake fra listen.\n setDeltakelse(svar.participations.find((p) => p.status !== 'trukket'));\n })\n // Programmet er et tilbud, aldri en sperre: svarer ikke kallet, finnes\n // banneret ikke — vertsappen står uendret.\n .catch(() => undefined);\n return () => {\n levende = false;\n };\n }, [client]);\n\n const bliMed = useCallback(async () => {\n if (!invitationToken) return;\n setSender(true);\n setFeil(undefined);\n try {\n const ny = await client.programs.accept(invitationToken);\n setDeltakelse(ny);\n setViserAksept(false);\n onEndring?.(ny);\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, invitationToken, onEndring]);\n\n const gaaUt = useCallback(async () => {\n if (!deltakelse) return;\n setSender(true);\n try {\n await client.programs.withdraw(deltakelse.id);\n setDeltakelse(undefined);\n setViserGaaUt(false);\n onEndring?.(null);\n } catch (e) {\n setFeil(e instanceof InnspelApiError ? e.message : 'tjeneren svarte ikke.');\n } finally {\n setSender(false);\n }\n }, [client, deltakelse, onEndring]);\n\n // Deltakelsen vinner over invitasjonen: har man sagt ja, er banneret ferdig.\n const invitasjon = deltakelse ? undefined : mine?.invitations[0];\n const program: ProgramView | undefined = deltakelse?.program ?? invitasjon?.program;\n\n if (!program) return null;\n\n if (deltakelse) {\n // 3d: kortene for DETTE programmet, i den rekkefølgen kontaktene kom. Et kort testeren\n // har lagt bort i denne økten vises ikke igjen før neste oppstart.\n const kort = (mine?.pendingFollowUps ?? [])\n .filter((f) => f.programId === program.id && !lagtBort.has(f.id))\n .sort((a, b) => a.emittedAt.localeCompare(b.emittedAt));\n const forsteKontaktNr = Math.max(1, deltakelse.contactsSent - kort.length + 1);\n\n return (\n <View testID=\"program-deltakelse\" accessibilityLabel={tekst.deltakelseRegion} style={{ gap: tema.space.sm }}>\n {kort.map((f, i) => (\n <Oppfolging\n key={f.id}\n oppfolging={f}\n kontaktNr={forsteKontaktNr + i}\n maksKontakter={program.maxContacts}\n onSenere={() => leggBort(f.id)}\n onSvar={() => {\n setSvarFeil(undefined);\n setDialog({ type: 'oppfolging', oppfolging: f });\n }}\n onAapneOppgavene={() => leggBort(f.id)}\n onGaaUt={() => setViserGaaUt(true)}\n />\n ))}\n\n <Card>\n <H sub={tekst.deltakelsePeriode(periode(program.opensAt, program.closesAt), deltakelse.contactsSent, program.maxContacts)}>\n {program.name}\n </H>\n <Oppgaver\n tasks={program.tasks}\n completions={deltakelse.completions}\n onGjort={(task) => {\n setSvarFeil(undefined);\n setDialog({ type: 'oppgave', task });\n }}\n />\n {meldFeilFor && onMeldFeil ? (\n <View style={{ gap: tema.space.xs }}>\n <Hint>{tekst.meldFeilHint}</Hint>\n <Btn\n variant=\"secondary\"\n testID=\"meld-feil\"\n ikon=\"🐞\"\n label={tekst.meldFeil}\n onPress={() => {\n const task = meldFeilFor;\n setMeldFeilFor(undefined);\n onMeldFeil(task);\n }}\n />\n </View>\n ) : null}\n {/* DD-36: «Gå ut» er ALLTID synlig — aldri gjemt bak en meny eller under rullefeltet. */}\n <Btn variant=\"ghost\" testID=\"gaa-ut\" ikon=\"🚪\" label={tekst.gaaUt} onPress={() => setViserGaaUt(true)} />\n </Card>\n\n {dialog ? (\n <HvordanGikkDet\n under={dialog.type === 'oppgave' ? dialog.task.title : dialog.oppfolging.question}\n sender={sender}\n {...(svarFeil ? { feil: svarFeil } : {})}\n onLagre={(outcome, text) => void lagreSvar(outcome, text)}\n onLukk={() => setDialog(undefined)}\n />\n ) : null}\n\n {viserGaaUt ? (\n <Modal visible transparent animationType=\"fade\" onRequestClose={() => setViserGaaUt(false)} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end', padding: tema.space.md }}>\n <View\n testID=\"gaa-ut-dialog\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.surface,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderStrong,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <H>{tekst.gaaUtTittel}</H>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {tekst.gaaUtTekst(program.name)}\n </Text>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {/* «Bli værende» står først: utgangen er et valg, ikke en felle med en angreknapp. */}\n <Btn grow variant=\"secondary\" testID=\"bli-vaerende\" label={tekst.bliVaerende} onPress={() => setViserGaaUt(false)} />\n <Btn grow variant=\"danger\" testID=\"bekreft-gaa-ut\" ikon=\"🚪\" label={tekst.gaaUtBekreft} disabled={sender} onPress={() => void gaaUt()} />\n </View>\n </View>\n </View>\n </Modal>\n ) : null}\n </View>\n );\n }\n\n if (!invitasjon || avvist) return null;\n\n return (\n <>\n <View\n testID=\"program-banner\"\n accessibilityLabel={tekst.invitasjonRegion}\n style={{\n backgroundColor: tema.color.brandBg,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.brand,\n padding: tema.space.md,\n gap: tema.space.sm,\n }}\n >\n <View style={{ flexDirection: 'row', gap: tema.space.sm, alignItems: 'flex-start' }}>\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.h3 }}>\n 🧪\n </Text>\n <View style={{ flex: 1, gap: tema.space.xs }}>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {tekst.invitasjonHva(program.name)}\n </Text>\n <Hint>{tekst.invitasjonKontakter(program.maxContacts)}</Hint>\n </View>\n {/* Avvisbart: invitasjonen er et tilbud. Den kommer tilbake ved neste oppstart, aldri som mas i samme økt. */}\n <Pressable\n testID=\"avvis-invitasjon\"\n accessibilityRole=\"button\"\n accessibilityLabel={tekst.avvisInvitasjon}\n onPress={() => setAvvist(true)}\n style={{ minWidth: tema.touch, minHeight: tema.touch, alignItems: 'center', justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.body }}>✕</Text>\n </Pressable>\n </View>\n {feil && !viserAksept ? <Banner live ikon=\"⚠\" tone=\"danger\" children={tekst.akseptFeil(feil)} /> : null}\n <Btn variant=\"secondary\" testID=\"les-mer\" label={tekst.lesMer} onPress={() => setViserAksept(true)} />\n </View>\n\n {viserAksept ? (\n <Aksept\n program={program}\n harToken={!!invitationToken}\n sender={sender}\n {...(feil ? { feil } : {})}\n onBliMed={() => void bliMed()}\n onLukk={() => setViserAksept(false)}\n />\n ) : null}\n </>\n );\n}\n","import type { ProgramView } from '@innspel/core';\nimport React from 'react';\nimport { Linking, Modal, Pressable, ScrollView, Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, Card, H, Hint, StatusPill } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\nimport { minutterPerOppgave, periode } from './periode.js';\n\n/**\n * 3b — aksepten. Én skjerm i fast rekkefølge (DD-13) med TALLENE øverst (DD-32):\n * N oppgaver × M minutter, dato til dato, maks K kontakter. Oppgavene står HER,\n * ikke i en e-post etterpå, og kjente feil er hele lista — testeren skal slippe\n * å melde det vi vet om.\n *\n * Vilkår er en LENKE, aldri en avkryssing (DD-37); ved forpliktelsesfri form\n * (tvunget når leietakeren har mindreårige brukere, K37) finnes ingen vilkår ut\n * over at man kan gå ut når som helst.\n *\n * «Bli med» krever tokenet leietakeren sendte i sin egen kanal (DD-12).\n * Plattformen sender aldri, og tokenet finnes ikke i `programs.list()` — uten\n * det verten har fanget fra dyplenken er knappen inaktiv, med lenken forklart.\n */\nexport function Aksept({\n program,\n harToken,\n sender,\n feil,\n onBliMed,\n onLukk,\n}: {\n program: ProgramView;\n harToken: boolean;\n sender: boolean;\n feil?: string;\n onBliMed: () => void;\n onLukk: () => void;\n}) {\n const tema = useTema();\n const tall = tekst.akseptTall(\n program.tasks.length,\n minutterPerOppgave(program.tasks),\n periode(program.opensAt, program.closesAt),\n program.maxContacts,\n );\n\n return (\n <Modal visible transparent animationType=\"slide\" onRequestClose={onLukk} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end' }}>\n <View\n testID=\"program-aksept\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.bg,\n borderTopLeftRadius: tema.radius.lg * 2,\n borderTopRightRadius: tema.radius.lg * 2,\n padding: tema.screenPadding,\n gap: tema.space.md,\n maxHeight: '92%',\n minHeight: '60%',\n }}\n >\n <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>\n <Btn variant=\"ghost\" testID=\"aksept-tilbake\" ikon=\"←\" label={tekst.tilbake} onPress={onLukk} />\n <View />\n </View>\n\n {feil ? <Banner live ikon=\"⚠\" tone=\"danger\" children={tekst.akseptFeil(feil)} /> : null}\n\n <ScrollView contentContainerStyle={{ gap: tema.space.md }}>\n <H sub={tekst.akseptHva}>{program.name}</H>\n\n {/* DD-32: tallene på én linje, før forklaringen. */}\n <Text\n accessibilityRole=\"text\"\n style={{\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n fontWeight: tema.weight.semibold,\n }}\n >\n {tall}\n </Text>\n\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {program.hypothesis}\n </Text>\n\n <Card>\n <H>{tekst.akseptOppgaver}</H>\n {program.tasks.map((o) => (\n <View key={o.id} style={{ gap: tema.space.xs }}>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n {o.title}\n </Text>\n <Hint>\n {tekst.akseptOppgaveTid(o.estimatedMinutes)}\n {o.screenHint ? ` · ${o.screenHint}` : ''}\n </Hint>\n </View>\n ))}\n </Card>\n\n {program.knownIssues.length > 0 ? (\n <Card>\n <H sub={tekst.akseptKjenteFeilUnder}>{tekst.akseptKjenteFeil(program.knownIssues.length)}</H>\n {program.knownIssues.map((k) => (\n <View key={k.id} style={{ gap: tema.space.xs }}>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {k.title}\n </Text>\n {k.workaround ? (\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small, lineHeight: tema.lineHeight.small }}>\n {tekst.omvei} {k.workaround}\n </Text>\n ) : null}\n {k.fixedIn ? (\n <StatusPill\n ikon={k.status === 'fikset' ? '✓' : '🔧'}\n etikett={k.status === 'fikset' ? tekst.rettetI(k.fixedIn) : tekst.rettesI(k.fixedIn)}\n farge={k.status === 'fikset' ? 'success' : 'info'}\n />\n ) : null}\n </View>\n ))}\n </Card>\n ) : null}\n\n <Card>\n <H sub={tekst.akseptInnsamlingTekst}>{tekst.akseptInnsamling}</H>\n <Hint>{tekst.kontekstAldri}</Hint>\n </Card>\n\n {/* DD-37: lenke, aldri avkryssing — og ingen vilkår i forpliktelsesfri form. */}\n {program.termsUrl && !program.commitmentFree ? (\n <View style={{ gap: tema.space.xs }}>\n <Pressable\n testID=\"vilkar-lenke\"\n accessibilityRole=\"link\"\n accessibilityLabel={tekst.akseptVilkar}\n onPress={() => void Linking.openURL(String(program.termsUrl))}\n style={{ minHeight: tema.touch, justifyContent: 'center' }}\n >\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, textDecorationLine: 'underline' }}>\n 🔗 {tekst.akseptVilkar}\n </Text>\n </Pressable>\n <Hint>{tekst.akseptVilkarHint}</Hint>\n </View>\n ) : (\n <Hint>{tekst.akseptIngenVilkar}</Hint>\n )}\n\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>\n 🚪 {tekst.akseptUtgang}\n </Text>\n </ScrollView>\n\n <Btn\n testID=\"bli-med\"\n label={tekst.bliMed}\n disabled={!harToken || sender}\n hint={harToken ? tekst.bliMedHint : tekst.bliMedUtenToken}\n onPress={onBliMed}\n />\n </View>\n </View>\n </Modal>\n );\n}\n","/**\n * Datoene testeren ser i aksepten (DD-32): «10.–24. oktober», eller med begge\n * måneder når perioden krysser et månedsskifte. Norsk bokmål, ingen klokkeslett —\n * et program varer i dager, og et tidspunkt ville lovet en presisjon som ikke finnes.\n */\nconst MANEDER = [\n 'januar',\n 'februar',\n 'mars',\n 'april',\n 'mai',\n 'juni',\n 'juli',\n 'august',\n 'september',\n 'oktober',\n 'november',\n 'desember',\n] as const;\n\nexport function periode(opensAt: string, closesAt: string): string {\n const fra = new Date(opensAt);\n const til = new Date(closesAt);\n if (Number.isNaN(fra.getTime()) || Number.isNaN(til.getTime())) return '';\n\n const sammeManed = fra.getMonth() === til.getMonth() && fra.getFullYear() === til.getFullYear();\n return sammeManed\n ? `${fra.getDate()}.–${til.getDate()}. ${MANEDER[til.getMonth()]}`\n : `${fra.getDate()}. ${MANEDER[fra.getMonth()]} – ${til.getDate()}. ${MANEDER[til.getMonth()]}`;\n}\n\n/** Anslått tid per oppgave, avrundet. Obligatorisk ved opprettelse (DD-32), så lista er aldri tom her. */\nexport function minutterPerOppgave(tasks: ReadonlyArray<{ estimatedMinutes: number }>): number {\n if (tasks.length === 0) return 0;\n return Math.round(tasks.reduce((sum, t) => sum + t.estimatedMinutes, 0) / tasks.length);\n}\n","import type { TaskOutcome } from '@innspel/core';\nimport React, { useState } from 'react';\nimport { Modal, Pressable, Text, TextInput, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Banner, Btn, H, Hint } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\n\nexport const UTFALL: ReadonlyArray<{ verdi: TaskOutcome; ikon: string; etikett: string }> = [\n { verdi: 'fungerte', ikon: '✓', etikett: tekst.utfallFungerte },\n { verdi: 'delvis', ikon: '◐', etikett: tekst.utfallDelvis },\n { verdi: 'ikke', ikon: '✕', etikett: tekst.utfallIkke },\n];\n\nexport const SETNING_MAKS = 140;\n\nexport function utfallEtikett(verdi: TaskOutcome): string {\n return UTFALL.find((u) => u.verdi === verdi)?.etikett ?? verdi;\n}\n\n/**\n * 3c — «Hvordan gikk det?». ETT spørsmål med tre lukkede valg og en valgfri\n * setning ≤ 140 — aldri en skala (tech-decisions «M3.2 (forts.)»). Samme dialog\n * for «Gjort» på en oppgave og for «Svar nå» på en oppfølging (3d): det er det\n * samme spørsmålet, og testeren skal kjenne det igjen.\n *\n * NN/G «task, then ask»: rett etter handlingen, under ett minutt, og «Lagre» er\n * slutten — ingen flere spørsmål etterpå. Push-spørsmålet fra wireframen (7c) er\n * vertens: plattformen holder aldri push-tokens.\n */\nexport function HvordanGikkDet({\n under,\n sender,\n feil,\n onLagre,\n onLukk,\n}: {\n /** Hva spørsmålet gjelder — oppgavens tittel eller oppfølgingens spørsmål. */\n under: string;\n sender: boolean;\n feil?: string;\n onLagre: (outcome: TaskOutcome, text: string | undefined) => void;\n onLukk: () => void;\n}) {\n const tema = useTema();\n const [valgt, setValgt] = useState<TaskOutcome | undefined>();\n const [setning, setSetning] = useState('');\n\n return (\n <Modal visible transparent animationType=\"fade\" onRequestClose={onLukk} accessibilityViewIsModal>\n <View style={{ flex: 1, backgroundColor: tema.color.scrim, justifyContent: 'flex-end', padding: tema.space.md }}>\n <View\n testID=\"hvordan-gikk-det\"\n accessibilityViewIsModal\n style={{\n backgroundColor: tema.color.surface,\n borderRadius: tema.radius.lg,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderStrong,\n padding: tema.space.md,\n gap: tema.space.md,\n }}\n >\n <Btn variant=\"ghost\" testID=\"hvordan-tilbake\" ikon=\"←\" label={tekst.tilbake} onPress={onLukk} />\n <Hint>{under}</Hint>\n <H>{tekst.hvordanGikkDet}</H>\n\n <View testID=\"utfall-gruppe\" accessibilityRole=\"radiogroup\" accessibilityLabel={tekst.hvordanGikkDet} style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {UTFALL.map((u) => {\n const aktiv = valgt === u.verdi;\n return (\n <Pressable\n key={u.verdi}\n testID={`utfall-${u.verdi}`}\n accessibilityRole=\"radio\"\n accessibilityLabel={u.etikett}\n accessibilityState={{ checked: aktiv }}\n onPress={() => setValgt(u.verdi)}\n style={{\n flex: 1,\n minHeight: tema.touch,\n alignItems: 'center',\n justifyContent: 'center',\n gap: tema.space.xs,\n padding: tema.space.sm,\n borderRadius: tema.radius.md,\n borderWidth: tema.hairline,\n borderColor: aktiv ? tema.color.brand : tema.color.borderStrong,\n backgroundColor: aktiv ? tema.color.brandBg : tema.color.surfaceRaised,\n }}\n >\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.h3, color: tema.color.textPrimary }}>\n {u.ikon}\n </Text>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.small, fontWeight: aktiv ? tema.weight.semibold : tema.weight.regular }}>\n {u.etikett}\n </Text>\n </Pressable>\n );\n })}\n </View>\n\n <View style={{ gap: tema.space.xs }}>\n <Text style={{ color: tema.color.textSecondary, fontSize: tema.font.small }}>{tekst.setningLabel}</Text>\n <TextInput\n testID=\"hvordan-setning\"\n accessibilityLabel={tekst.setningLabel}\n value={setning}\n onChangeText={setSetning}\n maxLength={SETNING_MAKS}\n multiline\n numberOfLines={3}\n placeholder={tekst.setningPlaceholder}\n placeholderTextColor={tema.color.textMuted}\n style={{\n backgroundColor: tema.color.surfaceRaised,\n borderWidth: tema.hairline,\n borderColor: tema.color.borderStrong,\n borderRadius: tema.radius.md,\n padding: tema.space.md,\n color: tema.color.textPrimary,\n fontSize: tema.font.body,\n lineHeight: tema.lineHeight.body,\n minHeight: tema.touch * 2,\n textAlignVertical: 'top',\n }}\n />\n </View>\n\n {feil ? <Banner live ikon=\"⚠\" tone=\"danger\" children={tekst.svarFeil(feil)} /> : null}\n\n <Btn\n testID=\"hvordan-lagre\"\n label={tekst.lagre}\n hint={tekst.lagreHint}\n disabled={valgt === undefined || sender}\n onPress={() => {\n if (valgt === undefined) return;\n const trimmet = setning.trim();\n onLagre(valgt, trimmet.length > 0 ? trimmet : undefined);\n }}\n />\n </View>\n </View>\n </Modal>\n );\n}\n","import type { FollowUpView } from '@innspel/core';\nimport React from 'react';\nimport { Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Btn, Hint } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\n\n/** Kontakter med spørsmål tar svar; de andre er handlinger (tech-decisions «M3.2 (forts.)»). */\nexport function tarSvar(kind: FollowUpView['kind']): boolean {\n return kind === 'hvordan_gikk_det' || kind === 'sjekkpunkt';\n}\n\n/**\n * 3d — oppfølgingskortene i appen (DD-34). Hvert kort er én av de maks tre\n * kontaktene, og arten avgjør knappene: et spørsmål får «Svar nå», en påminnelse\n * «Åpne oppgavene» (fristen står i teksten fra produkteier), og tilbudet om utgang\n * «Gå ut» — invertert fra press: utgangen er svaret som tilbys. «Senere» legger\n * kortet bort i denne økten; det kommer tilbake ved neste oppstart, aldri som\n * push — plattformen holder ingen push-tokens.\n */\nexport function Oppfolging({\n oppfolging,\n kontaktNr,\n maksKontakter,\n onSenere,\n onSvar,\n onAapneOppgavene,\n onGaaUt,\n}: {\n oppfolging: FollowUpView;\n kontaktNr: number;\n maksKontakter: number;\n onSenere: () => void;\n onSvar: () => void;\n onAapneOppgavene: () => void;\n onGaaUt: () => void;\n}) {\n const tema = useTema();\n const art = tarSvar(oppfolging.kind) ? 'spoersmaal' : oppfolging.kind === 'tilbud_om_utgang' ? 'utgang' : 'paaminnelse';\n const ikon = art === 'spoersmaal' ? '🧪' : art === 'utgang' ? '🚪' : '📅';\n const hint =\n art === 'spoersmaal'\n ? tekst.oppfolgingKontakt(kontaktNr, maksKontakter)\n : art === 'utgang'\n ? tekst.oppfolgingUtgangHint(kontaktNr, maksKontakter)\n : tekst.oppfolgingPaaminnelseHint(kontaktNr, maksKontakter);\n\n return (\n <View\n testID={`oppfolging-${oppfolging.id}`}\n accessibilityLabel={tekst.oppfolgingRegion}\n style={{\n backgroundColor: tema.color.brandBg,\n borderWidth: tema.hairline,\n borderColor: tema.color.brand,\n borderRadius: tema.radius.lg,\n padding: tema.space.md,\n gap: tema.space.sm,\n }}\n >\n <View style={{ flexDirection: 'row', gap: tema.space.sm, alignItems: 'flex-start' }}>\n <Text accessibilityElementsHidden importantForAccessibility=\"no\" style={{ fontSize: tema.font.h3 }}>\n {ikon}\n </Text>\n <View style={{ flex: 1, gap: tema.space.xs }}>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>{oppfolging.question}</Text>\n <Hint>{hint}</Hint>\n </View>\n </View>\n <View style={{ flexDirection: 'row', gap: tema.space.sm }}>\n {art === 'utgang' ? (\n <>\n {/* «Bli værende» står først: utgangen er et valg, ikke en felle. */}\n <Btn grow variant=\"secondary\" testID={`bli-vaerende-${oppfolging.id}`} label={tekst.bliVaerende} onPress={onSenere} />\n <Btn grow variant=\"danger\" testID={`gaa-ut-${oppfolging.id}`} ikon=\"🚪\" label={tekst.gaaUtBekreft} onPress={onGaaUt} />\n </>\n ) : (\n <>\n <Btn grow variant=\"secondary\" testID={`senere-${oppfolging.id}`} label={tekst.senere} onPress={onSenere} />\n {art === 'spoersmaal' ? (\n <Btn grow testID={`svar-naa-${oppfolging.id}`} label={tekst.svarNaa} onPress={onSvar} />\n ) : (\n <Btn grow testID={`aapne-oppgavene-${oppfolging.id}`} label={tekst.aapneOppgavene} onPress={onAapneOppgavene} />\n )}\n </>\n )}\n </View>\n </View>\n );\n}\n","import type { ParticipationView, ProgramTask, TaskCompletionView } from '@innspel/core';\nimport React from 'react';\nimport { Text, View } from 'react-native';\nimport { useTema } from '../tema.js';\nimport { Btn, Hint } from '../widget/primitiver.js';\nimport { tekst } from '../widget/tekster.js';\nimport { utfallEtikett } from './HvordanGikkDet.js';\n\n/**\n * 3c — oppgavelista i deltakelseskortet. Hver oppgave er én rad: tittel, anslag og\n * status «Ikke begynt» eller «Gjort · utfall». «Gjort» åpner «Hvordan gikk det?»\n * (én gang per oppgave — fullføringen er engangs, og raden viser svaret etterpå).\n * Fritt innspill er alltid mulig utenom oppgavene; det er widgetens sak, ikke denne.\n */\nexport function Oppgaver({\n tasks,\n completions,\n onGjort,\n}: {\n tasks: ProgramTask[];\n completions: ParticipationView['completions'];\n onGjort: (task: ProgramTask) => void;\n}) {\n const tema = useTema();\n const ferdig = new Map<string, TaskCompletionView>(completions.map((c) => [c.taskId, c]));\n\n return (\n <View testID=\"oppgaver\" accessibilityLabel={tekst.oppgaverTittel} style={{ gap: tema.space.sm }}>\n {[...tasks]\n .sort((a, b) => a.order - b.order)\n .map((o) => {\n const c = ferdig.get(o.id);\n return (\n <View\n key={o.id}\n testID={`oppgave-${o.id}`}\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n gap: tema.space.sm,\n paddingVertical: tema.space.xs,\n borderBottomWidth: tema.hairline,\n borderBottomColor: tema.color.border,\n }}\n >\n <View style={{ flex: 1, gap: tema.space.xs }}>\n <Text style={{ color: tema.color.textPrimary, fontSize: tema.font.body, lineHeight: tema.lineHeight.body }}>{o.title}</Text>\n <Hint>\n {c ? tekst.oppgaveGjortMed(utfallEtikett(c.outcome)) : `${tekst.oppgaveIkkeBegynt} · ${tekst.akseptOppgaveTid(o.estimatedMinutes)}`}\n {c?.text ? ` · «${c.text}»` : ''}\n </Hint>\n </View>\n {c ? (\n <Text accessibilityLabel={tekst.oppgaveGjortMed(utfallEtikett(c.outcome))} style={{ color: tema.color.success, fontSize: tema.font.h3 }}>\n ✓\n </Text>\n ) : (\n <Btn variant=\"secondary\" testID={`gjort-${o.id}`} ikon=\"✓\" label={tekst.oppgaveGjort} accessibilityLabel={tekst.oppgaveGjortLabel(o.title)} onPress={() => onGjort(o)} />\n )}\n </View>\n );\n })}\n </View>\n );\n}\n","import type { InnspelStorage } from '@innspel/core';\n\n/**\n * Formen på lagringspakkene i React Native-økosystemet: AsyncStorage, MMKV med\n * async-fasade, expo-secure-store. Alle tre har disse tre metodene.\n */\nexport interface AsyncStorageLike {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n}\n\n/**\n * Lager en {@link InnspelStorage} av vertens egen lagringspakke.\n *\n * Pakken tar ingen avhengighet på AsyncStorage eller MMKV med vilje: verten har\n * som regel én av dem allerede, og to kopier av samme lagring i én app er verre\n * enn litt oppsett. Send inn den du bruker:\n *\n * @example\n * ```ts\n * import AsyncStorage from '@react-native-async-storage/async-storage';\n * const storage = createStorage(AsyncStorage);\n * ```\n *\n * Det eneste som lagres er offline-køen (DD-41) — aldri feedback-tokenet, aldri\n * en install- eller enhets-ID (K20). Lagringen trenger derfor ikke være kryptert.\n */\nexport function createStorage(pakke: AsyncStorageLike): InnspelStorage {\n return {\n get: (key) => pakke.getItem(key),\n set: (key, value) => pakke.setItem(key, value),\n remove: (key) => pakke.removeItem(key),\n };\n}\n\n/**\n * Lagring i minne. Køen overlever da ikke at appen lukkes, så den er til\n * utvikling og test — ikke til produksjon. `InnspelProvider` sier fra i\n * konsollen hvis den brukes uten at det er sagt eksplisitt.\n */\nexport function createMemoryStorage(): InnspelStorage {\n const rader = new Map<string, string>();\n return {\n get: async (key) => rader.get(key) ?? null,\n set: async (key, value) => {\n rader.set(key, value);\n },\n remove: async (key) => {\n rader.delete(key);\n },\n };\n}\n"],"mappings":"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","names":["createContext","useCallback","useContext","useMemo","useRef","useState","View","createContext","useContext","createContext","useContext","useCallback","useRef","useState","Pressable","Text","View","Pressable","Text","View","periode","jsx","jsxs","verdi","View","Text","Pressable","Pressable","Text","View","jsx","jsxs","Pressable","Text","View","Text","View","jsx","jsxs","View","Text","Text","View","jsx","jsxs","View","Text","ActivityIndicator","Text","View","jsx","jsxs","View","ActivityIndicator","Text","useMemo","useState","Image","Pressable","Text","View","jsx","jsxs","useState","useMemo","Pressable","Text","View","Image","jsx","jsxs","useRef","useState","useCallback","View","Pressable","Text","jsx","jsxs","createContext","useState","useRef","useMemo","useCallback","View","useContext","useEffect","useRef","View","jsx","useRef","useEffect","View","InnspelApiError","useCallback","useEffect","useState","Modal","Pressable","Text","View","Modal","Pressable","ScrollView","Text","View","t","jsx","jsxs","Modal","View","ScrollView","Text","Pressable","useState","Modal","Pressable","Text","TextInput","View","jsx","jsxs","useState","Modal","View","Pressable","Text","TextInput","Text","View","Fragment","jsx","jsxs","View","Text","Text","View","jsx","jsxs","View","Text","Fragment","jsx","jsxs","useState","useCallback","InnspelApiError","useEffect","View","Modal","Text","Pressable"]}