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,79 @@
import type { BLEND_MODES, CULL_MODES } from './const';
/**
* This is a WebGL state, and is is passed to {@link StateSystem}.
*
* Each mesh rendered may require WebGL to be in a different state.
* For example you may want different blend mode or to enable polygon offsets
* @memberof rendering
*/
export declare class State {
/**
* The data is a unique number based on the states settings.
* This lets us quickly compare states with a single number rather than looking
* at all the individual settings.
*/
data: number;
_blendModeId: number;
private _blendMode;
private _polygonOffset;
constructor();
/**
* Activates blending of the computed fragment color values.
* @default true
*/
get blend(): boolean;
set blend(value: boolean);
/**
* Activates adding an offset to depth values of polygon's fragments
* @default false
*/
get offsets(): boolean;
set offsets(value: boolean);
/** The culling settings for this state none - No culling back - Back face culling front - Front face culling */
set cullMode(value: CULL_MODES);
get cullMode(): CULL_MODES;
/**
* Activates culling of polygons.
* @default false
*/
get culling(): boolean;
set culling(value: boolean);
/**
* Activates depth comparisons and updates to the depth buffer.
* @default false
*/
get depthTest(): boolean;
set depthTest(value: boolean);
/**
* Enables or disables writing to the depth buffer.
* @default true
*/
get depthMask(): boolean;
set depthMask(value: boolean);
/**
* Specifies whether or not front or back-facing polygons can be culled.
* @default false
*/
get clockwiseFrontFace(): boolean;
set clockwiseFrontFace(value: boolean);
/**
* The blend mode to be applied when this state is set. Apply a value of `normal` to reset the blend mode.
* Setting this mode to anything other than NO_BLEND will automatically switch blending on.
* @default 'normal'
*/
get blendMode(): BLEND_MODES;
set blendMode(value: BLEND_MODES);
/**
* The polygon offset. Setting this property to anything other than 0 will automatically enable polygon offset fill.
* @default 0
*/
get polygonOffset(): number;
set polygonOffset(value: number);
toString(): string;
/**
* A quickly getting an instance of a State that is configured for 2d rendering.
* @returns a new State with values set for 2d rendering
*/
static for2d(): State;
static default2d: State;
}

View File

