@spring-systems/core 0.8.6 → 0.8.7
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/adapters/index.js +1 -56
- package/dist/auth/index.js +1 -19
- package/dist/chunk-3OMNT22N.js +1 -0
- package/dist/chunk-4KRUU6MS.js +1 -0
- package/dist/chunk-6J2VFOKL.js +1 -0
- package/dist/chunk-7P4BJDQR.js +1 -0
- package/dist/chunk-AMXSATFF.js +1 -0
- package/dist/chunk-BMIRKMVX.js +1 -0
- package/dist/chunk-EVDFSWPU.js +1 -0
- package/dist/chunk-F3VXVDPQ.js +1 -0
- package/dist/chunk-GSQE2NEY.js +1 -0
- package/dist/chunk-HUASNNWD.js +1 -0
- package/dist/chunk-ICKHSEIX.js +1 -0
- package/dist/chunk-JRHMAY5G.js +1 -0
- package/dist/chunk-MNLYYTGZ.js +7 -0
- package/dist/chunk-OOVZTF74.js +1 -0
- package/dist/chunk-PNDXLNCU.js +1 -0
- package/dist/chunk-R3XYEEGR.js +1 -0
- package/dist/chunk-RKLYBW3O.js +1 -0
- package/dist/chunk-RVQHSQYF.js +3 -0
- package/dist/chunk-UT6X6RQM.js +1 -0
- package/dist/chunk-Y6DB43IE.js +3 -0
- package/dist/chunk-YMSSF2ZU.js +1 -0
- package/dist/config/index.js +1 -109
- package/dist/devtools/index.js +1 -67
- package/dist/errors/index.js +1 -21
- package/dist/events/index.js +1 -12
- package/dist/i18n/index.js +1 -7
- package/dist/index.js +1 -42
- package/dist/instance/index.js +1 -37
- package/dist/logger/index.js +1 -27
- package/dist/middleware/index.js +1 -23
- package/dist/plugins/index.js +1 -16
- package/dist/testing/index.js +1 -171
- package/dist/types/index.js +1 -72
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -772
- package/dist/validation/index.js +1 -147
- package/package.json +137 -136
- package/dist/adapters/index.js.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/chunk-2PJWFA5S.js +0 -393
- package/dist/chunk-2PJWFA5S.js.map +0 -1
- package/dist/chunk-EFUBAQCV.js +0 -94
- package/dist/chunk-EFUBAQCV.js.map +0 -1
- package/dist/chunk-F2SIMWZ5.js +0 -173
- package/dist/chunk-F2SIMWZ5.js.map +0 -1
- package/dist/chunk-F7WUQJH7.js +0 -399
- package/dist/chunk-F7WUQJH7.js.map +0 -1
- package/dist/chunk-GON7Q32Q.js +0 -176
- package/dist/chunk-GON7Q32Q.js.map +0 -1
- package/dist/chunk-GXU75LQX.js +0 -182
- package/dist/chunk-GXU75LQX.js.map +0 -1
- package/dist/chunk-HFELOXDQ.js +0 -110
- package/dist/chunk-HFELOXDQ.js.map +0 -1
- package/dist/chunk-KX32MU3I.js +0 -190
- package/dist/chunk-KX32MU3I.js.map +0 -1
- package/dist/chunk-MEWPYTWC.js +0 -284
- package/dist/chunk-MEWPYTWC.js.map +0 -1
- package/dist/chunk-N2L4TUC4.js +0 -34
- package/dist/chunk-N2L4TUC4.js.map +0 -1
- package/dist/chunk-NQQIVCLX.js +0 -47
- package/dist/chunk-NQQIVCLX.js.map +0 -1
- package/dist/chunk-OSSX443T.js +0 -146
- package/dist/chunk-OSSX443T.js.map +0 -1
- package/dist/chunk-PT4DIYUK.js +0 -78
- package/dist/chunk-PT4DIYUK.js.map +0 -1
- package/dist/chunk-QAVWXARR.js +0 -51
- package/dist/chunk-QAVWXARR.js.map +0 -1
- package/dist/chunk-RRWKDFAB.js +0 -143
- package/dist/chunk-RRWKDFAB.js.map +0 -1
- package/dist/chunk-RUCXSQEY.js +0 -42
- package/dist/chunk-RUCXSQEY.js.map +0 -1
- package/dist/chunk-S6RPCN5H.js +0 -64
- package/dist/chunk-S6RPCN5H.js.map +0 -1
- package/dist/chunk-S7MKRNMI.js +0 -153
- package/dist/chunk-S7MKRNMI.js.map +0 -1
- package/dist/chunk-SQB4F3EF.js +0 -55
- package/dist/chunk-SQB4F3EF.js.map +0 -1
- package/dist/chunk-UDT2RPX2.js +0 -43
- package/dist/chunk-UDT2RPX2.js.map +0 -1
- package/dist/chunk-VRMVN2UM.js +0 -17
- package/dist/chunk-VRMVN2UM.js.map +0 -1
- package/dist/config/index.js.map +0 -1
- package/dist/devtools/index.js.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/events/index.js.map +0 -1
- package/dist/i18n/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/instance/index.js.map +0 -1
- package/dist/logger/index.js.map +0 -1
- package/dist/middleware/index.js.map +0 -1
- package/dist/plugins/index.js.map +0 -1
- package/dist/testing/index.js.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/validation/index.js.map +0 -1
package/dist/chunk-F2SIMWZ5.js
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
disposePlugins
|
|
3
|
-
} from "./chunk-GXU75LQX.js";
|
|
4
|
-
import {
|
|
5
|
-
createFrameworkConfig,
|
|
6
|
-
validateFrameworkConfig
|
|
7
|
-
} from "./chunk-F7WUQJH7.js";
|
|
8
|
-
import {
|
|
9
|
-
DEFAULT_MESSAGES
|
|
10
|
-
} from "./chunk-N2L4TUC4.js";
|
|
11
|
-
import {
|
|
12
|
-
sanitizeSecurityData
|
|
13
|
-
} from "./chunk-KX32MU3I.js";
|
|
14
|
-
import {
|
|
15
|
-
__DEV__,
|
|
16
|
-
clearSpringInstanceIfCurrent
|
|
17
|
-
} from "./chunk-EFUBAQCV.js";
|
|
18
|
-
import {
|
|
19
|
-
SpringConfigError
|
|
20
|
-
} from "./chunk-PT4DIYUK.js";
|
|
21
|
-
|
|
22
|
-
// src/instance/create-instance.ts
|
|
23
|
-
var instanceCounter = 0;
|
|
24
|
-
function logNotification(level, message) {
|
|
25
|
-
if (!__DEV__) return;
|
|
26
|
-
const prefix = "[Notification]";
|
|
27
|
-
if (level === "error") {
|
|
28
|
-
console.error(prefix, message);
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (level === "warn") {
|
|
32
|
-
console.warn(prefix, message);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
console.info(prefix, message);
|
|
36
|
-
}
|
|
37
|
-
function createDefaultCoreState(overrides) {
|
|
38
|
-
const config = createFrameworkConfig(overrides);
|
|
39
|
-
return {
|
|
40
|
-
config,
|
|
41
|
-
contentAdapter: { getRes: (key) => DEFAULT_MESSAGES[key] ?? `[${key}]` },
|
|
42
|
-
notificationAdapter: {
|
|
43
|
-
error: (msg) => logNotification("error", msg),
|
|
44
|
-
success: (msg) => logNotification("info", msg),
|
|
45
|
-
warning: (msg) => logNotification("warn", msg),
|
|
46
|
-
info: (msg) => logNotification("info", msg)
|
|
47
|
-
},
|
|
48
|
-
logAdapter: {
|
|
49
|
-
onSecurityEvent: (event, data) => {
|
|
50
|
-
if (!__DEV__) {
|
|
51
|
-
console.warn(`[SPRING Security] ${event}`);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
console.warn(`[SPRING Security] ${event}`, sanitizeSecurityData(data));
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
logoutHandler: null,
|
|
58
|
-
authenticated: false,
|
|
59
|
-
logoutInFlight: null,
|
|
60
|
-
eventListeners: /* @__PURE__ */ new Map(),
|
|
61
|
-
middlewareRegistry: /* @__PURE__ */ new Map(),
|
|
62
|
-
validatorRegistry: /* @__PURE__ */ new Map()
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
function createDefaultApiState() {
|
|
66
|
-
return {
|
|
67
|
-
authToken: null,
|
|
68
|
-
requestControllers: /* @__PURE__ */ new Set(),
|
|
69
|
-
requestHook: null,
|
|
70
|
-
responseHook: null,
|
|
71
|
-
apiPrefix: "/api/v1",
|
|
72
|
-
sessionExpiredCodes: void 0
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
var LIFECYCLE_KEY = /* @__PURE__ */ Symbol.for("spring:lifecycleState");
|
|
76
|
-
var BOOTSTRAPPED_KEY = /* @__PURE__ */ Symbol.for("spring:bootstrapped");
|
|
77
|
-
function createSpringInstance(overrides) {
|
|
78
|
-
const id = `spring-${++instanceCounter}`;
|
|
79
|
-
const core = createDefaultCoreState(overrides);
|
|
80
|
-
const api = createDefaultApiState();
|
|
81
|
-
const validation = validateFrameworkConfig(core.config);
|
|
82
|
-
if (!validation.valid) {
|
|
83
|
-
throw new SpringConfigError(
|
|
84
|
-
`Invalid instance configuration for "${id}":
|
|
85
|
-
- ${validation.errors.join("\n - ")}`
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
const internal = {
|
|
89
|
-
[LIFECYCLE_KEY]: "creating",
|
|
90
|
-
[BOOTSTRAPPED_KEY]: false
|
|
91
|
-
};
|
|
92
|
-
const instance = {
|
|
93
|
-
id,
|
|
94
|
-
get state() {
|
|
95
|
-
return internal[LIFECYCLE_KEY];
|
|
96
|
-
},
|
|
97
|
-
core,
|
|
98
|
-
api,
|
|
99
|
-
ui: {},
|
|
100
|
-
dispose() {
|
|
101
|
-
if (internal[LIFECYCLE_KEY] === "disposed") return;
|
|
102
|
-
internal[LIFECYCLE_KEY] = "disposing";
|
|
103
|
-
disposePlugins(instance);
|
|
104
|
-
core.eventListeners.clear();
|
|
105
|
-
core.middlewareRegistry.clear();
|
|
106
|
-
core.validatorRegistry.clear();
|
|
107
|
-
for (const controller of api.requestControllers) {
|
|
108
|
-
controller.abort();
|
|
109
|
-
}
|
|
110
|
-
api.requestControllers.clear();
|
|
111
|
-
core.authenticated = false;
|
|
112
|
-
core.logoutHandler = null;
|
|
113
|
-
core.logoutInFlight = null;
|
|
114
|
-
api.authToken = null;
|
|
115
|
-
const uiKeys = [
|
|
116
|
-
...Object.keys(instance.ui),
|
|
117
|
-
...Object.getOwnPropertySymbols(instance.ui)
|
|
118
|
-
];
|
|
119
|
-
for (const key of uiKeys) {
|
|
120
|
-
const val = instance.ui[key];
|
|
121
|
-
if (val instanceof Map) val.clear();
|
|
122
|
-
delete instance.ui[key];
|
|
123
|
-
}
|
|
124
|
-
internal[LIFECYCLE_KEY] = "disposed";
|
|
125
|
-
internal[BOOTSTRAPPED_KEY] = false;
|
|
126
|
-
clearSpringInstanceIfCurrent(instance);
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
instance[LIFECYCLE_KEY] = internal;
|
|
130
|
-
return instance;
|
|
131
|
-
}
|
|
132
|
-
function markInstanceReady(instance) {
|
|
133
|
-
if (instance.state !== "creating") return;
|
|
134
|
-
const internal = instance[LIFECYCLE_KEY];
|
|
135
|
-
if (internal) internal[LIFECYCLE_KEY] = "ready";
|
|
136
|
-
}
|
|
137
|
-
function bootstrapSpringInstance(instance, activate) {
|
|
138
|
-
if (instance.state === "disposed" || instance.state === "disposing") {
|
|
139
|
-
throw new SpringConfigError(`Cannot bootstrap disposed instance "${instance.id}".`);
|
|
140
|
-
}
|
|
141
|
-
if (instance.state === "ready") {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
const internal = instance[LIFECYCLE_KEY];
|
|
145
|
-
const isBootstrapped = Boolean(internal?.[BOOTSTRAPPED_KEY]);
|
|
146
|
-
if (isBootstrapped) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
if (internal) {
|
|
150
|
-
internal[BOOTSTRAPPED_KEY] = true;
|
|
151
|
-
}
|
|
152
|
-
try {
|
|
153
|
-
activate();
|
|
154
|
-
markInstanceReady(instance);
|
|
155
|
-
} catch (error) {
|
|
156
|
-
if (internal) {
|
|
157
|
-
internal[BOOTSTRAPPED_KEY] = false;
|
|
158
|
-
}
|
|
159
|
-
clearSpringInstanceIfCurrent(instance);
|
|
160
|
-
throw error;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
function isInstanceActive(instance) {
|
|
164
|
-
return instance.state === "creating" || instance.state === "ready";
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export {
|
|
168
|
-
createSpringInstance,
|
|
169
|
-
markInstanceReady,
|
|
170
|
-
bootstrapSpringInstance,
|
|
171
|
-
isInstanceActive
|
|
172
|
-
};
|
|
173
|
-
//# sourceMappingURL=chunk-F2SIMWZ5.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/instance/create-instance.ts"],"sourcesContent":["/**\n * Factory for creating SpringInstance — a clean state container with all defaults.\n *\n * Lifecycle: `creating` → `ready` → `disposing` → `disposed`\n *\n * @module create-instance\n */\n\nimport { createFrameworkConfig, validateFrameworkConfig } from \"../config/framework-config\";\nimport type { FrameworkConfig, FrameworkConfigOverrides } from \"../config/framework-config-types\";\nimport { SpringConfigError } from \"../errors/errors\";\nimport { DEFAULT_MESSAGES } from \"../i18n/default-messages\";\nimport { disposePlugins } from \"../plugins/plugin\";\nimport { __DEV__ } from \"../utils/dev-warnings\";\nimport { sanitizeSecurityData, type SecurityLogData } from \"../utils/security-sanitize\";\nimport { clearSpringInstanceIfCurrent } from \"./current-instance\";\nimport type { InstanceLifecycleState,SpringApiState, SpringCoreState, SpringInstance } from \"./spring-instance\";\n\n/** @global Legitimately global — monotonic counter for unique instance IDs across all instances. */\nlet instanceCounter = 0;\n\nfunction logNotification(level: \"error\" | \"info\" | \"warn\", message: string): void {\n if (!__DEV__) return;\n const prefix = \"[Notification]\";\n if (level === \"error\") {\n console.error(prefix, message);\n return;\n }\n if (level === \"warn\") {\n console.warn(prefix, message);\n return;\n }\n console.info(prefix, message);\n}\n\nfunction createDefaultCoreState(overrides?: FrameworkConfigOverrides): SpringCoreState {\n const config: FrameworkConfig = createFrameworkConfig(overrides);\n\n return {\n config,\n contentAdapter: { getRes: (key: string) => (DEFAULT_MESSAGES as Record<string, string>)[key] ?? `[${key}]` },\n notificationAdapter: {\n error: (msg: string) => logNotification(\"error\", msg),\n success: (msg: string) => logNotification(\"info\", msg),\n warning: (msg: string) => logNotification(\"warn\", msg),\n info: (msg: string) => logNotification(\"info\", msg),\n },\n logAdapter: {\n onSecurityEvent: (event: string, data?: SecurityLogData) => {\n if (!__DEV__) {\n // Keep a minimal audit trail in production without payload details.\n console.warn(`[SPRING Security] ${event}`);\n return;\n }\n console.warn(`[SPRING Security] ${event}`, sanitizeSecurityData(data));\n },\n },\n logoutHandler: null,\n authenticated: false,\n logoutInFlight: null,\n eventListeners: new Map(),\n middlewareRegistry: new Map(),\n validatorRegistry: new Map(),\n };\n}\n\nfunction createDefaultApiState(): SpringApiState {\n return {\n authToken: null,\n requestControllers: new Set(),\n requestHook: null,\n responseHook: null,\n apiPrefix: \"/api/v1\",\n sessionExpiredCodes: undefined,\n };\n}\n\n/** Symbol key for mutable lifecycle state (hidden from public API) */\nconst LIFECYCLE_KEY = Symbol.for(\"spring:lifecycleState\");\nconst BOOTSTRAPPED_KEY = Symbol.for(\"spring:bootstrapped\");\n\n/** Type-safe accessor for the internal lifecycle record stored on an instance */\ninterface InstanceWithInternal extends SpringInstance {\n [key: symbol]: Record<symbol, unknown> | undefined;\n}\n\n/**\n * Create a fresh SpringInstance with clean state.\n * Each instance gets its own event listeners, middleware registry, validators, etc.\n *\n * The instance starts in `creating` state. Call `markInstanceReady()` after\n * applying plugins and fallbacks to transition to `ready`.\n *\n * @param overrides - Partial config overrides merged with DEFAULT_FRAMEWORK_CONFIG (deep-merged per section)\n * @returns A new SpringInstance in `creating` lifecycle state with a unique ID.\n */\nexport function createSpringInstance(overrides?: FrameworkConfigOverrides): SpringInstance {\n const id = `spring-${++instanceCounter}`;\n const core = createDefaultCoreState(overrides);\n const api = createDefaultApiState();\n\n // Reject invalid config in all runtimes to keep behavior aligned with configureFramework().\n const validation = validateFrameworkConfig(core.config);\n if (!validation.valid) {\n throw new SpringConfigError(\n `Invalid instance configuration for \"${id}\":\\n - ${validation.errors.join(\"\\n - \")}`,\n );\n }\n\n const internal: Record<symbol, unknown> = {\n [LIFECYCLE_KEY]: \"creating\" as InstanceLifecycleState,\n [BOOTSTRAPPED_KEY]: false,\n };\n\n const instance: SpringInstance = {\n id,\n get state() {\n return internal[LIFECYCLE_KEY] as InstanceLifecycleState;\n },\n core,\n api,\n ui: {},\n dispose() {\n if (internal[LIFECYCLE_KEY] === \"disposed\") return;\n internal[LIFECYCLE_KEY] = \"disposing\";\n\n // Dispose plugins first — their cleanups may reference instance state\n disposePlugins(instance);\n\n // Clear event bus\n core.eventListeners.clear();\n // Clear middleware\n core.middlewareRegistry.clear();\n // Clear validators\n core.validatorRegistry.clear();\n // Abort all pending requests\n for (const controller of api.requestControllers) {\n controller.abort();\n }\n api.requestControllers.clear();\n // Clear auth state\n core.authenticated = false;\n core.logoutHandler = null;\n core.logoutInFlight = null;\n api.authToken = null;\n // Clear UI state (dialog resolvers, after-navigate map, etc.)\n // Iterate both string and symbol keys\n const uiKeys: (string | symbol)[] = [\n ...Object.keys(instance.ui),\n ...Object.getOwnPropertySymbols(instance.ui),\n ];\n for (const key of uiKeys) {\n const val = instance.ui[key];\n if (val instanceof Map) val.clear();\n delete instance.ui[key];\n }\n\n internal[LIFECYCLE_KEY] = \"disposed\";\n internal[BOOTSTRAPPED_KEY] = false;\n clearSpringInstanceIfCurrent(instance);\n },\n };\n\n // Store internal ref for markInstanceReady\n (instance as InstanceWithInternal)[LIFECYCLE_KEY] = internal;\n\n return instance;\n}\n\n/**\n * Transition an instance to `ready` state.\n * Should be called after all initialization (plugins, fallbacks, adapters) is complete.\n */\nexport function markInstanceReady(instance: SpringInstance): void {\n if (instance.state !== \"creating\") return;\n const internal = (instance as InstanceWithInternal)[LIFECYCLE_KEY];\n if (internal) internal[LIFECYCLE_KEY] = \"ready\";\n}\n\n/**\n * Run one-time activation work for an instance and transition it to `ready`.\n *\n * Safe under StrictMode and remounts:\n * - render phase may create the instance, but activation happens later\n * - repeated activation on the same ready instance is a no-op\n * - bootstrap failures clear the current-instance bridge before rethrowing\n */\nexport function bootstrapSpringInstance(instance: SpringInstance, activate: () => void): void {\n if (instance.state === \"disposed\" || instance.state === \"disposing\") {\n throw new SpringConfigError(`Cannot bootstrap disposed instance \"${instance.id}\".`);\n }\n\n if (instance.state === \"ready\") {\n return;\n }\n\n const internal = (instance as InstanceWithInternal)[LIFECYCLE_KEY];\n const isBootstrapped = Boolean(internal?.[BOOTSTRAPPED_KEY]);\n if (isBootstrapped) {\n return;\n }\n\n if (internal) {\n internal[BOOTSTRAPPED_KEY] = true;\n }\n\n try {\n activate();\n markInstanceReady(instance);\n } catch (error) {\n if (internal) {\n internal[BOOTSTRAPPED_KEY] = false;\n }\n clearSpringInstanceIfCurrent(instance);\n throw error;\n }\n}\n\n/**\n * Check if an instance is in a usable state (creating or ready).\n */\nexport function isInstanceActive(instance: SpringInstance): boolean {\n return instance.state === \"creating\" || instance.state === \"ready\";\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-F7WUQJH7.js
DELETED
|
@@ -1,399 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
registerFallbackMigration
|
|
3
|
-
} from "./chunk-RUCXSQEY.js";
|
|
4
|
-
import {
|
|
5
|
-
__DEV__,
|
|
6
|
-
tryGetSpringInstance
|
|
7
|
-
} from "./chunk-EFUBAQCV.js";
|
|
8
|
-
import {
|
|
9
|
-
SpringConfigError
|
|
10
|
-
} from "./chunk-PT4DIYUK.js";
|
|
11
|
-
|
|
12
|
-
// src/config/framework-config.ts
|
|
13
|
-
function deepFreeze(obj) {
|
|
14
|
-
Object.freeze(obj);
|
|
15
|
-
for (const value of Object.values(obj)) {
|
|
16
|
-
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
17
|
-
deepFreeze(value);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return obj;
|
|
21
|
-
}
|
|
22
|
-
var DEFAULT_FRAMEWORK_CONFIG = deepFreeze({
|
|
23
|
-
app: {
|
|
24
|
-
name: "App",
|
|
25
|
-
defaultRoute: "/",
|
|
26
|
-
htmlLang: "en",
|
|
27
|
-
skipLinkText: "Skip to main content",
|
|
28
|
-
supportEmail: "",
|
|
29
|
-
logo: { src: "/images/logo.svg", alt: "Logo" }
|
|
30
|
-
},
|
|
31
|
-
auth: {
|
|
32
|
-
sessionCookiePrefix: "app",
|
|
33
|
-
publicAuthPaths: ["auth/login", "auth/forgot_password", "auth/change_password"],
|
|
34
|
-
sessionExpiredCodes: ["session_expired", "token_expired", "invalid_token"],
|
|
35
|
-
loginFormFieldPrefix: "app",
|
|
36
|
-
allowInMemoryTokenStorage: false,
|
|
37
|
-
loginPath: "auth/login",
|
|
38
|
-
logoutPath: "auth/logout",
|
|
39
|
-
infoPath: "auth/info",
|
|
40
|
-
tokenResponseFields: { accessToken: "access_token", refreshToken: "refresh_token" },
|
|
41
|
-
loginUsernameField: "username"
|
|
42
|
-
},
|
|
43
|
-
proxy: {
|
|
44
|
-
corsAllowedHeaders: "Content-Type, Authorization, X-Requested-With, X-hash, Hash",
|
|
45
|
-
maxProxyPathLength: 2048,
|
|
46
|
-
safeHashPattern: /^[A-Za-z0-9._~-]{1,256}$/,
|
|
47
|
-
blockedPathPrefixesInProd: []
|
|
48
|
-
},
|
|
49
|
-
csp: {
|
|
50
|
-
thirdPartyScriptSources: [],
|
|
51
|
-
thirdPartyConnectSources: [],
|
|
52
|
-
thirdPartyImageSources: [],
|
|
53
|
-
thirdPartyFrameSources: []
|
|
54
|
-
},
|
|
55
|
-
i18n: {
|
|
56
|
-
languages: [],
|
|
57
|
-
defaultLanguageCode: "en",
|
|
58
|
-
numberLocale: "en-US",
|
|
59
|
-
dayjsLocale: "en",
|
|
60
|
-
dateFormats: {
|
|
61
|
-
date: "YYYY-MM-DD",
|
|
62
|
-
dateTime: "YYYY-MM-DD HH:mm",
|
|
63
|
-
dateTimeSeconds: "YYYY-MM-DD HH:mm:ss",
|
|
64
|
-
time: "HH:mm"
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
theme: {},
|
|
68
|
-
darkTheme: {},
|
|
69
|
-
componentTokens: {},
|
|
70
|
-
limits: {
|
|
71
|
-
maxFileSize: 10 * 1024 * 1024,
|
|
72
|
-
autocompleteDebounceMs: 300,
|
|
73
|
-
maxOpenedTabs: 10,
|
|
74
|
-
signalrIdleTimeoutMs: 6e4,
|
|
75
|
-
signalrServerTimeoutMs: 3e4,
|
|
76
|
-
signalrKeepAliveIntervalMs: 1e4,
|
|
77
|
-
signalrReconnectDelaysMs: [0, 1e3, 2e3, 5e3, 1e4, 15e3],
|
|
78
|
-
idleSessionTimeoutMs: 30 * 60 * 1e3
|
|
79
|
-
},
|
|
80
|
-
api: {
|
|
81
|
-
listUrlPattern: "${route}/list",
|
|
82
|
-
detailWithMetaPattern: "${route}/${id}",
|
|
83
|
-
detailUrlPattern: "${route}/${id}",
|
|
84
|
-
nullDateSentinel: "0001-01-01T00:00:00",
|
|
85
|
-
timeoutMs: 3e4,
|
|
86
|
-
retryMaxAttempts: 2,
|
|
87
|
-
retryBaseDelayMs: 1e3,
|
|
88
|
-
retryMaxTotalMs: 6e4,
|
|
89
|
-
retryableStatusCodes: [502, 503, 429],
|
|
90
|
-
defaultPageSize: 20,
|
|
91
|
-
defaultThrowOnError: false,
|
|
92
|
-
searchGetStrictShape: false
|
|
93
|
-
},
|
|
94
|
-
navigation: {
|
|
95
|
-
items: []
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
var fallbackConfig = DEFAULT_FRAMEWORK_CONFIG;
|
|
99
|
-
var COOKIE_PREFIX_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
|
|
100
|
-
var UNSAFE_MERGE_KEYS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
101
|
-
var MAX_REASONABLE_FILE_SIZE = 500 * 1024 * 1024;
|
|
102
|
-
function validateStringArrayField(value, fieldPath, errors) {
|
|
103
|
-
if (!Array.isArray(value)) {
|
|
104
|
-
errors.push(`${fieldPath}: must be an array of strings`);
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
108
|
-
const item = value[i];
|
|
109
|
-
if (typeof item !== "string" || item.trim().length === 0) {
|
|
110
|
-
errors.push(`${fieldPath}[${i}]: must be a non-empty string`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
function validateFrameworkConfig(cfg) {
|
|
115
|
-
const errors = [];
|
|
116
|
-
const warnings = [];
|
|
117
|
-
const { i18n, auth, limits, app, proxy, csp } = cfg;
|
|
118
|
-
if (typeof app !== "object" || app === null) {
|
|
119
|
-
errors.push("app: must be an object");
|
|
120
|
-
} else {
|
|
121
|
-
if (!app.name || typeof app.name !== "string" || app.name.trim().length === 0) {
|
|
122
|
-
errors.push("app.name: must be a non-empty string");
|
|
123
|
-
}
|
|
124
|
-
if (typeof app.defaultRoute !== "string") {
|
|
125
|
-
errors.push("app.defaultRoute: must be a string");
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
if (typeof auth !== "object" || auth === null) {
|
|
129
|
-
errors.push("auth: must be an object");
|
|
130
|
-
} else {
|
|
131
|
-
if (!COOKIE_PREFIX_PATTERN.test(auth.sessionCookiePrefix)) {
|
|
132
|
-
errors.push(
|
|
133
|
-
`auth.sessionCookiePrefix: "${auth.sessionCookiePrefix}" is invalid \u2014 expected pattern [a-zA-Z][a-zA-Z0-9_-]*`
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
if (!COOKIE_PREFIX_PATTERN.test(auth.loginFormFieldPrefix)) {
|
|
137
|
-
errors.push(
|
|
138
|
-
`auth.loginFormFieldPrefix: "${auth.loginFormFieldPrefix}" is invalid`
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
validateStringArrayField(auth.publicAuthPaths, "auth.publicAuthPaths", errors);
|
|
142
|
-
validateStringArrayField(auth.sessionExpiredCodes, "auth.sessionExpiredCodes", errors);
|
|
143
|
-
if (auth.allowInMemoryTokenStorage !== void 0 && typeof auth.allowInMemoryTokenStorage !== "boolean") {
|
|
144
|
-
errors.push("auth.allowInMemoryTokenStorage: must be a boolean");
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (typeof i18n !== "object" || i18n === null) {
|
|
148
|
-
errors.push("i18n: must be an object");
|
|
149
|
-
} else {
|
|
150
|
-
let hasLanguageEntryErrors = false;
|
|
151
|
-
if (!Array.isArray(i18n.languages)) {
|
|
152
|
-
errors.push("i18n.languages: must be an array");
|
|
153
|
-
} else {
|
|
154
|
-
if (i18n.languages.length === 0) {
|
|
155
|
-
warnings.push("i18n.languages: empty \u2014 framework requires at least one language");
|
|
156
|
-
}
|
|
157
|
-
for (let i = 0; i < i18n.languages.length; i += 1) {
|
|
158
|
-
const language = i18n.languages[i];
|
|
159
|
-
if (typeof language !== "object" || language === null) {
|
|
160
|
-
errors.push(`i18n.languages[${i}]: must be an object`);
|
|
161
|
-
hasLanguageEntryErrors = true;
|
|
162
|
-
continue;
|
|
163
|
-
}
|
|
164
|
-
const entry = language;
|
|
165
|
-
if (typeof entry.id_public !== "string" || entry.id_public.trim().length === 0) {
|
|
166
|
-
errors.push(`i18n.languages[${i}].id_public: must be a non-empty string`);
|
|
167
|
-
hasLanguageEntryErrors = true;
|
|
168
|
-
}
|
|
169
|
-
if (typeof entry.name !== "string" || entry.name.trim().length === 0) {
|
|
170
|
-
errors.push(`i18n.languages[${i}].name: must be a non-empty string`);
|
|
171
|
-
hasLanguageEntryErrors = true;
|
|
172
|
-
}
|
|
173
|
-
if (entry.code !== void 0) {
|
|
174
|
-
if (typeof entry.code !== "string" || entry.code.trim().length === 0) {
|
|
175
|
-
errors.push(`i18n.languages[${i}].code: must be a non-empty string when provided`);
|
|
176
|
-
hasLanguageEntryErrors = true;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
if (!hasLanguageEntryErrors && i18n.languages.length > 0 && !i18n.languages.some(
|
|
181
|
-
(l) => typeof l?.code === "string" && l.code === i18n.defaultLanguageCode
|
|
182
|
-
)) {
|
|
183
|
-
warnings.push(
|
|
184
|
-
`i18n.defaultLanguageCode: "${i18n.defaultLanguageCode}" not in languages list`
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
if (typeof i18n.dateFormats !== "object" || i18n.dateFormats === null || Array.isArray(i18n.dateFormats)) {
|
|
189
|
-
errors.push("i18n.dateFormats: must be an object with non-empty string values");
|
|
190
|
-
} else {
|
|
191
|
-
for (const [key, value] of Object.entries(i18n.dateFormats)) {
|
|
192
|
-
if (!value || typeof value !== "string" || value.trim().length === 0) {
|
|
193
|
-
errors.push(`i18n.dateFormats.${key}: must be a non-empty string`);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
if (typeof limits !== "object" || limits === null) {
|
|
199
|
-
errors.push("limits: must be an object");
|
|
200
|
-
} else {
|
|
201
|
-
if (typeof limits.maxFileSize !== "number" || limits.maxFileSize <= 0 || limits.maxFileSize > MAX_REASONABLE_FILE_SIZE) {
|
|
202
|
-
errors.push(`limits.maxFileSize: must be > 0 and <= 500MB, got ${limits.maxFileSize}`);
|
|
203
|
-
}
|
|
204
|
-
if (typeof limits.autocompleteDebounceMs !== "number" || limits.autocompleteDebounceMs < 0 || limits.autocompleteDebounceMs > 1e4) {
|
|
205
|
-
errors.push(`limits.autocompleteDebounceMs: must be 0\u201310000, got ${limits.autocompleteDebounceMs}`);
|
|
206
|
-
}
|
|
207
|
-
if (limits.maxOpenedTabs !== void 0 && (typeof limits.maxOpenedTabs !== "number" || !Number.isInteger(limits.maxOpenedTabs) || limits.maxOpenedTabs < 1 || limits.maxOpenedTabs > 200)) {
|
|
208
|
-
errors.push(`limits.maxOpenedTabs: must be an integer in range 1\u2013200, got ${limits.maxOpenedTabs}`);
|
|
209
|
-
}
|
|
210
|
-
if (typeof limits.signalrIdleTimeoutMs !== "number" || limits.signalrIdleTimeoutMs < 5e3) {
|
|
211
|
-
errors.push(`limits.signalrIdleTimeoutMs: must be >= 5000, got ${limits.signalrIdleTimeoutMs}`);
|
|
212
|
-
}
|
|
213
|
-
if (typeof limits.signalrServerTimeoutMs !== "number" || limits.signalrServerTimeoutMs < 1e3) {
|
|
214
|
-
errors.push(`limits.signalrServerTimeoutMs: must be >= 1000, got ${limits.signalrServerTimeoutMs}`);
|
|
215
|
-
}
|
|
216
|
-
if (typeof limits.signalrKeepAliveIntervalMs !== "number" || limits.signalrKeepAliveIntervalMs < 1e3) {
|
|
217
|
-
errors.push(`limits.signalrKeepAliveIntervalMs: must be >= 1000, got ${limits.signalrKeepAliveIntervalMs}`);
|
|
218
|
-
}
|
|
219
|
-
if (!Array.isArray(limits.signalrReconnectDelaysMs) || limits.signalrReconnectDelaysMs.length === 0) {
|
|
220
|
-
errors.push("limits.signalrReconnectDelaysMs: must be a non-empty array of numbers");
|
|
221
|
-
}
|
|
222
|
-
if (typeof limits.idleSessionTimeoutMs !== "number" || limits.idleSessionTimeoutMs < 6e4) {
|
|
223
|
-
errors.push(`limits.idleSessionTimeoutMs: must be >= 60000 (1 minute), got ${limits.idleSessionTimeoutMs}`);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
if (typeof proxy !== "object" || proxy === null) {
|
|
227
|
-
errors.push("proxy: must be an object");
|
|
228
|
-
} else {
|
|
229
|
-
if (typeof proxy.maxProxyPathLength !== "number" || proxy.maxProxyPathLength <= 0 || proxy.maxProxyPathLength > 65536) {
|
|
230
|
-
errors.push(`proxy.maxProxyPathLength: must be 1\u201365536, got ${proxy.maxProxyPathLength}`);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
if (typeof csp !== "object" || csp === null) {
|
|
234
|
-
errors.push("csp: must be an object");
|
|
235
|
-
} else {
|
|
236
|
-
for (const key of ["thirdPartyScriptSources", "thirdPartyConnectSources", "thirdPartyImageSources", "thirdPartyFrameSources"]) {
|
|
237
|
-
validateStringArrayField(csp[key], `csp.${key}`, errors);
|
|
238
|
-
if (Array.isArray(csp[key])) {
|
|
239
|
-
for (const src of csp[key]) {
|
|
240
|
-
if (typeof src === "string" && /[\s;,\r\n]/.test(src)) {
|
|
241
|
-
warnings.push(`csp.${key}: "${src}" contains CSP injection characters and will be ignored at runtime`);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
if (cfg.api) {
|
|
248
|
-
if (cfg.api.requestAdapter !== void 0 && typeof cfg.api.requestAdapter !== "function") {
|
|
249
|
-
errors.push("api.requestAdapter: must be a function");
|
|
250
|
-
}
|
|
251
|
-
if (cfg.api.defaultThrowOnError !== void 0 && typeof cfg.api.defaultThrowOnError !== "boolean") {
|
|
252
|
-
errors.push("api.defaultThrowOnError: must be a boolean");
|
|
253
|
-
}
|
|
254
|
-
if (cfg.api.searchGetStrictShape !== void 0 && typeof cfg.api.searchGetStrictShape !== "boolean") {
|
|
255
|
-
errors.push("api.searchGetStrictShape: must be a boolean");
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
return { valid: errors.length === 0, errors, warnings };
|
|
259
|
-
}
|
|
260
|
-
function deepMergePlain(target, source) {
|
|
261
|
-
const t = target;
|
|
262
|
-
const s = source;
|
|
263
|
-
const result = { ...t };
|
|
264
|
-
for (const key of Object.keys(s)) {
|
|
265
|
-
if (UNSAFE_MERGE_KEYS.has(key)) {
|
|
266
|
-
continue;
|
|
267
|
-
}
|
|
268
|
-
const sourceVal = s[key];
|
|
269
|
-
const targetVal = t[key];
|
|
270
|
-
if (sourceVal !== null && sourceVal !== void 0 && typeof sourceVal === "object" && !Array.isArray(sourceVal) && !(sourceVal instanceof RegExp) && typeof targetVal === "object" && targetVal !== null && !Array.isArray(targetVal) && !(targetVal instanceof RegExp)) {
|
|
271
|
-
result[key] = deepMergePlain(
|
|
272
|
-
targetVal,
|
|
273
|
-
sourceVal
|
|
274
|
-
);
|
|
275
|
-
} else if (sourceVal !== void 0) {
|
|
276
|
-
result[key] = sourceVal;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
return result;
|
|
280
|
-
}
|
|
281
|
-
function cloneFrameworkValue(value) {
|
|
282
|
-
if (Array.isArray(value)) {
|
|
283
|
-
return value.map((item) => cloneFrameworkValue(item));
|
|
284
|
-
}
|
|
285
|
-
if (value instanceof RegExp) {
|
|
286
|
-
return new RegExp(value.source, value.flags);
|
|
287
|
-
}
|
|
288
|
-
if (value !== null && typeof value === "object") {
|
|
289
|
-
const source = value;
|
|
290
|
-
const cloned = {};
|
|
291
|
-
for (const [k, v] of Object.entries(source)) {
|
|
292
|
-
cloned[k] = cloneFrameworkValue(v);
|
|
293
|
-
}
|
|
294
|
-
return cloned;
|
|
295
|
-
}
|
|
296
|
-
return value;
|
|
297
|
-
}
|
|
298
|
-
function cloneDefaultFrameworkConfig() {
|
|
299
|
-
return cloneFrameworkValue(DEFAULT_FRAMEWORK_CONFIG);
|
|
300
|
-
}
|
|
301
|
-
function createFrameworkConfig(overrides) {
|
|
302
|
-
const base = cloneDefaultFrameworkConfig();
|
|
303
|
-
if (!overrides) return deepFreeze(base);
|
|
304
|
-
const merged = deepMergePlain(base, overrides);
|
|
305
|
-
return deepFreeze(merged);
|
|
306
|
-
}
|
|
307
|
-
function configureFramework(overrides) {
|
|
308
|
-
const merged = createFrameworkConfig(overrides);
|
|
309
|
-
const result = validateFrameworkConfig(merged);
|
|
310
|
-
if (!result.valid) {
|
|
311
|
-
throw new SpringConfigError(
|
|
312
|
-
`Invalid configuration:
|
|
313
|
-
- ${result.errors.join("\n - ")}`
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
if (__DEV__ && result.warnings.length > 0) {
|
|
317
|
-
for (const w of result.warnings) {
|
|
318
|
-
console.warn("[FrameworkConfig] Warning:", w);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
const instance = tryGetSpringInstance();
|
|
322
|
-
if (instance) {
|
|
323
|
-
instance.core.config = merged;
|
|
324
|
-
} else {
|
|
325
|
-
fallbackConfig = merged;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
function getFrameworkConfig() {
|
|
329
|
-
const instance = tryGetSpringInstance();
|
|
330
|
-
return instance ? instance.core.config : fallbackConfig;
|
|
331
|
-
}
|
|
332
|
-
function clearFrameworkConfig() {
|
|
333
|
-
const instance = tryGetSpringInstance();
|
|
334
|
-
if (instance) {
|
|
335
|
-
instance.core.config = DEFAULT_FRAMEWORK_CONFIG;
|
|
336
|
-
}
|
|
337
|
-
fallbackConfig = DEFAULT_FRAMEWORK_CONFIG;
|
|
338
|
-
}
|
|
339
|
-
function getMaxFileSize() {
|
|
340
|
-
return getFrameworkConfig().limits.maxFileSize;
|
|
341
|
-
}
|
|
342
|
-
function getAutocompleteDebounceMs() {
|
|
343
|
-
return getFrameworkConfig().limits.autocompleteDebounceMs;
|
|
344
|
-
}
|
|
345
|
-
function getSignalrIdleTimeoutMs() {
|
|
346
|
-
return getFrameworkConfig().limits.signalrIdleTimeoutMs;
|
|
347
|
-
}
|
|
348
|
-
function getSignalrServerTimeoutMs() {
|
|
349
|
-
return getFrameworkConfig().limits.signalrServerTimeoutMs;
|
|
350
|
-
}
|
|
351
|
-
function getSignalrKeepAliveIntervalMs() {
|
|
352
|
-
return getFrameworkConfig().limits.signalrKeepAliveIntervalMs;
|
|
353
|
-
}
|
|
354
|
-
function getSignalrReconnectDelaysMs() {
|
|
355
|
-
return getFrameworkConfig().limits.signalrReconnectDelaysMs;
|
|
356
|
-
}
|
|
357
|
-
function getIdleSessionTimeoutMs() {
|
|
358
|
-
return getFrameworkConfig().limits.idleSessionTimeoutMs;
|
|
359
|
-
}
|
|
360
|
-
function getApiTimeoutMs() {
|
|
361
|
-
return getFrameworkConfig().api?.timeoutMs ?? 3e4;
|
|
362
|
-
}
|
|
363
|
-
function getApiDefaultPageSize() {
|
|
364
|
-
return getFrameworkConfig().api?.defaultPageSize ?? 20;
|
|
365
|
-
}
|
|
366
|
-
function getSessionCookieName(prefix) {
|
|
367
|
-
return `${prefix}_session`;
|
|
368
|
-
}
|
|
369
|
-
function getSecureSessionCookieName(prefix) {
|
|
370
|
-
return `__Host-${prefix}_session`;
|
|
371
|
-
}
|
|
372
|
-
function applyFallbackConfig(instance) {
|
|
373
|
-
if (fallbackConfig !== DEFAULT_FRAMEWORK_CONFIG) {
|
|
374
|
-
instance.core.config = fallbackConfig;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
registerFallbackMigration(applyFallbackConfig, 100);
|
|
378
|
-
|
|
379
|
-
export {
|
|
380
|
-
DEFAULT_FRAMEWORK_CONFIG,
|
|
381
|
-
validateFrameworkConfig,
|
|
382
|
-
createFrameworkConfig,
|
|
383
|
-
configureFramework,
|
|
384
|
-
getFrameworkConfig,
|
|
385
|
-
clearFrameworkConfig,
|
|
386
|
-
getMaxFileSize,
|
|
387
|
-
getAutocompleteDebounceMs,
|
|
388
|
-
getSignalrIdleTimeoutMs,
|
|
389
|
-
getSignalrServerTimeoutMs,
|
|
390
|
-
getSignalrKeepAliveIntervalMs,
|
|
391
|
-
getSignalrReconnectDelaysMs,
|
|
392
|
-
getIdleSessionTimeoutMs,
|
|
393
|
-
getApiTimeoutMs,
|
|
394
|
-
getApiDefaultPageSize,
|
|
395
|
-
getSessionCookieName,
|
|
396
|
-
getSecureSessionCookieName,
|
|
397
|
-
applyFallbackConfig
|
|
398
|
-
};
|
|
399
|
-
//# sourceMappingURL=chunk-F7WUQJH7.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/framework-config.ts"],"sourcesContent":["/**\n * Centralized framework configuration.\n * Each project sets its own values via configureFramework().\n * The framework reads from getFrameworkConfig().\n * @module framework-config\n */\n\nimport { SpringConfigError } from \"../errors/errors\";\nimport { tryGetSpringInstance } from \"../instance/current-instance\";\nimport { registerFallbackMigration } from \"../instance/fallback-bridge\";\nimport { __DEV__ } from \"../utils/dev-warnings\";\n// Re-export types from the standalone types file (no circular dependency risk)\nexport type { DateFormatConfig, FrameworkConfig, FrameworkConfigOverrides } from \"./framework-config-types\";\nimport type { FrameworkConfig, FrameworkConfigOverrides } from \"./framework-config-types\";\n\n/** Deep-freezes an object at runtime. Returns Readonly<T> (top-level); runtime freeze is deeper than the type reflects. */\nfunction deepFreeze<T extends object>(obj: T): Readonly<T> {\n Object.freeze(obj);\n for (const value of Object.values(obj)) {\n if (value !== null && typeof value === \"object\" && !Object.isFrozen(value)) {\n deepFreeze(value);\n }\n }\n return obj;\n}\n\n/**\n * Default framework configuration. Exported as the single source of truth\n * for both configureFramework() and createSpringInstance().\n * Deep-frozen to prevent accidental mutation of shared defaults.\n */\nexport const DEFAULT_FRAMEWORK_CONFIG: FrameworkConfig = deepFreeze({\n app: {\n name: \"App\",\n defaultRoute: \"/\",\n htmlLang: \"en\",\n skipLinkText: \"Skip to main content\",\n supportEmail: \"\",\n logo: { src: \"/images/logo.svg\", alt: \"Logo\" },\n },\n auth: {\n sessionCookiePrefix: \"app\",\n publicAuthPaths: [\"auth/login\", \"auth/forgot_password\", \"auth/change_password\"],\n sessionExpiredCodes: [\"session_expired\", \"token_expired\", \"invalid_token\"],\n loginFormFieldPrefix: \"app\",\n allowInMemoryTokenStorage: false,\n loginPath: \"auth/login\",\n logoutPath: \"auth/logout\",\n infoPath: \"auth/info\",\n tokenResponseFields: { accessToken: \"access_token\", refreshToken: \"refresh_token\" },\n loginUsernameField: \"username\",\n },\n proxy: {\n corsAllowedHeaders: \"Content-Type, Authorization, X-Requested-With, X-hash, Hash\",\n maxProxyPathLength: 2048,\n safeHashPattern: /^[A-Za-z0-9._~-]{1,256}$/,\n blockedPathPrefixesInProd: [],\n },\n csp: {\n thirdPartyScriptSources: [],\n thirdPartyConnectSources: [],\n thirdPartyImageSources: [],\n thirdPartyFrameSources: [],\n },\n i18n: {\n languages: [],\n defaultLanguageCode: \"en\",\n numberLocale: \"en-US\",\n dayjsLocale: \"en\",\n dateFormats: {\n date: \"YYYY-MM-DD\",\n dateTime: \"YYYY-MM-DD HH:mm\",\n dateTimeSeconds: \"YYYY-MM-DD HH:mm:ss\",\n time: \"HH:mm\",\n },\n },\n theme: {},\n darkTheme: {},\n componentTokens: {},\n limits: {\n maxFileSize: 10 * 1024 * 1024,\n autocompleteDebounceMs: 300,\n maxOpenedTabs: 10,\n signalrIdleTimeoutMs: 60_000,\n signalrServerTimeoutMs: 30_000,\n signalrKeepAliveIntervalMs: 10_000,\n signalrReconnectDelaysMs: [0, 1000, 2000, 5000, 10000, 15000],\n idleSessionTimeoutMs: 30 * 60 * 1000,\n },\n api: {\n listUrlPattern: \"${route}/list\",\n detailWithMetaPattern: \"${route}/${id}\",\n detailUrlPattern: \"${route}/${id}\",\n nullDateSentinel: \"0001-01-01T00:00:00\",\n timeoutMs: 30_000,\n retryMaxAttempts: 2,\n retryBaseDelayMs: 1_000,\n retryMaxTotalMs: 60_000,\n retryableStatusCodes: [502, 503, 429],\n defaultPageSize: 20,\n defaultThrowOnError: false,\n searchGetStrictShape: false,\n },\n navigation: {\n items: [],\n },\n});\n\n// Fallback for code that runs before SpringInstance is created\nlet fallbackConfig: FrameworkConfig = DEFAULT_FRAMEWORK_CONFIG;\n\nconst COOKIE_PREFIX_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;\nconst UNSAFE_MERGE_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\n\nconst MAX_REASONABLE_FILE_SIZE = 500 * 1024 * 1024; // 500 MB\n\nexport interface ConfigValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n}\n\nfunction validateStringArrayField(\n value: unknown,\n fieldPath: string,\n errors: string[],\n): void {\n if (!Array.isArray(value)) {\n errors.push(`${fieldPath}: must be an array of strings`);\n return;\n }\n\n for (let i = 0; i < value.length; i += 1) {\n const item = value[i];\n if (typeof item !== \"string\" || item.trim().length === 0) {\n errors.push(`${fieldPath}[${i}]: must be a non-empty string`);\n }\n }\n}\n\n/**\n * Validate a framework configuration and return structured results.\n * Also callable standalone for CI/testing: `validateFrameworkConfig(config)`.\n */\nexport function validateFrameworkConfig(cfg: FrameworkConfig): ConfigValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n const { i18n, auth, limits, app, proxy, csp } = cfg;\n\n // --- Type guard checks (schema-like validation) ---\n if (typeof app !== \"object\" || app === null) {\n errors.push(\"app: must be an object\");\n } else {\n if (!app.name || typeof app.name !== \"string\" || app.name.trim().length === 0) {\n errors.push(\"app.name: must be a non-empty string\");\n }\n if (typeof app.defaultRoute !== \"string\") {\n errors.push(\"app.defaultRoute: must be a string\");\n }\n }\n\n if (typeof auth !== \"object\" || auth === null) {\n errors.push(\"auth: must be an object\");\n } else {\n if (!COOKIE_PREFIX_PATTERN.test(auth.sessionCookiePrefix)) {\n errors.push(\n `auth.sessionCookiePrefix: \"${auth.sessionCookiePrefix}\" is invalid — expected pattern [a-zA-Z][a-zA-Z0-9_-]*`,\n );\n }\n if (!COOKIE_PREFIX_PATTERN.test(auth.loginFormFieldPrefix)) {\n errors.push(\n `auth.loginFormFieldPrefix: \"${auth.loginFormFieldPrefix}\" is invalid`,\n );\n }\n validateStringArrayField(auth.publicAuthPaths, \"auth.publicAuthPaths\", errors);\n validateStringArrayField(auth.sessionExpiredCodes, \"auth.sessionExpiredCodes\", errors);\n if (\n auth.allowInMemoryTokenStorage !== undefined &&\n typeof auth.allowInMemoryTokenStorage !== \"boolean\"\n ) {\n errors.push(\"auth.allowInMemoryTokenStorage: must be a boolean\");\n }\n }\n\n // --- i18n ---\n if (typeof i18n !== \"object\" || i18n === null) {\n errors.push(\"i18n: must be an object\");\n } else {\n let hasLanguageEntryErrors = false;\n if (!Array.isArray(i18n.languages)) {\n errors.push(\"i18n.languages: must be an array\");\n } else {\n if (i18n.languages.length === 0) {\n warnings.push(\"i18n.languages: empty — framework requires at least one language\");\n }\n for (let i = 0; i < i18n.languages.length; i += 1) {\n const language = i18n.languages[i];\n if (typeof language !== \"object\" || language === null) {\n errors.push(`i18n.languages[${i}]: must be an object`);\n hasLanguageEntryErrors = true;\n continue;\n }\n const entry = language as Record<string, unknown>;\n if (typeof entry.id_public !== \"string\" || entry.id_public.trim().length === 0) {\n errors.push(`i18n.languages[${i}].id_public: must be a non-empty string`);\n hasLanguageEntryErrors = true;\n }\n if (typeof entry.name !== \"string\" || entry.name.trim().length === 0) {\n errors.push(`i18n.languages[${i}].name: must be a non-empty string`);\n hasLanguageEntryErrors = true;\n }\n if (entry.code !== undefined) {\n if (typeof entry.code !== \"string\" || entry.code.trim().length === 0) {\n errors.push(`i18n.languages[${i}].code: must be a non-empty string when provided`);\n hasLanguageEntryErrors = true;\n }\n }\n }\n\n if (\n !hasLanguageEntryErrors &&\n i18n.languages.length > 0 &&\n !i18n.languages.some(\n (l) => typeof l?.code === \"string\" && l.code === i18n.defaultLanguageCode,\n )\n ) {\n warnings.push(\n `i18n.defaultLanguageCode: \"${i18n.defaultLanguageCode}\" not in languages list`,\n );\n }\n }\n if (\n typeof i18n.dateFormats !== \"object\" ||\n i18n.dateFormats === null ||\n Array.isArray(i18n.dateFormats)\n ) {\n errors.push(\"i18n.dateFormats: must be an object with non-empty string values\");\n } else {\n for (const [key, value] of Object.entries(i18n.dateFormats)) {\n if (!value || typeof value !== \"string\" || value.trim().length === 0) {\n errors.push(`i18n.dateFormats.${key}: must be a non-empty string`);\n }\n }\n }\n }\n\n // --- Limits ---\n if (typeof limits !== \"object\" || limits === null) {\n errors.push(\"limits: must be an object\");\n } else {\n if (typeof limits.maxFileSize !== \"number\" || limits.maxFileSize <= 0 || limits.maxFileSize > MAX_REASONABLE_FILE_SIZE) {\n errors.push(`limits.maxFileSize: must be > 0 and <= 500MB, got ${limits.maxFileSize}`);\n }\n if (typeof limits.autocompleteDebounceMs !== \"number\" || limits.autocompleteDebounceMs < 0 || limits.autocompleteDebounceMs > 10000) {\n errors.push(`limits.autocompleteDebounceMs: must be 0–10000, got ${limits.autocompleteDebounceMs}`);\n }\n if (\n limits.maxOpenedTabs !== undefined &&\n (typeof limits.maxOpenedTabs !== \"number\" ||\n !Number.isInteger(limits.maxOpenedTabs) ||\n limits.maxOpenedTabs < 1 ||\n limits.maxOpenedTabs > 200)\n ) {\n errors.push(`limits.maxOpenedTabs: must be an integer in range 1–200, got ${limits.maxOpenedTabs}`);\n }\n if (typeof limits.signalrIdleTimeoutMs !== \"number\" || limits.signalrIdleTimeoutMs < 5000) {\n errors.push(`limits.signalrIdleTimeoutMs: must be >= 5000, got ${limits.signalrIdleTimeoutMs}`);\n }\n if (typeof limits.signalrServerTimeoutMs !== \"number\" || limits.signalrServerTimeoutMs < 1000) {\n errors.push(`limits.signalrServerTimeoutMs: must be >= 1000, got ${limits.signalrServerTimeoutMs}`);\n }\n if (typeof limits.signalrKeepAliveIntervalMs !== \"number\" || limits.signalrKeepAliveIntervalMs < 1000) {\n errors.push(`limits.signalrKeepAliveIntervalMs: must be >= 1000, got ${limits.signalrKeepAliveIntervalMs}`);\n }\n if (!Array.isArray(limits.signalrReconnectDelaysMs) || limits.signalrReconnectDelaysMs.length === 0) {\n errors.push(\"limits.signalrReconnectDelaysMs: must be a non-empty array of numbers\");\n }\n if (typeof limits.idleSessionTimeoutMs !== \"number\" || limits.idleSessionTimeoutMs < 60_000) {\n errors.push(`limits.idleSessionTimeoutMs: must be >= 60000 (1 minute), got ${limits.idleSessionTimeoutMs}`);\n }\n }\n\n // --- Proxy ---\n if (typeof proxy !== \"object\" || proxy === null) {\n errors.push(\"proxy: must be an object\");\n } else {\n if (typeof proxy.maxProxyPathLength !== \"number\" || proxy.maxProxyPathLength <= 0 || proxy.maxProxyPathLength > 65536) {\n errors.push(`proxy.maxProxyPathLength: must be 1–65536, got ${proxy.maxProxyPathLength}`);\n }\n }\n\n // --- CSP ---\n if (typeof csp !== \"object\" || csp === null) {\n errors.push(\"csp: must be an object\");\n } else {\n for (const key of [\"thirdPartyScriptSources\", \"thirdPartyConnectSources\", \"thirdPartyImageSources\", \"thirdPartyFrameSources\"] as const) {\n validateStringArrayField(csp[key], `csp.${key}`, errors);\n if (Array.isArray(csp[key])) {\n for (const src of csp[key]) {\n if (typeof src === \"string\" && /[\\s;,\\r\\n]/.test(src)) {\n warnings.push(`csp.${key}: \"${src}\" contains CSP injection characters and will be ignored at runtime`);\n }\n }\n }\n }\n }\n\n // --- API ---\n if (cfg.api) {\n if (cfg.api.requestAdapter !== undefined && typeof cfg.api.requestAdapter !== \"function\") {\n errors.push(\"api.requestAdapter: must be a function\");\n }\n if (\n cfg.api.defaultThrowOnError !== undefined &&\n typeof cfg.api.defaultThrowOnError !== \"boolean\"\n ) {\n errors.push(\"api.defaultThrowOnError: must be a boolean\");\n }\n if (\n cfg.api.searchGetStrictShape !== undefined &&\n typeof cfg.api.searchGetStrictShape !== \"boolean\"\n ) {\n errors.push(\"api.searchGetStrictShape: must be a boolean\");\n }\n }\n\n return { valid: errors.length === 0, errors, warnings };\n}\n\n/**\n * Deep merge two plain objects. Arrays and RegExp are replaced, not concatenated.\n * Only merges own enumerable properties. Handles nested objects recursively.\n */\nfunction deepMergePlain(target: object, source: object): object {\n const t = target as Record<string, unknown>;\n const s = source as Record<string, unknown>;\n const result: Record<string, unknown> = { ...t };\n for (const key of Object.keys(s)) {\n if (UNSAFE_MERGE_KEYS.has(key)) {\n continue;\n }\n const sourceVal = s[key];\n const targetVal = t[key];\n if (\n sourceVal !== null &&\n sourceVal !== undefined &&\n typeof sourceVal === \"object\" &&\n !Array.isArray(sourceVal) &&\n !(sourceVal instanceof RegExp) &&\n typeof targetVal === \"object\" &&\n targetVal !== null &&\n !Array.isArray(targetVal) &&\n !(targetVal instanceof RegExp)\n ) {\n result[key] = deepMergePlain(\n targetVal as object,\n sourceVal as object,\n );\n } else if (sourceVal !== undefined) {\n result[key] = sourceVal;\n }\n }\n return result;\n}\n\nfunction cloneFrameworkValue<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map((item) => cloneFrameworkValue(item)) as T;\n }\n if (value instanceof RegExp) {\n return new RegExp(value.source, value.flags) as T;\n }\n if (value !== null && typeof value === \"object\") {\n const source = value as Record<string, unknown>;\n const cloned: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(source)) {\n cloned[k] = cloneFrameworkValue(v);\n }\n return cloned as T;\n }\n return value;\n}\n\nfunction cloneDefaultFrameworkConfig(): FrameworkConfig {\n return cloneFrameworkValue(DEFAULT_FRAMEWORK_CONFIG);\n}\n\nexport function createFrameworkConfig(overrides?: FrameworkConfigOverrides): FrameworkConfig {\n const base = cloneDefaultFrameworkConfig();\n if (!overrides) return deepFreeze(base) as FrameworkConfig;\n const merged = deepMergePlain(base, overrides) as FrameworkConfig;\n return deepFreeze(merged) as FrameworkConfig;\n}\n\nexport function configureFramework(overrides: FrameworkConfigOverrides): void {\n const merged = createFrameworkConfig(overrides);\n const result = validateFrameworkConfig(merged);\n\n // Critical validation errors always throw — both dev and production.\n // A misconfigured framework is not safe to run (bad cookie prefixes,\n // missing auth paths, etc.). Only warnings are dev-only.\n if (!result.valid) {\n throw new SpringConfigError(\n `Invalid configuration:\\n - ${result.errors.join(\"\\n - \")}`,\n );\n }\n\n // Warnings are surfaced only in dev mode (non-blocking issues)\n if (__DEV__ && result.warnings.length > 0) {\n for (const w of result.warnings) {\n // Using console.warn intentionally — logWarn depends on config, so importing it here would create a circular dependency\n console.warn(\"[FrameworkConfig] Warning:\", w);\n }\n }\n\n // Write to SpringInstance if available, otherwise to fallback\n const instance = tryGetSpringInstance();\n if (instance) {\n instance.core.config = merged;\n } else {\n fallbackConfig = merged;\n }\n}\n\nexport function getFrameworkConfig(): FrameworkConfig {\n const instance = tryGetSpringInstance();\n return instance ? instance.core.config : fallbackConfig;\n}\n\n/**\n * Reset framework config to immutable defaults.\n * Intended for test/integration teardown.\n */\nexport function clearFrameworkConfig(): void {\n const instance = tryGetSpringInstance();\n if (instance) {\n instance.core.config = DEFAULT_FRAMEWORK_CONFIG;\n }\n fallbackConfig = DEFAULT_FRAMEWORK_CONFIG;\n}\n\n/** Max file size for upload — reads from framework config limits.maxFileSize */\nexport function getMaxFileSize(): number {\n return getFrameworkConfig().limits.maxFileSize;\n}\n\n/** Debounce delay for autocomplete search — reads from framework config limits.autocompleteDebounceMs */\nexport function getAutocompleteDebounceMs(): number {\n return getFrameworkConfig().limits.autocompleteDebounceMs;\n}\n\n/** Idle timeout for SignalR hub disconnect — reads from framework config limits.signalrIdleTimeoutMs */\nexport function getSignalrIdleTimeoutMs(): number {\n return getFrameworkConfig().limits.signalrIdleTimeoutMs;\n}\n\n/** SignalR server timeout — reads from framework config limits.signalrServerTimeoutMs */\nexport function getSignalrServerTimeoutMs(): number {\n return getFrameworkConfig().limits.signalrServerTimeoutMs;\n}\n\n/** SignalR keep-alive interval — reads from framework config limits.signalrKeepAliveIntervalMs */\nexport function getSignalrKeepAliveIntervalMs(): number {\n return getFrameworkConfig().limits.signalrKeepAliveIntervalMs;\n}\n\n/** SignalR reconnect delay sequence — reads from framework config limits.signalrReconnectDelaysMs */\nexport function getSignalrReconnectDelaysMs(): readonly number[] {\n return getFrameworkConfig().limits.signalrReconnectDelaysMs;\n}\n\n/** Idle session timeout — reads from framework config limits.idleSessionTimeoutMs */\nexport function getIdleSessionTimeoutMs(): number {\n return getFrameworkConfig().limits.idleSessionTimeoutMs;\n}\n\n/** API request timeout — reads from framework config api.timeoutMs */\nexport function getApiTimeoutMs(): number {\n return getFrameworkConfig().api?.timeoutMs ?? 30_000;\n}\n\n/** Default list page size — reads from framework config api.defaultPageSize */\nexport function getApiDefaultPageSize(): number {\n return getFrameworkConfig().api?.defaultPageSize ?? 20;\n}\n\nexport function getSessionCookieName(prefix: string): string {\n return `${prefix}_session`;\n}\n\nexport function getSecureSessionCookieName(prefix: string): string {\n return `__Host-${prefix}_session`;\n}\n\n/**\n * Apply the fallback config to a SpringInstance.\n * Called by SpringProvider after instance creation to pick up early configureFramework() calls.\n */\nexport function applyFallbackConfig(instance: { core: { config: FrameworkConfig } }): void {\n if (fallbackConfig !== DEFAULT_FRAMEWORK_CONFIG) {\n instance.core.config = fallbackConfig;\n }\n}\n\n// Register config migration with high priority so config lands before other migrations.\nregisterFallbackMigration(applyFallbackConfig, 100);\n"],"mappings":";;;;;;;;;;;;AAgBA,SAAS,WAA6B,KAAqB;AACvD,SAAO,OAAO,GAAG;AACjB,aAAW,SAAS,OAAO,OAAO,GAAG,GAAG;AACpC,QAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxE,iBAAW,KAAK;AAAA,IACpB;AAAA,EACJ;AACA,SAAO;AACX;AAOO,IAAM,2BAA4C,WAAW;AAAA,EAChE,KAAK;AAAA,IACD,MAAM;AAAA,IACN,cAAc;AAAA,IACd,UAAU;AAAA,IACV,cAAc;AAAA,IACd,cAAc;AAAA,IACd,MAAM,EAAE,KAAK,oBAAoB,KAAK,OAAO;AAAA,EACjD;AAAA,EACA,MAAM;AAAA,IACF,qBAAqB;AAAA,IACrB,iBAAiB,CAAC,cAAc,wBAAwB,sBAAsB;AAAA,IAC9E,qBAAqB,CAAC,mBAAmB,iBAAiB,eAAe;AAAA,IACzE,sBAAsB;AAAA,IACtB,2BAA2B;AAAA,IAC3B,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,qBAAqB,EAAE,aAAa,gBAAgB,cAAc,gBAAgB;AAAA,IAClF,oBAAoB;AAAA,EACxB;AAAA,EACA,OAAO;AAAA,IACH,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,2BAA2B,CAAC;AAAA,EAChC;AAAA,EACA,KAAK;AAAA,IACD,yBAAyB,CAAC;AAAA,IAC1B,0BAA0B,CAAC;AAAA,IAC3B,wBAAwB,CAAC;AAAA,IACzB,wBAAwB,CAAC;AAAA,EAC7B;AAAA,EACA,MAAM;AAAA,IACF,WAAW,CAAC;AAAA,IACZ,qBAAqB;AAAA,IACrB,cAAc;AAAA,IACd,aAAa;AAAA,IACb,aAAa;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,MACV,iBAAiB;AAAA,MACjB,MAAM;AAAA,IACV;AAAA,EACJ;AAAA,EACA,OAAO,CAAC;AAAA,EACR,WAAW,CAAC;AAAA,EACZ,iBAAiB,CAAC;AAAA,EAClB,QAAQ;AAAA,IACJ,aAAa,KAAK,OAAO;AAAA,IACzB,wBAAwB;AAAA,IACxB,eAAe;AAAA,IACf,sBAAsB;AAAA,IACtB,wBAAwB;AAAA,IACxB,4BAA4B;AAAA,IAC5B,0BAA0B,CAAC,GAAG,KAAM,KAAM,KAAM,KAAO,IAAK;AAAA,IAC5D,sBAAsB,KAAK,KAAK;AAAA,EACpC;AAAA,EACA,KAAK;AAAA,IACD,gBAAgB;AAAA,IAChB,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,IACjB,sBAAsB,CAAC,KAAK,KAAK,GAAG;AAAA,IACpC,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,sBAAsB;AAAA,EAC1B;AAAA,EACA,YAAY;AAAA,IACR,OAAO,CAAC;AAAA,EACZ;AACJ,CAAC;AAGD,IAAI,iBAAkC;AAEtC,IAAM,wBAAwB;AAC9B,IAAM,oBAAoB,oBAAI,IAAI,CAAC,aAAa,aAAa,aAAa,CAAC;AAE3E,IAAM,2BAA2B,MAAM,OAAO;AAQ9C,SAAS,yBACL,OACA,WACA,QACI;AACJ,MAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACvB,WAAO,KAAK,GAAG,SAAS,+BAA+B;AACvD;AAAA,EACJ;AAEA,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AACtC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,OAAO,SAAS,YAAY,KAAK,KAAK,EAAE,WAAW,GAAG;AACtD,aAAO,KAAK,GAAG,SAAS,IAAI,CAAC,+BAA+B;AAAA,IAChE;AAAA,EACJ;AACJ;AAMO,SAAS,wBAAwB,KAA8C;AAClF,QAAM,SAAmB,CAAC;AAC1B,QAAM,WAAqB,CAAC;AAE5B,QAAM,EAAE,MAAM,MAAM,QAAQ,KAAK,OAAO,IAAI,IAAI;AAGhD,MAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AACzC,WAAO,KAAK,wBAAwB;AAAA,EACxC,OAAO;AACH,QAAI,CAAC,IAAI,QAAQ,OAAO,IAAI,SAAS,YAAY,IAAI,KAAK,KAAK,EAAE,WAAW,GAAG;AAC3E,aAAO,KAAK,sCAAsC;AAAA,IACtD;AACA,QAAI,OAAO,IAAI,iBAAiB,UAAU;AACtC,aAAO,KAAK,oCAAoC;AAAA,IACpD;AAAA,EACJ;AAEA,MAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC3C,WAAO,KAAK,yBAAyB;AAAA,EACzC,OAAO;AACH,QAAI,CAAC,sBAAsB,KAAK,KAAK,mBAAmB,GAAG;AACvD,aAAO;AAAA,QACH,8BAA8B,KAAK,mBAAmB;AAAA,MAC1D;AAAA,IACJ;AACA,QAAI,CAAC,sBAAsB,KAAK,KAAK,oBAAoB,GAAG;AACxD,aAAO;AAAA,QACH,+BAA+B,KAAK,oBAAoB;AAAA,MAC5D;AAAA,IACJ;AACA,6BAAyB,KAAK,iBAAiB,wBAAwB,MAAM;AAC7E,6BAAyB,KAAK,qBAAqB,4BAA4B,MAAM;AACrF,QACI,KAAK,8BAA8B,UACnC,OAAO,KAAK,8BAA8B,WAC5C;AACE,aAAO,KAAK,mDAAmD;AAAA,IACnE;AAAA,EACJ;AAGA,MAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC3C,WAAO,KAAK,yBAAyB;AAAA,EACzC,OAAO;AACH,QAAI,yBAAyB;AAC7B,QAAI,CAAC,MAAM,QAAQ,KAAK,SAAS,GAAG;AAChC,aAAO,KAAK,kCAAkC;AAAA,IAClD,OAAO;AACH,UAAI,KAAK,UAAU,WAAW,GAAG;AAC7B,iBAAS,KAAK,uEAAkE;AAAA,MACpF;AACA,eAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK,GAAG;AAC/C,cAAM,WAAW,KAAK,UAAU,CAAC;AACjC,YAAI,OAAO,aAAa,YAAY,aAAa,MAAM;AACnD,iBAAO,KAAK,kBAAkB,CAAC,sBAAsB;AACrD,mCAAyB;AACzB;AAAA,QACJ;AACA,cAAM,QAAQ;AACd,YAAI,OAAO,MAAM,cAAc,YAAY,MAAM,UAAU,KAAK,EAAE,WAAW,GAAG;AAC5E,iBAAO,KAAK,kBAAkB,CAAC,yCAAyC;AACxE,mCAAyB;AAAA,QAC7B;AACA,YAAI,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,EAAE,WAAW,GAAG;AAClE,iBAAO,KAAK,kBAAkB,CAAC,oCAAoC;AACnE,mCAAyB;AAAA,QAC7B;AACA,YAAI,MAAM,SAAS,QAAW;AAC1B,cAAI,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,EAAE,WAAW,GAAG;AAClE,mBAAO,KAAK,kBAAkB,CAAC,kDAAkD;AACjF,qCAAyB;AAAA,UAC7B;AAAA,QACJ;AAAA,MACJ;AAEA,UACI,CAAC,0BACD,KAAK,UAAU,SAAS,KACxB,CAAC,KAAK,UAAU;AAAA,QACZ,CAAC,MAAM,OAAO,GAAG,SAAS,YAAY,EAAE,SAAS,KAAK;AAAA,MAC1D,GACF;AACE,iBAAS;AAAA,UACL,8BAA8B,KAAK,mBAAmB;AAAA,QAC1D;AAAA,MACJ;AAAA,IACJ;AACA,QACI,OAAO,KAAK,gBAAgB,YAC5B,KAAK,gBAAgB,QACrB,MAAM,QAAQ,KAAK,WAAW,GAChC;AACE,aAAO,KAAK,kEAAkE;AAAA,IAClF,OAAO;AACH,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,WAAW,GAAG;AACzD,YAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,WAAW,GAAG;AAClE,iBAAO,KAAK,oBAAoB,GAAG,8BAA8B;AAAA,QACrE;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAGA,MAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AAC/C,WAAO,KAAK,2BAA2B;AAAA,EAC3C,OAAO;AACH,QAAI,OAAO,OAAO,gBAAgB,YAAY,OAAO,eAAe,KAAK,OAAO,cAAc,0BAA0B;AACpH,aAAO,KAAK,qDAAqD,OAAO,WAAW,EAAE;AAAA,IACzF;AACA,QAAI,OAAO,OAAO,2BAA2B,YAAY,OAAO,yBAAyB,KAAK,OAAO,yBAAyB,KAAO;AACjI,aAAO,KAAK,4DAAuD,OAAO,sBAAsB,EAAE;AAAA,IACtG;AACA,QACI,OAAO,kBAAkB,WACxB,OAAO,OAAO,kBAAkB,YAC7B,CAAC,OAAO,UAAU,OAAO,aAAa,KACtC,OAAO,gBAAgB,KACvB,OAAO,gBAAgB,MAC7B;AACE,aAAO,KAAK,qEAAgE,OAAO,aAAa,EAAE;AAAA,IACtG;AACA,QAAI,OAAO,OAAO,yBAAyB,YAAY,OAAO,uBAAuB,KAAM;AACvF,aAAO,KAAK,qDAAqD,OAAO,oBAAoB,EAAE;AAAA,IAClG;AACA,QAAI,OAAO,OAAO,2BAA2B,YAAY,OAAO,yBAAyB,KAAM;AAC3F,aAAO,KAAK,uDAAuD,OAAO,sBAAsB,EAAE;AAAA,IACtG;AACA,QAAI,OAAO,OAAO,+BAA+B,YAAY,OAAO,6BAA6B,KAAM;AACnG,aAAO,KAAK,2DAA2D,OAAO,0BAA0B,EAAE;AAAA,IAC9G;AACA,QAAI,CAAC,MAAM,QAAQ,OAAO,wBAAwB,KAAK,OAAO,yBAAyB,WAAW,GAAG;AACjG,aAAO,KAAK,uEAAuE;AAAA,IACvF;AACA,QAAI,OAAO,OAAO,yBAAyB,YAAY,OAAO,uBAAuB,KAAQ;AACzF,aAAO,KAAK,iEAAiE,OAAO,oBAAoB,EAAE;AAAA,IAC9G;AAAA,EACJ;AAGA,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC7C,WAAO,KAAK,0BAA0B;AAAA,EAC1C,OAAO;AACH,QAAI,OAAO,MAAM,uBAAuB,YAAY,MAAM,sBAAsB,KAAK,MAAM,qBAAqB,OAAO;AACnH,aAAO,KAAK,uDAAkD,MAAM,kBAAkB,EAAE;AAAA,IAC5F;AAAA,EACJ;AAGA,MAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AACzC,WAAO,KAAK,wBAAwB;AAAA,EACxC,OAAO;AACH,eAAW,OAAO,CAAC,2BAA2B,4BAA4B,0BAA0B,wBAAwB,GAAY;AACpI,+BAAyB,IAAI,GAAG,GAAG,OAAO,GAAG,IAAI,MAAM;AACvD,UAAI,MAAM,QAAQ,IAAI,GAAG,CAAC,GAAG;AACzB,mBAAW,OAAO,IAAI,GAAG,GAAG;AACxB,cAAI,OAAO,QAAQ,YAAY,aAAa,KAAK,GAAG,GAAG;AACnD,qBAAS,KAAK,OAAO,GAAG,MAAM,GAAG,oEAAoE;AAAA,UACzG;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAGA,MAAI,IAAI,KAAK;AACT,QAAI,IAAI,IAAI,mBAAmB,UAAa,OAAO,IAAI,IAAI,mBAAmB,YAAY;AACtF,aAAO,KAAK,wCAAwC;AAAA,IACxD;AACA,QACI,IAAI,IAAI,wBAAwB,UAChC,OAAO,IAAI,IAAI,wBAAwB,WACzC;AACE,aAAO,KAAK,4CAA4C;AAAA,IAC5D;AACA,QACI,IAAI,IAAI,yBAAyB,UACjC,OAAO,IAAI,IAAI,yBAAyB,WAC1C;AACE,aAAO,KAAK,6CAA6C;AAAA,IAC7D;AAAA,EACJ;AAEA,SAAO,EAAE,OAAO,OAAO,WAAW,GAAG,QAAQ,SAAS;AAC1D;AAMA,SAAS,eAAe,QAAgB,QAAwB;AAC5D,QAAM,IAAI;AACV,QAAM,IAAI;AACV,QAAM,SAAkC,EAAE,GAAG,EAAE;AAC/C,aAAW,OAAO,OAAO,KAAK,CAAC,GAAG;AAC9B,QAAI,kBAAkB,IAAI,GAAG,GAAG;AAC5B;AAAA,IACJ;AACA,UAAM,YAAY,EAAE,GAAG;AACvB,UAAM,YAAY,EAAE,GAAG;AACvB,QACI,cAAc,QACd,cAAc,UACd,OAAO,cAAc,YACrB,CAAC,MAAM,QAAQ,SAAS,KACxB,EAAE,qBAAqB,WACvB,OAAO,cAAc,YACrB,cAAc,QACd,CAAC,MAAM,QAAQ,SAAS,KACxB,EAAE,qBAAqB,SACzB;AACE,aAAO,GAAG,IAAI;AAAA,QACV;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,WAAW,cAAc,QAAW;AAChC,aAAO,GAAG,IAAI;AAAA,IAClB;AAAA,EACJ;AACA,SAAO;AACX;AAEA,SAAS,oBAAuB,OAAa;AACzC,MAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,WAAO,MAAM,IAAI,CAAC,SAAS,oBAAoB,IAAI,CAAC;AAAA,EACxD;AACA,MAAI,iBAAiB,QAAQ;AACzB,WAAO,IAAI,OAAO,MAAM,QAAQ,MAAM,KAAK;AAAA,EAC/C;AACA,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC7C,UAAM,SAAS;AACf,UAAM,SAAkC,CAAC;AACzC,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AACzC,aAAO,CAAC,IAAI,oBAAoB,CAAC;AAAA,IACrC;AACA,WAAO;AAAA,EACX;AACA,SAAO;AACX;AAEA,SAAS,8BAA+C;AACpD,SAAO,oBAAoB,wBAAwB;AACvD;AAEO,SAAS,sBAAsB,WAAuD;AACzF,QAAM,OAAO,4BAA4B;AACzC,MAAI,CAAC,UAAW,QAAO,WAAW,IAAI;AACtC,QAAM,SAAS,eAAe,MAAM,SAAS;AAC7C,SAAO,WAAW,MAAM;AAC5B;AAEO,SAAS,mBAAmB,WAA2C;AAC1E,QAAM,SAAS,sBAAsB,SAAS;AAC9C,QAAM,SAAS,wBAAwB,MAAM;AAK7C,MAAI,CAAC,OAAO,OAAO;AACf,UAAM,IAAI;AAAA,MACN;AAAA,MAA+B,OAAO,OAAO,KAAK,QAAQ,CAAC;AAAA,IAC/D;AAAA,EACJ;AAGA,MAAI,WAAW,OAAO,SAAS,SAAS,GAAG;AACvC,eAAW,KAAK,OAAO,UAAU;AAE7B,cAAQ,KAAK,8BAA8B,CAAC;AAAA,IAChD;AAAA,EACJ;AAGA,QAAM,WAAW,qBAAqB;AACtC,MAAI,UAAU;AACV,aAAS,KAAK,SAAS;AAAA,EAC3B,OAAO;AACH,qBAAiB;AAAA,EACrB;AACJ;AAEO,SAAS,qBAAsC;AAClD,QAAM,WAAW,qBAAqB;AACtC,SAAO,WAAW,SAAS,KAAK,SAAS;AAC7C;AAMO,SAAS,uBAA6B;AACzC,QAAM,WAAW,qBAAqB;AACtC,MAAI,UAAU;AACV,aAAS,KAAK,SAAS;AAAA,EAC3B;AACA,mBAAiB;AACrB;AAGO,SAAS,iBAAyB;AACrC,SAAO,mBAAmB,EAAE,OAAO;AACvC;AAGO,SAAS,4BAAoC;AAChD,SAAO,mBAAmB,EAAE,OAAO;AACvC;AAGO,SAAS,0BAAkC;AAC9C,SAAO,mBAAmB,EAAE,OAAO;AACvC;AAGO,SAAS,4BAAoC;AAChD,SAAO,mBAAmB,EAAE,OAAO;AACvC;AAGO,SAAS,gCAAwC;AACpD,SAAO,mBAAmB,EAAE,OAAO;AACvC;AAGO,SAAS,8BAAiD;AAC7D,SAAO,mBAAmB,EAAE,OAAO;AACvC;AAGO,SAAS,0BAAkC;AAC9C,SAAO,mBAAmB,EAAE,OAAO;AACvC;AAGO,SAAS,kBAA0B;AACtC,SAAO,mBAAmB,EAAE,KAAK,aAAa;AAClD;AAGO,SAAS,wBAAgC;AAC5C,SAAO,mBAAmB,EAAE,KAAK,mBAAmB;AACxD;AAEO,SAAS,qBAAqB,QAAwB;AACzD,SAAO,GAAG,MAAM;AACpB;AAEO,SAAS,2BAA2B,QAAwB;AAC/D,SAAO,UAAU,MAAM;AAC3B;AAMO,SAAS,oBAAoB,UAAuD;AACvF,MAAI,mBAAmB,0BAA0B;AAC7C,aAAS,KAAK,SAAS;AAAA,EAC3B;AACJ;AAGA,0BAA0B,qBAAqB,GAAG;","names":[]}
|