@admin-layout/client 12.0.16-alpha.7 → 12.0.16-alpha.70
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/lib/__tests__/ApplicationErrorHandlerCommon.test.d.ts.map +1 -0
- package/lib/__tests__/ConfigurationModelWrapper.test.d.ts +2 -0
- package/lib/__tests__/ConfigurationModelWrapper.test.d.ts.map +1 -0
- package/lib/__tests__/SettingsConfigurationModel.test.d.ts.map +1 -0
- package/lib/__tests__/__fixtures__/defaultSettingsExample.d.ts +3 -0
- package/lib/__tests__/__fixtures__/defaultSettingsExample.d.ts.map +1 -0
- package/lib/colors/colorsList.js.map +1 -1
- package/lib/colors/presets/black.js.map +1 -1
- package/lib/colors/presets/white.js.map +1 -1
- package/lib/components/ApplicationErrorHandlerCommon.js.map +1 -1
- package/lib/components/ErrorBoundaryCommon.js.map +1 -1
- package/lib/components/UpdateSettings/UpdateSettings.server.d.ts +65 -20
- package/lib/components/UpdateSettings/UpdateSettings.server.d.ts.map +1 -1
- package/lib/components/UpdateSettings/UpdateSettings.server.js +198 -103
- package/lib/components/UpdateSettings/UpdateSettings.server.js.map +1 -1
- package/lib/components/UpdateSettings/UpdateSettings.server.test.d.ts +2 -0
- package/lib/components/UpdateSettings/UpdateSettings.server.test.d.ts.map +1 -0
- package/lib/config/defaultSettings.d.ts +76 -1
- package/lib/config/defaultSettings.d.ts.map +1 -1
- package/lib/config/defaultSettings.js +2 -112
- package/lib/config/defaultSettings.js.map +1 -1
- package/lib/config/env-config.d.ts +3 -5
- package/lib/config/env-config.d.ts.map +1 -1
- package/lib/config/env-config.js +13 -20
- package/lib/config/env-config.js.map +1 -1
- package/lib/constants/constants.js.map +1 -1
- package/lib/constants/error.js.map +1 -1
- package/lib/constants/languages.js.map +1 -1
- package/lib/constants/layout.js.map +1 -1
- package/lib/graphql/link/error-link.js.map +1 -1
- package/lib/hooks/useLayoutSettings.d.ts +1 -0
- package/lib/hooks/useLayoutSettings.d.ts.map +1 -1
- package/lib/hooks/useLayoutSettings.js +50 -9
- package/lib/hooks/useLayoutSettings.js.map +1 -1
- package/lib/hooks/useLayoutSettings.test.d.ts +2 -0
- package/lib/hooks/useLayoutSettings.test.d.ts.map +1 -0
- package/lib/index.js +1 -1
- package/lib/index.native.js +1 -1
- package/lib/interfaces/pure-settings.d.ts +8 -0
- package/lib/interfaces/pure-settings.d.ts.map +1 -1
- package/lib/interfaces/settings.d.ts +7 -6
- package/lib/interfaces/settings.d.ts.map +1 -1
- package/lib/interfaces/settings.js.map +1 -1
- package/lib/interfaces/typings.d.ts +1 -1
- package/lib/interfaces/typings.d.ts.map +1 -1
- package/lib/redux/actions/error-actions.js.map +1 -1
- package/lib/redux/reducers/error.js.map +1 -1
- package/lib/redux/reducers/settings.d.ts.map +1 -1
- package/lib/redux/reducers/settings.js +2 -2
- package/lib/redux/reducers/settings.js.map +1 -1
- package/lib/redux/selectors/index.js.map +1 -1
- package/lib/redux/store.js +1 -1
- package/lib/redux/store.js.map +1 -1
- package/lib/themes/systemFont/index.js.map +1 -1
- package/lib/themes/templates/createLayoutTheme.js.map +1 -1
- package/lib/themes/templates/darkLayoutTheme.js.map +1 -1
- package/lib/themes/templates/lightLayoutTheme.js.map +1 -1
- package/lib/utils/assignDefaults.d.ts +0 -1
- package/lib/utils/assignDefaults.d.ts.map +1 -1
- package/lib/utils/assignDefaults.test.d.ts +0 -1
- package/lib/utils/generateMenuLink.js.map +1 -1
- package/lib/utils/matchMenuKeys.js.map +1 -1
- package/lib/utils/menuUtils.js.map +1 -1
- package/lib/utils/parseEnvUiLayoutSettings.d.ts +6 -0
- package/lib/utils/parseEnvUiLayoutSettings.d.ts.map +1 -0
- package/lib/utils/parseEnvUiLayoutSettings.js +27 -0
- package/lib/utils/parseEnvUiLayoutSettings.js.map +1 -0
- package/lib/utils/parseEnvUiLayoutSettings.test.d.ts +2 -0
- package/lib/utils/parseEnvUiLayoutSettings.test.d.ts.map +1 -0
- package/lib/utils/seperatedMenus.js.map +1 -1
- package/lib/utils/settingsDifference.d.ts +1 -0
- package/lib/utils/settingsDifference.d.ts.map +1 -1
- package/lib/utils/settingsDifference.js +51 -110
- package/lib/utils/settingsDifference.js.map +1 -1
- package/package.json +8 -4
- package/lib/components/UpdateSettings/SettingsConfigurationModel.test.d.ts.map +0 -1
- package/lib/components/__tests__/ApplicationErrorHandlerCommon.test.d.ts.map +0 -1
- package/lib/utils/assignDefaults.js +0 -166
- package/lib/utils/assignDefaults.js.map +0 -1
- /package/lib/{components/__tests__ → __tests__}/ApplicationErrorHandlerCommon.test.d.ts +0 -0
- /package/lib/{components/UpdateSettings → __tests__}/SettingsConfigurationModel.test.d.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApplicationErrorHandlerCommon.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ApplicationErrorHandlerCommon.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfigurationModelWrapper.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ConfigurationModelWrapper.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SettingsConfigurationModel.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/SettingsConfigurationModel.test.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultSettingsExample.d.ts","sourceRoot":"","sources":["../../../src/__tests__/__fixtures__/defaultSettingsExample.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA+D,MAAM,8BAA8B,CAAC;AAEtH,eAAO,MAAM,eAAe,EAAE,SA+G7B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"colorsList.js","sources":["../../src/colors/colorsList.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA,MAAA,
|
|
1
|
+
{"version":3,"file":"colorsList.js","sources":["../../src/colors/colorsList.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA,MAAA,SAAa,GAAA;;;;;;;;;;;;;;;;;;;;;QA4DX,EAAA,GAAA,EAAA,OAAA,EAAA,KAAA,EAAA,SAAA,EAAA;AAEF,KAAK;AAEL,IAAA,KAAA,EAAA;;;QAKE,EAAA,GAAA,EAAA,OAAA,EAAA,KAAA,EAAA,SAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"black.js","sources":["../../../src/colors/presets/black.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAS,MAAA,KAAO,GAAA;AAEhB,IAAA,OAAA,EAAA,
|
|
1
|
+
{"version":3,"file":"black.js","sources":["../../../src/colors/presets/black.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAS,MAAA,KAAO,GAAA;AAEhB,IAAA,OAAA,EAAA,MAAO;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"white.js","sources":["../../../src/colors/presets/white.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAS,MAAA,KAAO,GAAA;AAEhB,IAAA,OAAA,EAAA,
|
|
1
|
+
{"version":3,"file":"white.js","sources":["../../../src/colors/presets/white.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAS,MAAA,KAAO,GAAA;AAEhB,IAAA,OAAA,EAAA,MAAO;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationErrorHandlerCommon.js","sources":["../../src/components/ApplicationErrorHandlerCommon.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"oSAUG;AACH;AACE;;AAED;AAED;;;AAGC;AAED;;AAGI,MAAS,6BAAE,GAAA,CAAA,iBAAA,EAAA,oBAAA,EAAA,iBAAA,KAAA,CAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA;
|
|
1
|
+
{"version":3,"file":"ApplicationErrorHandlerCommon.js","sources":["../../src/components/ApplicationErrorHandlerCommon.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"oSAUG;AACH;AACE;;AAED;AAED;;;AAGC;AAED;;AAGI,MAAS,6BAAE,GAAA,CAAA,iBAAA,EAAA,oBAAA,EAAA,iBAAA,KAAA,CAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA;UACT,iBAAgB,GAAA,WAAA,CAAA,CAAA,KAAA,KAAA,KAAA,EAAA,iBAAA,CAAA;UAChB,MAAA,GAAA,iBAAmB,EAAA,MAAA,CAAA,CAAA,KAAuB,KAAA,CAAA,CAAA,OAAA,CAAA,IAAA,CAAA,CAAA,MAAA,KAAA,MAAA,CAAA,IAAA,KAAA,KAAA,EAAA,UAAA,CAAA,CAAA;UAC3C,YAAA,GAAA,WAAA,CAAA,oBAAA,CAAA;AACF,IAAA,gCACe,GAAA,CAAA,KAAA,KAAA;AAClB,QAAA,OAAA,CAAA,CAAA,oBAAA,GAAAA,GAAA,CAAA,oBAAA,EAAA,EAAA,GAAA,KAAA,EAAA,CAAA,GAAAA,GAAA,CAAA,IAAA,EAAA,EAAA,GAAA,KAAA,EAAA,CAAA;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorBoundaryCommon.js","sources":["../../src/components/ErrorBoundaryCommon.tsx"],"sourcesContent":[null],"names":[],"mappings":"qGAG+C,MAAO,mBAAY,SAAA,KAAA,CAAA,SAAA,CAAA;IAAG,WAAA,CAAA,KAAA,EAAA;AACrE;
|
|
1
|
+
{"version":3,"file":"ErrorBoundaryCommon.js","sources":["../../src/components/ErrorBoundaryCommon.tsx"],"sourcesContent":[null],"names":[],"mappings":"qGAG+C,MAAO,mBAAY,SAAA,KAAA,CAAA,SAAA,CAAA;IAAG,WAAA,CAAA,KAAA,EAAA;AACrE;QACI,IAAQ,CAAC,KAAE,GAAA,EAAQ,QAAA,EAAA,KAAA,EAAA,KAAA,EAAA,IAAA,EAAA;IACnB;IACA,OAAA,wBAA2B,CAAA,KAAA,EAAA;QAAE,OAAO,UAAK,EAAA,IAAA,EAAA,KAAA,EAAA;AAAE,IAAA;IAC7C,iBAAA,CAAA,KAAA,EAAA;AAEF,QAAA,MAAA,CAAA,KAAA,CAAa,KAAA,CAAA;AACG,IAAA;AAKZ,IAAA,kBAAO,CAAA,SAAA,EAAA,SAAgC,EAAA;;;;IAIvC;AAIA,IAAA,MAAA,GAAA;QAMA,IAAM,IAAA,CAAA,KAAA,CAAA,QAAA,EAAA;AAOT,YAAA,MAAA,iBAAA,GAAA,IAAA,CAAA,KAAA,CAAA,iBAAA;;;;;"}
|
|
@@ -1,24 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Cookie configuration for storing user settings
|
|
3
|
+
* - Max age: 30 days
|
|
4
|
+
* - Client-side accessible for dynamic UI updates
|
|
5
|
+
* - Domain-scoped in production for subdomain sharing
|
|
6
|
+
*/
|
|
7
|
+
export declare const settingsCookie: import("@remix-run/server-runtime").Cookie;
|
|
8
|
+
/**
|
|
9
|
+
* Fetches page settings from GraphQL backend with device/route-specific overrides
|
|
10
|
+
*
|
|
11
|
+
* @param request - The incoming HTTP request (used for forwarding cookies and headers)
|
|
12
|
+
* @param overrideIdentifier - Optional override identifier (e.g., "[mobile]", "[desktop]", "[/dashboard][mobile]")
|
|
13
|
+
* @returns GraphQL query result containing merged settings with overrides applied
|
|
14
|
+
*
|
|
15
|
+
* @remarks
|
|
16
|
+
* - The GraphQL backend implements Redis caching for performance
|
|
17
|
+
* - Settings are returned in a flat structure with bracket notation for overrides
|
|
18
|
+
* - Example structure: { logo: '...', theme: '...', '[mobile]': { ... }, '[/dashboard][mobile]': { ... } }
|
|
19
|
+
*/
|
|
20
|
+
export declare function fetchPageSettingsWithFetch(request: Request, overrideIdentifier?: string): Promise<{
|
|
21
|
+
data: any;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Universal settings loader utility for both Remix loaders and actions
|
|
25
|
+
*
|
|
26
|
+
* @param params - Object containing request, context, and params
|
|
27
|
+
* @param params.request - The incoming HTTP request
|
|
28
|
+
* @param params.context - Optional Remix load context
|
|
29
|
+
* @param params.params - Optional route parameters
|
|
30
|
+
*
|
|
31
|
+
* @returns Object containing merged settings and cookie string
|
|
32
|
+
* @returns settings - Fully merged settings (GraphQL + env + cookies + request payload)
|
|
33
|
+
* @returns setCookie - Cookie string to set in response headers
|
|
34
|
+
*
|
|
35
|
+
* @remarks
|
|
36
|
+
* This utility handles both loader (GET) and action (POST/PUT/DELETE) requests:
|
|
37
|
+
* - **Loaders (GET)**: Fetches and merges settings from GraphQL, env, and cookies
|
|
38
|
+
* - **Actions (POST/PUT)**: Additionally processes request payload and updates cookies
|
|
39
|
+
*
|
|
40
|
+
* Settings merge order (later sources override earlier ones):
|
|
41
|
+
* 1. GraphQL backend settings (with device overrides)
|
|
42
|
+
* 2. Environment variable settings
|
|
43
|
+
* 3. Cookie settings (user preferences)
|
|
44
|
+
* 4. Request payload (only for actions)
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* // In a Remix loader
|
|
48
|
+
* export const loader = async ({ request }) => {
|
|
49
|
+
* const { settings, setCookie } = await settingsLoaderUtil({ request });
|
|
50
|
+
* return json({ settings }, { headers: { 'Set-Cookie': setCookie } });
|
|
51
|
+
* };
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // In a Remix action
|
|
55
|
+
* export const action = async ({ request }) => {
|
|
56
|
+
* const { settings, setCookie } = await settingsLoaderUtil({ request });
|
|
57
|
+
* return json(settings, { headers: { 'Set-Cookie': setCookie } });
|
|
58
|
+
* };
|
|
59
|
+
*/
|
|
60
|
+
export declare function settingsLoaderUtil({ request, context, params }: {
|
|
61
|
+
request: any;
|
|
62
|
+
context: any;
|
|
63
|
+
params: any;
|
|
8
64
|
}): Promise<{
|
|
9
|
-
settings:
|
|
65
|
+
settings: any;
|
|
10
66
|
setCookie: string;
|
|
11
67
|
}>;
|
|
12
|
-
export declare
|
|
13
|
-
request: Request;
|
|
14
|
-
context?: IAppLoadContext;
|
|
15
|
-
params?: IResourceParams;
|
|
16
|
-
}) => Promise<import("@remix-run/server-runtime").TypedResponse<any>>;
|
|
17
|
-
export declare const loader: ({ request, context, params, }: {
|
|
18
|
-
request: Request;
|
|
19
|
-
context?: IAppLoadContext;
|
|
20
|
-
params?: IResourceParams;
|
|
21
|
-
}) => Promise<import("@remix-run/server-runtime").TypedResponse<{
|
|
22
|
-
settings: any;
|
|
23
|
-
}>>;
|
|
68
|
+
export declare function getDeviceType(userAgent: string): 'mobile' | 'desktop';
|
|
24
69
|
//# sourceMappingURL=UpdateSettings.server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateSettings.server.d.ts","sourceRoot":"","sources":["../../../src/components/UpdateSettings/UpdateSettings.server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UpdateSettings.server.d.ts","sourceRoot":"","sources":["../../../src/components/UpdateSettings/UpdateSettings.server.ts"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH,eAAO,MAAM,cAAc,4CAMzB,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,OAAO,EAAE,kBAAkB,CAAC,EAAE,MAAM;;GAuF7F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE;;;;CAAA;;;GA8GpE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAQrE"}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {createCookie
|
|
1
|
+
import {createCookie}from'@remix-run/node';import {ConfigCollectionName,ConfigFragmentName,ConfigurationSchemaId}from'common';import {GetPageSettingsDocument}from'common/graphql';import {merge}from'lodash-es';import {print}from'graphql';import {parseEnvLayoutSettings}from'../../utils/parseEnvUiLayoutSettings.js';import {config}from'../../config/env-config.js';import'../../config/defaultSettings.js';import {generateCdecodeUri,DEFAULT_CONTRIBUTION_TENANT_ID}from'@adminide-stack/core';/**
|
|
2
|
+
* Cookie configuration for storing user settings
|
|
3
|
+
* - Max age: 30 days
|
|
4
|
+
* - Client-side accessible for dynamic UI updates
|
|
5
|
+
* - Domain-scoped in production for subdomain sharing
|
|
6
|
+
*/
|
|
2
7
|
const settingsCookie = createCookie('settings', {
|
|
3
8
|
maxAge: 60 * 60 * 24 * 30, // 1 month
|
|
4
9
|
httpOnly: false, // Allow client-side access
|
|
@@ -6,126 +11,216 @@ const settingsCookie = createCookie('settings', {
|
|
|
6
11
|
path: '/', // Ensure cookie is available for all paths
|
|
7
12
|
domain: config.isProd ? config.APP_DOMAIN : undefined,
|
|
8
13
|
});
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Fetches page settings from GraphQL backend with device/route-specific overrides
|
|
16
|
+
*
|
|
17
|
+
* @param request - The incoming HTTP request (used for forwarding cookies and headers)
|
|
18
|
+
* @param overrideIdentifier - Optional override identifier (e.g., "[mobile]", "[desktop]", "[/dashboard][mobile]")
|
|
19
|
+
* @returns GraphQL query result containing merged settings with overrides applied
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* - The GraphQL backend implements Redis caching for performance
|
|
23
|
+
* - Settings are returned in a flat structure with bracket notation for overrides
|
|
24
|
+
* - Example structure: { logo: '...', theme: '...', '[mobile]': { ... }, '[/dashboard][mobile]': { ... } }
|
|
25
|
+
*/
|
|
26
|
+
async function fetchPageSettingsWithFetch(request, overrideIdentifier) {
|
|
27
|
+
console.log(`🔍 Fetching settings from GraphQL (Redis-cached backend)...`);
|
|
28
|
+
// Generate resource URI for the application settings
|
|
29
|
+
const resource = generateCdecodeUri(DEFAULT_CONTRIBUTION_TENANT_ID, {
|
|
30
|
+
resourceType: ConfigCollectionName.Applications,
|
|
31
|
+
resourceId: config.APPLICATION_ID,
|
|
32
|
+
idField: 'appId',
|
|
33
|
+
}, {}, ConfigFragmentName.UiSettings);
|
|
34
|
+
const url = process.env.GRAPHQL_URL || 'http://localhost:8080/graphql';
|
|
35
|
+
// Convert GraphQL DocumentNode to string
|
|
36
|
+
const query = print(GetPageSettingsDocument);
|
|
37
|
+
// Prepare GraphQL query options
|
|
38
|
+
const options = {
|
|
39
|
+
schemaId: ConfigurationSchemaId.UiLayout,
|
|
40
|
+
target: 2 /* ConfigurationTarget.APPLICATION */,
|
|
41
|
+
configKey: 'uilayout',
|
|
42
|
+
};
|
|
43
|
+
// Add device/route overrides if provided
|
|
44
|
+
if (overrideIdentifier) {
|
|
45
|
+
options.overrides = {
|
|
46
|
+
strict: true,
|
|
47
|
+
overrideIdentifier,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const variables = {
|
|
51
|
+
resourceUri: resource,
|
|
52
|
+
options,
|
|
53
|
+
};
|
|
54
|
+
console.log('🔍 Fetching settings with direct fetch to:', url);
|
|
55
|
+
// console.log('🔍 Query variables:', JSON.stringify(variables, null, 2));
|
|
56
|
+
// Forward cookies and headers from the incoming request
|
|
57
|
+
const headers = {
|
|
58
|
+
'Content-Type': 'application/json',
|
|
59
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
60
|
+
Pragma: 'no-cache',
|
|
61
|
+
Expires: '0',
|
|
62
|
+
};
|
|
63
|
+
const cookieHeader = request.headers.get('Cookie');
|
|
64
|
+
if (cookieHeader) {
|
|
65
|
+
headers['Cookie'] = cookieHeader;
|
|
66
|
+
console.log('🍪 Forwarding cookies to GraphQL backend');
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.log('⚠️ No cookies found in request');
|
|
70
|
+
}
|
|
11
71
|
try {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
variables: {
|
|
20
|
-
resourceUri: `cdecode://default/uilayout#uiSettings`,
|
|
21
|
-
options: {
|
|
22
|
-
schemaId: 'uiLayout',
|
|
23
|
-
target: 2 /* ConfigurationTarget.APPLICATION */,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
72
|
+
const response = await fetch(url, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers,
|
|
75
|
+
body: JSON.stringify({
|
|
76
|
+
query,
|
|
77
|
+
variables,
|
|
78
|
+
}),
|
|
26
79
|
});
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
console.error('❌ GraphQL fetch failed with status:', response.status);
|
|
82
|
+
throw new Error(`GraphQL request failed: ${response.status} ${response.statusText}`);
|
|
83
|
+
}
|
|
84
|
+
const result = await response.json();
|
|
85
|
+
if (result.errors) {
|
|
86
|
+
console.error('❌ GraphQL errors:', JSON.stringify(result.errors, null, 2));
|
|
87
|
+
throw new Error(`GraphQL errors: ${JSON.stringify(result.errors)}`);
|
|
88
|
+
}
|
|
89
|
+
console.log('✅ Settings fetched successfully (from Redis-cached backend)');
|
|
90
|
+
return { data: result.data };
|
|
27
91
|
}
|
|
28
92
|
catch (error) {
|
|
29
|
-
console.
|
|
30
|
-
|
|
31
|
-
return null;
|
|
93
|
+
console.error('❌ Failed to fetch settings with fetch:', error);
|
|
94
|
+
throw error;
|
|
32
95
|
}
|
|
33
96
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Universal settings loader utility for both Remix loaders and actions
|
|
99
|
+
*
|
|
100
|
+
* @param params - Object containing request, context, and params
|
|
101
|
+
* @param params.request - The incoming HTTP request
|
|
102
|
+
* @param params.context - Optional Remix load context
|
|
103
|
+
* @param params.params - Optional route parameters
|
|
104
|
+
*
|
|
105
|
+
* @returns Object containing merged settings and cookie string
|
|
106
|
+
* @returns settings - Fully merged settings (GraphQL + env + cookies + request payload)
|
|
107
|
+
* @returns setCookie - Cookie string to set in response headers
|
|
108
|
+
*
|
|
109
|
+
* @remarks
|
|
110
|
+
* This utility handles both loader (GET) and action (POST/PUT/DELETE) requests:
|
|
111
|
+
* - **Loaders (GET)**: Fetches and merges settings from GraphQL, env, and cookies
|
|
112
|
+
* - **Actions (POST/PUT)**: Additionally processes request payload and updates cookies
|
|
113
|
+
*
|
|
114
|
+
* Settings merge order (later sources override earlier ones):
|
|
115
|
+
* 1. GraphQL backend settings (with device overrides)
|
|
116
|
+
* 2. Environment variable settings
|
|
117
|
+
* 3. Cookie settings (user preferences)
|
|
118
|
+
* 4. Request payload (only for actions)
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* // In a Remix loader
|
|
122
|
+
* export const loader = async ({ request }) => {
|
|
123
|
+
* const { settings, setCookie } = await settingsLoaderUtil({ request });
|
|
124
|
+
* return json({ settings }, { headers: { 'Set-Cookie': setCookie } });
|
|
125
|
+
* };
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* // In a Remix action
|
|
129
|
+
* export const action = async ({ request }) => {
|
|
130
|
+
* const { settings, setCookie } = await settingsLoaderUtil({ request });
|
|
131
|
+
* return json(settings, { headers: { 'Set-Cookie': setCookie } });
|
|
132
|
+
* };
|
|
133
|
+
*/
|
|
134
|
+
async function settingsLoaderUtil({ request, context, params }) {
|
|
135
|
+
// 1. Detect device type from User-Agent header
|
|
136
|
+
const userAgent = request.headers.get('User-Agent') || '';
|
|
137
|
+
const deviceType = getDeviceType(userAgent);
|
|
138
|
+
// 2. Fetch settings from GraphQL backend with device-specific overrides
|
|
139
|
+
// Override identifier format: "[desktop]" or "[mobile]"
|
|
140
|
+
const overrideIdentifier = `[${deviceType}]`;
|
|
141
|
+
const result = await fetchPageSettingsWithFetch(request, overrideIdentifier);
|
|
142
|
+
// console.log('ddRESULT=========>', JSON.stringify(result));
|
|
143
|
+
const pageBackendSettings = result?.data?.pageSettings?.settings
|
|
40
144
|
? JSON.parse(JSON.stringify(result?.data?.pageSettings?.settings))
|
|
41
145
|
: null;
|
|
42
|
-
|
|
146
|
+
// 3. Parse request payload (only available for POST/PUT requests in actions)
|
|
147
|
+
let requestPayload = {};
|
|
43
148
|
try {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
149
|
+
// Clone request to avoid "body already read" errors
|
|
150
|
+
const clonedRequest = request.clone();
|
|
151
|
+
const contentType = request.headers.get('content-type');
|
|
152
|
+
// Only parse JSON for non-GET requests with JSON content-type
|
|
153
|
+
if (request.method !== 'GET' && contentType?.includes('application/json')) {
|
|
154
|
+
const jsonData = await clonedRequest.json();
|
|
155
|
+
requestPayload = jsonData?.config || {};
|
|
156
|
+
}
|
|
47
157
|
}
|
|
48
158
|
catch (error) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
// If no settings in cookie, generate default settings
|
|
53
|
-
if (!settings) {
|
|
54
|
-
const fullSettings = merge({}, pageDefaultSettings, config.LAYOUT_SETTINGS);
|
|
55
|
-
assignDefaults(fullSettings, pageDefaultSettings);
|
|
56
|
-
// Only store differences to keep cookie size small
|
|
57
|
-
const diffSettings = await compareAndSaveSettingsDifferences(fullSettings, pageDefaultSettings);
|
|
58
|
-
const cookie = await settingsCookie.serialize(diffSettings);
|
|
59
|
-
return { settings: fullSettings, setCookie: cookie };
|
|
159
|
+
// Expected for GET requests (loaders) - no payload to parse
|
|
160
|
+
console.log('ℹ️ No request payload (likely a loader call)');
|
|
161
|
+
requestPayload = {};
|
|
60
162
|
}
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
163
|
+
// console.log('🔍 DEBUG - pageBackendSettings:', JSON.stringify(pageBackendSettings, null, 2));
|
|
164
|
+
// 4. Parse environment-based layout settings (fallback/default values)
|
|
165
|
+
const envLayoutSettings = parseEnvLayoutSettings();
|
|
166
|
+
// 5. Parse and validate existing cookie settings
|
|
167
|
+
const cookieHeader = request.headers.get('Cookie');
|
|
168
|
+
let existingCookieSettings;
|
|
169
|
+
let cookieUpdatedSettings;
|
|
68
170
|
try {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const cookieHeader = request.headers.get('Cookie');
|
|
80
|
-
let existingSettings;
|
|
81
|
-
let mergedSettings;
|
|
82
|
-
try {
|
|
83
|
-
existingSettings = await settingsCookie.parse(cookieHeader);
|
|
84
|
-
mergedSettings = merge({}, existingSettings, payload);
|
|
85
|
-
assignDefaults(mergedSettings, pageDefaultSettings);
|
|
171
|
+
existingCookieSettings = await settingsCookie.parse(cookieHeader);
|
|
172
|
+
// DEFENSIVE: Remove invalid numeric string keys (data corruption prevention)
|
|
173
|
+
if (existingCookieSettings && typeof existingCookieSettings === 'object') {
|
|
174
|
+
Object.keys(existingCookieSettings).forEach((key) => {
|
|
175
|
+
// Remove keys that are numeric strings (like "0", "1", etc.)
|
|
176
|
+
if (/^\d+$/.test(key)) {
|
|
177
|
+
console.warn(`⚠️ Removing invalid numeric key from cookie settings: "${key}" = ${JSON.stringify(existingCookieSettings[key])}`);
|
|
178
|
+
delete existingCookieSettings[key];
|
|
179
|
+
}
|
|
180
|
+
});
|
|
86
181
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
182
|
+
// 6. Merge existing cookie settings with new request payload
|
|
183
|
+
cookieUpdatedSettings = merge({}, existingCookieSettings, requestPayload);
|
|
184
|
+
// Validate merge result - check for numeric key corruption
|
|
185
|
+
const numericKeysAfterMerge = Object.keys(cookieUpdatedSettings).filter((k) => /^\d+$/.test(k));
|
|
186
|
+
if (numericKeysAfterMerge.length > 0) {
|
|
187
|
+
console.error('❌ NUMERIC KEYS APPEARED AFTER MERGE!', numericKeysAfterMerge);
|
|
188
|
+
console.error('❌ Values:', numericKeysAfterMerge.map((k) => `${k}: ${JSON.stringify(cookieUpdatedSettings[k])}`));
|
|
90
189
|
}
|
|
91
|
-
// Merge everything together
|
|
92
|
-
const fullSettings = merge({}, mergedSettings, config.LAYOUT_SETTINGS);
|
|
93
|
-
// Store only differences from default
|
|
94
|
-
const diffSettings = await compareAndSaveSettingsDifferences(fullSettings, pageDefaultSettings);
|
|
95
|
-
// Create a new cookie with the diff settings
|
|
96
|
-
const newCookie = await settingsCookie.serialize(diffSettings);
|
|
97
|
-
return json(fullSettings, {
|
|
98
|
-
headers: {
|
|
99
|
-
'Set-Cookie': newCookie,
|
|
100
|
-
},
|
|
101
|
-
});
|
|
102
190
|
}
|
|
103
191
|
catch (error) {
|
|
104
|
-
|
|
105
|
-
|
|
192
|
+
// If cookie parsing fails, use only the request payload
|
|
193
|
+
console.error('Error parsing settings cookie:', error);
|
|
194
|
+
existingCookieSettings = null;
|
|
195
|
+
cookieUpdatedSettings = requestPayload;
|
|
106
196
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
return json({ settings }, { headers });
|
|
197
|
+
// 7. Merge all settings sources in priority order (later sources override earlier)
|
|
198
|
+
// Priority: GraphQL backend → Environment → Cookie + Request payload
|
|
199
|
+
const fullSettings = merge({}, pageBackendSettings, envLayoutSettings, cookieUpdatedSettings);
|
|
200
|
+
// 8. Validate final merged settings - detect and remove numeric key corruption
|
|
201
|
+
const numericKeysAfterFinalMerge = Object.keys(fullSettings).filter((k) => /^\d+$/.test(k));
|
|
202
|
+
if (numericKeysAfterFinalMerge.length > 0) {
|
|
203
|
+
console.error('❌ NUMERIC KEYS APPEARED AFTER FINAL MERGE!', numericKeysAfterFinalMerge);
|
|
204
|
+
console.error('❌ Values:', numericKeysAfterFinalMerge.map((k) => `${k}: ${JSON.stringify(fullSettings[k])}`));
|
|
117
205
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
: null;
|
|
126
|
-
let pageDefaultSettings = pageSettings?.uilayout || defaultSettings || {};
|
|
127
|
-
return json({
|
|
128
|
-
settings: merge({}, pageDefaultSettings, config.LAYOUT_SETTINGS),
|
|
206
|
+
// 9. Final cleanup - remove any invalid numeric string keys before returning
|
|
207
|
+
if (fullSettings && typeof fullSettings === 'object') {
|
|
208
|
+
Object.keys(fullSettings).forEach((key) => {
|
|
209
|
+
if (/^\d+$/.test(key)) {
|
|
210
|
+
console.warn(`⚠️ Removing invalid numeric key from fullSettings: "${key}"`);
|
|
211
|
+
delete fullSettings[key];
|
|
212
|
+
}
|
|
129
213
|
});
|
|
130
214
|
}
|
|
131
|
-
|
|
215
|
+
// 10. Serialize cookie settings for response headers
|
|
216
|
+
const cookie = await settingsCookie.serialize(cookieUpdatedSettings);
|
|
217
|
+
console.log('✅ FULL_SETTINGS prepared:', Object.keys(fullSettings).length, 'keys');
|
|
218
|
+
return { settings: fullSettings, setCookie: cookie };
|
|
219
|
+
}
|
|
220
|
+
function getDeviceType(userAgent) {
|
|
221
|
+
if (!userAgent)
|
|
222
|
+
return 'desktop';
|
|
223
|
+
// Enhanced regex that catches more mobile devices
|
|
224
|
+
const mobileRegex = /mobile|android|iphone|ipad|ipod|blackberry|windows phone|opera mini|iemobile|webos|palm|playbook|kindle|silk|psp|symbian|nokia|nexus|htc|samsung|sony|ericsson|lg|motorola|sgh|sec|sharp|vodafone|benq|sanyo|kyocera|nec|alcatel|denso|jarviss|docomo|emacs|minimo|maemo|blazer|dolfin|dolphin|netfront|openwave|teleca|elaine|bolt|iris|maui|packet|pie|portalmmm|w3c|wig|zte|audiovox|ericsson|kyocera|panasonic|qwerty|sendo|sharp|sie-|sonyericsson|t-mobile|up\.browser|up\.link|verizon|vodafone|wap|winwap|xda|zte/i;
|
|
225
|
+
return mobileRegex.test(userAgent) ? 'mobile' : 'desktop';
|
|
226
|
+
}export{fetchPageSettingsWithFetch,getDeviceType,settingsCookie,settingsLoaderUtil};//# sourceMappingURL=UpdateSettings.server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateSettings.server.js","sources":["../../../src/components/UpdateSettings/UpdateSettings.server.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UpdateSettings.server.js","sources":["../../../src/components/UpdateSettings/UpdateSettings.server.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;AAyCG,IAAA,IAAA,EAAA,GAAA;AACH,IAAA,MAAA,EAAA,MAAA,CAAA,MAAsB,GAAA,MAAA,CAAA,UAAA,GAAA,SAA2B;;AAuFhD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCG,QAAA,WAAA,EAAA,QAAA;AACH,QAAA,OAAA;;;;AAAqE;;;AA8GpE,QAAA,eAAA,EAAA,qCAAA;AAED,QAAA,MAAA,EAAA,UAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UpdateSettings.server.test.d.ts","sourceRoot":"","sources":["../../../src/components/UpdateSettings/UpdateSettings.server.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,6 +1,81 @@
|
|
|
1
1
|
import { ProSettings, SearchbarSettings } from '../interfaces';
|
|
2
2
|
import { NavigationMode, SideMenuType, SearchBarBehavior } from '../interfaces/settings';
|
|
3
3
|
import { ContentWidth } from '../interfaces/pure-settings';
|
|
4
|
+
export declare const DEFAULT_LAYOUT: {
|
|
5
|
+
contentWidth: ContentWidth;
|
|
6
|
+
fixedHeader: boolean;
|
|
7
|
+
fixedSidebar: boolean;
|
|
8
|
+
splitMenus: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare const DEFAULT_HEADER: {
|
|
11
|
+
showLogo: boolean;
|
|
12
|
+
showRightContent: boolean;
|
|
13
|
+
showMenuToggle: boolean;
|
|
14
|
+
showBackButton: boolean;
|
|
15
|
+
showPageTitle: boolean;
|
|
16
|
+
showActionButtons: boolean;
|
|
17
|
+
position: "fixed";
|
|
18
|
+
backgroundColor: string;
|
|
19
|
+
elevation: number;
|
|
20
|
+
showHeader: boolean;
|
|
21
|
+
showMenu: boolean;
|
|
22
|
+
menuHeaderRender: boolean;
|
|
23
|
+
searchBarRender: boolean;
|
|
24
|
+
searchBarBehavior: SearchBarBehavior;
|
|
25
|
+
searchBarOverlay: boolean;
|
|
26
|
+
scrollThreshold: number;
|
|
27
|
+
};
|
|
28
|
+
export declare const SEARCH_TYPES: {
|
|
29
|
+
readonly HOTELS: "HOTELS";
|
|
30
|
+
readonly FLIGHTS: "FLIGHTS";
|
|
31
|
+
readonly CARS: "CARS";
|
|
32
|
+
};
|
|
33
|
+
export declare const AMENITIES: readonly ["WiFi", "Pool", "Parking", "Air Conditioning", "Kitchen", "Washer", "Dryer", "TV", "Gym", "Elevator", "Hot Tub", "Breakfast"];
|
|
34
|
+
export declare const SHARED_VIEW_CONFIG: {
|
|
35
|
+
layout: {
|
|
36
|
+
navigationMode: NavigationMode;
|
|
37
|
+
sideMenuType: SideMenuType;
|
|
38
|
+
upperMenuDividerName: string;
|
|
39
|
+
middleMenuDividerName: string;
|
|
40
|
+
lowerMenuDividerName: string;
|
|
41
|
+
contentWidth: ContentWidth;
|
|
42
|
+
fixedHeader: boolean;
|
|
43
|
+
fixedSidebar: boolean;
|
|
44
|
+
splitMenus: boolean;
|
|
45
|
+
};
|
|
46
|
+
regions: {
|
|
47
|
+
header: {
|
|
48
|
+
showSearchSlot: boolean;
|
|
49
|
+
height: string;
|
|
50
|
+
showLogo: boolean;
|
|
51
|
+
showRightContent: boolean;
|
|
52
|
+
showMenuToggle: boolean;
|
|
53
|
+
showBackButton: boolean;
|
|
54
|
+
showPageTitle: boolean;
|
|
55
|
+
showActionButtons: boolean;
|
|
56
|
+
position: "fixed";
|
|
57
|
+
backgroundColor: string;
|
|
58
|
+
elevation: number;
|
|
59
|
+
showHeader: boolean;
|
|
60
|
+
showMenu: boolean;
|
|
61
|
+
menuHeaderRender: boolean;
|
|
62
|
+
searchBarRender: boolean;
|
|
63
|
+
searchBarBehavior: SearchBarBehavior;
|
|
64
|
+
searchBarOverlay: boolean;
|
|
65
|
+
scrollThreshold: number;
|
|
66
|
+
};
|
|
67
|
+
background: {
|
|
68
|
+
type: string;
|
|
69
|
+
color: string;
|
|
70
|
+
image: string;
|
|
71
|
+
video: string;
|
|
72
|
+
videoThumbnail: string;
|
|
73
|
+
};
|
|
74
|
+
footer: {
|
|
75
|
+
showFooter: boolean;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
};
|
|
4
79
|
export type ISettings = ProSettings & {
|
|
5
80
|
logo: string;
|
|
6
81
|
showSettingPanel: boolean;
|
|
@@ -28,6 +103,7 @@ export type ISettings = ProSettings & {
|
|
|
28
103
|
verifyFormShowSkipButton: boolean;
|
|
29
104
|
searchbarSettings: SearchbarSettings;
|
|
30
105
|
currentRoute: string;
|
|
106
|
+
sideMenuType: SideMenuType;
|
|
31
107
|
routeSettings: Record<string, {
|
|
32
108
|
layout: {
|
|
33
109
|
desktop: {
|
|
@@ -122,5 +198,4 @@ export type ISettings = ProSettings & {
|
|
|
122
198
|
components: any[];
|
|
123
199
|
activeComponent: string | null;
|
|
124
200
|
};
|
|
125
|
-
export declare const defaultSettings: ISettings;
|
|
126
201
|
//# sourceMappingURL=defaultSettings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultSettings.d.ts","sourceRoot":"","sources":["../../src/config/defaultSettings.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"defaultSettings.d.ts","sourceRoot":"","sources":["../../src/config/defaultSettings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAG3D,eAAO,MAAM,cAAc;kBACE,YAAY;;;;CAIxC,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;CAiB1B,CAAC;AAEF,eAAO,MAAM,YAAY;;;;CAIf,CAAC;AAEX,eAAO,MAAM,SAAS,yIAaZ,CAAC;AAGX,eAAO,MAAM,kBAAkB;;wBAGI,cAAc;sBACb,YAAY;;;;sBAnDnB,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuExC,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yBAAyB,EAAE,MAAM,CAAC;IAClC,uBAAuB,EAAE,MAAM,CAAC;IAChC,wBAAwB,EAAE,OAAO,CAAC;IAClC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,MAAM,CACjB,MAAM,EACN;QACI,MAAM,EAAE;YACJ,OAAO,EAAE;gBACL,cAAc,EAAE,cAAc,CAAC;gBAC/B,YAAY,EAAE,YAAY,CAAC;gBAC3B,YAAY,EAAE,YAAY,CAAC;gBAC3B,WAAW,EAAE,OAAO,CAAC;gBACrB,YAAY,EAAE,OAAO,CAAC;gBACtB,UAAU,EAAE,OAAO,CAAC;gBACpB,oBAAoB,EAAE,MAAM,CAAC;gBAC7B,qBAAqB,EAAE,MAAM,CAAC;gBAC9B,oBAAoB,EAAE,MAAM,CAAC;aAChC,CAAC;YACF,MAAM,EAAE;gBACJ,cAAc,EAAE,cAAc,CAAC;gBAC/B,YAAY,EAAE,YAAY,CAAC;gBAC3B,YAAY,EAAE,YAAY,CAAC;gBAC3B,WAAW,EAAE,OAAO,CAAC;gBACrB,YAAY,EAAE,OAAO,CAAC;gBACtB,UAAU,EAAE,OAAO,CAAC;gBACpB,oBAAoB,EAAE,MAAM,CAAC;gBAC7B,qBAAqB,EAAE,MAAM,CAAC;gBAC9B,oBAAoB,EAAE,MAAM,CAAC;aAChC,CAAC;SACL,CAAC;QACF,OAAO,EAAE;YACL,OAAO,EAAE;gBACL,MAAM,EAAE;oBACJ,QAAQ,EAAE,OAAO,CAAC;oBAClB,cAAc,EAAE,OAAO,CAAC;oBACxB,gBAAgB,EAAE,OAAO,CAAC;oBAC1B,cAAc,EAAE,OAAO,CAAC;oBACxB,cAAc,EAAE,OAAO,CAAC;oBACxB,aAAa,EAAE,OAAO,CAAC;oBACvB,iBAAiB,EAAE,OAAO,CAAC;oBAC3B,QAAQ,EAAE,MAAM,CAAC;oBACjB,MAAM,EAAE,MAAM,CAAC;oBACf,eAAe,EAAE,MAAM,CAAC;oBACxB,SAAS,EAAE,MAAM,CAAC;oBAClB,UAAU,EAAE,OAAO,CAAC;oBACpB,QAAQ,EAAE,OAAO,CAAC;oBAClB,gBAAgB,EAAE,OAAO,CAAC;oBAC1B,eAAe,EAAE,OAAO,CAAC;oBACzB,iBAAiB,EAAE,iBAAiB,CAAC;oBACrC,gBAAgB,EAAE,OAAO,CAAC;oBAC1B,eAAe,EAAE,MAAM,CAAC;iBAC3B,CAAC;gBACF,UAAU,EAAE;oBACR,IAAI,EAAE,MAAM,CAAC;oBACb,KAAK,EAAE,MAAM,CAAC;oBACd,KAAK,EAAE,MAAM,CAAC;oBACd,KAAK,EAAE,MAAM,CAAC;oBACd,cAAc,EAAE,MAAM,CAAC;iBAC1B,CAAC;gBACF,MAAM,EAAE;oBACJ,UAAU,EAAE,OAAO,CAAC;iBACvB,CAAC;aACL,CAAC;YACF,MAAM,EAAE;gBACJ,MAAM,EAAE;oBACJ,QAAQ,EAAE,OAAO,CAAC;oBAClB,cAAc,EAAE,OAAO,CAAC;oBACxB,gBAAgB,EAAE,OAAO,CAAC;oBAC1B,cAAc,EAAE,OAAO,CAAC;oBACxB,cAAc,EAAE,OAAO,CAAC;oBACxB,aAAa,EAAE,OAAO,CAAC;oBACvB,iBAAiB,EAAE,OAAO,CAAC;oBAC3B,QAAQ,EAAE,MAAM,CAAC;oBACjB,MAAM,EAAE,MAAM,CAAC;oBACf,eAAe,EAAE,MAAM,CAAC;oBACxB,SAAS,EAAE,MAAM,CAAC;oBAClB,UAAU,EAAE,OAAO,CAAC;oBACpB,QAAQ,EAAE,OAAO,CAAC;oBAClB,gBAAgB,EAAE,OAAO,CAAC;oBAC1B,eAAe,EAAE,OAAO,CAAC;oBACzB,iBAAiB,EAAE,iBAAiB,CAAC;oBACrC,gBAAgB,EAAE,OAAO,CAAC;oBAC1B,eAAe,EAAE,MAAM,CAAC;iBAC3B,CAAC;gBACF,UAAU,EAAE;oBACR,IAAI,EAAE,MAAM,CAAC;oBACb,KAAK,EAAE,MAAM,CAAC;oBACd,KAAK,EAAE,MAAM,CAAC;oBACd,KAAK,EAAE,MAAM,CAAC;iBACjB,CAAC;gBACF,MAAM,EAAE;oBACJ,UAAU,EAAE,OAAO,CAAC;iBACvB,CAAC;aACL,CAAC;SACL,CAAC;KACL,CACJ,CAAC;IACF,UAAU,EAAE,GAAG,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC"}
|