@@ -0,0 +1,160 @@
'use strict';
"use strict";
const blendModeIds = {
normal: 0,
add: 1,
multiply: 2,
screen: 3,
overlay: 4,
erase: 5,
"normal-npm": 6,
"add-npm": 7,
"screen-npm": 8,
min: 9,
max: 10
};
const BLEND = 0;
const OFFSET = 1;
const CULLING = 2;
const DEPTH_TEST = 3;
const WINDING = 4;
const DEPTH_MASK = 5;
const _State = class _State {
constructor() {
this.data = 0;
this.blendMode = "normal";
this.polygonOffset = 0;
this.blend = true;
this.depthMask = true;
}
/**
* Activates blending of the computed fragment color values.
* @default true
*/
get blend() {
return !!(this.data & 1 << BLEND);
}
set blend(value) {
if (!!(this.data & 1 << BLEND) !== value) {
this.data ^= 1 << BLEND;
}
}
/**
* Activates adding an offset to depth values of polygon's fragments
* @default false
*/
get offsets() {
return !!(this.data & 1 << OFFSET);
}
set offsets(value) {
if (!!(this.data & 1 << OFFSET) !== value) {
this.data ^= 1 << OFFSET;
}
}
/** The culling settings for this state none - No culling back - Back face culling front - Front face culling */
set cullMode(value) {
if (value === "none") {
this.culling = false;
return;
}
this.culling = true;
this.clockwiseFrontFace = value === "front";
}
get cullMode() {
if (!this.culling) {
return "none";
}
return this.clockwiseFrontFace ? "front" : "back";
}
/**
* Activates culling of polygons.
* @default false
*/
get culling() {
return !!(this.data & 1 << CULLING);
}
set culling(value) {
if (!!(this.data & 1 << CULLING) !== value) {
this.data ^= 1 << CULLING;
}
}
/**
* Activates depth comparisons and updates to the depth buffer.
* @default false
*/
get depthTest() {
return !!(this.data & 1 << DEPTH_TEST);
}
set depthTest(value) {
if (!!(this.data & 1 << DEPTH_TEST) !== value) {
this.data ^= 1 << DEPTH_TEST;
}
}
/**
* Enables or disables writing to the depth buffer.
* @default true
*/
get depthMask() {
return !!(this.data & 1 << DEPTH_MASK);
}
set depthMask(value) {
if (!!(this.data & 1 << DEPTH_MASK) !== value) {
this.data ^= 1 << DEPTH_MASK;
}
}
/**
* Specifies whether or not front or back-facing polygons can be culled.
* @default false
*/
get clockwiseFrontFace() {
return !!(this.data & 1 << WINDING);
}
set clockwiseFrontFace(value) {
if (!!(this.data & 1 << WINDING) !== value) {
this.data ^= 1 << WINDING;
}
}
/**
* The blend mode to be applied when this state is set. Apply a value of `normal` to reset the blend mode.
* Setting this mode to anything other than NO_BLEND will automatically switch blending on.
* @default 'normal'
*/
get blendMode() {
return this._blendMode;
}
set blendMode(value) {
this.blend = value !== "none";
this._blendMode = value;
this._blendModeId = blendModeIds[value] || 0;
}
/**
* The polygon offset. Setting this property to anything other than 0 will automatically enable polygon offset fill.
* @default 0
*/
get polygonOffset() {
return this._polygonOffset;
}
set polygonOffset(value) {
this.offsets = !!value;
this._polygonOffset = value;
}
toString() {
return `[pixi.js/core:State blendMode=${this.blendMode} clockwiseFrontFace=${this.clockwiseFrontFace} culling=${this.culling} depthMask=${this.depthMask} polygonOffset=${this.polygonOffset}]`;
}
/**
* A quickly getting an instance of a State that is configured for 2d rendering.
* @returns a new State with values set for 2d rendering
*/
static for2d() {
const state = new _State();
state.depthTest = false;
state.blend = true;
return state;
}
};
_State.default2d = _State.for2d();
let State = _State;
exports.State = State;
//# sourceMappingURL=State.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,158 @@
"use strict";
const blendModeIds = {
normal: 0,
add: 1,
multiply: 2,
screen: 3,
overlay: 4,
erase: 5,
"normal-npm": 6,
"add-npm": 7,
"screen-npm": 8,
min: 9,
max: 10
};
const BLEND = 0;
const OFFSET = 1;
const CULLING = 2;
const DEPTH_TEST = 3;
const WINDING = 4;
const DEPTH_MASK = 5;
const _State = class _State {
constructor() {
this.data = 0;
this.blendMode = "normal";
this.polygonOffset = 0;
this.blend = true;
this.depthMask = true;
}
/**
* Activates blending of the computed fragment color values.
* @default true
*/
get blend() {
return !!(this.data & 1 << BLEND);
}
set blend(value) {
if (!!(this.data & 1 << BLEND) !== value) {
this.data ^= 1 << BLEND;
}
}
/**
* Activates adding an offset to depth values of polygon's fragments
* @default false
*/
get offsets() {
return !!(this.data & 1 << OFFSET);
}
set offsets(value) {
if (!!(this.data & 1 << OFFSET) !== value) {
this.data ^= 1 << OFFSET;
}
}
/** The culling settings for this state none - No culling back - Back face culling front - Front face culling */
set cullMode(value) {
if (value === "none") {
this.culling = false;
return;
}
this.culling = true;
this.clockwiseFrontFace = value === "front";
}
get cullMode() {
if (!this.culling) {
return "none";
}
return this.clockwiseFrontFace ? "front" : "back";
}
/**
* Activates culling of polygons.
* @default false
*/
get culling() {
return !!(this.data & 1 << CULLING);
}
set culling(value) {
if (!!(this.data & 1 << CULLING) !== value) {
this.data ^= 1 << CULLING;
}
}
/**
* Activates depth comparisons and updates to the depth buffer.
* @default false
*/
get depthTest() {
return !!(this.data & 1 << DEPTH_TEST);
}
set depthTest(value) {
if (!!(this.data & 1 << DEPTH_TEST) !== value) {
this.data ^= 1 << DEPTH_TEST;
}
}
/**
* Enables or disables writing to the depth buffer.
* @default true
*/
get depthMask() {
return !!(this.data & 1 << DEPTH_MASK);
}
set depthMask(value) {
if (!!(this.data & 1 << DEPTH_MASK) !== value) {
this.data ^= 1 << DEPTH_MASK;
}
}
/**
* Specifies whether or not front or back-facing polygons can be culled.
* @default false
*/
get clockwiseFrontFace() {
return !!(this.data & 1 << WINDING);
}
set clockwiseFrontFace(value) {
if (!!(this.data & 1 << WINDING) !== value) {
this.data ^= 1 << WINDING;
}
}
/**
* The blend mode to be applied when this state is set. Apply a value of `normal` to reset the blend mode.
* Setting this mode to anything other than NO_BLEND will automatically switch blending on.
* @default 'normal'
*/
get blendMode() {
return this._blendMode;
}
set blendMode(value) {
this.blend = value !== "none";
this._blendMode = value;
this._blendModeId = blendModeIds[value] || 0;
}
/**
* The polygon offset. Setting this property to anything other than 0 will automatically enable polygon offset fill.
* @default 0
*/
get polygonOffset() {
return this._polygonOffset;
}
set polygonOffset(value) {
this.offsets = !!value;
this._polygonOffset = value;
}
toString() {
return `[pixi.js/core:State blendMode=${this.blendMode} clockwiseFrontFace=${this.clockwiseFrontFace} culling=${this.culling} depthMask=${this.depthMask} polygonOffset=${this.polygonOffset}]`;
}
/**
* A quickly getting an instance of a State that is configured for 2d rendering.
* @returns a new State with values set for 2d rendering
*/
static for2d() {
const state = new _State();
state.depthTest = false;
state.blend = true;
return state;
}
};
_State.default2d = _State.for2d();
let State = _State;
export { State };
//# sourceMappingURL=State.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,30 @@
/**
* Various blend modes supported by Pixi
* @memberof filters
*/
export type BLEND_MODES = 'inherit' | 'normal' | 'add' | 'multiply' | 'screen' | 'darken' | 'lighten' | 'erase' | 'color-dodge' | 'color-burn' | 'linear-burn' | 'linear-dodge' | 'linear-light' | 'hard-light' | 'soft-light' | 'pin-light' | 'difference' | 'exclusion' | 'overlay' | 'saturation' | 'color' | 'luminosity' | 'normal-npm' | 'add-npm' | 'screen-npm' | 'none' | 'subtract' | 'divide' | 'vivid-light' | 'hard-mix' | 'negation' | 'min' | 'max';
/**
* The map of blend modes supported by Pixi
* @memberof rendering
*/
export declare const BLEND_TO_NPM: {
normal: string;
add: string;
screen: string;
};
/**
* The stencil operation to perform when using the stencil buffer
* @memberof rendering
*/
export declare enum STENCIL_MODES {
DISABLED = 0,
RENDERING_MASK_ADD = 1,
MASK_ACTIVE = 2,
RENDERING_MASK_REMOVE = 3,
NONE = 4
}
/**
* The culling mode to use. It can be either `none`, `front` or `back`.
* @memberof rendering
*/
export type CULL_MODES = 'none' | 'back' | 'front';

View File

@@ -0,0 +1,20 @@
'use strict';
"use strict";
const BLEND_TO_NPM = {
normal: "normal-npm",
add: "add-npm",
screen: "screen-npm"
};
var STENCIL_MODES = /* @__PURE__ */ ((STENCIL_MODES2) => {
STENCIL_MODES2[STENCIL_MODES2["DISABLED"] = 0] = "DISABLED";
STENCIL_MODES2[STENCIL_MODES2["RENDERING_MASK_ADD"] = 1] = "RENDERING_MASK_ADD";
STENCIL_MODES2[STENCIL_MODES2["MASK_ACTIVE"] = 2] = "MASK_ACTIVE";
STENCIL_MODES2[STENCIL_MODES2["RENDERING_MASK_REMOVE"] = 3] = "RENDERING_MASK_REMOVE";
STENCIL_MODES2[STENCIL_MODES2["NONE"] = 4] = "NONE";
return STENCIL_MODES2;
})(STENCIL_MODES || {});
exports.BLEND_TO_NPM = BLEND_TO_NPM;
exports.STENCIL_MODES = STENCIL_MODES;
//# sourceMappingURL=const.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"const.js","sources":["../../../../../src/rendering/renderers/shared/state/const.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/indent */\n/**\n * Various blend modes supported by Pixi\n * @memberof filters\n */\nexport type BLEND_MODES = 'inherit'\n| 'normal'\n| 'add'\n| 'multiply'\n| 'screen'\n| 'darken'\n| 'lighten'\n| 'erase'\n| 'color-dodge'\n| 'color-burn'\n| 'linear-burn'\n| 'linear-dodge'\n| 'linear-light'\n| 'hard-light'\n| 'soft-light'\n| 'pin-light'\n| 'difference'\n| 'exclusion'\n| 'overlay'\n// | 'hue'\n| 'saturation'\n| 'color'\n| 'luminosity'\n| 'normal-npm'\n| 'add-npm'\n| 'screen-npm'\n| 'none'\n| 'subtract'\n| 'divide'\n| 'vivid-light'\n| 'hard-mix'\n| 'negation'\n| 'min'\n| 'max';\n\n/**\n * The map of blend modes supported by Pixi\n * @memberof rendering\n */\nexport const BLEND_TO_NPM = {\n normal: 'normal-npm',\n add: 'add-npm',\n screen: 'screen-npm',\n};\n\n/**\n * The stencil operation to perform when using the stencil buffer\n * @memberof rendering\n */\nexport enum STENCIL_MODES\n{\n DISABLED = 0,\n RENDERING_MASK_ADD = 1,\n MASK_ACTIVE = 2,\n RENDERING_MASK_REMOVE = 3,\n NONE = 4,\n}\n\n/**\n * The culling mode to use. It can be either `none`, `front` or `back`.\n * @memberof rendering\n */\nexport type CULL_MODES = 'none' | 'back' | 'front';\n\n"],"names":["STENCIL_MODES"],"mappings":";;;AA4CO,MAAM,YAAe,GAAA;AAAA,EACxB,MAAQ,EAAA,YAAA;AAAA,EACR,GAAK,EAAA,SAAA;AAAA,EACL,MAAQ,EAAA,YAAA;AACZ,EAAA;AAMY,IAAA,aAAA,qBAAAA,cAAL,KAAA;AAEH,EAAAA,cAAAA,CAAAA,cAAAA,CAAA,cAAW,CAAX,CAAA,GAAA,UAAA,CAAA;AACA,EAAAA,cAAAA,CAAAA,cAAAA,CAAA,wBAAqB,CAArB,CAAA,GAAA,oBAAA,CAAA;AACA,EAAAA,cAAAA,CAAAA,cAAAA,CAAA,iBAAc,CAAd,CAAA,GAAA,aAAA,CAAA;AACA,EAAAA,cAAAA,CAAAA,cAAAA,CAAA,2BAAwB,CAAxB,CAAA,GAAA,uBAAA,CAAA;AACA,EAAAA,cAAAA,CAAAA,cAAAA,CAAA,UAAO,CAAP,CAAA,GAAA,MAAA,CAAA;AANQ,EAAAA,OAAAA,cAAAA,CAAAA;AAAA,CAAA,EAAA,aAAA,IAAA,EAAA;;;;;"}

View File

@@ -0,0 +1,17 @@
"use strict";
const BLEND_TO_NPM = {
normal: "normal-npm",
add: "add-npm",
screen: "screen-npm"
};
var STENCIL_MODES = /* @__PURE__ */ ((STENCIL_MODES2) => {
STENCIL_MODES2[STENCIL_MODES2["DISABLED"] = 0] = "DISABLED";
STENCIL_MODES2[STENCIL_MODES2["RENDERING_MASK_ADD"] = 1] = "RENDERING_MASK_ADD";
STENCIL_MODES2[STENCIL_MODES2["MASK_ACTIVE"] = 2] = "MASK_ACTIVE";
STENCIL_MODES2[STENCIL_MODES2["RENDERING_MASK_REMOVE"] = 3] = "RENDERING_MASK_REMOVE";
STENCIL_MODES2[STENCIL_MODES2["NONE"] = 4] = "NONE";
return STENCIL_MODES2;
})(STENCIL_MODES || {});
export { BLEND_TO_NPM, STENCIL_MODES };
//# sourceMappingURL=const.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"const.mjs","sources":["../../../../../src/rendering/renderers/shared/state/const.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/indent */\n/**\n * Various blend modes supported by Pixi\n * @memberof filters\n */\nexport type BLEND_MODES = 'inherit'\n| 'normal'\n| 'add'\n| 'multiply'\n| 'screen'\n| 'darken'\n| 'lighten'\n| 'erase'\n| 'color-dodge'\n| 'color-burn'\n| 'linear-burn'\n| 'linear-dodge'\n| 'linear-light'\n| 'hard-light'\n| 'soft-light'\n| 'pin-light'\n| 'difference'\n| 'exclusion'\n| 'overlay'\n// | 'hue'\n| 'saturation'\n| 'color'\n| 'luminosity'\n| 'normal-npm'\n| 'add-npm'\n| 'screen-npm'\n| 'none'\n| 'subtract'\n| 'divide'\n| 'vivid-light'\n| 'hard-mix'\n| 'negation'\n| 'min'\n| 'max';\n\n/**\n * The map of blend modes supported by Pixi\n * @memberof rendering\n */\nexport const BLEND_TO_NPM = {\n normal: 'normal-npm',\n add: 'add-npm',\n screen: 'screen-npm',\n};\n\n/**\n * The stencil operation to perform when using the stencil buffer\n * @memberof rendering\n */\nexport enum STENCIL_MODES\n{\n DISABLED = 0,\n RENDERING_MASK_ADD = 1,\n MASK_ACTIVE = 2,\n RENDERING_MASK_REMOVE = 3,\n NONE = 4,\n}\n\n/**\n * The culling mode to use. It can be either `none`, `front` or `back`.\n * @memberof rendering\n */\nexport type CULL_MODES = 'none' | 'back' | 'front';\n\n"],"names":["STENCIL_MODES"],"mappings":";AA4CO,MAAM,YAAe,GAAA;AAAA,EACxB,MAAQ,EAAA,YAAA;AAAA,EACR,GAAK,EAAA,SAAA;AAAA,EACL,MAAQ,EAAA,YAAA;AACZ,EAAA;AAMY,IAAA,aAAA,qBAAAA,cAAL,KAAA;AAEH,EAAAA,cAAAA,CAAAA,cAAAA,CAAA,cAAW,CAAX,CAAA,GAAA,UAAA,CAAA;AACA,EAAAA,cAAAA,CAAAA,cAAAA,CAAA,wBAAqB,CAArB,CAAA,GAAA,oBAAA,CAAA;AACA,EAAAA,cAAAA,CAAAA,cAAAA,CAAA,iBAAc,CAAd,CAAA,GAAA,aAAA,CAAA;AACA,EAAAA,cAAAA,CAAAA,cAAAA,CAAA,2BAAwB,CAAxB,CAAA,GAAA,uBAAA,CAAA;AACA,EAAAA,cAAAA,CAAAA,cAAAA,CAAA,UAAO,CAAP,CAAA,GAAA,MAAA,CAAA;AANQ,EAAAA,OAAAA,cAAAA,CAAAA;AAAA,CAAA,EAAA,aAAA,IAAA,EAAA;;;;"}

View File

@@ -0,0 +1,11 @@
import { type BLEND_MODES } from './const';
import type { TextureSource } from '../texture/sources/TextureSource';
/**
* Adjusts a blend mode for the current alpha mode. Returns the blend mode that works with that format.
* eg 'normal' blend mode will return 'normal-npm' when rendering with premultiplied alpha.
* and 'normal' if the texture is already premultiplied (the default)
* @param blendMode - The blend mode to get the adjusted blend mode for.
* @param textureSource - The texture to test the format of.
* @returns - the blend mode that should be used to render this texture correctly based on its alphaMode
*/
export declare function getAdjustedBlendModeBlend(blendMode: BLEND_MODES, textureSource: TextureSource): BLEND_MODES;

View File

@@ -0,0 +1,14 @@
'use strict';
var _const = require('./const.js');
"use strict";
function getAdjustedBlendModeBlend(blendMode, textureSource) {
if (textureSource.alphaMode === "no-premultiply-alpha") {
return _const.BLEND_TO_NPM[blendMode] || blendMode;
}
return blendMode;
}
exports.getAdjustedBlendModeBlend = getAdjustedBlendModeBlend;
//# sourceMappingURL=getAdjustedBlendModeBlend.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getAdjustedBlendModeBlend.js","sources":["../../../../../src/rendering/renderers/shared/state/getAdjustedBlendModeBlend.ts"],"sourcesContent":["import { type BLEND_MODES, BLEND_TO_NPM } from './const';\n\nimport type { TextureSource } from '../texture/sources/TextureSource';\n\n/**\n * Adjusts a blend mode for the current alpha mode. Returns the blend mode that works with that format.\n * eg 'normal' blend mode will return 'normal-npm' when rendering with premultiplied alpha.\n * and 'normal' if the texture is already premultiplied (the default)\n * @param blendMode - The blend mode to get the adjusted blend mode for.\n * @param textureSource - The texture to test the format of.\n * @returns - the blend mode that should be used to render this texture correctly based on its alphaMode\n */\nexport function getAdjustedBlendModeBlend(blendMode: BLEND_MODES, textureSource: TextureSource): BLEND_MODES\n{\n if (textureSource.alphaMode === 'no-premultiply-alpha')\n {\n return (BLEND_TO_NPM[blendMode as keyof typeof BLEND_TO_NPM] || blendMode) as BLEND_MODES;\n }\n\n return blendMode;\n}\n"],"names":["BLEND_TO_NPM"],"mappings":";;;;;AAYgB,SAAA,yBAAA,CAA0B,WAAwB,aAClE,EAAA;AACI,EAAI,IAAA,aAAA,CAAc,cAAc,sBAChC,EAAA;AACI,IAAQ,OAAAA,mBAAA,CAAa,SAAsC,CAAK,IAAA,SAAA,CAAA;AAAA,GACpE;AAEA,EAAO,OAAA,SAAA,CAAA;AACX;;;;"}

