@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
347 lines • 38.9 kB
JavaScript
import { TgdConsole } from "./../debug/index.js";
import { TgdVec2, TgdVec3, TgdVec4 } from "./../math/index.js";
import { TgdProgram } from "./../program/index.js";
import { tgdCodeStringify } from "./../shader/index.js";
export class TgdUniformBufferObject {
constructor(context, { uniforms, values }) {
this.context = context;
this.values = {};
this.dirty = true;
this.bindingPoint = context.uniformBufferObjects.add(this);
this.uniforms = uniforms;
// Offset in floats (not bytes).
let offsetInFloats = 0;
for (const name of Object.keys(uniforms)) {
const type = uniforms[name];
const { modulo, length } = LAYOUTS[type];
// Word alignment.
while (offsetInFloats % modulo !== 0)
offsetInFloats++;
this.makeAccessor(name, type, offsetInFloats);
offsetInFloats += length;
}
const bytesLength = Float32Array.BYTES_PER_ELEMENT * 4 * Math.ceil(offsetInFloats / 4);
this.data = new ArrayBuffer(bytesLength);
this.view = new DataView(this.data);
if (values) {
const keys = Object.keys(values);
for (const key of keys) {
const val = values[key];
if (val === undefined)
continue;
this.values[key] = val;
}
}
const { gl } = context;
this.buffer = gl.createBuffer();
gl.bindBufferBase(gl.UNIFORM_BUFFER, this.bindingPoint, this.buffer);
gl.bufferData(gl.UNIFORM_BUFFER, this.data.byteLength, gl.DYNAMIC_DRAW);
context.checkError("TgdUniformBufferObject");
}
get names() {
return Object.keys(this.uniforms);
}
delete() {
const { context } = this;
context.uniformBufferObjects.remove(this);
const { gl } = context;
gl.deleteBuffer(this.buffer);
}
bindToProgram(program, blockName) {
const { gl } = this.context;
const glPrg = program instanceof TgdProgram ? program.program : program;
gl.uniformBlockBinding(glPrg, gl.getUniformBlockIndex(glPrg, blockName), this.bindingPoint);
}
updateData() {
if (!this.dirty)
return;
const { data } = this;
const { gl } = this.context;
gl.bindBuffer(gl.UNIFORM_BUFFER, this.buffer);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
this.dirty = false;
}
toShaderCode(blockName, instanceName) {
const { uniforms } = this;
return [
`/* Binding point: ${this.bindingPoint} */`,
`layout(std140) uniform ${blockName} {`,
Object.keys(uniforms).map((key) => `${uniforms[key]} ${key};`),
instanceName ? `} ${instanceName};` : "};",
];
}
debug(caption) {
const out = new TgdConsole({ text: caption ?? "TgdUniformBufferObject", bold: true });
out.add(tgdCodeStringify(this.toShaderCode("myUniformBlock")));
const array = new Float32Array(this.data);
for (let i = 0; i < array.length; i++) {
if (i % 4 === 0)
out.nl();
out.add(`${array[i]}`.slice(0, 8).padStart(10, " "));
}
out.nl();
out.debug();
}
makeAccessor(name, type, offsetInFloats) {
const { values } = this;
const byteOffset = offsetInFloats * 4;
switch (type) {
case "bool":
Object.defineProperty(values, name, {
set: (value) => {
this.view.setUint8(byteOffset, value ? 1 : 0);
this.dirty = true;
},
get: () => this.view.getUint8(byteOffset) !== 0,
});
break;
case "int":
Object.defineProperty(values, name, {
set: (value) => {
this.view.setInt32(byteOffset, value, true);
this.dirty = true;
},
get: () => this.view.getInt32(byteOffset, true),
});
break;
case "uint":
Object.defineProperty(values, name, {
set: (value) => {
this.view.setUint32(byteOffset, value, true);
this.dirty = true;
},
get: () => this.view.getUint32(byteOffset, true),
});
break;
case "float":
Object.defineProperty(values, name, {
set: (value) => {
this.view.setFloat32(byteOffset, value, true);
this.dirty = true;
},
get: () => this.view.getFloat32(byteOffset, true),
});
break;
case "double":
Object.defineProperty(values, name, {
set: (value) => {
this.view.setFloat64(byteOffset, value, true);
this.dirty = true;
},
get: () => this.view.getFloat64(byteOffset, true),
});
break;
case "vec2":
Object.defineProperty(values, name, {
set: ([x, y]) => {
this.view.setFloat32(byteOffset, x, true);
this.view.setFloat32(byteOffset + 4, y, true);
this.dirty = true;
},
get: () => new TgdVec2(this.view.getFloat32(byteOffset, true), this.view.getFloat32(byteOffset + 4, true)),
});
break;
case "vec3":
Object.defineProperty(values, name, {
set: ([x, y, z]) => {
this.view.setFloat32(byteOffset, x, true);
this.view.setFloat32(byteOffset + 4, y, true);
this.view.setFloat32(byteOffset + 8, z, true);
this.dirty = true;
},
get: () => new TgdVec3(this.view.getFloat32(byteOffset, true), this.view.getFloat32(byteOffset + 4, true), this.view.getFloat32(byteOffset + 8, true)),
});
break;
case "vec4":
Object.defineProperty(values, name, {
set: ([x, y, z, w]) => {
this.view.setFloat32(byteOffset, x, true);
this.view.setFloat32(byteOffset + 4, y, true);
this.view.setFloat32(byteOffset + 8, z, true);
this.view.setFloat32(byteOffset + 12, w, true);
this.dirty = true;
},
get: () => new TgdVec4(this.view.getFloat32(byteOffset, true), this.view.getFloat32(byteOffset + 4, true), this.view.getFloat32(byteOffset + 8, true), this.view.getFloat32(byteOffset + 12, true)),
});
break;
case "dvec2":
Object.defineProperty(values, name, {
set: ([x, y]) => {
this.view.setFloat64(byteOffset, x, true);
this.view.setFloat64(byteOffset + 4, y, true);
this.dirty = true;
},
get: () => new TgdVec2(this.view.getFloat64(byteOffset, true), this.view.getFloat64(byteOffset + 4, true)),
});
break;
case "dvec3":
Object.defineProperty(values, name, {
set: ([x, y, z]) => {
this.view.setFloat64(byteOffset, x, true);
this.view.setFloat64(byteOffset + 4, y, true);
this.view.setFloat64(byteOffset + 8, z, true);
this.dirty = true;
},
get: () => new TgdVec3(this.view.getFloat64(byteOffset, true), this.view.getFloat64(byteOffset + 4, true), this.view.getFloat64(byteOffset + 8, true)),
});
break;
case "dvec4":
Object.defineProperty(values, name, {
set: ([x, y, z, w]) => {
this.view.setFloat64(byteOffset, x, true);
this.view.setFloat64(byteOffset + 4, y, true);
this.view.setFloat64(byteOffset + 8, z, true);
this.view.setFloat64(byteOffset + 12, w, true);
this.dirty = true;
},
get: () => new TgdVec4(this.view.getFloat64(byteOffset, true), this.view.getFloat64(byteOffset + 4, true), this.view.getFloat64(byteOffset + 8, true), this.view.getFloat64(byteOffset + 12, true)),
});
break;
case "ivec2":
Object.defineProperty(values, name, {
set: ([x, y]) => {
this.view.setInt32(byteOffset, x, true);
this.view.setInt32(byteOffset + 4, y, true);
this.dirty = true;
},
get: () => new TgdVec2(this.view.getInt32(byteOffset, true), this.view.getInt32(byteOffset + 4, true)),
});
break;
case "ivec3":
Object.defineProperty(values, name, {
set: ([x, y, z]) => {
this.view.setInt32(byteOffset, x, true);
this.view.setInt32(byteOffset + 4, y, true);
this.view.setInt32(byteOffset + 8, z, true);
this.dirty = true;
},
get: () => new TgdVec3(this.view.getInt32(byteOffset, true), this.view.getInt32(byteOffset + 4, true), this.view.getInt32(byteOffset + 8, true)),
});
break;
case "ivec4":
Object.defineProperty(values, name, {
set: ([x, y, z, w]) => {
this.view.setInt32(byteOffset, x, true);
this.view.setInt32(byteOffset + 4, y, true);
this.view.setInt32(byteOffset + 8, z, true);
this.view.setInt32(byteOffset + 12, z, true);
this.dirty = true;
},
get: () => new TgdVec4(this.view.getInt32(byteOffset, true), this.view.getInt32(byteOffset + 4, true), this.view.getInt32(byteOffset + 8, true), this.view.getInt32(byteOffset + 12, true)),
});
break;
case "uvec2":
Object.defineProperty(values, name, {
set: ([x, y]) => {
this.view.setUint32(byteOffset, x, true);
this.view.setUint32(byteOffset + 4, y, true);
this.dirty = true;
},
get: () => new TgdVec2(this.view.getUint32(byteOffset, true), this.view.getUint32(byteOffset + 4, true)),
});
break;
case "uvec3":
Object.defineProperty(values, name, {
set: ([x, y, z]) => {
this.view.setUint32(byteOffset, x, true);
this.view.setUint32(byteOffset + 4, y, true);
this.view.setUint32(byteOffset + 8, z, true);
this.dirty = true;
},
get: () => new TgdVec3(this.view.getUint32(byteOffset, true), this.view.getUint32(byteOffset + 4, true), this.view.getUint32(byteOffset + 8, true)),
});
break;
case "uvec4":
Object.defineProperty(values, name, {
set: ([x, y, z, w]) => {
this.view.setUint32(byteOffset, x, true);
this.view.setUint32(byteOffset + 4, y, true);
this.view.setUint32(byteOffset + 8, z, true);
this.view.setUint32(byteOffset + 12, w, true);
this.dirty = true;
},
get: () => new TgdVec4(this.view.getUint32(byteOffset, true), this.view.getUint32(byteOffset + 4, true), this.view.getUint32(byteOffset + 8, true), this.view.getUint32(byteOffset + 12, true)),
});
break;
case "mat2":
Object.defineProperty(values, name, {
set: (mat2) => {
let src = 0;
let dst = byteOffset;
for (let row = 0; row < 2; row++) {
for (let col = 0; col < 2; col++) {
this.view.setFloat32(dst, mat2[src++], true);
dst += 4;
}
dst += 8;
}
this.dirty = true;
},
});
break;
case "mat3":
Object.defineProperty(values, name, {
set: (mat3) => {
let src = 0;
let dst = byteOffset;
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 3; col++) {
this.view.setFloat32(dst, mat3[src++], true);
dst += 4;
}
dst += 4;
}
this.dirty = true;
},
});
break;
case "mat4":
Object.defineProperty(values, name, {
set: (mat4) => {
let src = 0;
let dst = byteOffset;
for (let row = 0; row < 4; row++) {
for (let col = 0; col < 4; col++) {
this.view.setFloat32(dst, mat4[src++], true);
dst += 4;
}
}
this.dirty = true;
},
});
break;
default:
throw new Error(`[TgdUniformBufferObject] Type "${type}" has been implemented yet!`);
}
}
}
/**
* Modulo is used for the padding necessary with Layout std140.
* The length is in floats.
*/
const LAYOUTS = {
bool: { modulo: 1, length: 1, rows: 1 },
int: { modulo: 1, length: 1, rows: 1 },
uint: { modulo: 1, length: 1, rows: 1 },
float: { modulo: 1, length: 1, rows: 1 },
double: { modulo: 2, length: 2, rows: 1 },
vec2: { modulo: 2, length: 2, rows: 1 },
bvec2: { modulo: 2, length: 2, rows: 1 },
ivec2: { modulo: 2, length: 2, rows: 1 },
uvec2: { modulo: 2, length: 2, rows: 1 },
dvec2: { modulo: 2, length: 2, rows: 1 },
vec3: { modulo: 4, length: 3, rows: 1 },
bvec3: { modulo: 4, length: 3, rows: 1 },
ivec3: { modulo: 4, length: 3, rows: 1 },
uvec3: { modulo: 4, length: 3, rows: 1 },
dvec3: { modulo: 4, length: 3, rows: 1 },
vec4: { modulo: 4, length: 4, rows: 1 },
bvec4: { modulo: 4, length: 4, rows: 1 },
ivec4: { modulo: 4, length: 4, rows: 1 },
uvec4: { modulo: 4, length: 4, rows: 1 },
dvec4: { modulo: 4, length: 4, rows: 1 },
mat2: { modulo: 4, length: 8, rows: 2 },
mat3: { modulo: 4, length: 12, rows: 3 },
mat4: { modulo: 4, length: 16, rows: 4 },
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pZm9ybS1idWZmZXItb2JqZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3VuaWZvcm0vdW5pZm9ybS1idWZmZXItb2JqZWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDdkMsT0FBTyxFQUE0QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUMvRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQ3pDLE9BQU8sRUFBb0IsZ0JBQWdCLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFzQ2hFLE1BQU0sT0FBTyxzQkFBc0I7SUFlL0IsWUFDb0IsT0FBbUIsRUFDbkMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUF1QztRQUR6QyxZQUFPLEdBQVAsT0FBTyxDQUFZO1FBWHZCLFdBQU0sR0FBRyxFQUV4QixDQUFBO1FBTU8sVUFBSyxHQUFHLElBQUksQ0FBQTtRQU1oQixJQUFJLENBQUMsWUFBWSxHQUFHLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDMUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUE7UUFDeEIsZ0NBQWdDO1FBQ2hDLElBQUksY0FBYyxHQUFHLENBQUMsQ0FBQTtRQUN0QixLQUFLLE1BQU0sSUFBSSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFRLEVBQUUsQ0FBQztZQUM5QyxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDM0IsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDeEMsa0JBQWtCO1lBQ2xCLE9BQU8sY0FBYyxHQUFHLE1BQU0sS0FBSyxDQUFDO2dCQUFFLGNBQWMsRUFBRSxDQUFBO1lBQ3RELElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQTtZQUM3QyxjQUFjLElBQUksTUFBTSxDQUFBO1FBQzVCLENBQUM7UUFDRCxNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ3RGLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUE7UUFDeEMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDbkMsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUNULE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFRLENBQUE7WUFDdkMsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDckIsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUN2QixJQUFJLEdBQUcsS0FBSyxTQUFTO29CQUFFLFNBQVE7Z0JBRS9CLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFBO1lBQzFCLENBQUM7UUFDTCxDQUFDO1FBQ0QsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQTtRQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQTtRQUMvQixFQUFFLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDcEUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQTtRQUN2RSxPQUFPLENBQUMsVUFBVSxDQUFDLHdCQUF3QixDQUFDLENBQUE7SUFDaEQsQ0FBQztJQUVELElBQUksS0FBSztRQUNMLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDckMsQ0FBQztJQUVELE1BQU07UUFDRixNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFBO1FBQ3hCLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDekMsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQTtRQUN0QixFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUNoQyxDQUFDO0lBRUQsYUFBYSxDQUFDLE9BQWtDLEVBQUUsU0FBaUI7UUFDL0QsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUE7UUFDM0IsTUFBTSxLQUFLLEdBQUcsT0FBTyxZQUFZLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFBO1FBQ3ZFLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLG9CQUFvQixDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUE7SUFDL0YsQ0FBQztJQUVELFVBQVU7UUFDTixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFNO1FBRXZCLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUE7UUFDckIsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUE7UUFDM0IsRUFBRSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUM3QyxFQUFFLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO1FBQzVDLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFBO0lBQ3RCLENBQUM7SUFFRCxZQUFZLENBQUMsU0FBaUIsRUFBRSxZQUFxQjtRQUNqRCxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFBO1FBQ3pCLE9BQU87WUFDSCxxQkFBcUIsSUFBSSxDQUFDLFlBQVksS0FBSztZQUMzQywwQkFBMEIsU0FBUyxJQUFJO1lBQ3RDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztZQUN2RSxZQUFZLENBQUMsQ0FBQyxDQUFDLEtBQUssWUFBWSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUk7U0FDN0MsQ0FBQTtJQUNMLENBQUM7SUFFRCxLQUFLLENBQUMsT0FBZ0I7UUFDbEIsTUFBTSxHQUFHLEdBQUcsSUFBSSxVQUFVLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxJQUFJLHdCQUF3QixFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO1FBQ3JGLEdBQUcsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUM5RCxNQUFNLEtBQUssR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDekMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztnQkFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUE7WUFDekIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ3hELENBQUM7UUFDRCxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUE7UUFDUixHQUFHLENBQUMsS0FBSyxFQUFFLENBQUE7SUFDZixDQUFDO0lBRU8sWUFBWSxDQUFDLElBQVksRUFBRSxJQUFZLEVBQUUsY0FBc0I7UUFDbkUsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQTtRQUN2QixNQUFNLFVBQVUsR0FBRyxjQUFjLEdBQUcsQ0FBQyxDQUFBO1FBQ3JDLFFBQVEsSUFBSSxFQUFFLENBQUM7WUFDWCxLQUFLLE1BQU07Z0JBQ1AsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFO29CQUNoQyxHQUFHLEVBQUUsQ0FBQyxLQUFjLEVBQUUsRUFBRTt3QkFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTt3QkFDN0MsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUE7b0JBQ3JCLENBQUM7b0JBQ0QsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7aUJBQ2xELENBQUMsQ0FBQTtnQkFDRixNQUFLO1lBQ1QsS0FBSyxLQUFLO2dCQUNOLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRTtvQkFDaEMsR0FBRyxFQUFFLENBQUMsS0FBYSxFQUFFLEVBQUU7d0JBQ25CLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQzNDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFBO29CQUNyQixDQUFDO29CQUNELEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDO2lCQUNsRCxDQUFDLENBQUE7Z0JBQ0YsTUFBSztZQUNULEtBQUssTUFBTTtnQkFDUCxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUU7b0JBQ2hDLEdBQUcsRUFBRSxDQUFDLEtBQWEsRUFBRSxFQUFFO3dCQUNuQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUM1QyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQTtvQkFDckIsQ0FBQztvQkFDRCxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQztpQkFDbkQsQ0FBQyxDQUFBO2dCQUNGLE1BQUs7WUFDVCxLQUFLLE9BQU87Z0JBQ1IsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFO29CQUNoQyxHQUFHLEVBQUUsQ0FBQyxLQUFhLEVBQUUsRUFBRTt3QkFDbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDN0MsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUE7b0JBQ3JCLENBQUM7b0JBQ0QsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUM7aUJBQ3BELENBQUMsQ0FBQTtnQkFDRixNQUFLO1lBQ1QsS0FBSyxRQUFRO2dCQUNULE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRTtvQkFDaEMsR0FBRyxFQUFFLENBQUMsS0FBYSxFQUFFLEVBQUU7d0JBQ25CLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQzdDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFBO29CQUNyQixDQUFDO29CQUNELEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDO2lCQUNwRCxDQUFDLENBQUE7Z0JBQ0YsTUFBSztZQUNULEtBQUssTUFBTTtnQkFDUCxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUU7b0JBQ2hDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBVSxFQUFFLEVBQUU7d0JBQ3JCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUM3QyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQTtvQkFDckIsQ0FBQztvQkFDRCxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQ04sSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7aUJBQ3RHLENBQUMsQ0FBQTtnQkFDRixNQUFLO1lBQ1QsS0FBSyxNQUFNO2dCQUNQLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRTtvQkFDaEMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBVSxFQUFFLEVBQUU7d0JBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUM3QyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDN0MsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUE7b0JBQ3JCLENBQUM7b0JBQ0QsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUNOLElBQUksT0FBTyxDQUNQLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsRUFDdEMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsRUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FDN0M7aUJBQ1IsQ0FBQyxDQUFBO2dCQUNGLE1BQUs7WUFDVCxLQUFLLE1BQU07Z0JBQ1AsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFO29CQUNoQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBVSxFQUFFLEVBQUU7d0JBQzNCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUM3QyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQzlDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFBO29CQUNyQixDQUFDO29CQUNELEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FDTixJQUFJLE9BQU8sQ0FDUCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLEVBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsR0FBRyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQzlDO2lCQUNSLENBQUMsQ0FBQTtnQkFDRixNQUFLO1lBQ1QsS0FBSyxPQUFPO2dCQUNSLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRTtvQkFDaEMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFVLEVBQUUsRUFBRTt3QkFDckIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDekMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQzdDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFBO29CQUNyQixDQUFDO29CQUNELEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FDTixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztpQkFDdEcsQ0FBQyxDQUFBO2dCQUNGLE1BQUs7WUFDVCxLQUFLLE9BQU87Z0JBQ1IsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFO29CQUNoQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFVLEVBQUUsRUFBRTt3QkFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDekMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUM3QyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQTtvQkFDckIsQ0FBQztvQkFDRCxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQ04sSUFBSSxPQUFPLENBQ1AsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxFQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUMxQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUM3QztpQkFDUixDQUFDLENBQUE7Z0JBQ0YsTUFBSztZQUNULEtBQUssT0FBTztnQkFDUixNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUU7b0JBQ2hDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFVLEVBQUUsRUFBRTt3QkFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDekMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUM3QyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDOUMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUE7b0JBQ3JCLENBQUM7b0JBQ0QsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUNOLElBQUksT0FBTyxDQUNQLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsRUFDdEMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsRUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsRUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FDOUM7aUJBQ1IsQ0FBQyxDQUFBO2dCQUNGLE1BQUs7WUFDVCxLQUFLLE9BQU87Z0JBQ1IsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFO29CQUNoQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQVUsRUFBRSxFQUFFO3dCQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDM0MsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUE7b0JBQ3JCLENBQUM7b0JBQ0QsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUNOLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO2lCQUNsRyxDQUFDLENBQUE7Z0JBQ0YsTUFBSztZQUNULEtBQUssT0FBTztnQkFDUixNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUU7b0JBQ2hDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQVUsRUFBRSxFQUFFO3dCQUN4QixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDM0MsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQzNDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFBO29CQUNyQixDQUFDO29CQUNELEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FDTixJQUFJLE9BQU8sQ0FDUCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLEVBQ3BDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQ3hDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQzNDO2lCQUNSLENBQUMsQ0FBQTtnQkFDRixNQUFLO1lBQ1QsS0FBSyxPQUFPO2dCQUNSLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRTtvQkFDaEMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQVUsRUFBRSxFQUFFO3dCQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDM0MsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQzNDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUM1QyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQTtvQkFDckIsQ0FBQztvQkFDRCxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQ04sSUFBSSxPQUFPLENBQ1AsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxFQUNwQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUN4QyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUN4QyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUM1QztpQkFDUixDQUFDLENBQUE7Z0JBQ0YsTUFBSztZQUNULEtBQUssT0FBTztnQkFDUixNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUU7b0JBQ2hDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBVSxFQUFFLEVBQUU7d0JBQ3JCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQ3hDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUM1QyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQTtvQkFDckIsQ0FBQztvQkFDRCxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQ04sSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7aUJBQ3BHLENBQUMsQ0FBQTtnQkFDRixNQUFLO1lBQ1QsS0FBSyxPQUFPO2dCQUNSLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRTtvQkFDaEMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBVSxFQUFFLEVBQUU7d0JBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQ3hDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUM1QyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDNUMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUE7b0JBQ3JCLENBQUM7b0JBQ0QsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUNOLElBQUksT0FBTyxDQUNQLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsRUFDckMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsRUFDekMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FDNUM7aUJBQ1IsQ0FBQyxDQUFBO2dCQUNGLE1BQUs7WUFDVCxLQUFLLE9BQU87Z0JBQ1IsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFO29CQUNoQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBVSxFQUFFLEVBQUU7d0JBQzNCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQ3hDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO3dCQUM1QyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTt3QkFDNUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7d0JBQzdDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFBO29CQUNyQixDQUFDO29CQUNELEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FDTixJQUFJLE9BQU8sQ0FDUCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLEVBQ3JDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQzdDO2lCQUNSLENBQUMsQ0FBQTtnQkFDRixNQUFLO1lBQ1QsS0FBSyxNQUFNO2dCQUNQLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRTtvQkFDaEMsR0FBRyxFQUFFLENBQUMsSUFBYSxFQUFFLEVBQUU7d0JBQ25CLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQTt3QkFDWCxJQUFJLEdBQUcsR0FBRyxVQUFVLENBQUE7d0JBQ3BCLEtBQUssSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQzs0QkFDL0IsS0FBSyxJQUFJLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO2dDQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7Z0NBQzVDLEdBQUcsSUFBSSxDQUFDLENBQUE7NEJBQ1osQ0FBQzs0QkFDRCxHQUFHLElBQUksQ0FBQyxDQUFBO3dCQUNaLENBQUM7d0JBQ0QsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUE7b0JBQ3JCLENBQUM7aUJBQ0osQ0FBQyxDQUFBO2dCQUNGLE1BQUs7WUFDVCxLQUFLLE1BQU07Z0JBQ1AsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFO29CQUNoQyxHQUFHLEVBQUUsQ0FBQyxJQUFhLEVBQUUsRUFBRTt3QkFDbkIsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFBO3dCQUNYLElBQUksR0FBRyxHQUFHLFVBQVUsQ0FBQTt3QkFDcEIsS0FBSyxJQUFJLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDOzRCQUMvQixLQUFLLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUM7Z0NBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTtnQ0FDNUMsR0FBRyxJQUFJLENBQUMsQ0FBQTs0QkFDWixDQUFDOzRCQUNELEdBQUcsSUFBSSxDQUFDLENBQUE7d0JBQ1osQ0FBQzt3QkFDRCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQTtvQkFDckIsQ0FBQztpQkFDSixDQUFDLENBQUE7Z0JBQ0YsTUFBSztZQUNULEtBQUssTUFBTTtnQkFDUCxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUU7b0JBQ2hDLEdBQUcsRUFBRSxDQUFDLElBQWEsRUFBRSxFQUFFO3dCQUNuQixJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUE7d0JBQ1gsSUFBSSxHQUFHLEdBQUcsVUFBVSxDQUFBO3dCQUNwQixLQUFLLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUM7NEJBQy9CLEtBQUssSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQztnQ0FDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO2dDQUM1QyxHQUFHLElBQUksQ0FBQyxDQUFBOzRCQUNaLENBQUM7d0JBQ0wsQ0FBQzt3QkFDRCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQTtvQkFDckIsQ0FBQztpQkFDSixDQUFDLENBQUE7Z0JBQ0YsTUFBSztZQUNUO2dCQUNJLE1BQU0sSUFBSSxLQUFLLENBQUMsa0NBQWtDLElBQUksNkJBQTZCLENBQUMsQ0FBQTtRQUM1RixDQUFDO0lBQ0wsQ0FBQztDQUNKO0FBNEJEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxHQUFzRjtJQUMvRixJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN2QyxHQUFHLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN0QyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN2QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN6QyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN2QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN2QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN2QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN2QyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUN4QyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtDQUMzQyxDQUFBIn0=