This commit is contained in:
Akko
2025-08-04 18:57:35 +02:00
parent 8cf6e78a79
commit 9495868c2e
5030 changed files with 518594 additions and 17609 deletions

View File

@@ -0,0 +1,2 @@
import type { FormatDetectionParser } from '../../assets/detections/types';
export declare const detectCompressed: FormatDetectionParser;

View File

@@ -0,0 +1,60 @@
'use strict';
var Extensions = require('../../extensions/Extensions.js');
var getSupportedCompressedTextureFormats = require('../../rendering/renderers/shared/texture/utils/getSupportedCompressedTextureFormats.js');
var isWebGLSupported = require('../../utils/browser/isWebGLSupported.js');
var isWebGPUSupported = require('../../utils/browser/isWebGPUSupported.js');
var resolveCompressedTextureUrl = require('./resolveCompressedTextureUrl.js');
"use strict";
let compressedTextureExtensions;
const detectCompressed = {
extension: {
type: Extensions.ExtensionType.DetectionParser,
priority: 2
},
test: async () => {
if (await isWebGPUSupported.isWebGPUSupported())
return true;
if (isWebGLSupported.isWebGLSupported())
return true;
return false;
},
add: async (formats) => {
const supportedCompressedTextureFormats = await getSupportedCompressedTextureFormats.getSupportedCompressedTextureFormats();
compressedTextureExtensions = extractExtensionsForCompressedTextureFormats(supportedCompressedTextureFormats);
return [...compressedTextureExtensions, ...formats];
},
remove: async (formats) => {
if (compressedTextureExtensions) {
return formats.filter((f) => !(f in compressedTextureExtensions));
}
return formats;
}
};
function extractExtensionsForCompressedTextureFormats(formats) {
const extensions = ["basis"];
const dupeMap = {};
formats.forEach((format) => {
const extension = format.split("-")[0];
if (extension && !dupeMap[extension]) {
dupeMap[extension] = true;
extensions.push(extension);
}
});
extensions.sort((a, b) => {
const aIndex = resolveCompressedTextureUrl.validFormats.indexOf(a);
const bIndex = resolveCompressedTextureUrl.validFormats.indexOf(b);
if (aIndex === -1) {
return 1;
}
if (bIndex === -1) {
return -1;
}
return aIndex - bIndex;
});
return extensions;
}
exports.detectCompressed = detectCompressed;
//# sourceMappingURL=detectCompressed.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"detectCompressed.js","sources":["../../../src/compressed-textures/shared/detectCompressed.ts"],"sourcesContent":["import { ExtensionType } from '../../extensions/Extensions';\n// eslint-disable-next-line max-len\nimport { getSupportedCompressedTextureFormats } from '../../rendering/renderers/shared/texture/utils/getSupportedCompressedTextureFormats';\nimport { isWebGLSupported } from '../../utils/browser/isWebGLSupported';\nimport { isWebGPUSupported } from '../../utils/browser/isWebGPUSupported';\nimport { validFormats } from './resolveCompressedTextureUrl';\n\nimport type { FormatDetectionParser } from '../../assets/detections/types';\nimport type { TEXTURE_FORMATS } from '../../rendering/renderers/shared/texture/const';\n\nlet compressedTextureExtensions: string[];\n\nexport const detectCompressed = {\n extension: {\n type: ExtensionType.DetectionParser,\n priority: 2,\n },\n test: async (): Promise<boolean> =>\n {\n if (await isWebGPUSupported()) return true;\n if (isWebGLSupported()) return true;\n\n return false;\n },\n add: async (formats: string[]): Promise<string[]> =>\n {\n const supportedCompressedTextureFormats = await getSupportedCompressedTextureFormats();\n\n compressedTextureExtensions = extractExtensionsForCompressedTextureFormats(supportedCompressedTextureFormats);\n\n return [...compressedTextureExtensions, ...formats];\n },\n remove: async (formats: string[]): Promise<string[]> =>\n {\n if (compressedTextureExtensions)\n {\n return formats.filter((f) => !(f in compressedTextureExtensions));\n }\n\n return formats;\n },\n} as FormatDetectionParser;\n\nfunction extractExtensionsForCompressedTextureFormats(formats: TEXTURE_FORMATS[]): string[]\n{\n const extensions: string[] = ['basis'];\n\n const dupeMap: Record<string, boolean> = {};\n\n formats.forEach((format) =>\n {\n const extension = format.split('-')[0];\n\n if (extension && !dupeMap[extension])\n {\n dupeMap[extension] = true;\n extensions.push(extension);\n }\n });\n\n // sort extensions by priority\n extensions.sort((a, b) =>\n {\n const aIndex = validFormats.indexOf(a);\n const bIndex = validFormats.indexOf(b);\n\n if (aIndex === -1)\n {\n return 1;\n }\n if (bIndex === -1)\n {\n return -1;\n }\n\n return aIndex - bIndex;\n });\n\n return extensions;\n}\n"],"names":["ExtensionType","isWebGPUSupported","isWebGLSupported","getSupportedCompressedTextureFormats","validFormats"],"mappings":";;;;;;;;;AAUA,IAAI,2BAAA,CAAA;AAEG,MAAM,gBAAmB,GAAA;AAAA,EAC5B,SAAW,EAAA;AAAA,IACP,MAAMA,wBAAc,CAAA,eAAA;AAAA,IACpB,QAAU,EAAA,CAAA;AAAA,GACd;AAAA,EACA,MAAM,YACN;AACI,IAAA,IAAI,MAAMC,mCAAkB,EAAA;AAAG,MAAO,OAAA,IAAA,CAAA;AACtC,IAAA,IAAIC,iCAAiB,EAAA;AAAG,MAAO,OAAA,IAAA,CAAA;AAE/B,IAAO,OAAA,KAAA,CAAA;AAAA,GACX;AAAA,EACA,GAAA,EAAK,OAAO,OACZ,KAAA;AACI,IAAM,MAAA,iCAAA,GAAoC,MAAMC,yEAAqC,EAAA,CAAA;AAErF,IAAA,2BAAA,GAA8B,6CAA6C,iCAAiC,CAAA,CAAA;AAE5G,IAAA,OAAO,CAAC,GAAG,2BAA6B,EAAA,GAAG,OAAO,CAAA,CAAA;AAAA,GACtD;AAAA,EACA,MAAA,EAAQ,OAAO,OACf,KAAA;AACI,IAAA,IAAI,2BACJ,EAAA;AACI,MAAA,OAAO,QAAQ,MAAO,CAAA,CAAC,CAAM,KAAA,EAAE,KAAK,2BAA4B,CAAA,CAAA,CAAA;AAAA,KACpE;AAEA,IAAO,OAAA,OAAA,CAAA;AAAA,GACX;AACJ,EAAA;AAEA,SAAS,6CAA6C,OACtD,EAAA;AACI,EAAM,MAAA,UAAA,GAAuB,CAAC,OAAO,CAAA,CAAA;AAErC,EAAA,MAAM,UAAmC,EAAC,CAAA;AAE1C,EAAQ,OAAA,CAAA,OAAA,CAAQ,CAAC,MACjB,KAAA;AACI,IAAA,MAAM,SAAY,GAAA,MAAA,CAAO,KAAM,CAAA,GAAG,EAAE,CAAC,CAAA,CAAA;AAErC,IAAA,IAAI,SAAa,IAAA,CAAC,OAAQ,CAAA,SAAS,CACnC,EAAA;AACI,MAAA,OAAA,CAAQ,SAAS,CAAI,GAAA,IAAA,CAAA;AACrB,MAAA,UAAA,CAAW,KAAK,SAAS,CAAA,CAAA;AAAA,KAC7B;AAAA,GACH,CAAA,CAAA;AAGD,EAAW,UAAA,CAAA,IAAA,CAAK,CAAC,CAAA,EAAG,CACpB,KAAA;AACI,IAAM,MAAA,MAAA,GAASC,wCAAa,CAAA,OAAA,CAAQ,CAAC,CAAA,CAAA;AACrC,IAAM,MAAA,MAAA,GAASA,wCAAa,CAAA,OAAA,CAAQ,CAAC,CAAA,CAAA;AAErC,IAAA,IAAI,WAAW,CACf,CAAA,EAAA;AACI,MAAO,OAAA,CAAA,CAAA;AAAA,KACX;AACA,IAAA,IAAI,WAAW,CACf,CAAA,EAAA;AACI,MAAO,OAAA,CAAA,CAAA,CAAA;AAAA,KACX;AAEA,IAAA,OAAO,MAAS,GAAA,MAAA,CAAA;AAAA,GACnB,CAAA,CAAA;AAED,EAAO,OAAA,UAAA,CAAA;AACX;;;;"}

