pompelmi
Version:
RFI-safe file uploads for Node.js — Express/Koa/Next.js middleware with deep ZIP inspection, MIME/size checks, and optional YARA scanning.
1 lines • 187 kB
Source Map (JSON)
{"version":3,"file":"pompelmi.cjs","sources":["../src/presets.ts","../src/scan.ts","../src/validate.ts","../node_modules/.pnpm/react@19.2.0/node_modules/react/cjs/react.production.js","../node_modules/.pnpm/react@19.2.0/node_modules/react/cjs/react.development.js","../node_modules/.pnpm/react@19.2.0/node_modules/react/index.js","../src/useFileScanner.ts","../src/yara/remote.ts","../src/scan/remote.ts","../src/types/decompilation.ts","../src/hipaa-compliance.ts","../src/verdict.ts","../src/scanners/common-heuristics.ts","../src/scanners/zip-bomb-guard.ts","../src/policy.ts"],"sourcesContent":["import type { Scanner, Match, DecompilationScanner, AnalysisDepth } from \"./types\";\n\nexport type PresetName = 'basic' | 'advanced' | 'malware-analysis' | 'decompilation-basic' | 'decompilation-deep' | string;\n\nexport interface PresetOptions { \n // YARA options\n yaraRules?: string | string[];\n yaraTimeout?: number;\n \n // Decompilation options\n enableDecompilation?: boolean;\n decompilationEngine?: 'binaryninja-hlil' | 'ghidra-pcode' | 'both';\n decompilationDepth?: AnalysisDepth;\n decompilationTimeout?: number;\n \n // Binary Ninja specific\n binaryNinjaPath?: string;\n pythonPath?: string;\n \n // Ghidra specific \n ghidraPath?: string;\n analyzeHeadless?: string;\n \n // General options\n timeout?: number;\n [key: string]: unknown;\n}\n\nfunction toScanFn(s: Scanner): (input: any, ctx?: any) => Promise<Match[]> {\n return (typeof s === \"function\" ? s : s.scan) as (input: any, ctx?: any) => Promise<Match[]>;\n}\n\nexport function composeScanners(...scanners: Scanner[]): Scanner {\n return async (input: any, ctx?: any) => {\n const all: Match[] = [];\n for (const s of scanners) {\n try {\n const out = await toScanFn(s)(input, ctx);\n if (Array.isArray(out)) all.push(...out);\n } catch {\n // ignore individual scanner failures\n }\n }\n return all;\n };\n}\n\nexport function createPresetScanner(preset: PresetName, opts: PresetOptions = {}): Scanner {\n const scanners: Scanner[] = [];\n \n // Add decompilation scanners based on preset\n if (preset === 'decompilation-basic' || preset === 'decompilation-deep' || \n preset === 'malware-analysis' || opts.enableDecompilation) {\n \n const depth = preset === 'decompilation-deep' ? 'deep' : \n preset === 'decompilation-basic' ? 'basic' : \n opts.decompilationDepth || 'basic';\n \n if (!opts.decompilationEngine || opts.decompilationEngine === 'binaryninja-hlil' || opts.decompilationEngine === 'both') {\n try {\n // Dynamic import to avoid bundling issues - using Function to bypass TypeScript type checking\n const importModule = new Function('specifier', 'return import(specifier)');\n importModule('@pompelmi/engine-binaryninja').then((mod: any) => {\n const binjaScanner = mod.createBinaryNinjaScanner({\n timeout: opts.decompilationTimeout || opts.timeout || 30000,\n depth,\n pythonPath: opts.pythonPath,\n binaryNinjaPath: opts.binaryNinjaPath\n });\n scanners.push(binjaScanner);\n }).catch(() => {\n // Binary Ninja engine not available\n });\n } catch {\n // Engine not installed\n }\n }\n \n if (!opts.decompilationEngine || opts.decompilationEngine === 'ghidra-pcode' || opts.decompilationEngine === 'both') {\n try {\n // Dynamic import for Ghidra engine (when implemented) - using Function to bypass TypeScript type checking\n const importModule = new Function('specifier', 'return import(specifier)');\n importModule('@pompelmi/engine-ghidra').then((mod: any) => {\n const ghidraScanner = mod.createGhidraScanner({\n timeout: opts.decompilationTimeout || opts.timeout || 30000,\n depth,\n ghidraPath: opts.ghidraPath,\n analyzeHeadless: opts.analyzeHeadless\n });\n scanners.push(ghidraScanner);\n }).catch(() => {\n // Ghidra engine not available\n });\n } catch {\n // Engine not installed\n }\n }\n }\n \n // Add other scanners for advanced presets\n if (preset === 'advanced' || preset === 'malware-analysis') {\n // Add heuristics scanner\n try {\n const { CommonHeuristicsScanner } = require('./scanners/common-heuristics');\n scanners.push(new CommonHeuristicsScanner());\n } catch {\n // Heuristics not available\n }\n }\n \n if (scanners.length === 0) {\n // Fallback scanner that returns no matches\n return async (_input: any, _ctx?: any) => {\n return [] as Match[];\n };\n }\n \n return composeScanners(...scanners);\n}\n\n// Preset configurations\nexport const PRESET_CONFIGS: Record<string, PresetOptions> = {\n 'basic': {\n timeout: 10000\n },\n 'advanced': {\n timeout: 30000,\n enableDecompilation: false\n },\n 'malware-analysis': {\n timeout: 60000,\n enableDecompilation: true,\n decompilationEngine: 'both',\n decompilationDepth: 'deep'\n },\n 'decompilation-basic': {\n timeout: 30000,\n enableDecompilation: true,\n decompilationDepth: 'basic'\n },\n 'decompilation-deep': {\n timeout: 120000,\n enableDecompilation: true,\n decompilationDepth: 'deep'\n }\n};\n","import { createPresetScanner, type PresetName } from './presets';\nimport type { Match, ScanContext, ScanReport, Verdict, YaraMatch } from './types';\n\n/** Mappa veloce estensione -> mime (basic) */\nfunction guessMimeByExt(name?: string): string | undefined {\n if (!name) return;\n const ext = name.toLowerCase().split('.').pop();\n switch (ext) {\n case 'zip': return 'application/zip';\n case 'png': return 'image/png';\n case 'jpg':\n case 'jpeg': return 'image/jpeg';\n case 'pdf': return 'application/pdf';\n case 'txt': return 'text/plain';\n default: return;\n }\n}\n\n/** Heuristica semplice per verdetto */\nfunction computeVerdict(matches: YaraMatch[]): Verdict {\n if (!matches.length) return 'clean';\n // se la regola contiene 'zip_' lo marchiamo \"suspicious\"\n const anyHigh = matches.some(m => (m.tags ?? []).includes('critical') || (m.tags ?? []).includes('high'));\n return anyHigh ? 'malicious' : 'suspicious';\n}\n\n/** Converte i Match (heuristics) in YaraMatch-like per uniformare l'output */\nfunction toYaraMatches(ms: Match[]): YaraMatch[] {\n return ms.map(m => ({\n rule: m.rule,\n namespace: 'heuristics',\n tags: ['heuristics'].concat(m.severity ? [m.severity] : []),\n meta: m.meta,\n }));\n}\n\nexport type ScanOptions = {\n preset?: PresetName; // default: 'zip-basic'\n ctx?: ScanContext; // filename/mime/size ecc.\n};\n\n/** Scan di bytes (browser/node) usando preset (default: zip-basic) */\nexport async function scanBytes(input: Uint8Array, opts: ScanOptions = {}): Promise<ScanReport> {\n const t0 = Date.now();\n const preset = opts.preset ?? 'zip-basic';\n const ctx: ScanContext = {\n ...opts.ctx,\n mimeType: opts.ctx?.mimeType ?? guessMimeByExt(opts.ctx?.filename),\n size: opts.ctx?.size ?? input.byteLength,\n };\n\n const scanFn = createPresetScanner(preset);\n const matchesH = await (typeof (scanFn as any) === \"function\" ? (scanFn as any) : (scanFn as any).scan)(input, ctx);\n const matches = toYaraMatches(matchesH);\n\n const verdict = computeVerdict(matches);\n const durationMs = Date.now() - t0;\n\n return {\n ok: verdict === 'clean',\n verdict,\n matches,\n reasons: matches.map(m => m.rule),\n file: { name: ctx.filename, mimeType: ctx.mimeType, size: ctx.size },\n durationMs,\n engine: 'heuristics',\n truncated: false,\n timedOut: false,\n };\n}\n\n/** Scan di un file su disco (Node). Import dinamico per non vincolare il bundle browser. */\nexport async function scanFile(filePath: string, opts: Omit<ScanOptions, 'ctx'> = {}): Promise<ScanReport> {\n const [{ readFile, stat }, path] = await Promise.all([\n import('fs/promises'),\n import('path'),\n ]);\n\n const [buf, st] = await Promise.all([readFile(filePath), stat(filePath)]);\n const ctx: ScanContext = {\n filename: path.basename(filePath),\n mimeType: guessMimeByExt(filePath),\n size: st.size,\n };\n return scanBytes(new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength), { ...opts, ctx });\n}\n\n/** Scan multipli File (browser) usando scanBytes + preset di default */\nexport async function scanFiles(\n files: ArrayLike<File>,\n opts: Omit<ScanOptions, 'ctx'> = {}\n): Promise<ScanReport[]> {\n const list = Array.from(files as ArrayLike<File>) as File[];\n const out: ScanReport[] = [];\n for (const f of list) {\n const buf = new Uint8Array(await f.arrayBuffer());\n const rep = await scanBytes(buf, {\n ...opts,\n ctx: { filename: f.name, mimeType: f.type || guessMimeByExt(f.name), size: f.size },\n });\n out.push(rep);\n }\n return out;\n}\n","/**\n * Validates a File by MIME type and size (max 5 MB).\n */\nexport function validateFile(\n file: File\n): { valid: boolean; error?: string } {\n const maxSize = 5 * 1024 * 1024;\n const allowedTypes = ['text/plain', 'application/json', 'text/csv'];\n\n if (!allowedTypes.includes(file.type)) {\n return { valid: false, error: 'Unsupported file type' };\n }\n if (file.size > maxSize) {\n return { valid: false, error: 'File too large (max 5 MB)' };\n }\n return { valid: true };\n}","/**\n * @license React\n * react.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n MAYBE_ITERATOR_SYMBOL = Symbol.iterator;\nfunction getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable) return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n}\nvar ReactNoopUpdateQueue = {\n isMounted: function () {\n return !1;\n },\n enqueueForceUpdate: function () {},\n enqueueReplaceState: function () {},\n enqueueSetState: function () {}\n },\n assign = Object.assign,\n emptyObject = {};\nfunction Component(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n}\nComponent.prototype.isReactComponent = {};\nComponent.prototype.setState = function (partialState, callback) {\n if (\n \"object\" !== typeof partialState &&\n \"function\" !== typeof partialState &&\n null != partialState\n )\n throw Error(\n \"takes an object of state variables to update or a function which returns an object of state variables.\"\n );\n this.updater.enqueueSetState(this, partialState, callback, \"setState\");\n};\nComponent.prototype.forceUpdate = function (callback) {\n this.updater.enqueueForceUpdate(this, callback, \"forceUpdate\");\n};\nfunction ComponentDummy() {}\nComponentDummy.prototype = Component.prototype;\nfunction PureComponent(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n}\nvar pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());\npureComponentPrototype.constructor = PureComponent;\nassign(pureComponentPrototype, Component.prototype);\npureComponentPrototype.isPureReactComponent = !0;\nvar isArrayImpl = Array.isArray;\nfunction noop() {}\nvar ReactSharedInternals = { H: null, A: null, T: null, S: null },\n hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction ReactElement(type, key, props) {\n var refProp = props.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== refProp ? refProp : null,\n props: props\n };\n}\nfunction cloneAndReplaceKey(oldElement, newKey) {\n return ReactElement(oldElement.type, newKey, oldElement.props);\n}\nfunction isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n}\nfunction escape(key) {\n var escaperLookup = { \"=\": \"=0\", \":\": \"=2\" };\n return (\n \"$\" +\n key.replace(/[=:]/g, function (match) {\n return escaperLookup[match];\n })\n );\n}\nvar userProvidedKeyEscapeRegex = /\\/+/g;\nfunction getElementKey(element, index) {\n return \"object\" === typeof element && null !== element && null != element.key\n ? escape(\"\" + element.key)\n : index.toString(36);\n}\nfunction resolveThenable(thenable) {\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n default:\n switch (\n (\"string\" === typeof thenable.status\n ? thenable.then(noop, noop)\n : ((thenable.status = \"pending\"),\n thenable.then(\n function (fulfilledValue) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = fulfilledValue));\n },\n function (error) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"rejected\"), (thenable.reason = error));\n }\n )),\n thenable.status)\n ) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n }\n }\n throw thenable;\n}\nfunction mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {\n var type = typeof children;\n if (\"undefined\" === type || \"boolean\" === type) children = null;\n var invokeCallback = !1;\n if (null === children) invokeCallback = !0;\n else\n switch (type) {\n case \"bigint\":\n case \"string\":\n case \"number\":\n invokeCallback = !0;\n break;\n case \"object\":\n switch (children.$$typeof) {\n case REACT_ELEMENT_TYPE:\n case REACT_PORTAL_TYPE:\n invokeCallback = !0;\n break;\n case REACT_LAZY_TYPE:\n return (\n (invokeCallback = children._init),\n mapIntoArray(\n invokeCallback(children._payload),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n )\n );\n }\n }\n if (invokeCallback)\n return (\n (callback = callback(children)),\n (invokeCallback =\n \"\" === nameSoFar ? \".\" + getElementKey(children, 0) : nameSoFar),\n isArrayImpl(callback)\n ? ((escapedPrefix = \"\"),\n null != invokeCallback &&\n (escapedPrefix =\n invokeCallback.replace(userProvidedKeyEscapeRegex, \"$&/\") + \"/\"),\n mapIntoArray(callback, array, escapedPrefix, \"\", function (c) {\n return c;\n }))\n : null != callback &&\n (isValidElement(callback) &&\n (callback = cloneAndReplaceKey(\n callback,\n escapedPrefix +\n (null == callback.key ||\n (children && children.key === callback.key)\n ? \"\"\n : (\"\" + callback.key).replace(\n userProvidedKeyEscapeRegex,\n \"$&/\"\n ) + \"/\") +\n invokeCallback\n )),\n array.push(callback)),\n 1\n );\n invokeCallback = 0;\n var nextNamePrefix = \"\" === nameSoFar ? \".\" : nameSoFar + \":\";\n if (isArrayImpl(children))\n for (var i = 0; i < children.length; i++)\n (nameSoFar = children[i]),\n (type = nextNamePrefix + getElementKey(nameSoFar, i)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (((i = getIteratorFn(children)), \"function\" === typeof i))\n for (\n children = i.call(children), i = 0;\n !(nameSoFar = children.next()).done;\n\n )\n (nameSoFar = nameSoFar.value),\n (type = nextNamePrefix + getElementKey(nameSoFar, i++)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (\"object\" === type) {\n if (\"function\" === typeof children.then)\n return mapIntoArray(\n resolveThenable(children),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n );\n array = String(children);\n throw Error(\n \"Objects are not valid as a React child (found: \" +\n (\"[object Object]\" === array\n ? \"object with keys {\" + Object.keys(children).join(\", \") + \"}\"\n : array) +\n \"). If you meant to render a collection of children, use an array instead.\"\n );\n }\n return invokeCallback;\n}\nfunction mapChildren(children, func, context) {\n if (null == children) return children;\n var result = [],\n count = 0;\n mapIntoArray(children, result, \"\", \"\", function (child) {\n return func.call(context, child, count++);\n });\n return result;\n}\nfunction lazyInitializer(payload) {\n if (-1 === payload._status) {\n var ctor = payload._result;\n ctor = ctor();\n ctor.then(\n function (moduleObject) {\n if (0 === payload._status || -1 === payload._status)\n (payload._status = 1), (payload._result = moduleObject);\n },\n function (error) {\n if (0 === payload._status || -1 === payload._status)\n (payload._status = 2), (payload._result = error);\n }\n );\n -1 === payload._status && ((payload._status = 0), (payload._result = ctor));\n }\n if (1 === payload._status) return payload._result.default;\n throw payload._result;\n}\nvar reportGlobalError =\n \"function\" === typeof reportError\n ? reportError\n : function (error) {\n if (\n \"object\" === typeof window &&\n \"function\" === typeof window.ErrorEvent\n ) {\n var event = new window.ErrorEvent(\"error\", {\n bubbles: !0,\n cancelable: !0,\n message:\n \"object\" === typeof error &&\n null !== error &&\n \"string\" === typeof error.message\n ? String(error.message)\n : String(error),\n error: error\n });\n if (!window.dispatchEvent(event)) return;\n } else if (\n \"object\" === typeof process &&\n \"function\" === typeof process.emit\n ) {\n process.emit(\"uncaughtException\", error);\n return;\n }\n console.error(error);\n },\n Children = {\n map: mapChildren,\n forEach: function (children, forEachFunc, forEachContext) {\n mapChildren(\n children,\n function () {\n forEachFunc.apply(this, arguments);\n },\n forEachContext\n );\n },\n count: function (children) {\n var n = 0;\n mapChildren(children, function () {\n n++;\n });\n return n;\n },\n toArray: function (children) {\n return (\n mapChildren(children, function (child) {\n return child;\n }) || []\n );\n },\n only: function (children) {\n if (!isValidElement(children))\n throw Error(\n \"React.Children.only expected to receive a single React element child.\"\n );\n return children;\n }\n };\nexports.Activity = REACT_ACTIVITY_TYPE;\nexports.Children = Children;\nexports.Component = Component;\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.Profiler = REACT_PROFILER_TYPE;\nexports.PureComponent = PureComponent;\nexports.StrictMode = REACT_STRICT_MODE_TYPE;\nexports.Suspense = REACT_SUSPENSE_TYPE;\nexports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n ReactSharedInternals;\nexports.__COMPILER_RUNTIME = {\n __proto__: null,\n c: function (size) {\n return ReactSharedInternals.H.useMemoCache(size);\n }\n};\nexports.cache = function (fn) {\n return function () {\n return fn.apply(null, arguments);\n };\n};\nexports.cacheSignal = function () {\n return null;\n};\nexports.cloneElement = function (element, config, children) {\n if (null === element || void 0 === element)\n throw Error(\n \"The argument must be a React element, but you passed \" + element + \".\"\n );\n var props = assign({}, element.props),\n key = element.key;\n if (null != config)\n for (propName in (void 0 !== config.key && (key = \"\" + config.key), config))\n !hasOwnProperty.call(config, propName) ||\n \"key\" === propName ||\n \"__self\" === propName ||\n \"__source\" === propName ||\n (\"ref\" === propName && void 0 === config.ref) ||\n (props[propName] = config[propName]);\n var propName = arguments.length - 2;\n if (1 === propName) props.children = children;\n else if (1 < propName) {\n for (var childArray = Array(propName), i = 0; i < propName; i++)\n childArray[i] = arguments[i + 2];\n props.children = childArray;\n }\n return ReactElement(element.type, key, props);\n};\nexports.createContext = function (defaultValue) {\n defaultValue = {\n $$typeof: REACT_CONTEXT_TYPE,\n _currentValue: defaultValue,\n _currentValue2: defaultValue,\n _threadCount: 0,\n Provider: null,\n Consumer: null\n };\n defaultValue.Provider = defaultValue;\n defaultValue.Consumer = {\n $$typeof: REACT_CONSUMER_TYPE,\n _context: defaultValue\n };\n return defaultValue;\n};\nexports.createElement = function (type, config, children) {\n var propName,\n props = {},\n key = null;\n if (null != config)\n for (propName in (void 0 !== config.key && (key = \"\" + config.key), config))\n hasOwnProperty.call(config, propName) &&\n \"key\" !== propName &&\n \"__self\" !== propName &&\n \"__source\" !== propName &&\n (props[propName] = config[propName]);\n var childrenLength = arguments.length - 2;\n if (1 === childrenLength) props.children = children;\n else if (1 < childrenLength) {\n for (var childArray = Array(childrenLength), i = 0; i < childrenLength; i++)\n childArray[i] = arguments[i + 2];\n props.children = childArray;\n }\n if (type && type.defaultProps)\n for (propName in ((childrenLength = type.defaultProps), childrenLength))\n void 0 === props[propName] &&\n (props[propName] = childrenLength[propName]);\n return ReactElement(type, key, props);\n};\nexports.createRef = function () {\n return { current: null };\n};\nexports.forwardRef = function (render) {\n return { $$typeof: REACT_FORWARD_REF_TYPE, render: render };\n};\nexports.isValidElement = isValidElement;\nexports.lazy = function (ctor) {\n return {\n $$typeof: REACT_LAZY_TYPE,\n _payload: { _status: -1, _result: ctor },\n _init: lazyInitializer\n };\n};\nexports.memo = function (type, compare) {\n return {\n $$typeof: REACT_MEMO_TYPE,\n type: type,\n compare: void 0 === compare ? null : compare\n };\n};\nexports.startTransition = function (scope) {\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n try {\n var returnValue = scope(),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n \"object\" === typeof returnValue &&\n null !== returnValue &&\n \"function\" === typeof returnValue.then &&\n returnValue.then(noop, reportGlobalError);\n } catch (error) {\n reportGlobalError(error);\n } finally {\n null !== prevTransition &&\n null !== currentTransition.types &&\n (prevTransition.types = currentTransition.types),\n (ReactSharedInternals.T = prevTransition);\n }\n};\nexports.unstable_useCacheRefresh = function () {\n return ReactSharedInternals.H.useCacheRefresh();\n};\nexports.use = function (usable) {\n return ReactSharedInternals.H.use(usable);\n};\nexports.useActionState = function (action, initialState, permalink) {\n return ReactSharedInternals.H.useActionState(action, initialState, permalink);\n};\nexports.useCallback = function (callback, deps) {\n return ReactSharedInternals.H.useCallback(callback, deps);\n};\nexports.useContext = function (Context) {\n return ReactSharedInternals.H.useContext(Context);\n};\nexports.useDebugValue = function () {};\nexports.useDeferredValue = function (value, initialValue) {\n return ReactSharedInternals.H.useDeferredValue(value, initialValue);\n};\nexports.useEffect = function (create, deps) {\n return ReactSharedInternals.H.useEffect(create, deps);\n};\nexports.useEffectEvent = function (callback) {\n return ReactSharedInternals.H.useEffectEvent(callback);\n};\nexports.useId = function () {\n return ReactSharedInternals.H.useId();\n};\nexports.useImperativeHandle = function (ref, create, deps) {\n return ReactSharedInternals.H.useImperativeHandle(ref, create, deps);\n};\nexports.useInsertionEffect = function (create, deps) {\n return ReactSharedInternals.H.useInsertionEffect(create, deps);\n};\nexports.useLayoutEffect = function (create, deps) {\n return ReactSharedInternals.H.useLayoutEffect(create, deps);\n};\nexports.useMemo = function (create, deps) {\n return ReactSharedInternals.H.useMemo(create, deps);\n};\nexports.useOptimistic = function (passthrough, reducer) {\n return ReactSharedInternals.H.useOptimistic(passthrough, reducer);\n};\nexports.useReducer = function (reducer, initialArg, init) {\n return ReactSharedInternals.H.useReducer(reducer, initialArg, init);\n};\nexports.useRef = function (initialValue) {\n return ReactSharedInternals.H.useRef(initialValue);\n};\nexports.useState = function (initialState) {\n return ReactSharedInternals.H.useState(initialState);\n};\nexports.useSyncExternalStore = function (\n subscribe,\n getSnapshot,\n getServerSnapshot\n) {\n return ReactSharedInternals.H.useSyncExternalStore(\n subscribe,\n getSnapshot,\n getServerSnapshot\n );\n};\nexports.useTransition = function () {\n return ReactSharedInternals.H.useTransition();\n};\nexports.version = \"19.2.0\";\n","/**\n * @license React\n * react.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function defineDeprecationWarning(methodName, info) {\n Object.defineProperty(Component.prototype, methodName, {\n get: function () {\n console.warn(\n \"%s(...) is deprecated in plain JavaScript React classes. %s\",\n info[0],\n info[1]\n );\n }\n });\n }\n function getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable)\n return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n }\n function warnNoop(publicInstance, callerName) {\n publicInstance =\n ((publicInstance = publicInstance.constructor) &&\n (publicInstance.displayName || publicInstance.name)) ||\n \"ReactClass\";\n var warningKey = publicInstance + \".\" + callerName;\n didWarnStateUpdateForUnmountedComponent[warningKey] ||\n (console.error(\n \"Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.\",\n callerName,\n publicInstance\n ),\n (didWarnStateUpdateForUnmountedComponent[warningKey] = !0));\n }\n function Component(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n }\n function ComponentDummy() {}\n function PureComponent(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n }\n function noop() {}\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function cloneAndReplaceKey(oldElement, newKey) {\n newKey = ReactElement(\n oldElement.type,\n newKey,\n oldElement.props,\n oldElement._owner,\n oldElement._debugStack,\n oldElement._debugTask\n );\n oldElement._store &&\n (newKey._store.validated = oldElement._store.validated);\n return newKey;\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n function escape(key) {\n var escaperLookup = { \"=\": \"=0\", \":\": \"=2\" };\n return (\n \"$\" +\n key.replace(/[=:]/g, function (match) {\n return escaperLookup[match];\n })\n );\n }\n function getElementKey(element, index) {\n return \"object\" === typeof element &&\n null !== element &&\n null != element.key\n ? (checkKeyStringCoercion(element.key), escape(\"\" + element.key))\n : index.toString(36);\n }\n function resolveThenable(thenable) {\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n default:\n switch (\n (\"string\" === typeof thenable.status\n ? thenable.then(noop, noop)\n : ((thenable.status = \"pending\"),\n thenable.then(\n function (fulfilledValue) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = fulfilledValue));\n },\n function (error) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"rejected\"),\n (thenable.reason = error));\n }\n )),\n thenable.status)\n ) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n }\n }\n throw thenable;\n }\n function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {\n var type = typeof children;\n if (\"undefined\" === type || \"boolean\" === type) children = null;\n var invokeCallback = !1;\n if (null === children) invokeCallback = !0;\n else\n switch (type) {\n case \"bigint\":\n case \"string\":\n case \"number\":\n invokeCallback = !0;\n break;\n case \"object\":\n switch (children.$$typeof) {\n case REACT_ELEMENT_TYPE:\n case REACT_PORTAL_TYPE:\n invokeCallback = !0;\n break;\n case REACT_LAZY_TYPE:\n return (\n (invokeCallback = children._init),\n mapIntoArray(\n invokeCallback(children._payload),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n )\n );\n }\n }\n if (invokeCallback) {\n invokeCallback = children;\n callback = callback(invokeCallback);\n var childKey =\n \"\" === nameSoFar ? \".\" + getElementKey(invokeCallback, 0) : nameSoFar;\n isArrayImpl(callback)\n ? ((escapedPrefix = \"\"),\n null != childKey &&\n (escapedPrefix =\n childKey.replace(userProvidedKeyEscapeRegex, \"$&/\") + \"/\"),\n mapIntoArray(callback, array, escapedPrefix, \"\", function (c) {\n return c;\n }))\n : null != callback &&\n (isValidElement(callback) &&\n (null != callback.key &&\n ((invokeCallback && invokeCallback.key === callback.key) ||\n checkKeyStringCoercion(callback.key)),\n (escapedPrefix = cloneAndReplaceKey(\n callback,\n escapedPrefix +\n (null == callback.key ||\n (invokeCallback && invokeCallback.key === callback.key)\n ? \"\"\n : (\"\" + callback.key).replace(\n userProvidedKeyEscapeRegex,\n \"$&/\"\n ) + \"/\") +\n childKey\n )),\n \"\" !== nameSoFar &&\n null != invokeCallback &&\n isValidElement(invokeCallback) &&\n null == invokeCallback.key &&\n invokeCallback._store &&\n !invokeCallback._store.validated &&\n (escapedPrefix._store.validated = 2),\n (callback = escapedPrefix)),\n array.push(callback));\n return 1;\n }\n invokeCallback = 0;\n childKey = \"\" === nameSoFar ? \".\" : nameSoFar + \":\";\n if (isArrayImpl(children))\n for (var i = 0; i < children.length; i++)\n (nameSoFar = children[i]),\n (type = childKey + getElementKey(nameSoFar, i)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (((i = getIteratorFn(children)), \"function\" === typeof i))\n for (\n i === children.entries &&\n (didWarnAboutMaps ||\n console.warn(\n \"Using Maps as children is not supported. Use an array of keyed ReactElements instead.\"\n ),\n (didWarnAboutMaps = !0)),\n children = i.call(children),\n i = 0;\n !(nameSoFar = children.next()).done;\n\n )\n (nameSoFar = nameSoFar.value),\n (type = childKey + getElementKey(nameSoFar, i++)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (\"object\" === type) {\n if (\"function\" === typeof children.then)\n return mapIntoArray(\n resolveThenable(children),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n );\n array = String(children);\n throw Error(\n \"Objects are not valid as a React child (found: \" +\n (\"[object Object]\" === array\n ? \"object with keys {\" + Object.keys(children).join(\", \") + \"}\"\n : array) +\n \"). If you meant to render a collection of children, use an array instead.\"\n );\n }\n return invokeCallback;\n }\n function mapChildren(children, func, context) {\n if (null == children) return children;\n var result = [],\n count = 0;\n mapIntoArray(children, result, \"\", \"\", function (child) {\n return func.call(context, child, count++);\n });\n return result;\n }\n function lazyInitializer(payload) {\n if (-1 === payload._status) {\n var ioInfo = payload._ioInfo;\n null != ioInfo && (ioInfo.start = ioInfo.end = performance.now());\n ioInfo = payload._result;\n var thenable = ioInfo();\n thenable.then(\n function (moduleObject) {\n if (0 === payload._status || -1 === payload._status) {\n payload._status = 1;\n payload._result = moduleObject;\n var _ioInfo = payload._ioInfo;\n null != _ioInfo && (_ioInfo.end = performance.now());\n void 0 === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = moduleObject));\n }\n },\n function (error) {\n if (0 === payload._status || -1 === payload._status) {\n payload._status = 2;\n payload._result = error;\n var _ioInfo2 = payload._ioInfo;\n null != _ioInfo2 && (_ioInfo2.end = performance.now());\n void 0 === thenable.status &&\n ((thenable.status = \"rejected\"), (thenable.reason = error));\n }\n }\n );\n ioInfo = payload._ioInfo;\n if (null != ioInfo) {\n ioInfo.value = thenable;\n var displayName = thenable.displayName;\n \"string\" === typeof displayName && (ioInfo.name = displayName);\n }\n -1 === payload._status &&\n ((payload._status = 0), (payload._result = thenable));\n }\n if (1 === payload._status)\n return (\n (ioInfo = payload._result),\n void 0 === ioInfo &&\n console.error(\n \"lazy: Expected the result of a dynamic import() call. Instead received: %s\\n\\nYour code should look like: \\n const MyComponent = lazy(() => import('./MyComponent'))\\n\\nDid you accidentally put curly braces around the import?\",\n ioInfo\n ),\n \"default\" in ioInfo ||\n console.error(\n \"lazy: Expected the result of a dynamic import() call. Instead received: %s\\n\\nYour code should look like: \\n const MyComponent = lazy(() => import('./MyComponent'))\",\n ioInfo\n ),\n ioInfo.default\n );\n throw payload._result;\n }\n function resolveDispatcher() {\n var dispatcher = ReactSharedInternals.H;\n null === dispatcher &&\n console.error(\n \"Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\\n1. You might have mismatching versions of React and the renderer (such as React DOM)\\n2. You might be breaking the Rules of Hooks\\n3. You might have more than one copy of React in the same app\\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.\"\n );\n return dispatcher;\n }\n function releaseAsyncTransition() {\n ReactSharedInternals.asyncTransitions--;\n }\n function enqueueTask(task) {\n if (null === enqueueTaskImpl)\n try {\n var requireString = (\"require\" + Math.random()).slice(0, 7);\n enqueueTaskImpl = (module && module[requireString]).call(\n module,\n \"timers\"\n ).setImmediate;\n } catch (_err) {\n enqueueTaskImpl = function (callback) {\n !1 === didWarnAboutMessageChannel &&\n ((didWarnAboutMessageChannel = !0),\n \"undefined\" === typeof MessageChannel &&\n console.error(\n \"This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning.\"\n ));\n var channel = new MessageChannel();\n channel.port1.onmessage = callback;\n channel.port2.postMessage(void 0);\n };\n }\n return enqueueTaskImpl(task);\n }\n function aggregateErrors(errors) {\n return 1 < errors.length && \"function\" === typeof AggregateError\n ? new AggregateError(errors)\n : errors[0];\n }\n function popActScope(prevActQueue, prevActScopeDepth) {\n prevActScopeDepth !== actScopeDepth - 1 &&\n console.error(\n \"You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. \"\n );\n actScopeDepth = prevActScopeDepth;\n }\n function recursivelyFlushAsyncActWork(returnValue, resolve, reject) {\n var queue = ReactSharedInternals.actQueue;\n if (null !== queue)\n if (0 !== queue.length)\n try {\n flushActQueue(queue);\n enqueueTask(function () {\n return recursivelyFlushAsyncActWork(returnValue, resolve, reject);\n });\n return;\n } catch (error) {\n ReactSharedInternals.thrownErrors.push(error);\n }\n else ReactSharedInternals.actQueue = null;\n 0 < ReactSharedInternals.thrownErrors.length\n ? ((queue = aggregateErrors(ReactSharedInternals.thrownErrors)),\n (ReactSharedInternals.thrownErrors.length = 0),\n reject(queue))\n : resolve(returnValue);\n }\n function flushActQueue(queue) {\n if (!isFlushing) {\n isFlushing = !0;\n var i = 0;\n try {\n for (; i < queue.length; i++) {\n var callback = queue[i];\n do {\n ReactSharedInternals.didUsePromise = !1;\n var continuation = callback(!1);\n if