View File

@@ -0,0 +1,12 @@
import { BLEND_TO_NPM } from './const.mjs';
"use strict";
function getAdjustedBlendModeBlend(blendMode, textureSource) {
if (textureSource.alphaMode === "no-premultiply-alpha") {
return BLEND_TO_NPM[blendMode] || blendMode;
}
return blendMode;
}
export { getAdjustedBlendModeBlend };
//# sourceMappingURL=getAdjustedBlendModeBlend.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getAdjustedBlendModeBlend.mjs","sources":["../../../../../src/rendering/renderers/shared/state/getAdjustedBlendModeBlend.ts"],"sourcesContent":["import { type BLEND_MODES, BLEND_TO_NPM } from './const';\n\nimport type { TextureSource } from '../texture/sources/TextureSource';\n\n/**\n * Adjusts a blend mode for the current alpha mode. Returns the blend mode that works with that format.\n * eg 'normal' blend mode will return 'normal-npm' when rendering with premultiplied alpha.\n * and 'normal' if the texture is already premultiplied (the default)\n * @param blendMode - The blend mode to get the adjusted blend mode for.\n * @param textureSource - The texture to test the format of.\n * @returns - the blend mode that should be used to render this texture correctly based on its alphaMode\n */\nexport function getAdjustedBlendModeBlend(blendMode: BLEND_MODES, textureSource: TextureSource): BLEND_MODES\n{\n if (textureSource.alphaMode === 'no-premultiply-alpha')\n {\n return (BLEND_TO_NPM[blendMode as keyof typeof BLEND_TO_NPM] || blendMode) as BLEND_MODES;\n }\n\n return blendMode;\n}\n"],"names":[],"mappings":";;;AAYgB,SAAA,yBAAA,CAA0B,WAAwB,aAClE,EAAA;AACI,EAAI,IAAA,aAAA,CAAc,cAAc,sBAChC,EAAA;AACI,IAAQ,OAAA,YAAA,CAAa,SAAsC,CAAK,IAAA,SAAA,CAAA;AAAA,GACpE;AAEA,EAAO,OAAA,SAAA,CAAA;AACX;;;;"}