View File

@@ -0,0 +1,58 @@
import { ExtensionType } from '../../extensions/Extensions.mjs';
import { getSupportedCompressedTextureFormats } from '../../rendering/renderers/shared/texture/utils/getSupportedCompressedTextureFormats.mjs';
import { isWebGLSupported } from '../../utils/browser/isWebGLSupported.mjs';
import { isWebGPUSupported } from '../../utils/browser/isWebGPUSupported.mjs';
import { validFormats } from './resolveCompressedTextureUrl.mjs';
"use strict";
let compressedTextureExtensions;
const detectCompressed = {
extension: {
type: ExtensionType.DetectionParser,
priority: 2
},
test: async () => {
if (await isWebGPUSupported())
return true;
if (isWebGLSupported())
return true;
return false;
},
add: async (formats) => {
const supportedCompressedTextureFormats = await getSupportedCompressedTextureFormats();
compressedTextureExtensions = extractExtensionsForCompressedTextureFormats(supportedCompressedTextureFormats);
return [...compressedTextureExtensions, ...formats];
},
remove: async (formats) => {
if (compressedTextureExtensions) {
return formats.filter((f) => !(f in compressedTextureExtensions));
}
return formats;
}
};
function extractExtensionsForCompressedTextureFormats(formats) {
const extensions = ["basis"];
const dupeMap = {};
formats.forEach((format) => {
const extension = format.split("-")[0];
if (extension && !dupeMap[extension]) {
dupeMap[extension] = true;
extensions.push(extension);
}
});
extensions.sort((a, b) => {
const aIndex = validFormats.indexOf(a);
const bIndex = validFormats.indexOf(b);
if (aIndex === -1) {
return 1;
}
if (bIndex === -1) {
return -1;
}
return aIndex - bIndex;
});
return extensions;
}
export { detectCompressed };
//# sourceMappingURL=detectCompressed.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"detectCompressed.mjs","sources":["../../../src/compressed-textures/shared/detectCompressed.ts"],"sourcesContent":["import { ExtensionType } from '../../extensions/Extensions';\n// eslint-disable-next-line max-len\nimport { getSupportedCompressedTextureFormats } from '../../rendering/renderers/shared/texture/utils/getSupportedCompressedTextureFormats';\nimport { isWebGLSupported } from '../../utils/browser/isWebGLSupported';\nimport { isWebGPUSupported } from '../../utils/browser/isWebGPUSupported';\nimport { validFormats } from './resolveCompressedTextureUrl';\n\nimport type { FormatDetectionParser } from '../../assets/detections/types';\nimport type { TEXTURE_FORMATS } from '../../rendering/renderers/shared/texture/const';\n\nlet compressedTextureExtensions: string[];\n\nexport const detectCompressed = {\n extension: {\n type: ExtensionType.DetectionParser,\n priority: 2,\n },\n test: async (): Promise<boolean> =>\n {\n if (await isWebGPUSupported()) return true;\n if (isWebGLSupported()) return true;\n\n return false;\n },\n add: async (formats: string[]): Promise<string[]> =>\n {\n const supportedCompressedTextureFormats = await getSupportedCompressedTextureFormats();\n\n compressedTextureExtensions = extractExtensionsForCompressedTextureFormats(supportedCompressedTextureFormats);\n\n return [...compressedTextureExtensions, ...formats];\n },\n remove: async (formats: string[]): Promise<string[]> =>\n {\n if (compressedTextureExtensions)\n {\n return formats.filter((f) => !(f in compressedTextureExtensions));\n }\n\n return formats;\n },\n} as FormatDetectionParser;\n\nfunction extractExtensionsForCompressedTextureFormats(formats: TEXTURE_FORMATS[]): string[]\n{\n const extensions: string[] = ['basis'];\n\n const dupeMap: Record<string, boolean> = {};\n\n formats.forEach((format) =>\n {\n const extension = format.split('-')[0];\n\n if (extension && !dupeMap[extension])\n {\n dupeMap[extension] = true;\n extensions.push(extension);\n }\n });\n\n // sort extensions by priority\n extensions.sort((a, b) =>\n {\n const aIndex = validFormats.indexOf(a);\n const bIndex = validFormats.indexOf(b);\n\n if (aIndex === -1)\n {\n return 1;\n }\n if (bIndex === -1)\n {\n return -1;\n }\n\n return aIndex - bIndex;\n });\n\n return extensions;\n}\n"],"names":[],"mappings":";;;;;;;AAUA,IAAI,2BAAA,CAAA;AAEG,MAAM,gBAAmB,GAAA;AAAA,EAC5B,SAAW,EAAA;AAAA,IACP,MAAM,aAAc,CAAA,eAAA;AAAA,IACpB,QAAU,EAAA,CAAA;AAAA,GACd;AAAA,EACA,MAAM,YACN;AACI,IAAA,IAAI,MAAM,iBAAkB,EAAA;AAAG,MAAO,OAAA,IAAA,CAAA;AACtC,IAAA,IAAI,gBAAiB,EAAA;AAAG,MAAO,OAAA,IAAA,CAAA;AAE/B,IAAO,OAAA,KAAA,CAAA;AAAA,GACX;AAAA,EACA,GAAA,EAAK,OAAO,OACZ,KAAA;AACI,IAAM,MAAA,iCAAA,GAAoC,MAAM,oCAAqC,EAAA,CAAA;AAErF,IAAA,2BAAA,GAA8B,6CAA6C,iCAAiC,CAAA,CAAA;AAE5G,IAAA,OAAO,CAAC,GAAG,2BAA6B,EAAA,GAAG,OAAO,CAAA,CAAA;AAAA,GACtD;AAAA,EACA,MAAA,EAAQ,OAAO,OACf,KAAA;AACI,IAAA,IAAI,2BACJ,EAAA;AACI,MAAA,OAAO,QAAQ,MAAO,CAAA,CAAC,CAAM,KAAA,EAAE,KAAK,2BAA4B,CAAA,CAAA,CAAA;AAAA,KACpE;AAEA,IAAO,OAAA,OAAA,CAAA;AAAA,GACX;AACJ,EAAA;AAEA,SAAS,6CAA6C,OACtD,EAAA;AACI,EAAM,MAAA,UAAA,GAAuB,CAAC,OAAO,CAAA,CAAA;AAErC,EAAA,MAAM,UAAmC,EAAC,CAAA;AAE1C,EAAQ,OAAA,CAAA,OAAA,CAAQ,CAAC,MACjB,KAAA;AACI,IAAA,MAAM,SAAY,GAAA,MAAA,CAAO,KAAM,CAAA,GAAG,EAAE,CAAC,CAAA,CAAA;AAErC,IAAA,IAAI,SAAa,IAAA,CAAC,OAAQ,CAAA,SAAS,CACnC,EAAA;AACI,MAAA,OAAA,CAAQ,SAAS,CAAI,GAAA,IAAA,CAAA;AACrB,MAAA,UAAA,CAAW,KAAK,SAAS,CAAA,CAAA;AAAA,KAC7B;AAAA,GACH,CAAA,CAAA;AAGD,EAAW,UAAA,CAAA,IAAA,CAAK,CAAC,CAAA,EAAG,CACpB,KAAA;AACI,IAAM,MAAA,MAAA,GAAS,YAAa,CAAA,OAAA,CAAQ,CAAC,CAAA,CAAA;AACrC,IAAM,MAAA,MAAA,GAAS,YAAa,CAAA,OAAA,CAAQ,CAAC,CAAA,CAAA;AAErC,IAAA,IAAI,WAAW,CACf,CAAA,EAAA;AACI,MAAO,OAAA,CAAA,CAAA;AAAA,KACX;AACA,IAAA,IAAI,WAAW,CACf,CAAA,EAAA;AACI,MAAO,OAAA,CAAA,CAAA,CAAA;AAAA,KACX;AAEA,IAAA,OAAO,MAAS,GAAA,MAAA,CAAA;AAAA,GACnB,CAAA,CAAA;AAED,EAAO,OAAA,UAAA,CAAA;AACX;;;;"}

View File

@@ -0,0 +1,11 @@
import { ExtensionType } from '../../extensions/Extensions';
export declare const validFormats: string[];
export declare const resolveCompressedTextureUrl: {
extension: ExtensionType.ResolveParser;
test: (value: string) => boolean;
parse: (value: string) => {
resolution: number;
format: string;
src: string;
};
};

View File

@@ -0,0 +1,33 @@
'use strict';
var Resolver = require('../../assets/resolver/Resolver.js');
var checkExtension = require('../../assets/utils/checkExtension.js');
var Extensions = require('../../extensions/Extensions.js');
"use strict";
const validFormats = ["basis", "bc7", "bc6h", "astc", "etc2", "bc5", "bc4", "bc3", "bc2", "bc1", "eac"];
const resolveCompressedTextureUrl = {
extension: Extensions.ExtensionType.ResolveParser,
test: (value) => checkExtension.checkExtension(value, [".ktx", ".ktx2", ".dds"]),
parse: (value) => {
let format;
const splitValue = value.split(".");
if (splitValue.length > 2) {
const newFormat = splitValue[splitValue.length - 2];
if (validFormats.includes(newFormat)) {
format = newFormat;
}
} else {
format = splitValue[splitValue.length - 1];
}
return {
resolution: parseFloat(Resolver.Resolver.RETINA_PREFIX.exec(value)?.[1] ?? "1"),
format,
src: value
};
}
};
exports.resolveCompressedTextureUrl = resolveCompressedTextureUrl;
exports.validFormats = validFormats;
//# sourceMappingURL=resolveCompressedTextureUrl.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"resolveCompressedTextureUrl.js","sources":["../../../src/compressed-textures/shared/resolveCompressedTextureUrl.ts"],"sourcesContent":["import { Resolver } from '../../assets/resolver/Resolver';\nimport { checkExtension } from '../../assets/utils/checkExtension';\nimport { ExtensionType } from '../../extensions/Extensions';\n\nimport type { ResolveURLParser } from '../../assets/resolver/types';\n\nexport const validFormats = ['basis', 'bc7', 'bc6h', 'astc', 'etc2', 'bc5', 'bc4', 'bc3', 'bc2', 'bc1', 'eac'];\n\nexport const resolveCompressedTextureUrl = {\n extension: ExtensionType.ResolveParser,\n test: (value: string) =>\n checkExtension(value, ['.ktx', '.ktx2', '.dds']),\n parse: (value: string) =>\n {\n let format;\n\n const splitValue = value.split('.');\n\n if (splitValue.length > 2)\n {\n const newFormat = splitValue[splitValue.length - 2];\n\n if (validFormats.includes(newFormat))\n {\n format = newFormat;\n }\n }\n else\n {\n format = splitValue[splitValue.length - 1];\n }\n\n return {\n resolution: parseFloat(Resolver.RETINA_PREFIX.exec(value)?.[1] ?? '1'),\n format,\n src: value,\n };\n }\n} satisfies ResolveURLParser;\n"],"names":["ExtensionType","checkExtension","Resolver"],"mappings":";;;;;;;AAMO,MAAM,YAAe,GAAA,CAAC,OAAS,EAAA,KAAA,EAAO,MAAQ,EAAA,MAAA,EAAQ,MAAQ,EAAA,KAAA,EAAO,KAAO,EAAA,KAAA,EAAO,KAAO,EAAA,KAAA,EAAO,KAAK,EAAA;AAEtG,MAAM,2BAA8B,GAAA;AAAA,EACvC,WAAWA,wBAAc,CAAA,aAAA;AAAA,EACzB,IAAA,EAAM,CAAC,KACH,KAAAC,6BAAA,CAAe,OAAO,CAAC,MAAA,EAAQ,OAAS,EAAA,MAAM,CAAC,CAAA;AAAA,EACnD,KAAA,EAAO,CAAC,KACR,KAAA;AACI,IAAI,IAAA,MAAA,CAAA;AAEJ,IAAM,MAAA,UAAA,GAAa,KAAM,CAAA,KAAA,CAAM,GAAG,CAAA,CAAA;AAElC,IAAI,IAAA,UAAA,CAAW,SAAS,CACxB,EAAA;AACI,MAAA,MAAM,SAAY,GAAA,UAAA,CAAW,UAAW,CAAA,MAAA,GAAS,CAAC,CAAA,CAAA;AAElD,MAAI,IAAA,YAAA,CAAa,QAAS,CAAA,SAAS,CACnC,EAAA;AACI,QAAS,MAAA,GAAA,SAAA,CAAA;AAAA,OACb;AAAA,KAGJ,MAAA;AACI,MAAS,MAAA,GAAA,UAAA,CAAW,UAAW,CAAA,MAAA,GAAS,CAAC,CAAA,CAAA;AAAA,KAC7C;AAEA,IAAO,OAAA;AAAA,MACH,UAAA,EAAY,WAAWC,iBAAS,CAAA,aAAA,CAAc,KAAK,KAAK,CAAA,GAAI,CAAC,CAAA,IAAK,GAAG,CAAA;AAAA,MACrE,MAAA;AAAA,MACA,GAAK,EAAA,KAAA;AAAA,KACT,CAAA;AAAA,GACJ;AACJ;;;;;"}

View File

@@ -0,0 +1,30 @@
import { Resolver } from '../../assets/resolver/Resolver.mjs';
import { checkExtension } from '../../assets/utils/checkExtension.mjs';
import { ExtensionType } from '../../extensions/Extensions.mjs';
"use strict";
const validFormats = ["basis", "bc7", "bc6h", "astc", "etc2", "bc5", "bc4", "bc3", "bc2", "bc1", "eac"];
const resolveCompressedTextureUrl = {
extension: ExtensionType.ResolveParser,
test: (value) => checkExtension(value, [".ktx", ".ktx2", ".dds"]),
parse: (value) => {
let format;
const splitValue = value.split(".");
if (splitValue.length > 2) {
const newFormat = splitValue[splitValue.length - 2];
if (validFormats.includes(newFormat)) {
format = newFormat;
}
} else {
format = splitValue[splitValue.length - 1];
}
return {
resolution: parseFloat(Resolver.RETINA_PREFIX.exec(value)?.[1] ?? "1"),
format,
src: value
};
}
};
export { resolveCompressedTextureUrl, validFormats };
//# sourceMappingURL=resolveCompressedTextureUrl.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"resolveCompressedTextureUrl.mjs","sources":["../../../src/compressed-textures/shared/resolveCompressedTextureUrl.ts"],"sourcesContent":["import { Resolver } from '../../assets/resolver/Resolver';\nimport { checkExtension } from '../../assets/utils/checkExtension';\nimport { ExtensionType } from '../../extensions/Extensions';\n\nimport type { ResolveURLParser } from '../../assets/resolver/types';\n\nexport const validFormats = ['basis', 'bc7', 'bc6h', 'astc', 'etc2', 'bc5', 'bc4', 'bc3', 'bc2', 'bc1', 'eac'];\n\nexport const resolveCompressedTextureUrl = {\n extension: ExtensionType.ResolveParser,\n test: (value: string) =>\n checkExtension(value, ['.ktx', '.ktx2', '.dds']),\n parse: (value: string) =>\n {\n let format;\n\n const splitValue = value.split('.');\n\n if (splitValue.length > 2)\n {\n const newFormat = splitValue[splitValue.length - 2];\n\n if (validFormats.includes(newFormat))\n {\n format = newFormat;\n }\n }\n else\n {\n format = splitValue[splitValue.length - 1];\n }\n\n return {\n resolution: parseFloat(Resolver.RETINA_PREFIX.exec(value)?.[1] ?? '1'),\n format,\n src: value,\n };\n }\n} satisfies ResolveURLParser;\n"],"names":[],"mappings":";;;;;AAMO,MAAM,YAAe,GAAA,CAAC,OAAS,EAAA,KAAA,EAAO,MAAQ,EAAA,MAAA,EAAQ,MAAQ,EAAA,KAAA,EAAO,KAAO,EAAA,KAAA,EAAO,KAAO,EAAA,KAAA,EAAO,KAAK,EAAA;AAEtG,MAAM,2BAA8B,GAAA;AAAA,EACvC,WAAW,aAAc,CAAA,aAAA;AAAA,EACzB,IAAA,EAAM,CAAC,KACH,KAAA,cAAA,CAAe,OAAO,CAAC,MAAA,EAAQ,OAAS,EAAA,MAAM,CAAC,CAAA;AAAA,EACnD,KAAA,EAAO,CAAC,KACR,KAAA;AACI,IAAI,IAAA,MAAA,CAAA;AAEJ,IAAM,MAAA,UAAA,GAAa,KAAM,CAAA,KAAA,CAAM,GAAG,CAAA,CAAA;AAElC,IAAI,IAAA,UAAA,CAAW,SAAS,CACxB,EAAA;AACI,MAAA,MAAM,SAAY,GAAA,UAAA,CAAW,UAAW,CAAA,MAAA,GAAS,CAAC,CAAA,CAAA;AAElD,MAAI,IAAA,YAAA,CAAa,QAAS,CAAA,SAAS,CACnC,EAAA;AACI,QAAS,MAAA,GAAA,SAAA,CAAA;AAAA,OACb;AAAA,KAGJ,MAAA;AACI,MAAS,MAAA,GAAA,UAAA,CAAW,UAAW,CAAA,MAAA,GAAS,CAAC,CAAA,CAAA;AAAA,KAC7C;AAEA,IAAO,OAAA;AAAA,MACH,UAAA,EAAY,WAAW,QAAS,CAAA,aAAA,CAAc,KAAK,KAAK,CAAA,GAAI,CAAC,CAAA,IAAK,GAAG,CAAA;AAAA,MACrE,MAAA;AAAA,MACA,GAAK,EAAA,KAAA;AAAA,KACT,CAAA;AAAA,GACJ;AACJ;;;;"}