diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8607040f17..6e0dc2dcba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: - uses: actions/checkout@v3 - name: Install pnpm uses: pnpm/action-setup@v2 - + - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: @@ -63,6 +63,12 @@ jobs: node-version: 16.x cache: pnpm + - name: Install + run: pnpm install + - name: Build + run: npm run build + - name: Test + run: npm run test-cov - run: pnpm install codecov -w - name: Upload coverage to Codecov run: ./node_modules/.bin/codecov diff --git a/package.json b/package.json index 7c749b10e1..3f45717801 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@galacean/engine-root", "version": "1.0.0", - "packageManager": "pnpm@8.3.1", + "packageManager": "pnpm@8.6.2", "private": true, "scripts": { "preinstall": "npx only-allow pnpm", diff --git a/packages/core/src/2d/atlas/SpriteAtlas.ts b/packages/core/src/2d/atlas/SpriteAtlas.ts index bf2e42da11..44adadbfdd 100644 --- a/packages/core/src/2d/atlas/SpriteAtlas.ts +++ b/packages/core/src/2d/atlas/SpriteAtlas.ts @@ -63,6 +63,8 @@ export class SpriteAtlas extends ReferResource { */ _addSprite(sprite: Sprite): void { this._spriteNamesToIndex[sprite.name] = this._sprites.push(sprite) - 1; + sprite._atlas = this; + sprite.isGCIgnored = true; } /** @@ -70,6 +72,11 @@ export class SpriteAtlas extends ReferResource { */ protected override _onDestroy(): void { super._onDestroy(); + const { _sprites: sprites } = this; + for (let i = 0, n = sprites.length; i < n; i++) { + sprites[i].destroy(); + } + sprites.length = 0; this._sprites = null; this._spriteNamesToIndex = null; } diff --git a/packages/core/src/2d/sprite/Sprite.ts b/packages/core/src/2d/sprite/Sprite.ts index 85cf820992..29d9c285cb 100644 --- a/packages/core/src/2d/sprite/Sprite.ts +++ b/packages/core/src/2d/sprite/Sprite.ts @@ -4,6 +4,7 @@ import { UpdateFlagManager } from "../../UpdateFlagManager"; import { ReferResource } from "../../asset/ReferResource"; import { Texture2D } from "../../texture/Texture2D"; import { SpriteModifyFlags } from "../enums/SpriteModifyFlags"; +import { SpriteAtlas } from "../atlas/SpriteAtlas"; /** * 2D sprite. @@ -32,6 +33,8 @@ export class Sprite extends ReferResource { private _dirtyUpdateFlag: SpriteUpdateFlags = SpriteUpdateFlags.all; + /** @internal */ + _atlas: SpriteAtlas; /** @internal */ _updateFlagManager: UpdateFlagManager = new UpdateFlagManager(); @@ -153,14 +156,7 @@ export class Sprite extends ReferResource { } set region(value: Rect) { - const region = this._region; - const x = MathUtil.clamp(value.x, 0, 1); - const y = MathUtil.clamp(value.y, 0, 1); - region.set(x, y, MathUtil.clamp(value.width, 0, 1 - x), MathUtil.clamp(value.height, 0, 1 - y)); - this._dispatchSpriteChange(SpriteModifyFlags.region); - if (this._customWidth === undefined || this._customHeight === undefined) { - this._dispatchSpriteChange(SpriteModifyFlags.size); - } + this._region !== value && this._region.copyFrom(value); } /** @@ -172,16 +168,7 @@ export class Sprite extends ReferResource { } set pivot(value: Vector2) { - const pivot = this._pivot; - if (pivot === value) { - this._dispatchSpriteChange(SpriteModifyFlags.pivot); - } else { - const { x, y } = value; - if (pivot.x !== x || pivot.y !== y) { - pivot.set(x, y); - this._dispatchSpriteChange(SpriteModifyFlags.pivot); - } - } + this._pivot !== value && this._pivot.copyFrom(value); } /** @@ -196,11 +183,7 @@ export class Sprite extends ReferResource { } set border(value: Vector4) { - const border = this._border; - const x = MathUtil.clamp(value.x, 0, 1); - const y = MathUtil.clamp(value.y, 0, 1); - border.set(x, y, MathUtil.clamp(value.z, 0, 1 - x), MathUtil.clamp(value.w, 0, 1 - y)); - this._dispatchSpriteChange(SpriteModifyFlags.border); + this._border !== value && this._border.copyFrom(value); } /** @@ -222,6 +205,15 @@ export class Sprite extends ReferResource { ) { super(engine); this._texture = texture; + this._onRegionChange = this._onRegionChange.bind(this); + this._onPivotChange = this._onPivotChange.bind(this); + this._onBorderChange = this._onBorderChange.bind(this); + // @ts-ignore + this._region._onValueChanged = this._onRegionChange; + // @ts-ignore + this._pivot._onValueChanged = this._onPivotChange; + // @ts-ignore + this._border._onValueChanged = this._onBorderChange; region && this._region.copyFrom(region); pivot && this._pivot.copyFrom(pivot); border && this._border.copyFrom(border); @@ -264,12 +256,32 @@ export class Sprite extends ReferResource { return this._bounds; } + /** + * @internal + */ + override _addReferCount(value: number): void { + super._addReferCount(value); + this._atlas?._addReferCount(value); + } + /** * @internal */ protected override _onDestroy(): void { super._onDestroy(); + this._positions.length = 0; + this._positions = null; + this._uvs.length = 0; + this._uvs = null; + this._atlasRegion = null; + this._atlasRegionOffset = null; + this._region = null; + this._pivot = null; + this._border = null; + this._bounds = null; + this._atlas = null; this._texture = null; + this._updateFlagManager = null; } private _calDefaultSize(): void { @@ -368,6 +380,37 @@ export class Sprite extends ReferResource { } this._updateFlagManager.dispatch(type); } + + private _onRegionChange(): void { + const { _region: region } = this; + // @ts-ignore + region._onValueChanged = null; + const x = MathUtil.clamp(region.x, 0, 1); + const y = MathUtil.clamp(region.y, 0, 1); + region.set(x, y, MathUtil.clamp(region.width, 0, 1 - x), MathUtil.clamp(region.height, 0, 1 - y)); + this._dispatchSpriteChange(SpriteModifyFlags.region); + if (this._customWidth === undefined || this._customHeight === undefined) { + this._dispatchSpriteChange(SpriteModifyFlags.size); + } + // @ts-ignore + region._onValueChanged = this._onRegionChange; + } + + private _onPivotChange(): void { + this._dispatchSpriteChange(SpriteModifyFlags.pivot); + } + + private _onBorderChange(): void { + const { _border: border } = this; + // @ts-ignore + border._onValueChanged = null; + const x = MathUtil.clamp(border.x, 0, 1); + const y = MathUtil.clamp(border.y, 0, 1); + border.set(x, y, MathUtil.clamp(border.z, 0, 1 - x), MathUtil.clamp(border.w, 0, 1 - y)); + this._dispatchSpriteChange(SpriteModifyFlags.border); + // @ts-ignore + border._onValueChanged = this._onBorderChange; + } } enum SpriteUpdateFlags { diff --git a/packages/core/src/2d/sprite/SpriteMask.ts b/packages/core/src/2d/sprite/SpriteMask.ts index 1a75102337..ba4b60a8b3 100644 --- a/packages/core/src/2d/sprite/SpriteMask.ts +++ b/packages/core/src/2d/sprite/SpriteMask.ts @@ -132,9 +132,13 @@ export class SpriteMask extends Renderer { set sprite(value: Sprite | null) { const lastSprite = this._sprite; if (lastSprite !== value) { - lastSprite && lastSprite._updateFlagManager.removeListener(this._onSpriteChange); + if (lastSprite) { + lastSprite._addReferCount(-1); + lastSprite._updateFlagManager.removeListener(this._onSpriteChange); + } this._dirtyUpdateFlag |= SpriteMaskUpdateFlags.All; if (value) { + value._addReferCount(1); value._updateFlagManager.addListener(this._onSpriteChange); this.shaderData.setTexture(SpriteMask._textureProperty, value.texture); } else { @@ -229,7 +233,12 @@ export class SpriteMask extends Renderer { */ protected override _onDestroy(): void { super._onDestroy(); - this._sprite?._updateFlagManager.removeListener(this._onSpriteChange); + const sprite = this._sprite; + if (sprite) { + sprite._addReferCount(-1); + sprite._updateFlagManager.removeListener(this._onSpriteChange); + } + this._entity = null; this._sprite = null; this._verticesData = null; } diff --git a/packages/core/src/2d/sprite/SpriteRenderer.ts b/packages/core/src/2d/sprite/SpriteRenderer.ts index 16b4678e22..d7c9b3ade0 100644 --- a/packages/core/src/2d/sprite/SpriteRenderer.ts +++ b/packages/core/src/2d/sprite/SpriteRenderer.ts @@ -131,9 +131,13 @@ export class SpriteRenderer extends Renderer { set sprite(value: Sprite | null) { const lastSprite = this._sprite; if (lastSprite !== value) { - lastSprite && lastSprite._updateFlagManager.removeListener(this._onSpriteChange); + if (lastSprite) { + lastSprite._addReferCount(-1); + lastSprite._updateFlagManager.removeListener(this._onSpriteChange); + } this._dirtyUpdateFlag |= SpriteRendererUpdateFlags.All; if (value) { + value._addReferCount(1); value._updateFlagManager.addListener(this._onSpriteChange); this.shaderData.setTexture(SpriteRenderer._textureProperty, value.texture); } else { @@ -329,7 +333,12 @@ export class SpriteRenderer extends Renderer { */ protected override _onDestroy(): void { super._onDestroy(); - this._sprite?._updateFlagManager.removeListener(this._onSpriteChange); + const sprite = this._sprite; + if (sprite) { + sprite._addReferCount(-1); + sprite._updateFlagManager.removeListener(this._onSpriteChange); + } + this._entity = null; this._color = null; this._sprite = null; this._assembler = null; diff --git a/packages/core/src/2d/text/SubFont.ts b/packages/core/src/2d/text/SubFont.ts index 945cadb792..eb3479209a 100644 --- a/packages/core/src/2d/text/SubFont.ts +++ b/packages/core/src/2d/text/SubFont.ts @@ -95,6 +95,7 @@ export class SubFont { const fontAtlas = new FontAtlas(engine); const texture = new Texture2D(engine, 256, 256); fontAtlas.texture = texture; + fontAtlas.isGCIgnored = texture.isGCIgnored = true; this._fontAtlases.push(fontAtlas); const nativeFontString = this.nativeFontString; diff --git a/packages/core/src/2d/text/TextRenderer.ts b/packages/core/src/2d/text/TextRenderer.ts index 08eca15e93..fe9ad202ec 100644 --- a/packages/core/src/2d/text/TextRenderer.ts +++ b/packages/core/src/2d/text/TextRenderer.ts @@ -480,97 +480,102 @@ export class TextRenderer extends Renderer { } private _updateLocalData(): void { - const { color, horizontalAlignment, verticalAlignment, _charRenderDatas: charRenderDatas } = this; + const { color, _charRenderDatas: charRenderDatas, _subFont: charFont } = this; const { min, max } = this._localBounds; - const { _pixelsPerUnit } = Engine; - const pixelsPerUnitReciprocal = 1.0 / _pixelsPerUnit; - const charFont = this._subFont; - const rendererWidth = this.width * _pixelsPerUnit; - const halfRendererWidth = rendererWidth * 0.5; - const rendererHeight = this.height * _pixelsPerUnit; - const textMetrics = this.enableWrapping ? TextUtils.measureTextWithWrap(this) : TextUtils.measureTextWithoutWrap(this); const { height, lines, lineWidths, lineHeight, lineMaxSizes } = textMetrics; const charRenderDataPool = TextRenderer._charRenderDataPool; - const halfLineHeight = lineHeight * 0.5; const linesLen = lines.length; + let renderDataCount = 0; - let startY = 0; - const topDiff = lineHeight * 0.5 - lineMaxSizes[0].ascent; - const bottomDiff = lineHeight * 0.5 - lineMaxSizes[linesLen - 1].descent - 1; - switch (verticalAlignment) { - case TextVerticalAlignment.Top: - startY = rendererHeight * 0.5 - halfLineHeight + topDiff; - break; - case TextVerticalAlignment.Center: - startY = height * 0.5 - halfLineHeight - (bottomDiff - topDiff) * 0.5; - break; - case TextVerticalAlignment.Bottom: - startY = height - rendererHeight * 0.5 - halfLineHeight - bottomDiff; - break; - } + if (linesLen > 0) { + const { _pixelsPerUnit } = Engine; + const { horizontalAlignment } = this; + const pixelsPerUnitReciprocal = 1.0 / _pixelsPerUnit; + const rendererWidth = this.width * _pixelsPerUnit; + const halfRendererWidth = rendererWidth * 0.5; + const rendererHeight = this.height * _pixelsPerUnit; + const halfLineHeight = lineHeight * 0.5; + + let startY = 0; + const topDiff = lineHeight * 0.5 - lineMaxSizes[0].ascent; + const bottomDiff = lineHeight * 0.5 - lineMaxSizes[linesLen - 1].descent - 1; + switch (this.verticalAlignment) { + case TextVerticalAlignment.Top: + startY = rendererHeight * 0.5 - halfLineHeight + topDiff; + break; + case TextVerticalAlignment.Center: + startY = height * 0.5 - halfLineHeight - (bottomDiff - topDiff) * 0.5; + break; + case TextVerticalAlignment.Bottom: + startY = height - rendererHeight * 0.5 - halfLineHeight - bottomDiff; + break; + } - let renderDataCount = 0; - let firstLine = -1; - let minX = Number.MAX_SAFE_INTEGER; - let minY = Number.MAX_SAFE_INTEGER; - let maxX = Number.MIN_SAFE_INTEGER; - let maxY = Number.MIN_SAFE_INTEGER; - for (let i = 0; i < linesLen; ++i) { - const lineWidth = lineWidths[i]; - if (lineWidth > 0) { - const line = lines[i]; - let startX = 0; - let firstRow = -1; - if (firstLine < 0) { - firstLine = i; - } - switch (horizontalAlignment) { - case TextHorizontalAlignment.Left: - startX = -halfRendererWidth; - break; - case TextHorizontalAlignment.Center: - startX = -lineWidth * 0.5; - break; - case TextHorizontalAlignment.Right: - startX = halfRendererWidth - lineWidth; - break; - } - for (let j = 0, n = line.length; j < n; ++j) { - const char = line[j]; - const charInfo = charFont._getCharInfo(char); - if (charInfo.h > 0) { - firstRow < 0 && (firstRow = j); - const charRenderData = (charRenderDatas[renderDataCount++] ||= charRenderDataPool.get()); - const { renderData, localPositions } = charRenderData; - charRenderData.texture = charFont._getTextureByIndex(charInfo.index); - renderData.color = color; - renderData.uvs = charInfo.uvs; - - const { w, ascent, descent } = charInfo; - const left = startX * pixelsPerUnitReciprocal; - const right = (startX + w) * pixelsPerUnitReciprocal; - const top = (startY + ascent) * pixelsPerUnitReciprocal; - const bottom = (startY - descent + 1) * pixelsPerUnitReciprocal; - localPositions.set(left, top, right, bottom); - i === firstLine && (maxY = Math.max(maxY, top)); - minY = Math.min(minY, bottom); - j === firstRow && (minX = Math.min(minX, left)); - maxX = Math.max(maxX, right); + let firstLine = -1; + let minX = Number.MAX_SAFE_INTEGER; + let minY = Number.MAX_SAFE_INTEGER; + let maxX = Number.MIN_SAFE_INTEGER; + let maxY = Number.MIN_SAFE_INTEGER; + for (let i = 0; i < linesLen; ++i) { + const lineWidth = lineWidths[i]; + if (lineWidth > 0) { + const line = lines[i]; + let startX = 0; + let firstRow = -1; + if (firstLine < 0) { + firstLine = i; + } + switch (horizontalAlignment) { + case TextHorizontalAlignment.Left: + startX = -halfRendererWidth; + break; + case TextHorizontalAlignment.Center: + startX = -lineWidth * 0.5; + break; + case TextHorizontalAlignment.Right: + startX = halfRendererWidth - lineWidth; + break; + } + for (let j = 0, n = line.length; j < n; ++j) { + const char = line[j]; + const charInfo = charFont._getCharInfo(char); + if (charInfo.h > 0) { + firstRow < 0 && (firstRow = j); + const charRenderData = (charRenderDatas[renderDataCount++] ||= charRenderDataPool.get()); + const { renderData, localPositions } = charRenderData; + charRenderData.texture = charFont._getTextureByIndex(charInfo.index); + renderData.color = color; + renderData.uvs = charInfo.uvs; + + const { w, ascent, descent } = charInfo; + const left = startX * pixelsPerUnitReciprocal; + const right = (startX + w) * pixelsPerUnitReciprocal; + const top = (startY + ascent) * pixelsPerUnitReciprocal; + const bottom = (startY - descent + 1) * pixelsPerUnitReciprocal; + localPositions.set(left, top, right, bottom); + i === firstLine && (maxY = Math.max(maxY, top)); + minY = Math.min(minY, bottom); + j === firstRow && (minX = Math.min(minX, left)); + maxX = Math.max(maxX, right); + } + startX += charInfo.xAdvance; } - startX += charInfo.xAdvance; } + startY -= lineHeight; } - startY -= lineHeight; - } - if (firstLine < 0) { + if (firstLine < 0) { + min.set(0, 0, 0); + max.set(0, 0, 0); + } else { + min.set(minX, minY, 0); + max.set(maxX, maxY, 0); + } + } else { min.set(0, 0, 0); max.set(0, 0, 0); - } else { - min.set(minX, minY, 0); - max.set(maxX, maxY, 0); } // Revert excess render data to pool. diff --git a/packages/core/src/2d/text/TextUtils.ts b/packages/core/src/2d/text/TextUtils.ts index 3b5e21e55b..e22fa890e8 100644 --- a/packages/core/src/2d/text/TextUtils.ts +++ b/packages/core/src/2d/text/TextUtils.ts @@ -110,6 +110,11 @@ export class TextUtils { subFont.nativeFontString = fontString; for (let i = 0, n = subTexts.length; i < n; i++) { const subText = subTexts[i]; + // If subText is empty, push an empty line directly + if (subText.length === 0) { + this._pushLine(lines, lineWidths, lineMaxSizes, "", 0, 0, 0); + continue; + } let word = ""; let wordWidth = 0; @@ -144,7 +149,11 @@ export class TextUtils { // If it is a word before, need to handle the previous word and line if (word.length > 0) { if (lineWidth + wordWidth > wrapWidth) { - this._pushLine(lines, lineWidths, lineMaxSizes, line, lineWidth, lineMaxAscent, lineMaxDescent); + // Push if before line is not empty + if (lineWidth > 0) { + this._pushLine(lines, lineWidths, lineMaxSizes, line, lineWidth, lineMaxAscent, lineMaxDescent); + } + textWidth = Math.max(textWidth, lineWidth); notFirstLine = true; line = word; @@ -191,7 +200,12 @@ export class TextUtils { line = ""; lineWidth = lineMaxAscent = lineMaxDescent = 0; } - this._pushLine(lines, lineWidths, lineMaxSizes, word, wordWidth, wordMaxAscent, wordMaxDescent); + + // Push if before word is not empty + if (wordWidth > 0) { + this._pushLine(lines, lineWidths, lineMaxSizes, word, wordWidth, wordMaxAscent, wordMaxDescent); + } + textWidth = Math.max(textWidth, wordWidth); notFirstLine = true; word = char; @@ -211,12 +225,16 @@ export class TextUtils { // If the total width from line and word exceed wrap width if (lineWidth + wordWidth > wrapWidth) { // Push chars to a single line - this._pushLine(lines, lineWidths, lineMaxSizes, line, lineWidth, lineMaxAscent, lineMaxDescent); + if (lineWidth > 0) { + this._pushLine(lines, lineWidths, lineMaxSizes, line, lineWidth, lineMaxAscent, lineMaxDescent); + } textWidth = Math.max(textWidth, lineWidth); lineWidth = 0; // Push word to a single line - this._pushLine(lines, lineWidths, lineMaxSizes, word, wordWidth, wordMaxAscent, wordMaxDescent); + if (wordWidth > 0) { + this._pushLine(lines, lineWidths, lineMaxSizes, word, wordWidth, wordMaxAscent, wordMaxDescent); + } textWidth = Math.max(textWidth, wordWidth); } else { // Merge to chars @@ -252,25 +270,21 @@ export class TextUtils { const { _subFont: subFont } = renderer; const fontString = subFont.nativeFontString; const fontSizeInfo = TextUtils.measureFont(fontString); - const lines = renderer.text.split(/(?:\r\n|\r|\n)/); - const lineCount = lines.length; + const subTexts = renderer.text.split(/(?:\r\n|\r|\n)/); + const textCount = subTexts.length; + const lines = new Array(); const lineWidths = new Array(); const lineMaxSizes = new Array(); const { _pixelsPerUnit } = Engine; const lineHeight = fontSizeInfo.size + renderer.lineSpacing * _pixelsPerUnit; let width = 0; - let height = renderer.height * _pixelsPerUnit; - if (renderer.overflowMode === OverflowMode.Overflow) { - height = lineHeight * lineCount; - } - subFont.nativeFontString = fontString; - for (let i = 0; i < lineCount; ++i) { - const line = lines[i]; + for (let i = 0; i < textCount; ++i) { + const line = subTexts[i]; let curWidth = 0; - let maxAscent = -1; - let maxDescent = -1; + let maxAscent = 0; + let maxDescent = 0; for (let j = 0, m = line.length; j < m; ++j) { const charInfo = TextUtils._getCharInfo(line[j], fontString, subFont); @@ -282,17 +296,18 @@ export class TextUtils { maxAscent < ascent && (maxAscent = ascent); maxDescent < descent && (maxDescent = descent); } - lineWidths[i] = curWidth; - lineMaxSizes[i] = { - ascent: maxAscent, - descent: maxDescent, - size: maxAscent + maxDescent - }; - if (curWidth > width) { - width = curWidth; + + if (curWidth > 0) { + this._pushLine(lines, lineWidths, lineMaxSizes, line, curWidth, maxAscent, maxDescent); + width = Math.max(width, curWidth); } } + let height = renderer.height * _pixelsPerUnit; + if (renderer.overflowMode === OverflowMode.Overflow) { + height = lineHeight * lines.length; + } + return { width, height, diff --git a/packages/core/src/Background.ts b/packages/core/src/Background.ts index 817c268f59..de3c44f403 100644 --- a/packages/core/src/Background.ts +++ b/packages/core/src/Background.ts @@ -48,6 +48,8 @@ export class Background { set texture(value: Texture2D) { if (this._texture !== value) { + value?._addReferCount(1); + this._texture?._addReferCount(-1); this._texture = value; this._engine._backgroundTextureMaterial.shaderData.setTexture("material_BaseTexture", value); } @@ -70,6 +72,17 @@ export class Background { } } + /** + * @internal + */ + destroy(): void { + this._mesh._addReferCount(-1); + this._mesh = null; + this.texture = null; + this.solidColor = null; + this.sky.destroy(); + } + /** * Constructor of Background. * @param _engine Engine Which the background belongs to. @@ -84,6 +97,7 @@ export class Background { */ _initMesh(engine): void { this._mesh = this._createPlane(engine); + this._mesh._addReferCount(1); } /** diff --git a/packages/core/src/Camera.ts b/packages/core/src/Camera.ts index 6a48cff828..37e92c8a67 100644 --- a/packages/core/src/Camera.ts +++ b/packages/core/src/Camera.ts @@ -36,9 +36,6 @@ export class Camera extends Component { /** @internal */ private static _cameraPositionProperty = ShaderProperty.getByName("camera_Position"); - /** Shader data. */ - readonly shaderData: ShaderData = new ShaderData(ShaderDataGroup.Camera); - /** Whether to enable frustum culling, it is enabled by default. */ enableFrustumCulling: boolean = true; @@ -71,6 +68,7 @@ export class Camera extends Component { _replacementSubShaderTag: ShaderTagKey = null; private _priority: number = 0; + private _shaderData: ShaderData = new ShaderData(ShaderDataGroup.Camera); private _isProjMatSetting = false; private _nearClipPlane: number = 0.1; private _farClipPlane: number = 100; @@ -99,6 +97,13 @@ export class Camera extends Component { @deepClone private _invViewProjMat: Matrix = new Matrix(); + /** + * Shader data. + */ + get shaderData(): ShaderData { + return this._shaderData; + } + /** * Near clip plane - the closest point to the camera when rendering occurs. */ @@ -282,7 +287,11 @@ export class Camera extends Component { } set renderTarget(value: RenderTarget | null) { - this._renderTarget = value; + if (this._renderTarget !== value) { + value?._addReferCount(1); + this._renderTarget?._addReferCount(-1); + this._renderTarget = value; + } } /** @@ -550,6 +559,21 @@ export class Camera extends Component { this._isInvViewProjDirty.destroy(); this._isViewMatrixDirty.destroy(); this.shaderData._addReferCount(-1); + + this._entity = null; + this._globalShaderMacro = null; + this._frustum = null; + this._renderPipeline = null; + this._virtualCamera = null; + this._shaderData = null; + this._frustumViewChangeFlag = null; + this._transform = null; + this._isViewMatrixDirty = null; + this._isInvViewProjDirty = null; + this._viewport = null; + this._inverseProjectionMatrix = null; + this._lastAspectSize = null; + this._invViewProjMat = null; } private _projMatChange(): void { diff --git a/packages/core/src/ComponentsManager.ts b/packages/core/src/ComponentsManager.ts index b1bd601ef6..4dc9edf643 100644 --- a/packages/core/src/ComponentsManager.ts +++ b/packages/core/src/ComponentsManager.ts @@ -228,4 +228,17 @@ export class ComponentsManager { componentContainer.length = 0; this._componentsContainerPool.push(componentContainer); } + + /** + * @internal + */ + _gc() { + this._renderers.garbageCollection(); + this._onStartScripts.garbageCollection(); + this._onUpdateScripts.garbageCollection(); + this._onLateUpdateScripts.garbageCollection(); + this._onPhysicsUpdateScripts.garbageCollection(); + this._onUpdateAnimations.garbageCollection(); + this._onUpdateRenderers.garbageCollection(); + } } diff --git a/packages/core/src/DisorderedArray.ts b/packages/core/src/DisorderedArray.ts index 9fba79af52..62cf6ff340 100644 --- a/packages/core/src/DisorderedArray.ts +++ b/packages/core/src/DisorderedArray.ts @@ -11,17 +11,27 @@ export class DisorderedArray { } add(element: T): void { - if (this.length === this._elements.length) this._elements.push(element); - else this._elements[this.length] = element; + if (this.length === this._elements.length) { + this._elements.push(element); + } else { + this._elements[this.length] = element; + } this.length++; } delete(element: T): void { - //TODO: It can be optimized for custom binary search and other algorithms, currently this._elements>=this.length wastes performance. + // @todo: It can be optimized for custom binary search and other algorithms, currently this._elements>=this.length wastes performance. const index = this._elements.indexOf(element); this.deleteByIndex(index); } + set(index: number, element: T): void { + if (index >= this.length) { + throw "Index is out of range."; + } + this._elements[index] = element; + } + get(index: number): T { if (index >= this.length) { throw "Index is out of range."; @@ -30,9 +40,9 @@ export class DisorderedArray { } /** - * - * @param index - * @returns The replaced item is used to reset its index. + * Delete the element at the specified index. + * @param index - The index of the element to be deleted + * @returns The replaced item is used to reset its index */ deleteByIndex(index: number): T { var elements: T[] = this._elements; diff --git a/packages/core/src/Engine.ts b/packages/core/src/Engine.ts index 5451dd8c90..7856646a04 100644 --- a/packages/core/src/Engine.ts +++ b/packages/core/src/Engine.ts @@ -130,6 +130,7 @@ export class Engine extends EventDispatcher { private _frameInProcess: boolean = false; private _waitingDestroy: boolean = false; private _isDeviceLost: boolean = false; + private _waitingGC: boolean = false; private _animate = () => { if (this._vSyncCount) { @@ -232,7 +233,7 @@ export class Engine extends EventDispatcher { this._spriteDefaultMaterial = this._createSpriteMaterial(); this._spriteMaskDefaultMaterial = this._createSpriteMaskMaterial(); this._textDefaultFont = Font.createFromOS(this, "Arial"); - this._textDefaultFont.isGCIgnored = false; + this._textDefaultFont.isGCIgnored = true; this.inputManager = new InputManager(this); @@ -247,6 +248,7 @@ export class Engine extends EventDispatcher { } const magentaMaterial = new Material(this, Shader.find("unlit")); + magentaMaterial.isGCIgnored = true; magentaMaterial.shaderData.setColor("material_BaseColor", new Color(1.0, 0.0, 1.01, 1.0)); this._magentaMaterial = magentaMaterial; @@ -370,6 +372,10 @@ export class Engine extends EventDispatcher { if (this._waitingDestroy) { this._destroy(); } + if (this._waitingGC) { + this._gc(); + this._waitingGC = false; + } this._frameInProcess = false; } @@ -560,6 +566,17 @@ export class Engine extends EventDispatcher { } } + /** + * @internal + */ + _pendingGC() { + if (this._frameInProcess) { + this._waitingGC = true; + } else { + this._gc(); + } + } + /** * @internal */ @@ -647,6 +664,14 @@ export class Engine extends EventDispatcher { }); } + private _gc(): void { + this._renderElementPool.garbageCollection(); + this._meshRenderDataPool.garbageCollection(); + this._spriteRenderDataPool.garbageCollection(); + this._spriteMaskRenderDataPool.garbageCollection(); + this._textRenderDataPool.garbageCollection(); + } + /** * @deprecated * The first scene physics manager. diff --git a/packages/core/src/Entity.ts b/packages/core/src/Entity.ts index 8458f01986..f953cfea2c 100644 --- a/packages/core/src/Entity.ts +++ b/packages/core/src/Entity.ts @@ -9,6 +9,7 @@ import { Scene } from "./Scene"; import { Script } from "./Script"; import { Transform } from "./Transform"; import { EngineObject } from "./base"; +import { ReferResource } from "./asset/ReferResource"; import { ComponentCloner } from "./clone/ComponentCloner"; import { ActiveChangeFlag } from "./enums/ActiveChangeFlag"; @@ -66,6 +67,8 @@ export class Entity extends EngineObject { _isActive: boolean = true; /** @internal */ _siblingIndex: number = -1; + /** @internal @todo: temporary solution */ + _hookResource: ReferResource; private _parent: Entity = null; private _activeChangedComponents: Component[]; @@ -394,6 +397,12 @@ export class Entity extends EngineObject { private _createCloneEntity(srcEntity: Entity): Entity { const cloneEntity = new Entity(srcEntity._engine, srcEntity.name); + const { _hookResource: hookResource } = this; + if (hookResource) { + cloneEntity._hookResource = hookResource; + hookResource._addReferCount(1); + } + cloneEntity.layer = srcEntity.layer; cloneEntity._isActive = srcEntity._isActive; cloneEntity.transform.localMatrix = srcEntity.transform.localMatrix; @@ -430,6 +439,10 @@ export class Entity extends EngineObject { } super.destroy(); + if (this._hookResource) { + this._hookResource._addReferCount(-1); + this._hookResource = null; + } const components = this._components; for (let i = components.length - 1; i >= 0; i--) { components[i].destroy(); diff --git a/packages/core/src/RenderPipeline/Basic2DBatcher.ts b/packages/core/src/RenderPipeline/Basic2DBatcher.ts index 581326a96c..36a8d68248 100644 --- a/packages/core/src/RenderPipeline/Basic2DBatcher.ts +++ b/packages/core/src/RenderPipeline/Basic2DBatcher.ts @@ -140,26 +140,28 @@ export abstract class Basic2DBatcher { private _createMesh(engine: Engine, index: number): BufferMesh { const { MAX_VERTEX_COUNT } = Basic2DBatcher; const mesh = new BufferMesh(engine, `BufferMesh${index}`); - + mesh.isGCIgnored = true; const vertexElements: VertexElement[] = []; const vertexStride = this.createVertexElements(vertexElements); // vertices - this._vertexBuffers[index] = new Buffer( + const vertexBuffer = (this._vertexBuffers[index] = new Buffer( engine, BufferBindFlag.VertexBuffer, - MAX_VERTEX_COUNT * 4 * vertexStride, + MAX_VERTEX_COUNT * vertexStride, BufferUsage.Dynamic - ); + )); + vertexBuffer.isGCIgnored = true; // indices - this._indiceBuffers[index] = new Buffer( + const indiceBuffer = (this._indiceBuffers[index] = new Buffer( engine, BufferBindFlag.IndexBuffer, - MAX_VERTEX_COUNT * 2 * 3, + MAX_VERTEX_COUNT * 6, BufferUsage.Dynamic - ); - mesh.setVertexBufferBinding(this._vertexBuffers[index], vertexStride); - mesh.setIndexBufferBinding(this._indiceBuffers[index], IndexFormat.UInt16); + )); + indiceBuffer.isGCIgnored = true; + mesh.setVertexBufferBinding(vertexBuffer, vertexStride); + mesh.setIndexBufferBinding(indiceBuffer, IndexFormat.UInt16); mesh.setVertexElements(vertexElements); return mesh; diff --git a/packages/core/src/RenderPipeline/ClassPool.ts b/packages/core/src/RenderPipeline/ClassPool.ts index de4fda8b01..98e17cde2c 100644 --- a/packages/core/src/RenderPipeline/ClassPool.ts +++ b/packages/core/src/RenderPipeline/ClassPool.ts @@ -1,7 +1,9 @@ +import { IPoolElement } from "./IPoolElement"; + /** * Class pool utils. */ -export class ClassPool { +export class ClassPool { private _elementPoolIndex: number = 0; private _elementPool: T[] = []; private _type: new () => T; @@ -31,4 +33,11 @@ export class ClassPool { resetPool(): void { this._elementPoolIndex = 0; } + + garbageCollection(): void { + const { _elementPool: pool } = this; + for (let i = pool.length - 1; i >= 0; i--) { + pool[i].dispose && pool[i].dispose(); + } + } } diff --git a/packages/core/src/RenderPipeline/IPoolElement.ts b/packages/core/src/RenderPipeline/IPoolElement.ts new file mode 100644 index 0000000000..547ba01e4d --- /dev/null +++ b/packages/core/src/RenderPipeline/IPoolElement.ts @@ -0,0 +1,3 @@ +export interface IPoolElement { + dispose?(): void; +} diff --git a/packages/core/src/RenderPipeline/MeshRenderData.ts b/packages/core/src/RenderPipeline/MeshRenderData.ts index 7737428f08..cfc41cd32c 100644 --- a/packages/core/src/RenderPipeline/MeshRenderData.ts +++ b/packages/core/src/RenderPipeline/MeshRenderData.ts @@ -2,12 +2,13 @@ import { Mesh } from "../graphic/Mesh"; import { SubMesh } from "../graphic/SubMesh"; import { Material } from "../material/Material"; import { Renderer } from "../Renderer"; +import { IPoolElement } from "./IPoolElement"; import { RenderData } from "./RenderData"; /** * Render element. */ -export class MeshRenderData extends RenderData { +export class MeshRenderData extends RenderData implements IPoolElement { /** Mesh. */ mesh: Mesh; /** Sub mesh. */ @@ -20,4 +21,8 @@ export class MeshRenderData extends RenderData { this.mesh = mesh; this.subMesh = subMesh; } + + dispose(): void { + this.component = this.material = this.mesh = this.subMesh = null; + } } diff --git a/packages/core/src/RenderPipeline/RenderElement.ts b/packages/core/src/RenderPipeline/RenderElement.ts index 4af61ab184..b10f1b1724 100644 --- a/packages/core/src/RenderPipeline/RenderElement.ts +++ b/packages/core/src/RenderPipeline/RenderElement.ts @@ -1,8 +1,9 @@ import { ShaderPass } from "../shader/ShaderPass"; import { RenderState } from "../shader/state/RenderState"; +import { IPoolElement } from "./IPoolElement"; import { RenderData } from "./RenderData"; -export class RenderElement { +export class RenderElement implements IPoolElement { data: RenderData; shaderPass: ShaderPass; renderState: RenderState; @@ -12,4 +13,8 @@ export class RenderElement { this.shaderPass = shaderPass; this.renderState = renderState; } + + dispose(): void { + this.data = this.shaderPass = this.renderState = null; + } } diff --git a/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts b/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts index fb01c2ff50..d07d62cef6 100644 --- a/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts +++ b/packages/core/src/RenderPipeline/SpriteMaskRenderData.ts @@ -1,9 +1,10 @@ import { VertexData2D } from "../2d/data/VertexData2D"; import { Material } from "../material/Material"; import { Renderer } from "../Renderer"; +import { IPoolElement } from "./IPoolElement"; import { RenderData } from "./RenderData"; -export class SpriteMaskRenderData extends RenderData { +export class SpriteMaskRenderData extends RenderData implements IPoolElement { isAdd: boolean = true; verticesData: VertexData2D; @@ -17,4 +18,8 @@ export class SpriteMaskRenderData extends RenderData { this.material = material; this.verticesData = verticesData; } + + dispose(): void { + this.component = this.material = this.verticesData = null; + } } diff --git a/packages/core/src/RenderPipeline/SpriteRenderData.ts b/packages/core/src/RenderPipeline/SpriteRenderData.ts index 50f3541285..2cd8984bb3 100644 --- a/packages/core/src/RenderPipeline/SpriteRenderData.ts +++ b/packages/core/src/RenderPipeline/SpriteRenderData.ts @@ -2,9 +2,10 @@ import { VertexData2D } from "../2d/data/VertexData2D"; import { Material } from "../material/Material"; import { Renderer } from "../Renderer"; import { Texture2D } from "../texture"; +import { IPoolElement } from "./IPoolElement"; import { RenderData } from "./RenderData"; -export class SpriteRenderData extends RenderData { +export class SpriteRenderData extends RenderData implements IPoolElement { verticesData: VertexData2D; texture: Texture2D; dataIndex: number; // Add for CanvasRenderer plugin. @@ -28,4 +29,8 @@ export class SpriteRenderData extends RenderData { this.texture = texture; this.dataIndex = dataIndex; } + + dispose(): void { + this.component = this.material = this.verticesData = this.texture = null; + } } diff --git a/packages/core/src/RenderPipeline/TextRenderData.ts b/packages/core/src/RenderPipeline/TextRenderData.ts index 1bb74d8fc7..c02fcfec2f 100644 --- a/packages/core/src/RenderPipeline/TextRenderData.ts +++ b/packages/core/src/RenderPipeline/TextRenderData.ts @@ -1,11 +1,17 @@ +import { IPoolElement } from "./IPoolElement"; import { RenderData } from "./RenderData"; import { SpriteRenderData } from "./SpriteRenderData"; -export class TextRenderData extends RenderData { +export class TextRenderData extends RenderData implements IPoolElement { charsData: SpriteRenderData[] = []; constructor() { super(); this.multiRenderData = true; } + + dispose(): void { + this.component = this.material = null; + this.charsData.length = 0; + } } diff --git a/packages/core/src/Renderer.ts b/packages/core/src/Renderer.ts index c7233ab1b4..4a5e1ea9a6 100644 --- a/packages/core/src/Renderer.ts +++ b/packages/core/src/Renderer.ts @@ -30,10 +30,6 @@ export class Renderer extends Component implements ICustomClone { private static _normalMatrixProperty = ShaderProperty.getByName("renderer_NormalMat"); private static _rendererLayerProperty = ShaderProperty.getByName("renderer_Layer"); - /** ShaderData related to renderer. */ - @deepClone - readonly shaderData: ShaderData = new ShaderData(ShaderDataGroup.Renderer); - /** @internal */ @ignoreClone _distanceForSort: number; @@ -59,6 +55,8 @@ export class Renderer extends Component implements ICustomClone { @ignoreClone protected _dirtyUpdateFlag: number = 0; + @deepClone + private _shaderData: ShaderData = new ShaderData(ShaderDataGroup.Renderer); @ignoreClone private _mvMatrix: Matrix = new Matrix(); @ignoreClone @@ -77,6 +75,13 @@ export class Renderer extends Component implements ICustomClone { @ignoreClone protected _rendererLayer: Vector4 = new Vector4(); + /** + * ShaderData related to renderer. + */ + get shaderData(): ShaderData { + return this._shaderData; + } + /** * Whether it is culled in the current frame and does not participate in rendering. */ @@ -352,6 +357,18 @@ export class Renderer extends Component implements ICustomClone { for (let i = 0, n = materials.length; i < n; i++) { materials[i]?._addReferCount(-1); } + + this._entity = null; + this._globalShaderMacro = null; + this._bounds = null; + this._materials = null; + this._shaderData = null; + this._mvMatrix = null; + this._mvpMatrix = null; + this._mvInvMatrix = null; + this._normalMatrix = null; + this._materialsInstanced = null; + this._rendererLayer = null; } /** diff --git a/packages/core/src/Scene.ts b/packages/core/src/Scene.ts index b8bac9477f..c05dc1ee59 100644 --- a/packages/core/src/Scene.ts +++ b/packages/core/src/Scene.ts @@ -33,10 +33,6 @@ export class Scene extends EngineObject { /** Physics. */ readonly physics: PhysicsScene = new PhysicsScene(this); - /** The background of the scene. */ - readonly background: Background = new Background(this._engine); - /** Scene-related shader data. */ - readonly shaderData: ShaderData = new ShaderData(ShaderDataGroup.Scene); /** If cast shadows. */ castShadows: boolean = true; @@ -66,6 +62,8 @@ export class Scene extends EngineObject { /** @internal */ _sunLight: Light; + private _background: Background = new Background(this._engine); + private _shaderData: ShaderData = new ShaderData(ShaderDataGroup.Scene); private _shadowCascades: ShadowCascadesMode = ShadowCascadesMode.NoCascades; private _ambientLight: AmbientLight; private _fogMode: FogMode = FogMode.None; @@ -75,6 +73,20 @@ export class Scene extends EngineObject { private _fogDensity: number = 0.01; private _fogParams: Vector4 = new Vector4(); + /** + * Scene-related shader data. + */ + get shaderData(): ShaderData { + return this._shaderData; + } + + /** + * The background of the scene. + */ + get background(): Background { + return this._background; + } + /** * Number of cascades to use for directional light shadows. */ @@ -209,7 +221,7 @@ export class Scene extends EngineObject { const shaderData = this.shaderData; shaderData._addReferCount(1); - this.ambientLight = new AmbientLight(); + this.ambientLight = new AmbientLight(engine); engine.sceneManager._allCreatedScenes.push(this); shaderData.enableMacro("SCENE_FOG_MODE", this._fogMode.toString()); @@ -417,13 +429,16 @@ export class Scene extends EngineObject { engine.time._updateSceneShaderData(shaderData); lightManager._updateShaderData(this.shaderData); + lightManager._updateSunLightIndex(); + + if (lightManager._directLights.length > 0) { + const sunlight = lightManager._directLights.get(0); - const sunLightIndex = lightManager._getSunLightIndex(); - if (sunLightIndex !== -1) { - const sunlight = lightManager._directLights.get(sunLightIndex); shaderData.setColor(Scene._sunlightColorProperty, sunlight._getLightIntensityColor()); shaderData.setVector3(Scene._sunlightDirectionProperty, sunlight.direction); this._sunLight = sunlight; + } else { + this._sunLight = null; } if (this.castShadows && this._sunLight && this._sunLight.shadowType !== ShadowType.None) { @@ -467,6 +482,8 @@ export class Scene extends EngineObject { this._rootEntities[0].destroy(); } this._activeCameras.length = 0; + this.background.destroy(); + this._ambientLight && this._ambientLight._removeFromScene(this); this.shaderData._addReferCount(-1); this._componentsManager.handlingInvalidScripts(); diff --git a/packages/core/src/Utils.ts b/packages/core/src/Utils.ts index 41eb543b13..d9d853c870 100644 --- a/packages/core/src/Utils.ts +++ b/packages/core/src/Utils.ts @@ -124,12 +124,7 @@ export class Utils { return relativeUrl; } - const char0 = relativeUrl.charAt(0); - if (char0 === ".") { - return Utils._formatRelativePath(relativeUrl + relativeUrl); - } - - return baseUrl.substring(0, baseUrl.lastIndexOf("/") + 1) + relativeUrl; + return baseUrl.substring(0, baseUrl.lastIndexOf("/") + 1) + this._formatRelativePath(relativeUrl); } private static _stringToPath(string): string[] { @@ -149,15 +144,17 @@ export class Utils { return result; } - private static _formatRelativePath(value: string): string { - const parts = value.split("/"); - for (let i = 0, n = parts.length; i < n; i++) { - if (parts[i] == "..") { - parts.splice(i - 1, 2); - i -= 2; - } - } - return parts.join("/"); + private static _formatRelativePath(path: string): string { + // For example input is "a/b", "/a/b", "./a/b", "./a/./b", "./a/../a/b", output is "a/b" + return path + .split("/") + .filter(Boolean) + .reduce((acc, cur) => { + if (cur === "..") acc.pop(); + else if (cur !== ".") acc.push(cur); + return acc; + }, []) + .join("/"); } } diff --git a/packages/core/src/animation/AnimationClip.ts b/packages/core/src/animation/AnimationClip.ts index 28f37d84e5..efde87f435 100644 --- a/packages/core/src/animation/AnimationClip.ts +++ b/packages/core/src/animation/AnimationClip.ts @@ -123,7 +123,8 @@ export class AnimationClip extends EngineObject { const targetEntity = entity.findByPath(curveData.relativePath); if (targetEntity) { const curveOwner = curveData._getTempCurveOwner(targetEntity); - curveOwner.evaluateAndApplyValue(curveData.curve, time, 1, false); + const value = curveOwner.evaluateValue(curveData.curve, time, false); + curveOwner.applyValue(value, 1, false); } } } diff --git a/packages/core/src/animation/AnimationClipCurveBinding.ts b/packages/core/src/animation/AnimationClipCurveBinding.ts index 6dfa8341c6..605c79a3fd 100644 --- a/packages/core/src/animation/AnimationClipCurveBinding.ts +++ b/packages/core/src/animation/AnimationClipCurveBinding.ts @@ -31,6 +31,7 @@ export class AnimationClipCurveBinding { const curveType = (this.curve.constructor) as IAnimationCurveCalculator; const owner = new AnimationCurveOwner(entity, this.type, this.property, curveType); curveType._initializeOwner(owner); + owner.saveDefaultValue(); return owner; } @@ -38,8 +39,12 @@ export class AnimationClipCurveBinding { * @internal */ _createCurveLayerOwner(owner: AnimationCurveOwner): AnimationCurveLayerOwner { + const curveType = (this.curve.constructor) as IAnimationCurveCalculator; const layerOwner = new AnimationCurveLayerOwner(); layerOwner.curveOwner = owner; + curveType._initializeLayerOwner(layerOwner); + // If curve.keys.length is 0, updateFinishedState will assign 0 to the target, causing an error, so initialize by assigning defaultValue to finalValue. + layerOwner.initFinalValue(); return layerOwner; } diff --git a/packages/core/src/animation/Animator.ts b/packages/core/src/animation/Animator.ts index da28677f38..651bafed19 100644 --- a/packages/core/src/animation/Animator.ts +++ b/packages/core/src/animation/Animator.ts @@ -3,6 +3,8 @@ import { Component } from "../Component"; import { Entity } from "../Entity"; import { ClassPool } from "../RenderPipeline/ClassPool"; import { Renderer } from "../Renderer"; +import { Script } from "../Script"; +import { Logger } from "../base/Logger"; import { assignmentClone, ignoreClone } from "../clone/CloneManager"; import { AnimatorController } from "./AnimatorController"; import { AnimatorState } from "./AnimatorState"; @@ -33,6 +35,8 @@ export class Animator extends Component { @ignoreClone protected _controllerUpdateFlag: BoolUpdateFlag; + @ignoreClone + protected _updateMark: number = 0; @ignoreClone private _animatorLayersData: AnimatorLayerData[] = []; @@ -82,20 +86,20 @@ export class Animator extends Component { } const stateInfo = this._getAnimatorStateInfo(stateName, layerIndex); - const { state } = stateInfo; + const { state, layerIndex: playLayerIndex } = stateInfo; if (!state) { return; } if (!state.clip) { - console.warn(`The state named ${stateName} has no AnimationClip data.`); + Logger.warn(`The state named ${stateName} has no AnimationClip data.`); return; } - const animatorLayerData = this._getAnimatorLayerData(stateInfo.layerIndex); - const animatorStateData = this._getAnimatorStateData(stateName, state, animatorLayerData); + const animatorLayerData = this._getAnimatorLayerData(playLayerIndex); + const animatorStateData = this._getAnimatorStateData(stateName, state, animatorLayerData, playLayerIndex); - this._preparePlay(animatorLayerData, state, animatorStateData); + this._preparePlay(animatorLayerData, state); animatorLayerData.layerState = LayerState.Playing; animatorLayerData.srcPlayData.reset(state, animatorStateData, state._getDuration() * normalizedTimeOffset); @@ -118,8 +122,8 @@ export class Animator extends Component { this._reset(); } - const { state } = this._getAnimatorStateInfo(stateName, layerIndex); - const { manuallyTransition } = this._getAnimatorLayerData(layerIndex); + const { state, layerIndex: playLayerIndex } = this._getAnimatorStateInfo(stateName, layerIndex); + const { manuallyTransition } = this._getAnimatorLayerData(playLayerIndex); manuallyTransition.duration = normalizedTransitionDuration; manuallyTransition.offset = normalizedTimeOffset; manuallyTransition.destinationState = state; @@ -155,6 +159,9 @@ export class Animator extends Component { } deltaTime *= this.speed; + + this._updateMark++; + for (let i = 0, n = animatorController.layers.length; i < n; i++) { const animatorLayerData = this._getAnimatorLayerData(i); if (animatorLayerData.layerState === LayerState.Standby) { @@ -212,7 +219,7 @@ export class Animator extends Component { const propertyOwners = animationCurveOwners[instanceId]; for (let property in propertyOwners) { const owner = propertyOwners[property]; - owner.hasSavedDefaultValue && owner.revertDefaultValue(); + owner.revertDefaultValue(); } } @@ -247,24 +254,18 @@ export class Animator extends Component { return stateInfo; } - private _saveDefaultValues(stateData: AnimatorStateData): void { - const { curveLayerOwner } = stateData; - for (let i = curveLayerOwner.length - 1; i >= 0; i--) { - curveLayerOwner[i]?.curveOwner.saveDefaultValue(); - } - } - private _getAnimatorStateData( stateName: string, animatorState: AnimatorState, - animatorLayerData: AnimatorLayerData + animatorLayerData: AnimatorLayerData, + layerIndex: number ): AnimatorStateData { const { animatorStateDataMap } = animatorLayerData; let animatorStateData = animatorStateDataMap[stateName]; if (!animatorStateData) { animatorStateData = new AnimatorStateData(); animatorStateDataMap[stateName] = animatorStateData; - this._saveAnimatorStateData(animatorState, animatorStateData, animatorLayerData); + this._saveAnimatorStateData(animatorState, animatorStateData, animatorLayerData, layerIndex); this._saveAnimatorEventHandlers(animatorState, animatorStateData); } return animatorStateData; @@ -273,13 +274,15 @@ export class Animator extends Component { private _saveAnimatorStateData( animatorState: AnimatorState, animatorStateData: AnimatorStateData, - animatorLayerData: AnimatorLayerData + animatorLayerData: AnimatorLayerData, + layerIndex: number ): void { const { entity, _curveOwnerPool: curveOwnerPool } = this; const { curveLayerOwner } = animatorStateData; - const { curveOwnerPool: layerCurveOwnerPool } = animatorLayerData; const { _curveBindings: curves } = animatorState.clip; + const { curveOwnerPool: layerCurveOwnerPool } = animatorLayerData; + for (let i = curves.length - 1; i >= 0; i--) { const curve = curves[i]; const targetEntity = curve.relativePath === "" ? entity : entity.findByPath(curve.relativePath); @@ -298,14 +301,15 @@ export class Animator extends Component { curveLayerOwner[i] = layerOwner; } else { curveLayerOwner[i] = null; - console.warn(`The entity don\'t have the child entity which path is ${curve.relativePath}.`); + Logger.warn(`The entity don\'t have the child entity which path is ${curve.relativePath}.`); } } } private _saveAnimatorEventHandlers(state: AnimatorState, animatorStateData: AnimatorStateData): void { const eventHandlerPool = this._animationEventHandlerPool; - const scripts = this._entity._scripts; + const scripts = []; + this._entity.getComponents(Script, scripts); const scriptCount = scripts.length; const { eventHandlers } = animatorStateData; const { events } = state.clip; @@ -320,7 +324,7 @@ export class Animator extends Component { eventHandler.event = event; handlers.length = 0; for (let j = scriptCount - 1; j >= 0; j--) { - const handler = scripts.get(j)[funcName]; + const handler = scripts[j][funcName]; handler && handlers.push(handler); } eventHandlers.push(eventHandler); @@ -329,7 +333,7 @@ export class Animator extends Component { private _clearCrossData(animatorLayerData: AnimatorLayerData): void { animatorLayerData.crossCurveMark++; - animatorLayerData.crossOwnerLayerDataCollection.length = 0; + animatorLayerData.crossLayerOwnerCollection.length = 0; } private _addCrossOwner( @@ -340,7 +344,7 @@ export class Animator extends Component { ): void { layerOwner.crossSrcCurveIndex = curCurveIndex; layerOwner.crossDestCurveIndex = nextCurveIndex; - animatorLayerData.crossOwnerLayerDataCollection.push(layerOwner); + animatorLayerData.crossLayerOwnerCollection.push(layerOwner); } private _prepareCrossFading(animatorLayerData: AnimatorLayerData): void { @@ -358,11 +362,11 @@ export class Animator extends Component { } private _prepareFixedPoseCrossFading(animatorLayerData: AnimatorLayerData): void { - const { crossOwnerLayerDataCollection } = animatorLayerData; + const { crossLayerOwnerCollection } = animatorLayerData; // Save current cross curve data owner fixed pose. - for (let i = crossOwnerLayerDataCollection.length - 1; i >= 0; i--) { - const layerOwner = crossOwnerLayerDataCollection[i]; + for (let i = crossLayerOwnerCollection.length - 1; i >= 0; i--) { + const layerOwner = crossLayerOwnerCollection[i]; if (!layerOwner) continue; layerOwner.curveOwner.saveFixedPoseValue(); // Reset destCurveIndex When fixed pose crossFading again. @@ -392,7 +396,6 @@ export class Animator extends Component { layerOwner.crossDestCurveIndex = i; } else { const owner = layerOwner.curveOwner; - owner.saveDefaultValue(); saveFixed && owner.saveFixedPoseValue(); layerOwner.crossCurveMark = animatorLayerData.crossCurveMark; this._addCrossOwner(animatorLayerData, layerOwner, -1, i); @@ -412,7 +415,7 @@ export class Animator extends Component { const { srcPlayData, destPlayData, crossFadeTransition: crossFadeTransitionInfo } = layerData; const additive = blendingMode === AnimatorLayerBlendingMode.Additive; firstLayer && (weight = 1.0); - //TODO: 任意情况都应该检查,后面要优化 + //@todo: All situations should be checked, optimizations will follow later. layerData.layerState !== LayerState.FixedCrossFading && this._checkTransition(srcPlayData, crossFadeTransitionInfo, layerIndex); @@ -426,6 +429,9 @@ export class Animator extends Component { case LayerState.CrossFading: this._updateCrossFade(srcPlayData, destPlayData, layerData, layerIndex, weight, deltaTime, additive, aniUpdate); break; + case LayerState.Finished: + this._updateFinishedState(srcPlayData, weight, additive, aniUpdate); + break; } } @@ -444,23 +450,35 @@ export class Animator extends Component { playData.update(this.speed < 0); - if (!aniUpdate) { - return; - } - const { clipTime, playState } = playData; - eventHandlers.length && this._fireAnimationEvents(playData, eventHandlers, lastClipTime, clipTime); + const finished = playState === AnimatorStatePlayState.Finished; - for (let i = curveBindings.length - 1; i >= 0; i--) { - curveLayerOwner[i]?.curveOwner.evaluateAndApplyValue(curveBindings[i].curve, clipTime, weight, additive); + if (aniUpdate || finished) { + for (let i = curveBindings.length - 1; i >= 0; i--) { + const layerOwner = curveLayerOwner[i]; + const owner = layerOwner?.curveOwner; + + if (!owner) continue; + + const curve = curveBindings[i].curve; + if (curve.keys.length) { + this._checkRevertOwner(owner, additive); + + const value = owner.evaluateValue(curve, clipTime, additive); + aniUpdate && owner.applyValue(value, weight, additive); + finished && layerOwner.saveFinalValue(); + } + } } playData.frameTime += state.speed * delta; if (playState === AnimatorStatePlayState.Finished) { - layerData.layerState = LayerState.Standby; + layerData.layerState = LayerState.Finished; } + eventHandlers.length && this._fireAnimationEvents(playData, eventHandlers, lastClipTime, clipTime); + if (lastPlayState === AnimatorStatePlayState.UnStarted) { this._callAnimatorScriptOnEnter(state, layerIndex); } @@ -481,7 +499,7 @@ export class Animator extends Component { additive: boolean, aniUpdate: boolean ) { - const { crossOwnerLayerDataCollection } = layerData; + const { crossLayerOwnerCollection } = layerData; const { _curveBindings: srcCurves } = srcPlayData.state.clip; const { state: srcState, stateData: srcStateData, playState: lastSrcPlayState } = srcPlayData; const { eventHandlers: srcEventHandlers } = srcStateData; @@ -491,24 +509,43 @@ export class Animator extends Component { const { clipTime: lastSrcClipTime } = srcPlayData; const { clipTime: lastDestClipTime } = destPlayData; - let crossWeight = - Math.abs(destPlayData.frameTime) / (destState._getDuration() * layerData.crossFadeTransition.duration); - crossWeight >= 1.0 && (crossWeight = 1.0); + const duration = destState._getDuration() * layerData.crossFadeTransition.duration; + let crossWeight = Math.abs(destPlayData.frameTime) / duration; + (crossWeight >= 1.0 || duration === 0) && (crossWeight = 1.0); srcPlayData.update(this.speed < 0); destPlayData.update(this.speed < 0); - const { playState: srcPlayState } = srcPlayData; - const { playState: destPlayState } = destPlayData; + const { clipTime: srcClipTime, playState: srcPlayState } = srcPlayData; + const { clipTime: destClipTime, playState: destPlayState } = destPlayData; + const finished = destPlayData.playState === AnimatorStatePlayState.Finished; - this._updateCrossFadeData(layerData, crossWeight, delta, false); + if (aniUpdate || finished) { + for (let i = crossLayerOwnerCollection.length - 1; i >= 0; i--) { + const layerOwner = crossLayerOwnerCollection[i]; + const owner = layerOwner?.curveOwner; - if (!aniUpdate) { - return; + if (!owner) continue; + + const srcCurveIndex = layerOwner.crossSrcCurveIndex; + const destCurveIndex = layerOwner.crossDestCurveIndex; + + this._checkRevertOwner(owner, additive); + + const value = owner.evaluateCrossFadeValue( + srcCurveIndex >= 0 ? srcCurves[srcCurveIndex].curve : null, + destCurveIndex >= 0 ? destCurves[destCurveIndex].curve : null, + srcClipTime, + destClipTime, + crossWeight, + additive + ); + aniUpdate && owner.applyValue(value, weight, additive); + finished && layerOwner.saveFinalValue(); + } } - const { clipTime: srcClipTime } = srcPlayData; - const { clipTime: destClipTime } = destPlayData; + this._updateCrossFadeData(layerData, crossWeight, delta, false); srcEventHandlers.length && this._fireAnimationEvents(srcPlayData, srcEventHandlers, lastSrcClipTime, srcClipTime); destEventHandlers.length && @@ -531,44 +568,26 @@ export class Animator extends Component { } else { this._callAnimatorScriptOnUpdate(destState, layerIndex); } - - for (let i = crossOwnerLayerDataCollection.length - 1; i >= 0; i--) { - const layerOwner = crossOwnerLayerDataCollection[i]; - - if (!layerOwner) continue; - - const srcCurveIndex = layerOwner.crossSrcCurveIndex; - const destCurveIndex = layerOwner.crossDestCurveIndex; - layerOwner.curveOwner.crossFadeAndApplyValue( - srcCurveIndex >= 0 ? srcCurves[srcCurveIndex].curve : null, - destCurveIndex >= 0 ? destCurves[destCurveIndex].curve : null, - srcClipTime, - destClipTime, - crossWeight, - weight, - additive - ); - } } private _updateCrossFadeFromPose( destPlayData: AnimatorStatePlayData, layerData: AnimatorLayerData, layerIndex: number, - layerWeight: number, + weight: number, delta: number, additive: boolean, aniUpdate: boolean ) { - const { crossOwnerLayerDataCollection } = layerData; + const { crossLayerOwnerCollection } = layerData; const { state, stateData, playState: lastPlayState } = destPlayData; const { eventHandlers } = stateData; const { _curveBindings: curveBindings } = state.clip; const { clipTime: lastDestClipTime } = destPlayData; - let crossWeight = - Math.abs(destPlayData.frameTime) / (state._getDuration() * layerData.crossFadeTransition.duration); - crossWeight >= 1.0 && (crossWeight = 1.0); + const duration = state._getDuration() * layerData.crossFadeTransition.duration; + let crossWeight = Math.abs(destPlayData.frameTime) / duration; + (crossWeight >= 1.0 || duration === 0) && (crossWeight = 1.0); destPlayData.update(this.speed < 0); @@ -576,12 +595,33 @@ export class Animator extends Component { this._updateCrossFadeData(layerData, crossWeight, delta, true); - if (!aniUpdate) { - return; + const { clipTime: destClipTime } = destPlayData; + const finished = playState === AnimatorStatePlayState.Finished; + + // When the animator is culled (aniUpdate=false), if the play state has finished, the final value needs to be calculated and saved to be applied directly. + if (aniUpdate || finished) { + for (let i = crossLayerOwnerCollection.length - 1; i >= 0; i--) { + const layerOwner = crossLayerOwnerCollection[i]; + const owner = layerOwner?.curveOwner; + + if (!owner) continue; + + const curveIndex = layerOwner.crossDestCurveIndex; + + this._checkRevertOwner(owner, additive); + + const value = layerOwner.curveOwner.crossFadeFromPoseAndApplyValue( + curveIndex >= 0 ? curveBindings[curveIndex].curve : null, + destClipTime, + crossWeight, + additive + ); + aniUpdate && owner.applyValue(value, weight, additive); + finished && layerOwner.saveFinalValue(); + } } - const { clipTime: destClipTime } = destPlayData; - //TODO: srcState 少了最新一段时间的判断 + //@todo: srcState is missing the judgment of the most recent period." eventHandlers.length && this._fireAnimationEvents(destPlayData, eventHandlers, lastDestClipTime, destClipTime); if (lastPlayState === AnimatorStatePlayState.UnStarted) { @@ -592,20 +632,30 @@ export class Animator extends Component { } else { this._callAnimatorScriptOnUpdate(state, layerIndex); } + } + + private _updateFinishedState( + playData: AnimatorStatePlayData, + weight: number, + additive: boolean, + aniUpdate: boolean + ): void { + if (!aniUpdate) { + return; + } - for (let i = crossOwnerLayerDataCollection.length - 1; i >= 0; i--) { - const layerOwner = crossOwnerLayerDataCollection[i]; + const { curveLayerOwner } = playData.stateData; + const { _curveBindings: curveBindings } = playData.state.clip; - if (!layerOwner) continue; + for (let i = curveBindings.length - 1; i >= 0; i--) { + const layerOwner = curveLayerOwner[i]; + const owner = layerOwner?.curveOwner; + + if (!owner) continue; - const curveIndex = layerOwner.crossDestCurveIndex; - layerOwner.curveOwner.crossFadeFromPoseAndApplyValue( - curveIndex >= 0 ? curveBindings[curveIndex].curve : null, - destClipTime, - crossWeight, - layerWeight, - additive - ); + this._checkRevertOwner(owner, additive); + + owner.applyValue(layerOwner.finalValue, weight, additive); } } @@ -614,7 +664,7 @@ export class Animator extends Component { destPlayData.frameTime += destPlayData.state.speed * delta; if (crossWeight === 1.0) { if (destPlayData.playState === AnimatorStatePlayState.Finished) { - layerData.layerState = LayerState.Standby; + layerData.layerState = LayerState.Finished; } else { layerData.layerState = LayerState.Playing; } @@ -625,25 +675,21 @@ export class Animator extends Component { } } - private _preparePlay(layerData: AnimatorLayerData, playState: AnimatorState, playStateData: AnimatorStateData): void { + private _preparePlay(layerData: AnimatorLayerData, playState: AnimatorState): void { if (layerData.layerState === LayerState.Playing) { const srcPlayData = layerData.srcPlayData; if (srcPlayData.state !== playState) { const { curveLayerOwner } = srcPlayData.stateData; for (let i = curveLayerOwner.length - 1; i >= 0; i--) { - const owner = curveLayerOwner[i]?.curveOwner; - owner?.hasSavedDefaultValue && owner.revertDefaultValue(); + curveLayerOwner[i]?.curveOwner.revertDefaultValue(); } - this._saveDefaultValues(playStateData); } } else { - // layerState is CrossFading, FixedCrossFading, Standby - const { crossOwnerLayerDataCollection } = layerData; - for (let i = crossOwnerLayerDataCollection.length - 1; i >= 0; i--) { - const owner = crossOwnerLayerDataCollection[i].curveOwner; - owner.hasSavedDefaultValue && owner.revertDefaultValue(); + // layerState is CrossFading, FixedCrossFading, Standby, Finished + const { crossLayerOwnerCollection } = layerData; + for (let i = crossLayerOwnerCollection.length - 1; i >= 0; i--) { + crossLayerOwnerCollection[i].curveOwner.revertDefaultValue(); } - this._saveDefaultValues(playStateData); } } @@ -666,27 +712,27 @@ export class Animator extends Component { private _crossFadeByTransition(transition: AnimatorStateTransition, layerIndex: number): void { const { name } = transition.destinationState; const stateInfo = this._getAnimatorStateInfo(name, layerIndex); - const { state: crossState } = stateInfo; + const { state: crossState, layerIndex: playLayerIndex } = stateInfo; if (!crossState) { return; } if (!crossState.clip) { - console.warn(`The state named ${name} has no AnimationClip data.`); + Logger.warn(`The state named ${name} has no AnimationClip data.`); return; } - const animatorLayerData = this._getAnimatorLayerData(stateInfo.layerIndex); + const animatorLayerData = this._getAnimatorLayerData(playLayerIndex); const layerState = animatorLayerData.layerState; const { destPlayData } = animatorLayerData; - const animatorStateData = this._getAnimatorStateData(name, crossState, animatorLayerData); + const animatorStateData = this._getAnimatorStateData(name, crossState, animatorLayerData, playLayerIndex); const duration = crossState._getDuration(); const offset = duration * transition.offset; destPlayData.reset(crossState, animatorStateData, offset); switch (layerState) { - // Maybe not play, maybe end. case LayerState.Standby: + case LayerState.Finished: animatorLayerData.layerState = LayerState.FixedCrossFading; this._clearCrossData(animatorLayerData); this._prepareStandbyCrossFading(animatorLayerData); @@ -820,6 +866,13 @@ export class Animator extends Component { } } } + + private _checkRevertOwner(owner: AnimationCurveOwner, additive: boolean): void { + if (additive && owner.updateMark !== this._updateMark) { + owner.revertDefaultValue(); + } + owner.updateMark = this._updateMark; + } } interface IAnimatorStateInfo { diff --git a/packages/core/src/animation/animationCurve/AnimationArrayCurve.ts b/packages/core/src/animation/animationCurve/AnimationArrayCurve.ts index f5092d1e39..b573373744 100644 --- a/packages/core/src/animation/animationCurve/AnimationArrayCurve.ts +++ b/packages/core/src/animation/animationCurve/AnimationArrayCurve.ts @@ -1,4 +1,5 @@ import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement"; +import { AnimationCurveLayerOwner } from "../internal/AnimationCurveLayerOwner"; import { AnimationCurveOwner } from "../internal/animationCurveOwner/AnimationCurveOwner"; import { Keyframe } from "../Keyframe"; import { AnimationCurve } from "./AnimationCurve"; @@ -24,6 +25,13 @@ export class AnimationArrayCurve extends AnimationCurve { owner.crossEvaluateData.value = []; } + /** + * @internal + */ + static _initializeLayerOwner(owner: AnimationCurveLayerOwner): void { + owner.finalValue = []; + } + /** * @internal */ diff --git a/packages/core/src/animation/animationCurve/AnimationBoolCurve.ts b/packages/core/src/animation/animationCurve/AnimationBoolCurve.ts index 4cf4f5db05..27a470f53a 100644 --- a/packages/core/src/animation/animationCurve/AnimationBoolCurve.ts +++ b/packages/core/src/animation/animationCurve/AnimationBoolCurve.ts @@ -1,4 +1,5 @@ import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement"; +import { AnimationCurveLayerOwner } from "../internal/AnimationCurveLayerOwner"; import { AnimationCurveOwner } from "../internal/animationCurveOwner/AnimationCurveOwner"; import { Keyframe } from "../Keyframe"; import { AnimationCurve } from "./AnimationCurve"; @@ -23,6 +24,14 @@ export class AnimationBoolCurve extends AnimationCurve { owner.baseEvaluateData.value = false; owner.crossEvaluateData.value = false; } + + /** + * @internal + */ + static _initializeLayerOwner(owner: AnimationCurveLayerOwner): void { + owner.finalValue = false; + } + /** * @internal */ diff --git a/packages/core/src/animation/animationCurve/AnimationColorCurve.ts b/packages/core/src/animation/animationCurve/AnimationColorCurve.ts index 90410fefb5..72a5c177fc 100644 --- a/packages/core/src/animation/animationCurve/AnimationColorCurve.ts +++ b/packages/core/src/animation/animationCurve/AnimationColorCurve.ts @@ -1,5 +1,6 @@ import { Color } from "@galacean/engine-math"; import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement"; +import { AnimationCurveLayerOwner } from "../internal/AnimationCurveLayerOwner"; import { AnimationCurveOwner } from "../internal/animationCurveOwner/AnimationCurveOwner"; import { Keyframe } from "../Keyframe"; import { AnimationCurve } from "./AnimationCurve"; @@ -25,6 +26,13 @@ export class AnimationColorCurve extends AnimationCurve { owner.crossEvaluateData.value = new Color(); } + /** + * @internal + */ + static _initializeLayerOwner(owner: AnimationCurveLayerOwner): void { + owner.finalValue = new Color(); + } + /** * @internal */ diff --git a/packages/core/src/animation/animationCurve/AnimationCurve.ts b/packages/core/src/animation/animationCurve/AnimationCurve.ts index 320aa56be3..f664a1bb3b 100644 --- a/packages/core/src/animation/animationCurve/AnimationCurve.ts +++ b/packages/core/src/animation/animationCurve/AnimationCurve.ts @@ -146,6 +146,9 @@ export abstract class AnimationCurve { break; } } + + evaluateData.value = value; + return value; } diff --git a/packages/core/src/animation/animationCurve/AnimationFloatArrayCurve.ts b/packages/core/src/animation/animationCurve/AnimationFloatArrayCurve.ts index 1300ef185e..7ee7b8c785 100644 --- a/packages/core/src/animation/animationCurve/AnimationFloatArrayCurve.ts +++ b/packages/core/src/animation/animationCurve/AnimationFloatArrayCurve.ts @@ -1,4 +1,5 @@ import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement"; +import { AnimationCurveLayerOwner } from "../internal/AnimationCurveLayerOwner"; import { AnimationCurveOwner } from "../internal/animationCurveOwner/AnimationCurveOwner"; import { Keyframe } from "../Keyframe"; import { AnimationCurve } from "./AnimationCurve"; @@ -25,6 +26,14 @@ export class AnimationFloatArrayCurve extends AnimationCurve { owner.crossEvaluateData.value = new Float32Array(size); } + /** + * @internal + */ + static _initializeLayerOwner(owner: AnimationCurveLayerOwner): void { + const size = (owner.curveOwner.referenceTargetValue).length; + owner.finalValue = new Float32Array(size); + } + /** * @internal */ diff --git a/packages/core/src/animation/animationCurve/AnimationFloatCurve.ts b/packages/core/src/animation/animationCurve/AnimationFloatCurve.ts index 7d8e66b7b8..0461d87e00 100644 --- a/packages/core/src/animation/animationCurve/AnimationFloatCurve.ts +++ b/packages/core/src/animation/animationCurve/AnimationFloatCurve.ts @@ -1,4 +1,5 @@ import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement"; +import { AnimationCurveLayerOwner } from "../internal/AnimationCurveLayerOwner"; import { AnimationCurveOwner } from "../internal/animationCurveOwner/AnimationCurveOwner"; import { Keyframe } from "../Keyframe"; import { AnimationCurve } from "./AnimationCurve"; @@ -24,6 +25,13 @@ export class AnimationFloatCurve extends AnimationCurve { owner.crossEvaluateData.value = 0; } + /** + * @internal + */ + static _initializeLayerOwner(owner: AnimationCurveLayerOwner): void { + owner.finalValue = 0; + } + /** * @internal */ diff --git a/packages/core/src/animation/animationCurve/AnimationQuaternionCurve.ts b/packages/core/src/animation/animationCurve/AnimationQuaternionCurve.ts index 8848e65b08..ed579bf9d3 100644 --- a/packages/core/src/animation/animationCurve/AnimationQuaternionCurve.ts +++ b/packages/core/src/animation/animationCurve/AnimationQuaternionCurve.ts @@ -1,5 +1,6 @@ import { Quaternion } from "@galacean/engine-math"; import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement"; +import { AnimationCurveLayerOwner } from "../internal/AnimationCurveLayerOwner"; import { AnimationCurveOwner } from "../internal/animationCurveOwner/AnimationCurveOwner"; import { Keyframe } from "../Keyframe"; import { AnimationCurve } from "./AnimationCurve"; @@ -28,6 +29,13 @@ export class AnimationQuaternionCurve extends AnimationCurve { owner.crossEvaluateData.value = new Quaternion(); } + /** + * @internal + */ + static _initializeLayerOwner(owner: AnimationCurveLayerOwner): void { + owner.finalValue = new Quaternion(); + } + /** * @internal */ diff --git a/packages/core/src/animation/animationCurve/AnimationVector2Curve.ts b/packages/core/src/animation/animationCurve/AnimationVector2Curve.ts index 49e344b33d..eb51dda7ff 100644 --- a/packages/core/src/animation/animationCurve/AnimationVector2Curve.ts +++ b/packages/core/src/animation/animationCurve/AnimationVector2Curve.ts @@ -1,5 +1,6 @@ import { Vector2 } from "@galacean/engine-math"; import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement"; +import { AnimationCurveLayerOwner } from "../internal/AnimationCurveLayerOwner"; import { AnimationCurveOwner } from "../internal/animationCurveOwner/AnimationCurveOwner"; import { Keyframe } from "../Keyframe"; import { AnimationCurve } from "./AnimationCurve"; @@ -25,6 +26,13 @@ export class AnimationVector2Curve extends AnimationCurve { owner.crossEvaluateData.value = new Vector2(); } + /** + * @internal + */ + static _initializeLayerOwner(owner: AnimationCurveLayerOwner): void { + owner.finalValue = new Vector2(); + } + /** * @internal */ diff --git a/packages/core/src/animation/animationCurve/AnimationVector3Curve.ts b/packages/core/src/animation/animationCurve/AnimationVector3Curve.ts index 77d43ae70e..e1f3eb3f57 100644 --- a/packages/core/src/animation/animationCurve/AnimationVector3Curve.ts +++ b/packages/core/src/animation/animationCurve/AnimationVector3Curve.ts @@ -1,5 +1,6 @@ import { Vector3 } from "@galacean/engine-math"; import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement"; +import { AnimationCurveLayerOwner } from "../internal/AnimationCurveLayerOwner"; import { AnimationCurveOwner } from "../internal/animationCurveOwner/AnimationCurveOwner"; import { Keyframe } from "../Keyframe"; import { AnimationCurve } from "./AnimationCurve"; @@ -25,6 +26,13 @@ export class AnimationVector3Curve extends AnimationCurve { owner.crossEvaluateData.value = new Vector3(); } + /** + * @internal + */ + static _initializeLayerOwner(owner: AnimationCurveLayerOwner): void { + owner.finalValue = new Vector3(); + } + /** * @internal */ diff --git a/packages/core/src/animation/animationCurve/AnimationVector4Curve.ts b/packages/core/src/animation/animationCurve/AnimationVector4Curve.ts index 94f7159bfd..e1f70e916d 100644 --- a/packages/core/src/animation/animationCurve/AnimationVector4Curve.ts +++ b/packages/core/src/animation/animationCurve/AnimationVector4Curve.ts @@ -1,5 +1,6 @@ import { Vector4 } from "@galacean/engine-math"; import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement"; +import { AnimationCurveLayerOwner } from "../internal/AnimationCurveLayerOwner"; import { AnimationCurveOwner } from "../internal/animationCurveOwner/AnimationCurveOwner"; import { Keyframe } from "../Keyframe"; import { AnimationCurve } from "./AnimationCurve"; @@ -25,6 +26,13 @@ export class AnimationVector4Curve extends AnimationCurve { owner.crossEvaluateData.value = new Vector4(); } + /** + * @internal + */ + static _initializeLayerOwner(owner: AnimationCurveLayerOwner): void { + owner.finalValue = new Vector4(); + } + /** * @internal */ diff --git a/packages/core/src/animation/animationCurve/interfaces/IAnimationCurveCalculator.ts b/packages/core/src/animation/animationCurve/interfaces/IAnimationCurveCalculator.ts index bb3509c735..dea6aadc0d 100644 --- a/packages/core/src/animation/animationCurve/interfaces/IAnimationCurveCalculator.ts +++ b/packages/core/src/animation/animationCurve/interfaces/IAnimationCurveCalculator.ts @@ -1,3 +1,4 @@ +import { AnimationCurveLayerOwner } from "../../internal/AnimationCurveLayerOwner"; import { AnimationCurveOwner } from "../../internal/animationCurveOwner/AnimationCurveOwner"; import { Keyframe, KeyframeValueType } from "../../Keyframe"; @@ -9,6 +10,7 @@ export interface IAnimationCurveCalculator { _isInterpolationType: boolean; _initializeOwner(owner: AnimationCurveOwner); + _initializeLayerOwner(owner: AnimationCurveLayerOwner); _lerpValue(src: V, dest: V, weight: number, out?: V): V; _additiveValue(additive: V, weight: number, srcOut: V): V; diff --git a/packages/core/src/animation/enums/LayerState.ts b/packages/core/src/animation/enums/LayerState.ts index 163cf660db..e121375893 100644 --- a/packages/core/src/animation/enums/LayerState.ts +++ b/packages/core/src/animation/enums/LayerState.ts @@ -3,11 +3,13 @@ */ export enum LayerState { /** Standby state. */ - Standby, //CM: Standby 优化 + Standby, /** Playing state. */ Playing, /** CrossFading state. */ CrossFading, /** FixedCrossFading state. */ - FixedCrossFading + FixedCrossFading, + /** Finished state. */ + Finished } diff --git a/packages/core/src/animation/internal/AnimationCurveLayerOwner.ts b/packages/core/src/animation/internal/AnimationCurveLayerOwner.ts index 471cb85c09..45a1190da4 100644 --- a/packages/core/src/animation/internal/AnimationCurveLayerOwner.ts +++ b/packages/core/src/animation/internal/AnimationCurveLayerOwner.ts @@ -9,4 +9,19 @@ export class AnimationCurveLayerOwner { crossDestCurveIndex: number; crossCurveMark: number = 0; curveOwner: AnimationCurveOwner; + finalValue: KeyframeValueType; + + initFinalValue() { + const { cureType, defaultValue } = this.curveOwner; + + if (cureType._isReferenceType) { + cureType._copyValue(defaultValue, this.finalValue); + } else { + this.finalValue = defaultValue; + } + } + + saveFinalValue(): void { + this.finalValue = this.curveOwner.getEvaluateValue(this.finalValue); + } } diff --git a/packages/core/src/animation/internal/AnimationEventHandler.ts b/packages/core/src/animation/internal/AnimationEventHandler.ts index 2d2e6c7ea3..53d1cf267e 100644 --- a/packages/core/src/animation/internal/AnimationEventHandler.ts +++ b/packages/core/src/animation/internal/AnimationEventHandler.ts @@ -1,8 +1,11 @@ +import { IPoolElement } from "../../RenderPipeline/IPoolElement"; import { AnimationEvent } from "../AnimationEvent"; /** * @internal */ -export class AnimationEventHandler { +export class AnimationEventHandler implements IPoolElement { event: AnimationEvent; handlers: Function[] = []; + + dispose() {} } diff --git a/packages/core/src/animation/internal/AnimatorLayerData.ts b/packages/core/src/animation/internal/AnimatorLayerData.ts index d89f73f542..9ea1f21564 100644 --- a/packages/core/src/animation/internal/AnimatorLayerData.ts +++ b/packages/core/src/animation/internal/AnimatorLayerData.ts @@ -17,7 +17,7 @@ export class AnimatorLayerData { crossCurveMark: number = 0; manuallyTransition: AnimatorStateTransition = new AnimatorStateTransition(); crossFadeTransition: AnimatorStateTransition; - crossOwnerLayerDataCollection: AnimationCurveLayerOwner[] = []; + crossLayerOwnerCollection: AnimationCurveLayerOwner[] = []; switchPlayData(): void { const srcPlayData = this.destPlayData; diff --git a/packages/core/src/animation/internal/animationCurveOwner/AnimationCurveOwner.ts b/packages/core/src/animation/internal/animationCurveOwner/AnimationCurveOwner.ts index 415cb39f8e..a1cea575f6 100644 --- a/packages/core/src/animation/internal/animationCurveOwner/AnimationCurveOwner.ts +++ b/packages/core/src/animation/internal/animationCurveOwner/AnimationCurveOwner.ts @@ -34,15 +34,13 @@ export class AnimationCurveOwner { defaultValue: V; fixedPoseValue: V; - hasSavedDefaultValue: boolean = false; baseEvaluateData: IEvaluateData = { curKeyframeIndex: 0, value: null }; - crossEvaluateData: IEvaluateData = { curKeyframeIndex: 0, value: null }; - referenceTargetValue: V; + cureType: IAnimationCurveCalculator; + updateMark: number = 0; private _assembler: IAnimationCurveOwnerAssembler; - private _cureType: IAnimationCurveCalculator; constructor( target: Entity, @@ -54,7 +52,7 @@ export class AnimationCurveOwner { this.type = type; this.property = property; this.component = target.getComponent(type); - this._cureType = cureType; + this.cureType = cureType; const assemblerType = AnimationCurveOwner.getAssemblerType(type, property); this._assembler = >new assemblerType(); @@ -65,44 +63,27 @@ export class AnimationCurveOwner { } } - evaluateAndApplyValue(curve: AnimationCurve, time: number, layerWeight: number, additive: boolean): void { - if (curve.keys.length) { - if (additive) { - const value = curve._evaluateAdditive(time, this.baseEvaluateData); - - const cureType = this._cureType; - if (cureType._isReferenceType) { - cureType._additiveValue(value, layerWeight, this.referenceTargetValue); - } else { - const assembler = this._assembler; - const originValue = assembler.getTargetValue(); - const additiveValue = cureType._additiveValue(value, layerWeight, originValue); - assembler.setTargetValue(additiveValue); - } - } else { - const value = curve._evaluate(time, this.baseEvaluateData); - - this._applyValue(value, layerWeight); - } - } + evaluateValue(curve: AnimationCurve, time: number, additive: boolean): KeyframeValueType { + return additive + ? curve._evaluateAdditive(time, this.baseEvaluateData) + : curve._evaluate(time, this.baseEvaluateData); } - crossFadeAndApplyValue( + evaluateCrossFadeValue( srcCurve: AnimationCurve, destCurve: AnimationCurve, srcTime: number, destTime: number, crossWeight: number, - layerWeight: number, additive: boolean - ): void { + ): KeyframeValueType { const srcValue = srcCurve && srcCurve.keys.length ? additive ? srcCurve._evaluateAdditive(srcTime, this.baseEvaluateData) : srcCurve._evaluate(srcTime, this.baseEvaluateData) : additive - ? this._cureType._getZeroValue(this.baseEvaluateData.value) + ? this.cureType._getZeroValue(this.baseEvaluateData.value) : this.defaultValue; const destValue = @@ -111,21 +92,20 @@ export class AnimationCurveOwner { ? destCurve._evaluateAdditive(destTime, this.crossEvaluateData) : destCurve._evaluate(destTime, this.crossEvaluateData) : additive - ? this._cureType._getZeroValue(this.crossEvaluateData.value) + ? this.cureType._getZeroValue(this.crossEvaluateData.value) : this.defaultValue; - this._applyCrossValue(srcValue, destValue, crossWeight, layerWeight, additive); + return this._lerpValue(srcValue, destValue, crossWeight); } crossFadeFromPoseAndApplyValue( destCurve: AnimationCurve, destTime: number, crossWeight: number, - layerWeight: number, additive: boolean - ): void { + ): KeyframeValueType { const srcValue = additive - ? this._cureType._subtractValue(this.fixedPoseValue, this.defaultValue, this.baseEvaluateData.value) + ? this.cureType._subtractValue(this.fixedPoseValue, this.defaultValue, this.baseEvaluateData.value) : this.fixedPoseValue; const destValue = destCurve && destCurve.keys.length @@ -133,77 +113,78 @@ export class AnimationCurveOwner { ? destCurve._evaluateAdditive(destTime, this.crossEvaluateData) : destCurve._evaluate(destTime, this.crossEvaluateData) : additive - ? this._cureType._getZeroValue(this.crossEvaluateData.value) + ? this.cureType._getZeroValue(this.crossEvaluateData.value) : this.defaultValue; - this._applyCrossValue(srcValue, destValue, crossWeight, layerWeight, additive); + return this._lerpValue(srcValue, destValue, crossWeight); } revertDefaultValue(): void { this._assembler.setTargetValue(this.defaultValue); } + getEvaluateValue(out: V): V { + if (this.cureType._isReferenceType) { + this.cureType._copyValue(this.baseEvaluateData.value, out); + return out; + } else { + return this.baseEvaluateData.value; + } + } + saveDefaultValue(): void { - if (this._cureType._isReferenceType) { - this._cureType._copyValue(this.referenceTargetValue, this.defaultValue); + if (this.cureType._isReferenceType) { + this.cureType._copyValue(this.referenceTargetValue, this.defaultValue); } else { this.defaultValue = this._assembler.getTargetValue(); } - this.hasSavedDefaultValue = true; } saveFixedPoseValue(): void { - if (this._cureType._isReferenceType) { - this._cureType._copyValue(this.referenceTargetValue, this.fixedPoseValue); + if (this.cureType._isReferenceType) { + this.cureType._copyValue(this.referenceTargetValue, this.fixedPoseValue); } else { this.fixedPoseValue = this._assembler.getTargetValue(); } } - private _applyValue(value: V, weight: number): void { - if (weight === 1.0) { - if (this._cureType._isReferenceType) { - this._cureType._copyValue(value, this.referenceTargetValue); + applyValue(value: V, weight: number, additive: boolean): void { + const cureType = this.cureType; + if (additive) { + if (cureType._isReferenceType) { + cureType._additiveValue(value, weight, this.referenceTargetValue); } else { - this._assembler.setTargetValue(value); + const assembler = this._assembler; + const originValue = assembler.getTargetValue(); + const additiveValue = cureType._additiveValue(value, weight, originValue); + assembler.setTargetValue(additiveValue); } } else { - if (this._cureType._isReferenceType) { - const targetValue = this.referenceTargetValue; - this._cureType._lerpValue(targetValue, value, weight, targetValue); + if (weight === 1.0) { + if (cureType._isReferenceType) { + cureType._copyValue(value, this.referenceTargetValue); + } else { + this._assembler.setTargetValue(value); + } } else { - const originValue = this._assembler.getTargetValue(); - const lerpValue = this._cureType._lerpValue(originValue, value, weight); - this._assembler.setTargetValue(lerpValue); + if (cureType._isReferenceType) { + const targetValue = this.referenceTargetValue; + cureType._lerpValue(targetValue, value, weight, targetValue); + } else { + const originValue = this._assembler.getTargetValue(); + const lerpValue = cureType._lerpValue(originValue, value, weight); + this._assembler.setTargetValue(lerpValue); + } } } } - private _applyCrossValue( - srcValue: V, - destValue: V, - crossWeight: number, - layerWeight: number, - additive: boolean - ): void { - let out: V; - if (this._cureType._isReferenceType) { - out = this.baseEvaluateData.value; - this._cureType._lerpValue(srcValue, destValue, crossWeight, out); - } else { - out = this._cureType._lerpValue(srcValue, destValue, crossWeight); - } - - if (additive) { - if (this._cureType._isReferenceType) { - this._cureType._additiveValue(out, layerWeight, this.referenceTargetValue); - } else { - const originValue = this._assembler.getTargetValue(); - const lerpValue = this._cureType._additiveValue(out, layerWeight, originValue); - this._assembler.setTargetValue(lerpValue); - } + private _lerpValue(srcValue: V, destValue: V, crossWeight: number): KeyframeValueType { + if (this.cureType._isReferenceType) { + return this.cureType._lerpValue(srcValue, destValue, crossWeight, this.baseEvaluateData.value); } else { - this._applyValue(out, layerWeight); + this.baseEvaluateData.value = this.cureType._lerpValue(srcValue, destValue, crossWeight); + return this.baseEvaluateData.value; } } } diff --git a/packages/core/src/asset/ResourceManager.ts b/packages/core/src/asset/ResourceManager.ts index 95f352198f..5bb29bbcaf 100644 --- a/packages/core/src/asset/ResourceManager.ts +++ b/packages/core/src/asset/ResourceManager.ts @@ -148,6 +148,7 @@ export class ResourceManager { */ gc(): void { this._gc(false); + this.engine._pendingGC(); } /** diff --git a/packages/core/src/base/EventDispatcher.ts b/packages/core/src/base/EventDispatcher.ts index aa1e0892c4..1c5399bcfc 100644 --- a/packages/core/src/base/EventDispatcher.ts +++ b/packages/core/src/base/EventDispatcher.ts @@ -2,9 +2,10 @@ * EventDispatcher, which can be inherited as a base class. */ export class EventDispatcher { + private static _dispatchingListenersPool: EventData[][] = []; + private _events: Record = Object.create(null); private _eventCount: number = 0; - private _dispatchingListeners: EventData[] = []; /** * Determine whether there is event listening. @@ -54,7 +55,8 @@ export class EventDispatcher { const count = listeners.length; // cloning list to avoid structure breaking - const dispatchingListeners = this._dispatchingListeners; + const { _dispatchingListenersPool: pool } = EventDispatcher; + const dispatchingListeners = pool.length > 0 ? pool.pop() : []; dispatchingListeners.length = count; for (let i = 0; i < count; i++) { dispatchingListeners[i] = listeners[i]; @@ -70,6 +72,7 @@ export class EventDispatcher { // remove hooked function to avoid gc problem dispatchingListeners.length = 0; + pool.push(dispatchingListeners); } else { if (listeners.once) this.off(event, listeners.fn); listeners.fn(data); diff --git a/packages/core/src/graphic/Mesh.ts b/packages/core/src/graphic/Mesh.ts index 59e458a622..784d041fd1 100644 --- a/packages/core/src/graphic/Mesh.ts +++ b/packages/core/src/graphic/Mesh.ts @@ -219,10 +219,10 @@ export abstract class Mesh extends GraphicsResource { * @internal */ _setVertexBufferBinding(index: number, binding: VertexBufferBinding): void { - if (this._getReferCount() > 0) { - const lastBinding = this._vertexBufferBindings[index]; - lastBinding && lastBinding.buffer._addReferCount(-1); - binding.buffer._addReferCount(1); + const referCount = this._getReferCount(); + if (referCount > 0) { + this._vertexBufferBindings[index]?.buffer._addReferCount(-referCount); + binding?.buffer._addReferCount(referCount); } this._vertexBufferBindings[index] = binding; this._bufferStructChanged = true; @@ -242,6 +242,7 @@ export abstract class Mesh extends GraphicsResource { for (let i = 0, n = vertexBufferBindings.length; i < n; i++) { vertexBufferBindings[i]?.buffer._addReferCount(value); } + this._indexBufferBinding?._buffer._addReferCount(value); } override _rebuild(): void { @@ -275,6 +276,11 @@ export abstract class Mesh extends GraphicsResource { */ protected _setIndexBufferBinding(binding: IndexBufferBinding | null): void { const lastBinding = this._indexBufferBinding; + const referCount = this._getReferCount(); + if (referCount > 0) { + lastBinding?.buffer._addReferCount(-referCount); + binding?.buffer._addReferCount(referCount); + } if (binding) { this._indexBufferBinding = binding; this._glIndexType = BufferUtil._getGLIndexType(binding.format); diff --git a/packages/core/src/graphic/SubMesh.ts b/packages/core/src/graphic/SubMesh.ts index c031e25593..edb0f7f68a 100644 --- a/packages/core/src/graphic/SubMesh.ts +++ b/packages/core/src/graphic/SubMesh.ts @@ -1,9 +1,10 @@ +import { IPoolElement } from "../RenderPipeline/IPoolElement"; import { MeshTopology } from "./enums/MeshTopology"; /** * Sub-mesh, mainly contains drawing information. */ -export class SubMesh { +export class SubMesh implements IPoolElement { /** Start drawing offset. */ start: number; /** Drawing count. */ @@ -22,4 +23,6 @@ export class SubMesh { this.count = count; this.topology = topology; } + + dispose?(): void {} } diff --git a/packages/core/src/lighting/AmbientLight.ts b/packages/core/src/lighting/AmbientLight.ts index 8e74ad3472..89987fc2e3 100644 --- a/packages/core/src/lighting/AmbientLight.ts +++ b/packages/core/src/lighting/AmbientLight.ts @@ -5,11 +5,13 @@ import { ShaderMacro } from "../shader/ShaderMacro"; import { ShaderProperty } from "../shader/ShaderProperty"; import { TextureCube } from "../texture"; import { DiffuseMode } from "./enums/DiffuseMode"; +import { ReferResource } from "../asset/ReferResource"; +import { Engine } from "../Engine"; /** * Ambient light. */ -export class AmbientLight { +export class AmbientLight extends ReferResource { private static _shMacro: ShaderMacro = ShaderMacro.getByName("SCENE_USE_SH"); private static _specularMacro: ShaderMacro = ShaderMacro.getByName("SCENE_USE_SPECULAR_ENV"); private static _decodeRGBMMacro: ShaderMacro = ShaderMacro.getByName("SCENE_IS_DECODE_ENV_RGBM"); @@ -151,8 +153,8 @@ export class AmbientLight { * @internal */ _addToScene(scene: Scene): void { + this._addReferCount(1); this._scenes.push(scene); - const shaderData = scene.shaderData; shaderData.setColor(AmbientLight._diffuseColorProperty, this._diffuseSolidColor); shaderData.setFloat(AmbientLight._diffuseIntensityProperty, this._diffuseIntensity); @@ -168,9 +170,17 @@ export class AmbientLight { * @internal */ _removeFromScene(scene: Scene): void { + this._addReferCount(-1); const scenes = this._scenes; const index = scenes.indexOf(scene); scenes.splice(index, 1); + const shaderData = scene.shaderData; + shaderData.setTexture(AmbientLight._specularTextureProperty, null); + shaderData.disableMacro(AmbientLight._specularMacro); + } + + constructor(engine: Engine) { + super(engine); } private _setDiffuseMode(sceneShaderData: ShaderData): void { diff --git a/packages/core/src/lighting/LightManager.ts b/packages/core/src/lighting/LightManager.ts index ddcf94aa24..ea74efa3d3 100644 --- a/packages/core/src/lighting/LightManager.ts +++ b/packages/core/src/lighting/LightManager.ts @@ -70,32 +70,19 @@ export class LightManager { /** * @internal */ - _getSunLightIndex(): number { + _updateSunLightIndex(): void { const directLights = this._directLights; - - let sunLightIndex = -1; - let maxIntensity = Number.NEGATIVE_INFINITY; - let hasShadowLight = false; - for (let i = 0, n = directLights.length; i < n; i++) { - const directLight = directLights.get(i); - if (directLight.shadowType !== ShadowType.None && !hasShadowLight) { - maxIntensity = Number.NEGATIVE_INFINITY; - hasShadowLight = true; - } - const intensity = directLight.intensity * directLight.color.getBrightness(); - if (hasShadowLight) { - if (directLight.shadowType !== ShadowType.None && maxIntensity < intensity) { - maxIntensity = intensity; - sunLightIndex = i; - } - } else { - if (maxIntensity < intensity) { - maxIntensity = intensity; - sunLightIndex = i; - } - } + const index = this._getSunLightIndex(); + // -1 means no sun light, 0 means the first direct light already is sun light + if (index > 0) { + const firstLight = directLights.get(0); + const sunLight = directLights.get(index); + directLights.set(0, sunLight); + directLights.set(index, firstLight); + + sunLight._lightIndex = 0; + firstLight._lightIndex = index; } - return sunLightIndex; } /** @@ -145,4 +132,41 @@ export class LightManager { shaderData.disableMacro("SCENE_SPOT_LIGHT_COUNT"); } } + + /** + * @internal + */ + _gc() { + this._spotLights.garbageCollection(); + this._pointLights.garbageCollection(); + this._directLights.garbageCollection(); + } + + private _getSunLightIndex(): number { + const directLights = this._directLights; + + let sunLightIndex = -1; + let maxIntensity = Number.NEGATIVE_INFINITY; + let hasShadowLight = false; + for (let i = 0, n = directLights.length; i < n; i++) { + const directLight = directLights.get(i); + if (directLight.shadowType !== ShadowType.None && !hasShadowLight) { + maxIntensity = Number.NEGATIVE_INFINITY; + hasShadowLight = true; + } + const intensity = directLight.intensity * directLight.color.getBrightness(); + if (hasShadowLight) { + if (directLight.shadowType !== ShadowType.None && maxIntensity < intensity) { + maxIntensity = intensity; + sunLightIndex = i; + } + } else { + if (maxIntensity < intensity) { + maxIntensity = intensity; + sunLightIndex = i; + } + } + } + return sunLightIndex; + } } diff --git a/packages/core/src/material/Material.ts b/packages/core/src/material/Material.ts index 01f1031196..aa8b203a5c 100644 --- a/packages/core/src/material/Material.ts +++ b/packages/core/src/material/Material.ts @@ -13,14 +13,21 @@ import { RenderState } from "../shader/state/RenderState"; export class Material extends ReferResource implements IClone { /** Name. */ name: string; - /** Shader data. */ - readonly shaderData: ShaderData = new ShaderData(ShaderDataGroup.Material); /** @internal */ _shader: Shader; /** @internal */ _renderStates: RenderState[] = []; // todo: later will as a part of shaderData when shader effect frame is OK, that is more powerful and flexible. + private _shaderData: ShaderData = new ShaderData(ShaderDataGroup.Material); + + /** + * Shader data. + */ + get shaderData(): ShaderData { + return this._shaderData; + } + /** * Shader used by the material. */ @@ -96,4 +103,15 @@ export class Material extends ReferResource implements IClone { super._addReferCount(value); this.shaderData._addReferCount(value); } + + /** + * @override + */ + protected override _onDestroy(): void { + super._onDestroy(); + this._shader = null; + this._shaderData = null; + this._renderStates.length = 0; + this._renderStates = null; + } } diff --git a/packages/core/src/mesh/MeshRenderer.ts b/packages/core/src/mesh/MeshRenderer.ts index a41052bf4e..fd569ff0b1 100644 --- a/packages/core/src/mesh/MeshRenderer.ts +++ b/packages/core/src/mesh/MeshRenderer.ts @@ -64,8 +64,8 @@ export class MeshRenderer extends Renderer { protected override _onDestroy(): void { super._onDestroy(); const mesh = this._mesh; - if (mesh && !mesh.destroyed) { - mesh._addReferCount(-1); + if (mesh) { + mesh.destroyed || mesh._addReferCount(-1); mesh._updateFlagManager.removeListener(this._onMeshChanged); this._mesh = null; } @@ -79,6 +79,17 @@ export class MeshRenderer extends Renderer { target.mesh = this._mesh; } + /** + * @internal + */ + override _prepareRender(context: RenderContext): void { + if (!this._mesh) { + Logger.error("mesh is null."); + return; + } + super._prepareRender(context); + } + /** * @internal */ @@ -99,52 +110,48 @@ export class MeshRenderer extends Renderer { */ protected override _render(context: RenderContext): void { const mesh = this._mesh; - if (mesh) { - if (this._dirtyUpdateFlag & MeshRendererUpdateFlags.VertexElementMacro) { - const shaderData = this.shaderData; - const vertexElements = mesh._vertexElements; - - shaderData.disableMacro(MeshRenderer._uvMacro); - shaderData.disableMacro(MeshRenderer._uv1Macro); - shaderData.disableMacro(MeshRenderer._normalMacro); - shaderData.disableMacro(MeshRenderer._tangentMacro); - shaderData.disableMacro(MeshRenderer._enableVertexColorMacro); - - for (let i = 0, n = vertexElements.length; i < n; i++) { - switch (vertexElements[i].semantic) { - case "TEXCOORD_0": - shaderData.enableMacro(MeshRenderer._uvMacro); - break; - case "TEXCOORD_1": - shaderData.enableMacro(MeshRenderer._uv1Macro); - break; - case "NORMAL": - shaderData.enableMacro(MeshRenderer._normalMacro); - break; - case "TANGENT": - shaderData.enableMacro(MeshRenderer._tangentMacro); - break; - case "COLOR_0": - this._enableVertexColor && shaderData.enableMacro(MeshRenderer._enableVertexColorMacro); - break; - } + if (this._dirtyUpdateFlag & MeshRendererUpdateFlags.VertexElementMacro) { + const shaderData = this.shaderData; + const vertexElements = mesh._vertexElements; + + shaderData.disableMacro(MeshRenderer._uvMacro); + shaderData.disableMacro(MeshRenderer._uv1Macro); + shaderData.disableMacro(MeshRenderer._normalMacro); + shaderData.disableMacro(MeshRenderer._tangentMacro); + shaderData.disableMacro(MeshRenderer._enableVertexColorMacro); + + for (let i = 0, n = vertexElements.length; i < n; i++) { + switch (vertexElements[i].semantic) { + case "TEXCOORD_0": + shaderData.enableMacro(MeshRenderer._uvMacro); + break; + case "TEXCOORD_1": + shaderData.enableMacro(MeshRenderer._uv1Macro); + break; + case "NORMAL": + shaderData.enableMacro(MeshRenderer._normalMacro); + break; + case "TANGENT": + shaderData.enableMacro(MeshRenderer._tangentMacro); + break; + case "COLOR_0": + this._enableVertexColor && shaderData.enableMacro(MeshRenderer._enableVertexColorMacro); + break; } - this._dirtyUpdateFlag &= ~MeshRendererUpdateFlags.VertexElementMacro; } + this._dirtyUpdateFlag &= ~MeshRendererUpdateFlags.VertexElementMacro; + } - const materials = this._materials; - const subMeshes = mesh.subMeshes; - const renderPipeline = context.camera._renderPipeline; - const meshRenderDataPool = this._engine._meshRenderDataPool; - for (let i = 0, n = subMeshes.length; i < n; i++) { - const material = materials[i]; - if (!material) continue; - const renderData = meshRenderDataPool.getFromPool(); - renderData.set(this, material, mesh, subMeshes[i]); - renderPipeline.pushRenderData(context, renderData); - } - } else { - Logger.error("mesh is null."); + const materials = this._materials; + const subMeshes = mesh.subMeshes; + const renderPipeline = context.camera._renderPipeline; + const meshRenderDataPool = this._engine._meshRenderDataPool; + for (let i = 0, n = subMeshes.length; i < n; i++) { + const material = materials[i]; + if (!material) continue; + const renderData = meshRenderDataPool.getFromPool(); + renderData.set(this, material, mesh, subMeshes[i]); + renderPipeline.pushRenderData(context, renderData); } } diff --git a/packages/core/src/mesh/SkinnedMeshRenderer.ts b/packages/core/src/mesh/SkinnedMeshRenderer.ts index af98302ab8..13753f187b 100644 --- a/packages/core/src/mesh/SkinnedMeshRenderer.ts +++ b/packages/core/src/mesh/SkinnedMeshRenderer.ts @@ -131,7 +131,7 @@ export class SkinnedMeshRenderer extends MeshRenderer { // Limit size to 256 to avoid some problem: // For renderer is "Apple GPU", when uniform is large than 256 the skeleton matrix array access in shader very slow in Safari or WKWebview. This may be a apple bug, Chrome and Firefox is OK! // For renderer is "ANGLE (AMD, AMD Radeon(TM) Graphics Direct3011 vs_5_0 ps_5_0, D3011)", compile shader si very slow because of max uniform is 4096. - maxVertexUniformVectors = Math.min(maxVertexUniformVectors, 256); + maxVertexUniformVectors = Math.min(maxVertexUniformVectors, rhi._options._maxAllowSkinUniformVectorCount); this._maxVertexUniformVectors = maxVertexUniformVectors; @@ -235,8 +235,19 @@ export class SkinnedMeshRenderer extends MeshRenderer { */ override _onDestroy(): void { super._onDestroy(); - this.rootBone?.transform._updateFlagManager.removeListener(this._onTransformChanged); + this._rootBone?.transform._updateFlagManager.removeListener(this._onTransformChanged); + this._rootBone = null; + this._jointDataCreateCache = null; + this._skin = null; + this._blendShapeWeights = null; + this._localBounds = null; + this._jointMatrices = null; this._jointTexture?.destroy(); + this._jointTexture = null; + if (this._jointEntities) { + this._jointEntities.length = 0; + this._jointEntities = null; + } } /** diff --git a/packages/core/src/physics/PhysicsScene.ts b/packages/core/src/physics/PhysicsScene.ts index c9a85aee66..1b056de895 100644 --- a/packages/core/src/physics/PhysicsScene.ts +++ b/packages/core/src/physics/PhysicsScene.ts @@ -406,6 +406,13 @@ export class PhysicsScene { } } + /** + * @internal + */ + _gc(): void { + this._colliders.garbageCollection(); + } + private _setGravity(): void { this._nativePhysicsScene.setGravity(this._gravity); } diff --git a/packages/core/src/shader/ShaderData.ts b/packages/core/src/shader/ShaderData.ts index e48489e0eb..a52c03fa04 100644 --- a/packages/core/src/shader/ShaderData.ts +++ b/packages/core/src/shader/ShaderData.ts @@ -601,7 +601,7 @@ export class ShaderData implements IReferable, IClone { cloneTo(target: ShaderData): void { CloneManager.deepCloneObject(this._macroCollection, target._macroCollection); Object.assign(target._macroMap, this._macroMap); - + const referCount = target._getReferCount(); const propertyValueMap = this._propertyValueMap; const targetPropertyValueMap = target._propertyValueMap; const keys = Object.keys(propertyValueMap); @@ -613,6 +613,7 @@ export class ShaderData implements IReferable, IClone { targetPropertyValueMap[k] = property; } else if (property instanceof Texture) { targetPropertyValueMap[k] = property; + referCount > 0 && property._addReferCount(referCount); } else if (property instanceof Array || property instanceof Float32Array || property instanceof Int32Array) { targetPropertyValueMap[k] = property.slice(); } else { diff --git a/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl b/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl index bbe8ab50bd..411cc81b14 100644 --- a/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl +++ b/packages/core/src/shaderlib/mobile_blinnphong_frag.glsl @@ -13,7 +13,7 @@ shadowAttenuation = 1.0; #ifdef SCENE_IS_CALCULATE_SHADOWS shadowAttenuation *= sampleShadowMap(); - int sunIndex = int(scene_ShadowInfo.z); + // int sunIndex = int(scene_ShadowInfo.z); #endif DirectLight directionalLight; @@ -23,7 +23,7 @@ directionalLight.color = scene_DirectLightColor[i]; #ifdef SCENE_IS_CALCULATE_SHADOWS - if (i == sunIndex) { + if (i == 0) { // Sun light index is always 0 directionalLight.color *= shadowAttenuation; } #endif diff --git a/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl b/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl index e1385d016f..7876a532d2 100644 --- a/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/direct_irradiance_frag_define.glsl @@ -79,7 +79,7 @@ void addTotalDirectRadiance(Geometry geometry, Material material, inout Reflecte shadowAttenuation = 1.0; #ifdef SCENE_IS_CALCULATE_SHADOWS shadowAttenuation *= sampleShadowMap(); - int sunIndex = int(scene_ShadowInfo.z); + // int sunIndex = int(scene_ShadowInfo.z); #endif DirectLight directionalLight; @@ -89,7 +89,7 @@ void addTotalDirectRadiance(Geometry geometry, Material material, inout Reflecte directionalLight.color = scene_DirectLightColor[i]; #ifdef SCENE_IS_CALCULATE_SHADOWS - if (i == sunIndex) { + if (i == 0) { // Sun light index is always 0 directionalLight.color *= shadowAttenuation; } #endif diff --git a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl index 49917a9e9f..10b00f62a2 100644 --- a/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl +++ b/packages/core/src/shaderlib/pbr/pbr_frag_define.glsl @@ -87,4 +87,4 @@ struct Material { float clearCoatRoughness; #endif -}; +}; \ No newline at end of file diff --git a/packages/core/src/shadow/CascadedShadowCasterPass.ts b/packages/core/src/shadow/CascadedShadowCasterPass.ts index bc67f021b5..41694a9e27 100644 --- a/packages/core/src/shadow/CascadedShadowCasterPass.ts +++ b/packages/core/src/shadow/CascadedShadowCasterPass.ts @@ -111,10 +111,8 @@ export class CascadedShadowCasterPass { const lightSide = this._lightSide; const lightForward = shadowSliceData.virtualCamera.forward; - const sunLightIndex = scene._lightManager._getSunLightIndex(); - - if (sunLightIndex !== -1) { - const light = camera.scene._sunLight; + const light = camera.scene._sunLight; + if (light) { const shadowFar = Math.min(camera.scene.shadowDistance, camera.farClipPlane); this._getCascadesSplitDistance(shadowFar); // prepare render target @@ -127,7 +125,7 @@ export class CascadedShadowCasterPass { rhi.clearRenderTarget(engine, CameraClearFlags.All, CascadedShadowCasterPass._clearColor); } this._shadowInfos.x = light.shadowStrength; - this._shadowInfos.z = sunLightIndex; + this._shadowInfos.z = 0; // @todo: sun light index always 0 // prepare light and camera direction Matrix.rotationQuaternion(light.entity.transform.worldRotationQuaternion, lightWorld); @@ -303,11 +301,13 @@ export class CascadedShadowCasterPass { depthTexture.depthCompareFunction = TextureDepthCompareFunction.Less; } + renderTarget?._addReferCount(-1); if (this._supportDepthTexture) { renderTarget = this._renderTargets = new RenderTarget(engine, width, height, null, depthTexture); } else { renderTarget = this._renderTargets = new RenderTarget(engine, width, height, depthTexture); } + renderTarget._addReferCount(1); } return renderTarget; } @@ -343,7 +343,12 @@ export class CascadedShadowCasterPass { this._shadowMapSize.set(1.0 / width, 1.0 / height, width, height); } - this._renderTargets = null; + const renderTargets = this._renderTargets; + if (renderTargets) { + renderTargets._addReferCount(-1); + renderTargets.destroy(); + this._renderTargets = null; + } const viewportOffset = this._viewportOffsets; const shadowTileResolution = this._shadowTileResolution; diff --git a/packages/core/src/sky/Sky.ts b/packages/core/src/sky/Sky.ts index 4df20a8e77..8c0e537c18 100644 --- a/packages/core/src/sky/Sky.ts +++ b/packages/core/src/sky/Sky.ts @@ -14,10 +14,46 @@ export class Sky { private static _viewProjMatrix: Matrix = new Matrix(); private static _projectionMatrix: Matrix = new Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, Sky._epsilon - 1, -1, 0, 0, 0, 0); - /** Material of the sky. */ - material: Material; - /** Mesh of the sky. */ - mesh: Mesh; + private _material: Material; + private _mesh: Mesh; + + /** + * Material of the sky. + */ + get material() { + return this._material; + } + + set material(value: Material) { + if (this._material !== value) { + value?._addReferCount(1); + this._material?._addReferCount(-1); + this._material = value; + } + } + + /** + * Mesh of the sky. + */ + get mesh() { + return this._mesh; + } + + set mesh(value: Mesh) { + if (this._mesh !== value) { + value?._addReferCount(1); + this._mesh?._addReferCount(-1); + this._mesh = value; + } + } + + /** + * @internal + */ + destroy(): void { + this.mesh = null; + this.material = null; + } /** * @internal diff --git a/packages/core/src/texture/RenderTarget.ts b/packages/core/src/texture/RenderTarget.ts index c102048c19..7787845970 100644 --- a/packages/core/src/texture/RenderTarget.ts +++ b/packages/core/src/texture/RenderTarget.ts @@ -164,9 +164,11 @@ export class RenderTarget extends GraphicsResource { if (renderTexture) { const colorTextures = renderTexture instanceof Array ? renderTexture.slice() : [renderTexture]; for (let i = 0, n = colorTextures.length; i < n; i++) { - if (colorTextures[i]._isDepthTexture) { + const colorTexture = colorTextures[i]; + if (colorTexture._isDepthTexture) { throw "Render texture can't use depth format."; } + colorTexture._addReferCount(1); } this._colorTextures = colorTextures; } else { @@ -178,6 +180,7 @@ export class RenderTarget extends GraphicsResource { throw "Depth texture must use depth format."; } this._depthTexture = depth; + this._depthTexture._addReferCount(1); } this._platformRenderTarget = engine._hardwareRenderer.createPlatformRenderTarget(this); @@ -212,7 +215,12 @@ export class RenderTarget extends GraphicsResource { protected override _onDestroy(): void { super._onDestroy(); this._platformRenderTarget.destroy(); - this._colorTextures.length = 0; + const { _colorTextures: colorTextures } = this; + for (let i = 0, n = colorTextures.length; i < n; i++) { + colorTextures[i]._addReferCount(-1); + } + colorTextures.length = 0; + this._depthTexture?._addReferCount(-1); this._depthTexture = null; this._depth = null; } diff --git a/packages/loader/src/AnimationClipLoader.ts b/packages/loader/src/AnimationClipLoader.ts index d70abdaea4..de638b27a8 100644 --- a/packages/loader/src/AnimationClipLoader.ts +++ b/packages/loader/src/AnimationClipLoader.ts @@ -18,9 +18,7 @@ class AnimationClipLoader extends Loader { ...item, type: "arraybuffer" }) - .then((data) => { - return decode(data, resourceManager.engine); - }) + .then((data) => decode(data, resourceManager.engine).then(resolve)) .catch(reject); }); } diff --git a/packages/loader/src/AnimatorControllerLoader.ts b/packages/loader/src/AnimatorControllerLoader.ts index 42034fcab2..023a446a50 100644 --- a/packages/loader/src/AnimatorControllerLoader.ts +++ b/packages/loader/src/AnimatorControllerLoader.ts @@ -48,7 +48,8 @@ class AnimatorControllerLoader extends Loader { state.wrapMode = wrapMode; state.clipStartTime = clipStartNormalizedTime; state.clipEndTime = clipEndNormalizedTime; - scripts?.forEach((script) => { + const scriptsObject = JSON.parse(scripts); + scriptsObject?.forEach((script) => { state.addStateMachineScript(Loader.getClass(script)); }); if (clipData) { diff --git a/packages/loader/src/EnvLoader.ts b/packages/loader/src/EnvLoader.ts index 2502460a90..0809c00c7f 100644 --- a/packages/loader/src/EnvLoader.ts +++ b/packages/loader/src/EnvLoader.ts @@ -23,7 +23,8 @@ class EnvLoader extends Loader { const shByteLength = 27 * 4; const size = new Uint16Array(arraybuffer, shByteLength, 1)?.[0]; - const texture = new TextureCube(resourceManager.engine, size); + const { engine } = resourceManager; + const texture = new TextureCube(engine, size); texture.filterMode = TextureFilterMode.Trilinear; const mipmapCount = texture.mipmapCount; let offset = shByteLength + 2; @@ -39,7 +40,7 @@ class EnvLoader extends Loader { } } - const ambientLight = new AmbientLight(); + const ambientLight = new AmbientLight(engine); const sh = new SphericalHarmonics3(); ambientLight.diffuseMode = DiffuseMode.SphericalHarmonics; diff --git a/packages/loader/src/GLTFContentRestorer.ts b/packages/loader/src/GLTFContentRestorer.ts index 0b1c1829f6..cd9d8160e0 100644 --- a/packages/loader/src/GLTFContentRestorer.ts +++ b/packages/loader/src/GLTFContentRestorer.ts @@ -12,6 +12,7 @@ import { Vector2 } from "@galacean/engine-math"; import { GLTFResource } from "./gltf/GLTFResource"; import type { IBufferView } from "./gltf/GLTFSchema"; import { GLTFUtils } from "./gltf/GLTFUtils"; +import { KTX2Loader } from "./ktx2/KTX2Loader"; /** * @internal @@ -49,11 +50,21 @@ export class GLTFContentRestorer extends ContentRestorer { const { bufferView } = textureRestoreInfo; const buffer = buffers[bufferView.buffer]; const bufferData = new Uint8Array(buffer, bufferView.byteOffset ?? 0, bufferView.byteLength); - - return GLTFUtils.loadImageBuffer(bufferData, textureRestoreInfo.mimeType).then((image) => { - textureRestoreInfo.texture.setImageSource(image); - textureRestoreInfo.texture.generateMipmaps(); - }); + const texture = textureRestoreInfo.texture; + if (textureRestoreInfo.mimeType === "image/ktx2") { + return KTX2Loader._parseBuffer(bufferData, texture.engine).then(({ result }) => { + const { faces } = result; + const mipmaps = faces[0]; + for (let i = 0; i < mipmaps.length; i++) { + texture.setPixelBuffer(mipmaps[i].data, i); + } + }); + } else { + return GLTFUtils.loadImageBuffer(bufferData, textureRestoreInfo.mimeType).then((image) => { + texture.setImageSource(image); + texture.generateMipmaps(); + }); + } }) ) .then(() => { diff --git a/packages/loader/src/gltf/GLTFResource.ts b/packages/loader/src/gltf/GLTFResource.ts index a57dcb6aef..98c2740b7d 100644 --- a/packages/loader/src/gltf/GLTFResource.ts +++ b/packages/loader/src/gltf/GLTFResource.ts @@ -2,11 +2,11 @@ import { AnimationClip, Camera, Engine, - EngineObject, Entity, Light, Material, ModelMesh, + ReferResource, Skin, Texture2D } from "@galacean/engine-core"; @@ -14,7 +14,7 @@ import { /** * Product after glTF parser, usually, `defaultSceneRoot` is only needed to use. */ -export class GLTFResource extends EngineObject { +export class GLTFResource extends ReferResource { /** glTF file url. */ url: string; /** Texture2D after TextureParser. */ @@ -44,23 +44,4 @@ export class GLTFResource extends EngineObject { super(engine); this.url = url; } - - /** - * @internal - */ - protected override _onDestroy(): void { - super._onDestroy(); - this.defaultSceneRoot.destroy(); - - this.textures = null; - this.materials = null; - this.meshes = null; - this.skins = null; - this.animations = null; - this.entities = null; - this.cameras = null; - this.lights = null; - this.sceneRoots = null; - this.extensionsData = null; - } } diff --git a/packages/loader/src/gltf/GLTFSchema.ts b/packages/loader/src/gltf/GLTFSchema.ts index 293a4f45fb..5ab681027c 100644 --- a/packages/loader/src/gltf/GLTFSchema.ts +++ b/packages/loader/src/gltf/GLTFSchema.ts @@ -2,7 +2,7 @@ * Module for glTF 2.0 Interface */ -import { MeshTopology } from "@galacean/engine-core"; +import type { MeshTopology, TextureFilterMode, TextureWrapMode as EngineTextureWrapMode } from "@galacean/engine-core"; /** * The datatype of the components in the attribute @@ -856,3 +856,10 @@ export interface IGLTF extends IProperty { /** glTF extensible owner schema. */ export type GLTFExtensionOwnerSchema = IMeshPrimitive | IMaterial | ITextureInfo | INode; + +export interface ISamplerInfo { + filterMode?: TextureFilterMode; + wrapModeU?: EngineTextureWrapMode; + wrapModeV?: EngineTextureWrapMode; + mipmap?: boolean; +} diff --git a/packages/loader/src/gltf/GLTFUtils.ts b/packages/loader/src/gltf/GLTFUtils.ts index 7be538c1d3..56217f0c5e 100644 --- a/packages/loader/src/gltf/GLTFUtils.ts +++ b/packages/loader/src/gltf/GLTFUtils.ts @@ -1,8 +1,26 @@ -import { IndexFormat, TypedArray, Utils, VertexElementFormat } from "@galacean/engine-core"; +import { + IndexFormat, + Texture2D, + TextureFilterMode, + TypedArray, + Utils, + VertexElementFormat +} from "@galacean/engine-core"; import { Color, Vector2, Vector3, Vector4 } from "@galacean/engine-math"; import { BufferDataRestoreInfo, RestoreDataAccessor } from "../GLTFContentRestorer"; -import { AccessorComponentType, AccessorType, IAccessor, IBufferView, IGLTF } from "./GLTFSchema"; +import { + AccessorComponentType, + AccessorType, + IAccessor, + IBufferView, + IGLTF, + ISampler, + ISamplerInfo, + TextureMagFilter, + TextureMinFilter +} from "./GLTFSchema"; import { BufferInfo, GLTFParserContext } from "./parser/GLTFParserContext"; +import { GLTFTextureParser } from "./parser"; /** * @internal @@ -448,16 +466,48 @@ export class GLTFUtils { }; } - private static _formatRelativePath(path: string): string { - // For example input is "a/b", "/a/b", "./a/b", "./a/./b", "./a/../a/b", output is "a/b" - return path - .split("/") - .filter(Boolean) - .reduce((acc, cur) => { - if (cur === "..") acc.pop(); - else if (cur !== ".") acc.push(cur); - return acc; - }, []) - .join("/"); + static parseSampler(texture: Texture2D, samplerInfo: ISamplerInfo): void { + const { filterMode, wrapModeU, wrapModeV } = samplerInfo; + + if (filterMode !== undefined) { + texture.filterMode = filterMode; + } + + if (wrapModeU !== undefined) { + texture.wrapModeU = wrapModeU; + } + + if (wrapModeV !== undefined) { + texture.wrapModeV = wrapModeV; + } + } + + static getSamplerInfo(sampler: ISampler): ISamplerInfo { + const { minFilter, magFilter, wrapS, wrapT } = sampler; + const info = {}; + + if (minFilter || magFilter) { + info.mipmap = minFilter >= TextureMinFilter.NEAREST_MIPMAP_NEAREST; + + if (magFilter === TextureMagFilter.NEAREST) { + info.filterMode = TextureFilterMode.Point; + } else { + if (minFilter <= TextureMinFilter.LINEAR_MIPMAP_NEAREST) { + info.filterMode = TextureFilterMode.Bilinear; + } else { + info.filterMode = TextureFilterMode.Trilinear; + } + } + } + + if (wrapS) { + info.wrapModeU = GLTFTextureParser._wrapMap[wrapS]; + } + + if (wrapT) { + info.wrapModeV = GLTFTextureParser._wrapMap[wrapT]; + } + + return info; } } diff --git a/packages/loader/src/gltf/extensions/KHR_texture_basisu.ts b/packages/loader/src/gltf/extensions/KHR_texture_basisu.ts index e69de29bb2..fe3cb1073b 100644 --- a/packages/loader/src/gltf/extensions/KHR_texture_basisu.ts +++ b/packages/loader/src/gltf/extensions/KHR_texture_basisu.ts @@ -0,0 +1,67 @@ +import { AssetType, Texture2D, Utils } from "@galacean/engine-core"; +import type { ITexture } from "../GLTFSchema"; +import { registerGLTFExtension } from "../parser/GLTFParser"; +import { GLTFParserContext } from "../parser/GLTFParserContext"; +import { GLTFExtensionMode, GLTFExtensionParser } from "./GLTFExtensionParser"; +import { GLTFUtils } from "../GLTFUtils"; +import { BufferTextureRestoreInfo } from "../../GLTFContentRestorer"; +import { KTX2Loader } from "../../ktx2/KTX2Loader"; + +interface KHRBasisSchema { + source: number; +} + +@registerGLTFExtension("KHR_texture_basisu", GLTFExtensionMode.CreateAndParse) +class KHR_texture_basisu extends GLTFExtensionParser { + override async createAndParse( + context: GLTFParserContext, + schema: KHRBasisSchema, + textureInfo: ITexture + ): Promise { + const { glTF, glTFResource } = context; + const { engine, url } = glTFResource; + + const { sampler, name: textureName } = textureInfo; + const { source } = schema; + const { uri, bufferView: bufferViewIndex, mimeType, name: imageName } = glTF.images[source]; + const samplerInfo = sampler !== undefined && GLTFUtils.getSamplerInfo(glTF.samplers[sampler]); + if (uri) { + const index = uri.lastIndexOf("."); + return engine.resourceManager + .load({ + url: Utils.resolveAbsoluteUrl(url, uri), + type: AssetType.KTX2 + }) + .then((texture) => { + if (!texture.name) { + texture.name = textureName || imageName || `texture_${index}`; + } + if (sampler !== undefined) { + GLTFUtils.parseSampler(texture, samplerInfo); + } + return texture; + }); + } else { + const bufferView = glTF.bufferViews[bufferViewIndex]; + + return context.getBuffers().then((buffers) => { + const buffer = buffers[bufferView.buffer]; + const imageBuffer = new Uint8Array(buffer, bufferView.byteOffset, bufferView.byteLength); + + return KTX2Loader._parseBuffer(imageBuffer, engine) + .then(({ engine, result, targetFormat, params }) => + KTX2Loader._createTextureByBuffer(engine, result, targetFormat, params) + ) + .then((texture: Texture2D) => { + texture.name = textureName || imageName || `texture_${bufferViewIndex}`; + if (sampler !== undefined) { + GLTFUtils.parseSampler(texture, samplerInfo); + } + const bufferTextureRestoreInfo = new BufferTextureRestoreInfo(texture, bufferView, mimeType); + context.contentRestorer.bufferTextures.push(bufferTextureRestoreInfo); + return texture; + }); + }); + } + } +} diff --git a/packages/loader/src/gltf/parser/GLTFEntityParser.ts b/packages/loader/src/gltf/parser/GLTFEntityParser.ts index 0921ad0f77..ff93ac22dd 100644 --- a/packages/loader/src/gltf/parser/GLTFEntityParser.ts +++ b/packages/loader/src/gltf/parser/GLTFEntityParser.ts @@ -95,5 +95,9 @@ export class GLTFEntityParser extends GLTFParser { glTFResource.sceneRoots = sceneRoots; glTFResource.defaultSceneRoot = sceneRoots[sceneID]; + // @ts-ignore + glTFResource.defaultSceneRoot._hookResource = glTFResource; + // @ts-ignore + glTFResource._addReferCount(1); } } diff --git a/packages/loader/src/gltf/parser/GLTFTextureParser.ts b/packages/loader/src/gltf/parser/GLTFTextureParser.ts index 57a5b2beb6..6810e5d99d 100644 --- a/packages/loader/src/gltf/parser/GLTFTextureParser.ts +++ b/packages/loader/src/gltf/parser/GLTFTextureParser.ts @@ -1,20 +1,13 @@ -import { - AssetPromise, - AssetType, - Texture, - Texture2D, - TextureFilterMode, - TextureWrapMode, - Utils -} from "@galacean/engine-core"; +import { AssetPromise, AssetType, Texture, Texture2D, TextureWrapMode, Utils } from "@galacean/engine-core"; import { BufferTextureRestoreInfo } from "../../GLTFContentRestorer"; -import { TextureWrapMode as GLTFTextureWrapMode, ISampler, TextureMagFilter, TextureMinFilter } from "../GLTFSchema"; +import { TextureWrapMode as GLTFTextureWrapMode } from "../GLTFSchema"; import { GLTFUtils } from "../GLTFUtils"; import { GLTFParser } from "./GLTFParser"; import { GLTFParserContext } from "./GLTFParserContext"; export class GLTFTextureParser extends GLTFParser { - private static _wrapMap = { + /** @internal */ + static _wrapMap = { [GLTFTextureWrapMode.CLAMP_TO_EDGE]: TextureWrapMode.Clamp, [GLTFTextureWrapMode.MIRRORED_REPEAT]: TextureWrapMode.Mirror, [GLTFTextureWrapMode.REPEAT]: TextureWrapMode.Repeat @@ -37,9 +30,9 @@ export class GLTFTextureParser extends GLTFParser { ); if (!texture) { - const samplerInfo = sampler !== undefined && this._getSamplerInfo(glTF.samplers[sampler]); + const samplerInfo = sampler !== undefined && GLTFUtils.getSamplerInfo(glTF.samplers[sampler]); if (uri) { - // TODO: support ktx extension https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_texture_basisu/README.md + // TODO: deleted in 2.0 const index = uri.lastIndexOf("."); const ext = uri.substring(index + 1); const type = ext.startsWith("ktx") ? AssetType.KTX : AssetType.Texture2D; @@ -56,7 +49,7 @@ export class GLTFTextureParser extends GLTFParser { texture.name = textureName || imageName || `texture_${index}`; } if (sampler !== undefined) { - this._parseSampler(texture, samplerInfo); + GLTFUtils.parseSampler(texture, samplerInfo); } return texture; }); @@ -73,7 +66,7 @@ export class GLTFTextureParser extends GLTFParser { texture.generateMipmaps(); texture.name = textureName || imageName || `texture_${index}`; if (sampler !== undefined) { - this._parseSampler(texture, samplerInfo); + GLTFUtils.parseSampler(texture, samplerInfo); } const bufferTextureRestoreInfo = new BufferTextureRestoreInfo(texture, bufferView, mimeType); context.contentRestorer.bufferTextures.push(bufferTextureRestoreInfo); @@ -98,56 +91,4 @@ export class GLTFTextureParser extends GLTFParser { return texturesPromiseInfo.promise; } } - - private _getSamplerInfo(sampler: ISampler): ISamplerInfo { - const { minFilter, magFilter, wrapS, wrapT } = sampler; - const info = {}; - - if (minFilter || magFilter) { - info.mipmap = minFilter >= TextureMinFilter.NEAREST_MIPMAP_NEAREST; - - if (magFilter === TextureMagFilter.NEAREST) { - info.filterMode = TextureFilterMode.Point; - } else { - if (minFilter <= TextureMinFilter.LINEAR_MIPMAP_NEAREST) { - info.filterMode = TextureFilterMode.Bilinear; - } else { - info.filterMode = TextureFilterMode.Trilinear; - } - } - } - - if (wrapS) { - info.wrapModeU = GLTFTextureParser._wrapMap[wrapS]; - } - - if (wrapT) { - info.wrapModeV = GLTFTextureParser._wrapMap[wrapT]; - } - - return info; - } - - private _parseSampler(texture: Texture2D, samplerInfo: ISamplerInfo): void { - const { filterMode, wrapModeU, wrapModeV } = samplerInfo; - - if (filterMode !== undefined) { - texture.filterMode = filterMode; - } - - if (wrapModeU !== undefined) { - texture.wrapModeU = wrapModeU; - } - - if (wrapModeV !== undefined) { - texture.wrapModeV = wrapModeV; - } - } -} - -interface ISamplerInfo { - filterMode?: TextureFilterMode; - wrapModeU?: TextureWrapMode; - wrapModeV?: TextureWrapMode; - mipmap?: boolean; } diff --git a/packages/loader/src/ktx2/KTX2Container.ts b/packages/loader/src/ktx2/KTX2Container.ts index 0af6dfcb68..ea32bdc079 100644 --- a/packages/loader/src/ktx2/KTX2Container.ts +++ b/packages/loader/src/ktx2/KTX2Container.ts @@ -44,7 +44,7 @@ export class KTX2Container { globalData: KTX2GlobalDataBasisLZ | null = null; - constructor(buffer: ArrayBuffer) { + constructor(buffer: Uint8Array) { this.parse(buffer); } @@ -56,8 +56,10 @@ export class KTX2Container { return this.dataFormatDescriptor.colorModel === ColorModel.UASTC; } - private parse(buffer: ArrayBuffer) { - const headerBufferReader = new BufferReader(buffer, 12, 68); + private parse(data: Uint8Array) { + const buffer = data.buffer; + const byteOffset = data.byteOffset; + const headerBufferReader = new BufferReader(data, 12); this.vkFormat = headerBufferReader.nextUint32(); this.typeSize = headerBufferReader.nextUint32(); this.pixelWidth = headerBufferReader.nextUint32(); @@ -82,17 +84,17 @@ export class KTX2Container { // level index const ktxLevels = new Array(levelCount); const levelByteLength = levelCount * 3 * 8; - const levelReader = new BufferReader(buffer, headerBufferReader.offset, levelByteLength, true); + const levelReader = new BufferReader(data, headerBufferReader.offset, levelByteLength); this.levels = ktxLevels; for (let i = 0; i < levelCount; i++) { ktxLevels[i] = { - levelData: new Uint8Array(buffer, levelReader.nextUint64(), levelReader.nextUint64()), + levelData: new Uint8Array(buffer, byteOffset + levelReader.nextUint64(), levelReader.nextUint64()), uncompressedByteLength: levelReader.nextUint64() }; } // Data Format Descriptor (DFD). - const dfdReader = new BufferReader(buffer, dfdByteOffset, dfdByteLength, true); + const dfdReader = new BufferReader(data, dfdByteOffset, dfdByteLength); const dfd: KTX2DataFormatDescriptorBasicFormat = { vendorId: dfdReader.skip(4 /* totalSize */).nextUint16(), @@ -144,7 +146,7 @@ export class KTX2Container { dfd.samples[i] = sample; } - const kvdReader = new BufferReader(buffer, kvdByteOffset, kvdByteLength, true); + const kvdReader = new BufferReader(data, kvdByteOffset, kvdByteLength, true); while (kvdReader.position < kvdByteLength) { const keyValueByteLength = kvdReader.nextUint32(); @@ -152,15 +154,17 @@ export class KTX2Container { const key = Utils.decodeText(keyData); // 4-byte alignment. - const kvPadding = keyValueByteLength % 4 ? 4 - (keyValueByteLength % 4) : 0; - const valueData = kvdReader.nextUint8Array(keyValueByteLength - keyData.byteLength - 2); - this.keyValue[key] = key.match(/^ktx/i) ? Utils.decodeText(valueData) : valueData; - kvdReader.skip(kvPadding + 1); + const valueData = kvdReader.nextUint8Array(keyValueByteLength - keyData.byteLength - 1); + this.keyValue[key] = key.match(/^ktx/i) ? Utils.decodeText(valueData).replace(/^(.*)\x00$/, "$1") : valueData; + + const kvPadding = keyValueByteLength % 4 ? 4 - (keyValueByteLength % 4) : 0; // align(4) + // 4-byte alignment. + kvdReader.skip(kvPadding); } if (sgdByteLength <= 0) return this; - const sgdReader = new BufferReader(buffer, sgdByteOffset, sgdByteLength, true); + const sgdReader = new BufferReader(data, sgdByteOffset, sgdByteLength, true); const endpointCount = sgdReader.nextUint16(); const selectorCount = sgdReader.nextUint16(); @@ -186,10 +190,10 @@ export class KTX2Container { const tablesByteOffset = selectorsByteOffset + selectorsByteLength; const extendedByteOffset = tablesByteOffset + tablesByteLength; - const endpointsData = new Uint8Array(buffer, endpointsByteOffset, endpointsByteLength); - const selectorsData = new Uint8Array(buffer, selectorsByteOffset, selectorsByteLength); - const tablesData = new Uint8Array(buffer, tablesByteOffset, tablesByteLength); - const extendedData = new Uint8Array(buffer, extendedByteOffset, extendedByteLength); + const endpointsData = new Uint8Array(buffer, byteOffset + endpointsByteOffset, endpointsByteLength); + const selectorsData = new Uint8Array(buffer, byteOffset + selectorsByteOffset, selectorsByteLength); + const tablesData = new Uint8Array(buffer, byteOffset + tablesByteOffset, tablesByteLength); + const extendedData = new Uint8Array(buffer, byteOffset + extendedByteOffset, extendedByteLength); this.globalData = { endpointCount, diff --git a/packages/loader/src/ktx2/KTX2Loader.ts b/packages/loader/src/ktx2/KTX2Loader.ts index 9b890af62a..78403e3f7c 100644 --- a/packages/loader/src/ktx2/KTX2Loader.ts +++ b/packages/loader/src/ktx2/KTX2Loader.ts @@ -43,6 +43,62 @@ export class KTX2Loader extends Loader { if (this._khronosTranscoder) this._khronosTranscoder.destroy(); this._binomialLLCTranscoder = null; this._khronosTranscoder = null; + this._isBinomialInit = false; + } + + /** @internal */ + static _parseBuffer(buffer: Uint8Array, engine: Engine, params?: KTX2Params) { + const ktx2Container = new KTX2Container(buffer); + const formatPriorities = params?.priorityFormats; + const targetFormat = KTX2Loader._decideTargetFormat(engine, ktx2Container, formatPriorities); + let transcodeResultPromise: Promise; + if (KTX2Loader._isBinomialInit || !KhronosTranscoder.transcoderMap[targetFormat] || !ktx2Container.isUASTC) { + const binomialLLCWorker = KTX2Loader._getBinomialLLCTranscoder(); + transcodeResultPromise = binomialLLCWorker.init().then(() => binomialLLCWorker.transcode(buffer, targetFormat)); + } else { + const khronosWorker = KTX2Loader._getKhronosTranscoder(); + transcodeResultPromise = khronosWorker.init().then(() => khronosWorker.transcode(ktx2Container)); + } + return transcodeResultPromise.then((result) => { + return { engine, result, targetFormat, params: ktx2Container.keyValue["GalaceanTextureParams"] as Uint8Array }; + }); + } + + /** @internal */ + static _createTextureByBuffer( + engine: Engine, + transcodeResult: TranscodeResult, + targetFormat: KTX2TargetFormat, + params?: Uint8Array + ): Texture2D | TextureCube { + const { width, height, faces } = transcodeResult; + const faceCount = faces.length; + const mipmaps = faces[0]; + const mipmap = mipmaps.length > 1; + const engineFormat = this._getEngineTextureFormat(targetFormat, transcodeResult); + let texture: Texture2D | TextureCube; + if (faceCount !== 6) { + texture = new Texture2D(engine, width, height, engineFormat, mipmap); + for (let mipLevel = 0; mipLevel < mipmaps.length; mipLevel++) { + const { data } = mipmaps[mipLevel]; + texture.setPixelBuffer(data, mipLevel); + } + } else { + texture = new TextureCube(engine, height, engineFormat, mipmap); + for (let i = 0; i < faces.length; i++) { + const faceData = faces[i]; + for (let mipLevel = 0; mipLevel < mipmaps.length; mipLevel++) { + texture.setPixelBuffer(TextureCubeFace.PositiveX + i, faceData[mipLevel].data, mipLevel); + } + } + } + if (params) { + texture.wrapModeU = params[0]; + texture.wrapModeV = params[1]; + texture.filterMode = params[2]; + texture.anisoLevel = params[3]; + } + return texture as Texture2D | TextureCube; } private static _decideTargetFormat( @@ -101,6 +157,27 @@ export class KTX2Loader extends Loader { return (this._khronosTranscoder ??= new KhronosTranscoder(workerCount, KTX2TargetFormat.ASTC)); } + private static _getEngineTextureFormat( + basisFormat: KTX2TargetFormat, + transcodeResult: TranscodeResult + ): TextureFormat { + const { hasAlpha } = transcodeResult; + switch (basisFormat) { + case KTX2TargetFormat.ASTC: + return TextureFormat.ASTC_4x4; + case KTX2TargetFormat.ETC: + return hasAlpha ? TextureFormat.ETC2_RGBA8 : TextureFormat.ETC2_RGB; + case KTX2TargetFormat.BC7: + return TextureFormat.BC7; + case KTX2TargetFormat.BC1_BC3: + return hasAlpha ? TextureFormat.BC3 : TextureFormat.BC1; + case KTX2TargetFormat.PVRTC: + return hasAlpha ? TextureFormat.PVRTC_RGBA4 : TextureFormat.PVRTC_RGB4; + case KTX2TargetFormat.R8G8B8A8: + return TextureFormat.R8G8B8A8; + } + } + override initialize(engine: Engine, configuration: EngineConfiguration): Promise { if (configuration.ktx2Loader) { const options = configuration.ktx2Loader; @@ -119,68 +196,12 @@ export class KTX2Loader extends Loader { item: LoadItem & { params?: KTX2Params }, resourceManager: ResourceManager ): AssetPromise { - return this.request(item.url!, { type: "arraybuffer" }).then((buffer) => { - const ktx2Container = new KTX2Container(buffer); - const formatPriorities = item.params?.priorityFormats; - const targetFormat = KTX2Loader._decideTargetFormat(resourceManager.engine, ktx2Container, formatPriorities); - let transcodeResultPromise: Promise; - if (KTX2Loader._isBinomialInit || !KhronosTranscoder.transcoderMap[targetFormat] || !ktx2Container.isUASTC) { - const binomialLLCWorker = KTX2Loader._getBinomialLLCTranscoder(); - transcodeResultPromise = binomialLLCWorker.init().then(() => binomialLLCWorker.transcode(buffer, targetFormat)); - } else { - const khronosWorker = KTX2Loader._getKhronosTranscoder(); - transcodeResultPromise = khronosWorker.init().then(() => khronosWorker.transcode(ktx2Container)); - } - return transcodeResultPromise.then((result) => { - const { width, height, faces } = result; - const faceCount = faces.length; - const mipmaps = faces[0]; - const mipmap = mipmaps.length > 1; - const engineFormat = this._getEngineTextureFormat(targetFormat, result); - let texture: Texture; - if (faceCount !== 6) { - texture = new Texture2D(resourceManager.engine, width, height, engineFormat, mipmap); - for (let mipLevel = 0; mipLevel < mipmaps.length; mipLevel++) { - const { data } = mipmaps[mipLevel]; - (texture as Texture2D).setPixelBuffer(data, mipLevel); - } - } else { - texture = new TextureCube(resourceManager.engine, height, engineFormat, mipmap); - for (let i = 0; i < faces.length; i++) { - const faceData = faces[i]; - for (let mipLevel = 0; mipLevel < mipmaps.length; mipLevel++) { - (texture as TextureCube).setPixelBuffer(TextureCubeFace.PositiveX + i, faceData[mipLevel].data, mipLevel); - } - } - } - const params = ktx2Container.keyValue["GalaceanTextureParams"] as Uint8Array; - if (params) { - texture.wrapModeU = params[0]; - texture.wrapModeV = params[1]; - texture.filterMode = params[2]; - texture.anisoLevel = params[3]; - } - return texture as Texture2D | TextureCube; - }); - }); - } - - private _getEngineTextureFormat(basisFormat: KTX2TargetFormat, transcodeResult: TranscodeResult): TextureFormat { - const { hasAlpha } = transcodeResult; - switch (basisFormat) { - case KTX2TargetFormat.ASTC: - return TextureFormat.ASTC_4x4; - case KTX2TargetFormat.ETC: - return hasAlpha ? TextureFormat.ETC2_RGBA8 : TextureFormat.ETC2_RGB; - case KTX2TargetFormat.BC7: - return TextureFormat.BC7; - case KTX2TargetFormat.BC1_BC3: - return hasAlpha ? TextureFormat.BC3 : TextureFormat.BC1; - case KTX2TargetFormat.PVRTC: - return hasAlpha ? TextureFormat.PVRTC_RGBA4 : TextureFormat.PVRTC_RGB4; - case KTX2TargetFormat.R8G8B8A8: - return TextureFormat.R8G8B8A8; - } + return this.request(item.url!, { type: "arraybuffer" }).then((buffer) => + KTX2Loader._parseBuffer(new Uint8Array(buffer), resourceManager.engine, item.params).then( + ({ engine, result, targetFormat, params }) => + KTX2Loader._createTextureByBuffer(engine, result, targetFormat, params) + ) + ); } private _isKhronosSupported( diff --git a/packages/loader/src/ktx2/transcoder/BinomialLLCWorkerCode.ts b/packages/loader/src/ktx2/transcoder/BinomialLLCWorkerCode.ts index f63809b18d..d161d33ad4 100644 --- a/packages/loader/src/ktx2/transcoder/BinomialLLCWorkerCode.ts +++ b/packages/loader/src/ktx2/transcoder/BinomialLLCWorkerCode.ts @@ -11,15 +11,17 @@ export function TranscodeWorkerCode() { BC3 = 3, BC4 = 4, BC5 = 5, + BC7 = 7, PVRTC1_4_RGB = 8, PVRTC1_4_RGBA = 9, + ASTC_4x4 = 10, RGBA8 = 13 } enum TargetFormat { ASTC, BC7, - DXT, + BC1_BC3, PVRTC, ETC, R8, @@ -70,29 +72,19 @@ export function TranscodeWorkerCode() { }; function getTranscodeFormatFromTarget(target: TargetFormat, hasAlpha: boolean) { - if (target === TargetFormat.DXT) { - if (hasAlpha) { - return BasisFormat.BC3; - } else { - return BasisFormat.BC1; - } - } - if (target === TargetFormat.ETC) { - if (hasAlpha) { - return BasisFormat.ETC2; - } else { - return BasisFormat.ETC1; - } - } - if (target === TargetFormat.PVRTC) { - if (hasAlpha) { - return BasisFormat.PVRTC1_4_RGBA; - } else { - return BasisFormat.PVRTC1_4_RGB; - } - } - if (target === TargetFormat.RGBA8) { - return BasisFormat.RGBA8; + switch (target) { + case TargetFormat.BC1_BC3: + return hasAlpha ? BasisFormat.BC3 : BasisFormat.BC1; + case TargetFormat.ETC: + return hasAlpha ? BasisFormat.ETC2 : BasisFormat.ETC1; + case TargetFormat.PVRTC: + return hasAlpha ? BasisFormat.PVRTC1_4_RGBA : BasisFormat.PVRTC1_4_RGB; + case TargetFormat.RGBA8: + return BasisFormat.RGBA8; + case TargetFormat.ASTC: + return BasisFormat.ASTC_4x4; + case TargetFormat.BC7: + return BasisFormat.BC7; } } diff --git a/packages/loader/src/resource-deserialize/index.ts b/packages/loader/src/resource-deserialize/index.ts index 064ec78e59..1ca3bdccf9 100644 --- a/packages/loader/src/resource-deserialize/index.ts +++ b/packages/loader/src/resource-deserialize/index.ts @@ -18,7 +18,7 @@ export type { IModelMesh } from "./resources/mesh/IModelMesh"; */ export function decode(arrayBuffer: ArrayBuffer, engine: Engine): Promise { const header = FileHeader.decode(arrayBuffer); - const bufferReader = new BufferReader(arrayBuffer, header.headerLength, header.dataLength); + const bufferReader = new BufferReader(new Uint8Array(arrayBuffer), header.headerLength, header.dataLength); return decoderMap[header.type].decode(engine, bufferReader).then((object) => { object.name = header.name; return object; diff --git a/packages/loader/src/resource-deserialize/resources/mesh/MeshDecoder.ts b/packages/loader/src/resource-deserialize/resources/mesh/MeshDecoder.ts index bec4976034..4d386846b6 100644 --- a/packages/loader/src/resource-deserialize/resources/mesh/MeshDecoder.ts +++ b/packages/loader/src/resource-deserialize/resources/mesh/MeshDecoder.ts @@ -20,10 +20,12 @@ export class MeshDecoder { encodedMeshData.bounds && modelMesh.bounds.copyFrom(encodedMeshData.bounds); const offset = Math.ceil(bufferReader.offset / 4) * 4; + const buffer = bufferReader.data.buffer; + const byteOffset = bufferReader.data.byteOffset; const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.positions.start + offset, + buffer, + encodedMeshData.positions.start + offset + byteOffset, (encodedMeshData.positions.end - encodedMeshData.positions.start) / 4 ); const vertexCount = float32Array.length / 3; @@ -31,8 +33,8 @@ export class MeshDecoder { modelMesh.setPositions(positions); if (encodedMeshData.normals) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.normals.start + offset, + buffer, + encodedMeshData.normals.start + offset + byteOffset, (encodedMeshData.normals.end - encodedMeshData.normals.start) / 4 ); const normals = float32ArrayToVector3(float32Array, vertexCount); @@ -40,88 +42,88 @@ export class MeshDecoder { } if (encodedMeshData.uvs) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.uvs.start + offset, + buffer, + encodedMeshData.uvs.start + offset + byteOffset, (encodedMeshData.uvs.end - encodedMeshData.uvs.start) / 4 ); modelMesh.setUVs(float32ArrayToVector2(float32Array, vertexCount)); } if (encodedMeshData.uv1) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.uv1.start + offset, + buffer, + encodedMeshData.uv1.start + offset + byteOffset, (encodedMeshData.uv1.end - encodedMeshData.uv1.start) / 4 ); modelMesh.setUVs(float32ArrayToVector2(float32Array, vertexCount), 1); } if (encodedMeshData.uv2) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.uv2.start + offset, + buffer, + encodedMeshData.uv2.start + offset + byteOffset, (encodedMeshData.uv2.end - encodedMeshData.uv2.start) / 4 ); modelMesh.setUVs(float32ArrayToVector2(float32Array, vertexCount), 2); } if (encodedMeshData.uv3) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.uv3.start + offset, + buffer, + encodedMeshData.uv3.start + offset + byteOffset, (encodedMeshData.uv3.end - encodedMeshData.uv3.start) / 4 ); modelMesh.setUVs(float32ArrayToVector2(float32Array, vertexCount), 3); } if (encodedMeshData.uv4) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.uv4.start + offset, + buffer, + encodedMeshData.uv4.start + offset + byteOffset, (encodedMeshData.uv4.end - encodedMeshData.uv4.start) / 4 ); modelMesh.setUVs(float32ArrayToVector2(float32Array, vertexCount), 4); } if (encodedMeshData.uv5) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.uv5.start + offset, + buffer, + encodedMeshData.uv5.start + offset + byteOffset, (encodedMeshData.uv5.end - encodedMeshData.uv5.start) / 4 ); modelMesh.setUVs(float32ArrayToVector2(float32Array, vertexCount), 5); } if (encodedMeshData.uv6) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.uv6.start + offset, + buffer, + encodedMeshData.uv6.start + offset + byteOffset, (encodedMeshData.uv6.end - encodedMeshData.uv6.start) / 4 ); modelMesh.setUVs(float32ArrayToVector2(float32Array, vertexCount), 6); } if (encodedMeshData.uv7) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.uv7.start + offset, + buffer, + encodedMeshData.uv7.start + offset + byteOffset, (encodedMeshData.uv7.end - encodedMeshData.uv7.start) / 4 ); modelMesh.setUVs(float32ArrayToVector2(float32Array, vertexCount), 7); } if (encodedMeshData.colors) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.colors.start + offset, + buffer, + encodedMeshData.colors.start + offset + byteOffset, (encodedMeshData.colors.end - encodedMeshData.colors.start) / 4 ); modelMesh.setColors(float32ArrayToVColor(float32Array, vertexCount)); } if (encodedMeshData.boneWeights) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.boneWeights.start + offset, + buffer, + encodedMeshData.boneWeights.start + offset + byteOffset, (encodedMeshData.boneWeights.end - encodedMeshData.boneWeights.start) / 4 ); modelMesh.setBoneWeights(float32ArrayToVector4(float32Array, vertexCount)); } if (encodedMeshData.boneIndices) { const float32Array = new Float32Array( - bufferReader.buffer, - encodedMeshData.boneIndices.start + offset, + buffer, + encodedMeshData.boneIndices.start + offset + byteOffset, (encodedMeshData.boneIndices.end - encodedMeshData.boneIndices.start) / 4 ); modelMesh.setBoneIndices(float32ArrayToVector4(float32Array, vertexCount)); @@ -131,8 +133,8 @@ export class MeshDecoder { const blendShape = new BlendShape(blendShapeData.name); blendShapeData.frames.forEach((frameData) => { const positionArray = new Float32Array( - bufferReader.buffer, - frameData.deltaPosition.start + offset, + buffer, + frameData.deltaPosition.start + offset + byteOffset, (frameData.deltaPosition.end - frameData.deltaPosition.start) / 4 ); const count = positionArray.length / 3; @@ -140,8 +142,8 @@ export class MeshDecoder { let deltaNormals: Vector3[] | null = null; if (frameData.deltaNormals) { const normalsArray = new Float32Array( - bufferReader.buffer, - frameData.deltaNormals.start + offset, + buffer, + frameData.deltaNormals.start + offset + byteOffset, (frameData.deltaNormals.end - frameData.deltaNormals.start) / 4 ); deltaNormals = float32ArrayToVector3(normalsArray, count); @@ -149,8 +151,8 @@ export class MeshDecoder { let deltaTangents: Vector4[] | null = null; if (frameData.deltaTangents) { const tangentsArray = new Float32Array( - bufferReader.buffer, - frameData.deltaTangents.start + offset, + buffer, + frameData.deltaTangents.start + offset + byteOffset, (frameData.deltaTangents.end - frameData.deltaTangents.start) / 4 ); deltaTangents = float32ArrayToVector4(tangentsArray, count); @@ -164,14 +166,14 @@ export class MeshDecoder { let indices: Uint16Array | Uint32Array = null; if (encodedMeshData.indices.type === 0) { indices = new Uint16Array( - bufferReader.buffer, - encodedMeshData.indices.start + offset, + buffer, + encodedMeshData.indices.start + offset + byteOffset, (encodedMeshData.indices.end - encodedMeshData.indices.start) / 2 ); } else { indices = new Uint32Array( - bufferReader.buffer, - encodedMeshData.indices.start + offset, + buffer, + encodedMeshData.indices.start + offset + byteOffset, (encodedMeshData.indices.end - encodedMeshData.indices.start) / 4 ); } diff --git a/packages/loader/src/resource-deserialize/resources/texture2D/TextureDecoder.ts b/packages/loader/src/resource-deserialize/resources/texture2D/TextureDecoder.ts index 3be25877b5..21b1eb38ab 100644 --- a/packages/loader/src/resource-deserialize/resources/texture2D/TextureDecoder.ts +++ b/packages/loader/src/resource-deserialize/resources/texture2D/TextureDecoder.ts @@ -27,12 +27,12 @@ export class Texture2DDecoder { texture2D.wrapModeV = wrapModeV; if (isPixelBuffer) { - const pixelBuffer = new Uint8Array(imagesData[0]); + const pixelBuffer = imagesData[0]; texture2D.setPixelBuffer(pixelBuffer); if (mipmap) { texture2D.generateMipmaps(); for (let i = 1; i < mipCount; i++) { - const pixelBuffer = new Uint8Array(imagesData[i]); + const pixelBuffer = imagesData[i]; texture2D.setPixelBuffer(pixelBuffer, i); } } diff --git a/packages/loader/src/resource-deserialize/utils/BufferReader.ts b/packages/loader/src/resource-deserialize/utils/BufferReader.ts index cff2955f12..c18ce702b3 100644 --- a/packages/loader/src/resource-deserialize/utils/BufferReader.ts +++ b/packages/loader/src/resource-deserialize/utils/BufferReader.ts @@ -6,24 +6,27 @@ export class BufferReader { private _baseOffset: number; constructor( - public buffer: ArrayBuffer, + public data: Uint8Array, byteOffset: number = 0, byteLength?: number, littleEndian: boolean = true ) { - // byteLength = byteLength ?? _buffer.byteLength; - this._dataView = new DataView(buffer); + this._dataView = new DataView( + data.buffer, + data.byteOffset + byteOffset, + byteLength ?? data.byteLength - byteOffset + ); this._littleEndian = littleEndian; - this._offset = byteOffset; + this._offset = 0; this._baseOffset = byteOffset; } get position() { - return this._offset - this._baseOffset; + return this._offset; } get offset() { - return this._offset; + return this._offset + this._baseOffset; } nextUint8() { @@ -51,7 +54,7 @@ export class BufferReader { } nextInt32Array(len: number) { - const value = new Int32Array(this.buffer, this._offset, len); + const value = new Int32Array(this.data.buffer, this._offset + this._dataView.byteOffset, len); this._offset += 4 * len; return value; } @@ -63,19 +66,19 @@ export class BufferReader { } nextFloat32Array(len: number) { - const value = new Float32Array(this.buffer, this._offset, len); + const value = new Float32Array(this.data.buffer, this._offset + this._dataView.byteOffset, len); this._offset += 4 * len; return value; } nextUint32Array(len: number) { - const value = new Uint32Array(this.buffer, this._offset, len); + const value = new Uint32Array(this.data.buffer, this._offset + this._dataView.byteOffset, len); this._offset += 4 * len; return value; } nextUint8Array(len: number) { - const value = new Uint8Array(this.buffer, this._offset, len); + const value = new Uint8Array(this.data.buffer, this._offset + this._dataView.byteOffset, len); this._offset += len; return value; } @@ -90,7 +93,7 @@ export class BufferReader { nextStr(): string { const strByteLength = this.nextUint16(); - const uint8Array = new Uint8Array(this.buffer, this._offset, strByteLength); + const uint8Array = new Uint8Array(this.data.buffer, this._offset + this._dataView.byteOffset, strByteLength); this._offset += strByteLength; return Utils.decodeText(uint8Array); } @@ -98,11 +101,11 @@ export class BufferReader { /** * image data 放在最后 */ - nextImageData(count: number = 0): ArrayBuffer { - return this.buffer.slice(this._offset); + nextImageData(count: number = 0): Uint8Array { + return new Uint8Array(this.data.buffer, this.data.byteOffset + this._offset); } - nextImagesData(count: number): ArrayBuffer[] { + nextImagesData(count: number): Uint8Array[] { const imagesLen = new Array(count); // Start offset of Uint32Array should be a multiple of 4. ref: https://stackoverflow.com/questions/15417310/why-typed-array-constructors-require-offset-to-be-multiple-of-underlying-type-si for (let i = 0; i < count; i++) { @@ -110,11 +113,11 @@ export class BufferReader { imagesLen[i] = len; this._offset += 4; } - const imagesData: ArrayBuffer[] = []; + const imagesData: Uint8Array[] = []; for (let i = 0; i < count; i++) { const len = imagesLen[i]; - const buffer = this.buffer.slice(this._offset, this._offset + len); + const buffer = new Uint8Array(this.data.buffer, this._dataView.byteOffset + this._offset, len); this._offset += len; imagesData.push(buffer); } diff --git a/packages/math/src/Rect.ts b/packages/math/src/Rect.ts index b10aeb832b..415779fce4 100644 --- a/packages/math/src/Rect.ts +++ b/packages/math/src/Rect.ts @@ -3,14 +3,64 @@ import { ICopy } from "./ICopy"; // A 2d rectangle defined by x and y position, width and height. export class Rect implements IClone, ICopy { - /** The x coordinate of the rectangle. */ - public x: number; - /** The y coordinate of the rectangle. */ - public y: number; - /** The width of the rectangle, measured from the x position. */ - public width: number; - /** The height of the rectangle, measured from the y position. */ - public height: number; + /** @internal */ + _x: number; + /** @internal */ + _y: number; + /** @internal */ + _width: number; + /** @internal */ + _height: number; + /** @internal */ + _onValueChanged: () => void = null; + + /** + * The x coordinate of the rectangle. + */ + get x(): number { + return this._x; + } + + set x(value: number) { + this._x = value; + this._onValueChanged && this._onValueChanged(); + } + + /** + * The y coordinate of the rectangle. + */ + get y(): number { + return this._y; + } + + set y(value: number) { + this._y = value; + this._onValueChanged && this._onValueChanged(); + } + + /** + * The width of the rectangle, measured from the x position. + */ + get width(): number { + return this._width; + } + + set width(value: number) { + this._width = value; + this._onValueChanged && this._onValueChanged(); + } + + /** + * The height of the rectangle, measured from the y position. + */ + get height(): number { + return this._height; + } + + set height(value: number) { + this._height = value; + this._onValueChanged && this._onValueChanged(); + } /** * Constructor of Rect. @@ -20,10 +70,10 @@ export class Rect implements IClone, ICopy { * @param height - The height of the rectangle, measured from the y position, default 0 */ constructor(x: number = 0, y: number = 0, width: number = 0, height: number = 0) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; + this._x = x; + this._y = y; + this._width = width; + this._height = height; } /** @@ -35,10 +85,11 @@ export class Rect implements IClone, ICopy { * @returns This rectangle */ set(x: number, y: number, width: number, height: number): Rect { - this.x = x; - this.y = y; - this.width = width; - this.height = height; + this._x = x; + this._y = y; + this._width = width; + this._height = height; + this._onValueChanged && this._onValueChanged(); return this; } @@ -56,10 +107,11 @@ export class Rect implements IClone, ICopy { * @returns This rect */ copyFrom(source: Rect): Rect { - this.x = source.x; - this.y = source.y; - this.width = source.width; - this.height = source.height; + this._x = source.x; + this._y = source.y; + this._width = source.width; + this._height = source.height; + this._onValueChanged && this._onValueChanged(); return this; } } diff --git a/packages/rhi-webgl/src/WebGLGraphicDevice.ts b/packages/rhi-webgl/src/WebGLGraphicDevice.ts index 73086c207f..e826b90458 100644 --- a/packages/rhi-webgl/src/WebGLGraphicDevice.ts +++ b/packages/rhi-webgl/src/WebGLGraphicDevice.ts @@ -60,6 +60,14 @@ export interface WebGLGraphicDeviceOptions extends WebGLContextAttributes { * iOS 15 webgl implement has bug, maybe should force call flush command buffer, for example iPhone13(iOS 15.4.1). */ _forceFlush?: boolean; + + /** + * @internal + * Max allow skin uniform vectors count, default is 256 + * + * @remarks large count maybe cause performance issue. + */ + _maxAllowSkinUniformVectorCount?: number; } /** @@ -126,6 +134,7 @@ export class WebGLGraphicDevice implements IHardwareRenderer { webGLMode: WebGLMode.Auto, stencil: true, _forceFlush: false, + _maxAllowSkinUniformVectorCount: 256, ...initializeOptions }; if (SystemInfo.platform === Platform.IPhone || SystemInfo.platform === Platform.IPad) { diff --git a/rollup.config.js b/rollup.config.js index 0e004917d2..603a8b9b19 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -104,7 +104,7 @@ function config({ location, pkgJson }) { sourcemap: false } ], - external: Object.keys(pkgJson.dependencies || {}) + external: external .concat("@galacean/engine-miniprogram-adapter") .map((name) => `${name}/dist/miniprogram`), plugins diff --git a/tests/index.ts b/tests/index.ts index 877ef80821..2a063a62d6 100644 --- a/tests/index.ts +++ b/tests/index.ts @@ -15,7 +15,7 @@ function searchTests(root: string) { } else if (stat.isDirectory()) { describe(file, () => { searchTests(filePath); - }); + }).timeout(5000); } }); } diff --git a/tests/src/core/2d/text/Font.test.ts b/tests/src/core/2d/text/Font.test.ts new file mode 100644 index 0000000000..e9e5911f41 --- /dev/null +++ b/tests/src/core/2d/text/Font.test.ts @@ -0,0 +1,62 @@ +import { WebGLEngine } from "@galacean/engine-rhi-webgl"; +import { Camera, Font, TextRenderer, Entity } from "@galacean/engine-core"; +import { Vector3 } from "@galacean/engine-math"; +import { expect } from "chai"; + +describe("Font", function () { + let engine: WebGLEngine; + let textRendererEntity: Entity; + + before(async () => { + engine = await WebGLEngine.create({ canvas: document.createElement("canvas") }); + engine.canvas.resizeByClientSize(); + + const rootEntity = engine.sceneManager.activeScene.createRootEntity("root"); + const camera = rootEntity.addComponent(Camera); + rootEntity.transform.setPosition(0, 0, 10); + rootEntity.transform.lookAt(new Vector3(0, 0, 0)); + + textRendererEntity = rootEntity.createChild("TextRenderer"); + textRendererEntity.addComponent(TextRenderer); + + engine.run(); + }); + + it("Font constructor", () => { + // Test that Font constructor works correctly. + expect(() => { + new Font(engine, "TestFont"); + new Font(engine); + new Font(engine, undefined); + }).not.to.throw(); + }); + + it("Font createFromOS", () => { + // Test that createFromOS returns null, while the name is empty string or undefined. + expect(Font.createFromOS(engine, "")).to.be.null; + expect(Font.createFromOS(engine, undefined)).to.be.null; + + const sysFont = Font.createFromOS(engine, "Arial"); + const sysFont2 = Font.createFromOS(engine, "Arial Black"); + const sysFont3 = Font.createFromOS(engine, "Rockwell"); + + // Test that fonts are same object, while call createFromOS with same parameter. + expect(Font.createFromOS(engine, "Arial")).to.be.eq(sysFont); + expect(Font.createFromOS(engine, "Arial Black")).to.be.eq(sysFont2); + expect(Font.createFromOS(engine, "Rockwell")).to.be.eq(sysFont3); + + // Test font name is right. + expect(sysFont.name).to.eq("Arial"); + expect(sysFont2.name).to.eq("Arial Black"); + expect(sysFont3.name).to.eq("Rockwell"); + }); + + it("Destroy font", () => { + // Test that destroy a font works correctly. + expect(textRendererEntity.destroy()).not.to.throw; + }); + + after(() => { + engine.destroy(); + }); +}); diff --git a/tests/src/core/Animator.test.ts b/tests/src/core/Animator.test.ts new file mode 100644 index 0000000000..e4c38b54d5 --- /dev/null +++ b/tests/src/core/Animator.test.ts @@ -0,0 +1,208 @@ +import { WebGLEngine } from "@galacean/engine-rhi-webgl"; +import { Animator, Camera } from "@galacean/engine-core"; +import { Quaternion } from "@galacean/engine-math"; +import { GLTFResource } from "@galacean/engine-loader"; +import chai, { expect } from "chai"; +import spies from "chai-spies"; +import { glbResource } from "./model"; + +chai.use(spies); + +const canvasDOM = document.createElement("canvas"); +canvasDOM.width = 1024; +canvasDOM.height = 1024; + +describe("Animator test", function () { + let animator: Animator; + let resource: GLTFResource; + let engine: WebGLEngine; + + before(async () => { + engine = await WebGLEngine.create({ canvas: canvasDOM }); + const scene = engine.sceneManager.activeScene; + const rootEntity = scene.createRootEntity(); + rootEntity.addComponent(Camera); + + resource = await engine.resourceManager.load(glbResource); + const defaultSceneRoot = resource.defaultSceneRoot; + rootEntity.addChild(defaultSceneRoot); + animator = defaultSceneRoot.getComponent(Animator); + + engine.run(); + }); + + after(function () { + animator.destroy(); + engine.destroy(); + }); + + afterEach(function () { + animator.speed = 1; + // @ts-ignore + animator._reset(); + }); + it("constructor", () => { + // Test default values + expect(animator).not.to.be.undefined; + expect(animator.cullingMode).to.eq(0); + expect(animator["_awoken"]).to.eq(true); + expect(animator["_enabled"]).to.eq(true); + expect(animator["_onUpdateIndex"]).to.eq(0); + expect(animator["_phasedActive"]).to.eq(true); + + // Test _tempAnimatorStateInfo default layerIndex values + expect(animator["_tempAnimatorStateInfo"].layerIndex).to.eq(-1); + }); + + it("animator speed value", () => { + // Test animator speed. + animator.play("Run"); + + let animatorLayerData = animator["_animatorLayersData"]; + const srcPlayData = animatorLayerData[0]?.srcPlayData; + + const speed = 1; + let expectedSpeed = speed * 0.5; + animator.speed = expectedSpeed; + let lastFrameTime = srcPlayData.frameTime; + animator.update(5); + expect(animator.speed).to.eq(expectedSpeed); + expect(srcPlayData.frameTime).to.eq(lastFrameTime + 5 * expectedSpeed); + expectedSpeed = speed * 2; + animator.speed = expectedSpeed; + lastFrameTime = srcPlayData.frameTime; + animator.update(10); + expect(animator.speed).to.eq(expectedSpeed); + expect(srcPlayData.frameTime).to.eq(lastFrameTime + 10 * expectedSpeed); + expectedSpeed = speed * 0; + animator.speed = expectedSpeed; + lastFrameTime = srcPlayData.frameTime; + animator.update(15); + expect(animator.speed).to.eq(expectedSpeed); + expect(srcPlayData.frameTime).to.eq(lastFrameTime + 15 * expectedSpeed); + }); + + it("play animation", () => { + // Test animator play. + const layerIndex = 0; + const normalizedTimeOffset = 0.5; + animator.play("Run"); + expect(animator["_tempAnimatorStateInfo"].layerIndex).to.eq(layerIndex); + + let animatorState = animator.getCurrentAnimatorState(layerIndex); + expect(animatorState.name).to.eq("Run"); + expect(animatorState.speed).to.eq(1); + expect(animatorState.wrapMode).to.eq(1); + + // Test animator change play state. + animator.play("Walk", layerIndex, normalizedTimeOffset); + animatorState = animator.getCurrentAnimatorState(layerIndex); + expect(animatorState.name).to.eq("Walk"); + }); + + it("animator cullingMode", () => { + // Test animator cullingMode. + //@ts-ignore + animator._controlledRenderers.forEach((renderer) => { + // mock entity is culled + renderer._renderFrameCount = Infinity; + }); + + animator.play("Run"); + + let animatorLayerData = animator["_animatorLayersData"]; + const srcPlayData = animatorLayerData[0]?.srcPlayData; + + animator.cullingMode = 1; + expect(animator.cullingMode).to.eq(1); + animator.update(5); + const curveOwner = srcPlayData.stateData.curveLayerOwner[0].curveOwner; + const initValue = curveOwner.defaultValue; + const currentValue = curveOwner.referenceTargetValue; + + expect(Quaternion.equals(initValue, currentValue)).to.eq(true); + + animator.cullingMode = 0; + expect(animator.cullingMode).to.eq(0); + animator.update(5); + expect(Quaternion.equals(initValue, currentValue)).to.eq(false); + }); + + it("animation enabled", () => { + // Test animator play. + animator.play("Survey"); + const onDisableSpy = chai.spy.on(animator, "_onDisable"); + const onEnableSpy = chai.spy.on(animator, "_onEnable"); + const onUpdateSpy = chai.spy.on(animator, "update"); + + animator.enabled = false; + expect(animator["_enabled"]).to.eq(false); + expect(onDisableSpy).to.have.been.called.exactly(1); + engine.update(); + expect(onUpdateSpy).to.have.been.called.exactly(0); + + animator.enabled = true; + expect(animator["_enabled"]).to.eq(true); + expect(onEnableSpy).to.have.been.called.exactly(1); + engine.update(); + expect(onUpdateSpy).to.have.been.called.exactly(1); + }); + + it("find animator state", () => { + const stateName = "Survey"; + const expectedStateName = "Run"; + const layerIndex = animator["_tempAnimatorStateInfo"].layerIndex; + + animator.play(stateName); + const currentAnimatorState = animator.getCurrentAnimatorState(layerIndex); + let animatorState = animator.findAnimatorState(stateName, layerIndex); + expect(animatorState).to.eq(currentAnimatorState); + + animator.play(expectedStateName); + animatorState = animator.findAnimatorState(expectedStateName, layerIndex); + expect(animatorState).not.to.eq(currentAnimatorState); + expect(animatorState.name).to.eq(expectedStateName); + }); + + it("animation getCurrentAnimatorState", () => { + //get random animation element from gltf resource + const min = 0; + const max = resource.animations.length - 1; + const index = Math.floor(Math.random() * (max - min + 1)) + min; + + //play animation and get current animator state + const expectedStateName = resource.animations[index].name; + animator.play(expectedStateName); + const layerIndex = animator["_tempAnimatorStateInfo"].layerIndex; + const currentAnimatorState = animator.getCurrentAnimatorState(layerIndex); + expect(currentAnimatorState.name).to.eq(expectedStateName); + }); + + it("animation cross fade", () => { + animator.play("Walk"); + animator.crossFade("Run", 0.5); + animator.update(1); + + const layerIndex = animator["_tempAnimatorStateInfo"].layerIndex; + const animatorLayerData = animator["_animatorLayersData"]; + const layerState = animatorLayerData[layerIndex].layerState; + + // current animator layerState should be CrossFading(2) + expect(layerState).to.eq(2); + }); + + it("animation fix cross fade", () => { + animator.play("Walk"); + animator.update(1); + animator.crossFade("Survey", 5); + animator.crossFade("Run", 0.5); + animator.update(10); + + const layerIndex = animator["_tempAnimatorStateInfo"].layerIndex; + const animatorLayerData = animator["_animatorLayersData"]; + const layerState = animatorLayerData[layerIndex].layerState; + + // current animator layerState should be FixedCrossFading(3) + expect(layerState).to.eq(3); + }); +}); diff --git a/tests/src/core/Sprite.test.ts b/tests/src/core/Sprite.test.ts index a4a7638c1a..cb3f941cb4 100644 --- a/tests/src/core/Sprite.test.ts +++ b/tests/src/core/Sprite.test.ts @@ -18,9 +18,9 @@ describe("Sprite", async () => { const sprite = new Sprite(engine); expect(sprite.texture).to.eq(null); - expect(sprite.region).to.deep.eq(new Rect(0, 0, 1, 1)); - expect(sprite.pivot).to.deep.eq(new Vector2(0.5, 0.5)); - expect(sprite.border).to.deep.eq(new Vector4(0, 0, 0, 0)); + expect(sprite.region).to.deep.include({ x: 0, y: 0, width: 1, height: 1 }); + expect(sprite.pivot).to.deep.include({ x: 0.5, y: 0.5 }); + expect(sprite.border).to.deep.include({ x: 0, y: 0, z: 0, w: 0 }); }); it("get set texture", () => { @@ -36,23 +36,23 @@ describe("Sprite", async () => { const rect = new Rect(0.1, 0.1, 0.7, 1.0); sprite.region = rect; - expect(sprite.region).to.deep.eq(new Rect(0.1, 0.1, 0.7, 0.9)); + expect(sprite.region).to.deep.include({ x: 0.1, y: 0.1, width: 0.7, height: 0.9 }); }); it("get set pivot", () => { const sprite = new Sprite(engine); const pivot = new Vector2(0.1, 0.1); sprite.pivot = pivot; - expect(sprite.pivot).to.deep.eq(pivot); + expect(sprite.pivot).to.deep.include({ x: 0.1, y: 0.1 }); sprite.pivot = sprite.pivot; - expect(sprite.pivot).to.deep.eq(pivot); + expect(sprite.pivot).to.deep.include({ x: 0.1, y: 0.1 }); }); it("get set border", () => { const sprite = new Sprite(engine); const border = new Vector4(0.1, 0.1, 0.8, 0.8); sprite.border = border; - expect(sprite.border).to.deep.eq(border); + expect(sprite.border).to.deep.include({ x: 0.1, y: 0.1, z: 0.8, w: 0.8 }); }); it("get set atlasRotated", () => { @@ -189,9 +189,6 @@ describe("Sprite", async () => { const sprite1 = new Sprite(engine, new Texture2D(engine, 1000, 2000)); const sprite2 = sprite1.clone(); expect(sprite1.texture).to.deep.eq(sprite2.texture); - expect(sprite1.region).to.deep.eq(sprite2.region); - expect(sprite1.pivot).to.deep.eq(sprite2.pivot); - expect(sprite1.border).to.deep.eq(sprite2.border); expect(sprite1.atlasRotated).to.eq(sprite2.atlasRotated); expect(sprite1.atlasRegion).to.deep.eq(sprite2.atlasRegion); expect(sprite1.atlasRegionOffset).to.deep.eq(sprite2.atlasRegionOffset); diff --git a/tests/src/core/base/EventDispatcher.test.ts b/tests/src/core/base/EventDispatcher.test.ts index b33f3ea394..55ba8eb4f6 100644 --- a/tests/src/core/base/EventDispatcher.test.ts +++ b/tests/src/core/base/EventDispatcher.test.ts @@ -72,4 +72,19 @@ describe("EventDispatcher test", function () { expect(eventOn).to.have.been.called.exactly(1); expect(eventDispatcher.listenerCount("test-event")).to.eql(1); }); + + it("call event in a callback", () => { + const eventDispatcher = new EventDispatcher(); + const event1On = chai.spy(() => { + eventDispatcher.dispatch("event2"); + }); + const event2On = chai.spy(() => {}); + eventDispatcher.on("event1", event1On); + eventDispatcher.on("event1", event1On); + eventDispatcher.on("event2", event2On); + eventDispatcher.on("event2", event2On); + eventDispatcher.dispatch("event1"); + expect(event1On).to.have.been.called.exactly(2); + expect(event2On).to.have.been.called.exactly(4); + }); }); diff --git a/tests/src/core/model/index.ts b/tests/src/core/model/index.ts new file mode 100644 index 0000000000..f1c5745a73 --- /dev/null +++ b/tests/src/core/model/index.ts @@ -0,0 +1,2 @@ +export const glbResource = + "data:application/octet-stream;base64,Z2xURgIAAAAofAIAID8AAEpTT057ImFzc2V0Ijp7ImNvcHlyaWdodCI6IkNDLUJZIDQuMCBNb2RlbCBieSBQaXhlbE1hbm5lbiBodHRwczovL29wZW5nYW1lYXJ0Lm9yZy9jb250ZW50L2ZveC1hbmQtc2hpYmEgYW5kIEB0b21rcmFuaXMgaHR0cHM6Ly9za2V0Y2hmYWIuY29tLzNkLW1vZGVscy9sb3ctcG9seS1mb3gtYnktcGl4ZWxtYW5uZW4tYW5pbWF0ZWQtMzcxZGVhODhkN2UwNGE3NmFmNTc2M2YyYTM2ODY2YmMgYW5kIEBBc29ib1N0dWRpbyB3aXRoIEBzY3VyZXN0IGh0dHBzOi8vZ2l0aHViLmNvbS9LaHJvbm9zR3JvdXAvZ2xURi1TYW1wbGUtTW9kZWxzL3B1bGwvMTUwI2lzc3VlY29tbWVudC00MDYzMDAxMTgiLCJ2ZXJzaW9uIjoiMi4wIn0sImFjY2Vzc29ycyI6W3siYnVmZmVyVmlldyI6MCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjE3MjgsInR5cGUiOiJWRUMzIiwiYnl0ZU9mZnNldCI6MCwibWluIjpbLTEyLjU5MjcxODEyNDM4OTY0OCwtMC4xMjE3NDQ3NjY4MzEzOTgwMSwtODguMDk1MDAxMjIwNzAzMTJdLCJtYXgiOlsxMi41OTI3MTgxMjQzODk2NDgsNzguOTA3MTg4NDE1NTI3MzQsNjYuNjI0ODYyNjcwODk4NDRdfSx7ImJ1ZmZlclZpZXciOjEsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxNzI4LCJ0eXBlIjoiVkVDMiIsImJ5dGVPZmZzZXQiOjB9LHsiYnVmZmVyVmlldyI6MSwiY29tcG9uZW50VHlwZSI6NTEyMywiY291bnQiOjE3MjgsInR5cGUiOiJWRUM0IiwiYnl0ZU9mZnNldCI6MTM4MjR9LHsiYnVmZmVyVmlldyI6MiwiYnl0ZU9mZnNldCI6MCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjE3MjgsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3IjozLCJieXRlT2Zmc2V0IjowLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjQsInR5cGUiOiJNQVQ0In0seyJidWZmZXJWaWV3Ijo0LCJieXRlT2Zmc2V0IjowLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJTQ0FMQVIiLCJtaW4iOlswXSwibWF4IjpbMy40MTY2NjY3NDYxMzk1MjY0XX0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjowLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjoxMzI4LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjoyNjU2LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjozOTg0LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0Ijo1MzEyLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0Ijo2NjQwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0Ijo3OTY4LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0Ijo5Mjk2LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjoxMDYyNCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjgzLCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MTE5NTIsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50Ijo4MywidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjEzMjgwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjoxNDYwOCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjgzLCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MTU5MzYsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50Ijo4MywidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjE3MjY0LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjoxODU5MiwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjgzLCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MTk5MjAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50Ijo4MywidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjIxMjQ4LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjoyMjU3NiwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjgzLCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MjM5MDQsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50Ijo4MywidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjYsImJ5dGVPZmZzZXQiOjAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50Ijo4MywidHlwZSI6IlZFQzMifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjI1MjMyLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6ODMsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo0LCJieXRlT2Zmc2V0IjozMzIsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxOCwidHlwZSI6IlNDQUxBUiIsIm1pbiI6WzBdLCJtYXgiOlswLjcwODMzMzMxMzQ2NTExODRdfSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjI2NTYwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MTgsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjoyNjg0OCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjE4LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MjcxMzYsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxOCwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjI3NDI0LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MTgsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjoyNzcxMiwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjE4LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MjgwMDAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxOCwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjI4Mjg4LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MTgsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjoyODU3NiwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjE4LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6Mjg4NjQsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxOCwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjI5MTUyLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MTgsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjoyOTQ0MCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjE4LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6Mjk3MjgsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxOCwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjMwMDE2LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MTgsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjozMDMwNCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjE4LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MzA1OTIsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxOCwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjMwODgwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MTgsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjozMTE2OCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjE4LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MzE0NTYsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxOCwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjMxNzQ0LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MTgsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo2LCJieXRlT2Zmc2V0Ijo5OTYsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxOCwidHlwZSI6IlZFQzMifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjMyMDMyLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MTgsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo0LCJieXRlT2Zmc2V0Ijo0MDQsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoyNSwidHlwZSI6IlNDQUxBUiIsIm1pbiI6WzBdLCJtYXgiOlsxLjE1ODMzMzMwMTU0NDE4OTVdfSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjMyMzIwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjUsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjozMjcyMCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjI1LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MzMxMjAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoyNSwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjMzNTIwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjUsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjozMzkyMCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjI1LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MzQzMjAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoyNSwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjM0NzIwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjUsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjozNTEyMCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjI1LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MzU1MjAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoyNSwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjM1OTIwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjUsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjozNjMyMCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjI1LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MzY3MjAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoyNSwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjM3MTIwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjUsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjozNzUyMCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjI1LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6Mzc5MjAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoyNSwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjM4MzIwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjUsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjozODcyMCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjI1LCJ0eXBlIjoiVkVDNCJ9LHsiYnVmZmVyVmlldyI6NSwiYnl0ZU9mZnNldCI6MzkxMjAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoyNSwidHlwZSI6IlZFQzQifSx7ImJ1ZmZlclZpZXciOjUsImJ5dGVPZmZzZXQiOjM5NTIwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjUsInR5cGUiOiJWRUM0In0seyJidWZmZXJWaWV3Ijo2LCJieXRlT2Zmc2V0IjoxMjEyLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjUsInR5cGUiOiJWRUMzIn0seyJidWZmZXJWaWV3Ijo1LCJieXRlT2Zmc2V0IjozOTkyMCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjI1LCJ0eXBlIjoiVkVDNCJ9XSwiYW5pbWF0aW9ucyI6W3siY2hhbm5lbHMiOlt7InNhbXBsZXIiOjAsInRhcmdldCI6eyJub2RlIjo4LCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjoxLCJ0YXJnZXQiOnsibm9kZSI6NywicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MiwidGFyZ2V0Ijp7Im5vZGUiOjExLCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjozLCJ0YXJnZXQiOnsibm9kZSI6MTAsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjQsInRhcmdldCI6eyJub2RlIjo5LCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjo1LCJ0YXJnZXQiOnsibm9kZSI6MTQsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjYsInRhcmdldCI6eyJub2RlIjoxMywicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6NywidGFyZ2V0Ijp7Im5vZGUiOjEyLCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjo4LCJ0YXJnZXQiOnsibm9kZSI6NiwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6OSwidGFyZ2V0Ijp7Im5vZGUiOjUsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjEwLCJ0YXJnZXQiOnsibm9kZSI6MTcsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjExLCJ0YXJnZXQiOnsibm9kZSI6MTYsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjEyLCJ0YXJnZXQiOnsibm9kZSI6MTUsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjEzLCJ0YXJnZXQiOnsibm9kZSI6MjAsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE0LCJ0YXJnZXQiOnsibm9kZSI6MTksInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE1LCJ0YXJnZXQiOnsibm9kZSI6MTgsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE2LCJ0YXJnZXQiOnsibm9kZSI6MjQsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE3LCJ0YXJnZXQiOnsibm9kZSI6MjMsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE4LCJ0YXJnZXQiOnsibm9kZSI6MjIsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE5LCJ0YXJnZXQiOnsibm9kZSI6NCwicGF0aCI6InRyYW5zbGF0aW9uIn19LHsic2FtcGxlciI6MjAsInRhcmdldCI6eyJub2RlIjo0LCJwYXRoIjoicm90YXRpb24ifX1dLCJzYW1wbGVycyI6W3siaW5wdXQiOjUsIm91dHB1dCI6Nn0seyJpbnB1dCI6NSwib3V0cHV0Ijo3fSx7ImlucHV0Ijo1LCJvdXRwdXQiOjh9LHsiaW5wdXQiOjUsIm91dHB1dCI6OX0seyJpbnB1dCI6NSwib3V0cHV0IjoxMH0seyJpbnB1dCI6NSwib3V0cHV0IjoxMX0seyJpbnB1dCI6NSwib3V0cHV0IjoxMn0seyJpbnB1dCI6NSwib3V0cHV0IjoxM30seyJpbnB1dCI6NSwib3V0cHV0IjoxNH0seyJpbnB1dCI6NSwib3V0cHV0IjoxNX0seyJpbnB1dCI6NSwib3V0cHV0IjoxNn0seyJpbnB1dCI6NSwib3V0cHV0IjoxN30seyJpbnB1dCI6NSwib3V0cHV0IjoxOH0seyJpbnB1dCI6NSwib3V0cHV0IjoxOX0seyJpbnB1dCI6NSwib3V0cHV0IjoyMH0seyJpbnB1dCI6NSwib3V0cHV0IjoyMX0seyJpbnB1dCI6NSwib3V0cHV0IjoyMn0seyJpbnB1dCI6NSwib3V0cHV0IjoyM30seyJpbnB1dCI6NSwib3V0cHV0IjoyNH0seyJpbnB1dCI6NSwib3V0cHV0IjoyNX0seyJpbnB1dCI6NSwib3V0cHV0IjoyNn1dLCJuYW1lIjoiU3VydmV5In0seyJjaGFubmVscyI6W3sic2FtcGxlciI6MCwidGFyZ2V0Ijp7Im5vZGUiOjgsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjEsInRhcmdldCI6eyJub2RlIjo3LCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjoyLCJ0YXJnZXQiOnsibm9kZSI6MTEsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjMsInRhcmdldCI6eyJub2RlIjoxMCwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6NCwidGFyZ2V0Ijp7Im5vZGUiOjksInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjUsInRhcmdldCI6eyJub2RlIjoxNCwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6NiwidGFyZ2V0Ijp7Im5vZGUiOjEzLCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjo3LCJ0YXJnZXQiOnsibm9kZSI6MTIsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjgsInRhcmdldCI6eyJub2RlIjo2LCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjo5LCJ0YXJnZXQiOnsibm9kZSI6NSwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MTAsInRhcmdldCI6eyJub2RlIjoxNywicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MTEsInRhcmdldCI6eyJub2RlIjoxNiwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MTIsInRhcmdldCI6eyJub2RlIjoxNSwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MTMsInRhcmdldCI6eyJub2RlIjoyMCwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MTQsInRhcmdldCI6eyJub2RlIjoxOSwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MTUsInRhcmdldCI6eyJub2RlIjoxOCwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MTYsInRhcmdldCI6eyJub2RlIjoyNCwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MTcsInRhcmdldCI6eyJub2RlIjoyMywicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MTgsInRhcmdldCI6eyJub2RlIjoyMiwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MTksInRhcmdldCI6eyJub2RlIjo0LCJwYXRoIjoidHJhbnNsYXRpb24ifX0seyJzYW1wbGVyIjoyMCwidGFyZ2V0Ijp7Im5vZGUiOjQsInBhdGgiOiJyb3RhdGlvbiJ9fV0sInNhbXBsZXJzIjpbeyJpbnB1dCI6MjcsIm91dHB1dCI6Mjh9LHsiaW5wdXQiOjI3LCJvdXRwdXQiOjI5fSx7ImlucHV0IjoyNywib3V0cHV0IjozMH0seyJpbnB1dCI6MjcsIm91dHB1dCI6MzF9LHsiaW5wdXQiOjI3LCJvdXRwdXQiOjMyfSx7ImlucHV0IjoyNywib3V0cHV0IjozM30seyJpbnB1dCI6MjcsIm91dHB1dCI6MzR9LHsiaW5wdXQiOjI3LCJvdXRwdXQiOjM1fSx7ImlucHV0IjoyNywib3V0cHV0IjozNn0seyJpbnB1dCI6MjcsIm91dHB1dCI6Mzd9LHsiaW5wdXQiOjI3LCJvdXRwdXQiOjM4fSx7ImlucHV0IjoyNywib3V0cHV0IjozOX0seyJpbnB1dCI6MjcsIm91dHB1dCI6NDB9LHsiaW5wdXQiOjI3LCJvdXRwdXQiOjQxfSx7ImlucHV0IjoyNywib3V0cHV0Ijo0Mn0seyJpbnB1dCI6MjcsIm91dHB1dCI6NDN9LHsiaW5wdXQiOjI3LCJvdXRwdXQiOjQ0fSx7ImlucHV0IjoyNywib3V0cHV0Ijo0NX0seyJpbnB1dCI6MjcsIm91dHB1dCI6NDZ9LHsiaW5wdXQiOjI3LCJvdXRwdXQiOjQ3fSx7ImlucHV0IjoyNywib3V0cHV0Ijo0OH1dLCJuYW1lIjoiV2FsayJ9LHsiY2hhbm5lbHMiOlt7InNhbXBsZXIiOjAsInRhcmdldCI6eyJub2RlIjo4LCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjoxLCJ0YXJnZXQiOnsibm9kZSI6NywicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6MiwidGFyZ2V0Ijp7Im5vZGUiOjExLCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjozLCJ0YXJnZXQiOnsibm9kZSI6MTAsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjQsInRhcmdldCI6eyJub2RlIjo5LCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjo1LCJ0YXJnZXQiOnsibm9kZSI6MTQsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjYsInRhcmdldCI6eyJub2RlIjoxMywicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6NywidGFyZ2V0Ijp7Im5vZGUiOjEyLCJwYXRoIjoicm90YXRpb24ifX0seyJzYW1wbGVyIjo4LCJ0YXJnZXQiOnsibm9kZSI6NiwicGF0aCI6InJvdGF0aW9uIn19LHsic2FtcGxlciI6OSwidGFyZ2V0Ijp7Im5vZGUiOjUsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjEwLCJ0YXJnZXQiOnsibm9kZSI6MTcsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjExLCJ0YXJnZXQiOnsibm9kZSI6MTYsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjEyLCJ0YXJnZXQiOnsibm9kZSI6MTUsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjEzLCJ0YXJnZXQiOnsibm9kZSI6MjAsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE0LCJ0YXJnZXQiOnsibm9kZSI6MTksInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE1LCJ0YXJnZXQiOnsibm9kZSI6MTgsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE2LCJ0YXJnZXQiOnsibm9kZSI6MjQsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE3LCJ0YXJnZXQiOnsibm9kZSI6MjMsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE4LCJ0YXJnZXQiOnsibm9kZSI6MjIsInBhdGgiOiJyb3RhdGlvbiJ9fSx7InNhbXBsZXIiOjE5LCJ0YXJnZXQiOnsibm9kZSI6NCwicGF0aCI6InRyYW5zbGF0aW9uIn19LHsic2FtcGxlciI6MjAsInRhcmdldCI6eyJub2RlIjo0LCJwYXRoIjoicm90YXRpb24ifX1dLCJzYW1wbGVycyI6W3siaW5wdXQiOjQ5LCJvdXRwdXQiOjUwfSx7ImlucHV0Ijo0OSwib3V0cHV0Ijo1MX0seyJpbnB1dCI6NDksIm91dHB1dCI6NTJ9LHsiaW5wdXQiOjQ5LCJvdXRwdXQiOjUzfSx7ImlucHV0Ijo0OSwib3V0cHV0Ijo1NH0seyJpbnB1dCI6NDksIm91dHB1dCI6NTV9LHsiaW5wdXQiOjQ5LCJvdXRwdXQiOjU2fSx7ImlucHV0Ijo0OSwib3V0cHV0Ijo1N30seyJpbnB1dCI6NDksIm91dHB1dCI6NTh9LHsiaW5wdXQiOjQ5LCJvdXRwdXQiOjU5fSx7ImlucHV0Ijo0OSwib3V0cHV0Ijo2MH0seyJpbnB1dCI6NDksIm91dHB1dCI6NjF9LHsiaW5wdXQiOjQ5LCJvdXRwdXQiOjYyfSx7ImlucHV0Ijo0OSwib3V0cHV0Ijo2M30seyJpbnB1dCI6NDksIm91dHB1dCI6NjR9LHsiaW5wdXQiOjQ5LCJvdXRwdXQiOjY1fSx7ImlucHV0Ijo0OSwib3V0cHV0Ijo2Nn0seyJpbnB1dCI6NDksIm91dHB1dCI6Njd9LHsiaW5wdXQiOjQ5LCJvdXRwdXQiOjY4fSx7ImlucHV0Ijo0OSwib3V0cHV0Ijo2OX0seyJpbnB1dCI6NDksIm91dHB1dCI6NzB9XSwibmFtZSI6IlJ1biJ9XSwiYnVmZmVyVmlld3MiOlt7ImJ1ZmZlciI6MCwiYnl0ZU9mZnNldCI6MCwiYnl0ZUxlbmd0aCI6MjA3MzYsImJ5dGVTdHJpZGUiOjEyfSx7ImJ1ZmZlciI6MCwiYnl0ZU9mZnNldCI6MjA3MzYsImJ5dGVMZW5ndGgiOjI3NjQ4LCJieXRlU3RyaWRlIjo4fSx7ImJ1ZmZlciI6MCwiYnl0ZU9mZnNldCI6NDgzODQsImJ5dGVMZW5ndGgiOjI3NjQ4LCJieXRlU3RyaWRlIjoxNn0seyJidWZmZXIiOjAsImJ5dGVPZmZzZXQiOjc2MDMyLCJieXRlTGVuZ3RoIjoxNTM2fSx7ImJ1ZmZlciI6MCwiYnl0ZU9mZnNldCI6Nzc1NjgsImJ5dGVMZW5ndGgiOjUwNCwiYnl0ZVN0cmlkZSI6NH0seyJidWZmZXIiOjAsImJ5dGVPZmZzZXQiOjc4MDcyLCJieXRlTGVuZ3RoIjo0MDMyMCwiYnl0ZVN0cmlkZSI6MTZ9LHsiYnVmZmVyIjowLCJieXRlT2Zmc2V0IjoxMTgzOTIsImJ5dGVMZW5ndGgiOjE1MTIsImJ5dGVTdHJpZGUiOjEyfSx7ImJ1ZmZlciI6MCwiYnl0ZU9mZnNldCI6MTE5OTA0LCJieXRlTGVuZ3RoIjoyNjc2NH1dLCJidWZmZXJzIjpbeyJieXRlTGVuZ3RoIjoxNDY2Njh9XSwiaW1hZ2VzIjpbeyJtaW1lVHlwZSI6ImltYWdlL3BuZyIsImJ1ZmZlclZpZXciOjd9XSwibWF0ZXJpYWxzIjpbeyJuYW1lIjoiZm94X21hdGVyaWFsIiwicGJyTWV0YWxsaWNSb3VnaG5lc3MiOnsiYmFzZUNvbG9yVGV4dHVyZSI6eyJpbmRleCI6MH0sIm1ldGFsbGljRmFjdG9yIjowLCJyb3VnaG5lc3NGYWN0b3IiOjAuNTh9fV0sIm1lc2hlcyI6W3sibmFtZSI6ImZveDEiLCJwcmltaXRpdmVzIjpbeyJhdHRyaWJ1dGVzIjp7IlBPU0lUSU9OIjowLCJURVhDT09SRF8wIjoxLCJKT0lOVFNfMCI6MiwiV0VJR0hUU18wIjozfSwibWF0ZXJpYWwiOjB9XX1dLCJub2RlcyI6W3siY2hpbGRyZW4iOlsxLDJdLCJuYW1lIjoicm9vdCJ9LHsibmFtZSI6ImZveCIsIm1lc2giOjAsInNraW4iOjB9LHsiY2hpbGRyZW4iOlszXSwibmFtZSI6Il9yb290Sm9pbnQifSx7ImNoaWxkcmVuIjpbNF0sIm5hbWUiOiJiX1Jvb3RfMDAiLCJyb3RhdGlvbiI6Wy0wLjcwNzEwODA5MjQ4NzUzOTEsMCwwLDAuNzA3MTA1NDY5ODgzMTI0Ml19LHsiY2hpbGRyZW4iOls1LDE1LDE4LDIyXSwibmFtZSI6ImJfSGlwXzAxIiwicm90YXRpb24iOlswLjEyNzY5MDk0MTc2MTc1NTQ3LC0wLjY5NTQ4MjAxOTIzOTM3NjIsLTAuMTI3NjkwMjI2NTA2MDE0NDQsMC42OTU0ODE4NDA0MjU0NDFdLCJ0cmFuc2xhdGlvbiI6WzAsMjYuNzQ4NDAzNTQ5MTk0MzM2LDQyLjkzODE3MTM4NjcxODc1XX0seyJjaGlsZHJlbiI6WzZdLCJuYW1lIjoiYl9TcGluZTAxXzAyIiwicm90YXRpb24iOlswLDAsLTAuNTkwNDE1NzYzODIzODMxNywwLjgwNzA5OTI2NjQwMzAzNzZdLCJ0cmFuc2xhdGlvbiI6WzEyLjg1MDYwMTE5NjI4OTA2MiwwLDBdfSx7ImNoaWxkcmVuIjpbNyw5LDEyXSwibmFtZSI6ImJfU3BpbmUwMl8wMyIsInJvdGF0aW9uIjpbMCwwLDAuMDE3NDExOTUyNDA0MjgxMDgyLDAuOTk5ODQ4NDAwNDY1NTI2MV0sInRyYW5zbGF0aW9uIjpbMjEuNjU1NzU0MDg5MzU1NDcsLTAuMDAwMTE4MjU1NjE1MjM0Mzc1LDBdfSx7ImNoaWxkcmVuIjpbOF0sIm5hbWUiOiJiX05lY2tfMDQiLCJyb3RhdGlvbiI6WzAsMCwwLjMwMzM3OTE0MDI4MjY0MzQ2LDAuOTUyODY5OTI2NzE2ODQ0M10sInRyYW5zbGF0aW9uIjpbMjUuNjQ5MTQzMjE4OTk0MTQsMCwwXX0seyJuYW1lIjoiYl9IZWFkXzA1Iiwicm90YXRpb24iOlswLDAsLTAuNDAwMjg1NDE1MTQ4NzM0OSwwLjkxNjM5MDUyMDY5NDc1NTVdLCJ0cmFuc2xhdGlvbiI6WzEzLjM3Njk2MDc1NDM5NDUzMSwwLDBdfSx7ImNoaWxkcmVuIjpbMTBdLCJuYW1lIjoiYl9SaWdodFVwcGVyQXJtXzA2Iiwicm90YXRpb24iOlswLjAwMDQ2NzMyNzMyNjIwMTE1NjIsLTAuMDAwNDQ2MTQ4NDY5MjI1NTkyOCwtMC43MTIxNzkyODgxMTEwNjkxLDAuNzAxOTk3MzI0ODgyNTk4NV0sInRyYW5zbGF0aW9uIjpbMTguNjc3OTEzNjY1NzcxNDg0LC00LjI5NzM0MDM5MzA2NjQwNiw2Ljk2NzU3NTA3MzI0MjE4NzVdfSx7ImNoaWxkcmVuIjpbMTFdLCJuYW1lIjoiYl9SaWdodEZvcmVBcm1fMDciLCJyb3RhdGlvbiI6WzAsMCwwLjAzNzEyNTg5OTc3MzQ4NzQ0LDAuOTk5MzEwNTk2MTQ0MTY2M10sInRyYW5zbGF0aW9uIjpbMjMuMDQ1MTI1OTYxMzAzNzEsMCwwXX0seyJuYW1lIjoiYl9SaWdodEhhbmRfMDgiLCJyb3RhdGlvbiI6Wy0wLjAxMjAzNzQwNjkxNDc5NzAxOCwtMC4wMDc4MjIyMTAxMjQ2NTI3NiwwLjQ2MDU2MjMyNzcxODUxNDgsMC44ODc1MTEyNzA5OTg4NzQxXSwidHJhbnNsYXRpb24iOlsxOS4zNTAwNTU2OTQ1ODAwNzgsLTAuMTQ1OTg2NTU3MDA2ODM1OTQsMF19LHsiY2hpbGRyZW4iOlsxM10sIm5hbWUiOiJiX0xlZnRVcHBlckFybV8wOSIsInJvdGF0aW9uIjpbMC4wMDA0OTcyNjE5MjIwOTQwMTc0LC0wLjAwMDg4MjE5MjMxNjY0NDI4NzUsLTAuNzEyMDg3NDkyOTkxNDY2MywwLjcwMjA5MDAwNjE5MDM5MjddLCJ0cmFuc2xhdGlvbiI6WzE4LjY3NzkxNzQ4MDQ2ODc1LC00LjI5NzM0NDIwNzc2MzY3MiwtNi45Njc5ODcwNjA1NDY4NzVdfSx7ImNoaWxkcmVuIjpbMTRdLCJuYW1lIjoiYl9MZWZ0Rm9yZUFybV8wMTAiLCJyb3RhdGlvbiI6WzAsMCwwLjAzNzEyNTg5OTc3MzQ4NzQ0LDAuOTk5MzEwNTk2MTQ0MTY2M10sInRyYW5zbGF0aW9uIjpbMjMuMDQ1MTI0MDUzOTU1MDc4LDAsMF19LHsibmFtZSI6ImJfTGVmdEhhbmRfMDExIiwicm90YXRpb24iOlswLjAxNjUxNzkxNDQwNzIxNTA3LDAuMDE0MDEzNzM5ODczOTk3NzgxLDAuNDYwMDc1NTc1MjEyNzEsMC44ODc2MTU0NzkwNzM2MDk5XSwidHJhbnNsYXRpb24iOlsxOS4zNTAwNTE4Nzk4ODI4MTIsLTAuMTQ1OTkwMzcxNzA0MTAxNTYsMF19LHsiY2hpbGRyZW4iOlsxNl0sIm5hbWUiOiJiX1RhaWwwMV8wMTIiLCJyb3RhdGlvbiI6WzAsMCwwLjk4MTg5Mjg5NDA2NTYyOTUsMC4xODk0MzY5MTQ1MjE0OTA0XSwidHJhbnNsYXRpb24iOls0LjI2MDM3NTk3NjU2MjUsMTUuOTU4NzcwNzUxOTUzMTI1LDBdfSx7ImNoaWxkcmVuIjpbMTddLCJuYW1lIjoiYl9UYWlsMDJfMDEzIiwicm90YXRpb24iOlswLDAsLTAuMDY5NjE3MTY2MzM4NzQ2NiwwLjk5NzU3Mzc4MTgwODEyNDRdLCJ0cmFuc2xhdGlvbiI6WzEyLjQxMTkxODY0MDEzNjcxOSwwLDBdfSx7Im5hbWUiOiJiX1RhaWwwM18wMTQiLCJyb3RhdGlvbiI6WzAsMCwtMC4wNTM4MzI3NDQ4NDIwNzY4NCwwLjk5ODU0OTk2NjQ5Mjc5NzldLCJ0cmFuc2xhdGlvbiI6WzI0LjI0MDMyMjExMzAzNzExLDAsMF19LHsiY2hpbGRyZW4iOlsxOV0sIm5hbWUiOiJiX0xlZnRMZWcwMV8wMTUiLCJyb3RhdGlvbiI6WzAsLTAuMDAwMTcxNzUyMjUzNjU1OTkzNiwwLjk3MDAxNTg4MzQwMjA2ODEsLTAuMjQzMDQxNDcwNjM1OTE2MV0sInRyYW5zbGF0aW9uIjpbNC44MTM3NzAyOTQxODk0NTMsNS4xNTQwMTg0MDIwOTk2MDksLTYuOTY4MDA2MTM0MDMzMjAzXX0seyJjaGlsZHJlbiI6WzIwXSwibmFtZSI6ImJfTGVmdExlZzAyXzAxNiIsInJvdGF0aW9uIjpbMCwwLC0wLjM2ODA0Mzc4ODU1NTExNjU1LDAuOTI5ODA4NDU4NjExNzcwNl0sInRyYW5zbGF0aW9uIjpbMTguOTQ0MTc1NzIwMjE0ODQ0LDAsMF19LHsiY2hpbGRyZW4iOlsyMV0sIm5hbWUiOiJiX0xlZnRGb290MDFfMDE3Iiwicm90YXRpb24iOlswLjAwMDI0ODQxMDU5Mjk2NjQ2NjYsMCwwLjQ1ODQ4NDExMjI1ODUwOTksMC44ODg3MDI1Njk1MzUzMzNdLCJ0cmFuc2xhdGlvbiI6WzE3Ljk0MjgxMTk2NTk0MjM4MywwLDBdfSx7Im5hbWUiOiJiX0xlZnRGb290MDJfMDE4Iiwicm90YXRpb24iOlswLDAsMC41NDcyODgyOTQ5MDkwMjQzLDAuODM2OTQ0MTU3MTkwNjUzM10sInRyYW5zbGF0aW9uIjpbMTUuNzc5OTM4Njk3ODE0OTQxLDAsMF19LHsiY2hpbGRyZW4iOlsyM10sIm5hbWUiOiJiX1JpZ2h0TGVnMDFfMDE5Iiwicm90YXRpb24iOlswLDAsMC45Njk5NTg1OTQyMDU0NTM1LC0wLjI0MzI3MDA2NzA1OTE4NTMzXSwidHJhbnNsYXRpb24iOls0LjgxMzc3NzkyMzU4Mzk4NCw1LjE1NDAyNjAzMTQ5NDE0MSw2Ljk2NzU2MzYyOTE1MDM5MV19LHsiY2hpbGRyZW4iOlsyNF0sIm5hbWUiOiJiX1JpZ2h0TGVnMDJfMDIwIiwicm90YXRpb24iOlswLDAsLTAuMzY4MDQzODE0MzIwNTI4ODUsMC45Mjk4MDg0NDg0MTMxMTA2XSwidHJhbnNsYXRpb24iOlsxOC45NDQxODMzNDk2MDkzNzUsMCwwXX0seyJjaGlsZHJlbiI6WzI1XSwibmFtZSI6ImJfUmlnaHRGb290MDFfMDIxIiwicm90YXRpb24iOlstMC4wMDAxNTM0NTQ1NTg3NjgwMzE2MywwLDAuNDU3OTA5Mzc0NjE2ODM0NiwwLjg4ODk5ODg2NDUwNDE3OF0sInRyYW5zbGF0aW9uIjpbMTcuOTQyODEwMDU4NTkzNzUsMCwwXX0seyJuYW1lIjoiYl9SaWdodEZvb3QwMl8wMjIiLCJyb3RhdGlvbiI6WzAsMCwwLjU0NzI4ODI5NDkwOTAyNDMsMC44MzY5NDQxNTcxOTA2NTMzXSwidHJhbnNsYXRpb24iOlsxNS43Nzk5MzU4MzY3OTE5OTIsMCwwXX1dLCJzYW1wbGVycyI6W3sibWFnRmlsdGVyIjo5NzI5LCJtaW5GaWx0ZXIiOjk5ODd9XSwic2NlbmUiOjAsInNjZW5lcyI6W3sibm9kZXMiOlswXX1dLCJza2lucyI6W3siaW52ZXJzZUJpbmRNYXRyaWNlcyI6NCwiam9pbnRzIjpbMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1XSwic2tlbGV0b24iOjJ9XSwidGV4dHVyZXMiOlt7InNhbXBsZXIiOjAsInNvdXJjZSI6MH1dfSAgIOw8AgBCSU4AnZsDQJHbDEJnXLjB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AgAQAAIAAgACABAAAgACAAIADQACAAIABAAFAAcACgAKAAQAAgACAAoAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABQAEAAIAAgAKAAIAAgACAAUABAACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIAAgAQAAIAAgADAAIAAgACAAIAEAARAAIABAAFAAcACgAEAAoABwACAAoABAACAAIAAgANAAIAAgACABAAAgACAAIADQACAAIAAwACAAIAAgADAAIAAgACAAIAEAACAAIAAgAQABEAAgADAAIAAgACAAIAAgACAAIACgACAAIAAgAKAAQAAgACAAoAAgACAAIADwACAAIAAgAPAA4AAgACAA8AAgACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIAAgAUAAIAAgACAA0AAgACAAIAEAAUAAIACgACAAIAAgAFAAQAAgACAAUABAACAAIABQAEAAIAAgAEAAUABwAKAAoAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABwACAAIAAgAHAAgAAgACAAcAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIAAgAUAAIAAgACAA0AAgACAAIAFAACAAIAAwACAAIAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgACABQAAgACAAMAAgACAAIAAgAQABQAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABQAAgACAAIAEAAUAAIAAgAUAAIAAgAVABQAAgACAAIAFAACAAIABwACAAIAAgAIAAcAAgACAAcACAACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIADwAOAAIAAgAPAAIAAgACAA8AAgACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIAAwACAAIAAgAHAAQAAgACAAMAFAACAAIAAgAUAAIAAgACAA0AAgACAAIAFAACAAIABAAFAAcACgAHAAIAAgACAAcABAACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABQAEAAIAAgAFAAQAAgACAAcAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIAAgAUAAIAAgACABQAFQACAAMAAgACAAIABAAFAAcACgAHAAQAAgACAAQACgAHAAIAAgANAAIAAgACAA0AAgACAAIAFAACAAIAAwACAAIAAgACABQAAgACAAMAAgACAAIAAgAUABUAAgACABQAAgACAAIAAgACAAIABwACAAIAAgAHAAIAAgACAAcABAACAAIADwACAAIAAgAPAAIAAgACAA8ADgACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIADwACAAIAAgAPAAIAAgACAA8AAgACAAIABwACAAIAAgAEAAUABwAKAAUABAACAAIABQAEAAIAAgAFAAQAAgACAAcAAgACAAIACgACAAIAAgAKAAIAAgACAAoAAgACAAIACgACAAIAAgAKAAQAAgACAAoAAgACAAIACgACAAIAAgALAAoAAgACAAoACwACAAIACgALAAIAAgAKAAIAAgACAAoAAgACAAIABwACAAIAAgAHAAQAAgACAAcAAgACAAIABwACAAIAAgAHAAIAAgACAAcAAgACAAIACgALAAIAAgAKAAIAAgACAAoABAACAAIACgAEAAIAAgAEAAoABwACAAoACwACAAIABwAIAAIAAgAEAAoABwACAAcABAACAAIABwAEAAIAAgAHAAIAAgACAAcACAACAAIABwACAAIAAgAHAAIAAgACAAcACAACAAIABwAIAAIAAgAIAAcAAgACAAcAAgACAAIAAwAUAAIAAgACABQAAgACAAIAFAACAAIAAgAUAAIAAgADAAIAAgACAAMAFAACAAIABAAKAAcAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgAEAAoABwACAAcABAACAAIABwAEAAIAAgADAAIAAgACAAMAAgACAAIAAwAQAAIAAgADAAIAAgACAAIAEAACAAIAAgAQAAIAAgACABAAAgACAAMAEAACAAIABAAKAAcAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgADAAIAAgACAAoABAACAAIACgAEAAIAAgAEAAoABwACAAMAAgACAAIAAwACAAIAAgACAAIAAgACAAIAAgACAAIAAwACAAIAAgACAAIAAgACAAIAAgACAAIAAwACAAIAAgACABQAFQACAAIAAgACAAIAAgAQAAIAAgACABAAEQACAAIAAgACAAIABQAEAAIAAgAFAAQAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAUABAACAAIABQAEAAIAAgAFAAQAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAUABAACAAIABQAEAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAFAAQAAgACAAUABAACAAIABQAEAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAFAAQAAgACAAUABAACAAIAAgANAAIAAgACAA0AAgACAA0ADgACAAIADQAOAAIAAgACAA0AAgACAA0ADgACAAIACgAEAAIAAgADABAAAgACAAMAEAACAAIAAwAQAAIAAgAKAAQAAgACAAoABAACAAIAAwACAAIAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgACAAIAAgACAAMAAgACAAIAAgANAAIAAgACABAAAgACAAIADQACAAIAAgACAAIAAgACABAAAgACAAIAEAACAAIAAgAQAAIAAgACABAAAgACAAIADQACAAIACgAEAAIAAgAKAAQAAgACAAoACwACAAIABAACAAIAAgAEAAIAAgACAAUABAACAAIABAACAAIAAgAEAAIAAgACAAUABAACAAIABgACAAIAAgAFAAQAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABQAEAAIAAgAFAAQAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABQAEAAIAAgAFAAQAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIAAgANAAIAAgACAA0AAgACAA0ADgACAAIAAgAQAAIAAgACABAAAgACABEAEAACAAIADQAOAAIAAgANAA4AAgACAA8ADgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIAAgACAAIAAgACAAIAAgACAAIADQACAAIAAgANAAIAAgACAA0AAgACAAIADQACAAIAAgAQAAIAAgACABAAAgACABAAEQACAAIAAgAQAAIAAgACABAAAgACABEAEAACAAIAAgAQAAIAAgACABAAAgACABEAEAACAAIAAgAQAAIAAgACABAAAgACABEAEAACAAIAEQASAAIAAgARABIAAgACABEAEgACAAIAEQASAAIAAgARABIAAgACABEAEgACAAIAEQAQAAIAAgACABAAEQACABEAEgACAAIAEQASAAIAAgARABIAAgACABEAEgACAAIAEQASAAIAAgARABIAAgACABEAEgACAAIAEQAQAAIAAgARABAAAgACABEAAgACAAIAEAARAAIAAgARABAAAgACABEAAgACAAIAEQASAAIAAgARABIAAgACABEAEgACAAIACgALAAIAAgAKAAsAAgACAAsAAgACAAIACwAKAAIAAgAKAAsAAgACAAsAAgACAAIABwACAAIAAgAHAAIAAgACAAcAAgACAAIABwACAAIAAgAHAAIAAgACAAcAAgACAAIABAAKAAcAAgAKAAQAAgACAAoACwACAAIACgALAAIAAgAKAAsAAgACAAsAAgACAAIADQAOAAIAAgACAA0AAgACAA0ADgACAAIADQAOAAIAAgAPAA4AAgACAA0ADgACAAIAAgANAAIAAgACAA0AAgACAA0ADgACAAIADQAOAAIAAgANAA4AAgACAAIADQACAAIADwAOAAIAAgAPAA4AAgACAA8AAgACAAIADwAOAAIAAgAPAA4AAgACAA8AAgACAAIADwAOAAIAAgAPAA4AAgACAA8AAgACAAIADwAOAAIAAgAPAA4AAgACAA8AAgACAAIADwAOAAIAAgAPAA4AAgACAA8AAgACAAIAEQAQAAIAAgACABAAAgACAAIAEAARAAIAAwACAAIAAgACAAIAAgACAAIAAgACAAIAAgANAAIAAgACAA0AAgACAAIADQACAAIAAgANAAIAAgACAA0AAgACAAIADQACAAIAAgANAAIAAgACAAIAAgACAAIAEAACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIAAgANAAIAAgACABAAAgACAAIADQACAAIABQAEAAIAAgAEAAIAAgACAAUABAACAAIABQAEAAIAAgAEAAIAAgACAAUABAACAAIACgALAAIAAgAKAAQAAgACAAoACwACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAFAAQAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIACgALAAIAAgAKAAQAAgACAAoACwACAAIACgACAAIAAgAKAAIAAgACAAoAAgACAAIAAwAQAAIAAgADAAIAAgACAAoABAACAAIADQAOAAIAAgACAA0AAgACAAIADQACAAIAEAARAAIAAgACABAAAgACABEAEAACAAIADwAOAAIAAgANAA4AAgACAA8ADgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIAAgANAAIAAgACAAIAAgACAAIADQACAAIAEQAQAAIAAgACABAAAgACABAAEQACAAIAAwACAAIAAgADAAIAAgACAAIAAgACAAIAEQAQAAIAAgACABAAAgACABEAEAACAAIAEQAQAAIAAgACABAAAgACABEAEAACAAIAEQAQAAIAAgACABAAAgACABEAEAACAAIAEQASAAIAAgACABAAEQACABEAEgACAAIACgALAAIAAgAEAAoABwACAAoACwACAAIACwACAAIAAgAKAAsAAgACAAsACgACAAIADwAOAAIAAgANAA4AAgACAA8ADgACAAIADwAOAAIAAgANAA4AAgACAA8ADgACAAIADwAOAAIAAgANAA4AAgACAA8ADgACAAIADwAOAAIAAgANAA4AAgACAA0ADgACAAIADwACAAIAAgAPAA4AAgACAA8AAgACAAIADwACAAIAAgAPAA4AAgACAA8AAgACAAIADwACAAIAAgAPAA4AAgACAA8AAgACAAIAAgANAAIAAgANAA4AAgACAAIADQACAAIADQAOAAIAAgANAA4AAgACAAIADQACAAIABwAEAAIAAgADABQAAgACAAMAFAACAAIAAwAUAAIAAgAHAAQAAgACAAcABAACAAIAAgACAAIAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgADAAIAAgACAAIAAgACAAIABAACAAIAAgAHAAIAAgACAAcAAgACAAIABwACAAIAAgAEAAIAAgACAAQAAgACAAIAAgANAAIAAgACAA0AAgACAAIAFAACAAIAAgACAAIAAgACABQAAgACAAIAFAACAAIAAgAUAAIAAgACAA0AAgACAAIAFAACAAIABwAEAAIAAgAHAAgAAgACAAcABAACAAIABAACAAIAAgAFAAQAAgACAAQAAgACAAIABAACAAIAAgAFAAQAAgACAAQAAgACAAIABgACAAIAAgAGAAIAAgACAAUABAACAAIABAACAAIAAgAFAAQAAgACAAUABAACAAIABQAEAAIAAgAKAAIAAgACAAQAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABQAEAAIAAgAGAAIAAgACAAUABAACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABQAEAAIAAgAGAAIAAgACAAUABAACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIAAgANAAIAAgANAA4AAgACAAIADQACAAIAAgAUAAIAAgAVABQAAgACAAIAFAACAAIADQAOAAIAAgAPAA4AAgACAA0ADgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIAAgACAAIAAgACAA0AAgACAAIAAgACAAIAAgANAAIAAgACAA0AAgACAAIADQACAAIAAgAUAAIAAgAUABUAAgACAAIAFAACAAIAAgAUAAIAAgAVABQAAgACAAIAFAACAAIAAgAUAAIAAgAVABQAAgACAAIAFAACAAIAAgAUAAIAAgAVABQAAgACAAIAFAACAAIAFQAWAAIAAgAVABYAAgACABUAFgACAAIAFQAUAAIAAgAVABYAAgACAAIAFAAVAAIAFQAWAAIAAgAVABYAAgACABUAFgACAAIAFQAWAAIAAgAVABYAAgACABUAFgACAAIAFQAUAAIAAgAVAAIAAgACABUAFAACAAIAFAAVAAIAAgAVAAIAAgACABUAFAACAAIAFQAWAAIAAgAVABYAAgACABUAFgACAAIABwAIAAIAAgAIAAIAAgACAAcACAACAAIACAAHAAIAAgAIAAIAAgACAAcACAACAAIABAAKAAcAAgAHAAgAAgACAAcABAACAAIABwAIAAIAAgAIAAIAAgACAAcACAACAAIADQAOAAIAAgAPAA4AAgACAA0ADgACAAIADQAOAAIAAgAPAA4AAgACAA0ADgACAAIADQAOAAIAAgAPAA4AAgACAA8ADgACAAIADwAOAAIAAgANAA4AAgACAA0ADgACAAIADwAOAAIAAgAPAAIAAgACAA8ADgACAAIADwAOAAIAAgAPAAIAAgACAA8ADgACAAIADwAOAAIAAgAPAAIAAgACAA8ADgACAAIADwAOAAIAAgAPAAIAAgACAA8ADgACAAIADwAOAAIAAgAPAAIAAgACAA8ADgACAAIAFQAUAAIAAgACABQAFQACAAIAFAACAAIAAwACAAIAAgACAAIAAgACAAIAAgACAAIAAgANAAIAAgACAA0AAgACAAIADQACAAIAAgANAAIAAgACAA0AAgACAAIADQACAAIAAgANAAIAAgACABQAAgACAAIAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIAAgANAAIAAgACAA0AAgACAAIAFAACAAIABQAEAAIAAgAFAAQAAgACAAQAAgACAAIABQAEAAIAAgAEAAIAAgACAAUABAACAAIABwAIAAIAAgAHAAgAAgACAAcABAACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAUABAACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABwAIAAIAAgAHAAgAAgACAAcABAACAAIABwACAAIAAgAHAAIAAgACAAcAAgACAAIAAwAUAAIAAgAHAAQAAgACAAMAAgACAAIADQAOAAIAAgACAA0AAgACAAIADQACAAIAFAAVAAIAAgAVABQAAgACAAIAFAACAAIADwAOAAIAAgAPAA4AAgACAA0ADgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIAAgANAAIAAgACAA0AAgACAAIAAgACAAIAFQAUAAIAAgAUABUAAgACAAIAFAACAAIAAwACAAIAAgACAAIAAgACAAMAAgACAAIAFQAUAAIAAgAVABQAAgACAAIAFAACAAIAFQAUAAIAAgAVABQAAgACAAIAFAACAAIAFQAUAAIAAgAVABQAAgACAAIAFAACAAIAFQAWAAIAAgAVABYAAgACABUAFgACAAIABwAIAAIAAgAEAAoABwACAAcACAACAAIACAACAAIAAgAIAAcAAgACAAcACAACAAIADwAOAAIAAgAPAA4AAgACAA0ADgACAAIADwAOAAIAAgAPAA4AAgACAA0ADgACAAIADwAOAAIAAgAPAA4AAgACAA0ADgACAAIADQAOAAIAAgANAA4AAgACAA8ADgACAAIADwAOAAIAAgAPAA4AAgACAA0ADgACAAIADwACAAIAAgAPAAIAAgACAA8ADgACAAIADwACAAIAAgAPAAIAAgACAA8ADgACAAIADwACAAIAAgAPAAIAAgACAA8ADgACAAIAEQASAAIAAgARABIAAgACAAIAEAARAAIAAgAQABEAAgACABAAAgACABEAEgACAAIABAACAAIAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgAEAAIAAgACAAQAAgACAAIACgAEAAIAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgAEAAIAAgACAAoABAACAAIABwAEAAIAAgAHAAgAAgACAAcAAgACAAIABAACAAIAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgAHAAQAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAMAAgACAAIAAwACAAIAAgADAAIAAgACAAQAAgACAAIACgACAAIAAgAKAAIAAgACAAoAAgACAAIACgACAAIAAgAKAAIAAgACAAoAAgACAAIABwAIAAIAAgAIAAcAAgACAAcAAgACAAIABwACAAIAAgAHAAIAAgACAAcACAACAAIABwAIAAIAAgAHAAgAAgACAAcAAgACAAIACgACAAIAAgAKAAsAAgACAAoACwACAAIACgALAAIAAgAKAAIAAgACAAoAAgACAAIACgACAAIAAgAKAAsAAgACAAsACgACAAIACwAKAAIAAgAKAAIAAgACAAoAAgACAAIABwACAAIAAgAHAAIAAgACAAgABwACAAIACAAHAAIAAgAHAAgAAgACAAcAAgACAAIACwAKAAIAAgAKAAsAAgACAAoACwACAAIACAAHAAIAAgAHAAgAAgACAAcACAACAAIACgALAAIAAgAKAAIAAgACAAsACgACAAIACgACAAIAAgAKAAsAAgACAAoAAgACAAIACgACAAIAAgAKAAIAAgACAAoAAgACAAIABAACAAIAAgAEAAIAAgACAAoAAgACAAIACgACAAIAAgAKAAIAAgACAAQAAgACAAIACgACAAIAAgAKAAQAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAoAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIABwACAAIAAgAHAAIAAgACAAcACAACAAIABwAIAAIAAgAHAAIAAgACAAcAAgACAAIACgAEAAIAAgAKAAIAAgACAAoACwACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAcABAACAAIABwAEAAIAAgAHAAIAAgACAAQAAgACAAIAEQASAAIAAgARABIAAgACABEAEAACAAIAEQAQAAIAAgARABAAAgACABEAEgACAAIAEQASAAIAAgARABIAAgACAAIAEAACAAIAAgAQAAIAAgARABAAAgACABEAEgACAAIAEQASAAIAAgARABIAAgACABEAEAACAAIAEQAQAAIAAgARABAAAgACABEAEgACAAIAFQAWAAIAAgAVABQAAgACABUAFAACAAIAFQAUAAIAAgAVABYAAgACABUAFgACAAIAFQAWAAIAAgAVABQAAgACABUAFAACAAIAFQAUAAIAAgAVABYAAgACABUAFgACAAIAFQAUAAIAAgAVABYAAgACABQAFQACAAIAEQAQAAIAAgAQABEAAgACABEAEgACAAIAFQAWAAIAAgACABQAAgACAAIAFAAVAAIAAgAUABUAAgAVABYAAgACABUAFgACAAIAFQAWAAIAAgAVABQAAgACAAIAFAACAAIAAgAUAAIAAgAVABYAAgACABUAFgACAAIAAgAUABUAAgAVABYAAgACABUAFgACAAIAAgANAAIAAgANAA4AAgACAA0ADgACAAIADQAOAAIAAgACAA0AAgACAAIADQACAAIAAgANAAIAAgANAA4AAgACAA0ADgACAAIAAgANAAIAAgANAA4AAgACAA0ADgACAAIAAgANAAIAAgANAA4AAgACAA0ADgACAAIABAACAAIAAgADAAIAAgACAAMAAgACAAIABAACAAIAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgADAAIAAgACAAQAAgACAAIABAACAAIAAgAEAAIAAgACAAMAAgACAAIAAwACAAIAAgADAAIAAgACAAIAEAACAAIAAgAQAAIAAgACAAIAAgACAAMAAgACAAIAAwACAAIAAgADABAAAgACAAIAEAACAAIAAgAQAAIAAgACABAAAgACAAMAAgACAAIAAgAQAAIAAgADAAIAAgACAAMAAgACAAIAAgAQAAIAAgADABAAAgACAAMAEAACAAIAAgAUAAIAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgAEAAIAAgACAAQAAgACAAIABAACAAIAAgADAAIAAgACAAMAAgACAAIAAwACAAIAAgACAAIAAgACAAIAFAACAAIAAgAUAAIAAgADAAIAAgACAAMAAgACAAIAAgAUAAIAAgADABQAAgACAAMAFAACAAIAAwACAAIAAgACABQAAgACAAIAFAACAAIAAgAUAAIAAgADABQAAgACAAMAAgACAAIABAACAAIAAgAHAAIAAgACAAUABAACAAIABQAEAAIAAgAFAAQAAgACAAQAAgACAAIABQAEAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAFAAQAAgACAAUABAACAAIABQAEAAIAAgAFAAQAAgACAAoAAgACAAIACgACAAIAAgAKAAIAAgACAAUABAACAAIABQAEAAIAAgAHAAIAAgACAAcAAgACAAIABwACAAIAAgAFAAQAAgACAAUABAACAAIABQAEAAIAAgAFAAQAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAUABAACAAIABgACAAIAAgAFAAQAAgACAAUABAACAAIABgACAAIAAgAFAAQAAgACAAUABAACAAIAEQASAAIAAgARAAIAAgACABIAEQACAAIAEQASAAIAAgARABIAAgACABMAEgACAAIAEQASAAIAAgASABEAAgACABIAEwACAAIAEwASAAIAAgASABMAAgACABMAAgACAAIAEQASAAIAAgARABIAAgACABMAEgACAAIAEgARAAIAAgARABIAAgACABIAEwACAAIAEQASAAIAAgARABIAAgACABIAEwACAAIAEQASAAIAAgARABIAAgACABIAEwACAAIAEwACAAIAAgATABIAAgACABMAAgACAAIAEwACAAIAAgATAAIAAgACABMAAgACAAIAEwASAAIAAgATAAIAAgACABMAAgACAAIAEwACAAIAAgASABMAAgACABMAAgACAAIAEgATAAIAAgASABMAAgACABMAAgACAAIAEgATAAIAAgASABMAAgACABMAAgACAAIACwACAAIAAgALAAIAAgACAAwACwACAAIACwACAAIAAgAMAAsAAgACAAsAAgACAAIACwACAAIAAgALAAIAAgACAAwACwACAAIACwACAAIAAgALAAIAAgACAAwACwACAAIACwACAAIAAgALAAIAAgACAAwACwACAAIACwACAAIAAgALAAoAAgACAAsAAgACAAIADAACAAIAAgAMAAsAAgACAAwAAgACAAIADAACAAIAAgAMAAIAAgACAAwAAgACAAIADAALAAIAAgAMAAsAAgACAAwAAgACAAIADAALAAIAAgAMAAsAAgACAAwAAgACAAIADAALAAIAAgAMAAsAAgACAAwAAgACAAIADAALAAIAAgAMAAsAAgACAAwAAgACAAIADAALAAIAAgAMAAsAAgACAAwAAgACAAIAEQASAAIAAgARABAAAgACABEAEgACAAIAEQACAAIAAgARABAAAgACABEAEgACAAIAEQASAAIAAgARABAAAgACABEAEgACAAIAEgARAAIAAgARAAIAAgACABEAEgACAAIAEQASAAIAAgAQABEAAgACABEAAgACAAIAEgATAAIAAgARABIAAgACABMAEgACAAIAEgATAAIAAgASABEAAgACABIAEwACAAIAEwASAAIAAgARABIAAgACABMAEgACAAIAEgATAAIAAgASABEAAgACABIAEwACAAIAEwASAAIAAgARABIAAgACABIAEwACAAIAEwACAAIAAgATABIAAgACABMAEgACAAIAEwACAAIAAgATAAIAAgACABMAAgACAAIAEwASAAIAAgATAAIAAgACABMAAgACAAIAEwACAAIAAgATAAIAAgACABMAAgACAAIAEwACAAIAAgASABMAAgACABMAEgACAAIAEwACAAIAAgASABMAAgACABMAAgACAAIACwACAAIAAgAKAAsAAgACAAsAAgACAAIADAALAAIAAgALAAIAAgACAAwACwACAAIACwACAAIAAgALAAoAAgACAAsAAgACAAIACwACAAIAAgALAAoAAgACAAsAAgACAAIACwACAAIAAgAKAAsAAgACAAsAAgACAAIADAALAAIAAgALAAIAAgACAAwACwACAAIADAALAAIAAgALAAIAAgACAAwACwACAAIADAACAAIAAgAMAAsAAgACAAwAAgACAAIADAALAAIAAgAMAAsAAgACAAwACwACAAIADAACAAIAAgAMAAIAAgACAAwAAgACAAIADAACAAIAAgAMAAIAAgACAAwAAgACAAIADAACAAIAAgAMAAsAAgACAAwAAgACAAIADAACAAIAAgAMAAsAAgACAAwAAgACAAIADAACAAIAAgAMAAsAAgACAAwAAgACAAIAFQAWAAIAAgAWABUAAgACABUAAgACAAIAFQAWAAIAAgAXABYAAgACABUAFgACAAIAFQAWAAIAAgAWABcAAgACABYAFQACAAIAFwAWAAIAAgAXAAIAAgACABYAFwACAAIAFQAWAAIAAgAXABYAAgACABUAFgACAAIAFgAVAAIAAgAWABcAAgACABUAFgACAAIAFQAWAAIAAgAWABcAAgACABUAFgACAAIAFQAWAAIAAgAWABcAAgACABUAFgACAAIAFwACAAIAAgAXAAIAAgACABcAFgACAAIAFwACAAIAAgAXAAIAAgACABcAAgACAAIAFwAWAAIAAgAXAAIAAgACABcAAgACAAIAFwACAAIAAgAXAAIAAgACABYAFwACAAIAFgAXAAIAAgAXAAIAAgACABYAFwACAAIAFgAXAAIAAgAXAAIAAgACABYAFwACAAIACAACAAIAAgAJAAgAAgACAAgAAgACAAIACAACAAIAAgAJAAgAAgACAAgAAgACAAIACAACAAIAAgAJAAgAAgACAAgAAgACAAIACAACAAIAAgAJAAgAAgACAAgAAgACAAIACAACAAIAAgAJAAgAAgACAAgAAgACAAIACAACAAIAAgAJAAgAAgACAAgAAgACAAIACQACAAIAAgAJAAIAAgACAAkACAACAAIACQACAAIAAgAJAAIAAgACAAkAAgACAAIACQAIAAIAAgAJAAIAAgACAAkACAACAAIACQAIAAIAAgAJAAIAAgACAAkACAACAAIACQAIAAIAAgAJAAIAAgACAAkACAACAAIACQAIAAIAAgAJAAIAAgACAAkACAACAAIACQAIAAIAAgAJAAIAAgACAAkACAACAAIAFQAWAAIAAgAVABYAAgACABUAFAACAAIAFQACAAIAAgAVABYAAgACABUAFAACAAIAFQAWAAIAAgAVABYAAgACABUAFAACAAIAFgAVAAIAAgAVABYAAgACABUAAgACAAIAFQAWAAIAAgAVAAIAAgACABQAFQACAAIAFgAXAAIAAgAXABYAAgACABUAFgACAAIAFgAXAAIAAgAWABcAAgACABYAFQACAAIAFwAWAAIAAgAXABYAAgACABUAFgACAAIAFgAXAAIAAgAWABcAAgACABYAFQACAAIAFwAWAAIAAgAWABcAAgACABUAFgACAAIAFwACAAIAAgAXABYAAgACABcAFgACAAIAFwACAAIAAgAXAAIAAgACABcAAgACAAIAFwAWAAIAAgAXAAIAAgACABcAAgACAAIAFwACAAIAAgAXAAIAAgACABcAAgACAAIAFwACAAIAAgAXABYAAgACABYAFwACAAIAFwACAAIAAgAXAAIAAgACABYAFwACAAIACAACAAIAAgAIAAIAAgACAAcACAACAAIACQAIAAIAAgAJAAgAAgACAAgAAgACAAIACAACAAIAAgAIAAIAAgACAAgABwACAAIACAACAAIAAgAIAAIAAgACAAgABwACAAIACAACAAIAAgAIAAIAAgACAAcACAACAAIACQAIAAIAAgAJAAgAAgACAAgAAgACAAIACQAIAAIAAgAJAAgAAgACAAgAAgACAAIACQACAAIAAgAJAAIAAgACAAkACAACAAIACQAIAAIAAgAJAAgAAgACAAkACAACAAIACQACAAIAAgAJAAIAAgACAAkAAgACAAIACQACAAIAAgAJAAIAAgACAAkAAgACAAIACQACAAIAAgAJAAIAAgACAAkACAACAAIACQACAAIAAgAJAAIAAgACAAkACAACAAIACQACAAIAAgAJAAIAAgACAAkACAACAAIACwACAAIAAgAMAAsAAgACAAwACwACAAIADAALAAIAAgALAAIAAgACAAsAAgACAAIACAACAAIAAgAIAAIAAgACAAkACAACAAIACQAIAAIAAgAJAAgAAgACAAgAAgACAAIACAACAAIAAgAIAAIAAgACAAkACAACAAIACQAIAAIAAgAJAAgAAgACAAgAAgACAAIACwACAAIAAgALAAIAAgACAAsACgACAAIACwAKAAIAAgAKAAsAAgACAAsAAgACAAIACwACAAIAAgAMAAsAAgACAAwACwACAAIADAALAAIAAgALAAIAAgACAAsAAgACAAIACwACAAIAAgAMAAsAAgACAAwACwACAAIADAALAAIAAgALAAIAAgACAAsAAgACAAIACAACAAIAAgAHAAgAAgACAAcACAACAAIABwAIAAIAAgAIAAIAAgACAAgAAgACAAIACAACAAIAAgAIAAcAAgACAAcACAACAAIABwAIAAIAAgAIAAIAAgACAAgAAgACAAIACwACAAIAAgALAAIAAgACAAoACwACAAIACgALAAIAAgAKAAsAAgACAAsAAgACAAIACwACAAIAAgALAAIAAgACAAoACwACAAIACgALAAIAAgALAAoAAgACAAsAAgACAAIACAACAAIAAgAHAAgAAgACAAgABwACAAIACAAHAAIAAgAIAAIAAgACAAgAAgACAAIACAACAAIAAgAIAAIAAgACAAkACAACAAIACQAIAAIAAgAJAAgAAgACAAgAAgACAAIADAALAAIAAgALAAIAAgACAAsAAgACAAIACwAKAAIAAgALAAIAAgACAAsAAgACAAIACAAHAAIAAgAIAAIAAgACAAgAAgACAAIACAAHAAIAAgAIAAIAAgACAAgAAgACAAIAFQAWAAIAAgAVABYAAgACABUAFgACAAIAFQAWAAIAAgAVABYAAgACABUAFgACAAIAEQASAAIAAgARABIAAgACABEAEgACAAIAEQASAAIAAgARABIAAgACABEAEgACAAIAEQASAAIAAgARABIAAgACABEAEgACAAIAEQASAAIAAgARABIAAgACABEAEgACAAIAFQAWAAIAAgAVABYAAgACABUAFgACAAIAFQAWAAIAAgAVABYAAgACABUAFgACAAIAFQAWAAIAAgAVABYAAgACABUAFAACAAIAFQAWAAIAAgAVABYAAgACABUAFgACAAIAEQASAAIAAgARABAAAgACABEAEgACAAIAEQASAAIAAgARABIAAgACABEAEgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIABgACAAIAAgAGAAIAAgACAAYAAgACAAIAmpkZP83MzD4AAAAAAAAAANo/Mz+amRk+AmcZPgAAAAAK12M/rkfhPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/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AACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAMzNzP83MTD0AAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAMzNzP83MTD0AAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAACtdjP65H4T0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAACZmRk/zszMPgAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAChcDz+wR+E+AAAAAAAAAACZmRk/zszMPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAACA61E/AVI4PgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAACA61E/AVI4PgAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAACamRk/zczMPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAB+Faz8K16M9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAmZkZP87MzD4AAAAAAAAAAIFuFD8BNKY+9rvDPQAAAAAfhWs/CtejPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAACamRk/zczMPgAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAACamRk/zczMPgAAAAAAAAAAmZkZP87MzD4AAAAAAAAAAJmZGT/OzMw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAJmZGT/OzMw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAACamRk/zczMPgAAAAAAAAAApHA9P7gehT4AAAAAAAAAAKRwPT+4HoU+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAKRwPT+4HoU+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAytRMP83MzD3cjMw9AAAAAM3MTD/NzEw+AAAAAAAAAACkcD0/uB6FPgAAAAAAAAAApHA9P7gehT4AAAAAAAAAAKRwPT+4HoU+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAACtdjP65H4T0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAmZkZP87MzD4AAAAAAAAAAChcDz+wR+E+AAAAAAAAAACBbhQ/ATSmPva7wz0AAAAAexQuPwrXoz4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAACtdjP65H4T0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAACtdjP65H4T0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAACtdjP65H4T0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAEA/AACAPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAACtdjP65H4T0AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAMzNzP83MTD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAMzNzP83MTD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAApHA9P7gehT4AAAAAAAAAAM3MTD/NzEw+AAAAAAAAAACkcD0/uB6FPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAApHA9P7gehT4AAAAAAAAAAM3MTD/NzEw+AAAAAAAAAACkcD0/uB6FPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAACZmRk/zszMPgAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAgOtRPwFSOD4AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAXI9CP4/CdT4AAAAAAAAAAML1KD97FK4+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAmZkZP87MzD4AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAACZmRk/zszMPgAAAAAAAAAAgOtRPwFSOD4AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAACA61E/AVI4PgAAAAAAAAAAGIVrP0HXoz0AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAACA61E/AVI4PgAAAAAAAAAAH4VrPwrXoz0AAAAAAAAAAIFuFD8BNKY+9rvDPQAAAABmZmY/zMzMPQAAAAAAAAAApHA9P7gehT4AAAAAAAAAAMrUTD/NzMw93IzMPQAAAACkcD0/uB6FPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAKRwPT+4HoU+AAAAAAAAAAAUrkc/sEdhPgAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAACtdjP65H4T0AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAM3MTD/NzEw+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAFyPQj+PwnU+AAAAAAAAAABcj0I/j8J1PgAAAAAAAAAAXI9CP4/CdT4AAAAAAAAAAHsULj8K16M+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAACtdjP65H4T0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAAAEA/AACAPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAEA/AACAPgAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAArXYz+uR+E9AAAAAAAAAACamRk/zczMPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAKRwPT+4HoU+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAMzNzP83MTD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAMzNzP83MTD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAMzNzP83MTD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAACtdjP65H4T0AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAJmZGT/OzMw+AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAEA/AACAPgAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAJmZGT/OzMw+AAAAAAAAAAAoXA8/sEfhPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAIDrUT8BUjg+AAAAAAAAAAAAAEA/AACAPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAIDrUT8BUjg+AAAAAAAAAACamRk/zczMPgAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAmZkZP87MzD4AAAAAAAAAAB+Faz8K16M9AAAAAAAAAACBbhQ/ATSmPva7wz0AAAAAZmZmP8zMzD0AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAmZkZP87MzD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAACZmRk/zszMPgAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAACZmRk/zszMPgAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAApHA9P7gehT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAACkcD0/uB6FPgAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAACkcD0/uB6FPgAAAAAAAAAAytRMP83MzD3cjMw9AAAAAKRwPT+4HoU+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAApHA9P7gehT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAACkcD0/uB6FPgAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAmZkZP87MzD4AAAAAAAAAAIFuFD8BNKY+9rvDPQAAAAAoXA8/sEfhPgAAAAAAAAAAexQuPwrXoz4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAACtdjP65H4T0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAACtdjP65H4T0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAACtdjP65H4T0AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAACtdjP65H4T0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAAAEA/AACAPgAAAAAAAAAAMzNzP83MTD0AAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAMzNzP83MTD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAApHA9P7gehT4AAAAAAAAAAKRwPT+4HoU+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAApHA9P7gehT4AAAAAAAAAAKRwPT+4HoU+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAJmZGT/OzMw+AAAAAAAAAAAAAEA/AACAPgAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAgOtRPwFSOD4AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAEA/AACAPgAAAAAAAAAAXI9CP4/CdT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADC9Sg/exSuPgAAAAAAAAAAmZkZP87MzD4AAAAAAAAAAJmZGT/OzMw+AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAgOtRPwFSOD4AAAAAAAAAAIDrUT8BUjg+AAAAAAAAAACamRk/zczMPgAAAAAAAAAAGIVrP0HXoz0AAAAAAAAAAIDrUT8BUjg+AAAAAAAAAACamRk/zczMPgAAAAAAAAAAH4VrPwrXoz0AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAApHA9P7gehT4AAAAAAAAAAMrUTD/NzMw93IzMPQAAAACkcD0/uB6FPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAABSuRz+wR2E+AAAAAAAAAACkcD0/uB6FPgAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAACBbhQ/ATSmPva7wz0AAAAAgW4UPwE0pj72u8M9AAAAAJqZGT/NzMw+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAML1KD97FK4+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAKRwPT+4HoU+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAML1KD97FK4+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAApHA9P7gehT4AAAAAAAAAABSuRz+wR2E+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAM3MTD/NzEw+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAUrkc/sEdhPgAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAUrkc/sEdhPgAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAKRwPT+4HoU+AAAAAAAAAACkcD0/uB6FPgAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAKRwPT+4HoU+AAAAAAAAAACkcD0/uB6FPgAAAAAAAAAApHA9P7gehT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAUrkc/sEdhPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAKRwPT+4HoU+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAACkcD0/uB6FPgAAAAAAAAAApHA9P7gehT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAACkcD0/uB6FPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAAAYhWs/QdejPQAAAAAAAAAAGIVrP0HXoz0AAAAAAAAAAIDrUT8BUjg+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAACamRk/zczMPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAABiFaz9B16M9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAACA61E/AVI4PgAAAAAAAAAAgOtRPwFSOD4AAAAAAAAAAIDrUT8BUjg+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAIDrUT8BUjg+AAAAAAAAAACA61E/AVI4PgAAAAAAAAAAgOtRPwFSOD4AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAIDrUT8BUjg+AAAAAAAAAAAYhWs/QdejPQAAAAAAAAAAGIVrP0HXoz0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAgOtRPwFSOD4AAAAAAAAAAB+Faz8K16M9AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAgOtRPwFSOD4AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAfhWs/CtejPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAACBbhQ/ATSmPva7wz0AAAAAgW4UPwE0pj72u8M9AAAAAGZmZj/MzMw9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAABiFaz9B16M9AAAAAAAAAACamRk/zczMPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAgW4UPwE0pj72u8M9AAAAAB+Faz8K16M9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAACtdjP65H4T0AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAArXYz+uR+E9AAAAAAAAAAAK12M/rkfhPQAAAAAAAAAACtdjP65H4T0AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAACtdjP65H4T0AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAACtdjP65H4T0AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAFyPQj+PwnU+AAAAAAAAAABcj0I/j8J1PgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAFyPQj+PwnU+AAAAAAAAAABcj0I/j8J1PgAAAAAAAAAAwvUoP3sUrj4AAAAAAAAAAFyPQj+PwnU+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADC9Sg/exSuPgAAAAAAAAAAwvUoP3sUrj4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAEA/AACAPgAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADC9Sg/exSuPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAwvUoP3sUrj4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAFyPQj+PwnU+AAAAAAAAAADC9Sg/exSuPgAAAAAAAAAAwvUoP3sUrj4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAEA/AACAPgAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADC9Sg/exSuPgAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAMzNzP83MTD0AAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAMzNzP83MTD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAMzNzP83MTD0AAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAMzNzP83MTD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAMzNzP83MTD0AAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAADMzcz/NzEw9AAAAAAAAAAAzM3M/zcxMPQAAAAAAAAAAH4VrPwrXoz0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADhehQ/PgrXPgAAAAAAAAAAH4VrPwrXoz0AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAH4VrPwrXoz0AAAAAAAAAAOF6FD8+Ctc+AAAAAAAAAAB7FC4/CtejPgAAAAAAAAAANDMzP5mZmT4AAAAAAAAAAHsULj8K16M+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAAA0MzM/mZmZPgAAAAAAAAAA4XoUPz4K1z4AAAAAAAAAAB+Faz8K16M9AAAAAAAAAAB7FC4/CtejPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAB+Faz8K16M9AAAAAAAAAAB7FC4/CtejPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAAB7FC4/CtejPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAANDMzP5mZmT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAHsULj8K16M+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAexQuPwrXoz4AAAAAAAAAAD0KVz8M1yM+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAPQpXPwzXIz4AAAAAAAAAAHsULj8K16M+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAABSuRz+wR2E+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAIDrUT8BUjg+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAJmZGT/OzMw+AAAAAAAAAAAfhWs/CtejPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAABiFaz9B16M9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAA4XoUPz4K1z4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAfhWs/CtejPQAAAAAAAAAAH4VrPwrXoz0AAAAAAAAAAAAAAD8AAAA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAexQuPwrXoz4AAAAAAAAAAB+Faz8K16M9AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAexQuPwrXoz4AAAAAAAAAAOF6FD8+Ctc+AAAAAAAAAAA9Clc/DNcjPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAAA0MzM/mZmZPgAAAAAAAAAAPQpXPwzXIz4AAAAAAAAAAOF6FD8+Ctc+AAAAAAAAAAB7FC4/CtejPgAAAAAAAAAANDMzP5mZmT4AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAAB7FC4/CtejPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAA0MzM/mZmZPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAANDMzP5mZmT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAHsULj8K16M+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAD0KVz8M1yM+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAKRwPT+4HoU+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAABSuRz+wR2E+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAABSuRz+wR2E+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAH4VrPwrXoz0AAAAAAAAAAOF6FD8+Ctc+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAH4VrPwrXoz0AAAAAAAAAAM3MTD/NzEw+AAAAAAAAAACamRk/zczMPgAAAAAAAAAAH4VrPwrXoz0AAAAAAAAAAHsULj8K16M+AAAAAAAAAADhehQ/PgrXPgAAAAAAAAAANDMzP5mZmT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAB7FC4/CtejPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAADQzMz+ZmZk+AAAAAAAAAACamRk/zczMPgAAAAAAAAAA4XoUPz4K1z4AAAAAAAAAAHsULj8K16M+AAAAAAAAAAAfhWs/CtejPQAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAHsULj8K16M+AAAAAAAAAAAfhWs/CtejPQAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAHsULj8K16M+AAAAAAAAAACamRk/zczMPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAANDMzP5mZmT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAB7FC4/CtejPgAAAAAAAAAAexQuPwrXoz4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAA9Clc/DNcjPgAAAAAAAAAAPQpXPwzXIz4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAB7FC4/CtejPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAACA61E/AVI4PgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAB+Faz8K16M9AAAAAAAAAACZmRk/zszMPgAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAAAYhWs/QdejPQAAAAAAAAAA4XoUPz4K1z4AAAAAAAAAAB+Faz8K16M9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAH4VrPwrXoz0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAexQuPwrXoz4AAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAfhWs/CtejPQAAAAAAAAAAexQuPwrXoz4AAAAAAAAAAD0KVz8M1yM+AAAAAAAAAADhehQ/PgrXPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAADQzMz+ZmZk+AAAAAAAAAACamRk/zczMPgAAAAAAAAAAPQpXPwzXIz4AAAAAAAAAAHsULj8K16M+AAAAAAAAAADhehQ/PgrXPgAAAAAAAAAANDMzP5mZmT4AAAAAAAAAAHsULj8K16M+AAAAAAAAAACamRk/zczMPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAADQzMz+ZmZk+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAANDMzP5mZmT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAB7FC4/CtejPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAA9Clc/DNcjPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAACkcD0/uB6FPgAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAUrkc/sEdhPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAUrkc/sEdhPgAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAUrkc/sEdhPgAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAGZmZj/NzMw9AAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAM3MTD/NzEw+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAABSuRz+wR2E+AAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAADNzEw/zcxMPgAAAAAAAAAAzcxMP83MTD4AAAAAAAAAABSuRz+wR2E+AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAM3MTD/NzEw+AAAAAAAAAAAUrkc/sEdhPgAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAABmZmY/zczMPQAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAGZmZj/NzMw9AAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP83MzD0AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAFK5HP7BHYT4AAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAACamRk/zczMPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAACamRk/zczMPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAACamRk/zczMPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAACamRk/zczMPgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAJqZGT/NzMw+AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAB+Faz8K16M9AAAAAAAAAACA61E/AVI4PgAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAB+Faz8K16M9AAAAAAAAAABmZmY/zMzMPQAAAAAAAAAAZmZmP8zMzD0AAAAAAAAAAIDrUT8BUjg+AAAAAAAAAAAfhWs/CtejPQAAAAAAAAAAmpkZP83MzD4AAAAAAAAAAGZmZj/MzMw9AAAAAAAAAAAfhWs/CtejPQAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAIAAAAAAAAAAgAAAAIAAAIA/AAAAgAAAAAAAAAAAAAAAgAAAgD8AAACAAAAAgAAAAAAAAACAAACAPwAAgD8AAACAAAAAAAAAAIAAAACA1Zp2tgEAgD8AAAAAAAAAAAEAgL/Vmna2AAAAgAAAAIAAAAAAAAAAgAAAgD/B0nGz/imLtQAAgL8AAAAA3E1vP7vftT7YW+K0AAAAALvftT7cTW+/cM1/NQAAAICZFvXBzAYhwjXYNjgAAIA/dVeCNdZfxbQAAIC/AAAAgNg5Y70Um38/2FvitAAAAAAUm38/2DljPW/NfzUAAACAbZXJQY+KVsI12DY4AACAP2aLgDVwaNe0AACAvwAAAICiYam8/fF/P9hb4rQAAAAA/fF/P6JhqTxwzX81AAAAgFwW1j9u51bCNtg2OAAAgD+NfhM1Y4RstQAAgL8AAACAsqgPP0nkUz/XW+K0AAAAgEnkUz+yqA+/cc1/NQAAAIBdgErCisrvwTXYNjgAAIA/gt+INegQUrQAAIC/AAAAgL5QZ74GYnk/2FvitAAAAAAGYnk/vlBnPnHNfzUAAACA9QSswVelhsI12DY4AACAPyNCJjiaKqm68v9/vwAAAICw13+/8KUPvSmCvTYAAAAA6qUPvaLXfz97Pqm6AAAAgLusRkIjaILBnznewAAAgD8732u46BWpuvL/f78AAAAArs1/v498ID05gr02AAAAAIV8ID2gzX8/eT6pugAAAICcucpB5dmRwZ853sAAAIA/a4h+uxVb5DwK5n+/AAAAAKsMC7912FY/fgLRPAAAAABH8VY/DQULPzOqQjwAAACA/r81wR2wccHLHevAAACAP9r7CrpICQC73v9/vwAAAABG2H+/8ZMOvR66HDoAAAAAF5UOvSnYfz91f/26AAAAgOGrRkJfVILBNyffQAAAgD8mmjC61DX6ut7/f78AAAAA/sx/v4GOIT0duhw6AAAAADmNIT3jzH8/dX/9ugAAAIBgucpBEMaRwTYn30AAAIA/Tk/9OyItL70Uwn+/AAAAgOYoC7/GoFY/yjskvQAAAAA/3VY/jBsLPyBbibwAAACA0jA2wZAlcMH2IPBAAACAP3cGs7S3/IM1AACAvwAAAICCTDy/QG8tv9pb4rQAAAAAQG8tv4JMPD9wzX81AAAAgJqpN0FDU4JCNNg2OAAAgD/Cnvq0ivt4NQAAgL8AAACAW2Iiv1LoRb/YW+K0AAAAAFLoRb9bYiI/b81/NQAAAIDfmB/Bg82AQjXYNjgAAIA/DFoXtUkRajUAAIC/AAAAgIgqDL/hN1a/2lvitAAAAADhN1a/iCoMP3DNfzUAAACALMMjwhRmcUI22DY4AACAP0A2sDgpKa85//9/vwAAAIAi6X2/ZI8CPuHiKrgAAAAAY48CPiHpfT+UWbM5AAAAgOKwUkI4obpB+F3fQAAAgD/Bhy+5u9udOQAAgL8AAACAcHZPv/b7Fb/f4iq4AAAAAPX7Fb9vdk8/lFmzOQAAAICi/QlBcV8gQvld30AAAIA/DZumuJfyCLkAAIC/AAAAAFJ3cr8/RaQ+29YLOAAAAAA/RaQ+UndyP0duHLkAAACAjy/aQVKs9kGOu95AAACAP6fbHrk3PKs3AACAvwAAAACnyK+9KA5/P9zWCzgAAAAAKA5/P6jIrz1Ibhy5AAAAgOtrA0I4wOo/j7veQAAAgD+5rBA1mEBuNQAAgL8AAACAMOV9v/EJAz7ZW+K0AAAAAPEJAz4w5X0/b81/NQAAAIC/vFJCInO6Qev13sAAAIA/RlZmtNBciDUAAIC/AAAAgIWIT7/s4hW/2FvitAAAAADs4hW/hYhPP2/NfzUAAACASF8KQb5WIELt9d7AAACAP50ZFDnWco85AQCAvwAAAICUiHK/NN+jPtnwQbgAAAAANN+jPpSIcj/xmp85AAAAgM/q2UFBwPZBoZHewAAAgD+FGqE5LCSltwAAgL8AAACA7nWxvYEJfz/Y8EG4AAAAAIEJfz/tdbE98pqfOQAAAIBCZwNCnC/vP6GR3sAAAIA/AAAAAKuqKj2rqqo9AAAAPquqKj5VVVU+AACAPlVVlT6rqqo+AADAPlVV1T6rquo+AAAAP6uqCj9VVRU/AAAgP6uqKj9VVTU/AABAP6uqSj9VVVU/AABgP6uqaj9VVXU/AACAP1VVhT+rqoo/AACQP1VVlT+rqpo/AACgP1VVpT+rqqo/AACwP1VVtT+rqro/AADAP1VVxT+rqso/AADQP1VV1T+rqto/AADgP1VV5T+rquo/AADwP1VV9T+rqvo/AAAAQKuqAkBVVQVAAAAIQKuqCkBVVQ1AAAAQQKuqEkBVVRVAAAAYQKuqGkBVVR1AAAAgQKuqIkBVVSVAAAAoQKuqKkBVVS1AAAAwQKuqMkBVVTVAAAA4QKuqOkBVVT1AAABAQKuqQkBVVUVAAABIQKuqSkBVVU1AAABQQKuqUkBVVVVAAABYQKuqWkAAAAAAq6oqPauqqj0AAAA+q6oqPlVVVT4AAIA+VVWVPquqqj4AAMA+VVXVPquq6j4AAAA/q6oKP1VVFT8AACA/q6oqP1VVNT8AAAAAq6oqPauqqj0AAAA+q6oqPlVVVT4AAIA+VVWVPquqqj4AAMA+VVXVPquq6j4AAAA/q6oKP1VVFT8AACA/q6oqP97dXT+IiGg/NDNzP97dfT9ERIQ/mpmJP+/ujj9ERJQ/6d/MvQ2coL5GsdC+QQtaP42ozb2SIJ++x1/SvmzmWT+sL829xTicvnBz1L7N7Vk/LXrLvdP0l74s4ta+kRxaPwKOyL32Y5K+lp/ZvhttWj+rQsS9s2OLvs+n3L4E31o/LNK+vUM4g77P3N++5mRbP9REuL184HO+Ri3jvsj3Wz9jo7C9djVfviSH5r6VkFw/WtCnvT1FSL5Z2em+gSxdPyD/nb1khS++SwztvrK/XT+EOZO9SxoVvvsN8L6XQ14/vImHvcBV8r0mzfK+BbJeP3q3db1IY7e94DL1vqUIXz9AuFq9h1N0vWw0977CPl8/Qi0+vScc7Lwkxfi+GVBfP3kvIL2iXTQ7WNr5viw5Xz/AqgC9kSMPPWtg+r5d+l4/JuC/vJYjij3ZW/q+0I5eP2p6eLwl78w90cn5vrX1XT+Tvtq7vcUHPimq+L4iL10/WNcFO+O7KD4E9fa+kz9cP9/UMjz9KEk+p7v0vrYlWz8fCqM8udxoPpQG8r5U5Fk/yD/tPKLUgz7G4O6++35YP+HYGz0GnpI+VFPrvnr+Vj8I7kA9FMagPoV1577NY1U/I6llPSw7rj4gWeO+grRTP+HohD2e7bo+fRHfvpr2UT81hZY91LDGPoq52r5ZNlA/SICcPUGMyj4ppNi+JMJPP4zpjj30aME+aWbavp6eUT8PwH49X0m2PptK3L4sw1M/ucVfPZguqj5Q3t2+hf5VP/WQQT0OXJ0+NRLfvvk8WD+3rCQ9/PSPPrvX376YdFo/mo4JPfwfgj4uJeC+HZxcP+v/4TxiDWg+munfvhiuXj+hzbU8/8FLPr0z376ynmA/+s6OPG+6Lz5YC96+M2hiPw87Wjx+VRQ+Jn3cvmAGZD9O/iI8sWL0PXSW2r5cdWU/PB/rO1MQwz2mdti+CLRmPylVojuhcJU9dTfWvt/CZz+0fFM79HhYPdj0076To2g/PYsCO+ZBEj0B2NG+3FRpP9i9kDpbFLA8rfnPvhndaT8tOQQ6eJ4sPFF2zr5zP2o/7WoVOTeXTjsSaM2+cH5qP4DARze/pIw5S/zMvl2Waj+wXY4yVMH1sTXyzL6SmGo/+VGOMmWq+LE18sy+kphqP/lRjjJlqvixNfLMvpKYaj/6UY4yZ6r4sTXyzL6SmGo/+lGOMmeq+LE18sy+kphqP/pRjjJnqvixNfLMvpKYaj/6UY4yZ6r4sTXyzL6SmGo/+lGOMmeq+LE18sy+kphqP/pRjjJnqvixNfLMvpKYaj/6UY4yZ6r4sTXyzL6SmGo/+lGOMmeq+LE18sy+kphqP/pRjjJnqvixNfLMvpKYaj/6UY4yZ6r4sTXyzL6SmGo/+lGOMmeq+LE18sy+kphqP/pRjjJnqvixNfLMvpKYaj/6UY4yZ6r4sTXyzL6SmGo/+lGOMmeq+LE18sy+kphqP8opWLt6mFG8W9bNvl5gaj/eCh28j3YWvbpBz77X4mk/VAyJvLw3gb34bNC+ADtpP2MAyLwLrrm91krRvhxlaD9sKgW9cXvzvcnU0b5PX2c/eXUnvZW/Fr6uCdK+7ipmP/9MSr1dKzO+LerRvjPPZD913my9lnVOvmSI0b5AU2M/Cj+HvXUaaL7P9dC+S8JhP4M8l73/m3++x0jQvv8pYD8PzKW9mwKKvn2kz75Tol4/mrCyvYufkr6GJM++sjZdPz2Hvb3ibZm+IujOvnD4Wz/16sW9iTeevjAOz75K+Fo/cuvKvVNeoL7OzM++bVRaP+nfzL0NnKC+RrHQvkELWj9Xeno9v61EvlEkmD6D7W4/uetuPZiaO76abpg+KmJvP5pXYz0hgzK+XbWYPk7Rbz9Bvlc9j2cpvp74mD7rOnA/8B9MPRNIIL5bOJk+/55wP+p8QD3oJBe+jHSZPoj9cD9z1TQ9Qf4NvjWtmT6EVnE/0ikpPVPUBL5U4pk+8alxP096HT2vTve96xOaPsz3cT8kxxE9AO/kvfFBmj4VQHI/oRAGPRCK0r1pbJo+yoJyPxKu9DxHIMC9VJOaPui/cj9CNd08EbKtvbG2mj5u93I/UbfFPNc/m7181po+WylzP9E0rjwJyoi9tPKaPq9Vcz9VrpY8LqJsvV0Lmz5nfHM/uUh+PNeqR71yIJs+g51zP/YuTzzrriK99DGbPgO5cz9eECA8al77vOQ/mz7lznM/NtzhOzhZsbxASps+Kt9zP4CSgzvsn068CFGbPtDpcz8oF5U6vyJquzxUmz7Y7nM/Rh/kuukfszvcU5s+Qe5zPx1Ul7uKpm086E+bPgzocz/jnPW7zdvAPF9Imz453HM/BPApvPNvBT1EPZs+x8pzP68NWbzwbio9lS6bPrezcz8uE4S8AGpPPVMcmz4Kl3M/dpybvEVgdD1+Bps+wXRzPyQis7xyqIw9Fu2aPtxMcz8m6b683ueVPQXfmj7ENnM/GZO2vC1cjz0T6Zo+jUZzP0OPrLwGf4c9i/SaPpNYcz+4iqK8nEJ/PWL/mj6VaXM/gIWYvB6Gbz2RCZs+k3lzP59/jrybyF89GBObPo2Icz8qeYS8KgpQPfwbmz6ClnM/SOR0vNhKQD04JJs+cqNzPz3VYLy9ijA90CubPl6vcz8/xUy848kgPcAymz5FunM/arQ4vF8IET0NOZs+J8RzP9GiJLxBRgE9sj6bPgXNcz+BkBC8LAfjPLJDmz7e1HM/Lvv4u+GAwzwKSJs+sttzP1DU0LvF+aM8vUubPoHhcz+YrKi7/nGEPMpOmz5L5nM/LISAu1XTSTwxUZs+EOpzP2m2MLvTwQo88VKbPtHscz9ux8C6a1+XOwxUmz6N7nM/isfAuYJflzp8VJs+Pe9zP/2rAK9ZE8ovhlSbPkjvcz8WpFwnVX+MJoNUmz5J73M/F6RcJ1V/jCaCVJs+Se9zPxekXCdVf4wmglSbPknvcz8YpFwnV3+MJoRUmz5I73M/F6RcJ1Z/jCaDVJs+SO9zPxmkXCdYf4wmg1SbPkjvcz8WpFwnVn+MJoRUmz5I73M/F6RcJ1d/jCaEVJs+SO9zPxekXCdXf4wmg1SbPkjvcz8XpFwnVX+MJoNUmz5I73M/F6RcJ1Z/jCaDVJs+SO9zPxekXCdVf4wmg1SbPkjvcz8XpFwnVX+MJoNUmz5I73M/GKRcJ1Z/jCaDVJs+SO9zPxikXCdXf4wmg1SbPkjvcz9M3LU6o8yOuxlUmz6h7nM//dyoO/+XhLzHTps+RuZzPxJdFTyKkOq8j0KbPhXTcz8aRVY8aD8ovY0vmz48tXM/6ZGLPDwvW73DFZs+u4xzPyz7qzy9Coe9MvWaPpZZcz/kXMw88HegvdrNmj7NG3M/rLXsPB7eub2/n5o+ZNNyPwuCBj0rPNO94GqaPl6Acj9moxY9BZHsvUIvmj6+InI/Kb4mPcLtAr7m7Jk+ibpxP6HRNj1IjQ++0KOZPsNHcT8e3UY9iiYcvgNUmT5xynA/6t9WPfm4KL6D/Zg+mEJwP07ZZj0ERDW+U6CYPj+wbz/pwHU9EvhAviFDmD7kHW8/V3p6Pb+tRL5RJJg+g+1uP3nDWrzjs8S7G2WhPmPrcj81Jlq8SevFuwAdoj7JzHI/92FavAwbxrv51qI+pq1yP09hWrwVl8a7LpOjPv6Ncj+Mblq8+/XGu55RpD7MbXI/YelZvKZIyLscO6U+H0ZyP0sLWbzV4cu7C0ipPuaScT9a5Fe8pxDQuwGPrT5b0HA/TXBXvEJO07svF7I+NPxvP5UCVrxZMti7wwe3PuQNbz9rAVW857Pcu3lvvD6GAG4/OBhVvAqI3LtpWrw+sARuP8IdVbz0stu7j+66Pl5Mbj+ecFW8gW7auyeOuT4vkW4/mQRWvNna2LuaN7g+gtNuP4QBVrwBKNi7rOu2PkQTbz+jVFa8hqjWu2ydtT7yUm8/9ZhWvHW71bvlaLQ+QY1vP88LV7xddNS77jSzPgLHbz/EHVe8pqbTu5QIsj7t/m8/dF5XvHSf0rtV4rA+TDVwPxWhV7y+ndG7tMKvPg5qcD9yn1e8T/XQu2mrrj7unHA/p5tYvPV/zbtdMKs+0DxxP9FiWbxC+8m7uUynPjLrcT95Llq8FcHGuzOloz72inI/djRbvOAkw7vtF6A+eSJzP45xW7xGQ8G7G9+dPmd/cz8o9Vq8V5jCu1C9nj5JW3M/vwdbvOkBw7v5iZ8+zzlzP1MtW7xFUsO7sVagPiIYcz/JzFq8smnEu5QloT7u9XI/To9avKVHxbur9qE+KtNyP/BdWrya+8W7dsqiPsCvcj928lm87BPHu56goz6/i3I/MgpavKOHx7s9eaQ+GGdyP1z5Wbx4H8i7pFSlPsRBcj+k/lm835XIu/sypj62G3I/Z3xZvBPMybsdFKc++fRxP++CWbwqcMq7j/mnPjzNcT8XDlm8Em3Lu6vbqD7dpXE/2e5YvAZHzLsHzak+kHtxPybkWLx+4My7FryqPmdRcT/ngFi8Ev7Nu3Wuqz5oJnE/11RYvN3lzruApKw+evpwP2QaWLzXws+7jJ+tPl7NcD+A6Ve8qbHQu1ierj5Kn3A/aKxXvN6h0bs3oa8+K3BwPxE2V7z/ztK7H6mwPtM/cD/eOle8ZXjTu/e9sT6/DHA//TVXvG9r07uLpbE+RRFwP8juVrzKkdO7Z02xPpIhcD+file8KIPSu3T2sD6VMXA/esJXvJsP0rugoLA+XkFwP6mGV7yBJtK7gUuwPgJRcD9Tl1e8ydjRu233rz5pYHA/IPxXvD8i0bvUo68+rm9wP368V7zsTdG7IlGvPsh+cD8BCFi8NajQu4X/rj6hjXA/xNdXvMqm0LtHrq4+Z5xwP+7uV7w+Y9C7F16uPvCqcD+U/le8VCDQu30Orj5YuXA/r2ZYvNV4z7u0v60+jsdwP/8YWLzHhs+7OHGtPrfVcD+UMli8wkfPu5YjrT6t43A/ykJYvI/+zruC1qw+hPFwP2xOWLwBtM67YoqsPij/cD8ZXVi8aG3Ou2c+rD6+DHE/XANZvB3Py7t9Uak+P5FxP0jsWbwiesi7vemlPkYocj/tZlq859vFu3uhoj6etnI/JAlbvJP+wrvVdp8+8jxzPw6qW7wqHcC7ZUacPkjBcz8o5Fu8HVC/u9ZUmz7d53M/GrVbvDX0v7skFJw+VMlzPySXW7x+kMC77L2cPheucz9Rd1u8SR3Bu8RlnT4Jk3M/D+xavGsUwrtbDZ4+63dzP5UsW7xbYsK7osWePutZcz8LE1u8+AzDuzF2nz4MPXM/6PFavFaow7s/KKA+zB9zP5wZW7zl08O7ltygPgMCcz95w1q847PEuxtloT5j63I/A9gbMzuHMTL8eYw+Ci12P0nVGzOjay8yIAOLPjdidj+WVBwzZbMuMnmHiT51l3Y/wfobM4RlLDKXBog+zsx2P8eGHDM4cSoysYCGPjUCdz8DPhwzSE4oMu2thD5JQXc/g9AcM6yaHjIxs3o+kzV4P66zHTP+ehQy7hNrPrQpeT+aPR4zp8YJMshWWj7tHHo/3+keM8Tw/DEw50c+FRN7P9+hHzOxZeMxB3kzPpIJfD9t3x8zL8vkMbkgND4YAnw/mKAfM+Kd6zEW7zk+l757P1LpHjPHb/Ix94s/Pjl7ez+9Qx8zyB/6Mab9RD7mN3s/9dYeM0IPADKVQ0o+0vR6P/WJHjNjSAMyBH5PPn6wej/AuR4zpH0GMv5qVD50bno/mEYeMwZ5CTL5R1k+qit6P2MeHjO+VwwyzQRePhPpeT9xwR0z0HkPMmimYj6Gpnk/Kc8dM0BKEjKcK2c+LGR5P+3IHTPzIxUyio1rPoYieT+vTx0z3kodMuZ/eD74WHg/VLUcM+o8JjLzX4M+2m13P133GzMBUy4yGgyKPu2Edj9OlhszJzI2Mit2kD5DmXU/t9MaM8SqOzIYZZQ+AAN1P5I0GzPHEToyOr2SPspCdT/+txszseI3Mu8ykT5tfXU/RJQbM9DuNTJ8pY8+27d1PztFGzNAHjMyIxOOPk/ydT8dlRszVsAxMhB8jD6+LHY/o78bM2fuLzLE3oo+V2d2P1lsHDNVAi4yVDyJPuyhdj/UPxwzkX0rMm6Uhz6C3HY/TVkcM8lrKTJW5oU+Kxd3P7nAHDMBGCgy+TGEPuJRdz/skxwzpdEkMg53gj6njHc/PbUcM+ipIjIttIA+ocd3P7DEHDPK1iAyqOJ9PsABeD99DR0zcEgeMqY0ej6OPXg/aSIdM2PnGzKjg3Y+nnh4P84cHTPB1BkyTMNyPrCzeD9yYx0zsRMXMuTybj7D7ng/PNcdM0cRFTKiDms+BCp5Pw8fHjO68hEyJxlnPj1leT9+ax4zgukPMuUQYz55oHk/Y+kdMxDYDDKQ814+ytt5P21mHjN6Fgoy4p5aPv0Yej+8Wx4z7gMLMjM5Wz6LEHo/AgAeM4x6CzJb3Fw+ffl5P/xkHjMHEg0ygHpePojieT87Nx4zOikOMokSYD6+y3k/8NUdM/esDjJopmE+BLV5P64KHjP3hg8yiTVjPmSeeT9ZFx4zlCkRMsDAZD7Uh3k/F/0dM/HCETJlR2Y+XnF5P9/dHTMhtxIyjchnPhFbeT9qmB0zDbQTMrRGaT7KRHk/oEwdM0qhFDJKwGo+oS55P9+GHTNfkBUyUjVsPpgYeT/g4h0zy/wVMvKmbT6eAnk/7pgdM3RrFzKtFG8+u+x4P6dbHTPvxhcyq35wPu/WeD/nUx0zESAZMurkcT47wXg/ujodM+jvGTLaRnM+p6t4PzwWHTNDrxoyZaZ0PhiWeD+zSR0zFIchMs1lfz7m6Hc/H3QcM8J2KTIu5YU+Uxd3P1JAHDNtQjEyG9CLPjZFdj/BZhszH9Q4MsN5kT7xcnU/26QaM+J5PzJTIpc+wJd0PzqpGjMwU0Eyd7aYPvZYdD/+5hozBxw/Mhk7lz7sk3Q/F80aM7RoPTKp5ZU+csh0P/ViGzP1XTwy6o+UPoP8dD/1SRszP6s6Muk3kz5oMHU/hHYbM33JODJfzZE+imZ1P8Z4GzNQGzcy02eQPl+bdT8JkBszbSU1Mnf+jj400HU/SbobM0djMzLHj40+PgV2PwPYGzM7hzEy/HmMPgotdj9BsQQ6bfbCuZvORb+mgSI/TMT7ObwNublAUEW/+xojP8SNAzqgJ8G5rNBEv9W0Iz8ovwU6jhHEucpPRL9NTyQ/6BUJOjT+yLmkzUO/T+okP9+sAzq91MC5G0dDv4eJJT8z1gI6aXLDuUWAQr/7ciY/XU78OTgOwLkopkG/inAnP0XyBTqhwc+5nbVAvyuFKD+9Zv859H7Kuc2iP79rvSk/pyUCOplO07mGZz6/yR4rPwsaAzqyX9W5XMg+v8yyKj9YkPw5i2vNuSWNP7/b1Sk/yCf9OX+EzbkmTUC/VvwoP9TcAjpmHNS54ghBv8IlKD+S5vs5VRnMuWHAQb8yUic/9jEAOhd0z7kXdkK/334mPzOG/jlK2M25BiVDv7SxJT/IxwE6/rLRue7RQ7845SQ/6vP9OfoVzbmMe0S/9xokPzwE/jnnCc25UCJFv31SIz/DIP45MwvNuSfGRb/wiyI/OuP2OTQax7kcZ0a/U8chP46A/zlqd8u5Vj9Hv7m8ID/BgAA6ZULJueEVSL9ZsR8/vBkBOt0ex7nQ2ki/YbkePwSKBjp/T8y5lpVJv+fLHT+r1gQ6+ubHuej0Sb/WUR0/aH3+Oa+pv7knh0m/Vt4dP0u0AjqN/cS5Sh1Jvx1lHj8uWQc6YPXLuZiySL837B4/KJ8DOkyIxrnWRki/73MfPyRLAjransS5C9pHvzX8Hz87TgI6Y7vEufNrR79bhSA/SyD9OX4hv7nC/Ea/Hg8hP6dFAjof1sS5X4xGv5WZIT+e/QM6esjHubQaRr/aJCI/sFwHOgPizLm9p0W/6rAiP1+CAjojhMW5ZDNFv949Iz9UBQU6i6zJuXq9RL/myyM/YugBOksWxbkyR0S/kVkkP+RTAjobAsa5c81Dv4rqJD8fzgQ6igXKuRtTQ79eeyU/6OABOhypxbkt10K/Nw0mPwHWATqA28W5nFlCvx2gJj9oxQE6yv/FuSbaQb9WNCc/VrYBOrwcxrnvWEG/sMknP4pQATq6xMW509VAv05gKD9MDPw56CXBua9QQL9Q+Cg/9rABOjnoxrnqwz+/AZgpP+wRATpqY8a5MwhAv6tKKT9cXPc5u4e+uR94QL9iyyg/eNgDOt6uy7lE50C/UUwoP3CnBTqiq865h1VBv5zNJz/JAQE63O7HuQ3DQb8ZTyc/seEAOhNCyLnQL0K/0dAmP/KVBTouFtC51JtCv8FSJj9MbwA616nIuR8HQ7/l1CU/rAQEOlOzzrmTcUO/YVclP55bADrGVMm5ZttDv/jZJD+nRQA6dd7JuX5ERL/MXCQ/SBYAOpfFybnQrES/6d8jPz2OBDodmtG5gBRFvyhjIz/YjP85U7TKuXh7Rb+k5iI/N7H/Oej5yrnJ4UW/S2oiPxpU/zl5X8u5aEdGvyzuIT/xKf85C6DLuVasRr9IciE/7PT+OY/ey7mtEEe/fvYgP3hPADpFmMq5D7BHv5owID/PBQQ6lI7NudBQSL9mZx8/AGUBOrSMxrnZ5ki/JKoeP7M9AjqQusS5JnNJv9z3HT/A8QI6jt3CufX+Sb/uRB0/9TkDOpwgwrkD9Um/tFEdP5RLAzoy5sG5fHpJv4DuHT9NPwM6VxfCud4ESb8bhB4/dqwDOk94wrnCjki/bxkfPyUn/Tn6nrq51BdIv+iuHz9jYQM6BLbBuaudR7+ERyA/rHwDOulfwbnFI0e/3t4gP4K0Azr0nsG5zahGv6F2IT/8pgg6syXJuYYsRr8QDyI/QbEEOm32wrmbzkW/poEiPzZVcjz6t/I7ex2hPjn1cj+rHHI82F3zO5nVoT6h1nI/V+9xPF4V9Du2j6I+i7dyP+DBcTxW0vQ7+0ujPvCXcj8UaXE87Mn1O1IKpD7Vd3I/5HZzPAhh8zuB9KQ+A1ByP0dKcDzJffo7qgGpPiidcT98Km88O7z+OzxJrT7X2nA/hO5tPJCaATy40bE+BQdwP36VbDzdDQQ8UsO2PuYYbz8cEGs8PbkGPCYsvD7BC24/9xZrPL+xBjy4Frw+/Q9uP1yEazzHBAY8tKq6PpNXbj+i3Ws861AFPM5JuT5hnG4/OmhsPPCFBDxP87c+lt5uPwkIbjz4GQM8+aa2PkIebz92y2w8YF0DPABYtT4IXm8/vjxtPPfBAjx4I7Q+PZhvP3mPbTyLNgI8KO+yPvjRbz9+m288j3AAPOrCsT6yCXA/7TxuPPYDATxTnLA+GkBwP0UNcDy/1/47pnyvPrh0cD+mxm480wIAPMZkrj6pp3A/Br5vPIh+/DsT6qo+NUdxP6q4cDyVnPg7VQunPm/0cT8SsHE8svz0OwZdoz4SlXI/C7tyPJUm8Tuuz58+UCxzP4x1dDy0Lu07o5adPgqJcz+v0nI8oiLwOxB1nj4BZXM/lutyPP2r8DvEQZ8+lUNzP9jVczxIu+87qw6gPukhcz+ACHQ8xRDwO+LdoD6x/3I/8hpyPBNw8zvyrqE+EN1yP7npcTwxFfQ7yoKiPrW5cj9nsnE8bfD0Ox1Zoz67lXI/m7RzPEif8jvxMaQ+CXFyPycpcTw86fY7WQ2lPt5Lcj+cBXE8p5j3O8HrpT7hJXI/8P5yPP5H9TtZzaY+Cf9xPxd7cDwoefk7trKnPnvXcT+HRXI8kDz3O9KUqD4YsHE/iSBwPKgB+ztjhqk+6YVxP67obzxYCfw7s3WqPshbcT8PZnE8kpL6O25oqz65MHE/fXFvPP/O/TucXqw+6gRxP+avcDySqvw7r1mtPtLXcD+q0G48StH/O2hYrj7nqXA/4Y5uPP5eADyHW68+0npwPwJdbzzIPgA82GOwPm5KcD+6wG48yPEAPOl4sT5rF3A/kBhuPEVnATwgYLE+BhxwP7ItbjyOOgE8OQixPj0scD8QFG48AikBPDuxsD5DPHA/9YZwPObW/js8W7A+90twPwJjbjzrswA8BgawPqxbcD9jfG48CI0APJOxrz4da3A/jpJuPMFkADwQXq8+W3pwPxi4bjycSAA8MAuvPnKJcD+BxW48UCEAPG25rj5OmHA/DAxxPBLZ/DuDaK4+5aZwP2SibzzToP474xeuPoy1cD+iYXE8eO/7O1rIrT7Zw3A/qDdxPD3z+ztlea0+GNJwPzQabzzMwf47yCqtPlLgcD8NQW88qWz+OxLdrD5F7nA/6oBvPC7v/TsfkKw+DfxwPwK1cTwLlvo720OsPpwJcT+pxXE8iEn6O873qz4vF3E/4BhwPDul+jtHCqk+qZtxPwgZcTzWOfc7IaKlPnsycj9Q9XE8KQT0O4hZoj6bwHI/Guh0PP2Y7TvDLp8+nUZzP+Nbczy+4O07uP2bPuHKcz/TvHM8LqfsOzwMmz5g8XM/4ZBzPMFo7Tt6y5s+6NJzP7hSczzuOu47m3WcPqu3cz+HKnU8ytXrO5EdnT6SnHM/Wf1yPPE/7zsfxZ0+k4FzP2v2cjwgHfA7jn2ePp1jcz+TxXI83cLwOycunz7MRnM/DZ1yPNN38TtW4J8+lClzPxBycjyrKfI74pSgPtQLcz82VXI8+rfyO3sdoT459XI/1dUbM8riMTKHcYw+Pi52P2X2GzPm8i8ykfqKPmxjdj9XGBwzBdMtMrx+iT6tmHY/pjQcMx01LDLP/Yc+BM52P/NcHDMLSCoyvneGPmwDdz/HjBwzudcnMqCkhD6IQnc/giEdM/unHjK1n3o+zjZ4P6DAHTPuxxQyU/9qPusqeT9QVB4zUQgKMiBBWj4bHno/APAeM8sR/TFQz0c+RRR7P4+MHzP5WeMxk14zPsAKfD8Rih8zN+rjMdIGND5AA3w/oGAfMwAf6zHz1Tk+wL97P8AzHzPQZfIx2nM/Pl98ez/BCR8zXYj5MSfmRD4NOXs/N+geM1UUADI1LUo+8/V6PxS0HjOUOQMyymhPPpexej8iih4zFG4GMhVWVD6Qb3o/SV0eM8OQCTKUM1k+xSx6P1g2HjP1mAwyD/FdPivqeT+7Cx4zHSwPMk6TYj6bp3k/8ecdM29KEjKaGGc+RmV5P2O1HTOMMhUyaHtrPpgjeT/BNB0zol0dMixteD4kWng/Z6McMygmJjKHUYM+xG93PyMNHDMz7i4ynQSKPvqFdj8ddxszofg2MqBukD5fmnU/+CobM6PcOzLKXZQ+GwR1P85CGzMnnDkypLWSPuxDdT8iaxsz+7E3MjArkT6SfnU/l4cbM439NTK9nY8+/bh1P06gGzOs0zMyOQuOPnTzdT/21hszwfAxMvFzjD7mLXY/ffwbM2SaLzKo1oo+e2h2P9sfHDPPzS0yGzSJPhGjdj8ITBwzEF8rMjOMhz6j3XY/h3AcM+BJKTKy3YU+Vhh3Pz2PHDPqSScyRSmEPgtTdz9pwhwz0yolMkdugj7PjXc/xN0cM0mxIjIUq4A+0Mh3P2ECHTOUxCAyldB9PugCeD/KJh0zMVseMuQhej69Png/TkgdM6EDHDJIcHY+0nl4P1Z0HTPBmxkymK9yPuS0eD+fkx0zWBIXMsvebj7373g/Zr8dM7WuFDI/+mo+Nyt5Px7hHTPXPhIyUgRnPnJmeT+4BR4zcpQPMqT7Yj6voXk/PSceM1g9DTJx3V4+Bd15P81OHjOXhQoya4haPjcaej8ZTh4zfl8KMi8jWz7AEXo/lT0eM8/TCzJAxlw+tfp5P1QtHjNOAQ0yrWRePr/jeT8HKh4zDZMNMkP9Xz7vzHk/UBQeM92cDjJdkWE+NLZ5P90GHjPQnw8yDiFjPo6feT/b8R0zT30QMlSsZD7/iHk/N+UdM1/RETJSM2Y+hnJ5P8zaHTPbwRIy4bRnPjVceT/0yR0zk50TMiwzaT7uRXk/LrkdM+N4FDIcrWo+wy95P6OvHTNloRUycyJsPrYZeT+fkx0zzHcWMjGUbT68A3k/t5YdMz9uFzL6AW8+2+14P1uFHTO6bRgyYWxwPgrYeD+kdB0zTS8ZMqrScT5Wwng/rl0dMy3nGTIjNXM+vKx4P9tpHTNGEBsyz5R0Pi2XeD8c7RwzbeEhMg9Vfz766Xc/TmocM4OjKTL+3IU+bxh3P73mGzNd4DAyTMiLPlJGdj/IaxszzRE4MkFykT4OdHU/ftIaM3lcPzIHG5c+4Jh0P9uyGjO6Q0EyH6+YPhxadD+e0xozCIs/Mq0zlz4RlXQ/z/YaM9GZPTIX3pU+m8l0PxYEGzPECTwySoiUPqv9dD8XOhszLHw6Mk4wkz6MMXU/NV0bM/GgODJ+xZE+tmd1P6qAGzNY2TYy6l+QPomcdT8FohszXsQ0MkT2jj5m0XU/8rsbM8A7MzJVh40+dQZ2P9XVGzPK4jEyh3GMPj4udj860l+4Oj2ouBnFRb89jSI/JeJguAr8p7i0RkW/iyYjP1qWYbg2X6e4E8dEv2TAIz+/3GG4m36muClGRL/SWiQ/mi45uPDStbjvw0O/2vUkPxGtQLnDsIc3Vz1DvxCVJT+zeWS4SNWkuGt2Qr+CfiY/pRtmuOl9o7gynEG/E3wnP9EEZrj8XaG4hatAv7mQKD9jnme4N1yguIaYP78KySk/lNdpuI4nn7gEXT6/fyorP5/KaLj6Ip+45r0+v4G+Kj8mYGi4wH+guMuCP7+M4Sk/JnVmuOyroLjmQkC/BAgpPxAeiLizUI+4wf5Av2cxKD/LjA25MRRMt1y2Qb/PXSc/DjFUuFyjqLgsbEK/eIomP8XUYbgbZaO4MBtDv069JT8Q/lm4swanuCjIQ7/Y8CQ/6UgfudqGYDXgcUS/jyYkP6YxZrj1faK4uxhFvxJeIz+5+xS53Lzvtpq8Rb+TlyI/xvxQuOaRq7ilXUa/8tIhP508XLgBL6i44TVHv3bIID+JYVq4pwqpuLULSL8cvh8/OaRZuIUYqrit0Ui/9MQePzxhgrgkGZq4doxJv5TXHT8j8wy5v+6mt9DrSb+HXR0/F8BJuNVssbgCfkm/B+odPwd8grhmSJu4FxRJv89wHj9H8Qm55fqzt2GpSL/f9x4/n+QguR61qraVPUi/k38fP5OqS7hvU7C4u9BHv9sHID9SJ1y41CWpuJ9iR7/2kCA/2KZZuNi4qbhk80a/tRohP22GQbmZE6I3+oJGvyOlIT+udTW4Iee3uDkRRr9zMCI/TZdOuOiWrbg5nkW/frwiP/fYPrnrApk33ClFv2VJIz/9jDq42+e0uN6zRL921yM/iNAyuRMTJTeKPUS/HWUkP0ekYbj5W6W4vMNDvxb2JD9uAly4qsGnuFFJQ7/whiU/vIciucIL3bVYzUK/xRgmP9afa7hEBKG4vU9Cv6WrJj+a3xi56R8NtzTQQb/hPyc/z1lZuMtPp7jrTkG/PtUnP2InYrgBvqO4w8tAv9lrKD+b1u24+SMJuIZGQL/lAyk/KKbLuMu7PLi4uT+/jaMpPzgXaLisi6G4Cf4/vzhWKT8gcWe4WsShuP9tQL/y1ig/8649uEYXsrgz3UC/4FcoP9WWPrnqfbA3gUtBvyzZJz9CY2O4kGSiuBe5Qb+mWic/bMtjuE/GorjnJUK/XtwmP9LlYri9UKO495FCv1BeJj/mXGO4p02kuEv9Qr944CU/XD1fuECwpbjQZ0O/72IlP7xbP7mxgb43r9FDv4jlJD9zD8e4/hBDuM46RL9haCQ/77lKuZ9MBTgvo0S/e+sjP4EgPLnK16s35QpFv8JuIz/XjFK4pLWruORxRb9F8iI/0gJeuJtsprhF2EW/53UiP9vEgrgynZe48D1Gv8j5IT9Wz0S5ETDqN+yiRr/hfSE/p3BEuYZ/6jdLB0e/HQIhPyIOSrjPpK64w6ZHvzQ8ID+slVq406ypuI1HSL8Pcx8/XzpXuN76q7ip3Ui/y7UeP94sQLlhKJY3BGpJv4UDHj/wXi64zcC7uN31Sb+hUB0/fmJYuChArLjl60m/bF0dP9BvWLisW6u4VHFJvzT6HT/Pt0C464y1uK37SL/Hjx4/iM0yuaV1uTaFhUi/GCUfPzoZW7i5WKq4mA5Iv3+6Hz/W+1y4PDGquFmUR78kUyA/yqRcuKOyqLhsGke/deogPxrZXbi/k6i4X59Gvz+CIT++tF+49TGpuAgjRr+wGiI/OtJfuDo9qLgZxUW/PY0iP4B8STOGY6EwPP/MPHrrfz9ffkkzgneXMHRmwDzs7X8/QYBJMxGNjTCOzbM8NvB/P+SBSTPKooMwjjSnPFnyfz92g0kzAHNzMHObmjxU9H8/vIRJMxe0YTDCVo88+PV/PyKDSTN+J3gwrZedPN/zfz9QgUkzQ0iHMGrVqzyV8X8/VX9JM5qAkjAEE7o8F+9/PzZ9STNgtJ0wfFDIPGjsfz/uekkzEOqoMMuN1jyF6X8/hnhJM1YftDDuyuQ8b+Z/P+l1STNkV78w5QfzPCfjfz8zc0kz5ovKMFaiAD2t338/T3BJM0nD1TChwAc9/9t/Pz1tSTPN9eAwz94OPR/Yfz8KakkzCyvsMOT8FT0M1H8/q2ZJMzRf9zDYGh09xs9/Py1jSTMKSwExrTgkPU7Lfz95X0kzeeQGMWNWKz2jxn8/sFtJMzF9DDH2czI9xsF/P6VXSTNhGBIxZpE5PbW8fz98U0kzz7wXMaG6QD1pt38/11RJM7rzFTETeD49G7l/P3hXSTMRYBIxdOw5PXO8fz8LWkkz8MsOMclgNT23v38/h1xJMwc4CzEN1TA95sJ/P/peSTOcowcxQ0ksPQDGfz9gYUkz9w8EMWy9Jz0GyX8/qWNJMzZ7ADGIMSM998t/P+hlSTPXzvkwk6UePdPOfz8daEkzlqXyMJUZGj2a0X8/QGpJM6V96zCJjRU9TdR/P05sSTNnVOQwcgERPevWfz9QbkkzlCvdME51DD112X8/OnBJM8kB1jAd6Qc96tt/PxhySTN+2M4w5FwDPUrefz/rc0kzgazHMD6h/TyV4H8/p3VJM5CFwDChiPQ8zOJ/P1Z3STNNWrkw7m/rPO7kfz/yeEkz9DGyMCpX4jz75n8/fnpJMywJqzBUPtk89Oh/P/p7STM73qMwbCXQPNjqfz9pfUkzorWcMHEMxzyn7H8/x35JMwyMlTBo8708Ye5/PxCASTP0YY4wUNq0PAfwfz9PgUkzkTmHMCjBqzyY8X8/eYJJM28OgDDxp6I8FfN/P5iDSTOtxnEwsI6ZPHz0fz+rhEkz261iMJD2jzzh9X8/lYNJM7nMcTCyjpk8fPR/P+2BSTN3pIMwkDSnPFnyfz8OgEkzSmOOMFDatDwH8H8/GX5JM4QgmTDwf8I8h+1/P/x7STNb36MwbSXQPNjqfz+5eUkzbpyuMMPK3Tz6538/VXdJM35duTDwb+s87uR/P8d0STP3GcQw9RT5PLPhfz8TckkzBdnOMOZcAz1K3n8/RW9JM3CT2TA4Lwo9stp/P0JsSTOjU+QwcgERPevWfz8waUkzXhDvMJLTFz320n8/8WVJM37M+TCVpR49085/P39iSTPhRQIxenclPYHKfz/9XkkzwqMHMURJLD0Axn8/R1tJM78CDTHvGjM9UcF/P3xXSTOUYRIxd+w5PXO8fz9/U0kzOb8XMd+9QD1nt38/rFVJM8zaFDEKEj09Jbp/P0JZSTNo5Q8x2MY2Pbi+fz+3XEkzf/EKMYh7MD0kw38/FmBJM278BTEcMCo9aMd/P1hjSTNmCAExmeQjPYTLfz90Zkkz7yf4MPmYHT15z38/b2lJM5897jBCTRc9RtN/P0JsSTMoVeQwcAERPevWfz8Ob0kzU2naMIu1Cj1p2n8/rnFJMwB/0DCQaQQ9v91/PzV0STPGlcYwATv8PO7gfz+Rdkkz36q8MLii7zz0438/0XhJM4PAsjBOCuM80+Z/P/R6STPQ0qgwv3HWPIvpfz+AfEkzhmOhMDz/zDx6638/OCLZs3bGJ7R9JRe/Dp5OPw1agDNDDBS0fSUXvw6eTj+e9xcymEKzs3wlF78Pnk4/d1kstOfE9LN7JRe/EJ5OP8PvcrL9QICyfSUXvw6eTj9tXZm0rV0YtHwlF78Pnk4/43e+sZtxcLR9JRe/D55OP/PoJ7Lo5kmzfSUXvw+eTj8aU6K0vcIMtHslF78Qnk4/xPZLtCaNe7N9JRe/Dp5OP5aXp7MuWCOzfCUXvw+eTj884Wq0+Bc9s30lF78Onk4/mUxmsmiaRrR8JRe/D55OP49LJbSAeFO0fSUXvw6eTj/HNpa0L00PtH0lF78Onk4/Mq5msysLdbR8JRe/D55OP+niYLQ82bazeyUXvxCeTj8HrhK0hkrys30lF78Onk4/+LM5tKFcLrR9JRe/Dp5OP1EqDbQc9eKzfSUXvw6eTj9ioxG0MRLds30lF78Onk4/bWQ0tOdywrJ9JRe/Dp5OP3vPdbTRps6zeyUXvxCeTj+VIRyziNc5tH0lF78Onk4/oXI7tGA+n7N9JRe/Dp5OPza1dbRplwGzfCUXvw+eTj8TBpq0mdcLtHslF78Qnk4/FsgNtNEB27N8JRe/D55OPyLEcrPzWCy0fSUXvw6eTj8VZ1Szg+YxtH0lF78Onk4/cZ8ftAT0x7N8JRe/D55OPyNtF7NPDT20fCUXvw+eTj+C1SezHw06tH0lF78Onk4/FDIQtB+G3rN8JRe/D55OP7BFV7TYEW2zfCUXvw+eTj/MOmi0VHM7s3wlF78Pnk4/wv9QsoQwT7R9JRe/Dp5OP2EhOLRErZGzeyUXvxCeTj9VZL2094lstHwlF78Pnk4/R+sCtNHZ47N8JRe/D55OP+ULZbS6w0SzfSUXvw6eTj8/hwe0lM3Ts3wlF78Pnk4/Ea++s/UkVrN9JRe/Dp5OP9bsWLSpO2izfCUXvw+eTj9jKgq0nVjns30lF78Onk4/TioNtB714rN8JRe/D55OP04qDbQe9eKzfCUXvw+eTj9QPQG0aELfs3wlF78Pnk4/iU+FsohZvLN9JRe/Dp5OP/oZE7RjzOSzfCUXvw+eTj//zPuzTjnes3wlF78Pnk4/xof6s90G3rN9JRe/D55OP+dNyLJS8r6zfiUXvw6eTj+yEqe0dmYPtH0lF78Onk4/ls+utLzMEbR7JRe/EJ5OPzwsiLRw0QW0eyUXvxCeTj90jG60DtsXs30lF78Onk4/iteLs/E80rN9JRe/Dp5OPydyDLSnjjO0fCUXvw+eTj/63JS0e2UItH4lF78Onk4/EsCQs24KvLN8JRe/D55OP5ojn7T/Po20eyUXvxCeTj84MkqzM+nLsX0lF78Onk4/LdFBM6N3ejJ9JRe/Dp5OP/zRSLRg1C20fSUXvw6eTj/AX/ayJDM1tHwlF78Pnk4/GxIQtClnFrR8JRe/D55OPyGuPLRQzYu0fSUXvw6eTj9y1I20nb2btHslF78Qnk4/5Iers/oNxrN8JRe/D55OP57GbrLroOGyfCUXvw+eTj/3m3y058xds3slF78Qnk4/YIGXtF8qr7R7JRe/EJ5OP6G1LrTtoCW0fSUXvw6eTj/HsLq0XQdztHslF78Qnk4/3IMiM4LLtrN+JRe/Dp5OP0EcRTKcAQi0fiUXvw6eTj/lGEC0+81HtHslF78Qnk4/20Z/s1wmObN9JRe/Dp5OP9u7u7Rg+Vi0eyUXvxCeTj8yApS0iqMGtH0lF78Onk4/N28NNF4z0LN+JRe/Dp5OPzgi2bN2xie0fSUXvw6eTj/PcSi720FnvTePRr0TSn8/y/IYu0X8Ub1Rn0a9clx/P82xCLs0rDu9iq5Gvc5tfz+hiO+6Jm8kvZW8Rr3PfX8/rX/Mup5iDL0ryUa9JYx/PzJQqLpxF+e8D9RGvZSYfz9OVYO6GFK0vALdRr3Jon8/hnQ7uqKwgLza40a9lap/P5mp3rk43Ri8duhGvdGvfz9iYAq5kgU+u7XqRr1msn8/ACEpObItaDuU6ka9Q7J/P/vq7Tn/USM8F+hGvWqvfz/tGEM6k+2FPEfjRr3pqX8/OBSHOoV0uTw13Ea93qF/Px30qzrEFOw8D9NGvXCXfz/kANA6cMkOPf7HRr3Rin8/ZQ/zOsfZJj05u0a9P3x/Pw5eCjsP9z09EK1GvRxsfz8ahBo7GiJUPcGdRr2sWn8/VuQpO2g9aT2gjUa9Rkh/P1hpODuXK309/XxGvUs1fz9D0kU7zcmHPWVsRr1hIn8/GC9SO75FkD0QXEa9ww9/P4lqXTsC+5c9XUxGvd39fj9Wb2c7CduePa09Rr0c7X4/bO1vO+SupD20MEa9U95+PzMEdzsnjKk9hiVGvZLRfj9innw7PWStPXMcRr07x34/WVOAO5AosD3MFUa9pL9+P+BegTuvl7E9TxJGvam7fj9Kg4E7sr+xPU8cRr0yu34/vaOAO+JPsD0mYEa9/b5+P298fTutNq09lvBGvRHHfj85dnc761qoPWjPR71v034/0KVvO4Ekoj2t50i9t+J+P4MlZjv8tZo90zBKvTX0fj/rD1s79TGSPUKiS70yB38/YEdOO3qYiD12N029QRt/PzUtQDtocXw9aeFOvVMvfz/t4zA7uWpmPYuXUL3QQn8/z5EgO3ViTz1eUVK9MFV/P1FEDzvnijc9igRUvRJmfz8CrPo6HFEfPTeoVb0AdX8/9PfVOvf6Bj0aNFe9wIF/P3nfsDrRnN08AKBYvTSMfz+f94s6f1+uPBncWb1UlH8/+KBPOgS1gDzP5Vq9Opp/P1nqCTqDUio8PrVbvRmefz+g1I85HiCxO5lCXL03oH8/er04OI9HYzoheVy9+KB/P9E9OrkzQmW7PmRcvamgfz9AD9e595AEvNUOXL0yn38/m0Erun6pU7xjf1u9V5x/P+0wbbq+JpO8+bNaveaXfz8EF5i6XJa9vHe7Wb24kX8/XsK5uiLJ6Lyim1i9u4l/P7BE27pPMgq9QlpXved/fz9PLPy6EAEgvdj5Vb1NdH8/CB0Ou/OcNb1fhVS9CWd/P9qUHbvP2Eq9zwJTvURYfz9WXiy7kIdfvTB4Ub07SH8/EDc6u+NVc7107E+9Vzd/P4QkR7sgGIO9imZOvd4lfz9WEFO75fSLvZDsTL0wFH8/U+Zdu9MqlL2shEu9ugJ/PxVgZ7tZgJu9MTpKvUDyfj9DnG+74vuhvdQPSb3/4n4/MYt2uxaHp725C0i9b9V+P2wdfLudC6y9BzRHvQjKfj/GAYC77z+vvUuYRr3BwX4/aDOBu346sb3hNka9kbx+P1aZgbvw5bG9JhRGvc26fj8XJIG7iUexvRETRr2JvH4/0Vx/u71Gr73uF0a9E8J+P7/QersBKKy9Yh9GvZTKfj9BuXS77/mnvSspRr271X4/pCttux3Lor32NEa9LeN+PwAGZLtDhJy9vUJGveTyfj/jmlm7Al6VvcZRRr0JBH8/kf9Nu+pmjb2yYUa9MBZ/P1RJQbuZrYS9InJGvesofz+hZTO7jUp2veGCRr0FPH8/z3Eou9tBZ703j0a9E0p/P3qEertkU2e99gqKvaQBfz9QeWO7MwxSvewUir0NFH8/dk1Lu3K6O71XHoq9dCV/P+AgMrufeyS9BCeKvX41fz+GExi7QW0Mvcouir3dQ38/5lX6uu4o57yINYq9UlB/P+ZVw7qzX7S8ETuKvY5afz9zZ4u6S7qAvEs/ir1eYn8/G5YluoboGLwiQoq9nmd/PzXOTbl7Ej67h0OKvTRqfz9MkHs5KkFoO3ZDir0Ran8/m+8wOu9eIzzqQYq9Nmd/P/YWkToM+IU87j6KvbJhfz+w6Mg67oK5PJE6ir2iWX8/fsD/Ogwn7DzqNIq9Lk9/P/6uGjt31A49Ei6KvYhCfz94wDQ7pOYmPSsmir3tM38/ocpNO60FPj1sHYq9wSN/P2HOZTtnMlQ99hOKvUYSfz/Aq3w7UE9pPfwJir3V/34/ciGJO/w+fT2x/4m9z+x+P7EZkzsy1Ic9b/WJvdrZfj+ISpw7xVCQPVjrib0xx34/JqSkO5sGmD2j4Ym9QLV+P8QWrDsm5549jdiJvXWkfj/hZrI7cbukPYnQib2klX4/2qu3OxCZqT2eyYm93Ih+P+XVuztuca09A8SJvX5+fj831b479jWwPea/ib3jdn4/6mLAOzGlsT29vYm95nJ+PyyRwDs4zbE9lL+JvXJyfj+gFL87Wl2wPZnOib1Wdn4/j967OwVErT2R7om9nn5+P5zRtjsRaKg93B+KvU2Lfj+RVrA7XTGiPcJdir39mn4/Bo6oO3/Cmj1Jpoq99ax+P6qYnzsLPpI9d/eKvX3Afj+HcJU7B6SIPTpQi70l1X4/wmeKO0SHfD0prYu92+l+P3RBfTssf2Y9VgyMvQH+fj86fWQ7VHVPPdhrjL0PEX8/+K9KOwGcNz19yYy9niJ/P0pUMDtLYB89TCONvTQyfz/NthU7HAgHPYl3jb2VP38/0Uv2OtSy3TyAxI29nkp/P70dwjoaca48BAeOvUBTfz93e486MMKAPJc+jr2VWX8/Dxc+OiRkKjy1aY69yl1/P67YxTmYMrE75IaOvSRgfz8A8X04U19jOiGSjr37YH8/9g2AuR1aZbvSjY69pGB/P9wGFLq8ngS8HXyOvQlffz9XLGy6T79TvDtejr3yW38/JgGkur01k7y3M469LFd/PwYE07pqqb28gP+NvZdQfz+HWQG7KuDovLjCjb0iSH8/H1IZu8A/Cr2Gfo29yz1/P1IsMbtUECC9czONvaIxfz9tski76a01vbvjjL3HI38/CbNfu1vrSr2jkIy9aRR/P+39dbuMm1+9dTuMvcMDfz9Gm4W7KmtzvcHli71G8n4/1aePu1Ujg70CkYu9NeB+P24OmbubAIy9lj6LvffNfj9HuaG79zaUveLvir34u34/vWypu9iMm710p4q9A6t+Pw40sLusCKK97GWKvVObfj9v+rW7G5SnvbQsir1jjX4/IKu6u9MYrL0z/Ym9roF+Pwz8vbtFTa+949qJvS55fj87B8C75UexvWrFib3bc34/srfAu17zsb3LvYm9CnJ+P2ALwLvrVLG9Nb6JvcZzfj/e3727+FOvvTfBib1UeX4/nX66uwE1rL3TxYm92oF+P2r3tbufBqi93suJvQeNfj8YWrC7bNeivSrTib2Bmn4/ao2puxqQnL2v24m9Qqp+P7fOobtQaZW9++SJvXC7fj/JLZm7oHGNvdPuib2izX4/c7qPu6W3hL37+Im9aOB+P+Bmhbs6XXa9VwOKvY3zfj96hHq7ZFNnvfYKir2kAX8/EbljPfC7L7wZ9no/EKxBPrbGTj2xkR+8Owh7Pw66QT7wzTg98JwOvF0Zez9Ix0E+yeshPSno+bspKXs/eNNBPlU9Cj0eW9W7Tzd7P2TeQT4xj+M8fJqvu5RDez/b50E+b5CxPGkFibunTXs/o+9BPtpxfTwlkkO7WVV7P5P1QT6YhhY80ErouoRaez+Q+UE+YBs7O8JSELoQXXs/hvtBPpKkZLsFhTA67Vx7P237QT710yC8okP4Oh5aez9B+UE+H+KDvG+SSzuvVHs/EPVBPoeftrxq8Yw7v0x7P/DuQT6+eei8SGqzO3RCez/+5kE+IJsMvaoG2Tv/NXs/Yt1BPldNJL2Emf07nSd7P0jSQT4xEDu9dl0QPLEXez/+xUE+g+RQvRY2ITx6Bns/t7hBPj2tZb00QDE8UfR6P7KqQT5vTXm9fGVAPJbhej8+nEE+tbaFvUJiTjzrzno/1o1BPnMRjr1HR1s8i7x6P6h/QT6OqJW9WP5mPOCqej8GckE+q22cvU9xcTxXmno/Q2VBPrgqor21THo8wIt6PwBaQT7x9Ka9p9iAPCp/ej9JUEE++72qvXvEgzz1dHo/aUhBPnl3rb3A3oU8eG16P6JCQT784K69vPWGPIppej+aP0E+aAivvSgUhzwcaXo/RD9BPlierb2+/IU8DG16P09CQT6Gkaq9LKKDPG51ej/HSEE+KcmlvZvifzxGgno/sVJBPoGrn70ccnY8KpJ6P/ReQT6PWpi9UydrPGKkej8DbUE+WPiPvcY2Xjw0uHo/TnxBPuGEhr11oE88Ms16P4GMQT4lnHi9qdw/PEbiej/GnEE+OexivSEgLzzT9no/oaxBPnA+TL2unx08TQp7P6q7QT46xDS9e4ELPE0cez+OyUE+BOkcvdMw8jtXLHs/7tVBPqDxBL00M807Kzp7P5rgQT7jRdq8anSoO6NFez9z6UE+fr+rvOqMhDuqTns/avBBPu+KfbyarkM7V1V7P5H1QT5Wwye86nsBO9ZZez8J+UE+kneuu+ushjpjXHs/AvtBPkDlX7q8ES05T117P7f7QT4SzmE79y8uuvBcez9v+0E+QpICPGR+ybo3W3s/GvpBPgZ6UDw53iC77ld7P5H3QT6L75A8n65fu+NSez+t80E+F7u6PGEYkLv+S3s/Wu5BPoJG5TyE7bC7MEN7P4/nQT5XHAg98xHSu3k4ez9K30E+MJYdPY8387vrK3s/mNVBPrjdMj3CBwq8qh17P5jKQT57xkc9mCoavOYNez9vvkE+EyRcPQniKbzd/Ho/SbFBPnOkbz3B7ji8AOt6P3+jQT43GoE99UFHvJXYej9KlUE+7tOJPZG5VLwCxno/9IZBPk7pkT2HM2G8t7N6P9V4QT6tIZk9ZFhsvH2iej+Ka0E+ZoOfPfExdryQkno/QF9BPnv4pD1Dnn68boR6P1dUQT74aqk9ub2CvI54ej8tS0E+eZKsPeQshbzxb3o/h0RBPhmFrj2xrYa8i2p6P1xAQT7cLa897S+HvLNoej/xPkE+4JGuPY23hrxnano/QUBBPuyYrD3eMYW83296P3lEQT5mhqk95NKCvER4ej/0SkE+sGilPXFLf7xGg3o/clNBPihOoD3iane8i5B6P7BdQT7fH5o9ueBtvA2gej+paUE+mBWTPQIDY7z5sHo/uXZBPqw9iz3n51a848J6P4uEQT59poI9lqVJvGDVej/PkkE+8YZyPaooO7w66Ho/XKFBPhG5Yz3wuy+8GfZ6PxCsQT6X3wU0yDRatJXfBT/GNFo//tS/NnUyDrRGNQU/6JxaP22RQLlbNaQ2UIkEP1MFWz+fmry3x9VaOJLbAz8Ybls/ziOsNdSzJrZ8LAM/79ZbP/t5AjQPQVy0+XkCPxFBXD++xgE02KpctL/GAT/aqlw/8hABNGMVXbTvEAE/YxVdP5bx67VG3GU2fVkAPxWAXT9zCfi3F4hxOAM//z5x610/8TCPNTStCrYiwf0+01heP3nh/jNOBl60feH+Pk8GXj+tSwA0FYhdtK1LAD8ViF0/EiUBNJ8JXbQRJQE/oAldP/r6ATQZjFy0+voBPxqMXD+ozgI00g5ctKjOAj/QDlw/F58DNGOSW7QZnwM/Y5JbP+xsBDSBFlu062wEP38WWz9MOAU0DZtatEw4BT8Qm1o/bQEGNP4fWrRsAQY//x9aP7AoCrYYllw2UcgGP1GlWT8vkNI3bjHCOKqMBz8/K1k/hw8/OKpz2DduTwg/NLFYP74hJTc2Msg2aw8JP/g3WD/nl9Q4GzKHOILNCT8Dv1c/O1titqhexbbFiQo/UEZXPwTkMriS+q04KUYLP57MVj8AJJo1ANERtm2iCz+vkFY/OhULNFHsVrQ7FQs/UOxWP+ebLDcW89M2W4wKP6ZEVz+gmxo5h1LFOGsCCj8unVc/2EEjOCoazjeMdwk/0/VXP/lj4bW+UV020+sIP4ROWD+EREW4JO+/OMBeCD+Qp1g/yrVQtwx1yzc30Ac/BgFZP/VRM7ghf6447EAHP3NaWT/94IS3ib4AOISwBj8NtFk/zfxjt5WD3je7HgY/+w1aP96LBTQOaFq02osFPw9oWj+19wQ0YcJatLX3BD9fwlo/IWIENAcdW7QgYgQ/BR1bP6cvnzQIFRG1NssDP+x3Wz9RwZ63pXoaOJEzAz+10ls/tuJGt26vwTdsmQI/bC5cP6xrZjSM+s60jP4BPwCKXD/YNYy3oF8IOFhhAT9e5lw/sAJit8VE3DcNwwA/yEJdP1VFQLb5LLs2GSMAP5CfXT+ImgG4i7l8OGcD/z6S/F0/d61BNuOovLaIrP0+s15ePzcyL7j7aKo4SHj+PnkkXj9CWJY13m4PtlOz/z71yV0/GXUANBJwXbQadQA/EnBdP2kOATTcFl20ag4BP9sWXT/mpgE0lL1ctOWmAT+TvVw/LT4CNHNkXLQrPgI/c2RcP8rUAjQqC1y0ytQCPysLXD9zaAM0HLNbtHNoAz8cs1s/EPsDNCZbW7QQ+wM/KFtbP9uMBDQtA1u02owEPy4DWz8iHQU0nKtatCAdBT+cq1o/F6wFNFhUWrQVrAU/VlRaPyU6BjQc/Vm0JDoGPx39WT/LxgY0QqZZtMvGBj9Dplk/mVIHNHFPWbSYUgc/c09ZPyPdBzTw+Fi0I90HP+/4WD9UZwg0KqJYtFJnCD8rolg/W+8INEhMWLRb7wg/SExYP312CTR+9le0gHYJP372Vz/SusY0ahk1tQL9CT+loFc/s64JuOgAhjh/ggo//kpXP1YAWTV8A8u1CwcLP371Vj8NlQs0ZJlWtA2VCz9jmVY/53YLNPysVrTndgs//KxWP2rSCjR8F1e0a9IKP34XVz8apRA2fwiKtuMzCj98fVc/qG4huIvVnDjMkwk/1eNXP2o3sTQoYR+1y/IIPxpKWD9Pm6C3/kocOPlPCD/dsFg/Ji5JtxX6wzdTqwc/GBhZP9kIR7nDVVu2sgUHP0J/WT9Ah+M2cXDvsyleBj/r5lk/l98FNMg0WrSV3wU/xjRaP1zOFDIxmI8yj4zrvrpMYz8LVRMyVfqPMr806b4l52M/4ZcRMtJGkDJS1ea+ioFkP+MsEDLyxJAy8m3kvvAbZT96yQ4yRx2RMgoD4r4wtWU/7DQNMhCAkTIThd++C1FmP1qfCzK/4ZEyQQPdvrDrZj87BAoyZEOSMpN42r5Hhmc/92MIMuGkkjLg5Ne+ySBoP9PEBjKJA5MyeUbVvoW7aD9YCgUyc2mTMlCY0r6GV2k/h08GMpUfkzKemtS+0eJoP/tECDImrJIybbTXvgssaD+aMQoyvziSMj3A2r5cdWc/QhYMMj7FkTIZv92+pr5mP3/zDTKbUZEy/rLgvo0HZj/yxw8yXN6QMpCY474BUWU/T5QRMixrkDIDcea+2ZpkP/1ZEzL+948yVT/pvnDkYz8+GRUyxoSPMhsD7L76LWM/ZM0WMvsPjzLIvO6+cndiPxQ6GDJyho4ya2vxvi7BYT8RNRoy/yqOMpAV9L6DCWE/x9YbMp+3jTJZrva+AVRgPzN1HTLXRI0y0T75vk+eXz+mDh8y0dGMMiLI+74r6F4/U8ggMiNbjDJ+T/6+JjBeP3tvITI5JIwyq4v/vmLVXT9bPiAy1XuMMoan/b4hYF4/7hQfMijQjDLQ0Pu+t+VeP77oHTKUJI0yavX5vlVrXz/MuRwy3XiNMsoV+L7T8F8/woUbMuzMjTJ8M/a+vXVgP2gtGjKRHY4yZUr0vi77YD82IhkymHOOMltX8r7zgWE/aukXMuXFjjJSY/C+mAdiP/V5FjKxFI8ylmnuvlqNYj+uQRUy4muPMnJq7L4cE2M/AhQUMlHIjzKkZeq+5ZhjP8DJEjLXHJAy4FrovsAeZD/9exEyWHGQMo5K5r6JpGQ/vSoQMuzFkDI/NOS+TyplPwW4DjIeGZEyDxvivkevZT8laA0yam6RMv70377bNWY/khwMMsTDkTJtyd2+K7xmP8u5CjIeEZIyOJjbvjVCZz8TUwkyHWeSMkdg2b4zyGc/yuYHMgTDkjJXIde+J05oPwZsBjIFJJMyuNrUvi3UaD8w9gQyuW2TMrdy0r4BYGk/XYAFMrpEkzIx4NO+Rg1pPwFCBzI76JIyURfWvpCLaD+toQgymZaSMoJH2L7UCWg/fv8JMp9EkjJwcNq+M4hnPzhYCzLQ8pEyrJLcvpcGZz9VrQwy3KCRMqau3r7yhGY/AwQOMpNNkTJRzeC+HwFmP25NDzKx/JAyYdbivhaBZT9ylRAyNquQMpfd5L4UAGU/W9sRMmNZkDIs4ea+jH5kP2sdEzJ3B5AyNd/ovgL9Yz+wWxQyvrWPMm/X6r6Qe2M/EpcVMu5jjzJ/yuy+FfpiPxDPFjI1Eo8yF7juvq54Yj+rAxgyYMCOMuug8L4092E/2jUZModujjIkhfK+pHVhP2poGjKnG44yqmr0vmvyYD+4kBsywcqNMsI/9r5fcmA/nrccMll5jTK2Evi+rfFfPyXdHTLGJ40yAOP5vntwXz8L8B4y09+MMiKv+745714/NSAgMkeEjDIqd/2+6W1eP3hTITJuLIwyA17/vobiXT8WEiEyOj+MMn32/r5IAF4/aq0fMgaljDIfwvy+ZKFePzBWHjJqBo0yB6D6voc7Xz/M1xwyIWeNMt53+L6i1V8/GZgbMpTIjTKUS/a+IW9gP8E5GjLnNo4y7Rb0viQJYT9nyxgyTZSOMtrW8b5tpGE/sDUXMhv+jjLwk+++nT5iP0voFTJ9To8yFkntvgbZYj9czhQyMZiPMo+M6766TGM/rFSNs6DX1TR4knY/N6uJvsdVg7W/EJi2Xbd2P9GhiL4ODgc4vMA0OXTcdj/RlIe+hseXN2B1zji/AXc/EISGvrzab7X6A4e26yZ3P91xhb7XFoSzEDbWNAJNdz9pVoS++yeCs/9I1jQPc3c/tziDvtwygLPgW9Y0Ppl3P1gXgr4JbZY1wSn8Nqu/dz9s8YC+1o2eN/fs7Thi5nc/4Yx/voSvNLWr2Fi2ig14PyEqfb5tVXezc4bWNFXwdz8+8n6+QiJ8sxlw1jRxwnc/H9yAvuxpgLPPWdY0EZV3PyQ3gr4cuYKzd0PWNO5ndz+HjIO+9f6EsxYt1jQMO3c/Y9yEvnY5h7PCFtY0lg53P54lhr77aImzfADWNIzidj9raIe+aJCLsy3q1TS5tnY/cqaIvkGvjbPf09U0LIt2P3Pfib7OYrY1QoX6NuFfdj+tE4u+grS7N8p/7DjsNHY/r0KMvuoyUrXBrle21wl2P81vjb5Q2pWztHrVNJ/fdT9IlI6+SM+Xs5Zk1TShtXU/urSPvg+imrUT/Za2wot1P+TRkL77CRA4cQkmObhhdT/Q7ZG+ZUVytWV8XbYVTXU/V3iSvq8qrbNJZ+Q0qGx1Pyikkb46xZmzG07VNDOLdT+s1ZC+lFqYs15e1TTjqXU/6gSQvoTslrOibtU0rsh1Pysyj76bBq81laPuNnLndT9JXo6+2uwWOHTOODl+BnY/E4eNvmBXHzeXYUY4ESZ2P9KqjL5NVAY4xMUoOXZFdj9Zzou+TRJBN6PyezgMZXY/Bu+KvqPtKDc/tFk4xYR2PzsNir5Dcoyz7+DVNKekdj+wKIm+8uCKs1Tx1TS3xHY/P0GIvl1LibOrAdY04+R2P1RXh74BsUG0BUyJtDgFdz+Kaoa+8DhZN9XglziDJXc/RHyFvlhQCDd8qD84YUZ3P++HhL5eqAG0OodFM2Zndz+IkIO+Uuc3N74GhzhqiHc/NpeCvjz4FDeho1o4n6l3P2magb5HG/Q1+DlFN/zKdz9TmoC+xIulN9xl+TiT7Hc/uSx/vm6w9bVXECu3rw94P3IIfb4z9ds3haMnOej6dz+ATX6+6pg0tZthY7Zj2nc/ZSOAvpsDfbPza9Y0+Ll3Pzcdgb79LICzF1zWNLCZdz/3E4K+09GBs0NM1jSleXc//AaDvllxg7NtPNY0xVl3P+H2g75AFIWzQizWNGU5dz+v6IS+CaSGs6Yc1jRGGnc/Y8+FvuwyiLPfDNY0Aft2P4y1hr7UvomzB/3VNMDbdj/xmYe+n0aLsy3t1TSdvHY/43uIvq3JjLNa3dU0pJ12PxZbib4/SI6zhs3VNNR+dj+jN4q+psKPs6+91TQmYHY/wxGLvvc4kbPfrdU0nEF2P3fpi77Sq5KzDZ7VNCojdj8hv4y+ICCUs/yN1TRoBHY/mpWNvu+FlbNlftU0quZ1P69jjr6H6pazum7VNNnIdT8FMY++gx+PtKvgBrURq3U/4/yPvtKW2zf9VgA5X411P+3GkL54tiK1Kj8NtspvdT8Oj5G+EHqcs5wu1TQPUHU/YmSSviQrnLM5MtU01VZ1P/c2kr5JfZqzzEXVNI17dT+cP5G+Kmvatc3B7rbmnnU/00+Qvn4g+ze5Jhc5YcJ1P2hdj77u+260sE2+tOnldT/haI6+HQl0NzNPlzjBCXY/ZHCNvjUkGTe98D44Jy52PylyjL6+lAs4whwwOXFSdj+8cou+wgintbGTt7b5dnY/oW+KvqxUjbOg19U0eJJ2Pzerib5y3j65lYrfuKLfBT++NFo/7H/Tt7Cs0bhiNQU/1pxaP5puPzgSXLm4FokEP3YFWz9Wfss3ve5EuITbAz8gbls/JbJJOO1birheLAM/AddbP+SFDblx1Li4KnoCP/NAXD9Hlz04vN22uILGAT/+qlw/+Ng8OALVtrgxEQE/PBVdP60zGrlZR7a4bVkAPx6AXT8f9RI4b+lluPw+/z5z610/JNWGtTQiEDYJwf0+2lhePxG8RTjfaLm44d/+PsUGXj8HDeu3xAe2uOJLAD/2h10/rM8ouXcRt7gwJQE/jgldP4S6STjBSra4KvsBP/6LXD9RcZq4U1ncuNvOAj+yDlw/zL6Ut4vRy7hOnwM/Q5JbP6uXBjghY7i4FW0EP2YWWz9dQDi5pgveuF04BT8Fm1o/YB+6t0yYzrhoAQY/AiBaP2tvQTgwRrm4IMgGP2+lWT+51d23O9i7uJuMBz9IK1k/NztQt8PnvLhrTwg/NrFYP24+F7f43pi2YA8JP/83WD+OlCq5HRjbuG7NCT8Pv1c/mL8juFQy17e0iQo/W0ZXPwDoPLdGGOm2G0YLP6jMVj/m64y4FQjGuGuiCz+wkFY/mmxVOMWJurgnFQs/XexWP0IeCDhy2bq4SIwKP7JEVz+jWhi5GQHEuGUCCj8ynVc/GGwYufE6w7iAdwk/2vVXPz577zYE1Ta23OsIP35OWD9rI384KiHzuL5eCD+Rp1g/jObAuHajvLhL0Ac/+QBZPxfAV7nu8QW52EAHP39aWT/jF464cAvAuFywBj8ltFk/LEDCN3MKtLfDHgY/9g1aP6QaDbld87241YsFPxFoWj/xk1A4czm4uKX3BD9pwlo/Six4OCctuLgUYgQ/DB1bP5LxG7ngzbq4KcsDP/N3Wz8roI+4STq5uIQzAz+90ls/pXI9OF97t7hOmQI/fi5cPyV3GzjXVre4LP4BPziKXD8oXq+4REC3uFBhAT9i5lw/AUtTOHYttrgDwwA/zUJdP+aMUbmGZ/24CiMAP5ifXT82Pok4VeG5uFcC/z7h/F0/WO43N8WIsbdvrP0+ul5ePwApNTi8Rqm4Hnj+PoUkXj+bQJi4YF8RuGWy/z46yl0/qX3ANSNwyLgFdQA/HnBdP+xrhzZbJ9C2wg4BP6gWXT/DORG4V4W3uCmnAT9rvVw/d7IbuReauLgnPgI/dWRcP3BnE7kRYrm4AdUCPwoLXD9Wel84UGW3uGJoAz8ms1s/Ph4Qua0i8rgn+wM/GltbPxfUC7nl37m41owEPzEDWz+XSyS4gGrauDcdBT+Oq1o/GyU6uTPh1bgorAU/SlRaP2fQNTjToau4RDoGPwn9WT8jMcM23e+7NuDGBj82plk/pvEFuZoClrigUgc/bU9ZPzFYQDg4S7m4N90HP+P4WD9qXUk4Cxi5uDtnCD86olg/wUnGuM8xwLhQ7wg/TkxYPytDWDiIZLm4cXYJP4f2Vz+LJNm3/cq9uPf8CT+soFc/SrRIt8RAvriEggo/+0pXP2yXWbfTOPK2DgcLP3z1Vj+3u1e5G/YGuQeVCz9mmVY/p71stjbwurjcdgs/A61WP42/3TfwxcG4cdIKP3oXVz9N2sm4JZ3wuOkzCj94fVc/w07RuKLqsbjZkwk/zONXP0O7vLjG6za5wfIIPyBKWD+jnD843B+5uPlPCD/dsFg//wM/OHMoubhVqwc/FxhZP5YQF7kAQb+4qQUHP0h/WT+gSqC3vNW6uCReBj/u5lk/ct4+uZWK37ii3wU/vjRaP9nTFDJvmY8yh4zrvrxMYz+Y+RIyHOaPMrI06b4o52M/WQUSMn9XkDI91ea+j4FkP8dtEDIcxZAy423kvvQbZT+hjg4yohKRMgUD4r4ytWU/pDgNMgZ9kTIRhd++C1FmP0PACzI5z5EyNgPdvrLrZj/HaQoyx06SMoV42r5Lhmc/LGAIMoikkjLZ5Ne+yyBoP77EBjKHA5MydEbVvoa7aD8wCgUyf2mTMjqY0r6LV2k/4WQGMrMbkzKJmtS+1eJoPzuhCDI6tJIyZ7TXvg0saD/6KwoyMTiSMj7A2r5cdWc/ID4MMqrJkTL9vt2+rb5mP/z9DTLwR5Ey7LLgvpEHZj+g2A8yleCQMomY474DUWU/w5IRMs5pkDL1cOa+3JpkP/1ZEzK6948ySj/pvnLkYz/hHRUy7pWPMhgD7L77LWM/vQcXMsIijzLAvO6+dHdiP3RjGDKDjI4yWWvxvjPBYT8mEhoyKRiOMooV9L6FCWE/U9cbMhO4jTJRrva+A1RgPzN1HTLLRI0yxj75vlKeXz+gDx8yx9GMMhvI+74t6F4/pKcgMp1djDJsT/6+KzBePwuaITIDHYwyn4v/vmXVXT9pmiAyPpqMMnyn/b4kYF4/qCcfMpbRjDLF0Pu+uuVeP8voHTKVJI0yZ/X5vlZrXz+2uRwy73iNMsIV+L7V8F8/6IsbMrnPjTJiM/a+xHVgP4OdGjLtUY4yWUr0vjH7YD9rKhkyaHeOMlFX8r71gWE/VNwXMt7KjjJCY/C+nAdiP7jAFjIgFY8yjGnuvlyNYj+ocxUyl2yPMllq7L4iE2M/oRgUMvrLjzKkZeq+5ZhjP+m3EjKzPJAy0VrovsQeZD80YBEyNnCQMn9K5r6MpGQ/CioQMtLFkDIrNOS+VSplP7kDDzLjIJEy+Rrivk2vZT+umw0ygneRMvL0377eNWY/m30MMmDNkTJOyd2+MrxmP6G6CjKwI5IyI5jbvjpCZz/teQkyMHOSMjlg2b42yGc/uukHMh/CkjJQIde+KU5oP6mfBjLcHpMyptrUvjHUaD/39wQyGnKTMp9y0r4HYGk/rQgGMsAlkzIm4NO+SQ1pPx48BzL45pIyRRfWvpOLaD8p1Qgygr2SMmlH2L7aCWg/CPcJMrpFkjJhcNq+NohnP78XCzLB+5Eym5LcvpsGZz9ZrQwy26CRMoqu3r75hGY/QgcOMkhOkTJLzeC+IAFmP0CDDzK6AZEyVdbivhmBZT/umRAyEqaQMofd5L4YAGU/8toRMt9WkDIe4ea+kH5kP8kbEzKI7Y8yLd/ovgT9Yz9vXBQyZbaPMmfX6r6Se2M/64gVMrl2jzJzyuy+GPpiP13PFjLBEY8yHLjuvq14Yj/v/hcy6MGOMvCg8L4z92E/NXcZMvVcjjIdhfK+pnVhP1t9GjLtJ44yqWr0vmvyYD/6lRsyQ8uNMr0/9r5hcmA/QtUcMrmBjTKtEvi+sPFfP3f7HTJfI40y9+L5vn5wXz+bRh8yIduMMiKv+745714/PB4gMmOEjDIad/2+7m1eP5xVITK8LIwy+13/voniXT908SAyYzmMMnj2/r5JAF4/lnAfMgesjDIfwvy+ZKFePwZYHjJ0AI0y/Z/6voo7Xz9H+BwyXGSNMtx3+L6i1V8/U5sbMp3LjTKMS/a+I29gP6osGjKBHI4y4Rb0vigJYT/JshgyloCOMtLW8b5vpGE/NF0XMqjsjjLjk+++oD5iPywLFjJOOI8yBUntvgrZYj/Z0xQyb5mPMoeM6768TGM/cz7ANRomETd8knY/HauJvuNSxrc4CQG5Ybd2P7WhiL59Bwe4DNoyuW/cdj/2lIe+W1eOt7zAvLjAAXc/B4SGvov41LdaSBK56SZ3P+pxhb55TRG2lCw9twlNdz81VoS+7b76txTtMbkJc3c/4ziDvkuk9rdnzjG5Rpl3PxkXgr4/lNq0Enfetau/dz9w8YC+AkyftzfO67hi5nc/4Yx/vm08NjVReKk2ig14PyEqfb49WPK33OI1uUHwdz9y836+LOSVt4ur3bh4wnc/59uAvkF/5zXZOTo3FJV3Pwg3gr5ukv+3axw0ufdndz9FjIO+MyqIt2TivLgTO3c/LNyEviEGx7eYWQW5nA53P28lhr7QePi3fOYkuZHidj9AaIe+UJm5NDcGOja9tnY/WKaIvjfWy7c1wQG5LIt2P3Pfib69YQ24yUcxudxfdj/PE4u+quWxt1pk3LjsNHY/q0KMvhJLzbfggve41wl2P81vjb4Jj9k0Bn9KNqDfdT9HlI6+vKnfs/5oCTWftXU/x7SPvqcn4rOrWAk1wIt1P+zRkL5aIkk0G8z5NbhhdT/P7ZG+zE6Dt4pMlLgWTXU/TXiSvnshHrhZ/DS5pmx1PzWkkb6ouA24yxAkuTOLdT+s1ZC+bXWas32kMTXjqXU/6gSQvpiF3rNmcAk1rsh1Pysyj77UZQu2yBMZt3bndT8rXo6+9PM/uFSIaLl/BnY/C4eNvtv0H7caGUC4FSZ2P7aqjL69Hxo0Bz/tNXZFdj9azou+tFRtt3WFlbgJZXY/G++KvsfZK7dBvFW4yIR2PyYNir4diRy2qok8t6ekdj+wKIm+Q1gKuNAjNbm3xHY/QEGIvlEED7goCT654+R2P1VXh7786DMziDiqNTkFdz+Gaoa+EsdVtwFukbiEJXc/QXyFvkwXALjAeTG5X0Z3P/2HhL5If/K3+BsquV1ndz/NkIO+KDomt0+5bbhqiHc/NpeCvilE+7cFrja5n6l3P2iagb7tK7K1jNXstvvKdz9cmoC+0dEEuO58R7mG7Hc/eC1/vplB5rZ0kiq4sA94P28Ifb7LQty3iKYmuef6dz+VTX6+fFv1NSgLRzdY2nc/uiOAvtUx0Lf0Qxe597l3Pzcdgb7LZRe24CxIt7uZdz+iE4K+tNaSt+Ab0biueXc/twaDvqBsxbNvCQo1yFl3P872g752ObK1cwXRtm05dz936IS+I6sHuJGuOLlGGnc/ZM+FvguJFbcAKke4Bvt2P2u1hr6JpBa28RI1t8Dbdj/umYe+UZm7t9SH9rihvHY/xXuIvhIZATbClzk3p512PwBbib4j3gG4bsQludh+dj+EN4q+UuQnNduajzYoYHY/tBGLvrkvHzYOGlQ3nUF2P2/pi74vERC4xAAxuS0jdj8Kv4y+Qo4TuEIHM7llBHY/rJWNvl6KHbeR/zq4quZ1P7Bjjr4XVxm4Sic2udnIdT8GMY++sIq7txb727gQq3U/5PyPvmYK1reiKfe4YI11P+bGkL7OzuQ05jFKNstvdT8Bj5G+7J7dNR1oEDcQUHU/XmSSvheh4bf3aQC51VZ1P/c2kr4arA248agiuY97dT+SP5G+I9aFt+w4nLjnnnU/yk+Qvv812rZ2sfO3ZMJ1P1Ndj75xeBO46MswuenldT/haI6+RWcRuB25MLnDCXY/WnCNvnuKD7j1wjC5KC52PyJyjL7HUAK14IDetXJSdj+8cou+R4+6t6/H6rj7dnY/k2+KvnM+wDUaJhE3fJJ2Px2rib59wQI+Gwsyv1HBAr4YCzI/eMECPhsLMr9MwQK+GAsyP3PBAj4cCzK/R8ECvhkLMj9vwQI+HAsyv0PBAr4ZCzI/asECPhwLMr8+wQK+GQsyP2bBAj4cCzK/OsECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/acECPhwLMr89wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/acECPhwLMr89wQK+GQsyP2bBAj4cCzK/OsECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/Z8ECPhwLMr87wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/acECPhwLMr89wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9mwQI+HAsyvzrBAr4ZCzI/ZsECPhwLMr86wQK+GQsyP2bBAj4cCzK/OsECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/Z8ECPhwLMr87wQK+GQsyP2bBAj4cCzK/OsECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/aMECPhwLMr88wQK+GQsyP2bBAj4cCzK/OsECvhkLMj9owQI+HAsyvzzBAr4ZCzI/acECPhwLMr89wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/acECPhwLMr89wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/Z8ECPhwLMr87wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/acECPhwLMr89wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/acECPhwLMr89wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/acECPhwLMr89wQK+GQsyP2bBAj4cCzK/OsECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/acECPhwLMr89wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9mwQI+HAsyvzrBAr4ZCzI/acECPhwLMr89wQK+GQsyP2bBAj4cCzK/OsECvhkLMj9nwQI+HAsyvzvBAr4ZCzI/ZsECPhwLMr86wQK+GQsyP2bBAj4cCzK/OsECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/acECPhwLMr89wQK+GQsyP2bBAj4cCzK/OsECvhkLMj9owQI+HAsyvzzBAr4ZCzI/ZsECPhwLMr86wQK+GQsyP2bBAj4cCzK/OsECvhkLMj9mwQI+HAsyvzrBAr4ZCzI/ZsECPhwLMr86wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9pwQI+HAsyvz3BAr4ZCzI/acECPhwLMr89wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9nwQI+HAsyvzvBAr4ZCzI/Z8ECPhwLMr87wQK+GQsyP2nBAj4cCzK/PcECvhkLMj9nwQI+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#.glb"; diff --git a/tests/src/loader/GLTFLoader.test.ts b/tests/src/loader/GLTFLoader.test.ts index f095a6949e..59ccbeb8f1 100644 --- a/tests/src/loader/GLTFLoader.test.ts +++ b/tests/src/loader/GLTFLoader.test.ts @@ -306,7 +306,7 @@ class GLTFCustomBufferParser extends GLTFParser { 0, 0, 0, 0, 7, 9, 255, 196, 0, 20, 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0, 157, 0, 6, 42, 155, 255, 217 ]); - context.buffers = [buffer]; + context._buffers = [buffer]; } } diff --git a/tests/src/loader/KTX2Loader.test.ts b/tests/src/loader/KTX2Loader.test.ts index 0e5b1a375d..41a9eb1880 100644 --- a/tests/src/loader/KTX2Loader.test.ts +++ b/tests/src/loader/KTX2Loader.test.ts @@ -100,7 +100,7 @@ describe("ktx2 Loader test", function () { expect(texture2d.width).to.be.equal(32); expect(texture2d.height).to.be.equal(32); expect(texture2d.mipmapCount).to.be.equal(6); - expect(texture2d.format).to.be.equal(TextureFormat.DXT1); + expect(texture2d.format).to.be.equal(TextureFormat.BC1); }); });