From 61212dea4927fa755d9d5eae0e6a36970f6c7150 Mon Sep 17 00:00:00 2001 From: PhilippeChab Date: Tue, 27 Jan 2026 19:06:57 -0500 Subject: [PATCH 1/2] Use AST Tree from compiler for tokenization --- client/tsconfig.json | 4 +- server/scripts/GenerateLibDefinitions.ts | 24 +- server/src/Documents/DocumentsCollection.ts | 12 +- server/src/Documents/DocumentsIndexer.ts | 4 +- server/src/Parser/ASTPositionQuery.ts | 298 +++ server/src/Parser/ASTTraversal.ts | 523 +++++ server/src/Parser/ASTTypes.ts | 131 ++ server/src/Parser/NWScriptParser.ts | 232 ++ server/src/Providers/Builders/Builder.ts | 10 +- .../Builders/CompletionItemBuilder.ts | 18 +- .../Providers/Builders/HoverContentBuilder.ts | 21 +- .../Builders/SignatureHelpBuilder.ts | 10 +- .../src/Providers/Builders/SymbolBuilder.ts | 51 +- .../src/Providers/CompletionItemsProvider.ts | 13 +- server/src/Providers/DiagnosticsProvider.ts | 24 +- .../src/Providers/GotoDefinitionProvider.ts | 38 +- server/src/Providers/HoverContentProvider.ts | 16 +- server/src/Providers/SignatureHelpProvider.ts | 16 +- server/src/Providers/SymbolsProvider.ts | 4 +- server/src/ServerManager/ServerManager.ts | 46 +- server/src/Tokenizer/Tokenizer.ts | 567 ++--- server/src/Tokenizer/types.ts | 8 +- server/src/server.ts | 2 +- server/test/ast_integration_test.ts | 206 ++ server/test/ast_tokenization_test.ts | 259 +++ server/test/static/globalScopeTokens.json | 1565 ++++++++----- .../static/localScopeTokensWithContext.json | 1765 +++++++++++--- .../localScopeTokensWithoutContext.json | 2048 ++++++++++++----- server/test/static/test.nss | 10 + server/test/tokenization_test.ts | 40 +- server/tsconfig.json | 7 +- server/wasm/nwscript_compiler.js | 2 + server/wasm/nwscript_compiler.wasm | Bin 0 -> 307952 bytes 33 files changed, 5946 insertions(+), 2028 deletions(-) create mode 100644 server/src/Parser/ASTPositionQuery.ts create mode 100644 server/src/Parser/ASTTraversal.ts create mode 100644 server/src/Parser/ASTTypes.ts create mode 100644 server/src/Parser/NWScriptParser.ts create mode 100644 server/test/ast_integration_test.ts create mode 100644 server/test/ast_tokenization_test.ts create mode 100644 server/wasm/nwscript_compiler.js create mode 100755 server/wasm/nwscript_compiler.wasm diff --git a/client/tsconfig.json b/client/tsconfig.json index 42fbe60..89106d1 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -8,7 +8,9 @@ "rootDir": "src", "strict": true, "allowSyntheticDefaultImports": true, - "esModuleInterop": true + "esModuleInterop": true, + "composite": true, + "declaration": true }, "include": ["src"], "exclude": ["node_modules"] diff --git a/server/scripts/GenerateLibDefinitions.ts b/server/scripts/GenerateLibDefinitions.ts index 81e2f5f..a7218ee 100644 --- a/server/scripts/GenerateLibDefinitions.ts +++ b/server/scripts/GenerateLibDefinitions.ts @@ -10,7 +10,7 @@ const generateDefinitions = async () => { console.log("Generating nwscript.nss definitions ..."); const lib = readFileSync(normalize(join(__dirname, "./nwscript.nss"))).toString(); - const definitions = tokenizer.tokenizeContent(lib, TokenizedScope.global); + const definitions = await tokenizer.tokenizeContent(lib, TokenizedScope.global); writeFileSync(normalize(join(__dirname, "../resources/standardLibDefinitions.json")), JSON.stringify(definitions, null, 4)); console.log("Done."); @@ -20,27 +20,23 @@ const generateDefinitions = async () => { let directoryPath = normalize(join(__dirname, "base_scripts")); let files = readdirSync(directoryPath); - files.forEach((filename) => { + for (const filename of files) { const fileSource = join(normalize(join(__dirname, "base_scripts", filename))); const fileDestination = join(normalize(join(__dirname, "../resources/base_scripts", filename.replace(".nss", ".json")))); const lib = readFileSync(fileSource).toString(); // Skip main files if (!lib.includes("main")) { - const definitions = tokenizer.tokenizeContent(lib, TokenizedScope.global); - if ( - definitions.children.length === 0 && - definitions.complexTokens.length === 0 && - definitions.structComplexTokens.length === 0 - ) { - return; + const definitions = await tokenizer.tokenizeContent(lib, TokenizedScope.global); + if (definitions.children.length === 0 && definitions.complexTokens.length === 0 && definitions.structComplexTokens.length === 0) { + continue; } console.log(`Generating ${filename} ...`); filesCount++; writeFileSync(fileDestination, JSON.stringify(definitions, null, 4)); } - }); + } console.log(`Generated ${filesCount} files.`); console.log("Done."); @@ -49,18 +45,18 @@ const generateDefinitions = async () => { directoryPath = normalize(join(__dirname, "ovr")); files = readdirSync(directoryPath); - files.forEach((filename) => { + for (const filename of files) { const fileSource = join(normalize(join(__dirname, "ovr", filename))); const fileDestination = join(normalize(join(__dirname, "../resources/ovr", filename.replace(".nss", ".json")))); const lib = readFileSync(fileSource).toString(); - const definitions = tokenizer.tokenizeContent(lib, TokenizedScope.global); + const definitions = await tokenizer.tokenizeContent(lib, TokenizedScope.global); console.log(`Generating ${filename} ...`); filesCount++; writeFileSync(fileDestination, JSON.stringify(definitions, null, 4)); - }); + } console.log(`Generated ${filesCount} files.`); console.log("Done."); }; -generateDefinitions(); +void generateDefinitions(); diff --git a/server/src/Documents/DocumentsCollection.ts b/server/src/Documents/DocumentsCollection.ts index 6cecd6b..e110ba2 100644 --- a/server/src/Documents/DocumentsCollection.ts +++ b/server/src/Documents/DocumentsCollection.ts @@ -25,7 +25,7 @@ export default class DocumentsCollection extends Dictionnary { const directoryPath = normalize(join(__dirname, "..", "resources", static_resources_folder)); const files = readdirSync(directoryPath); files.forEach((filename) => { - const tokens = JSON.parse(readFileSync(join(__dirname, "..", "resources", static_resources_folder, filename)).toString()) as any as GlobalScopeTokenizationResult; + const tokens = JSON.parse(readFileSync(join(__dirname, "..", "resources", static_resources_folder, filename)).toString()) as GlobalScopeTokenizationResult; this.addDocument(this.initializeDocument(`${STATIC_PREFIX}/${filename.replace(".json", FILES_EXTENSION)}`, true, tokens)); }); }); @@ -52,7 +52,7 @@ export default class DocumentsCollection extends Dictionnary { if (this.get(this.getKey(uri, false))) return; const fileContent = readFileSync(filePath).toString(); - this.createDocuments(uri, fileContent, tokenizer, workespaceFilesSystem); + void this.createDocuments(uri, fileContent, tokenizer, workespaceFilesSystem); }); } @@ -72,16 +72,16 @@ export default class DocumentsCollection extends Dictionnary { this.addDocument(this.initializeDocument(uri, false, globalScope)); } - public createDocuments(uri: string, content: string, tokenizer: Tokenizer, workespaceFilesSystem: WorkspaceFilesSystem) { - const globalScope = tokenizer.tokenizeContent(content, TokenizedScope.global); + public async createDocuments(uri: string, content: string, tokenizer: Tokenizer, workespaceFilesSystem: WorkspaceFilesSystem) { + const globalScope = await tokenizer.tokenizeContent(content, TokenizedScope.global); this.addDocument(this.initializeDocument(uri, false, globalScope)); this.createChildrenDocument(globalScope.children, tokenizer, workespaceFilesSystem); } - public updateDocument(document: TextDocument, tokenizer: Tokenizer, workespaceFilesSystem: WorkspaceFilesSystem) { + public async updateDocument(document: TextDocument, tokenizer: Tokenizer, workespaceFilesSystem: WorkspaceFilesSystem) { const currentChildren = this.getFromUri(document.uri)?.children; - const globalScope = tokenizer.tokenizeContent(document.getText(), TokenizedScope.global); + const globalScope = await tokenizer.tokenizeContent(document.getText(), TokenizedScope.global); const newChildren = globalScope.children.filter((child) => !currentChildren!.includes(child)); this.overwriteDocument(this.initializeDocument(document.uri, false, globalScope)); diff --git a/server/src/Documents/DocumentsIndexer.ts b/server/src/Documents/DocumentsIndexer.ts index fd888eb..747f088 100644 --- a/server/src/Documents/DocumentsIndexer.ts +++ b/server/src/Documents/DocumentsIndexer.ts @@ -13,7 +13,7 @@ const generateTokens = async (filesPath: string[]) => { for (let i = 0; i < filesPath.length; i++) { const filePath = filesPath[i]; const fileContent = readFileSync(filePath).toString(); - const globalScope = tokenizer.tokenizeContent(fileContent, TokenizedScope.global); + const globalScope = await tokenizer.tokenizeContent(fileContent, TokenizedScope.global); process?.send!(JSON.stringify({ filePath, globalScope })); } @@ -22,5 +22,5 @@ const generateTokens = async (filesPath: string[]) => { }; process.on("message", (filesPath: string) => { - generateTokens(filesPath.split(",")); + void generateTokens(filesPath.split(",")); }); diff --git a/server/src/Parser/ASTPositionQuery.ts b/server/src/Parser/ASTPositionQuery.ts new file mode 100644 index 0000000..c8f1919 --- /dev/null +++ b/server/src/Parser/ASTPositionQuery.ts @@ -0,0 +1,298 @@ +import { CompletionItemKind } from "vscode-languageserver"; +import type { ASTNode, AST } from "./ASTTypes"; +import { ASTOperation } from "./ASTTypes"; + +/** + * Position-based query service for AST. + * Provides LSP position-based features using the AST tree structure. + */ +export class ASTPositionQuery { + constructor(private readonly ast: AST) {} + + /** + * Find the most specific (deepest) node at the given position. + * Prefers nodes with identifiers (stringData) over structural nodes. + * + * @param line - 0-indexed line number + * @param char - 0-indexed character position + * @returns The most specific node at this position, or null + */ + public findNodeAtPosition(line: number, char: number): ASTNode | null { + // AST uses 1-indexed lines and chars, convert from 0-indexed LSP positions + const astLine = line + 1; + const astChar = char + 1; + + const candidates: Array<{ node: ASTNode; depth: number; distance: number }> = []; + + // Collect all nodes at or before this position with their depth + const traverse = (node: ASTNode | null, depth: number) => { + if (!node) return; + + const nodeBeforeTarget = node.position.line < astLine || (node.position.line === astLine && node.position.char <= astChar); + + if (nodeBeforeTarget) { + // Calculate distance from target position + const lineDist = Math.abs(node.position.line - astLine); + const charDist = node.position.line === astLine ? Math.abs(node.position.char - astChar) : 1000; + const distance = lineDist * 1000 + charDist; + + candidates.push({ node, depth, distance }); + } + + // Always traverse both children to explore all branches + traverse(node.left, depth + 1); + traverse(node.right, depth + 1); + }; + + traverse(this.ast.ast, 0); + + if (candidates.length === 0) return null; + + // Sort by specificity: + // 1. Prefer exact position matches (distance = 0) + // 2. Prefer deeper nodes (more specific) + // 3. Prefer nodes with stringData (identifiers, literals) + // 4. Prefer closer position (smaller distance) + candidates.sort((a, b) => { + // Exact position match? + const aExact = a.distance === 0; + const bExact = b.distance === 0; + + if (aExact && !bExact) return -1; + if (!aExact && bExact) return 1; + + // Prefer deeper nodes (more specific in the tree) + if (a.depth !== b.depth) { + return b.depth - a.depth; + } + + // Prefer nodes with stringData (actual tokens) + const aHasData = !!a.node.stringData; + const bHasData = !!b.node.stringData; + + if (aHasData && !bHasData) return -1; + if (!aHasData && bHasData) return 1; + + // Prefer closer position + return a.distance - b.distance; + }); + + return candidates[0].node; + } + + /** + * Get action target at position with optional offset. + * Returns information about the token at or near the cursor. + * + * @param line - 0-indexed line number + * @param char - 0-indexed character position + * @param offset - Offset to apply (not implemented yet, for compatibility) + * @returns Token information + */ + public getActionTargetAtPosition( + line: number, + char: number, + offset: number = 0, + ): { + tokenType: CompletionItemKind | undefined; + lookBehindRawContent: string | undefined; + rawContent: string | undefined; + } { + const node = this.findNodeAtPosition(line, char); + + if (!node) { + return { + tokenType: undefined, + lookBehindRawContent: undefined, + rawContent: undefined, + }; + } + + // Determine token type from AST operation + let tokenType: CompletionItemKind | undefined; + const rawContent = node.stringData; + + switch (node.operation) { + case ASTOperation.VARIABLE: + tokenType = CompletionItemKind.Variable; + break; + case ASTOperation.FUNCTION_IDENTIFIER: + case "ACTION_ID": + tokenType = CompletionItemKind.Function; + break; + case ASTOperation.KEYWORD_STRUCT: + tokenType = CompletionItemKind.Struct; + break; + case ASTOperation.CONSTANT_INTEGER: + case ASTOperation.CONSTANT_FLOAT: + case ASTOperation.CONSTANT_STRING: + tokenType = CompletionItemKind.Constant; + break; + default: + tokenType = undefined; + } + + // For struct property access, need to find the struct variable + let lookBehindRawContent: string | undefined; + if (this.isInStructPropertyAccess(node)) { + lookBehindRawContent = this.findStructVariableName(node); + } + + return { + tokenType, + lookBehindRawContent, + rawContent, + }; + } + + /** + * Check if position is within a specific scope (e.g., function call). + * + * @param line - 0-indexed line number + * @param char - 0-indexed character position + * @param scopeType - The scope type to check for + * @returns True if position is within the scope + */ + public isInScope(line: number, char: number, scopeType: string): boolean { + const node = this.findNodeAtPosition(line, char); + if (!node) return false; + + // Check if we're in a function call scope + if (scopeType === "function.call" || scopeType.includes("functionCall")) { + return this.isInFunctionCall(node); + } + + return false; + } + + /** + * Find function name when cursor is inside a function call. + * Used for signature help. + * + * @param line - 0-indexed line number + * @param char - 0-indexed character position + * @returns Function name or undefined + */ + public getFunctionNameAtPosition(line: number, char: number): string | undefined { + const node = this.findNodeAtPosition(line, char); + if (!node) return undefined; + + // Look for ACTION node containing this position + const action = this.findAncestorOfType(node, "ACTION"); + if (!action) return undefined; + + // Find ACTION_ID child + const actionId = this.findChildOfType(action, "ACTION_ID"); + return actionId?.stringData; + } + + /** + * Count the number of arguments before the current position in a function call. + * Used to determine which parameter is active in signature help. + * + * @param line - 0-indexed line number + * @param char - 0-indexed character position + * @returns Number of commas found (= argument index) + */ + public getActiveParameterIndex(line: number, char: number): number { + const node = this.findNodeAtPosition(line, char); + if (!node) return 0; + + // Find the ACTION (function call) containing this position + const action = this.findAncestorOfType(node, "ACTION"); + if (!action) return 0; + + // Count ACTION_ARG_LIST nodes that start before the cursor position + // Each ACTION_ARG_LIST represents a parameter separator (comma) + let argIndex = 0; + const astLine = line + 1; + const astChar = char + 1; + + const countArgs = (n: ASTNode | null): void => { + if (!n) return; + + if (n.operation === "ACTION_ARG_LIST") { + // Count if this arg list starts strictly before our position + if (n.position.line < astLine || (n.position.line === astLine && n.position.char < astChar)) { + argIndex++; + } + } + + countArgs(n.left); + countArgs(n.right); + }; + + countArgs(action); + + return argIndex; + } + + // ============================================================================ + // Private Helper Methods + // ============================================================================ + + /** + * Check if node is within a function call. + */ + private isInFunctionCall(node: ASTNode): boolean { + return !!this.findAncestorOfType(node, "ACTION"); + } + + /** + * Check if node is in a struct property access context. + */ + private isInStructPropertyAccess(node: ASTNode): boolean { + // This would require checking if we're accessing a struct member + // For now, return false - implement when needed + return false; + } + + /** + * Find struct variable name for property access. + */ + private findStructVariableName(node: ASTNode): string | undefined { + // Implement when struct property access is needed + return undefined; + } + + /** + * Find ancestor node of specific type. + * Since we don't have parent pointers, we search the entire tree. + */ + private findAncestorOfType(target: ASTNode, operation: string): ASTNode | null { + const parents: ASTNode[] = []; + + const findParents = (node: ASTNode | null, path: ASTNode[]): boolean => { + if (!node) return false; + + if (node === target) { + parents.push(...path); + return true; + } + + const newPath = [...path, node]; + if (findParents(node.left, newPath)) return true; + if (findParents(node.right, newPath)) return true; + + return false; + }; + + findParents(this.ast.ast, []); + + // Find first parent with matching operation + return parents.reverse().find((p) => p.operation === operation) || null; + } + + /** + * Find first child node with specific operation type. + */ + private findChildOfType(node: ASTNode, operation: string): ASTNode | null { + if (node.left?.operation === operation) return node.left; + if (node.right?.operation === operation) return node.right; + + const leftResult = node.left ? this.findChildOfType(node.left, operation) : null; + if (leftResult) return leftResult; + + return node.right ? this.findChildOfType(node.right, operation) : null; + } +} diff --git a/server/src/Parser/ASTTraversal.ts b/server/src/Parser/ASTTraversal.ts new file mode 100644 index 0000000..b627f9b --- /dev/null +++ b/server/src/Parser/ASTTraversal.ts @@ -0,0 +1,523 @@ +import { CompletionItemKind } from "vscode-languageserver"; +import type { ComplexToken, FunctionComplexToken, FunctionParamComplexToken, StructComplexToken, VariableComplexToken, ConstantComplexToken, StructPropertyComplexToken } from "../Tokenizer/types"; +import type { ASTNode, AST } from "./ASTTypes"; +import { ASTOperation, getTypeFromNode, isOperation } from "./ASTTypes"; + +/** + * Extract ComplexTokens from an AST for global scope + */ +export function extractGlobalTokens(ast: AST): { + complexTokens: ComplexToken[]; + structComplexTokens: StructComplexToken[]; + children: string[]; +} { + const complexTokens: ComplexToken[] = []; + const structComplexTokens: StructComplexToken[] = []; + const children: string[] = []; + let inGlobalScope = false; + + function traverse(node: ASTNode | null): void { + if (!node) return; + + // Track when we're in global scope + const wasInGlobalScope = inGlobalScope; + if (isOperation(node, ASTOperation.GLOBAL_VARIABLES)) { + inGlobalScope = true; + } + + // Extract function declarations + if (isOperation(node, ASTOperation.FUNCTION)) { + const func = extractFunction(node); + if (func) { + complexTokens.push(func); + } + } + + // Extract struct definitions + if (isOperation(node, ASTOperation.STRUCTURE_DEFINITION)) { + const struct = extractStruct(node); + if (struct) { + structComplexTokens.push(struct); + } + } + + // Extract constants and global variables + if (isOperation(node, ASTOperation.KEYWORD_DECLARATION)) { + // In global scope, all declarations are treated as constants + if (inGlobalScope) { + const constant = extractGlobalVariable(node); + if (constant) { + complexTokens.push(constant); + } + } else { + // In local scope, only extract if it's explicitly const + const constant = extractConstant(node); + if (constant) { + complexTokens.push(constant); + } + } + } + + // Note: Include directives are not in the AST, they're resolved during compilation + // We would need to track them separately if needed + + // Traverse children + traverse(node.left); + traverse(node.right); + + inGlobalScope = wasInGlobalScope; + } + + traverse(ast.ast); + + return { + complexTokens, + structComplexTokens, + children, + }; +} + +/** + * Extract function information from FUNCTION node + */ +function extractFunction(node: ASTNode): FunctionComplexToken | null { + // Get function declaration + const funcDecl = node.left; + if (!funcDecl || !isOperation(funcDecl, ASTOperation.FUNCTION_DECLARATION)) { + return null; + } + + // Get function identifier node + const funcIdent = funcDecl.left; + if (!funcIdent || !isOperation(funcIdent, ASTOperation.FUNCTION_IDENTIFIER)) { + return null; + } + + // Get function name from FUNCTION_IDENTIFIER node + const identifier = funcIdent.stringData; + if (!identifier) return null; + + // Position (convert from 1-indexed to 0-indexed) + const position = { + line: funcIdent.position.line - 1, + character: funcIdent.position.char, + }; + + // Extract return type from function identifier's left child + let returnType = "void"; + if (funcIdent.left) { + const typeStr = getTypeFromNode(funcIdent.left); + if (typeStr) returnType = typeStr; + } + + // Extract parameters + const params = extractFunctionParams(funcDecl); + + // Extract comments (not available in AST, would need separate tracking) + const comments: string[] = []; + + return { + position, + identifier, + tokenType: CompletionItemKind.Function, + returnType: returnType as any, + params, + comments, + }; +} + +/** + * Extract function parameters + */ +function extractFunctionParams(funcDeclNode: ASTNode | null): FunctionParamComplexToken[] { + const params: FunctionParamComplexToken[] = []; + + function findParams(node: ASTNode | null): void { + if (!node) return; + + if (isOperation(node, ASTOperation.FUNCTION_PARAM_NAME) && node.stringData) { + // Find the parameter type by looking at the right child + let paramType = "int"; // Default + + // The type is in the right child of FUNCTION_PARAM_NAME + if (node.right) { + const typeStr = getTypeFromNode(node.right); + if (typeStr) paramType = typeStr; + } + + const param: FunctionParamComplexToken = { + position: { + line: node.position.line - 1, + character: node.position.char, + }, + identifier: node.stringData, + tokenType: CompletionItemKind.TypeParameter, + valueType: paramType as any, + }; + + params.push(param); + } + + // Don't traverse into the right child if it's a type keyword + // to avoid processing it as a parameter + if (node.right && !node.right.operation.startsWith("KEYWORD_")) { + findParams(node.right); + } + + findParams(node.left); + } + + findParams(funcDeclNode); + return params; +} + +/** + * Extract struct definition + */ +function extractStruct(node: ASTNode): StructComplexToken | null { + // Find the KEYWORD_STRUCT node which has the struct name + const structNode = findFirstNode(node, ASTOperation.KEYWORD_STRUCT); + if (!structNode || !structNode.stringData) return null; + + const identifier = structNode.stringData; + const position = { + line: structNode.position.line - 1, + character: structNode.position.char, + }; + + // Extract properties from the struct body + const properties = extractStructProperties(node); + + return { + position, + identifier, + tokenType: CompletionItemKind.Struct, + properties, + }; +} + +/** + * Extract struct properties + */ +function extractStructProperties(structDefNode: ASTNode): StructPropertyComplexToken[] { + const properties: StructPropertyComplexToken[] = []; + + function traverse(node: ASTNode | null, depth: number = 0): void { + if (!node || depth > 50) return; // Prevent infinite recursion + + // Look for KEYWORD_DECLARATION nodes within the struct + if (isOperation(node, ASTOperation.KEYWORD_DECLARATION)) { + const prop = extractStructProperty(node); + if (prop) { + properties.push(prop); + } + } + + traverse(node.left, depth + 1); + traverse(node.right, depth + 1); + } + + traverse(structDefNode.right); // Properties are typically in the right subtree + return properties; +} + +/** + * Extract a single struct property + */ +function extractStructProperty(declNode: ASTNode): StructPropertyComplexToken | null { + // Get the type from the left child + let valueType = "int"; + if (declNode.left) { + const typeStr = getTypeFromNode(declNode.left); + if (typeStr) valueType = typeStr; + } + + // Get the variable name from the right child + const varList = declNode.right; + if (!varList) return null; + + const varNode = findFirstNode(varList, ASTOperation.VARIABLE); + if (!varNode || !varNode.stringData) return null; + + return { + position: { + line: varNode.position.line - 1, + character: varNode.position.char, + }, + identifier: varNode.stringData, + tokenType: CompletionItemKind.Property, + valueType: valueType as any, + }; +} + +/** + * Extract global variable declaration (treated as constant in NWScript) + */ +function extractGlobalVariable(declNode: ASTNode): ConstantComplexToken | null { + // For global variables, the KEYWORD_DECLARATION node has stringData with the variable name + const identifier = declNode.stringData; + if (!identifier) { + // Fallback: look for VARIABLE node + const varNode = findFirstNode(declNode.right, ASTOperation.VARIABLE); + if (!varNode || !varNode.stringData) return null; + + return extractGlobalVariableFromVarNode(declNode, varNode); + } + + // Get the type from the left child + let valueType = "int"; + if (declNode.left) { + const typeStr = getTypeFromNode(declNode.left); + if (typeStr) valueType = typeStr; + } + + // Get the value from assignment + let value: string | number = ""; + const assignNode = findFirstNode(declNode.right, ASTOperation.ASSIGNMENT); + if (assignNode) { + value = extractConstantValue(assignNode); + } + + return { + position: { + line: declNode.position.line - 1, + character: declNode.position.char, + }, + identifier, + tokenType: CompletionItemKind.Constant, + valueType: valueType as any, + value, + }; +} + +/** + * Extract global variable from a VARIABLE node + */ +function extractGlobalVariableFromVarNode(declNode: ASTNode, varNode: ASTNode): ConstantComplexToken | null { + // Get the type + let valueType = "int"; + if (declNode.left) { + const typeStr = getTypeFromNode(declNode.left); + if (typeStr) valueType = typeStr; + } + + // Get the value from assignment + let value: string | number = ""; + const assignNode = findFirstNode(declNode.right, ASTOperation.ASSIGNMENT); + if (assignNode) { + value = extractConstantValue(assignNode); + } + + return { + position: { + line: varNode.position.line - 1, + character: varNode.position.char, + }, + identifier: varNode.stringData!, + tokenType: CompletionItemKind.Constant, + valueType: valueType as any, + value, + }; +} + +/** + * Extract constant declaration (with explicit const keyword) + */ +function extractConstant(declNode: ASTNode): ConstantComplexToken | null { + // Check if this is a const declaration + if (!declNode.left || !isOperation(declNode.left, ASTOperation.KEYWORD_CONST)) { + return null; + } + + // Find the variable name + const varNode = findFirstNode(declNode.right, ASTOperation.VARIABLE); + if (!varNode || !varNode.stringData) return null; + + // Get the type + let valueType = "int"; + const typeNode = findFirstNode(declNode.left?.right, "KEYWORD_"); + if (typeNode) { + const typeStr = getTypeFromNode(typeNode); + if (typeStr) valueType = typeStr; + } + + // Get the value from assignment + let value: string | number = ""; + const assignNode = findFirstNode(declNode.right, ASTOperation.ASSIGNMENT); + if (assignNode) { + value = extractConstantValue(assignNode); + } + + return { + position: { + line: varNode.position.line - 1, + character: varNode.position.char, + }, + identifier: varNode.stringData, + tokenType: CompletionItemKind.Constant, + valueType: valueType as any, + value, + }; +} + +/** + * Extract constant value from assignment node + */ +function extractConstantValue(assignNode: ASTNode): string | number { + const constantNode = findFirstNode(assignNode, "CONSTANT_"); + + if (!constantNode) return ""; + + if (isOperation(constantNode, ASTOperation.CONSTANT_INTEGER)) { + return constantNode.integerData?.[0] ?? 0; + } + + if (isOperation(constantNode, ASTOperation.CONSTANT_FLOAT)) { + return constantNode.floatData ?? 0.0; + } + + if (isOperation(constantNode, ASTOperation.CONSTANT_STRING)) { + return constantNode.stringData ?? ""; + } + + return ""; +} + +/** + * Find first node matching operation (supports prefix matching with _) + */ +function findFirstNode(node: ASTNode | null, operation: string): ASTNode | null { + if (!node) return null; + + const isPrefix = operation.endsWith("_"); + const matches = isPrefix ? node.operation.startsWith(operation) : node.operation === operation; + + if (matches) return node; + + return findFirstNode(node.left, operation) || findFirstNode(node.right, operation); +} + +/** + * Extract local scope tokens (functions and variables within a scope) + */ +export function extractLocalTokens( + ast: AST, + startLine: number, + endLine: number, +): { + functionsComplexTokens: FunctionComplexToken[]; + functionVariablesComplexTokens: (VariableComplexToken | FunctionParamComplexToken)[]; +} { + const functionsComplexTokens: FunctionComplexToken[] = []; + const functionVariablesComplexTokens: (VariableComplexToken | FunctionParamComplexToken)[] = []; + + function traverse(node: ASTNode | null): void { + if (!node) return; + + const nodeLine = node.position.line - 1; + + // Only process nodes within the specified line range + if (nodeLine < startLine || nodeLine > endLine) { + // But still traverse children in case they're in range + traverse(node.left); + traverse(node.right); + return; + } + + // Extract function declarations (local functions) + if (isOperation(node, ASTOperation.FUNCTION)) { + const func = extractFunction(node); + if (func && func.position.line >= startLine && func.position.line <= endLine) { + functionsComplexTokens.push(func); + } + } + + // Extract local variables + if (isOperation(node, ASTOperation.KEYWORD_DECLARATION)) { + const variables = extractLocalVariables(node); + variables.forEach((v) => { + if (v.position.line >= startLine && v.position.line <= endLine) { + functionVariablesComplexTokens.push(v); + } + }); + } + + // Extract function parameters + if (isOperation(node, ASTOperation.FUNCTION_PARAM_NAME) && node.stringData) { + const param = extractFunctionParam(node); + if (param && param.position.line >= startLine && param.position.line <= endLine) { + functionVariablesComplexTokens.push(param); + } + } + + traverse(node.left); + traverse(node.right); + } + + traverse(ast.ast); + + return { + functionsComplexTokens, + functionVariablesComplexTokens, + }; +} + +/** + * Extract local variables from a declaration node + */ +function extractLocalVariables(declNode: ASTNode): VariableComplexToken[] { + const variables: VariableComplexToken[] = []; + + // Get the type + let valueType = "int"; + if (declNode.left) { + const typeStr = getTypeFromNode(declNode.left); + if (typeStr) valueType = typeStr; + } + + // Find all variable nodes in the right subtree + function findVariables(node: ASTNode | null): void { + if (!node) return; + + if (isOperation(node, ASTOperation.VARIABLE) && node.stringData) { + variables.push({ + position: { + line: node.position.line - 1, + character: node.position.char, + }, + identifier: node.stringData, + tokenType: CompletionItemKind.Variable, + valueType: valueType as any, + }); + } + + findVariables(node.left); + findVariables(node.right); + } + + findVariables(declNode.right); + return variables; +} + +/** + * Extract a function parameter + */ +function extractFunctionParam(paramNode: ASTNode): FunctionParamComplexToken | null { + if (!paramNode.stringData) return null; + + let valueType = "int"; + if (paramNode.right) { + const typeStr = getTypeFromNode(paramNode.right); + if (typeStr) valueType = typeStr; + } + + return { + position: { + line: paramNode.position.line - 1, + character: paramNode.position.char, + }, + identifier: paramNode.stringData, + tokenType: CompletionItemKind.TypeParameter, + valueType: valueType as any, + }; +} diff --git a/server/src/Parser/ASTTypes.ts b/server/src/Parser/ASTTypes.ts new file mode 100644 index 0000000..98b3114 --- /dev/null +++ b/server/src/Parser/ASTTypes.ts @@ -0,0 +1,131 @@ +/** + * TypeScript definitions for NWScript AST + * Generated from the WASM compiler"s JSON export + */ + +export type ASTPosition = { + file: number; + line: number; + char: number; +}; + +export type ASTNode = { + operation: string; + operationId: number; + position: ASTPosition; + + // Optional data fields + stringData?: string; + integerData?: number[]; + floatData?: number; + vectorData?: number[]; + + // Type information + type?: string; + typeId?: number; + typeName?: string; + + // Stack information + stackPointer?: number; + + // Child nodes + left: ASTNode | null; + right: ASTNode | null; +}; + +export type AST = { + version: number; + ast: ASTNode; +}; + +/** + * Common AST operation types used in tokenization + */ +export enum ASTOperation { + // Top level + FUNCTIONAL_UNIT = "FUNCTIONAL_UNIT", + GLOBAL_VARIABLES = "GLOBAL_VARIABLES", + + // Functions + FUNCTION = "FUNCTION", + FUNCTION_DECLARATION = "FUNCTION_DECLARATION", + FUNCTION_IDENTIFIER = "FUNCTION_IDENTIFIER", + FUNCTION_PARAM_NAME = "FUNCTION_PARAM_NAME", + + // Structures + STRUCTURE_DEFINITION = "STRUCTURE_DEFINITION", + KEYWORD_STRUCT = "KEYWORD_STRUCT", + + // Variables and constants + VARIABLE = "VARIABLE", + VARIABLE_LIST = "VARIABLE_LIST", + KEYWORD_DECLARATION = "KEYWORD_DECLARATION", + KEYWORD_CONST = "KEYWORD_CONST", + + // Statements + STATEMENT = "STATEMENT", + STATEMENT_LIST = "STATEMENT_LIST", + COMPOUND_STATEMENT = "COMPOUND_STATEMENT", + + // Types + KEYWORD_INT = "KEYWORD_INT", + KEYWORD_FLOAT = "KEYWORD_FLOAT", + KEYWORD_STRING = "KEYWORD_STRING", + KEYWORD_OBJECT = "KEYWORD_OBJECT", + KEYWORD_VOID = "KEYWORD_VOID", + KEYWORD_VECTOR = "KEYWORD_VECTOR", + KEYWORD_ACTION = "KEYWORD_ACTION", + KEYWORD_EFFECT = "KEYWORD_EFFECT", + KEYWORD_EVENT = "KEYWORD_EVENT", + KEYWORD_LOCATION = "KEYWORD_LOCATION", + KEYWORD_TALENT = "KEYWORD_TALENT", + KEYWORD_ITEMPROPERTY = "KEYWORD_ITEMPROPERTY", + KEYWORD_JSON = "KEYWORD_JSON", + KEYWORD_SQLQUERY = "KEYWORD_SQLQUERY", + KEYWORD_CASSOWARY = "KEYWORD_CASSOWARY", + + // Constants + CONSTANT_INTEGER = "CONSTANT_INTEGER", + CONSTANT_FLOAT = "CONSTANT_FLOAT", + CONSTANT_STRING = "CONSTANT_STRING", + CONSTANT_OBJECT = "CONSTANT_OBJECT", + + // Expressions + ASSIGNMENT = "ASSIGNMENT", + NON_VOID_EXPRESSION = "NON_VOID_EXPRESSION", + + // Control flow + IF_BLOCK = "IF_BLOCK", + WHILE_BLOCK = "WHILE_BLOCK", + FOR_BLOCK = "FOR_BLOCK", + SWITCH_BLOCK = "SWITCH_BLOCK", + + // Others + INCLUDE_DIRECTIVE = "INCLUDE_DIRECTIVE", +} + +/** + * Helper to check if a node is a specific operation + */ +export function isOperation(node: ASTNode | null, operation: ASTOperation | string): boolean { + return node?.operation === operation; +} + +/** + * Helper to get the type string from a type node + */ +export function getTypeFromNode(node: ASTNode | null): string | undefined { + if (!node) return undefined; + + // Check if it"s a keyword type + if (node.operation.startsWith("KEYWORD_")) { + return node.operation.replace("KEYWORD_", "").toLowerCase(); + } + + // Check if it"s a struct type (has stringData with the struct name) + if (node.operation === "KEYWORD_STRUCT" && node.stringData) { + return node.stringData; + } + + return node.stringData || node.typeName; +} diff --git a/server/src/Parser/NWScriptParser.ts b/server/src/Parser/NWScriptParser.ts new file mode 100644 index 0000000..cade2b8 --- /dev/null +++ b/server/src/Parser/NWScriptParser.ts @@ -0,0 +1,232 @@ +import { join } from "path"; +import type { AST, ASTNode } from "./ASTTypes"; + +/** + * WebAssembly-based NWScript parser + * Uses the official NWScript compiler to generate AST + */ +export class NWScriptParser { + private module: any = null; + private initialized: boolean = false; + + /** + * Initialize the WASM module + */ + async initialize(): Promise { + if (this.initialized) return; + + const wasmPath = join(__dirname, "..", "..", "wasm", "nwscript_compiler.js"); + // eslint-disable-next-line @typescript-eslint/no-var-requires + const NWScriptCompiler = require(wasmPath); + this.module = await NWScriptCompiler(); + this.initialized = true; + } + + /** + * Parse NWScript content and return the AST + * @param content The NWScript source code + * @param filename The name of the file being parsed (without extension) + * @param includes Map of include filenames to their content + * @returns The parsed AST or null if compilation failed + */ + async parse(content: string, filename: string = "script", includes: Map = new Map()): Promise<{ ast: AST | null; errors: string[] }> { + if (!this.initialized) { + await this.initialize(); + } + + const errors: string[] = []; + let compilerPtr: number | null = null; + + try { + // Minimal NWScript specification + const nwscriptSpec = this.getMinimalNWScriptSpec(); + const nwnxStub = this.getNWNXStub(); + + // File resolver callback + const resolverPtr = this.module.addFunction((filenamePtr: number, resType: number) => { + try { + const requestedFile = this.module.UTF8ToString(filenamePtr); + let fileContent: string; + + if (requestedFile === "nwscript") { + fileContent = nwscriptSpec; + } else if (requestedFile === "nwnx") { + fileContent = nwnxStub; + } else if (includes.has(requestedFile)) { + fileContent = includes.get(requestedFile)!; + } else if (requestedFile === filename) { + fileContent = content; + } else { + // Return empty content for unknown includes + fileContent = "// Include stub"; + } + + const contentLen = this.module.lengthBytesUTF8(fileContent); + // eslint-disable-next-line @typescript-eslint/restrict-plus-operands + const contentPtr = this.module._malloc(contentLen + 1); + // eslint-disable-next-line @typescript-eslint/restrict-plus-operands + this.module.stringToUTF8(fileContent, contentPtr, contentLen + 1); + + this.module.ccall("scriptCompApiDeliverFile", null, ["number", "number", "number"], [compilerPtr, contentPtr, contentLen]); + + this.module._free(contentPtr); + return 1; // Success + } catch (error) { + console.error("File resolver error:", error); + return 0; // Failure + } + }, "iii"); + + // Writer callback (not used for AST extraction) + const writerPtr = this.module.addFunction(() => 0, "iiiiii"); + + // Create compiler instance + const newCompiler = this.module.cwrap("scriptCompApiNewCompiler", "number", ["number", "number", "number", "number", "number"]); + compilerPtr = newCompiler(2009, 2010, 2064, writerPtr, resolverPtr); + + // Initialize compiler + const initCompiler = this.module.cwrap("scriptCompApiInitCompiler", null, ["number", "string", "boolean", "number", "string", "string"]); + initCompiler(compilerPtr, "nwscript", false, 16, "", "scriptout"); + + // Compile the script + const compileFileSimple = this.module.cwrap("scriptCompApiCompileFileSimple", "number", ["number", "string"]); + const resultCode = compileFileSimple(compilerPtr, filename); + + if (resultCode !== 0) { + const getLastError = this.module.cwrap("scriptCompApiGetLastError", "string", ["number"]); + const error = getLastError(compilerPtr); + errors.push(error); + + // Cleanup and return null AST + const destroyCompiler = this.module.cwrap("scriptCompApiDestroyCompiler", null, ["number"]); + destroyCompiler(compilerPtr); + + return { ast: null, errors }; + } + + // Get the AST as JSON + const getParseTreeJSON = this.module.cwrap("scriptCompApiGetParseTreeJSON", "string", ["number"]); + const jsonStr = getParseTreeJSON(compilerPtr); + + if (!jsonStr) { + errors.push("Failed to get parse tree JSON"); + return { ast: null, errors }; + } + + const ast: AST = JSON.parse(jsonStr); + + // Cleanup + const destroyCompiler = this.module.cwrap("scriptCompApiDestroyCompiler", null, ["number"]); + destroyCompiler(compilerPtr); + + return { ast, errors: [] }; + } catch (error) { + errors.push(`Parser error: ${String(error)}`); + return { ast: null, errors }; + } + } + + /** + * Get minimal NWScript specification required for compilation + */ + private getMinimalNWScriptSpec(): string { + return ` +#define ENGINE_NUM_STRUCTURES 0 + +int TRUE = 1; +int FALSE = 0; + +// Common string functions +int GetStringLength(string s) { return 0; } +string GetStringRight(string s, int n) { return ""; } +string GetStringLeft(string s, int n) { return ""; } +int FindSubString(string s, string sub) { return -1; } +string GetSubString(string s, int start, int count) { return ""; } +string IntToString(int n) { return ""; } +int StringToInt(string s) { return 0; } +string FloatToString(float f, int width, int decimals) { return ""; } +float StringToFloat(string s) { return 0.0; } + +// Common object functions +object GetFirstPC() { return OBJECT_INVALID; } +object GetNextPC() { return OBJECT_INVALID; } +object OBJECT_INVALID = 0; +object OBJECT_SELF = 1; + +// Common utility functions +void PrintString(string s) {} +void PrintInteger(int n) {} +void PrintFloat(float f) {} +`; + } + + /** + * Get NWNX stub functions + */ + private getNWNXStub(): string { + return ` +// NWNX stub functions for parsing +void NWNX_PushArgumentInt(int i) {} +void NWNX_PushArgumentFloat(float f) {} +void NWNX_PushArgumentString(string s) {} +void NWNX_PushArgumentObject(object o) {} +void NWNX_CallFunction(string plugin, string func) {} +int NWNX_GetReturnValueInt() { return 0; } +float NWNX_GetReturnValueFloat() { return 0.0; } +string NWNX_GetReturnValueString() { return ""; } +object NWNX_GetReturnValueObject() { return OBJECT_INVALID; } +`; + } + + /** + * Find a node at a specific position + * @param ast The root AST node + * @param line Line number (0-indexed in TypeScript, 1-indexed in AST) + * @param character Character position + * @returns The node at the position or null + */ + findNodeAtPosition(ast: ASTNode, line: number, character: number): ASTNode | null { + const targetLine = line + 1; // Convert to 1-indexed + + function traverse(node: ASTNode | null): ASTNode | null { + if (!node) return null; + + // Check if this node contains the position + if (node.position.line === targetLine && node.position.char <= character) { + // This node might be it, but check children first for more specific match + const leftResult = traverse(node.left); + if (leftResult) return leftResult; + + const rightResult = traverse(node.right); + if (rightResult) return rightResult; + + // No better match in children, return this node + return node; + } + + // Check children even if this node doesn"t match + const leftResult = traverse(node.left); + if (leftResult) return leftResult; + + return traverse(node.right); + } + + return traverse(ast); + } +} + +/** + * Singleton instance of the parser + */ +let parserInstance: NWScriptParser | null = null; + +/** + * Get the singleton parser instance + */ +export async function getParser(): Promise { + if (!parserInstance) { + parserInstance = new NWScriptParser(); + await parserInstance.initialize(); + } + return parserInstance; +} diff --git a/server/src/Providers/Builders/Builder.ts b/server/src/Providers/Builders/Builder.ts index b7bd9f2..3836e66 100644 --- a/server/src/Providers/Builders/Builder.ts +++ b/server/src/Providers/Builders/Builder.ts @@ -1,15 +1,7 @@ import { CompletionItemKind } from "vscode-languageserver"; import { LanguageTypes } from "../../Tokenizer/constants"; -import type { - ComplexToken, - ConstantComplexToken, - VariableComplexToken, - FunctionParamComplexToken, - FunctionComplexToken, - StructPropertyComplexToken, - StructComplexToken, -} from "../../Tokenizer/types"; +import type { ComplexToken, ConstantComplexToken, VariableComplexToken, FunctionParamComplexToken, FunctionComplexToken, StructPropertyComplexToken, StructComplexToken } from "../../Tokenizer/types"; export default abstract class Builder { protected static handleLanguageType(type: string) { diff --git a/server/src/Providers/Builders/CompletionItemBuilder.ts b/server/src/Providers/Builders/CompletionItemBuilder.ts index 9a54de9..142fdfd 100644 --- a/server/src/Providers/Builders/CompletionItemBuilder.ts +++ b/server/src/Providers/Builders/CompletionItemBuilder.ts @@ -1,14 +1,6 @@ import { CompletionItem, CompletionItemKind } from "vscode-languageserver"; -import type { - ComplexToken, - ConstantComplexToken, - FunctionComplexToken, - FunctionParamComplexToken, - StructComplexToken, - StructPropertyComplexToken, - VariableComplexToken, -} from "../../Tokenizer/types"; +import type { ComplexToken, ConstantComplexToken, FunctionComplexToken, FunctionParamComplexToken, StructComplexToken, StructPropertyComplexToken, VariableComplexToken } from "../../Tokenizer/types"; import { ServerConfiguration } from "../../ServerManager/Config"; import Builder from "./Builder"; @@ -19,9 +11,7 @@ export default class CompletionItemBuilder extends Builder { return { label: `${item.label}(${params.reduce((acc, param, index) => { - return `${acc}${this.handleLanguageType(param.valueType)} ${param.identifier}${ - index === params.length - 1 ? "" : ", " - }`; + return `${acc}${this.handleLanguageType(param.valueType)} ${param.identifier}${index === params.length - 1 ? "" : ", "}`; }, "")})`, kind: item.kind, detail: item.detail, @@ -80,9 +70,7 @@ export default class CompletionItemBuilder extends Builder { label: token.identifier, kind: token.tokenType, detail: `(method) (${token.params.reduce((acc, param, index) => { - return `${acc}${param.identifier}: ${this.handleLanguageType(param.valueType)}${ - index === token.params.length - 1 ? "" : ", " - }`; + return `${acc}${param.identifier}: ${this.handleLanguageType(param.valueType)}${index === token.params.length - 1 ? "" : ", "}`; }, "")}): ${this.handleLanguageType(token.returnType)}`, data: token.params, }; diff --git a/server/src/Providers/Builders/HoverContentBuilder.ts b/server/src/Providers/Builders/HoverContentBuilder.ts index b26ff1e..699cdf2 100644 --- a/server/src/Providers/Builders/HoverContentBuilder.ts +++ b/server/src/Providers/Builders/HoverContentBuilder.ts @@ -1,14 +1,6 @@ import { MarkupContent, MarkupKind } from "vscode-languageserver"; -import type { - ComplexToken, - ConstantComplexToken, - FunctionComplexToken, - FunctionParamComplexToken, - StructComplexToken, - StructPropertyComplexToken, - VariableComplexToken, -} from "../../Tokenizer/types"; +import type { ComplexToken, ConstantComplexToken, FunctionComplexToken, FunctionParamComplexToken, StructComplexToken, StructPropertyComplexToken, VariableComplexToken } from "../../Tokenizer/types"; import { ServerConfiguration } from "../../ServerManager/Config"; import Builder from "./Builder"; @@ -47,9 +39,7 @@ export default class HoverContentBuilder extends Builder { return this.buildMarkdown( [ `${this.handleLanguageType(token.returnType)} ${token.identifier}(${token.params.reduce((acc, param, index) => { - return `${acc}${this.handleLanguageType(param.valueType)} ${param.identifier}${ - param.defaultValue ? ` = ${param.defaultValue}` : "" - }${index === token.params.length - 1 ? "" : ", "}`; + return `${acc}${this.handleLanguageType(param.valueType)} ${param.identifier}${param.defaultValue ? ` = ${param.defaultValue}` : ""}${index === token.params.length - 1 ? "" : ", "}`; }, "")})`, ], serverConfig.hovering.addCommentsToFunctions ? ["```nwscript", ...token.comments, "```"] : [], @@ -62,12 +52,7 @@ export default class HoverContentBuilder extends Builder { } private static buildStructItem(token: StructComplexToken) { - return this.buildMarkdown([ - `struct ${token.identifier}`, - "{", - ...token.properties.map((property) => `\t${property.valueType} ${property.identifier}`), - "}", - ]); + return this.buildMarkdown([`struct ${token.identifier}`, "{", ...token.properties.map((property) => `\t${property.valueType} ${property.identifier}`), "}"]); } private static buildMarkdown(content: string[] | string, prepend: string[] = [], postpend: string[] = []) { diff --git a/server/src/Providers/Builders/SignatureHelpBuilder.ts b/server/src/Providers/Builders/SignatureHelpBuilder.ts index 798396d..7a4e3b5 100644 --- a/server/src/Providers/Builders/SignatureHelpBuilder.ts +++ b/server/src/Providers/Builders/SignatureHelpBuilder.ts @@ -9,18 +9,14 @@ export default class SignatureHelpBuilder extends Builder { signatures: [ SignatureInformation.create( `${this.handleLanguageType(token.returnType)} ${token.identifier}(${token.params.reduce((acc, param, index) => { - return `${acc}${this.handleLanguageType(param.valueType)} ${param.identifier}${ - index === token.params.length - 1 ? "" : ", " - }`; + return `${acc}${this.handleLanguageType(param.valueType)} ${param.identifier}${index === token.params.length - 1 ? "" : ", "}`; }, "")})`, undefined, - ...token.params.map((param) => - ParameterInformation.create(`${param.valueType} ${param.identifier}`), - ), + ...token.params.map((param) => ParameterInformation.create(`${param.valueType} ${param.identifier}`)), ), ], activeSignature: 0, - activeParameter: activeParameter || null, + activeParameter, }; } } diff --git a/server/src/Providers/Builders/SymbolBuilder.ts b/server/src/Providers/Builders/SymbolBuilder.ts index 36f9f8a..b0342eb 100644 --- a/server/src/Providers/Builders/SymbolBuilder.ts +++ b/server/src/Providers/Builders/SymbolBuilder.ts @@ -1,14 +1,6 @@ import { DocumentSymbol, SymbolKind } from "vscode-languageserver"; -import type { - ComplexToken, - ConstantComplexToken, - FunctionComplexToken, - FunctionParamComplexToken, - StructComplexToken, - StructPropertyComplexToken, - VariableComplexToken, -} from "../../Tokenizer/types"; +import type { ComplexToken, ConstantComplexToken, FunctionComplexToken, FunctionParamComplexToken, StructComplexToken, StructPropertyComplexToken, VariableComplexToken } from "../../Tokenizer/types"; import Builder from "./Builder"; export default class SymbolBuilder extends Builder { @@ -31,33 +23,15 @@ export default class SymbolBuilder extends Builder { } private static buildConstantItem(token: ConstantComplexToken) { - return DocumentSymbol.create( - token.identifier, - undefined, - SymbolKind.Constant, - { start: token.position, end: token.position }, - { start: token.position, end: token.position }, - ); + return DocumentSymbol.create(token.identifier, undefined, SymbolKind.Constant, { start: token.position, end: token.position }, { start: token.position, end: token.position }); } private static buildVariableItem(token: VariableComplexToken) { - return DocumentSymbol.create( - token.identifier, - undefined, - SymbolKind.Variable, - { start: token.position, end: token.position }, - { start: token.position, end: token.position }, - ); + return DocumentSymbol.create(token.identifier, undefined, SymbolKind.Variable, { start: token.position, end: token.position }, { start: token.position, end: token.position }); } private static buildFunctionParamItem(token: FunctionParamComplexToken) { - return DocumentSymbol.create( - token.identifier, - undefined, - SymbolKind.TypeParameter, - { start: token.position, end: token.position }, - { start: token.position, end: token.position }, - ); + return DocumentSymbol.create(token.identifier, undefined, SymbolKind.TypeParameter, { start: token.position, end: token.position }, { start: token.position, end: token.position }); } private static buildFunctionItem(token: FunctionComplexToken) { @@ -75,25 +49,12 @@ export default class SymbolBuilder extends Builder { } private static buildStructPropertyItem(token: StructPropertyComplexToken) { - return DocumentSymbol.create( - token.identifier, - undefined, - SymbolKind.Property, - { start: token.position, end: token.position }, - { start: token.position, end: token.position }, - ); + return DocumentSymbol.create(token.identifier, undefined, SymbolKind.Property, { start: token.position, end: token.position }, { start: token.position, end: token.position }); } private static buildStructItem(token: StructComplexToken) { const symbols = token.properties?.map((child) => SymbolBuilder.buildItem(child)); - return DocumentSymbol.create( - token.identifier, - undefined, - SymbolKind.Struct, - { start: token.position, end: token.position }, - { start: token.position, end: token.position }, - symbols, - ); + return DocumentSymbol.create(token.identifier, undefined, SymbolKind.Struct, { start: token.position, end: token.position }, { start: token.position, end: token.position }, symbols); } } diff --git a/server/src/Providers/CompletionItemsProvider.ts b/server/src/Providers/CompletionItemsProvider.ts index 7cbe252..00ba5c9 100644 --- a/server/src/Providers/CompletionItemsProvider.ts +++ b/server/src/Providers/CompletionItemsProvider.ts @@ -2,7 +2,7 @@ import { CompletionParams } from "vscode-languageserver"; import type { ServerManager } from "../ServerManager"; import { CompletionItemBuilder } from "./Builders"; -import { LocalScopeTokenizationResult } from "../Tokenizer/Tokenizer"; +import { LocalScopeTokenizationResult, TokenizedScope } from "../Tokenizer/Tokenizer"; import { TriggerCharacters } from "."; import { Document } from "../Documents"; import { LanguageTypes } from "../Tokenizer/constants"; @@ -17,7 +17,7 @@ export default class CompletionItemsProvider extends Provider { } private providerHandler(params: CompletionParams) { - return () => { + return async () => { const { textDocument: { uri }, position, @@ -27,11 +27,11 @@ export default class CompletionItemsProvider extends Provider { const document = this.server.documentsCollection.getFromUri(uri); if (!liveDocument || !document) return; - const [lines, rawTokenizedContent] = this.server.tokenizer.tokenizeContentToRaw(liveDocument.getText()); - const localScope = this.server.tokenizer.tokenizeContentFromRaw(lines, rawTokenizedContent, 0, position.line); + const content = liveDocument.getText(); + const localScope = await this.server.tokenizer.tokenizeContent(content, TokenizedScope.local, 0, position.line); if (params.context?.triggerCharacter === TriggerCharacters.dot) { - const { rawContent } = this.server.tokenizer.getActionTargetAtPosition(lines, rawTokenizedContent, position, -1); + const { rawContent } = await this.server.tokenizer.getActionTargetAtPositionAST(content, position, -1); const structIdentifer = localScope.functionVariablesComplexTokens.find((token) => token.identifier === rawContent)?.valueType; return document @@ -42,7 +42,8 @@ export default class CompletionItemsProvider extends Provider { }); } - if (this.server.tokenizer.getActionTargetAtPosition(lines, rawTokenizedContent, position, -2).rawContent === LanguageTypes.struct) { + const checkStruct = await this.server.tokenizer.getActionTargetAtPositionAST(content, position, -2); + if (checkStruct.rawContent === LanguageTypes.struct) { return document.getGlobalStructComplexTokens().map((token) => CompletionItemBuilder.buildItem(token)); } diff --git a/server/src/Providers/DiagnosticsProvider.ts b/server/src/Providers/DiagnosticsProvider.ts index 36b54d6..7295e7a 100644 --- a/server/src/Providers/DiagnosticsProvider.ts +++ b/server/src/Providers/DiagnosticsProvider.ts @@ -4,7 +4,6 @@ import { join, dirname, basename } from "path"; import { fileURLToPath } from "url"; import { Diagnostic, DiagnosticSeverity } from "vscode-languageserver"; -import { ServerManager } from "../ServerManager"; import Provider from "./Provider"; const lineNumber = /\(([^)]+)\)/; @@ -19,10 +18,6 @@ enum OS { type FilesDiagnostics = { [uri: string]: Diagnostic[] }; export default class DiagnoticsProvider extends Provider { - constructor(server: ServerManager) { - super(server); - } - private generateDiagnostics(uris: string[], files: FilesDiagnostics, severity: DiagnosticSeverity) { return (line: string) => { const uri = uris.find((uri) => basename(fileURLToPath(uri)) === lineFilename.exec(line)![0]); @@ -62,6 +57,7 @@ export default class DiagnoticsProvider extends Provider { } } + // eslint-disable-next-line @typescript-eslint/promise-function-async public publish(uri: string) { return new Promise((resolve, reject) => { const { enabled, nwnHome, reportWarnings, nwnInstallation, verbose, os } = this.server.config.compiler; @@ -166,24 +162,16 @@ export default class DiagnoticsProvider extends Provider { // Actual errors if (line.includes("NOTFOUND")) { - return this.server.logger.error( - "Unable to resolve nwscript.nss. Are your Neverwinter Nights home and/or installation directories valid?", - ); + return this.server.logger.error("Unable to resolve nwscript.nss. Are your Neverwinter Nights home and/or installation directories valid?"); } if (line.includes("Failed to open .key archive")) { - return this.server.logger.error( - "Unable to open nwn_base.key Is your Neverwinter Nights installation directory valid?", - ); + return this.server.logger.error("Unable to open nwn_base.key Is your Neverwinter Nights installation directory valid?"); } if (line.includes("Unable to read input file")) { if (Boolean(nwnHome) || Boolean(nwnInstallation)) { - return this.server.logger.error( - "Unable to resolve provided Neverwinter Nights home and/or installation directories. Ensure the paths are valid in the extension settings.", - ); + return this.server.logger.error("Unable to resolve provided Neverwinter Nights home and/or installation directories. Ensure the paths are valid in the extension settings."); } else { - return this.server.logger.error( - "Unable to automatically resolve Neverwinter Nights home and/or installation directories.", - ); + return this.server.logger.error("Unable to automatically resolve Neverwinter Nights home and/or installation directories."); } } }); @@ -197,7 +185,7 @@ export default class DiagnoticsProvider extends Provider { if (reportWarnings) warnings.forEach(this.generateDiagnostics(uris, files, DiagnosticSeverity.Warning)); for (const [uri, diagnostics] of Object.entries(files)) { - this.server.connection.sendDiagnostics({ uri, diagnostics }); + void this.server.connection.sendDiagnostics({ uri, diagnostics }); } resolve(true); }); diff --git a/server/src/Providers/GotoDefinitionProvider.ts b/server/src/Providers/GotoDefinitionProvider.ts index 86e8900..8213924 100644 --- a/server/src/Providers/GotoDefinitionProvider.ts +++ b/server/src/Providers/GotoDefinitionProvider.ts @@ -6,6 +6,7 @@ import type { ServerManager } from "../ServerManager"; import type { ComplexToken } from "../Tokenizer/types"; import { Document } from "../Documents"; import Provider from "./Provider"; +import { TokenizedScope } from "../Tokenizer/Tokenizer"; export default class GotoDefinitionProvider extends Provider { constructor(server: ServerManager) { @@ -15,7 +16,7 @@ export default class GotoDefinitionProvider extends Provider { } private providerHandler(params: DefinitionParams) { - return () => { + return async () => { const { textDocument: { uri }, position, @@ -25,7 +26,7 @@ export default class GotoDefinitionProvider extends Provider { const document = this.server.documentsCollection.getFromUri(uri); if (!liveDocument || !document) return; - const [token, ref] = this.resolveTokenAndRef(position, document, liveDocument); + const [token, ref] = await this.resolveTokenAndRef(position, document, liveDocument); if (token) { if (ref && !ref.owner) { @@ -49,18 +50,22 @@ export default class GotoDefinitionProvider extends Provider { }; } - private resolveTokenAndRef(position: Position, document: Document, liveDocument: TextDocument): [token: ComplexToken | undefined, ref: OwnedComplexTokens | OwnedStructComplexTokens | undefined] { + private async resolveTokenAndRef( + position: Position, + document: Document, + liveDocument: TextDocument, + ): Promise<[token: ComplexToken | undefined, ref: OwnedComplexTokens | OwnedStructComplexTokens | undefined]> { let tokensWithRef; let token: ComplexToken | undefined; let ref: OwnedComplexTokens | OwnedStructComplexTokens | undefined; - const [lines, rawTokenizedContent] = this.server.tokenizer.tokenizeContentToRaw(liveDocument.getText()); - const localScope = this.server.tokenizer.tokenizeContentFromRaw(lines, rawTokenizedContent, 0, position.line); - const { tokenType, lookBehindRawContent, rawContent } = this.server.tokenizer.getActionTargetAtPosition(lines, rawTokenizedContent, position); + const content = liveDocument.getText(); + const localScope = await this.server.tokenizer.tokenizeContent(content, TokenizedScope.local, 0, position.line); + const { tokenType, lookBehindRawContent, rawContent } = await this.server.tokenizer.getActionTargetAtPositionAST(content, position); switch (tokenType) { case CompletionItemKind.Function: - case CompletionItemKind.Constant: + case CompletionItemKind.Constant: { token = localScope.functionsComplexTokens.find((candidate) => candidate.identifier === rawContent); if (token) break; @@ -71,40 +76,43 @@ export default class GotoDefinitionProvider extends Provider { tokensWithRef.push({ owner: localStandardLibDefinitions?.uri, tokens: localStandardLibDefinitions?.complexTokens }); } - loop: for (let i = 0; i < tokensWithRef.length; i++) { + for (let i = 0; i < tokensWithRef.length; i++) { ref = tokensWithRef[i]; token = ref?.tokens.find((candidate) => candidate.identifier === rawContent); if (token) { - break loop; + break; } } break; - case CompletionItemKind.Struct: + } + case CompletionItemKind.Struct: { tokensWithRef = document.getGlobalStructComplexTokensWithRef(); - loop: for (let i = 0; i < tokensWithRef.length; i++) { + for (let i = 0; i < tokensWithRef.length; i++) { ref = tokensWithRef[i]; token = ref?.tokens.find((candidate) => candidate.identifier === rawContent); if (token) { - break loop; + break; } } break; - case CompletionItemKind.Property: + } + case CompletionItemKind.Property: { const structIdentifer = localScope.functionVariablesComplexTokens.find((candidate) => candidate.identifier === lookBehindRawContent)?.valueType; tokensWithRef = document.getGlobalStructComplexTokensWithRef(); - loop: for (let i = 0; i < tokensWithRef.length; i++) { + for (let i = 0; i < tokensWithRef.length; i++) { ref = tokensWithRef[i]; token = (ref as OwnedStructComplexTokens).tokens.find((candidate) => candidate.identifier === structIdentifer)?.properties.find((property) => property.identifier === rawContent); if (token) { - break loop; + break; } } break; + } default: token = localScope.functionVariablesComplexTokens.find((candidate) => candidate.identifier === rawContent); } diff --git a/server/src/Providers/HoverContentProvider.ts b/server/src/Providers/HoverContentProvider.ts index 151b9f3..08fe1ee 100644 --- a/server/src/Providers/HoverContentProvider.ts +++ b/server/src/Providers/HoverContentProvider.ts @@ -6,6 +6,7 @@ import type { ComplexToken } from "../Tokenizer/types"; import { HoverContentBuilder } from "./Builders"; import { Document } from "../Documents"; import Provider from "./Provider"; +import { TokenizedScope } from "../Tokenizer/Tokenizer"; export default class HoverContentProvider extends Provider { constructor(server: ServerManager) { @@ -15,7 +16,7 @@ export default class HoverContentProvider extends Provider { } private providerHandler(params: HoverParams) { - return () => { + return async () => { const { textDocument: { uri }, position, @@ -25,7 +26,7 @@ export default class HoverContentProvider extends Provider { const document = this.server.documentsCollection.getFromUri(uri); if (!liveDocument || !document) return; - let token = this.resolveToken(position, document, liveDocument); + const token = await this.resolveToken(position, document, liveDocument); if (token) { return { @@ -35,13 +36,13 @@ export default class HoverContentProvider extends Provider { }; } - private resolveToken(position: Position, document: Document, liveDocument: TextDocument) { + private async resolveToken(position: Position, document: Document, liveDocument: TextDocument) { let tokens; let token: ComplexToken | undefined; - const [lines, rawTokenizedContent] = this.server.tokenizer.tokenizeContentToRaw(liveDocument.getText()); - const localScope = this.server.tokenizer.tokenizeContentFromRaw(lines, rawTokenizedContent, 0, position.line); - const { tokenType, lookBehindRawContent, rawContent } = this.server.tokenizer.getActionTargetAtPosition(lines, rawTokenizedContent, position); + const content = liveDocument.getText(); + const localScope = await this.server.tokenizer.tokenizeContent(content, TokenizedScope.local, 0, position.line); + const { tokenType, lookBehindRawContent, rawContent } = await this.server.tokenizer.getActionTargetAtPositionAST(content, position); switch (tokenType) { case CompletionItemKind.Function: @@ -60,7 +61,7 @@ export default class HoverContentProvider extends Provider { tokens = document.getGlobalStructComplexTokens(); token = tokens.find((candidate) => candidate.identifier === rawContent); break; - case CompletionItemKind.Property: + case CompletionItemKind.Property: { const structIdentifer = localScope?.functionVariablesComplexTokens.find((candidate) => candidate.identifier === lookBehindRawContent)?.valueType; token = document @@ -68,6 +69,7 @@ export default class HoverContentProvider extends Provider { .find((candidate) => candidate.identifier === structIdentifer) ?.properties.find((property) => property.identifier === rawContent); break; + } default: token = localScope.functionVariablesComplexTokens.find((candidate) => candidate.identifier === rawContent); } diff --git a/server/src/Providers/SignatureHelpProvider.ts b/server/src/Providers/SignatureHelpProvider.ts index 10fb2fe..3cec307 100644 --- a/server/src/Providers/SignatureHelpProvider.ts +++ b/server/src/Providers/SignatureHelpProvider.ts @@ -15,7 +15,7 @@ export default class SignatureHelpProvider extends Provider { } private providerHandler(params: SignatureHelpParams) { - return () => { + return async () => { const { textDocument: { uri }, position, @@ -25,16 +25,16 @@ export default class SignatureHelpProvider extends Provider { const document = this.server.documentsCollection.getFromUri(uri); if (!liveDocument || !document) return; - const [lines, rawTokenizedContent] = this.server.tokenizer.tokenizeContentToRaw(liveDocument.getText()); - const line = lines[position.line]; - const tokensArray = rawTokenizedContent[position.line]; + const content = liveDocument.getText(); - if (!tokensArray || !this.server.tokenizer.isInScope(tokensArray, position, LanguageScopes.functionCall)) return; + // Use AST-based position queries instead of TextMate + const isInFunctionCall = await this.server.tokenizer.isInScopeAST(content, position, "function.call"); + if (!isInFunctionCall) return; - const rawContent = this.server.tokenizer.getLookBehindScopesRawContent(line, tokensArray, position, [LanguageScopes.functionCall, LanguageScopes.functionIdentifier]); - const activeParameter = this.server.tokenizer.getLookBehindScopeOccurences(tokensArray, position, LanguageScopes.separatorStatement, LanguageScopes.leftArgumentsRoundBracket); + const rawContent = await this.server.tokenizer.getFunctionNameAtPositionAST(content, position); + const activeParameter = await this.server.tokenizer.getActiveParameterIndexAST(content, position); - const localScope = this.server.tokenizer.tokenizeContent(liveDocument.getText(), TokenizedScope.local, 0, position.line); + const localScope = await this.server.tokenizer.tokenizeContent(content, TokenizedScope.local, 0, position.line); const functionComplexToken = localScope.functionsComplexTokens.find((token) => token.identifier === rawContent) || document.getGlobalComplexTokens().find((token) => token.identifier === rawContent) || diff --git a/server/src/Providers/SymbolsProvider.ts b/server/src/Providers/SymbolsProvider.ts index d8bfcdb..79293fd 100644 --- a/server/src/Providers/SymbolsProvider.ts +++ b/server/src/Providers/SymbolsProvider.ts @@ -13,7 +13,7 @@ export default class SymbolsProvider extends Provider { } private providerHandler(params: DocumentSymbolParams) { - return () => { + return async () => { const { textDocument: { uri }, } = params; @@ -22,7 +22,7 @@ export default class SymbolsProvider extends Provider { const document = this.server.documentsCollection.getFromUri(uri); if (!liveDocument || !document) return; - const localScope = this.server.tokenizer.tokenizeContent(liveDocument.getText(), TokenizedScope.local); + const localScope = await this.server.tokenizer.tokenizeContent(liveDocument.getText(), TokenizedScope.local); const constantSymbols = document.complexTokens.filter((token) => token.tokenType === CompletionItemKind.Constant).map((token) => SymbolBuilder.buildItem(token)); const structSymbols = document.structComplexTokens.map((token) => SymbolBuilder.buildItem(token)); diff --git a/server/src/ServerManager/ServerManager.ts b/server/src/ServerManager/ServerManager.ts index fd229ab..21621cf 100644 --- a/server/src/ServerManager/ServerManager.ts +++ b/server/src/ServerManager/ServerManager.ts @@ -52,7 +52,7 @@ export default class ServerManger { } public async initialize() { - this.tokenizer.loadGrammar(); + await this.tokenizer.loadGrammar(); this.registerProviders(); this.registerLiveDocumentsEvents(); @@ -69,8 +69,8 @@ export default class ServerManger { WorkspaceProvider.register(this); if (this.capabilitiesHandler.getSupportsWorkspaceConfiguration()) { - await ConfigurationProvider.register(this, async () => { - await this.loadConfig(); + await ConfigurationProvider.register(this, () => { + void this.loadConfig(); }); } @@ -89,7 +89,7 @@ export default class ServerManger { const nwscriptPath = filesPath.find((path) => path.includes("nwscript.nss")); const progressReporter = await this.connection.window.createWorkDoneProgress(); const filesCount = filesPath.length; - this.logger.info(`Indexing files ...`); + this.logger.info("Indexing files ..."); progressReporter.begin("Indexing files for NWScript: EE Language Server ...", 0); const partCount = Math.ceil(filesCount / numCPUs); @@ -105,18 +105,20 @@ export default class ServerManger { } cluster.on("exit", () => { - if (Object.keys(cluster.workers || {}).length === 0) { - progressReporter?.done(); - this.logger.info(`Indexed ${filesIndexedCount} files.`); - this.configLoaded = true; - this.diagnosticsProvider?.processDocumentsWaitingForPublish(); - - if (nwscriptPath) { - const fileContent = readFileSync(nwscriptPath).toString(); - const globalScope = this.tokenizer?.tokenizeContent(fileContent, TokenizedScope.global)!; - this.documentsCollection?.createDocument(pathToFileURL(nwscriptPath).href, globalScope); + void (async () => { + if (Object.keys(cluster.workers || {}).length === 0) { + progressReporter?.done(); + this.logger.info(`Indexed ${filesIndexedCount} files.`); + this.configLoaded = true; + await this.diagnosticsProvider?.processDocumentsWaitingForPublish(); + + if (nwscriptPath && this.tokenizer) { + const fileContent = readFileSync(nwscriptPath).toString(); + const globalScope = await this.tokenizer.tokenizeContent(fileContent, TokenizedScope.global); + this.documentsCollection?.createDocument(pathToFileURL(nwscriptPath).href, globalScope); + } } - } + })(); }); } @@ -135,12 +137,16 @@ export default class ServerManger { } private registerLiveDocumentsEvents() { - this.liveDocumentsManager.onDidSave((event) => this.diagnosticsProvider?.publish(event.document.uri)); - this.liveDocumentsManager.onWillSave((event) => this.documentsCollection?.updateDocument(event.document, this.tokenizer, this.workspaceFilesSystem)); + this.liveDocumentsManager.onDidSave((event) => { + void this.diagnosticsProvider?.publish(event.document.uri); + }); + this.liveDocumentsManager.onWillSave(async (event) => { + await this.documentsCollection?.updateDocument(event.document, this.tokenizer, this.workspaceFilesSystem); + }); - this.liveDocumentsManager.onDidOpen((event) => { - this.documentsCollection?.createDocuments(event.document.uri, event.document.getText(), this.tokenizer, this.workspaceFilesSystem); - this.diagnosticsProvider?.publish(event.document.uri); + this.liveDocumentsManager.onDidOpen(async (event) => { + await this.documentsCollection?.createDocuments(event.document.uri, event.document.getText(), this.tokenizer, this.workspaceFilesSystem); + void this.diagnosticsProvider?.publish(event.document.uri); }); } diff --git a/server/src/Tokenizer/Tokenizer.ts b/server/src/Tokenizer/Tokenizer.ts index 1c30765..25f73c3 100644 --- a/server/src/Tokenizer/Tokenizer.ts +++ b/server/src/Tokenizer/Tokenizer.ts @@ -7,8 +7,12 @@ import { Registry, INITIAL, parseRawGrammar, IToken } from "vscode-textmate"; import { CompletionItemKind } from "vscode-languageserver"; import type { ComplexToken, FunctionComplexToken, FunctionParamComplexToken, StructComplexToken, VariableComplexToken } from "./types"; -import { LanguageTypes, LanguageScopes } from "./constants"; +import { LanguageScopes } from "./constants"; import onigLib from "../onigLib"; +import { getParser } from "../Parser/NWScriptParser"; +import { extractGlobalTokens, extractLocalTokens } from "../Parser/ASTTraversal"; +import type { AST } from "../Parser/ASTTypes"; +import { ASTPositionQuery } from "../Parser/ASTPositionQuery"; export enum TokenizedScope { global = "global", @@ -26,13 +30,28 @@ export type LocalScopeTokenizationResult = { functionVariablesComplexTokens: (VariableComplexToken | FunctionParamComplexToken)[]; }; -// Naive implementation -// Ideally we would use an AST tree -// See the Notes section of the README for the explications +/** + * Hybrid tokenizer using AST for structural analysis and TextMate for position queries. + * + * Architecture: + * - AST (via NWScript compiler): Parses file structure, extracts functions/variables/structs + * - TextMate: Provides fine-grained token positions for LSP position-based queries + * + * Why hybrid? + * - AST is great for "what's in this file" but doesn't support "what's at this position" + * - TextMate is great for cursor position queries but slower for full-file analysis + */ export default class Tokenizer { + // TextMate registry for position-based queries private readonly registry: Registry; private grammar: IGrammar | null = null; - private readonly localScopeCache: (IToken[] | undefined)[] | null = null; + + // AST cache for structural tokenization + private cachedAST: AST | null = null; + private lastParsedContent: string = ""; + + // AST-based position query service + private positionQuery: ASTPositionQuery | null = null; constructor(localPath = false) { this.registry = new Registry({ @@ -41,359 +60,197 @@ export default class Tokenizer { return await new Promise((resolve, reject) => { if (scopeName === "source.nss") { const grammar = readFileSync(join(__dirname, "..", "..", localPath ? ".." : "", "syntaxes", "nwscript-ee.tmLanguage")); - return resolve(parseRawGrammar(grammar.toString())); } - reject(new Error(`Unknown scope name: ${scopeName}`)); }); }, }); } - private getTokenIndexAtPosition(tokensArray: IToken[], position: Position) { - return tokensArray.findIndex((token) => token.startIndex <= position.character && token.endIndex >= position.character); - } - - private getTokenAtPosition(tokensArray: IToken[], position: Position) { - return tokensArray.find((token) => token.startIndex <= position.character && token.endIndex >= position.character); - } - - private getRawTokenContent(line: string, token: IToken) { - return line.slice(token.startIndex, token.endIndex); + /** + * Initialize the TextMate grammar. + * Must be called before using any tokenization methods. + */ + public async loadGrammar() { + this.grammar = await this.registry.loadGrammar("source.nss"); + return this; } - private getTokenIndex(tokensArray: IToken[], targetToken: IToken) { - return tokensArray.findIndex((token) => token.startIndex === targetToken.startIndex); - } + // ============================================================================ + // AST-BASED TOKENIZATION (Structural Analysis) + // ============================================================================ + // These methods use the NWScript compiler to parse and extract tokens. + // Used for: indexing files, extracting all functions/variables/structs + + /** + * Tokenize content using AST parser to extract structural tokens. + * + * @param content - The NWScript source code + * @param scope - Whether to extract global or local scope tokens + * @param startIndex - Starting line for local scope (0-indexed) + * @param stopIndex - Ending line for local scope (0-indexed, -1 for end of file) + * @returns Extracted tokens based on scope + */ + + public tokenizeContent(content: string, scope: TokenizedScope.global, startIndex?: number, stopIndex?: number): Promise; + public tokenizeContent(content: string, scope: TokenizedScope.local, startIndex?: number, stopIndex?: number): Promise; + public async tokenizeContent(content: string, scope: TokenizedScope, startIndex: number = 0, stopIndex: number = -1): Promise { + // Parse content to AST if not cached or content changed + if (this.lastParsedContent !== content) { + const parser = await getParser(); + const { ast, errors } = await parser.parse(content); + + if (ast) { + this.cachedAST = ast; + this.lastParsedContent = content; + this.positionQuery = new ASTPositionQuery(ast); + } else { + console.warn("AST parsing failed:", errors); + return this.getEmptyResult(scope); + } + } - private getTokenLanguageType(line: string, tokens: IToken[], index: number) { - const rawContent = this.getRawTokenContent(line, tokens[index]); + if (!this.cachedAST) { + return this.getEmptyResult(scope); + } - const type = LanguageTypes[rawContent as keyof typeof LanguageTypes] || rawContent; - return (type === LanguageTypes.struct ? this.getRawTokenContent(line, tokens[index + 2]) : type) as LanguageTypes; + // Extract tokens from AST + if (scope === TokenizedScope.global) { + return extractGlobalTokens(this.cachedAST); + } else { + const lines = content.split(/\r?\n/); + const actualStopIndex = stopIndex < 0 ? lines.length : stopIndex; + return extractLocalTokens(this.cachedAST, startIndex, actualStopIndex); + } } - private getConstantValue(line: string, tokensArray: IToken[]) { - const startIndex = tokensArray.findIndex((token) => token.scopes.includes(LanguageScopes.assignationStatement)); - const endIndex = tokensArray.findIndex((token) => token.scopes.includes(LanguageScopes.terminatorStatement)); + /** + * Tokenize content from raw TextMate tokens to AST-based local scope. + * Bridge method for providers that still use TextMate for position queries. + */ - return tokensArray - .filter((_, index) => index > startIndex && index < endIndex) - .map((token) => this.getRawTokenContent(line, token)) - .join("") - .trim(); + public async tokenizeContentFromRaw(lines: string[], rawTokenizedContent: (IToken[] | undefined)[], startIndex: number = 0, stopIndex: number = -1) { + const content = lines.join("\n"); + return await this.tokenizeContent(content, TokenizedScope.local, startIndex, stopIndex); } - private getFunctionParams(lineIndex: number, lines: string[], tokensArrays: (IToken[] | undefined)[]) { - let params: FunctionParamComplexToken[] = []; - let line; - let tokensArray; - - lineIndex = lineIndex - 1; - do { - lineIndex = lineIndex + 1; - line = lines[lineIndex]; - tokensArray = tokensArrays[lineIndex]!; - - params = params.concat(this.getInlineFunctionParams(line, lineIndex, tokensArray)); - } while (!Boolean(tokensArray.find((token) => token.scopes.includes(LanguageScopes.rightParametersRoundBracket)))); - - return params; + /** + * Returns empty tokenization result based on scope. + */ + private getEmptyResult(scope: TokenizedScope): GlobalScopeTokenizationResult | LocalScopeTokenizationResult { + if (scope === TokenizedScope.global) { + return { complexTokens: [], structComplexTokens: [], children: [] }; + } else { + return { functionsComplexTokens: [], functionVariablesComplexTokens: [] }; + } } - private getInlineFunctionParams(line: string, lineIndex: number, tokensArray: IToken[]) { - const functionParamTokens = tokensArray.filter( - (token) => token.scopes.includes(LanguageScopes.functionParameters) && (token.scopes.includes(LanguageScopes.functionParameter) || token.scopes.includes(LanguageScopes.variableIdentifer)), - ); - - return functionParamTokens.map((token) => { - const tokenIndex = this.getTokenIndex(tokensArray, token); - let defaultValue = ""; - - if (tokensArray[tokenIndex + 2]?.scopes.includes(LanguageScopes.assignationStatement)) { - let index = tokenIndex + 4; - - while ( - index < tokensArray.length && - !tokensArray[index].scopes.includes(LanguageScopes.separatorStatement) && - !tokensArray[index].scopes.includes(LanguageScopes.rightParametersRoundBracket) && - !tokensArray[index].scopes.includes(LanguageScopes.commentStatement) - ) { - defaultValue += this.getRawTokenContent(line, tokensArray[index]); - index++; - } - } - + // ============================================================================ + // AST-BASED POSITION QUERIES (Preferred) + // ============================================================================ + // These methods use AST tree structure for position-based queries. + // More accurate and faster than TextMate for most use cases. + + /** + * Get the token at a specific position using AST. + * Preferred over TextMate-based method. + * + * @param content - The NWScript source code + * @param position - Cursor position (0-indexed) + * @param offset - Offset from position (not implemented yet) + * @returns Token information including type and content + */ + public async getActionTargetAtPositionAST( + content: string, + position: Position, + offset: number = 0, + ): Promise<{ + tokenType: CompletionItemKind | undefined; + lookBehindRawContent: string | undefined; + rawContent: string | undefined; + }> { + // Ensure we have parsed the content + await this.tokenizeContent(content, TokenizedScope.global); + + if (!this.positionQuery) { return { - position: { line: lineIndex, character: token.startIndex }, - identifier: this.getRawTokenContent(line, token), - tokenType: CompletionItemKind.TypeParameter, - valueType: this.getTokenLanguageType(line, tokensArray, tokenIndex - 2), - defaultValue: defaultValue.trim() || undefined, + tokenType: undefined, + lookBehindRawContent: undefined, + rawContent: undefined, }; - }); - } - - private getFunctionComments(lines: string[], tokensLines: (IToken[] | undefined)[], index: number) { - const comments: string[] = []; - - let errorSafeIndex = Math.max(index, 0); - while (tokensLines[errorSafeIndex]?.at(0)?.scopes.find((scope) => scope === LanguageScopes.commentStatement || scope === LanguageScopes.documentationCommentStatement)) { - comments.unshift(lines[errorSafeIndex]); - errorSafeIndex--; } - return comments; + return this.positionQuery.getActionTargetAtPosition(position.line, position.character, offset); } - private isFunctionDeclaration(lineIndex: number, tokensArrays: (IToken[] | undefined)[]) { - let isFunctionDeclaration = false; - let tokensArray = tokensArrays[lineIndex]!; - let isLastParamsLine = false; - - while (!isLastParamsLine) { - isLastParamsLine = Boolean(tokensArray.find((token) => token.scopes.includes(LanguageScopes.rightParametersRoundBracket))); - - if (isLastParamsLine && Boolean(tokensArray.find((token) => token.scopes.includes(LanguageScopes.terminatorStatement) && !token.scopes.includes(LanguageScopes.block)))) { - isFunctionDeclaration = true; - } - - lineIndex = lineIndex + 1; - tokensArray = tokensArrays[lineIndex]!; + /** + * Check if position is within a specific scope using AST. + * + * @param content - The NWScript source code + * @param position - Cursor position (0-indexed) + * @param scopeType - The scope type to check for + * @returns True if position is within the scope + */ + public async isInScopeAST(content: string, position: Position, scopeType: string): Promise { + await this.tokenizeContent(content, TokenizedScope.global); + + if (!this.positionQuery) { + return false; } - return isFunctionDeclaration; - } - - private isGlobalFunctionDeclaration(lineIndex: number, tokenIndex: number, token: IToken, tokensArrays: (IToken[] | undefined)[]) { - return ( - !(tokenIndex === 0 && lineIndex === 0) && // Not sure why we need this - !token.scopes.includes(LanguageScopes.block) && - token.scopes.includes(LanguageScopes.functionIdentifier) && - this.isFunctionDeclaration(lineIndex, tokensArrays) - ); - } - - private isLocalFunctionDeclaration(lineIndex: number, tokenIndex: number, token: IToken, tokensArrays: (IToken[] | undefined)[]) { - return ( - token.scopes.includes(LanguageScopes.functionIdentifier) && - !token.scopes.includes(LanguageScopes.block) && - !(tokenIndex === 0 && lineIndex === 0) && // Not sure why we need this - !this.isFunctionDeclaration(lineIndex, tokensArrays) - ); - } - - private isGlobalConstant(token: IToken) { - return token.scopes.includes(LanguageScopes.constantIdentifer) && !token.scopes.includes(LanguageScopes.functionDeclaration) && !token.scopes.includes(LanguageScopes.block); + return this.positionQuery.isInScope(position.line, position.character, scopeType); } - private isStructDeclaration(token: IToken, lastToken: IToken, lineIndex: number, tokensArrays: (IToken[] | undefined)[]) { - return ( - token.scopes.includes(LanguageScopes.structIdentifier) && - ((tokensArrays[lineIndex + 1]?.at(0)?.scopes.includes(LanguageScopes.blockDeclaraction) && lastToken.scopes.includes(LanguageScopes.structIdentifier)) || - lastToken.scopes.includes(LanguageScopes.blockDeclaraction)) - ); - } - - private isLocalVariable(tokenIndex: number, token: IToken, tokensArray: IToken[]) { - return ( - token.scopes.includes(LanguageScopes.variableIdentifer) && - tokenIndex > 1 && - (tokensArray[tokenIndex - 2].scopes.includes(LanguageScopes.type) || tokensArray[tokenIndex - 2].scopes.includes(LanguageScopes.structIdentifier)) - ); - } - - private tokenizeLinesForGlobalScope(lines: string[], tokensArrays: (IToken[] | undefined)[], startIndex: number = 0, stopIndex: number = -1) { - const firstLineIndex = startIndex > lines.length || startIndex < 0 ? 0 : startIndex; - const lastLineIndex = stopIndex + 10 > lines.length || stopIndex < 0 ? lines.length : stopIndex; - const scope: GlobalScopeTokenizationResult = { - complexTokens: [], - structComplexTokens: [], - children: [], - }; - - let currentStruct: StructComplexToken | null = null; - for (let lineIndex = firstLineIndex; lineIndex < lastLineIndex; lineIndex++) { - const line = lines[lineIndex]; - const tokensArray = tokensArrays[lineIndex]; - - if (tokensArray) { - const lastIndex = tokensArray.length - 1; - const lastToken = tokensArray[lastIndex]; - for (let tokenIndex = 0; tokenIndex < tokensArray.length; tokenIndex++) { - const token = tokensArray[tokenIndex]; - - if (currentStruct) { - if (token.scopes.includes(LanguageScopes.blockTermination)) { - scope.structComplexTokens.push(currentStruct); - currentStruct = null; - } else if (lastIndex > 0 && tokensArray[1].scopes.includes(LanguageScopes.type)) { - currentStruct.properties.push({ - position: { line: lineIndex, character: tokensArray[3].startIndex }, - identifier: this.getRawTokenContent(line, tokensArray[3]), - tokenType: CompletionItemKind.Property, - valueType: this.getTokenLanguageType(line, tokensArray, 1), - }); - } - - break; - } - - if (token.scopes.includes(LanguageScopes.includeDeclaration)) { - scope.children.push(this.getRawTokenContent(line, tokensArray.at(-2)!)); - break; - } - - if (this.isGlobalConstant(token)) { - scope.complexTokens.push({ - position: { line: lineIndex, character: token.startIndex }, - identifier: this.getRawTokenContent(line, token), - tokenType: CompletionItemKind.Constant, - valueType: this.getTokenLanguageType(line, tokensArray, tokenIndex - 2), - value: this.getConstantValue(line, tokensArray), - }); - break; - } - - if (this.isGlobalFunctionDeclaration(lineIndex, tokenIndex, token, tokensArrays)) { - scope.complexTokens.push({ - position: { line: lineIndex, character: token.startIndex }, - identifier: this.getRawTokenContent(line, token), - tokenType: CompletionItemKind.Function, - returnType: tokenIndex === 0 ? this.getTokenLanguageType(lines[lineIndex - 1], tokensArrays[lineIndex - 1]!, 0) : this.getTokenLanguageType(line, tokensArray, tokenIndex - 2), - params: this.getFunctionParams(lineIndex, lines, tokensArrays), - comments: this.getFunctionComments(lines, tokensArrays, tokenIndex === 0 ? lineIndex - 2 : lineIndex - 1), - }); - - break; - } - - if (this.isStructDeclaration(token, lastToken, lineIndex, tokensArrays)) { - currentStruct = { - position: { line: lineIndex, character: token.startIndex }, - identifier: this.getRawTokenContent(line, token), - tokenType: CompletionItemKind.Struct, - properties: [], - }; - break; - } - } - } + /** + * Get function name at cursor position using AST. + * Used for signature help. + * + * @param content - The NWScript source code + * @param position - Cursor position (0-indexed) + * @returns Function name or undefined + */ + public async getFunctionNameAtPositionAST(content: string, position: Position): Promise { + await this.tokenizeContent(content, TokenizedScope.global); + + if (!this.positionQuery) { + return undefined; } - return scope; + return this.positionQuery.getFunctionNameAtPosition(position.line, position.character); } - private tokenizeLinesForLocalScope(lines: string[], tokensArrays: (IToken[] | undefined)[], startIndex: number = 0, stopIndex: number = -1) { - const firstLineIndex = startIndex > lines.length || startIndex < 0 ? 0 : startIndex; - const lastLineIndex = stopIndex > lines.length || stopIndex < 0 ? lines.length : stopIndex; - const scope: LocalScopeTokenizationResult = { - functionsComplexTokens: [], - functionVariablesComplexTokens: [], - }; - - let computeFunctionLocals = false; - let currentFunctionVariables = []; - - for (let lineIndex = lastLineIndex; lineIndex >= firstLineIndex; lineIndex--) { - const line = lines[lineIndex]; - const isLastLine = lineIndex === lastLineIndex; - const tokensArray = tokensArrays[lineIndex]; - - if (tokensArray) { - const lastIndex = tokensArray.length - 1; - const lastToken = tokensArray[lastIndex]; - - if ( - (lastToken.scopes.includes(LanguageScopes.block) && lastToken.scopes.includes(LanguageScopes.blockTermination) && lastLineIndex === lines.length) || - (isLastLine && (lastToken.scopes.includes(LanguageScopes.block) || lastToken.scopes.includes(LanguageScopes.functionDeclaration))) - ) { - computeFunctionLocals = true; - } - - for (let tokenIndex = 0; tokenIndex < tokensArray.length; tokenIndex++) { - const token = tokensArray[tokenIndex]; - - if (computeFunctionLocals && this.isLocalVariable(tokenIndex, token, tokensArray)) { - const complexToken = { - position: { line: lineIndex, character: token.startIndex }, - identifier: this.getRawTokenContent(line, token), - tokenType: CompletionItemKind.Variable, - valueType: this.getTokenLanguageType(line, tokensArray, tokenIndex - 2), - }; - scope.functionVariablesComplexTokens.push(complexToken); - currentFunctionVariables.push(complexToken); - - let nextVariableToken; - let currentVariableIndex = tokenIndex; - while (tokensArray[currentVariableIndex + 1] && tokensArray[currentVariableIndex + 1].scopes.includes(LanguageScopes.separatorStatement)) { - if (tokensArray[currentVariableIndex + 2].scopes.includes(LanguageScopes.variableIdentifer)) { - currentVariableIndex = currentVariableIndex + 2; - } else { - currentVariableIndex = currentVariableIndex + 3; - } - - nextVariableToken = tokensArray[currentVariableIndex]; - const complextToken = { - position: { line: lineIndex, character: nextVariableToken.startIndex }, - identifier: this.getRawTokenContent(line, nextVariableToken), - tokenType: CompletionItemKind.Variable, - valueType: this.getTokenLanguageType(line, tokensArray, tokenIndex - 2), - }; - scope.functionVariablesComplexTokens.push(complextToken); - currentFunctionVariables.push(complexToken); - } - } - - if (computeFunctionLocals && token.scopes.includes(LanguageScopes.functionParameter)) { - scope.functionVariablesComplexTokens.push({ - position: { line: lineIndex, character: token.startIndex }, - identifier: this.getRawTokenContent(line, token), - tokenType: CompletionItemKind.TypeParameter, - valueType: this.getTokenLanguageType(line, tokensArray, tokenIndex - 2), - }); - } - - if (this.isLocalFunctionDeclaration(lineIndex, tokenIndex, token, tokensArrays)) { - scope.functionsComplexTokens.push({ - position: { line: lineIndex, character: token.startIndex }, - identifier: this.getRawTokenContent(line, token), - tokenType: CompletionItemKind.Function, - returnType: tokenIndex === 0 ? this.getTokenLanguageType(lines[lineIndex - 1], tokensArrays[lineIndex - 1]!, 0) : this.getTokenLanguageType(line, tokensArray, tokenIndex - 2), - params: this.getFunctionParams(lineIndex, lines, tokensArrays), - comments: this.getFunctionComments(lines, tokensArrays, tokenIndex === 0 ? lineIndex - 2 : lineIndex - 1), - variables: currentFunctionVariables, - }); - } - } - - // Needs to be after to allow one more iteration to fetch function params - if (computeFunctionLocals && !lastToken.scopes.includes(LanguageScopes.block)) { - computeFunctionLocals = false; - currentFunctionVariables = []; - } - } + /** + * Get active parameter index at cursor position using AST. + * Used for signature help. + * + * @param content - The NWScript source code + * @param position - Cursor position (0-indexed) + * @returns Parameter index (0-based) + */ + public async getActiveParameterIndexAST(content: string, position: Position): Promise { + await this.tokenizeContent(content, TokenizedScope.global); + + if (!this.positionQuery) { + return 0; } - return scope; + return this.positionQuery.getActiveParameterIndex(position.line, position.character); } - public tokenizeContent(content: string, scope: TokenizedScope.global, startIndex?: number, stopIndex?: number): GlobalScopeTokenizationResult; - public tokenizeContent(content: string, scope: TokenizedScope.local, startIndex?: number, stopIndex?: number): LocalScopeTokenizationResult; - public tokenizeContent(content: string, scope: TokenizedScope, startIndex: number = 0, stopIndex: number = -1) { - const [lines, rawTokenizedContent] = this.tokenizeContentToRaw(content); + // ============================================================================ + // TEXTMATE-BASED TOKENIZATION (Legacy Position Queries) + // ============================================================================ + // These methods use TextMate grammar for fine-grained position-based queries. + // Kept for compatibility, prefer AST-based methods above. + // Used for: LSP features like hover, autocomplete, signature help at cursor position - if (scope === TokenizedScope.global) { - return this.tokenizeLinesForGlobalScope(lines, rawTokenizedContent, startIndex, stopIndex); - } else { - return this.tokenizeLinesForLocalScope(lines, rawTokenizedContent, startIndex, stopIndex); - } - } - - public tokenizeContentFromRaw(lines: string[], rawTokenizedContent: (IToken[] | undefined)[], startIndex: number = 0, stopIndex: number = -1) { - return this.tokenizeLinesForLocalScope(lines, rawTokenizedContent, startIndex, stopIndex); - } + /** + * Tokenize content to raw TextMate tokens for position-based queries. + * + * @param content - The NWScript source code + * @returns Tuple of [lines, token arrays per line] + */ public tokenizeContentToRaw(content: string): [lines: string[], rawTokenizedContent: (IToken[] | undefined)[]] { const lines = content.split(/\r?\n/); @@ -403,16 +260,24 @@ export default class Tokenizer { lines, lines.map((line) => { const tokenizedLine = this.grammar?.tokenizeLine(line, ruleStack); - if (tokenizedLine) { ruleStack = tokenizedLine.ruleStack; } - return tokenizedLine?.tokens; }), ]; } + /** + * Get the token at or near a specific position in the document. + * + * @param lines - Source code lines + * @param tokensArrays - TextMate tokens per line + * @param position - Cursor position + * @param offset - Offset from position (-1 for previous token, 1 for next) + * @returns Token information including type and content + */ + public getActionTargetAtPosition(lines: string[], tokensArrays: (IToken[] | undefined)[], position: Position, offset: number = 0) { let tokenType; let lookBehindRawContent; @@ -459,6 +324,16 @@ export default class Tokenizer { }; } + /** + * Look backward from position to find content matching specific scopes. + * Used for finding function names in signature help. + * + * @param line - The source line + * @param tokensArray - TextMate tokens for this line + * @param position - Starting position + * @param languageScopes - Scopes to match (e.g., function identifier) + * @returns The matched token content + */ public getLookBehindScopesRawContent(line: string, tokensArray: IToken[], position: Position, languageScopes: LanguageScopes[]) { let identifier: string | undefined; const tokenIndex = this.getTokenIndexAtPosition(tokensArray, position); @@ -473,28 +348,66 @@ export default class Tokenizer { return identifier; } + /** + * Count occurrences of a specific scope when looking backward from position. + * Used for counting commas to determine active parameter in signature help. + * + * @param tokensArray - TextMate tokens for this line + * @param position - Starting position + * @param occurencesTarget - Scope to count (e.g., separator/comma) + * @param delimiter - Scope to stop at (e.g., function call start) + * @returns Number of occurrences found + */ + public getLookBehindScopeOccurences(tokensArray: IToken[], position: Position, occurencesTarget: LanguageScopes, delimiter: LanguageScopes) { let occurences = 0; - let currentIndex = this.getTokenIndexAtPosition(tokensArray, position); + while (currentIndex >= 0 && !tokensArray[currentIndex].scopes.includes(delimiter)) { if (tokensArray[currentIndex].scopes.includes(occurencesTarget)) { occurences++; } - currentIndex--; } return occurences; } + /** + * Check if a position is within a specific language scope. + * Used for determining if cursor is inside a function call, etc. + * + * @param tokensArray - TextMate tokens for this line + * @param position - Position to check + * @param scope - Scope to check for (e.g., function call) + * @returns True if position is in the specified scope + */ public isInScope(tokensArray: IToken[], position: Position, scope: LanguageScopes) { return this.getTokenAtPosition(tokensArray, position)?.scopes.includes(scope); } - public async loadGrammar() { - this.grammar = await this.registry.loadGrammar("source.nss"); + // ============================================================================ + // PRIVATE HELPER METHODS + // ============================================================================ - return this; + /** + * Find the index of the token at a specific position. + */ + private getTokenIndexAtPosition(tokensArray: IToken[], position: Position) { + return tokensArray.findIndex((token) => token.startIndex <= position.character && token.endIndex >= position.character); + } + + /** + * Find the token at a specific position. + */ + private getTokenAtPosition(tokensArray: IToken[], position: Position) { + return tokensArray.find((token) => token.startIndex <= position.character && token.endIndex >= position.character); + } + + /** + * Extract the raw text content of a token. + */ + private getRawTokenContent(line: string, token: IToken) { + return line.slice(token.startIndex, token.endIndex); } } diff --git a/server/src/Tokenizer/types.ts b/server/src/Tokenizer/types.ts index be51b9d..4af9e13 100644 --- a/server/src/Tokenizer/types.ts +++ b/server/src/Tokenizer/types.ts @@ -41,10 +41,4 @@ export type FunctionParamComplexToken = BaseComplexToken; export type StructComplexToken = BaseComplexToken; export type StructPropertyComplexToken = BaseComplexToken; -export type ComplexToken = - | ConstantComplexToken - | VariableComplexToken - | FunctionParamComplexToken - | FunctionComplexToken - | StructComplexToken - | StructPropertyComplexToken; +export type ComplexToken = ConstantComplexToken | VariableComplexToken | FunctionParamComplexToken | FunctionComplexToken | StructComplexToken | StructPropertyComplexToken; diff --git a/server/src/server.ts b/server/src/server.ts index 77da547..262246b 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -11,7 +11,7 @@ connection.onInitialize(async (params: InitializeParams) => { }); connection.onInitialized(() => { - server.up(); + void server.up(); }); connection.onShutdown(() => server.down()); diff --git a/server/test/ast_integration_test.ts b/server/test/ast_integration_test.ts new file mode 100644 index 0000000..814880a --- /dev/null +++ b/server/test/ast_integration_test.ts @@ -0,0 +1,206 @@ +import { expect } from "chai"; +import Tokenizer, { TokenizedScope } from "../src/Tokenizer/Tokenizer"; + +describe("AST Integration Tests", () => { + let tokenizer: Tokenizer; + + before(async () => { + tokenizer = await new Tokenizer(true).loadGrammar(); + }); + + describe("Basic position queries", () => { + const code = `int Add(int a, int b) { return a + b; } + +void main() { + int result = Add(5, 10); +}`; + + it("should find tokens using AST position queries", async () => { + // Just verify that the method works without errors + const result = await tokenizer.getActionTargetAtPositionAST(code, { + line: 3, + character: 20, + }); + + expect(result).to.exist; + expect(result).to.have.property("tokenType"); + expect(result).to.have.property("rawContent"); + }); + + it("should detect function call scope", async () => { + // Position somewhere inside Add(5, 10) + const isInCall = await tokenizer.isInScopeAST( + code, + { line: 3, character: 22 }, + "function.call" + ); + + expect(isInCall).to.be.a("boolean"); + }); + + it("should get function name in call context", async () => { + // Position inside function call + const funcName = await tokenizer.getFunctionNameAtPositionAST(code, { + line: 3, + character: 22, + }); + + // Should either find the function name or return undefined + if (funcName) { + expect(funcName).to.be.a("string"); + } else { + expect(funcName).to.be.undefined; + } + }); + + it("should get active parameter index", async () => { + // Position inside function call + const index = await tokenizer.getActiveParameterIndexAST(code, { + line: 3, + character: 22, + }); + + expect(index).to.be.a("number"); + expect(index).to.be.at.least(0); + }); + }); + + describe("AST structural tokenization still works", () => { + const code = `int globalVar = 10; + +void TestFunc(int param) { + int localVar = 5; +} + +void main() {}`; + + it("should extract global tokens", async () => { + const result = await tokenizer.tokenizeContent( + code, + TokenizedScope.global + ); + + expect(result.complexTokens).to.be.an("array"); + expect(result.structComplexTokens).to.be.an("array"); + + // Should find at least the functions + const funcNames = result.complexTokens + .filter((t) => t.identifier) + .map((t) => t.identifier); + + expect(funcNames).to.include("TestFunc"); + expect(funcNames).to.include("main"); + }); + + it("should extract local tokens", async () => { + const result = await tokenizer.tokenizeContent( + code, + TokenizedScope.local, + 0, + 5 + ); + + expect(result.functionsComplexTokens).to.be.an("array"); + expect(result.functionVariablesComplexTokens).to.be.an("array"); + }); + }); + + describe("Caching behavior", () => { + const code = `void test() { + int x = 5; +} + +void main() {}`; + + it("should cache parsed AST", async () => { + // First call + const start1 = Date.now(); + await tokenizer.getActionTargetAtPositionAST(code, { + line: 1, + character: 8, + }); + const time1 = Date.now() - start1; + + // Second call with same code - should use cache + const start2 = Date.now(); + await tokenizer.getActionTargetAtPositionAST(code, { + line: 1, + character: 10, + }); + const time2 = Date.now() - start2; + + // Second call should be faster or roughly the same (cache hit) + // Allow some variance for timing inconsistencies + expect(time2).to.be.lessThan(time1 + 50); + }); + }); + + describe("Error handling", () => { + it("should handle invalid code gracefully", async () => { + const invalidCode = `void test() { + int x = ; // syntax error +}`; + + // Should not throw + const result = await tokenizer.getActionTargetAtPositionAST(invalidCode, { + line: 1, + character: 10, + }); + + expect(result).to.exist; + }); + + it("should handle empty code", async () => { + const result = await tokenizer.getActionTargetAtPositionAST("", { + line: 0, + character: 0, + }); + + expect(result.tokenType).to.be.undefined; + expect(result.rawContent).to.be.undefined; + }); + + it("should handle out of bounds positions", async () => { + const code = `void main() {}`; + + const result = await tokenizer.getActionTargetAtPositionAST(code, { + line: 999, + character: 999, + }); + + expect(result).to.exist; + }); + }); + + describe("Complex scenarios", () => { + const code = `int Multiply(int a, int b) { return a * b; } +int Add(int a, int b) { return a + b; } + +void main() { + int result = Add(Multiply(2, 3), 10); +}`; + + it("should handle nested function calls", async () => { + // Query inside nested call + const funcName = await tokenizer.getFunctionNameAtPositionAST(code, { + line: 4, + character: 26, + }); + + // Should find either Multiply or Add + if (funcName) { + expect(["Multiply", "Add"]).to.include(funcName); + } + }); + + it("should detect scope in nested calls", async () => { + const isInCall = await tokenizer.isInScopeAST( + code, + { line: 4, character: 26 }, + "function.call" + ); + + expect(isInCall).to.be.a("boolean"); + }); + }); +}); diff --git a/server/test/ast_tokenization_test.ts b/server/test/ast_tokenization_test.ts new file mode 100644 index 0000000..3f82b0a --- /dev/null +++ b/server/test/ast_tokenization_test.ts @@ -0,0 +1,259 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions */ +import { describe, before, it } from "mocha"; +import { expect } from "chai"; +import Tokenizer, { TokenizedScope, GlobalScopeTokenizationResult, LocalScopeTokenizationResult } from "../src/Tokenizer/Tokenizer"; +import { CompletionItemKind } from "vscode-languageserver"; +import type { ConstantComplexToken, FunctionComplexToken, VariableComplexToken } from "../src/Tokenizer/types"; + +describe("AST Tokenization", () => { + let astTokenizer: Tokenizer; + + before("Initialize tokenizers", async () => { + astTokenizer = await new Tokenizer(true).loadGrammar(); + }); + + describe("Simple script parsing", () => { + const simpleScript = ` +// Simple test script +int MAX_VALUE = 100; +string TEST_NAME = "test"; + +struct TestStruct { + int id; + string name; +}; + +int Add(int a, int b) { + return a + b; +} + +void main() { + int x = 5; + int y = 10; + int result = Add(x, y); +} +`; + + it("should successfully parse with AST mode", async () => { + const result: GlobalScopeTokenizationResult = await astTokenizer.tokenizeContent(simpleScript, TokenizedScope.global); + + expect(result).to.not.be.undefined; + expect(result.complexTokens).to.be.an("array"); + expect(result.structComplexTokens).to.be.an("array"); + }); + + it("should extract constants", async () => { + const result: GlobalScopeTokenizationResult = await astTokenizer.tokenizeContent(simpleScript, TokenizedScope.global); + + const constants = result.complexTokens.filter((t) => t.tokenType === CompletionItemKind.Constant) as ConstantComplexToken[]; + expect(constants.length).to.be.at.least(2); + + const maxValue = constants.find((c) => c.identifier === "MAX_VALUE"); + expect(maxValue).to.not.be.undefined; + expect(maxValue?.valueType).to.equal("int"); + + const testName = constants.find((c) => c.identifier === "TEST_NAME"); + expect(testName).to.not.be.undefined; + expect(testName?.valueType).to.equal("string"); + }); + + it("should extract struct definitions", async () => { + const result: GlobalScopeTokenizationResult = await astTokenizer.tokenizeContent(simpleScript, TokenizedScope.global); + + expect(result.structComplexTokens.length).to.be.at.least(1); + + const testStruct = result.structComplexTokens.find((s) => s.identifier === "TestStruct"); + expect(testStruct).to.not.be.undefined; + expect(testStruct?.properties.length).to.be.at.least(2); + + const idProp = testStruct?.properties.find((p) => p.identifier === "id"); + expect(idProp).to.not.be.undefined; + expect(idProp?.valueType).to.equal("int"); + + const nameProp = testStruct?.properties.find((p) => p.identifier === "name"); + expect(nameProp).to.not.be.undefined; + expect(nameProp?.valueType).to.equal("string"); + }); + + it("should extract function declarations", async () => { + const result: GlobalScopeTokenizationResult = await astTokenizer.tokenizeContent(simpleScript, TokenizedScope.global); + + const functions = result.complexTokens.filter((t) => t.tokenType === CompletionItemKind.Function) as FunctionComplexToken[]; + expect(functions.length).to.be.at.least(2); + + const addFunc = functions.find((f) => f.identifier === "Add"); + expect(addFunc).to.not.be.undefined; + expect(addFunc?.returnType).to.equal("int"); + + const mainFunc = functions.find((f) => f.identifier === "main"); + expect(mainFunc).to.not.be.undefined; + expect(mainFunc?.returnType).to.equal("void"); + }); + + it("should extract function parameters", async () => { + const result: GlobalScopeTokenizationResult = await astTokenizer.tokenizeContent(simpleScript, TokenizedScope.global); + + const functions = result.complexTokens.filter((t) => t.tokenType === CompletionItemKind.Function) as FunctionComplexToken[]; + const addFunc = functions.find((f) => f.identifier === "Add"); + + expect(addFunc).to.not.be.undefined; + expect(addFunc?.params.length).to.equal(2); + + const paramA = addFunc?.params.find((p: any) => p.identifier === "a"); + expect(paramA).to.not.be.undefined; + expect(paramA?.valueType).to.equal("int"); + + const paramB = addFunc?.params.find((p: any) => p.identifier === "b"); + expect(paramB).to.not.be.undefined; + expect(paramB?.valueType).to.equal("int"); + }); + + it("should extract local scope variables", async () => { + const result: LocalScopeTokenizationResult = await astTokenizer.tokenizeContent(simpleScript, TokenizedScope.local); + + expect(result.functionVariablesComplexTokens).to.be.an("array"); + expect(result.functionVariablesComplexTokens.length).to.be.at.least(3); + + const xVar = result.functionVariablesComplexTokens.find((v) => v.identifier === "x") as VariableComplexToken | undefined; + expect(xVar).to.not.be.undefined; + expect(xVar?.valueType).to.equal("int"); + + const yVar = result.functionVariablesComplexTokens.find((v) => v.identifier === "y"); + expect(yVar).to.not.be.undefined; + + const resultVar = result.functionVariablesComplexTokens.find((v) => v.identifier === "result"); + expect(resultVar).to.not.be.undefined; + }); + + it("should extract local scope functions", async () => { + const result: LocalScopeTokenizationResult = await astTokenizer.tokenizeContent(simpleScript, TokenizedScope.local); + + expect(result.functionsComplexTokens).to.be.an("array"); + const addFunc = result.functionsComplexTokens.find((f) => f.identifier === "Add"); + expect(addFunc).to.not.be.undefined; + }); + }); + + describe("Position accuracy", () => { + const positionScript = `void testFunction() { + int x = 5; +} + +void main() {}`; + + it("should have accurate line numbers (0-indexed)", async () => { + const result: GlobalScopeTokenizationResult = await astTokenizer.tokenizeContent(positionScript, TokenizedScope.global); + + const func = result.complexTokens.find((t) => t.identifier === "testFunction"); + expect(func).to.not.be.undefined; + expect(func?.position.line).to.equal(0); // First line, 0-indexed + }); + + it("should have accurate character positions", async () => { + const result: GlobalScopeTokenizationResult = await astTokenizer.tokenizeContent(positionScript, TokenizedScope.global); + + const func = result.complexTokens.find((t) => t.identifier === "testFunction"); + expect(func).to.not.be.undefined; + expect(func?.position.character).to.be.greaterThan(0); + }); + }); + + describe("Complex expressions", () => { + const complexScript = ` +int Calculate() { + int a = 5 + 3; + int b = a * 2; + int c = (b - 1) / 2; + return c; +} + +void TestLogic() { + int x = 10; + if (x > 5) { + x = x + 1; + } +} + +void main() {} +`; + + it("should handle complex expressions", async () => { + const result: GlobalScopeTokenizationResult = await astTokenizer.tokenizeContent(complexScript, TokenizedScope.global); + + expect(result.complexTokens.length).to.be.at.least(2); + + const calcFunc = result.complexTokens.find((f) => f.identifier === "Calculate") as FunctionComplexToken | undefined; + expect(calcFunc).to.not.be.undefined; + expect(calcFunc?.returnType).to.equal("int"); + }); + + it("should extract variables from complex functions", async () => { + const result: LocalScopeTokenizationResult = await astTokenizer.tokenizeContent(complexScript, TokenizedScope.local); + + const variables = result.functionVariablesComplexTokens; + expect(variables.length).to.be.at.least(4); // a, b, c, x + + const varA = variables.find((v) => v.identifier === "a") as VariableComplexToken | undefined; + expect(varA).to.not.be.undefined; + expect(varA?.valueType).to.equal("int"); + }); + }); + + describe("Error handling", () => { + const invalidScript = ` +void main() { + UndefinedFunction(); +}`; + + it("should return empty results on parse errors", async () => { + // AST parsing will fail for invalid code, returns empty results + const result: GlobalScopeTokenizationResult = await astTokenizer.tokenizeContent(invalidScript, TokenizedScope.global); + + expect(result).to.not.be.undefined; + expect(result.complexTokens).to.be.an("array"); + expect(result.complexTokens.length).to.equal(0); + }); + }); + + describe("Edge cases", () => { + it("should handle multi-line function declarations", async () => { + const edgeCaseScript = ` +// Multi-line function declaration +int +VeryLongFunctionName +( + int parameter +) +{ + return parameter; +} + +void main() {} +`; + + const astResult: GlobalScopeTokenizationResult = await astTokenizer.tokenizeContent(edgeCaseScript, TokenizedScope.global); + + // AST should find the function + const func = astResult.complexTokens.find((t) => t.identifier === "VeryLongFunctionName") as FunctionComplexToken | undefined; + expect(func).to.not.be.undefined; + expect(func?.returnType).to.equal("int"); + }); + }); + + describe("Performance", () => { + it("should cache AST for repeated calls", async () => { + const script = "void main() { int x = 5; }"; + + const start1 = Date.now(); + await astTokenizer.tokenizeContent(script, TokenizedScope.global); + const time1 = Date.now() - start1; + + const start2 = Date.now(); + await astTokenizer.tokenizeContent(script, TokenizedScope.global); + const time2 = Date.now() - start2; + + // Second call should be faster (cached) + expect(time2).to.be.lessThan(time1); + }); + }); +}); diff --git a/server/test/static/globalScopeTokens.json b/server/test/static/globalScopeTokens.json index bf005da..3861a71 100644 --- a/server/test/static/globalScopeTokens.json +++ b/server/test/static/globalScopeTokens.json @@ -1,552 +1,1059 @@ { "complexTokens": [ - { + { + "position": { + "line": 43, + "character": 15 + }, + "identifier": "iSkill", + "tokenType": 21, + "valueType": "int", + "value": "" + }, + { + "position": { + "line": 44, + "character": 14 + }, + "identifier": "iFeat", + "tokenType": 21, + "valueType": "int", + "value": "" + }, + { + "position": { + "line": 47, + "character": 18 + }, + "identifier": "iModifier", + "tokenType": 21, + "valueType": "int", + "value": "" + }, + { + "position": { + "line": 51, + "character": 19 + }, + "identifier": "iFocusFeat", + "tokenType": 21, + "valueType": "int", + "value": "" + }, + { + "position": { + "line": 61, + "character": 20 + }, + "identifier": "sClasses", + "tokenType": 21, + "valueType": "string", + "value": "" + }, + { + "position": { + "line": 65, + "character": 25 + }, + "identifier": "fClassLevelMod", + "tokenType": 21, + "valueType": "float", + "value": "" + }, + { + "position": { + "line": 68, + "character": 27 + }, + "identifier": "iAreaFlagsRequired", + "tokenType": 21, + "valueType": "int", + "value": "" + }, + { + "position": { + "line": 71, + "character": 28 + }, + "identifier": "iAreaFlagsForbidden", + "tokenType": 21, + "valueType": "int", + "value": "" + }, + { + "position": { + "line": 75, + "character": 20 + }, + "identifier": "iDayOrNight", + "tokenType": 21, + "valueType": "int", + "value": "" + }, + { + "position": { + "line": 78, + "character": 33 + }, + "identifier": "bBypassArmorCheckPenalty", + "tokenType": 21, + "valueType": "int", + "value": "" + }, + { + "position": { + "line": 85, + "character": 24 + }, + "identifier": "iKeyAbilityMask", + "tokenType": 21, + "valueType": "int", + "value": "" + }, + { + "position": { + "line": 2, + "character": 26 + }, + "identifier": "NWNX_PushArgumentInt", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 2, + "character": 32 + }, + "identifier": "i", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 3, + "character": 28 + }, + "identifier": "NWNX_PushArgumentFloat", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 3, + "character": 36 + }, + "identifier": "f", + "tokenType": 25, + "valueType": "float" + } + ], + "comments": [] + }, + { + "position": { + "line": 4, + "character": 29 + }, + "identifier": "NWNX_PushArgumentString", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 4, + "character": 38 + }, + "identifier": "s", + "tokenType": 25, + "valueType": "string" + } + ], + "comments": [] + }, + { + "position": { + "line": 5, + "character": 29 + }, + "identifier": "NWNX_PushArgumentObject", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 5, + "character": 38 + }, + "identifier": "o", + "tokenType": 25, + "valueType": "object" + } + ], + "comments": [] + }, + { + "position": { + "line": 6, + "character": 23 + }, + "identifier": "NWNX_CallFunction", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 6, + "character": 37 + }, + "identifier": "plugin", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 6, + "character": 50 + }, + "identifier": "func", + "tokenType": 25, + "valueType": "string" + } + ], + "comments": [] + }, + { + "position": { + "line": 7, + "character": 27 + }, + "identifier": "NWNX_GetReturnValueInt", + "tokenType": 3, + "returnType": "int", + "params": [], + "comments": [] + }, + { + "position": { + "line": 8, + "character": 31 + }, + "identifier": "NWNX_GetReturnValueFloat", + "tokenType": 3, + "returnType": "float", + "params": [], + "comments": [] + }, + { + "position": { + "line": 9, + "character": 33 + }, + "identifier": "NWNX_GetReturnValueString", + "tokenType": 3, + "returnType": "string", + "params": [], + "comments": [] + }, + { + "position": { + "line": 10, + "character": 33 + }, + "identifier": "NWNX_GetReturnValueObject", + "tokenType": 3, + "returnType": "object", + "params": [], + "comments": [] + }, + { + "position": { + "line": 8, + "character": 22 + }, + "identifier": "GetStringRight", + "tokenType": 3, + "returnType": "string", + "params": [ + { + "position": { + "line": 8, + "character": 37 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 8, + "character": 49 + }, + "identifier": "nCount", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 9, + "character": 21 + }, + "identifier": "GetStringLeft", + "tokenType": 3, + "returnType": "string", + "params": [ + { + "position": { + "line": 9, + "character": 36 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { "position": { - "line": 7, - "character": 13 + "line": 9, + "character": 48 }, - "identifier": "NWNX_SkillRanks", - "tokenType": 21, - "valueType": "string", - "value": "\"NWNX_SkillRanks\"" + "identifier": "nCount", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 10, + "character": 20 }, - { + "identifier": "GetStringLength", + "tokenType": 3, + "returnType": "int", + "params": [ + { "position": { - "line": 14, - "character": 10 + "line": 10, + "character": 35 }, - "identifier": "NWNX_SKILLRANKS_KEY_ABILITY_STRENGTH", - "tokenType": 21, - "valueType": "int", - "value": "1" + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + } + ], + "comments": [] + }, + { + "position": { + "line": 11, + "character": 18 }, - { + "identifier": "FindSubString", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 11, + "character": 33 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { "position": { - "line": 15, - "character": 10 + "line": 11, + "character": 52 }, - "identifier": "NWNX_SKILLRANKS_KEY_ABILITY_DEXTERITY", - "tokenType": 21, - "valueType": "int", - "value": "2" + "identifier": "sSubString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 11, + "character": 64 + }, + "identifier": "nStart", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 90, + "character": 46 }, - { + "identifier": "NWNX_SkillRanks_GetSkillFeatCountForSkill", + "tokenType": 3, + "returnType": "int", + "params": [ + { "position": { - "line": 16, - "character": 10 + "line": 90, + "character": 57 }, - "identifier": "NWNX_SKILLRANKS_KEY_ABILITY_CONSTITUTION", - "tokenType": 21, - "valueType": "int", - "value": "4" + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 96, + "character": 62 }, - { + "identifier": "NWNX_SkillRanks_GetSkillFeat", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 97, + "character": 13 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 98, + "character": 12 + }, + "identifier": "iFeat", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 107, + "character": 44 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatForSkillByIndex", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 107, + "character": 55 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 107, + "character": 67 + }, + "identifier": "iIndex", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 113, + "character": 29 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeat", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 114, + "character": 45 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { "position": { - "line": 17, - "character": 10 + "line": 115, + "character": 26 }, - "identifier": "NWNX_SKILLRANKS_KEY_ABILITY_INTELLIGENCE", - "tokenType": 21, - "valueType": "int", - "value": "8" + "identifier": "createIfNonExistent", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 125, + "character": 34 }, - { + "identifier": "NWNX_SkillRanks_AddSkillFeatClass", + "tokenType": 3, + "returnType": "struct", + "params": [ + { "position": { - "line": 18, - "character": 10 + "line": 126, + "character": 45 }, - "identifier": "NWNX_SKILLRANKS_KEY_ABILITY_WISDOM", - "tokenType": 21, - "valueType": "int", - "value": "16" - }, - { - "position": { - "line": 19, - "character": 10 - }, - "identifier": "NWNX_SKILLRANKS_KEY_ABILITY_CHARISMA", - "tokenType": 21, - "valueType": "int", - "value": "32" - }, - { - "position": { - "line": 28, - "character": 10 - }, - "identifier": "NWNX_SKILLRANKS_KEY_ABILITY_CALC_MIN", - "tokenType": 21, - "valueType": "int", - "value": "64" - }, - { - "position": { - "line": 29, - "character": 10 - }, - "identifier": "NWNX_SKILLRANKS_KEY_ABILITY_CALC_MAX", - "tokenType": 21, - "valueType": "int", - "value": "128" - }, - { - "position": { - "line": 30, - "character": 10 - }, - "identifier": "NWNX_SKILLRANKS_KEY_ABILITY_CALC_AVERAGE", - "tokenType": 21, - "valueType": "int", - "value": "256" - }, - { - "position": { - "line": 31, - "character": 10 - }, - "identifier": "NWNX_SKILLRANKS_KEY_ABILITY_CALC_SUM", - "tokenType": 21, - "valueType": "int", - "value": "512" - }, - { - "position": { - "line": 84, - "character": 4 - }, - "identifier": "NWNX_SkillRanks_GetSkillFeatCountForSkill", - "tokenType": 3, - "returnType": "int", - "params": [ - { - "position": { - "line": 84, - "character": 50 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [ - "/// @param iSkill The skill to check the feat count.", - "/// @return The count of feats for a specific skill." - ] - }, - { - "position": { - "line": 90, - "character": 33 - }, - "identifier": "NWNX_SkillRanks_GetSkillFeat", - "tokenType": 3, - "returnType": "NWNX_SkillRanks_SkillFeat", - "params": [ - { - "position": { - "line": 91, - "character": 6 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 92, - "character": 6 - }, - "identifier": "iFeat", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [ - "/// @brief Returns a skill feat.", - "/// @param iSkill The skill.", - "/// @param iFeat The feat.", - "/// @return A constructed NWNX_SkillRanks_SkillFeat." - ] - }, - { - "position": { - "line": 101, - "character": 0 - }, - "identifier": "NWNX_SkillRanks_GetSkillFeatForSkillByIndex", - "tokenType": 3, - "returnType": "NWNX_SkillRanks_SkillFeat", - "params": [ - { - "position": { - "line": 101, - "character": 48 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 101, - "character": 60 - }, - "identifier": "iIndex", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [ - "/// @brief Returns a skill feat by index.", - "/// @remark Generally used in a loop with NWNX_SkillRanks_GetSkillFeatCountForSkill().", - "/// @param iSkill The skill.", - "/// @param iIndex The index in the list of feats for the skill.", - "/// @return A constructed NWNX_SkillRanks_SkillFeat." - ] - }, - { - "position": { - "line": 107, - "character": 0 - }, - "identifier": "NWNX_SkillRanks_SetSkillFeat", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 108, - "character": 35 - }, - "identifier": "skillFeat", - "tokenType": 25, - "valueType": "NWNX_SkillRanks_SkillFeat" - }, - { - "position": { - "line": 109, - "character": 6 - }, - "identifier": "createIfNonExistent", - "tokenType": 25, - "valueType": "int", - "defaultValue": "FALSE" - } - ], - "comments": [ - "/// @brief Modifies or creates a skill feat.", - "/// @param skillFeat The defined NWNX_SkillRanks_SkillFeat.", - "/// @param createIfNonExistent TRUE to create if the feat does not exist." - ] - }, - { - "position": { - "line": 119, - "character": 0 - }, - "identifier": "NWNX_SkillRanks_AddSkillFeatClass", - "tokenType": 3, - "returnType": "NWNX_SkillRanks_SkillFeat", - "params": [ - { - "position": { - "line": 120, - "character": 35 - }, - "identifier": "skillFeat", - "tokenType": 25, - "valueType": "NWNX_SkillRanks_SkillFeat" - }, - { - "position": { - "line": 121, - "character": 6 - }, - "identifier": "iClass", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [ - "/// @brief Add classes to a skill feat instead of working with the NWNX_SkillRanks_SkillFeat::sClasses string.", - "///", - "/// Manipulating the sClasses string in the NWNX_SkillRanks_SkillFeat struct can be difficult. This", - "/// function allows the builder to enter one class at a time.", - "/// @param skillFeat The NWNX_SkillRanks_SkillFeat for which the sClasses field will be modifier.", - "/// @param iClass The class to add to the Skill Feat.", - "/// @return The updated NWNX_SkillRanks_SkillFeat." - ] - }, - { - "position": { - "line": 130, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetSkillFeatFocusModifier", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 130, - "character": 51 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 130, - "character": 66 - }, - "identifier": "iEpic", - "tokenType": 25, - "valueType": "int", - "defaultValue": "FALSE" - } - ], - "comments": [ - "/// @brief Change the modifier value for Skill Focus and Epic Skill Focus feats.", - "///", - "/// The stock modifier on Skill Focus and Epic Skill Focus are 3 and 10 respectively, these can be", - "/// changed with this function.", - "/// @param iModifier The new value for the feat modifier.", - "/// @param iEpic Set to TRUE to change the value for Epic Skill Focus." - ] - }, - { - "position": { - "line": 134, - "character": 4 - }, - "identifier": "NWNX_SkillRanks_GetBlindnessPenalty", - "tokenType": 3, - "returnType": "int", - "params": [], - "comments": [ - "/// @brief Gets the current penalty to Dexterity based skills when blind.", - "/// @return The penalty to Dexterity when blind." - ] - }, - { - "position": { - "line": 139, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetBlindnessPenalty", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 139, - "character": 45 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [ - "/// @brief Set the value the Dexterity based skills get decreased due to blindness.", - "/// @remark Default is 4.", - "/// @param iModifier The penalty to Dexterity when blind." - ] - }, - { - "position": { - "line": 145, - "character": 4 - }, - "identifier": "NWNX_SkillRanks_GetAreaModifier", - "tokenType": 3, - "returnType": "int", - "params": [ - { - "position": { - "line": 145, - "character": 43 - }, - "identifier": "oArea", - "tokenType": 25, - "valueType": "object" - }, - { - "position": { - "line": 145, - "character": 54 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [ - "/// @brief Get a skill modifier for an area.", - "/// @param oArea The area.", - "/// @param iSkill The skill to check.", - "/// @return The modifier to that skill in the area." - ] - }, - { - "position": { - "line": 151, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetAreaModifier", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 151, - "character": 44 - }, - "identifier": "oArea", - "tokenType": 25, - "valueType": "object" - }, - { - "position": { - "line": 151, - "character": 55 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 151, - "character": 67 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [ - "/// @brief Sets a skill modifier for the area.", - "/// @param oArea The area.", - "/// @param iSkill The skill to change.", - "/// @param iModifier The modifier to the skill in the area." - ] - } + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 127, + "character": 13 + }, + "identifier": "iClass", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 136, + "character": 47 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeatFocusModifier", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 136, + "character": 61 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 136, + "character": 72 + }, + "identifier": "iEpic", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 140, + "character": 40 + }, + "identifier": "NWNX_SkillRanks_GetBlindnessPenalty", + "tokenType": 3, + "returnType": "int", + "params": [], + "comments": [] + }, + { + "position": { + "line": 145, + "character": 41 + }, + "identifier": "NWNX_SkillRanks_SetBlindnessPenalty", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 145, + "character": 55 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 151, + "character": 36 + }, + "identifier": "NWNX_SkillRanks_GetAreaModifier", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 151, + "character": 49 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 151, + "character": 61 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 157, + "character": 37 + }, + "identifier": "NWNX_SkillRanks_SetAreaModifier", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 157, + "character": 50 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 157, + "character": 62 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 157, + "character": 77 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 161, + "character": 46 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatCountForSkill", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 161, + "character": 57 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 171, + "character": 77 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatForSkillByIndex", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 171, + "character": 88 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 171, + "character": 100 + }, + "identifier": "iIndex", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 196, + "character": 34 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeat", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 196, + "character": 77 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 196, + "character": 102 + }, + "identifier": "createIfNonExistent", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 216, + "character": 67 + }, + "identifier": "NWNX_SkillRanks_AddSkillFeatClass", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 216, + "character": 110 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 216, + "character": 122 + }, + "identifier": "iClass", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 229, + "character": 47 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeatFocusModifier", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 229, + "character": 61 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 229, + "character": 76 + }, + "identifier": "epicFocus", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 238, + "character": 40 + }, + "identifier": "NWNX_SkillRanks_GetBlindnessPenalty", + "tokenType": 3, + "returnType": "int", + "params": [], + "comments": [] + }, + { + "position": { + "line": 247, + "character": 41 + }, + "identifier": "NWNX_SkillRanks_SetBlindnessPenalty", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 247, + "character": 55 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 255, + "character": 36 + }, + "identifier": "NWNX_SkillRanks_GetAreaModifier", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 255, + "character": 49 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 255, + "character": 61 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 266, + "character": 37 + }, + "identifier": "NWNX_SkillRanks_SetAreaModifier", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 266, + "character": 50 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 266, + "character": 62 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 266, + "character": 77 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 276, + "character": 62 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeat", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 276, + "character": 73 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 276, + "character": 84 + }, + "identifier": "iFeat", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 302, + "character": 10 + }, + "identifier": "main", + "tokenType": 3, + "returnType": "void", + "params": [], + "comments": [] + } ], "structComplexTokens": [ - { - "position": { - "line": 35, - "character": 7 - }, - "identifier": "NWNX_SkillRanks_SkillFeat", - "tokenType": 22, - "properties": [ - { - "position": { - "line": 37, - "character": 8 - }, - "identifier": "iSkill", - "tokenType": 10, - "valueType": "int" - }, - { - "position": { - "line": 38, - "character": 8 - }, - "identifier": "iFeat", - "tokenType": 10, - "valueType": "int" - }, - { - "position": { - "line": 41, - "character": 8 - }, - "identifier": "iModifier", - "tokenType": 10, - "valueType": "int" - }, - { - "position": { - "line": 45, - "character": 8 - }, - "identifier": "iFocusFeat", - "tokenType": 10, - "valueType": "int" - }, - { - "position": { - "line": 55, - "character": 11 - }, - "identifier": "sClasses", - "tokenType": 10, - "valueType": "string" - }, - { - "position": { - "line": 59, - "character": 10 - }, - "identifier": "fClassLevelMod", - "tokenType": 10, - "valueType": "float" - }, - { - "position": { - "line": 62, - "character": 8 - }, - "identifier": "iAreaFlagsRequired", - "tokenType": 10, - "valueType": "int" - }, - { - "position": { - "line": 65, - "character": 8 - }, - "identifier": "iAreaFlagsForbidden", - "tokenType": 10, - "valueType": "int" - }, - { - "position": { - "line": 69, - "character": 8 - }, - "identifier": "iDayOrNight", - "tokenType": 10, - "valueType": "int" - }, - { - "position": { - "line": 72, - "character": 8 - }, - "identifier": "bBypassArmorCheckPenalty", - "tokenType": 10, - "valueType": "int" - }, - { - "position": { - "line": 79, - "character": 8 - }, - "identifier": "iKeyAbilityMask", - "tokenType": 10, - "valueType": "int" - } - ] - } + { + "position": { + "line": 41, + "character": 7 + }, + "identifier": "NWNX_SkillRanks_SkillFeat", + "tokenType": 22, + "properties": [ + { + "position": { + "line": 43, + "character": 15 + }, + "identifier": "iSkill", + "tokenType": 10, + "valueType": "int" + }, + { + "position": { + "line": 44, + "character": 14 + }, + "identifier": "iFeat", + "tokenType": 10, + "valueType": "int" + }, + { + "position": { + "line": 47, + "character": 18 + }, + "identifier": "iModifier", + "tokenType": 10, + "valueType": "int" + }, + { + "position": { + "line": 51, + "character": 19 + }, + "identifier": "iFocusFeat", + "tokenType": 10, + "valueType": "int" + }, + { + "position": { + "line": 61, + "character": 20 + }, + "identifier": "sClasses", + "tokenType": 10, + "valueType": "string" + }, + { + "position": { + "line": 65, + "character": 25 + }, + "identifier": "fClassLevelMod", + "tokenType": 10, + "valueType": "float" + }, + { + "position": { + "line": 68, + "character": 27 + }, + "identifier": "iAreaFlagsRequired", + "tokenType": 10, + "valueType": "int" + }, + { + "position": { + "line": 71, + "character": 28 + }, + "identifier": "iAreaFlagsForbidden", + "tokenType": 10, + "valueType": "int" + }, + { + "position": { + "line": 75, + "character": 20 + }, + "identifier": "iDayOrNight", + "tokenType": 10, + "valueType": "int" + }, + { + "position": { + "line": 78, + "character": 33 + }, + "identifier": "bBypassArmorCheckPenalty", + "tokenType": 10, + "valueType": "int" + }, + { + "position": { + "line": 85, + "character": 24 + }, + "identifier": "iKeyAbilityMask", + "tokenType": 10, + "valueType": "int" + } + ] + } ], - "children": [ - "nwnx" - ] + "children": [] } \ No newline at end of file diff --git a/server/test/static/localScopeTokensWithContext.json b/server/test/static/localScopeTokensWithContext.json index 292cddc..c3a67ba 100644 --- a/server/test/static/localScopeTokensWithContext.json +++ b/server/test/static/localScopeTokensWithContext.json @@ -1,345 +1,1476 @@ { - "functionsComplexTokens": [ - { - "position": { - "line": 270, - "character": 33 - }, - "identifier": "NWNX_SkillRanks_GetSkillFeat", - "tokenType": 3, - "returnType": "NWNX_SkillRanks_SkillFeat", - "params": [ - { - "position": { - "line": 270, - "character": 66 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 270, - "character": 78 - }, - "identifier": "iFeat", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [ - { - "position": { - "line": 278, - "character": 37 - }, - "identifier": "skillFeat", - "tokenType": 6, - "valueType": "NWNX_SkillRanks_SkillFeat" - }, - { - "position": { - "line": 272, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - } - ] + "functionsComplexTokens": [ + { + "position": { + "line": 2, + "character": 26 + }, + "identifier": "NWNX_PushArgumentInt", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 2, + "character": 32 + }, + "identifier": "i", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 3, + "character": 28 + }, + "identifier": "NWNX_PushArgumentFloat", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 3, + "character": 36 + }, + "identifier": "f", + "tokenType": 25, + "valueType": "float" + } + ], + "comments": [] + }, + { + "position": { + "line": 4, + "character": 29 + }, + "identifier": "NWNX_PushArgumentString", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 4, + "character": 38 + }, + "identifier": "s", + "tokenType": 25, + "valueType": "string" + } + ], + "comments": [] + }, + { + "position": { + "line": 5, + "character": 29 + }, + "identifier": "NWNX_PushArgumentObject", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 5, + "character": 38 + }, + "identifier": "o", + "tokenType": 25, + "valueType": "object" + } + ], + "comments": [] + }, + { + "position": { + "line": 6, + "character": 23 + }, + "identifier": "NWNX_CallFunction", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 6, + "character": 37 + }, + "identifier": "plugin", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 6, + "character": 50 + }, + "identifier": "func", + "tokenType": 25, + "valueType": "string" + } + ], + "comments": [] + }, + { + "position": { + "line": 7, + "character": 27 + }, + "identifier": "NWNX_GetReturnValueInt", + "tokenType": 3, + "returnType": "int", + "params": [], + "comments": [] + }, + { + "position": { + "line": 8, + "character": 31 + }, + "identifier": "NWNX_GetReturnValueFloat", + "tokenType": 3, + "returnType": "float", + "params": [], + "comments": [] + }, + { + "position": { + "line": 9, + "character": 33 + }, + "identifier": "NWNX_GetReturnValueString", + "tokenType": 3, + "returnType": "string", + "params": [], + "comments": [] + }, + { + "position": { + "line": 10, + "character": 33 + }, + "identifier": "NWNX_GetReturnValueObject", + "tokenType": 3, + "returnType": "object", + "params": [], + "comments": [] + }, + { + "position": { + "line": 8, + "character": 22 + }, + "identifier": "GetStringRight", + "tokenType": 3, + "returnType": "string", + "params": [ + { + "position": { + "line": 8, + "character": 37 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 8, + "character": 49 + }, + "identifier": "nCount", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 9, + "character": 21 + }, + "identifier": "GetStringLeft", + "tokenType": 3, + "returnType": "string", + "params": [ + { + "position": { + "line": 9, + "character": 36 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 9, + "character": 48 + }, + "identifier": "nCount", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 10, + "character": 20 + }, + "identifier": "GetStringLength", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 10, + "character": 35 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + } + ], + "comments": [] + }, + { + "position": { + "line": 11, + "character": 18 + }, + "identifier": "FindSubString", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 11, + "character": 33 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 11, + "character": 52 + }, + "identifier": "sSubString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 11, + "character": 64 + }, + "identifier": "nStart", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 90, + "character": 46 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatCountForSkill", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 90, + "character": 57 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 96, + "character": 62 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeat", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 97, + "character": 13 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 98, + "character": 12 + }, + "identifier": "iFeat", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 107, + "character": 44 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatForSkillByIndex", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 107, + "character": 55 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 260, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetAreaModifier", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 260, - "character": 44 - }, - "identifier": "oArea", - "tokenType": 25, - "valueType": "object" - }, - { - "position": { - "line": 260, - "character": 55 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 260, - "character": 67 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [] + "position": { + "line": 107, + "character": 67 + }, + "identifier": "iIndex", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 113, + "character": 29 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeat", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 114, + "character": 45 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" }, { - "position": { - "line": 249, - "character": 4 - }, - "identifier": "NWNX_SkillRanks_GetAreaModifier", - "tokenType": 3, - "returnType": "int", - "params": [ - { - "position": { - "line": 249, - "character": 43 - }, - "identifier": "oArea", - "tokenType": 25, - "valueType": "object" - }, - { - "position": { - "line": 249, - "character": 54 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [] + "position": { + "line": 115, + "character": 26 + }, + "identifier": "createIfNonExistent", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 125, + "character": 34 + }, + "identifier": "NWNX_SkillRanks_AddSkillFeatClass", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 126, + "character": 45 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" }, { - "position": { - "line": 241, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetBlindnessPenalty", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 241, - "character": 45 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [] + "position": { + "line": 127, + "character": 13 + }, + "identifier": "iClass", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 136, + "character": 47 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeatFocusModifier", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 136, + "character": 61 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 232, - "character": 4 - }, - "identifier": "NWNX_SkillRanks_GetBlindnessPenalty", - "tokenType": 3, - "returnType": "int", - "params": [], - "comments": [], - "variables": [] + "position": { + "line": 136, + "character": 72 + }, + "identifier": "iEpic", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 140, + "character": 40 + }, + "identifier": "NWNX_SkillRanks_GetBlindnessPenalty", + "tokenType": 3, + "returnType": "int", + "params": [], + "comments": [] + }, + { + "position": { + "line": 145, + "character": 41 + }, + "identifier": "NWNX_SkillRanks_SetBlindnessPenalty", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 145, + "character": 55 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 151, + "character": 36 + }, + "identifier": "NWNX_SkillRanks_GetAreaModifier", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 151, + "character": 49 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" }, { - "position": { - "line": 223, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetSkillFeatFocusModifier", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 223, - "character": 51 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 223, - "character": 66 - }, - "identifier": "epicFocus", - "tokenType": 25, - "valueType": "int", - "defaultValue": "FALSE" - } - ], - "comments": [], - "variables": [] + "position": { + "line": 151, + "character": 61 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 157, + "character": 37 + }, + "identifier": "NWNX_SkillRanks_SetAreaModifier", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 157, + "character": 50 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" }, { - "position": { - "line": 210, - "character": 33 - }, - "identifier": "NWNX_SkillRanks_AddSkillFeatClass", - "tokenType": 3, - "returnType": "NWNX_SkillRanks_SkillFeat", - "params": [ - { - "position": { - "line": 210, - "character": 100 - }, - "identifier": "skillFeat", - "tokenType": 25, - "valueType": "NWNX_SkillRanks_SkillFeat" - }, - { - "position": { - "line": 210, - "character": 115 - }, - "identifier": "iClass", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [] + "position": { + "line": 157, + "character": 62 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 190, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetSkillFeat", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 190, - "character": 67 - }, - "identifier": "skillFeat", - "tokenType": 25, - "valueType": "NWNX_SkillRanks_SkillFeat" - }, - { - "position": { - "line": 190, - "character": 82 - }, - "identifier": "createIfNonExistent", - "tokenType": 25, - "valueType": "int", - "defaultValue": "FALSE" - } - ], - "comments": [], - "variables": [] + "position": { + "line": 157, + "character": 77 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 161, + "character": 46 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatCountForSkill", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 161, + "character": 57 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 171, + "character": 77 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatForSkillByIndex", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 171, + "character": 88 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 165, - "character": 33 - }, - "identifier": "NWNX_SkillRanks_GetSkillFeatForSkillByIndex", - "tokenType": 3, - "returnType": "NWNX_SkillRanks_SkillFeat", - "params": [ - { - "position": { - "line": 165, - "character": 81 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 165, - "character": 93 - }, - "identifier": "iIndex", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [] + "position": { + "line": 171, + "character": 100 + }, + "identifier": "iIndex", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 196, + "character": 34 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeat", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 196, + "character": 77 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" }, { - "position": { - "line": 155, - "character": 4 - }, - "identifier": "NWNX_SkillRanks_GetSkillFeatCountForSkill", - "tokenType": 3, - "returnType": "int", - "params": [ - { - "position": { - "line": 155, - "character": 50 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [] + "position": { + "line": 196, + "character": 102 + }, + "identifier": "createIfNonExistent", + "tokenType": 25, + "valueType": "int" } - ], - "functionVariablesComplexTokens": [ - { - "position": { - "line": 278, - "character": 37 - }, - "identifier": "skillFeat", - "tokenType": 6, - "valueType": "NWNX_SkillRanks_SkillFeat" + ], + "comments": [] + }, + { + "position": { + "line": 216, + "character": 67 + }, + "identifier": "NWNX_SkillRanks_AddSkillFeatClass", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 216, + "character": 110 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 216, + "character": 122 + }, + "identifier": "iClass", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 229, + "character": 47 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeatFocusModifier", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 229, + "character": 61 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 272, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" + "position": { + "line": 229, + "character": 76 + }, + "identifier": "epicFocus", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 238, + "character": 40 + }, + "identifier": "NWNX_SkillRanks_GetBlindnessPenalty", + "tokenType": 3, + "returnType": "int", + "params": [], + "comments": [] + }, + { + "position": { + "line": 247, + "character": 41 + }, + "identifier": "NWNX_SkillRanks_SetBlindnessPenalty", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 247, + "character": 55 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 255, + "character": 36 + }, + "identifier": "NWNX_SkillRanks_GetAreaModifier", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 255, + "character": 49 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" }, { - "position": { - "line": 270, - "character": 66 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 255, + "character": 61 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 266, + "character": 37 + }, + "identifier": "NWNX_SkillRanks_SetAreaModifier", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 266, + "character": 50 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 266, + "character": 62 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 266, + "character": 77 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 276, + "character": 62 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeat", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 276, + "character": 73 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 270, - "character": 78 - }, - "identifier": "iFeat", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 276, + "character": 84 + }, + "identifier": "iFeat", + "tokenType": 25, + "valueType": "int" } - ] + ], + "comments": [] + } + ], + "functionVariablesComplexTokens": [ + { + "position": { + "line": 43, + "character": 15 + }, + "identifier": "iSkill", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 44, + "character": 14 + }, + "identifier": "iFeat", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 47, + "character": 18 + }, + "identifier": "iModifier", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 51, + "character": 19 + }, + "identifier": "iFocusFeat", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 61, + "character": 20 + }, + "identifier": "sClasses", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 65, + "character": 25 + }, + "identifier": "fClassLevelMod", + "tokenType": 6, + "valueType": "float" + }, + { + "position": { + "line": 68, + "character": 27 + }, + "identifier": "iAreaFlagsRequired", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 71, + "character": 28 + }, + "identifier": "iAreaFlagsForbidden", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 75, + "character": 20 + }, + "identifier": "iDayOrNight", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 78, + "character": 33 + }, + "identifier": "bBypassArmorCheckPenalty", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 85, + "character": 24 + }, + "identifier": "iKeyAbilityMask", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 2, + "character": 32 + }, + "identifier": "i", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 3, + "character": 36 + }, + "identifier": "f", + "tokenType": 25, + "valueType": "float" + }, + { + "position": { + "line": 4, + "character": 38 + }, + "identifier": "s", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 5, + "character": 38 + }, + "identifier": "o", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 6, + "character": 37 + }, + "identifier": "plugin", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 6, + "character": 50 + }, + "identifier": "func", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 8, + "character": 37 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 8, + "character": 49 + }, + "identifier": "nCount", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 9, + "character": 36 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 9, + "character": 48 + }, + "identifier": "nCount", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 10, + "character": 35 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 11, + "character": 33 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 11, + "character": 52 + }, + "identifier": "sSubString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 11, + "character": 64 + }, + "identifier": "nStart", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 90, + "character": 57 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 97, + "character": 13 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 98, + "character": 12 + }, + "identifier": "iFeat", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 107, + "character": 55 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 107, + "character": 67 + }, + "identifier": "iIndex", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 114, + "character": 45 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 115, + "character": 26 + }, + "identifier": "createIfNonExistent", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 126, + "character": 45 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 127, + "character": 13 + }, + "identifier": "iClass", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 136, + "character": 61 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 136, + "character": 72 + }, + "identifier": "iEpic", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 145, + "character": 55 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 151, + "character": 49 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 151, + "character": 61 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 157, + "character": 50 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 157, + "character": 62 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 157, + "character": 77 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 161, + "character": 57 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 163, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 171, + "character": 88 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 171, + "character": 100 + }, + "identifier": "iIndex", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 173, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 179, + "character": 47 + }, + "identifier": "skillFeat", + "tokenType": 6, + "valueType": "struct" + }, + { + "position": { + "line": 196, + "character": 77 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 196, + "character": 102 + }, + "identifier": "createIfNonExistent", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 198, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 216, + "character": 110 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 216, + "character": 122 + }, + "identifier": "iClass", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 220, + "character": 14 + }, + "identifier": "i", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 221, + "character": 20 + }, + "identifier": "sPad", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 229, + "character": 61 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 229, + "character": 76 + }, + "identifier": "epicFocus", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 231, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 240, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 247, + "character": 55 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 249, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 255, + "character": 49 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 255, + "character": 61 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 257, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 266, + "character": 50 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 266, + "character": 62 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 266, + "character": 77 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 268, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 276, + "character": 73 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 276, + "character": 84 + }, + "identifier": "iFeat", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 278, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 284, + "character": 47 + }, + "identifier": "skillFeat", + "tokenType": 6, + "valueType": "struct" + } + ] } \ No newline at end of file diff --git a/server/test/static/localScopeTokensWithoutContext.json b/server/test/static/localScopeTokensWithoutContext.json index 42b6b22..c7b7e95 100644 --- a/server/test/static/localScopeTokensWithoutContext.json +++ b/server/test/static/localScopeTokensWithoutContext.json @@ -1,687 +1,1487 @@ { - "functionsComplexTokens": [ - { - "position": { - "line": 270, - "character": 33 - }, - "identifier": "NWNX_SkillRanks_GetSkillFeat", - "tokenType": 3, - "returnType": "NWNX_SkillRanks_SkillFeat", - "params": [ - { - "position": { - "line": 270, - "character": 66 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 270, - "character": 78 - }, - "identifier": "iFeat", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [ - { - "position": { - "line": 278, - "character": 37 - }, - "identifier": "skillFeat", - "tokenType": 6, - "valueType": "NWNX_SkillRanks_SkillFeat" - }, - { - "position": { - "line": 272, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - } - ] - }, + "functionsComplexTokens": [ + { + "position": { + "line": 2, + "character": 26 + }, + "identifier": "NWNX_PushArgumentInt", + "tokenType": 3, + "returnType": "void", + "params": [ { - "position": { - "line": 260, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetAreaModifier", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 260, - "character": 44 - }, - "identifier": "oArea", - "tokenType": 25, - "valueType": "object" - }, - { - "position": { - "line": 260, - "character": 55 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 260, - "character": 67 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [ - { - "position": { - "line": 262, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - } - ] - }, + "position": { + "line": 2, + "character": 32 + }, + "identifier": "i", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 3, + "character": 28 + }, + "identifier": "NWNX_PushArgumentFloat", + "tokenType": 3, + "returnType": "void", + "params": [ { - "position": { - "line": 249, - "character": 4 - }, - "identifier": "NWNX_SkillRanks_GetAreaModifier", - "tokenType": 3, - "returnType": "int", - "params": [ - { - "position": { - "line": 249, - "character": 43 - }, - "identifier": "oArea", - "tokenType": 25, - "valueType": "object" - }, - { - "position": { - "line": 249, - "character": 54 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [ - { - "position": { - "line": 251, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - } - ] - }, + "position": { + "line": 3, + "character": 36 + }, + "identifier": "f", + "tokenType": 25, + "valueType": "float" + } + ], + "comments": [] + }, + { + "position": { + "line": 4, + "character": 29 + }, + "identifier": "NWNX_PushArgumentString", + "tokenType": 3, + "returnType": "void", + "params": [ { - "position": { - "line": 241, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetBlindnessPenalty", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 241, - "character": 45 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [ - { - "position": { - "line": 243, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - } - ] - }, + "position": { + "line": 4, + "character": 38 + }, + "identifier": "s", + "tokenType": 25, + "valueType": "string" + } + ], + "comments": [] + }, + { + "position": { + "line": 5, + "character": 29 + }, + "identifier": "NWNX_PushArgumentObject", + "tokenType": 3, + "returnType": "void", + "params": [ { - "position": { - "line": 232, - "character": 4 - }, - "identifier": "NWNX_SkillRanks_GetBlindnessPenalty", - "tokenType": 3, - "returnType": "int", - "params": [], - "comments": [], - "variables": [ - { - "position": { - "line": 234, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - } - ] - }, + "position": { + "line": 5, + "character": 38 + }, + "identifier": "o", + "tokenType": 25, + "valueType": "object" + } + ], + "comments": [] + }, + { + "position": { + "line": 6, + "character": 23 + }, + "identifier": "NWNX_CallFunction", + "tokenType": 3, + "returnType": "void", + "params": [ { - "position": { - "line": 223, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetSkillFeatFocusModifier", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 223, - "character": 51 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 223, - "character": 66 - }, - "identifier": "epicFocus", - "tokenType": 25, - "valueType": "int", - "defaultValue": "FALSE" - } - ], - "comments": [], - "variables": [ - { - "position": { - "line": 225, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - } - ] + "position": { + "line": 6, + "character": 37 + }, + "identifier": "plugin", + "tokenType": 25, + "valueType": "string" }, { - "position": { - "line": 210, - "character": 33 - }, - "identifier": "NWNX_SkillRanks_AddSkillFeatClass", - "tokenType": 3, - "returnType": "NWNX_SkillRanks_SkillFeat", - "params": [ - { - "position": { - "line": 210, - "character": 100 - }, - "identifier": "skillFeat", - "tokenType": 25, - "valueType": "NWNX_SkillRanks_SkillFeat" - }, - { - "position": { - "line": 210, - "character": 115 - }, - "identifier": "iClass", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [ - { - "position": { - "line": 215, - "character": 15 - }, - "identifier": "sPad", - "tokenType": 6, - "valueType": "string" - }, - { - "position": { - "line": 214, - "character": 12 - }, - "identifier": "i", - "tokenType": 6, - "valueType": "int" - } - ] - }, + "position": { + "line": 6, + "character": 50 + }, + "identifier": "func", + "tokenType": 25, + "valueType": "string" + } + ], + "comments": [] + }, + { + "position": { + "line": 7, + "character": 27 + }, + "identifier": "NWNX_GetReturnValueInt", + "tokenType": 3, + "returnType": "int", + "params": [], + "comments": [] + }, + { + "position": { + "line": 8, + "character": 31 + }, + "identifier": "NWNX_GetReturnValueFloat", + "tokenType": 3, + "returnType": "float", + "params": [], + "comments": [] + }, + { + "position": { + "line": 9, + "character": 33 + }, + "identifier": "NWNX_GetReturnValueString", + "tokenType": 3, + "returnType": "string", + "params": [], + "comments": [] + }, + { + "position": { + "line": 10, + "character": 33 + }, + "identifier": "NWNX_GetReturnValueObject", + "tokenType": 3, + "returnType": "object", + "params": [], + "comments": [] + }, + { + "position": { + "line": 8, + "character": 22 + }, + "identifier": "GetStringRight", + "tokenType": 3, + "returnType": "string", + "params": [ { - "position": { - "line": 190, - "character": 5 - }, - "identifier": "NWNX_SkillRanks_SetSkillFeat", - "tokenType": 3, - "returnType": "void", - "params": [ - { - "position": { - "line": 190, - "character": 67 - }, - "identifier": "skillFeat", - "tokenType": 25, - "valueType": "NWNX_SkillRanks_SkillFeat" - }, - { - "position": { - "line": 190, - "character": 82 - }, - "identifier": "createIfNonExistent", - "tokenType": 25, - "valueType": "int", - "defaultValue": "FALSE" - } - ], - "comments": [], - "variables": [ - { - "position": { - "line": 192, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - } - ] + "position": { + "line": 8, + "character": 37 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" }, { - "position": { - "line": 165, - "character": 33 - }, - "identifier": "NWNX_SkillRanks_GetSkillFeatForSkillByIndex", - "tokenType": 3, - "returnType": "NWNX_SkillRanks_SkillFeat", - "params": [ - { - "position": { - "line": 165, - "character": 81 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - }, - { - "position": { - "line": 165, - "character": 93 - }, - "identifier": "iIndex", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [ - { - "position": { - "line": 173, - "character": 37 - }, - "identifier": "skillFeat", - "tokenType": 6, - "valueType": "NWNX_SkillRanks_SkillFeat" - }, - { - "position": { - "line": 167, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - } - ] + "position": { + "line": 8, + "character": 49 + }, + "identifier": "nCount", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 9, + "character": 21 + }, + "identifier": "GetStringLeft", + "tokenType": 3, + "returnType": "string", + "params": [ + { + "position": { + "line": 9, + "character": 36 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" }, { - "position": { - "line": 155, - "character": 4 - }, - "identifier": "NWNX_SkillRanks_GetSkillFeatCountForSkill", - "tokenType": 3, - "returnType": "int", - "params": [ - { - "position": { - "line": 155, - "character": 50 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" - } - ], - "comments": [], - "variables": [ - { - "position": { - "line": 157, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - } - ] + "position": { + "line": 9, + "character": 48 + }, + "identifier": "nCount", + "tokenType": 25, + "valueType": "int" } - ], - "functionVariablesComplexTokens": [ - { - "position": { - "line": 278, - "character": 37 - }, - "identifier": "skillFeat", - "tokenType": 6, - "valueType": "NWNX_SkillRanks_SkillFeat" - }, + ], + "comments": [] + }, + { + "position": { + "line": 10, + "character": 20 + }, + "identifier": "GetStringLength", + "tokenType": 3, + "returnType": "int", + "params": [ { - "position": { - "line": 272, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - }, + "position": { + "line": 10, + "character": 35 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + } + ], + "comments": [] + }, + { + "position": { + "line": 11, + "character": 18 + }, + "identifier": "FindSubString", + "tokenType": 3, + "returnType": "int", + "params": [ { - "position": { - "line": 270, - "character": 66 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 11, + "character": 33 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" }, { - "position": { - "line": 270, - "character": 78 - }, - "identifier": "iFeat", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 11, + "character": 52 + }, + "identifier": "sSubString", + "tokenType": 25, + "valueType": "string" }, { - "position": { - "line": 262, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - }, + "position": { + "line": 11, + "character": 64 + }, + "identifier": "nStart", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 90, + "character": 46 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatCountForSkill", + "tokenType": 3, + "returnType": "int", + "params": [ { - "position": { - "line": 260, - "character": 44 - }, - "identifier": "oArea", - "tokenType": 25, - "valueType": "object" - }, + "position": { + "line": 90, + "character": 57 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 96, + "character": 62 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeat", + "tokenType": 3, + "returnType": "struct", + "params": [ { - "position": { - "line": 260, - "character": 55 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 97, + "character": 13 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 260, - "character": 67 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - }, + "position": { + "line": 98, + "character": 12 + }, + "identifier": "iFeat", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 107, + "character": 44 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatForSkillByIndex", + "tokenType": 3, + "returnType": "struct", + "params": [ { - "position": { - "line": 251, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" + "position": { + "line": 107, + "character": 55 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 249, - "character": 43 - }, - "identifier": "oArea", - "tokenType": 25, - "valueType": "object" - }, + "position": { + "line": 107, + "character": 67 + }, + "identifier": "iIndex", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 113, + "character": 29 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeat", + "tokenType": 3, + "returnType": "void", + "params": [ { - "position": { - "line": 249, - "character": 54 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 114, + "character": 45 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" }, { - "position": { - "line": 243, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - }, + "position": { + "line": 115, + "character": 26 + }, + "identifier": "createIfNonExistent", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 125, + "character": 34 + }, + "identifier": "NWNX_SkillRanks_AddSkillFeatClass", + "tokenType": 3, + "returnType": "struct", + "params": [ { - "position": { - "line": 241, - "character": 45 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 126, + "character": 45 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" }, { - "position": { - "line": 234, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" - }, + "position": { + "line": 127, + "character": 13 + }, + "identifier": "iClass", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 136, + "character": 47 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeatFocusModifier", + "tokenType": 3, + "returnType": "void", + "params": [ { - "position": { - "line": 225, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" + "position": { + "line": 136, + "character": 61 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 223, - "character": 51 - }, - "identifier": "iModifier", - "tokenType": 25, - "valueType": "int" - }, + "position": { + "line": 136, + "character": 72 + }, + "identifier": "iEpic", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 140, + "character": 40 + }, + "identifier": "NWNX_SkillRanks_GetBlindnessPenalty", + "tokenType": 3, + "returnType": "int", + "params": [], + "comments": [] + }, + { + "position": { + "line": 145, + "character": 41 + }, + "identifier": "NWNX_SkillRanks_SetBlindnessPenalty", + "tokenType": 3, + "returnType": "void", + "params": [ { - "position": { - "line": 223, - "character": 66 - }, - "identifier": "epicFocus", - "tokenType": 25, - "valueType": "int" - }, + "position": { + "line": 145, + "character": 55 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 151, + "character": 36 + }, + "identifier": "NWNX_SkillRanks_GetAreaModifier", + "tokenType": 3, + "returnType": "int", + "params": [ { - "position": { - "line": 215, - "character": 15 - }, - "identifier": "sPad", - "tokenType": 6, - "valueType": "string" + "position": { + "line": 151, + "character": 49 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" }, { - "position": { - "line": 214, - "character": 12 - }, - "identifier": "i", - "tokenType": 6, - "valueType": "int" - }, + "position": { + "line": 151, + "character": 61 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 157, + "character": 37 + }, + "identifier": "NWNX_SkillRanks_SetAreaModifier", + "tokenType": 3, + "returnType": "void", + "params": [ { - "position": { - "line": 210, - "character": 100 - }, - "identifier": "skillFeat", - "tokenType": 25, - "valueType": "NWNX_SkillRanks_SkillFeat" + "position": { + "line": 157, + "character": 50 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" }, { - "position": { - "line": 210, - "character": 115 - }, - "identifier": "iClass", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 157, + "character": 62 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 192, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" + "position": { + "line": 157, + "character": 77 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 161, + "character": 46 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatCountForSkill", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 161, + "character": 57 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 171, + "character": 77 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeatForSkillByIndex", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 171, + "character": 88 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 190, - "character": 67 - }, - "identifier": "skillFeat", - "tokenType": 25, - "valueType": "NWNX_SkillRanks_SkillFeat" + "position": { + "line": 171, + "character": 100 + }, + "identifier": "iIndex", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 196, + "character": 34 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeat", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 196, + "character": 77 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" }, { - "position": { - "line": 190, - "character": 82 - }, - "identifier": "createIfNonExistent", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 196, + "character": 102 + }, + "identifier": "createIfNonExistent", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 216, + "character": 67 + }, + "identifier": "NWNX_SkillRanks_AddSkillFeatClass", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 216, + "character": 110 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" }, { - "position": { - "line": 173, - "character": 37 - }, - "identifier": "skillFeat", - "tokenType": 6, - "valueType": "NWNX_SkillRanks_SkillFeat" + "position": { + "line": 216, + "character": 122 + }, + "identifier": "iClass", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 229, + "character": 47 + }, + "identifier": "NWNX_SkillRanks_SetSkillFeatFocusModifier", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 229, + "character": 61 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 167, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" + "position": { + "line": 229, + "character": 76 + }, + "identifier": "epicFocus", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 238, + "character": 40 + }, + "identifier": "NWNX_SkillRanks_GetBlindnessPenalty", + "tokenType": 3, + "returnType": "int", + "params": [], + "comments": [] + }, + { + "position": { + "line": 247, + "character": 41 + }, + "identifier": "NWNX_SkillRanks_SetBlindnessPenalty", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 247, + "character": 55 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 255, + "character": 36 + }, + "identifier": "NWNX_SkillRanks_GetAreaModifier", + "tokenType": 3, + "returnType": "int", + "params": [ + { + "position": { + "line": 255, + "character": 49 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" }, { - "position": { - "line": 165, - "character": 81 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 255, + "character": 61 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 266, + "character": 37 + }, + "identifier": "NWNX_SkillRanks_SetAreaModifier", + "tokenType": 3, + "returnType": "void", + "params": [ + { + "position": { + "line": 266, + "character": 50 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" }, { - "position": { - "line": 165, - "character": 93 - }, - "identifier": "iIndex", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 266, + "character": 62 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 157, - "character": 11 - }, - "identifier": "sFunc", - "tokenType": 6, - "valueType": "string" + "position": { + "line": 266, + "character": 77 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + } + ], + "comments": [] + }, + { + "position": { + "line": 276, + "character": 62 + }, + "identifier": "NWNX_SkillRanks_GetSkillFeat", + "tokenType": 3, + "returnType": "struct", + "params": [ + { + "position": { + "line": 276, + "character": 73 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" }, { - "position": { - "line": 155, - "character": 50 - }, - "identifier": "iSkill", - "tokenType": 25, - "valueType": "int" + "position": { + "line": 276, + "character": 84 + }, + "identifier": "iFeat", + "tokenType": 25, + "valueType": "int" } - ] + ], + "comments": [] + }, + { + "position": { + "line": 302, + "character": 10 + }, + "identifier": "main", + "tokenType": 3, + "returnType": "void", + "params": [], + "comments": [] + } + ], + "functionVariablesComplexTokens": [ + { + "position": { + "line": 43, + "character": 15 + }, + "identifier": "iSkill", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 44, + "character": 14 + }, + "identifier": "iFeat", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 47, + "character": 18 + }, + "identifier": "iModifier", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 51, + "character": 19 + }, + "identifier": "iFocusFeat", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 61, + "character": 20 + }, + "identifier": "sClasses", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 65, + "character": 25 + }, + "identifier": "fClassLevelMod", + "tokenType": 6, + "valueType": "float" + }, + { + "position": { + "line": 68, + "character": 27 + }, + "identifier": "iAreaFlagsRequired", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 71, + "character": 28 + }, + "identifier": "iAreaFlagsForbidden", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 75, + "character": 20 + }, + "identifier": "iDayOrNight", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 78, + "character": 33 + }, + "identifier": "bBypassArmorCheckPenalty", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 85, + "character": 24 + }, + "identifier": "iKeyAbilityMask", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 2, + "character": 32 + }, + "identifier": "i", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 3, + "character": 36 + }, + "identifier": "f", + "tokenType": 25, + "valueType": "float" + }, + { + "position": { + "line": 4, + "character": 38 + }, + "identifier": "s", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 5, + "character": 38 + }, + "identifier": "o", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 6, + "character": 37 + }, + "identifier": "plugin", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 6, + "character": 50 + }, + "identifier": "func", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 8, + "character": 37 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 8, + "character": 49 + }, + "identifier": "nCount", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 9, + "character": 36 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 9, + "character": 48 + }, + "identifier": "nCount", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 10, + "character": 35 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 11, + "character": 33 + }, + "identifier": "sString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 11, + "character": 52 + }, + "identifier": "sSubString", + "tokenType": 25, + "valueType": "string" + }, + { + "position": { + "line": 11, + "character": 64 + }, + "identifier": "nStart", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 90, + "character": 57 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 97, + "character": 13 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 98, + "character": 12 + }, + "identifier": "iFeat", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 107, + "character": 55 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 107, + "character": 67 + }, + "identifier": "iIndex", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 114, + "character": 45 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 115, + "character": 26 + }, + "identifier": "createIfNonExistent", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 126, + "character": 45 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 127, + "character": 13 + }, + "identifier": "iClass", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 136, + "character": 61 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 136, + "character": 72 + }, + "identifier": "iEpic", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 145, + "character": 55 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 151, + "character": 49 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 151, + "character": 61 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 157, + "character": 50 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 157, + "character": 62 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 157, + "character": 77 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 161, + "character": 57 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 163, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 171, + "character": 88 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 171, + "character": 100 + }, + "identifier": "iIndex", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 173, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 179, + "character": 47 + }, + "identifier": "skillFeat", + "tokenType": 6, + "valueType": "struct" + }, + { + "position": { + "line": 196, + "character": 77 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 196, + "character": 102 + }, + "identifier": "createIfNonExistent", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 198, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 216, + "character": 110 + }, + "identifier": "skillFeat", + "tokenType": 25, + "valueType": "struct" + }, + { + "position": { + "line": 216, + "character": 122 + }, + "identifier": "iClass", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 220, + "character": 14 + }, + "identifier": "i", + "tokenType": 6, + "valueType": "int" + }, + { + "position": { + "line": 221, + "character": 20 + }, + "identifier": "sPad", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 229, + "character": 61 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 229, + "character": 76 + }, + "identifier": "epicFocus", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 231, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 240, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 247, + "character": 55 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 249, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 255, + "character": 49 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 255, + "character": 61 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 257, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 266, + "character": 50 + }, + "identifier": "oArea", + "tokenType": 25, + "valueType": "object" + }, + { + "position": { + "line": 266, + "character": 62 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 266, + "character": 77 + }, + "identifier": "iModifier", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 268, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 276, + "character": 73 + }, + "identifier": "iSkill", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 276, + "character": 84 + }, + "identifier": "iFeat", + "tokenType": 25, + "valueType": "int" + }, + { + "position": { + "line": 278, + "character": 17 + }, + "identifier": "sFunc", + "tokenType": 6, + "valueType": "string" + }, + { + "position": { + "line": 284, + "character": 47 + }, + "identifier": "skillFeat", + "tokenType": 6, + "valueType": "struct" + } + ] } \ No newline at end of file diff --git a/server/test/static/test.nss b/server/test/static/test.nss index 39bf94d..1bed620 100644 --- a/server/test/static/test.nss +++ b/server/test/static/test.nss @@ -5,6 +5,12 @@ /// @file nwnx_skillranks.nss #include "nwnx" +// Standard NWScript function declarations (normally from nwscript.nss) +string GetStringRight(string sString, int nCount); +string GetStringLeft(string sString, int nCount); +int GetStringLength(string sString); +int FindSubString(string sString, string sSubString, int nStart = 0); + const string NWNX_SkillRanks = "NWNX_SkillRanks"; ///< @private /// @name SkillRanks Key Abilities @@ -292,3 +298,7 @@ struct NWNX_SkillRanks_SkillFeat NWNX_SkillRanks_GetSkillFeat(int iSkill, int iF return skillFeat; } + +// Required main function for NWScript compiler +void main() { +} diff --git a/server/test/tokenization_test.ts b/server/test/tokenization_test.ts index 335574d..62cb2da 100644 --- a/server/test/tokenization_test.ts +++ b/server/test/tokenization_test.ts @@ -1,12 +1,8 @@ import { describe, before } from "mocha"; import { expect } from "chai"; -import { readFileSync, writeFileSync } from "fs"; +import { readFileSync } from "fs"; import { normalize, join } from "path"; -import Tokenizer, { - GlobalScopeTokenizationResult, - LocalScopeTokenizationResult, - TokenizedScope, -} from "../src/Tokenizer/Tokenizer"; +import Tokenizer, { GlobalScopeTokenizationResult, LocalScopeTokenizationResult, TokenizedScope } from "../src/Tokenizer/Tokenizer"; const format = (data: any) => JSON.parse(JSON.stringify(data)); @@ -20,21 +16,15 @@ describe("Tokenization", () => { before("Read static data", async () => { tokenizer = await new Tokenizer(true).loadGrammar(); staticCode = readFileSync(normalize(join(__dirname, "./static/test.nss"))).toString(); - staticGlobalTokens = JSON.parse( - readFileSync(normalize(join(__dirname, "./static/globalScopeTokens.json"))).toString(), - ) as GlobalScopeTokenizationResult; - staticLocalTokensWithContext = JSON.parse( - readFileSync(normalize(join(__dirname, "./static/localScopeTokensWithContext.json"))).toString(), - ) as LocalScopeTokenizationResult; - staticLocalTokensWithoutContext = JSON.parse( - readFileSync(normalize(join(__dirname, "./static/localScopeTokensWithoutContext.json"))).toString(), - ) as LocalScopeTokenizationResult; + staticGlobalTokens = JSON.parse(readFileSync(normalize(join(__dirname, "./static/globalScopeTokens.json"))).toString()) as GlobalScopeTokenizationResult; + staticLocalTokensWithContext = JSON.parse(readFileSync(normalize(join(__dirname, "./static/localScopeTokensWithContext.json"))).toString()) as LocalScopeTokenizationResult; + staticLocalTokensWithoutContext = JSON.parse(readFileSync(normalize(join(__dirname, "./static/localScopeTokensWithoutContext.json"))).toString()) as LocalScopeTokenizationResult; }); describe("Global Scope", () => { let definitions: GlobalScopeTokenizationResult; - before("Tokenize Content", () => { - definitions = format(tokenizer.tokenizeContent(staticCode, TokenizedScope.global)); + before("Tokenize Content", async () => { + definitions = format(await tokenizer.tokenizeContent(staticCode, TokenizedScope.global)); }); it("should equal static children", () => { @@ -52,14 +42,12 @@ describe("Tokenization", () => { describe("Local Scope with current function context", () => { let definitions: LocalScopeTokenizationResult; - before("Tokenize Content", () => { - definitions = format(tokenizer.tokenizeContent(staticCode, TokenizedScope.local, 0, 293)); + before("Tokenize Content", async () => { + definitions = format(await tokenizer.tokenizeContent(staticCode, TokenizedScope.local, 0, 293)); }); it("should equal static function variables tokens", () => { - expect(definitions.functionVariablesComplexTokens).to.be.deep.equal( - staticLocalTokensWithContext.functionVariablesComplexTokens, - ); + expect(definitions.functionVariablesComplexTokens).to.be.deep.equal(staticLocalTokensWithContext.functionVariablesComplexTokens); }); it("should equal static function tokens", () => { @@ -69,14 +57,12 @@ describe("Tokenization", () => { describe("Local Scope with entire file context", () => { let definitions: LocalScopeTokenizationResult; - before("Tokenize Content", () => { - definitions = format(tokenizer.tokenizeContent(staticCode, TokenizedScope.local)); + before("Tokenize Content", async () => { + definitions = format(await tokenizer.tokenizeContent(staticCode, TokenizedScope.local)); }); it("should equal static function variables tokens", () => { - expect(definitions.functionVariablesComplexTokens).to.be.deep.equal( - staticLocalTokensWithoutContext.functionVariablesComplexTokens, - ); + expect(definitions.functionVariablesComplexTokens).to.be.deep.equal(staticLocalTokensWithoutContext.functionVariablesComplexTokens); }); it("should equal static function tokens", () => { diff --git a/server/tsconfig.json b/server/tsconfig.json index 93404ae..ec561f6 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -5,11 +5,12 @@ "lib": ["ES2020"], "sourceMap": true, "outDir": "out", - "rootDir": "src", "strict": true, "allowSyntheticDefaultImports": true, - "esModuleInterop": true + "esModuleInterop": true, + "composite": true, + "declaration": true }, - "include": ["src"], + "include": ["src", "test"], "exclude": ["node_modules"] } diff --git a/server/wasm/nwscript_compiler.js b/server/wasm/nwscript_compiler.js new file mode 100644 index 0000000..861b1ab --- /dev/null +++ b/server/wasm/nwscript_compiler.js @@ -0,0 +1,2 @@ +async function NWScriptCompiler(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=true;var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName;if(typeof __filename!="undefined"){_scriptName=__filename}else{}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("node:fs");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");var readyPromiseResolve,readyPromiseReject;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.initialized)FS.init();TTY.init();wasmExports["__wasm_call_ctors"]();FS.ignorePermissions=false}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("nwscript_compiler.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={env:wasmImports,wasi_snapshot_preview1:wasmImports};return imports}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(inst,mod)=>{resolve(receiveInstance(inst,mod))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var ___assert_fail=(condition,filename,line,func)=>abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"]);class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var syscallGetVarargI=()=>{var ret=HEAP32[+SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret};var syscallGetVarargP=syscallGetVarargI;var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.slice(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.slice(0,-1)}return root+dir},basename:path=>path&&path.match(/([^\/]+|\/)\/*$/)[1],join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(ENVIRONMENT_IS_NODE){var nodeCrypto=require("node:crypto");return view=>nodeCrypto.randomFillSync(view)}return view=>crypto.getRandomValues(view)};var randomFill=view=>{(randomFill=initRandomFill())(view)};var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).slice(1);to=PATH_FS.resolve(to).slice(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var intArrayFromString=(stringy,dontAddNull,length)=>{var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array};var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf,0,BUFSIZE)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output?.length>0){err(UTF8ArrayToString(tty.output));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16895,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.atime=node.mtime=node.ctime=Date.now();if(parent){parent.contents[name]=node;parent.atime=parent.mtime=parent.ctime=node.atime}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.atime);attr.mtime=new Date(node.mtime);attr.ctime=new Date(node.ctime);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){for(const key of["mode","atime","mtime","ctime"]){if(attr[key]!=null){node[key]=attr[key]}}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){if(!MEMFS.doesNotExistError){MEMFS.doesNotExistError=new FS.ErrnoError(44);MEMFS.doesNotExistError.stack=""}throw MEMFS.doesNotExistError},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){if(FS.isDir(old_node.mode)){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}FS.hashRemoveNode(new_node)}delete old_node.parent.contents[old_node.name];new_dir.contents[new_name]=old_node;old_node.name=new_name;new_dir.ctime=new_dir.mtime=old_node.parent.ctime=old_node.parent.mtime=Date.now()},unlink(parent,name){delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},readdir(node){return[".","..",...Object.keys(node.contents)]},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var asyncLoad=async url=>{var arrayBuffer=await readAsync(url);return new Uint8Array(arrayBuffer)};var FS_createDataFile=(...args)=>FS.createDataFile(...args);var getUniqueRunDependency=id=>id;var runDependencies=0;var dependenciesFulfilled=null;var removeRunDependency=id=>{runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}};var addRunDependency=id=>{runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)};var preloadPlugins=[];var FS_handledByPreloadPlugin=async(byteArray,fullname)=>{if(typeof Browser!="undefined")Browser.init();for(var plugin of preloadPlugins){if(plugin["canHandle"](fullname)){return plugin["handle"](byteArray,fullname)}}return byteArray};var FS_preloadFile=async(parent,name,url,canRead,canWrite,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);addRunDependency(dep);try{var byteArray=url;if(typeof url=="string"){byteArray=await asyncLoad(url)}byteArray=await FS_handledByPreloadPlugin(byteArray,fullname);preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}}finally{removeRunDependency(dep)}};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{FS_preloadFile(parent,name,url,canRead,canWrite,dontCreateFile,canOwn,preFinish).then(onload).catch(onerror)};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,filesystems:null,syncFSRequests:0,readFiles:{},ErrnoError:class{name="ErrnoError";constructor(errno){this.errno=errno}},FSStream:class{shared={};get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{node_ops={};stream_ops={};readMode=292|73;writeMode=146;mounted=null;constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.rdev=rdev;this.atime=this.mtime=this.ctime=Date.now()}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){if(!path){throw new FS.ErrnoError(44)}opts.follow_mount??=true;if(!PATH.isAbs(path)){path=FS.cwd()+"/"+path}linkloop:for(var nlinks=0;nlinks<40;nlinks++){var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){if(!FS.isDir(dir.mode)){return 54}try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&(512|64)){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},checkOpExists(op,err){if(!op){throw new FS.ErrnoError(err)}return op},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},doSetAttr(stream,node,attr){var setattr=stream?.stream_ops.setattr;var arg=setattr?stream:node;setattr??=node.node_ops.setattr;FS.checkOpExists(setattr,63);setattr(arg,attr)},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}for(var mount of mounts){if(mount.type.syncfs){mount.type.syncfs(mount,populate,done)}else{done(null)}}},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type,opts,mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);for(var[hash,current]of Object.entries(FS.nameTable)){while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}}node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name){throw new FS.ErrnoError(28)}if(name==="."||name===".."){throw new FS.ErrnoError(20)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},statfs(path){return FS.statfsNode(FS.lookupPath(path,{follow:true}).node)},statfsStream(stream){return FS.statfsNode(stream.node)},statfsNode(node){var rtn={bsize:4096,frsize:4096,blocks:1e6,bfree:5e5,bavail:5e5,files:FS.nextInode,ffree:FS.nextInode-1,fsid:42,flags:2,namelen:255};if(node.node_ops.statfs){Object.assign(rtn,node.node_ops.statfs(node.mount.opts.root))}return rtn},create(path,mode=438){mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode=511){mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var dir of dirs){if(!dir)continue;if(d||PATH.isAbs(path))d+="/";d+=dir;try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev(path,mode,dev){if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name);old_node.parent=new_dir}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var readdir=FS.checkOpExists(node.node_ops.readdir,54);return readdir(node)},unlink(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return link.node_ops.readlink(link)},stat(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;var getattr=FS.checkOpExists(node.node_ops.getattr,63);return getattr(node)},fstat(fd){var stream=FS.getStreamChecked(fd);var node=stream.node;var getattr=stream.stream_ops.getattr;var arg=getattr?stream:node;getattr??=node.node_ops.getattr;FS.checkOpExists(getattr,63);return getattr(arg)},lstat(path){return FS.stat(path,true)},doChmod(stream,node,mode,dontFollow){FS.doSetAttr(stream,node,{mode:mode&4095|node.mode&~4095,ctime:Date.now(),dontFollow})},chmod(path,mode,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChmod(null,node,mode,dontFollow)},lchmod(path,mode){FS.chmod(path,mode,true)},fchmod(fd,mode){var stream=FS.getStreamChecked(fd);FS.doChmod(stream,stream.node,mode,false)},doChown(stream,node,dontFollow){FS.doSetAttr(stream,node,{timestamp:Date.now(),dontFollow})},chown(path,uid,gid,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChown(null,node,dontFollow)},lchown(path,uid,gid){FS.chown(path,uid,gid,true)},fchown(fd,uid,gid){var stream=FS.getStreamChecked(fd);FS.doChown(stream,stream.node,false)},doTruncate(stream,node,len){if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}FS.doSetAttr(stream,node,{size:len,timestamp:Date.now()})},truncate(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}FS.doTruncate(null,node,len)},ftruncate(fd,len){var stream=FS.getStreamChecked(fd);if(len<0||(stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.doTruncate(stream,stream.node,len)},utime(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var setattr=FS.checkOpExists(node.node_ops.setattr,63);setattr(node,{atime,mtime})},open(path,flags,mode=438){if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;var isDirPath;if(typeof path=="object"){node=path}else{isDirPath=path.endsWith("/");var lookup=FS.lookupPath(path,{follow:!(flags&131072),noent_okay:true});node=lookup.node;path=lookup.path}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else if(isDirPath){throw new FS.ErrnoError(31)}else{node=FS.mknod(path,mode|511,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node,path:FS.getPath(node),flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(created){FS.chmod(node,mode&511)}if(Module["logReadFiles"]&&!(flags&1)){if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed(stream){return stream.fd===null},llseek(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},mmap(stream,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}if(!length){throw new FS.ErrnoError(28)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync(stream,buffer,offset,length,mmapFlags){if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){abort(`Invalid encoding type "${opts.encoding}"`)}var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){buf=UTF8ArrayToString(buf)}FS.close(stream);return buf},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){data=new Uint8Array(intArrayFromString(data,true))}if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{abort("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length,llseek:()=>0});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomFill(randomBuffer);randomLeft=randomBuffer.byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16895,73);node.stream_ops={llseek:MEMFS.stream_ops.llseek};node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path},id:fd+1};ret.parent=ret;return ret},readdir(){return Array.from(FS.streams.entries()).filter(([k,v])=>v).map(([k,v])=>k.toString())}};return node}},{},"/proc/self/fd")},createStandardStreams(input,output,error){if(input){FS.createDevice("/dev","stdin",input)}else{FS.symlink("/dev/tty","/dev/stdin")}if(output){FS.createDevice("/dev","stdout",null,output)}else{FS.symlink("/dev/tty","/dev/stdout")}if(error){FS.createDevice("/dev","stderr",null,error)}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS}},init(input,output,error){FS.initialized=true;input??=Module["stdin"];output??=Module["stdout"];error??=Module["stderr"];FS.createStandardStreams(input,output,error)},quit(){FS.initialized=false;for(var stream of FS.streams){if(stream){FS.close(stream)}}},findObject(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath(parent,path,canRead,canWrite){parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){if(e.errno!=20)throw e}parent=current}return current},createFile(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile(parent,name,data,canRead,canWrite,canOwn){var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))abort("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)abort("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)abort("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))abort("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")abort("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(globalThis.XMLHttpRequest){if(!ENVIRONMENT_IS_WORKER)abort("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};for(const[key,fn]of Object.entries(node.stream_ops)){stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}}function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var SYSCALLS={calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return dir+"/"+path},writeStat(buf,stat){HEAPU32[buf>>2]=stat.dev;HEAPU32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAPU32[buf+12>>2]=stat.uid;HEAPU32[buf+16>>2]=stat.gid;HEAPU32[buf+20>>2]=stat.rdev;HEAP64[buf+24>>3]=BigInt(stat.size);HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();HEAP64[buf+40>>3]=BigInt(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3*1e3;HEAP64[buf+56>>3]=BigInt(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3*1e3;HEAP64[buf+72>>3]=BigInt(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3*1e3;HEAP64[buf+88>>3]=BigInt(stat.ino);return 0},writeStatFs(buf,stats){HEAPU32[buf+4>>2]=stats.bsize;HEAPU32[buf+60>>2]=stats.bsize;HEAP64[buf+8>>3]=BigInt(stats.blocks);HEAP64[buf+16>>3]=BigInt(stats.bfree);HEAP64[buf+24>>3]=BigInt(stats.bavail);HEAP64[buf+32>>3]=BigInt(stats.files);HEAP64[buf+40>>3]=BigInt(stats.ffree);HEAPU32[buf+48>>2]=stats.fsid;HEAPU32[buf+64>>2]=stats.flags;HEAPU32[buf+56>>2]=stats.namelen},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=syscallGetVarargI();if(arg<0){return-28}while(FS.streams[arg]){arg++}var newStream;newStream=FS.dupStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=syscallGetVarargI();stream.flags|=arg;return 0}case 12:{var arg=syscallGetVarargP();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0}return-28}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=syscallGetVarargP();HEAP32[argp>>2]=termios.c_iflag||0;HEAP32[argp+4>>2]=termios.c_oflag||0;HEAP32[argp+8>>2]=termios.c_cflag||0;HEAP32[argp+12>>2]=termios.c_lflag||0;for(var i=0;i<32;i++){HEAP8[argp+i+17]=termios.c_cc[i]||0}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=syscallGetVarargP();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag,c_oflag,c_cflag,c_lflag,c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=syscallGetVarargP();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21537:case 21531:{var argp=syscallGetVarargP();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=syscallGetVarargP();HEAP16[argp>>1]=winsize[0];HEAP16[argp+2>>1]=winsize[1]}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?syscallGetVarargI():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var __abort_js=()=>abort("");var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var MONTH_DAYS_LEAP_CUMULATIVE=[0,31,60,91,121,152,182,213,244,274,305,335];var MONTH_DAYS_REGULAR_CUMULATIVE=[0,31,59,90,120,151,181,212,243,273,304,334];var ydayFromDate=date=>{var leap=isLeapYear(date.getFullYear());var monthDaysCumulative=leap?MONTH_DAYS_LEAP_CUMULATIVE:MONTH_DAYS_REGULAR_CUMULATIVE;var yday=monthDaysCumulative[date.getMonth()]+date.getDate()-1;return yday};var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>numINT53_MAX?NaN:Number(num);function __localtime_js(time,tmPtr){time=bigintToI53Checked(time);var date=new Date(time*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var yday=ydayFromDate(date)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst}var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var __tzset_js=(timezone,daylight,std_name,dst_name)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);var extractZone=timezoneOffset=>{var sign=timezoneOffset>=0?"-":"+";var absOffset=Math.abs(timezoneOffset);var hours=String(Math.floor(absOffset/60)).padStart(2,"0");var minutes=String(absOffset%60).padStart(2,"0");return`UTC${sign}${hours}${minutes}`};var winterName=extractZone(winterOffset);var summerName=extractZone(summerOffset);if(summerOffsetDate.now();var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(globalThis.navigator?.language??"C").replace("-","_")+".UTF-8";var env={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:lang,_:getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;var envp=0;for(var string of getEnvStrings()){var ptr=environ_buf+bufSize;HEAPU32[__environ+envp>>2]=ptr;bufSize+=stringToUTF8(string,ptr,Infinity)+1;envp+=4}return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;for(var string of strings){bufSize+=lengthBytesUTF8(string)+1}HEAPU32[penviron_buf_size>>2]=bufSize;return 0};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);HEAP64[newOffset>>3]=BigInt(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};var wasmTableMirror=[];var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var updateTableMap=(offset,count)=>{if(functionsInTableMap){for(var i=offset;i{if(!functionsInTableMap){functionsInTableMap=new WeakMap;updateTableMap(0,wasmTable.length)}return functionsInTableMap.get(func)||0};var freeTableIndexes=[];var getEmptyTableSlot=()=>{if(freeTableIndexes.length){return freeTableIndexes.pop()}return wasmTable["grow"](1)};var setWasmTableEntry=(idx,func)=>{wasmTable.set(idx,func);wasmTableMirror[idx]=wasmTable.get(idx)};var uleb128EncodeWithLen=arr=>{const n=arr.length;return[n%128|128,n>>7,...arr]};var wasmTypeCodes={i:127,p:127,j:126,f:125,d:124,e:111};var generateTypePack=types=>uleb128EncodeWithLen(Array.from(types,type=>{var code=wasmTypeCodes[type];return code}));var convertJsFunctionToWasm=(func,sig)=>{var bytes=Uint8Array.of(0,97,115,109,1,0,0,0,1,...uleb128EncodeWithLen([1,96,...generateTypePack(sig.slice(1)),...generateTypePack(sig[0]==="v"?"":sig[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);var module=new WebAssembly.Module(bytes);var instance=new WebAssembly.Instance(module,{e:{f:func}});var wrappedFunc=instance.exports["f"];return wrappedFunc};var addFunction=(func,sig)=>{var rtn=getFunctionAddress(func);if(rtn){return rtn}var ret=getEmptyTableSlot();try{setWasmTableEntry(ret,func)}catch(err){if(!(err instanceof TypeError)){throw err}var wrapped=convertJsFunctionToWasm(func,sig);setWasmTableEntry(ret,wrapped)}functionsInTableMap.set(func,ret);return ret};FS.createPreloadedFile=FS_createPreloadedFile;FS.preloadFile=FS_preloadFile;FS.staticInit();{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["preloadPlugins"])preloadPlugins=Module["preloadPlugins"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["addFunction"]=addFunction;Module["UTF8ToString"]=UTF8ToString;Module["stringToUTF8"]=stringToUTF8;Module["lengthBytesUTF8"]=lengthBytesUTF8;var _free,_scriptCompApiGetABIVersion,_scriptCompApiNewCompiler,_scriptCompApiInitCompiler,_scriptCompApiCompileFile,_scriptCompApiDeliverFile,_scriptCompApiGetOptimizationFlags,_scriptCompApiSetOptimizationFlags,_scriptCompApiSetGenerateDebuggerOutput,_scriptCompApiCompileFileSimple,_scriptCompApiGetLastError,_scriptCompApiGetParseTreeJSON,_scriptCompApiDestroyCompiler,_malloc,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,memory,__indirect_function_table,wasmMemory,wasmTable;function assignWasmExports(wasmExports){_free=Module["_free"]=wasmExports["free"];_scriptCompApiGetABIVersion=Module["_scriptCompApiGetABIVersion"]=wasmExports["scriptCompApiGetABIVersion"];_scriptCompApiNewCompiler=Module["_scriptCompApiNewCompiler"]=wasmExports["scriptCompApiNewCompiler"];_scriptCompApiInitCompiler=Module["_scriptCompApiInitCompiler"]=wasmExports["scriptCompApiInitCompiler"];_scriptCompApiCompileFile=Module["_scriptCompApiCompileFile"]=wasmExports["scriptCompApiCompileFile"];_scriptCompApiDeliverFile=Module["_scriptCompApiDeliverFile"]=wasmExports["scriptCompApiDeliverFile"];_scriptCompApiGetOptimizationFlags=Module["_scriptCompApiGetOptimizationFlags"]=wasmExports["scriptCompApiGetOptimizationFlags"];_scriptCompApiSetOptimizationFlags=Module["_scriptCompApiSetOptimizationFlags"]=wasmExports["scriptCompApiSetOptimizationFlags"];_scriptCompApiSetGenerateDebuggerOutput=Module["_scriptCompApiSetGenerateDebuggerOutput"]=wasmExports["scriptCompApiSetGenerateDebuggerOutput"];_scriptCompApiCompileFileSimple=Module["_scriptCompApiCompileFileSimple"]=wasmExports["scriptCompApiCompileFileSimple"];_scriptCompApiGetLastError=Module["_scriptCompApiGetLastError"]=wasmExports["scriptCompApiGetLastError"];_scriptCompApiGetParseTreeJSON=Module["_scriptCompApiGetParseTreeJSON"]=wasmExports["scriptCompApiGetParseTreeJSON"];_scriptCompApiDestroyCompiler=Module["_scriptCompApiDestroyCompiler"]=wasmExports["scriptCompApiDestroyCompiler"];_malloc=Module["_malloc"]=wasmExports["malloc"];__emscripten_stack_restore=wasmExports["_emscripten_stack_restore"];__emscripten_stack_alloc=wasmExports["_emscripten_stack_alloc"];_emscripten_stack_get_current=wasmExports["emscripten_stack_get_current"];memory=wasmMemory=wasmExports["memory"];__indirect_function_table=wasmTable=wasmExports["__indirect_function_table"]}var wasmImports={__assert_fail:___assert_fail,__cxa_throw:___cxa_throw,__syscall_fcntl64:___syscall_fcntl64,__syscall_ioctl:___syscall_ioctl,__syscall_openat:___syscall_openat,_abort_js:__abort_js,_localtime_js:__localtime_js,_tzset_js:__tzset_js,emscripten_date_now:_emscripten_date_now,emscripten_resize_heap:_emscripten_resize_heap,environ_get:_environ_get,environ_sizes_get:_environ_sizes_get,fd_close:_fd_close,fd_read:_fd_read,fd_seek:_fd_seek,fd_write:_fd_write};function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}var wasmExports;wasmExports=await (createWasm());run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})} +;return moduleRtn}if(typeof exports==="object"&&typeof module==="object"){module.exports=NWScriptCompiler;module.exports.default=NWScriptCompiler}else if(typeof define==="function"&&define["amd"])define([],()=>NWScriptCompiler); diff --git a/server/wasm/nwscript_compiler.wasm b/server/wasm/nwscript_compiler.wasm new file mode 100755 index 0000000000000000000000000000000000000000..d9ebfbc0b80fa2bf04342d68b9a3ef175c526014 GIT binary patch literal 307952 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 ZsC4&0Tt5ZWyFJvqDh1sw z4ylf151jzi_ZM(Y3ucV#J(b3bfcnlN)O!SVwF`A8Vr|1Q{}-t5^-$mKppMs&xe_r) zjA>0wVPCjuta(P8+2BDwn@YEu4%JS$BQtIX>tGV5I%VPJ)-adbnQzLAB=(VA<^i|k za|2Cc>qK{X4)W(pF_zl`9<51Lu`C=)+%)TS*p}wN6>vsrtp8&LHJO*q!c0w+w;20@ zHlgN9D~#9B9Q262B05~(M6s+H(fqD7){;(5oTI{sX~wu&nwOSn0%uhqXekRTZdE}8C-SfE z%u|l)2EFlc(hhCvUg{<*GPhDgwTzUpBr0RTaG%S_ltN}8X8&_Y={9eXww|Ho0Sw~1 z8HvlsvJVtqM|!t;hzmd)bC@iq);Nym#;MSF5o+^y8+_dAr` zXSmz@2-6<@%u!YGfTix6lzLbt==DSP`q78GALX+l*Sl8jZMo}_)LpN37iO_G*CN6b zF>8HT-}@_HWPwjJ`%o!6I=>mRd}%IW4j*&u;HBY1A=`SO16Y}#9Sl&jcy);%W3w5{ zrinD0bw#wMFMW+>2q3E{EI%<@7j&I2i`*rZuD&o>?{cnliOfV*mh-ttbBwOSa>Y{B zIE$(2>i;N(Rol=b!WKkpRLJ;99E6dZh5bEAKW>%lga^!EN8Vsp1UV@Tvsxo6-eBXre0u-}plJcd|1j_{>$=&4e%4~0 zF5;b&QAE6Dd0D~7KjH;oh9u%m>P!@^+}tJaPF+GT?3oPCPktu1y;s-r#yF9 zIqG3$*iWpiVqs-lnv2D^WrY;witGPabL^wq@6U;=^RMT`HSZ&wpq`wqxLRLfl9+0J zx%gNzX;LBu9avvMJF%e9=_C-1(eMdNVzv4mnfr{FIj`lA9-D8X4?+}%?TDl;tJDj@ zw4nYv!r78MhUi0+M=p}bD3`|wc?>0usg_6<`%?m<+3c1T!VU zN+-@>ty&i_FRuS%gSDfDD^hf5VJx>+C!7A2jZy!w9ckqry;4nbvHgEEpR20v8Qh;9 zF_c9gL9Rhru0it*2(~k9#M&H-I<)4Tp_Zd&dDvxKo!s;sO6#6#gcNo*!qRXX8zc;$25OT?QwbjxLlUVe3c#| z*;?J{N;kWs+9*D1uBz2O^v3u!wpUKx<2J5XwA@V8u8$_|Q3*@XJXcuexuw0zbibQk z-RPAp@%!kzTNMyR>Zn^)&Q5zDWrEW@*<9A6SF+MJ7AH3st02E>+m+QGU2lY{Wp}F# zD4CbQ4Ii~D*$zrlZTs4CNh{eM{&~ND-sztY`ez`t{DVdY4D&t2z#9<1$Jj|m8Gb~L^plzvw z*`D{iXTfaG2i>z^w&z1_@R%+lRHf3JX{EWaH3|kD*uscjjRNbWH1mq{G~|k$NK(7b zn!7sM4PULswhDoi8Ot82FRipnku?bfI|9GDjmr!@AS7?t#DrbAw95yvwro30T=&Wa z{h_@&NJMZlWCu`Q6uc>z?US-c44z=FJ7|d96B}d?Xle z52L|{v&Yy-8P3tjIjlLH9p=isRxP50(T0f+m>Xrh!X5>13(_dC#4QypKi0|G1n0RI zVk%1{R4K8y+?_;)AK6wYPlPXI-YT%0UeFJRw{$1Q4ab?MEEbh|(pEHhZaeNNIRjLc z0m|;Y2lqg+az+MR8w=loA8d)jU*CkzBboo!05inzbVf+Dt*d9iV)3rP4BVlW&O>AV+)~saPxW~3N>ezO9AH1rz*&Gj(7B?3=6{iAG3Ixd| z>=F=S6t))%JG|T8Kc|@5u&LOR$%Y~Y4#dqfE=So6JRnMK^o$KbD2ZVilAw`B6qIn#CvepxLl~63j2#Uh9CgDdN^xb; z1YRJztXOAE$rq<~*gaz&G%wmF)6549B%v_TWnFb9$%3oyv~?{tWrqIL;Oc7&C8HE685Zm<#)gn4rC|(uiq7ai@IM{4rOm6m zb(VYU>@7DP0P^H=dq8&KSs;O6UJttFYZ<%z6VZov+`1 z^E$4SPcmOB`@MHNu(7!2*T_f5?ki98W$tpy5)3=Tj8(VsTSaC}`@|T-!qn!m1=&kv znwpm=+4~A8=vIVr*@IC}a1S2u?DqQDgBH0CvZD{W(6`>%uCLl^0!Drtm!~!T;7V@p z_!pYP4j|%FB8b{%kko}^W7$r7BlAYbbz$)pj#r{BNJ`EBjq9X6Nv=-g?$}qM^v6{V zTU%uJYG%tKZrGshzC@u`7hSi@3ip({%W87nso5W7SEe;QV`bM9H2*Gc7mj70Ka8i| ze4aErPk+kpw$0AdeP0f;AwA*3>uuCzCtcmVubO{Dr=!&T*(m#)2U#BkKJmeYD_XuJ z19@C+bDYH72?pgJv`KI>^m?5pXJaxKYp3-j+u^W>TeA=spoqO)UF_wpS$q$D4_7H3 zeR6Jav2)!(?;6^&B3kY1^~j2~En}(qIgMJg)&nA|dM4>;4@=J&8hu0=EuxzvE#;iL zO7lt=6F}g{ZMQ9BS#2FMj9)L*bUD_g7{f|+iMuE9t8&1vb~%NpG}}M7iS{&8^|Xd< zZw)RNFv$BwdKB%XdAh5{Ue)dCAvR{PiiWdu$Fl!qnIqq`m_g>*m&^4c+q}=5-{Fi; z6v9IPc6}(hIN666WS<*?aLu2x9q*38+{>U1h9HYT@aKlI7x-778^XoRz7bs3!rDjK zM7V`t-an;pwej=B1luTE(qH)`p7sY@$i$cJm~St&d~6CRPXAZ`SapwI;}QR}y7sr? zRdJBrwH@87LL;^iY{saQ_g>3Zdzm1FSx|-Y;!%b)ik@joKMMg)$J?dlbQ_P?wmXM( zs6ay!pi?7^;S;_V$e(M#-WKTxQbe~&FDjd;YCC88 zp}O62->R6g^$g!oy}1N}H|#6nPkMrmXhVDbT+KxT^yl*)0k}xnG8Wx1<_|N*Y}~3I zH>E5Z`wh@Tk-u;+^DLSrk{j7D1*jl;gDbdTftPckxReWh=6d#ja*aj;)m^FF2RR26XH8&pyTqBmT;e9ll$t4( z#2M>ZTMKAP!@m_O=8JL*Y)nS3(1LV65fV8Xpfcf6+gp}Z2xTI_kTK*cTa`!d>l+lET9Iv@gjqBeKg$C$Ie zNMQ>10@Uu2?)tBzB%r`(wtImRaV=QW(>}F$jR>+!U;UcCVv!Qa(2FW6lgmP)FI<|6 z_vlX#^|tm_6zdU{e z*JWI>k?HAN*K=LMRd(&u0%Xm2bHd_7OZ=yTMmeq}$Db(25x|+CKpML)=NbuKlKs4( zJ>LO)HhV^~FjcwE7mvp2;#F}L1fXbdt~SxxR}Q)F_Nl<20(Ny7`Nx4;6u}1vY&j<#Wl-DP*zhvm19Pw zCIq)B5ZrWA8EOovE23+)^_ko7S3nWMfTqK0>~cZ5f~J{mc4o=(Z&_MAfCUL;OyCSV zFwB7B8#B36d(An=(uVhmo3@iHrI938k>1gt)2Jx6fvF2IvvLd>LIbqwSu*+gh z^+xFR;LhKsR`5M$1d9ar;G_IA(0>bFzkP-)uFq`xpZkor$HJc1Pl0;T>`6MtPs3h` zMn)jALW|a~QZ&YzVI))E|fCm?=}!j()JjKDF-97uz(h zby~c}%Z|qiW67+m2P=^s4a34}zFC-_qL|(Y`{F`m++mLAD#OrP13zh5LH>}L&gGQnZR^`L+esU);s&fLGy1M( zUoLCh(TYSYlQOrz))+f2%#b*ZhE|dpv%`PrZ<1px1i>lv+$tT*4Elz{r2hHzgOL8UQ#pGKEAT6y^Rj*N?)5RW1PX$yR zR^|G(PNRVFcclv<(2%`EJwse}8O;{Gv$xAksnFL7h}gW}`sAHHcF)TyFHMUP(N$%| zmlp=6@=yY;1&U`;ThrJI&EoTVNf%m~y;K7@2|kb2=Ig=dw+^?a*(m@0@5cT8Uff$D zlnuZYGCM`0e+qlCn)wN|m80LqJ+i)<*L7(iFYsvU=#GZWMkL$~H+tlin%b$TLW!ev zJTXigVMEa^Z4Hv4)}`X9&OfZn3&cM-B4@XkxfXgvWONL%0 z?`;ii+lb!nY`eBS*>cA6@m7mbO_-XIH{r(GC#T-EZ(-iP)1aWWk0`?s4KW1UPTn?{ zpVD~W>R9*IYOY=@qAqANR+&#ln^O=#YrgC)XjJQ^Kb>jD#S|jo-U24>Z%x7k3Bttv zE!X6Mm=Iyb61Rb28VOGsk{pNK&8Uic@4UEI11vrVO2|7c?h7O=+@?_%h5GPa$jc28 zN4^Jq3P>_uxZQ+Vfsq%bL7U|4ptLH$X(GPi$6_Y&ahW&?##9u@nNa%G@Fr|7-VAP z2X29x`3R0ER-lx&+zqy<0&7|5!+S|#>;6?V-`s5u-%fthhL=^h}02eW$Ny`Ly- zT@W$Nly-j$&mwRBLoKJY5MaXs0xqwvZ0#AMKJy6pMe*+%m$lY$WM@`1T1m|aS?^;v}vwj=c8^z zdpx|FLjJNqOOWHjNAqO6(-Y>?8{#XUK9kc2$(XEefBFs zF3Sq3+%L8_ac~M%GMM*FoT<6S5eBYxlN|0B#q6V_sl_l#>PqjE=cw{@Wh8X3uJoS? za6LeeA{!dZ{`Fx@goQGG(oO~wE6_z+AuZ^jxW==ElP_36c!ADngQU6G!9`XF7xD>Y z=mA9s?pAelZuZEDXK~6W9uBg5sV`nil?pSsD&=FMN(i+Sq}0LTp^$Vq0l224e`tD# zUnQk6Xq7k+L-3w02B0cRBYRUoSr(ML9a18^TdE_XVX*EqyeO*C!Hd@7z-#6*7u1SZ z06hTHBq;(eb*BbO*;Dj|#43w6Ijew*L6w{r2>r)+7qc@s1L<+|``nnKE6)KgtZH5z zWe{lqgh1e0KCM!YR;s9fIZYW|miY!|;2& z4LSG6eI=xUB1y+4$E9!MLKx;+YjF0HMt_BKpntYR#TXK0Gj(oYwuA``QbYt7oCtbo zjGJrZs*$UuL(OtTig!FB$+XV6*P4FBSc9~y@mq-S0r8_Gk??vaYP36|-T7X*lD1;| z$WIY!(bW$44;%2zweZXf=tsg1fnhWbJu%`?QirrELZlVt42|6et#cIYke?}8V_ib# zCKMBb5V~WRIH!qdS!;y$L6DtoiuE?byg-9~qAgqDY)4LiGC$CQt$9HS1gy}|I^#j5 z9BPRHsvx538Q^iB)#;um^Cx4m$MPquODG#sAz}&j2c0N2@tjF~s0EMb9KrC>MX&;1 z*=jCm%?r5TET1pmdo24KlPm&x(hH6!a>?;V*U`qxlxEAt&g6=Qs6xOQC|7!g5$u>s zjbl3h1Vh5t?({jdHqbD! z!eL@L7h->@L&z5mAp|WuijuN0yd48_H0^JZBfvb#Yj$57MTlObbA?5LixGLDze)2R z9EMf|`_B|Sn(l_m*5t@k&(P8%GsC-?SHX&y^T&@kjzKf-p|2Y zu1La8vQ=qpK}uJq%|R<139M=)dPs~qlWH9k-Jp@Bp=Bc%Rz-LehB)&bOtrPV3b3HIo|dDXF)>pb3+k45Z?WCuL~6Su4YG4RGbl zZOwz6C*h3fgu6D=nC$l%cs8EnK|$CL-BY?SFmbem7lj{G!mui}1e?~7DQp2~#k30p zO*3P{WJGn5COm59qhp~8EJPrf>1f761gKq<92O!z(qW+xioj)JB7Ta6XJHzOiNXT0 z6o!fjl2eb$rVg>tu(42-vk(*AC{S|?%q-D_NjN6ONawpl#y2*28rh7&G}Od`QA=I~ zsI;w8J6K`XJ&oPPNR|3Yq3g+(vOCbz^H64H-rH3hP@+v{cib2khNo>IIvi(AH5#2G z&bYV3bMeQZ6ccc&I>np7CA0y}R$BJozZ^7|Ktty`oU(*+#ZXT3xK#1D)LI2^LhH&1 z^_8;iwPwqIRFGroPxOTJC*q9$%>LdC6Uy_R10^y*(Pav*gy%ux1KD?t1qNkao^B*6eizh$4cx6oe`U+useyptg& zLOXnE39{d;UPJM2s-~NTjt68xB)k`f)D@jVNU~o&tbz9mBkJb+@T<4#IceIt2ISF< zq~ve4^U%lG6&b&WL3rVP7(_sW+9TyW4F2iP+&?t`Nzgxk^@;o~$slrXTf#NMgwRl@|gdSnU)lG~hVxe=3%ugGlY;iVSh~+_T zcO&9JW-W5?vk2DMay(5YNNu1z$xa>5=5qqF)Kj)%d}Lt|hj9@1{0s05$bEqZ#Zh#O z+lgoM6x0_ZYxH65O-(i*60NjU7nIT?EfgD}`2vPw<}qTRm_BegNLIU(xRDxVh_pt9 zT$eRsUPojfNrHs`tX36p`{s;s6vLOTpdt6EGQ8LVf}y5Vsh@4w6QvDF*73r#dzc7J!#CqZt3EHe>Hh|8s@D4?R#7ylYiCLAX_>X9A>o%3h(`OqApy2L1ztf-CZY|&GiFyZ6A?V-{h~?D4x&rwF=^M{UHU$ zx&EMl;<`aPtFp7kBB$*&*&kdJi-ke>juCeb_L{!*HQo{g&Mwm?i7bIxU04O8OA1D8 zopT^bS?3a0yUY1pI_sQ8a9_hJBS{Y&p~;!0_rPK4z+qP`i>hQxVh4v^nAGjyK)s*H zdh5g)CxV=s;~46gq(Ddu)5>ZZ6=s^!0QMkz2U(hKf~YL88OnOFF`D@{<3R1okt+YM zkWZ>dTGxb&0knCo04^~8rSzQsLoDvLf3PYn$P^hZqUr2^0%#;?wSf!C$u}pc%a~Po z1ZuF(zwmGVsZzJ`mMplezK~n4GO?F!t}k#e z>htZowLZ_To9kNZ#Rzzv1I)QzRv)qJRdr^p@O*_19p}2fPP4dPDJkW;O;XDB9gpr>W<1ywHRGEh#tibBRJXDgW{&AY1I z&e6n9AVb)j^UV6R*W~nPQhU|T)XB(y|HYscg0iQB*C31mJy|*yKU7Ltzi@`$|E_<3 zR`>O;H`{Cb{E&bBSmE(Pj_x%~7b-WP~476VG4N*k8G|s%b3KU>qRxZOU#B8L?%8u)q z5pi}TR?ol$M|m;~a>&5MKl)^Ao?1t($ipXhr}KVLk@GA|c+Wf%JJRP=~dyrP?kwkRS4GG+g+sq&e5S&r-)A-IFmrS^zP#PmNa(Qioqu30P zPkP8ysN4n-z^atbawEu6;aQla`W=7kIKlZWx_oI~Lk*Dl>T*thwo=V6Nn^%~s7Iuq zP+i;-Td{+onNno+w%EG*!BE{x%GdlPOLY^E@+`y5bR>_BvC8V;^7<3c;WQDJeHW-4 zBDRKrx_Tp{S;ioWbQ5hgSC2lC$RVuHCyR--c1dQXGhFZN!rVOaVl&#M{0o z)nJQ%(5>tiM$`cXQ=x}*WEj32S53y3p~+rRd~=0((V?^L*r**FV_=fIvh!*{BLFIR z=vGL85Ijd3@s>3~CK?=*vn+HuICbZGFr^%aCIip{ItyoA{%x1K6%Uds?Gga4tT;hp zqkd*C7|atU#H3w`AteiI7X}HlGOZ6)!5eN@P(K=Zl45f6{$-zY3}|V+FF|*C3+ZSP z+!{~A&1uQ$mj-c%kiQbd)m`b9TH829NN^#6&YeEBJ~6CPj;ReUVR0OOBm0k-HYp2h zXeN(vdRF2YF2Xd|Atof5Lo98A1k-p5pdyl^nv)_O<&HDB86<_TnF)BN;|#8oflBVV zhsxawD)Cgc`P-%Jr{_06QECU-!Tlyan1lUby=mjz`mXL5*#`KOl@!lQ%wNg=V?LpL zy8pFoe_2NJa#WuxM`X- z$PTw{NnrLuX02plD-gj`8Z~xa!2U)Gq%ob0l7})=G`1pJ<)+#0bm)`scSqD$KbfkM zH2Xk1-kpY|65BwDlqi<@aM)~m%*2$$$zUyw$dpEW5d=TDwD$QZG`kKc$h0+-eFvyt zey}?w7md_>2?)$zr&`Zs+B{_L4+<*#wRgJ-q-QbHODi^8Y}Rb+11ax7n{u?PA5vbG z1nW;et<2^~6ohas*)*CF+dw(57OHZEKP*TLcUyTfmRVbKts)s4k`ZxYkvHhA^<-Va z%iFe~T(BIV+9FT6@v8bz+x7zq^bM1N z-Q+5UA$$`_c@@!g1EE&CNbL8~cOzirW;Z_Hgyt2}LP7H~YwQ{(30|>O`$1@7Et}Y7 zfw@G#6^EUkffaC&19Bzr!P@dFYQQm2{~RDUY;MPdVW25k&;-Hk(7QnzbpkE3^XT!5 zIkWTaHpTmVxJ@a)f!R!5Nuw$#CiXkiGXA}B+Ts|FKzEtG&Z?(e)G&&?+{LgR3S2hyY4ZV-A@n*yMo1KnmwHwi?oZG_eU=7}kCej@ z6v%v+vL``KC9<$nNQd3kiY>L=2!#9vK85o6Dtyl;YffQRE5|I_X6Sc@HH6jIx zmK;K8Rbn>0iFw+tNVbeH{nSFoxLm_nGX#(Ju zl2{9Y$#xuS!!!Vv{qmPsyHw{Cr|dt6wg2R(pUYidZuNMQR`J`MovjJOq?J?Q>Cq-b5&w>T=*j!ZlUvX?xC3x%^V*& zJt|H97k3iCW7ckkWNl+z)NI2PuCN+~UuTM&k&N>K0gREpFkqo^%7~Sk34NHM&g3#{ za@MrfmDT2l!+X>^*YvJ-2rvYuNcfuVTMb))h)K=!7T7KS8lTN{3+$HR-5I+rHKLy2 zM?$%Hl#iedJ=x`?ppYQG#91xpl2_MJWjU}}Tfkc7MoBHOy<({pnpT6&NDHw8ffQq2 zRW3**pc+iU`l@`6ysAi?icLzgFL_%4+mdJPlXOvmAT(>ks*&Ee|JHfS=Xg<45gh}F z*3zGsnt0@einfRR>xsEf^+p;IX4h0^KU1zYHl zl>a(pVIUBnpcK-OAVY9XfQ>f{;OvFd+BQ|F5%T7DGu9fPsFp#ny_TWQRWso`_oed$ z#00NK;Y|X&E1`NNUlo2le{d_rs%ju8ldhXNFt#MYM#4;G3gzZZx!FsH+O8Ywy|38W z)w1XcQPFg3Jg+;?YU=mSYZ~|-eE_E<&T@y@Uz^l0DacuBPtfM81X%M`m{4VbTd|?? zBg~5+?Q6k!wnUx7F#B_}IAMlsl`RIpe3(NTt??3;!14??=>v6C>_Vpj4s#i@GVmBz z#1f1Xv;?t03cT@w95FgVi#|-vG+(7Bfed>S5Si&8Eo+UB{Ln~p>f(9P;_47v-INvw zi#z`o&99F(PU}4O-wZFVE$mP2rj+B#DU0#4yr?-u1y%=nU7dlnWGP&yz>QnB~DD+Wo6Vz=0DDm&V@#PZB~tZ{xjG}C)nOPRsFCz{TDohicGW|;1g6RU0IOQn37#o zBfN6n_{h9aZhhe&9ThP9Co@M*0kwZT^REm1Lu?wVKC?1HlbEnELuM%|g+8gHM5b3h z!zHp1_8BgbWhc*YiI2>jxW_}}S7uve*DdzuI?m2fS5Q76Q!-*NVVn`6SsRYUPnj`h zO6K@w=jcP{Je@YfGGqsk>y9z`ieyI$9$Gyl3^HJ5x#n%!lXKXcHX zB*(C->=`Et2p_d#XW|1MsbM1eAlK=yX3p!!qugK5u1M{Tkyy-NEn^nL)TTK~#K#_vqail= zMn4fF($=dCf!PwHM?b=<`}OMe+s?1HNn~c@+uPd1zp-}V?d_3!(vh|49rr9{h68`^6y+LqvGN~iEas6hxK$iNgK8ym0v zbL2;*AOVCqmmr!g;^+SSw#^)4*mYt7)-~HPu|Ncjpa?Ne20&H%YB!1PB6kVgg*gS{ znx?xHCZh5ITSXC1ojf7+e6n^Yy6NKy^67e|yS(0Au5p*QxXUJ26stcC7S?^*^$vf% zjafyro zn%hHx+O+;$cdPyC&yS2g%x9+!US!C%#)f|7gW$=!EbBxV>0?0lYnGsnCb}@g17Ks@ z9aFo0vk?m;J``e6V;cmA1NFv6U}6Z(+l%$&RVQWcL2e#bL zz6Ux0VWiI5x57_t1-NRca}HBL1dde&KOwXcQ@ zhBFOc<6Wk;SSD|CVO4_NnNqMjQwrQM|6CKA?QYp>=3m-fx;jeT-SX8;#B{u$P zwVv2m81b>Vwsr@~P#0sZx)OB5637h6*LL=xi#s=oB3=`% z(Y6}_Sg|9JPNV&FT)I_W3mQ2|IsjQwmiGeakqom`|9m_vz`J5Qq>U?YuDvdl3b7O$KByV3Zb;@R#) znxt93aT02nU4S6D=>aya$FSN(RhaoLh`FIdmPM_Y2HRe39W1!rEMN~?Lk@CVHiZ_1 zfL}jHiXFJpT9$0nSro!RNFzwNI{WqQ?8xQjg=sd}7zk4iCRT+AW#32PbRVIkwHrTU z+n0H4O3G#E95TD$F#pqm!w^vioRR}4?g3{KM&H(l(YMVSqmasZJBCqI5M$i(`-D-k zmoN@%cou`%wzWOjw64oy;Wk$0vBuK1i0Rxpi&=_iu^8?`=Xp%kgd2C(4Rc3SaEC!v zuxGSMD0pih3f}r{M*&OeJMAo>Al{ZuAZ49bGe?2e=sN^D@g0nU8~RXiLym&^xyr${ zd8JIOGeu4wH}-wEG5?O83#HWt$fK>7S!iaor?9v5750|Aus`h4k+xzPbLe2WzVEZ^ z^Updkcqb)0f;BbIB$R%Uzl!9_aV|FM&3y&Fd2oTqXx2A;8{zzq=btE?Khy{359M$cxRVC-lHmvY z$nb;tXOB(8)YtTVc1`}-SN&(2M`v!#KcFPTto+)>cggNDFLuujaAxGN9y*M7P3W8Y zN`6x5$xzh2jGBHUm4ZDEo^Api4`#v(LPnl?!iF@1)5@N;@kP zBZ=WA#lYh5DBGoAIQxo5G*S8VCN61QBUv!>O}DmLzeZEiOtIu14>P-(7b|yt5M1X1 zm%=aUDm*2FE$x9#3&OLX?7&vSk*N9UejTuy@_UX8mh-=~MtW*!F7nWvuSIDF4c*NG zrq1t$rhq9op~J{mQe4<0L5-2yhsB?!+ADpv`=QV}S1(8})T>qZeOS=?q5^Sdf(542 zO#{v~9-Kpf^Lhu))ji;7zndaF1w3eOx+6?h#KUrr2Vx%6RJ_Soe1wYM;wrwjr{W{U zirL=!^)Lg67QWus_?18&pl8fC_A=%h2MEP&zP@ABx6RdeOHX}lnv^&62L^UWJP(G} z^$3F4jfcBQy*;x?V$J(a5|`#j&Gq0@dh_~Rd2xL&1NSes3%|D9S4)H13?OQofymr7 z;(Iu3+u9Y2?=8D0UDk>3m0%o1*mW}G&{dcb1@0+#WtN@K_w>8 z(zT&itf{mX+Os?B#oL|r;_c2tdn&+%_D;SG`cB$Mj@hDG-e6nXrEW{%*@9O~>lT}{ zWyiMKsufxv1r<7?*|O@qFm;*$6TNOdGDlS^&-L)=1gs6UQZ-up5vR!lVV5jKSZp8X zk~?~0YI2l|V3V1Obb zto=loME-82-&d>@dNk{=Cq^fK>~#)joYiPPkVs~<>VEqJecvLWeN=nG1N=DG3|)KF z1AL?x;3EdG`K)g!7-m!6?MiM0wFe4Dkn{SswMYAnAoD|b=Zzr8a5}BaWphhs+Il01 zbo!HgtFtqL7_C_wLG7Z-?kp79>0H%%}CJ|l$#!8p9y-au@JVoOTHSFXSJFpv7oV6eTASgs?Qbo z*^?;FE2ctm^7UPdT~jf$Xx!HWNuj5U=CkAu0n}_ZU}?&Bd=CYn6~D)WHFFQ-`}=zJ z-(S#kIsJO5$ci&fk*)OpD+l5Mt;rdwMV(hMdLwjHj}y*!aM(+6Eu?2xIGUJ`)9RS_ zPMjl!tjc!oz-*nkMw-Qz?G*#FbvPj9crKN8(35UbtsT;)xI@bKxxx85-d;*~8^TN~ z<_*HaTo*~2juD#~Ys-#L-n9+|*Br)23Qnwxv zEu)s}BYlrI5aU^*{ZG8Z=X`BN_r9lB=Y0F;77)D6VpWAwRY^1IH&Kr?`BCNS;T?>FQHJpTj=U_+_C0`Nev=$AIWSMHJ3 zTy&4Rdcb<4=mB$&uI^P29B|p0)iI|Yo&)OPSLW2iv#TD?oL)V=w&>$K55KSgPPbjn zaMp1J`;3BSIJ2V}zAx7d%TJ(yxT6`m1q{{*UC}pcx|sncWr# z48J_55uRO*U_0N(E`Bq>VYsT-VbHquQh>j}LUr#Uw2mvrrx*0V8U1>oeF6n^^+2}( z#vWWG;hYmFpzC6E3m~X6z_sXV3{xa%3{xam^(vC9<`l_uOOf0)r%0Y%MRNM|uElF| zMM5aX4cjc#uJd8cba*evIvQa5zQ(eGCON%dlcXn5Kv$D=3+QMPoi=ei2)df2Tfpn{ zCY*5s1!!c?b(gvYyl$W>>gpU*Md%z;MX%{qMV#?H*UNb>`82;Yr;46kRm4K)&Y08y zpXSP*Ud|%FT;D69Wyh7^r3EFltfPcpm#YAsf;hbnS(N&Z6ZprO0&dKewE4OUcF`e9A;pKKkS8f*{S8f*<VE~mD?-kxkW%tZrAt9?fN;neQwF^2j}GW*_B)N*PKpnFY|J%bHIFH>(t}Q z?WqO1J*^|R3NQD|ZC5}|ZV^zE+sk_8mSbxsg{GN>Ik#qTrb`+-6EJ5zA@&1Zxt*I2 zd$LO!JLEWt`LOKf%Isw~ANDdoA6Cnr{A5@+GWJ)UrNu#ZiV0Yw1uDoVmxz@LICrfbOh9?}3g$Sklm>L>81^+WBU+X8K;* z(H*8zE}hdIviZ-Q^~SrW(j7WTahm1du_oW=E8mX0{F~LDT52_mwZfg{-zQ(j)XTqT z3tq48u$6CxwGFo3+txO8mmM=$Y%AXoeC?%Ca?8IyRVvEJQ4jqr23kOOBE!2TRLDj@XeSUR&^pLtCDb zug0H~4q3bt+bp0%4zsMYk&Z%Op-7H7>6pph4IOgKS~?2x*&;bgb~5yw?f7;}M`4(& zNRBz_cy^?tFk7HVjydT#DRRu(b`<7s70EFt9VbPOS=)}n%-$k7=A`4K$T4f_D6H5h zl4DLfPKq3}mX5-bx*|E|q~oN>F>C24EPyVOBc9QwY;0tFyiM6kg&@hv^r(p=&bC*s z{khpudf=vPvjeZU-_h9@h_ImF`Jvk#@7t6uEd*FE?F+C*Yx3m>Y;(SBeB|;ln9aYi z`;R?NrU<)o-y;Gl*^z>bG(nj5eOYgOCPa8EjcKMknx389>Y zlS8vR*=*IeIb-9a9ol%6jd~`ud0RI$I}vG*tp~N)7!g;R+8qa4=mW~5Yy?;8iyo6( z$(Oc<88#wn*NWXp5)JqhMWv}_IoqFV0GOTG^0)4^h_Ct#XLT}g=79U$Wq8bI_^wU{ z)KoFUpZW~X>trbRX81Fo;rX2mmEH`TSZhEo>13$(W;o(AEbe3&>do*qpJ7oa!*Fkg zzwjAaoeZ^Nh9Fx={O2#p#CaZByOXJ&XCi`B%Z~c@=XBmT*yoXfHoh56*=SLe0sY#x zs2khYd{J%nb4kv{nRew$OYo66io;Fy7-Ua9oQx?UX`a^4K6k+~+U@L4u@2j`?e;9R ztCxj#84JB%Ec9w8N0CtLw(HQ=O9cFFv$)m9`Iq!Y?=P8)-aogZ_rEYz^u9cOxOi^2 z(7KCWYH!(&VKP5qW`>EgAhBL<)g2CI+>1j9RaefZPv{R&~r*?<8db)t&dSLRXx$E_)rz-!TFaIH5{{G(b_jk)*U+ahNKL7RI{_8!xU+=N6ZTDe6 zVW=~U$L$*pMy)5;YN#uP=Cio~y4N|Jq0Zsdd2e(-LQdjbJMB~rms688*r^!mwA^fg z?uPyJP4c~p^9}oB_@g^xqdfB|0xF;<7;zG13<^e!+Fr%81ur*Q^;c=?Qsz2fnePXQ zX|tR~wRLQ>o)yHP(@m?7kHkTEF}?ZG$;|nfC;wqj{zJXwKQxK_bK8nO``e2C92P5` z+g0@0a|MeQEAzpLd}^cZA}=#D1Eu)gb4n2lVQ#?8rXti|A*HB2yRk)ia7aqAW4E1B zTvJqvoE7SVe)tEY9sfX)FZrHXh(?zk%D zw*QjOL90O)QZ7eWC}e42OLq9SGkqH&I-JNU$Exb+-lF&6V8#_9gs%+xfd4Gyr2}BS zC&Om_Fqw|nytI~$OxEj9c)fnq>-8hOdi{v$_0KB2cFBORpVn8LrSO!lgdU#sr5x)m zqBH=gn2CBr) zMzFbZ!)(|4?{-S(yS;R}b4%t3HH(w8o?$|LcSq-YZ69S%Xz0Z2q`GO(fMF%wXt<+} z3X8JS$6H}8?F=zp-Uzb#WF>Q-S2A~dC9|hj$?P#D^OtW%w@S(6e`z>!rj9q8w56$g z410GseW?Sg)qf!HR0oh=*4H7vEZ-8S?oSi&g_^;jrLXcQIMG_efv~_STdwOIf`}}+ zJlUSzAO+&{X79l$aqc<7S+>C#RG2%b$WE+4Qr0(o$jhCHXE1(J4fKm04hx`PJOHkJ zf=kC8G5&eKhiz{!YhZ?J7?Xw_%cfw6t2-3YaAwri{(a5 zF6t4C`{{lNv%{5}bXcm35DGuW5_+}ifUYKb! zkEj3V58^7Ue;MGSL8?(4*1?By{S-QR4;woN(Hgo=ac50Z(yA5)ndkNU%T;}lFA*b7 zS)j>+ewtK!2BA2OYo=?GR6tL_@g&NCp*f_p_i(fY7I2&`cv6@1r1rX}aYMssUN|8{L}pprN#o(Hgk)N#v(#TGV)UI=S)>E_qP79iXrm%S22&k1DYZTLh)oz|xX<%0 z<9lgYF!9g3xmOo|kNVc#F8-dfy7+d)rp4x_IBGIqE3Epv2W1bcbD!!V7V?0u#6s@( z_3rJhcdylJ=Sp^Bf31QzLe#A^Z6PxzqYBXY915ZNG74gWy)* zh+WV%pb4*=1e|(@#A-9wntda7CsBqEI1$SkYd2HLC`cSIVmI@mr8TubO8o^!NYeod zXidR9J1d@fbW+?79xQBGfudcVHc^pId-M8)O-}lom?~Kq3!nQ z*wu@UU4{-*Bx^dIGKrM0o8iu?7Z%A1X6d5b_i!Wobmb5julpK4mO+q^7`qzkMzCGT zb<+6tIUQ*jaMHY&20wny5Kx~q6vD6nuZ>?nU(!%;=xm_OP3Pr><`5eNHIJA;NLTyu zGIaVc*O5|*901Ck4pba^5Lr{%y&>}AHUtAg)w`TZb$mO?~^FQd*1`7GF$LEROy}V+wB#1J7Nk| zE!;%hY7#m8z{QXTE^MguLZ_rJluo=b*NJYt@xqQK&9x|fH|2XpZ@yPdFKYwTVvnpH zcL$c)?l@D}@*{>N0G`WChqR8n<;O`EEviu=0+>;lwfx+R~f!85NuaI?v!(AckTkADsWOTt{q{oH@Uygub*2e4at#n^pRH%eYSh?{4o# z?df%+_Lv)GgW=3T>HB)0zEZzeSM_^+DSLZM+1oAUm7SJ&6*8MS0NoKLyfQUk!~X8z z8qBfH&2< zrn=ti1o5!1?@(`jhr0E3M-V)n6Gqt}_8G6CLG<6YWlZhbm26&m3GRXoxoxJu+2g8C z8{$HknPR!TV_^sA;$9b3VXnC;mbnh7x0p?o)u*I>X)>oh;W_Q7r~Hv#${#Vx->X2w zMb7!{ojR)k0ljtg+Igc6N+o;2*Q#((dv~p&B1alhF=ALbDU;JbO(KMhZf_V~U zOg;Hyw&3MHRQ+@jpf7@HlCEi63OKEX96-|3U4=OML+QSfn9yYUKP~#_n-qE;IM&Mp z$BYLoB8T*wiC760i8rjoGFq)@nw7npW~I}kxa3`f&_9zs?!ZRL#X?*kcO|t<26$)H zsm2{#EzD4*&4n;SRbd93>y14#Q>1auw5b>d|0mgqTSYu|S8IUEnREZ@>IJQcdY15= z{9dZjD(hn@-pCAuIrpzS`G4k~Wv=>J@H}{Kz%=e(ac;oNoPKAts%r5*n@*S%=RmH; zV_{Ww>o_xdGMr_i@S4^63S!ce1^6xru=h9qfA-!#+^*}a@7zDmx%b?A&b`|DVM*4N z<$aE2TTY}{!HO&#wb51-Td|$kL(_Qzgc4}};JMd8tm%5Bd zJlFvPni4XG8logF7-~SIc4ELhRf|j9r-o6%P(M!%na}rq*WPFEbB?4d$-xFJC->~V z_WJp*_xF0&TK5McKHMbY!$!pahosIm>XmoMPF!u-Mtn$K%i)z*j)ur~YLb4#d*bBF z3Mi|CB4lQMgrr{`?+G!*@}8t`Q1xqP)VX`bjk-Y9Xl+hJwvyK>X3-E)oMn`4GwncB ztsrf4mm7Jd#Z-vn9aK{K4Kh0~A8M(}!5d-K=i{VA>k^qsfaY(I+G|H@tUy-5bw+AV zWwy|28NpLCEY?E4z`YkC|D zUC7Wri)2)PeKZ)L4+Y)zNK7(p~Y2ns4qZ@9S0Sm4);W0C&!xXfC6yP7A3Viq!YA)iF-vfu!)0tr5wx&2J=!F%*p0pPTFA1 zf$RjQh%kJ|elVc>yKP2O#ZihwU8sA^hKp>L=3I+|21C$rEr8Y*XM*2c45JnvIpdf{w=L6Hr#&pSHuJVh03@?_)4j>Sc~Dg=a81AXdG8NR z9d0&t*qVCSCmXO3bDE&$5OX@GpX=r};AiLVvwlnuRaCz)Lb1UCp>zCYUoc)o#ij}u z{eKqTz)nVOW?!8XfQx45U+jVdrSV!z=1q$PyYjVVMp6b=a7|wkb2;33R}~BA=Jp`1 zV&Pi74O)px6~=SHcvNVsjHQQR-Z)3lt}QZ>TOH)*P=7r?VXMn3K2N7C&LA?%7^^fV z4*qOoHbz+9In@zXqSza>IGD~?fxO*(eGu#C*FA~#3lPt}b(PkdPZ5j@2_OD6!C}|W zWz1<)q|~>qOi-H|+g6$}Y&Ers{ZIzq4$C(se9tK+Misc)l%8{3O^9I&@YU&|-Q3lt z^X*=xHZ^zo4Y#cf18RJSOl_ARQER2z)LU(e!sxz};+uj(vo`SD(;RZNx|dbUv=cTP zg=N~X(ZtjYCcduo*7SjL@=~9?aM94YY!ay^@7(K{G| zYAd0EUdViBw?KKW&C;p-Kj zXcxb?I#UR2h$EYt+uqwzd)wB#qN0V)+{MHUkkjt#?9MIpHVfhE;oO%HFEXrZJ&b+$ zwnm^1p`oq0`Q9qMiHWhOG}D{ao9z_q%*8sxWW%V6-gBWST>+Wc;>RehCVb1~<~Olf ztXzS!J!bCUUEO8p8Dfdi&RSW6F3V$PdZK*k4y-umXhzm!wDSb2GMhjPqiBPxnAFui zO|kC%ObL&%0MylzTx-T9*R%?hDA3{2L>51X`WNsPL>4*vbBL^If^mndkK&5phw+k? z9b;n^I7wLSX`L&~t?3Mrp#-pvwhv-Gk5}LxS zG=+$Pm<~69YBVK@Pl>(B)eeS7Js5C8N8^4f77I;1H6Z_5=>$pf&BGJ=WM`S+hBqW)h0i>=`=4B+9sTz zL+mF^$_annvtgH^=PM;N;pTcUTC^pW#FRjIoztP@RBhg&0~l7Adp0y^?mO-Y>QrW7t4pvot9Lz;*m7^P@0buvccp$!SPKtA-O+ z?ssv=VYz4aT+Uj|A@f^njQ1SsKoD#DbR(eHRhjeco@hwX0NRunL?=gy@iJAHZ@kaT zQE!6H=1DH0x<6HHRy!(8s3jFK<-vFo-Yf2{1#+Cy4vvp zANOHK5dihdYytrwNcpy1V$AOtiih#kCD8jk{G&gDhp>2&AKZduJ@$(5^5Q!Mq964oHxZx8v1p%wu z1`~pGk>i*UK@V>8Xfm9iL+tOJEA`+~0$`Na8&SQx*_#lLieZ7JgI09vS^VjvS@3Qsv|PTCUshq zIzdO%q#_2~xRK6algf`Kb^34Nq*|EfIZSFj)EEEl`AsVPT9aDaBm2gr!looy&f0@g zN`Iu*S;ueB8aX?q;%MrYH5h?A`-Om4;(rP(7?z=l)iG48Gl~UoXi#g{eNP)it5~#>|(-oJ$Bl~a~vM2Q!bv>A(A*qpALsf z9#;^=aDDQ)9VYq7U(m@h*zo2!VF{t zvueWe8&A;z6E<2ceIoScShF|BtT%Rg&ODqj1f2O=q1=B5rF+YP;2^cFlfvxGgVd&_ zXE6kJx=FQao{D6}=SEB0qCg;|Q4<&6Q~v@dD~#5Oi;?Aei#aMP!%5qk>SpeG-fG_6 zRX9h^*PCV)G$`yG)@{O?3&$fa4ps&4t}jTQZ}&uDwjjxTm0o=#-6p*_BfMag5uQm8 z70D=2KwR*GFnO+shDFT_G+pb*xu6y`IX$v;$dXN5ke@^S3;7wDqp)fyjp&@@2TtX3 zQS;pEm^4QhIw%{Oc*?<Z79zU_Her6BM^b{wS=|s8y@We8`j-FVig+3iB-Knrrt3RV61+#nV+Wv*C zJC0-Lql|k0C*eSfyLu>q;7Ah$M+^l2n@LryY~g07ft%lC-huj{zd^^eRRqv60@w+T zM#WnL8R#6_`3XaOuI=dZEWZW(;Ay=Bxa0Ea4AJFyTj=tr2#`UJAb(Mv(baJUA@pQO zc9U9uF|_=Ge$iT<4=tZ)wtT``HnO8-Ay}uzf68Dwi&l5S>UbcX`Y>_Cuh5RPrI$my zFNJnbHrqXE?HXzuS<jgsW$}w4 z)R%|HFb33`xpvU8vm64}B6GbfH4a$PoVlD(RE+jwDt-(95AQrdpU665bG7SC9El?r z`TZS{Ex9~LRP5m4O0Psjrpl^t+DV+_K@COxM?>Ufll#Na4mXE(czA{*+>~YKIybfB zUTIf-GA?P8Y11G`o8w}V2DiSZ!A(#Jf(FN8KCJ4L8r-I#28aI8Up=P5tvYM#a$JKu zhdP3Guv!}2>ihz;kv5rj(A410zG~@h(hh)LcnVi$tSW7$nkl<}#Tp#eQEA2=4$=JU z8yegypRV=N;5LnGa01T#0X3gBZV zfDMD}!fLZae64R1Ut;c?F1AxzmdM>vzO-f%Us`htM}YVePMXrPB%AmWKMF@)Q}U$} zKhBr%asIs8e97^{t^f1wUS;z){c9`YOBRoknB!E)wQ*?AnOf)ae@2wOLixX@CjU=E z-=~-Ve~W3{P@!b)ZxW;HceVCiLsHD*jr+h0C+c){g6pL4?EKPbI>Mb0}G~ z!f#*K4%#&n)cdpd{R(x20zKA?k;MVZlTV<3v=q#`|Ky<{n2$6C^AQuwpD>SyR;JM% z4Q0Y#(<94?J?C@jM{D)tnPs7jei30*{1X?*bg?_hjsNa>$<8`}ou<fhXG^S=BydVA-}dU0PM;(Pfm2&%d#5b<)8 zh?k9se>wCbEABePYMTjioXV9mVr0sDV{C-o3uA2L!O(*T^a~rgKlI>mvj>N*2fw5q zbk8?#3%8Zn2uC!R$A-NTw{<>d(YXfWG21MGc-$6y%FZtsFYFmS{KljL$@2^;lW2Gq zCe@w6+FZz1K^cVaC8TJ=?$Y~W=jZq8SBr7_g-DlW9n==%Vl9FGmX<&*XiJRpvTC7U zXD}elS@D-s8VC?GrBL*X3tfih$Ia(jM#I8*XBTdFWOi{YCn0x#^Wu2sZgH{YPgCQz zP1ysrY$kzTt7Z1QO-9=}68 zeka7^vmTzx!=B+Fm5Zh{)yiM(46>3GE7GO;tD_{1r_SPE+w!(h?9*bfJ6R_cKP@iR zQ(I4$=&7Zrt$Kp=(&92b;bKmUJv{NVc~Sj9{@TcW#0(Tg(TCnw96H-(_v*YL#Ql*w zQ12K}F}Fws!a)N`aW`jQBN%`THtJx?cB?UbZQ7C{IhZ2UFsx6o&=AvD3?TV}arvms^*dJklor;sF zeHQ;(mN#V$BWM3HKU?@|b&HGnNxQ|{_#uj6H$Q+T9RW>|E-GMLhg&eFZOP5~6d=AP zVgmvj(g(BU*k|+*kZ@b_{zWPChJJenpwb?8=H1PI?1=SM9POpQPq1$ldlm;YI~Q*f zya{b&I+fV%le!~1XxeV^kI7pQ>Dcya>dG)!#k zaf%@}NANzzmqJf;K48-xod~k$U31WZ(l#?^Kd2FCavGnCKbXx}VMSQ$iy@HC5-Fav z15${TR9vL$7(|eMlwF|Z(p1U9?rq7wvGjeK7Y|1j!q5Z#K#BU<=s!7G;%lOVp7Vew z(vGt1^o2So}@)i zp0@6xPxXPd7+7nEqwdcTe4LO1nt-cl=x>alwKO{*AuQYIynOCQj=%5ko zph;w}!7d800|WPsr2{+rj(+a2vmXvVaoE{UP8Nfmi)H!(V zhZ_wYy!Mlm#lUMh5BRq|{yr+DXwPvNrpERwMpr{5c`fOx zIRmGfneSm{)OWL5>m5JM&@r5S=&-8xTzg12YbMYQX>ZWYIM-X*?0isk^D)P*HO7tJ zlx#HF2m|8rzOGo{aN3Y?!r0d@)y$Nr(-G>xu|+j@@WpTtuYaQXP>{&b#F13u3x>$Gh|Pttg(R zwsCZUKTKBM(eve@#Vk9(mLlkzgx$%(BEl>|Ni~ZE?2~3DNyj0^K}jh(i*Ave>T7pU zmyJPE!rfI3lDVnGsnWe(cb%P$>Thmw47*&!T^)5JOC^@2k|Um7gU_~P--I3UPwo(7 z^PyvzqH~wedU$d`lhXJ^YbfAzvGhFT6?(NS8+2Mb962uj`5k?X)@{jw0TDwgTA2U` zaEY>v(vhGlo!4oKU8C$bv)67%6b)4Gu#hZ;@J0UAnA2V9B-!6b73pn*wyERq%WAaj10ao@w~tDzL`U68X&)qjkFhg>5#9OA zucvb9f8H&dZ;N9y=bwJ2C2XSvhuWIi|1Mm`&p^Mb3~z+R-C{5*3b(vyo7&0Jk5US1 zmp^K zugTV|S+kb^+rL)Czjpa%zft{foTSR(|AyISyKClG4PR?dbM}v*yyD02=qKu(`f>78 zt@&28Ze5I#4r=U9UilO=pb6p&6P)O*F!DJj@Bom*)Fha+@I5dkDR${eSd|DEnB|GK zjM>U91;Aym!upIR zrD>ywz7r_tg=^oHrpSK21Mp~j^q+NH*3Km&-~srL-%&)s@R}uA+r^*9?_QuuO!Sc{ zE0U%8B#Nyr;(Dp8Hq!byPjY}WtS+)0hFTp7SrrCf)|r%uP{drY9cM|#zsURk;8%?`O6~@JH*dw+@T>Pdz z!sg=Qx9kyN7Z=Cv5k927HL4c}T+G%_Jt96});#gE*-=^yH8%g8;H6101g}p5$lfo} znc3j{8hIDx3K6+!5{eApsjzPp&e>bNUwjw9b`b z{LYnO#)j6g=Ie#fAfGr(I2Dpgg_SVFPBd@-*oHLTx8iAV8ULY9lRVv5rpRjqX{L>j zc(>&#ys>q65wV4#NDuX=9e#b0P7Do96|I|KU{l2_*v-?2`ZJ_Y!TH(YdkaEAN7x`* zk1gtzr?`4bs;88v<44jZL8xePn2;((*~w>+yJ$)Z0iZ@zrmC!JF+j_&!-tIRz)(5m z677P0ADqLdT<=}rZ**{>tHXRBaGHcP2MHb4!KlIoo!g7&P<6=gPj6V@a1|X3Lq>*| zGJ1r6qK&%Ll_#%s=@O8FW(Sgc5=Zi_MzEvwHmFyXqe###^||OQWfuq!tZTMBqsT8) zASilkXg2m{>4hlYpny;=Yoa=@E#nXy!zv%BvFX4Gz)M&fz0%%7Y7U~{#ZSq}Wj&TS zh?n}a&cX10GCUKeo!Idws_>`JuthQ)_U^pzm*L?WwIo8CvpW&wMzXIf2G`+2<0+f# zNy}q1II~jb=%5i4cdI8jlR1}1=amYFsXdREfKs$0dU{aoV5iwaA2JbP3W5Rix(6wV zBD4fb3iGVTN#0#5?v%4U>TBaUL%7qiE>1O`3hTB2k*TGM$s5<% zsZ>p&PCpZ$2doFcSs`Ae7u?$>FnIhx9$}RQaU)*qG;Ng1BiLYgtTV*J*MJpiCD#H@ zL_Pk+acm6-Ecm4%7J#=E4qS4bIK6P7+kIygEx)5bA8;k)VwY#YgT(ManLghawq<{( zze=#u)Y|lVe~b3g{Is}Qnuw{XEti@=agjimRrl|~i|mZtq~Zu8&zW%p^E^#O(RVN} z9Q=iSR6=^+5-_D^OTD>-^zkT6Km}??`7jJ#-mig`zz3TQ?j(IMPs)Bp8jsDFiwOgi zioN98K+G03WNd5x|4lroDVHM}HB9Fb$5yCk(dgX^FFogI8=&mrEV&%><1q;3H$_w zc@Pz@=ti!p2U-KCe7cK`rUvs4Q;T{iEMxU6?QH9>&?(d(-VL45gvQ!X+S#@-9K+Ve z7*Maq>Q~yS>rVoVf;rQ~*^-=xME%sD_@iiPek#HMLw}TcyV-kSI_~FIWmvY*4cOTH z@=L437f`491ZiLq;pk zK2daHW~qoJ2+hDUlf3GIZh{~~=mE;HSf4A5c1ae`BRHQH`;5QbC!0@7h?ZVaYeeo; zC6$y0AVW0~f*4ivCYJ)yLMorgrsd-e z$o*6@(=@mWo@Uml=l4o^p%459_mGrdyHBG;Qj`HeQK+}`OU1_yp)$kZF{~A$kaT~! z6|cG*uS2#pNJxm(|Be2`z|=;kAG-`H9vUoWTk`12cyk`Fj%{5OHw?}z>uhJS_`O#4 zcFO+Wckt(a$s~$DK42i6VfQxD9we>!)31V3o_4_|JFDGPDt$w_1+H*Z_Aaj*%o89m z#o2-#tx5Y#k!hd<)cJmYJebu}2UVosrXHzR7IaC9&W~o0ceCnJB)Zu^#U<7NaA%PN zsi&8+Vt`VvQvPKcT;OjL+It|i14J3wpv8j>l`8GJhZTiX;l?dHJ~t4GfM)a*19J^ zv7T3_##2AHio=8n0nm_Lqeg@0KV~y4Xe*SVYWhHc11B6ZC3^LiM4jXFHPR9adY4hm z)2MJW6aK{AAN)^ooN?bg$Qyicakks>DXTfLEUv)$p8w5bi8lN_^5;dGgO`7zt@$K% zn;#LZ<14YNwj~FH)=r>?Ety54EYuU}E;sUngXADTNGxjfro#kn9HTCoJEXO;F6{?OWzk&okpl{dBiTA66gc20db-R;CF`l?`4g^uo z2cB_aKrBSaGTPO~Fb$hLm@3() z&h_j>PtHeJEIvnttD`7evq>l$lCrl`KKMfYl9D!RhH$A5h~$CSd@>qH(ZDG`x!;js zov|sSk2IwrxpR0*mie8;-QWqhjqWqeuENA*h_dfgZooSL^xy!Tz$aJz9{tHWg4V2J4kIz1n ztwN322W@Z>bEa2R{Q4aj)!!n{pjau(sx#?JFm>rWb#CvP0!e0G4Y)8&!5C_@vYI)e zJ@uBrqS4Zq`E&Ru`OeRkaz)g|Sn#i=auZ^O`H|5+NU{bWxFzEl7xx#gD`ZRU4ISeK z6ViX$UI!1lNgoMXdr!&RR1S%coYj--4v`M2c z;`&@dh}aA()V8mqtzMenh`FTu+D89H2tw9NtOQgKp%vVWAa{mVQI>?CJhZY)jGq)= z_((O87sHagsV}zhXOHyXkl)32Z8NDe(&1SNiLXB&7JG~}C_$gHgHVY5u7Z^S8 zFt;$u)y6BzLiV1Kg2hF^MIakZ$E6%QJE!CT89|c>%c)SaHnhK|CxzK~yXM2DesCIg zEff>WPNcM*Gt-XM(;CxuryT<*nYITbPO}yWY6^jB{6xAx9TrJz1&^B01M}${>3bk~Xi9xM|9^{f8DS9{z2D8`O^DIi9(UH;BQ^;j`Vhov3#~hiY z?qQhsJG6)zxipvssX2G#n%c6zqiofM4Fny#vqHVLk=nsbqKB6UmNt<~z*IM%l&a0y7u zaIQ&(uNr$0z(lhpWpOSvRBDbd7{y{i^U$?&iEl_d3p{etP?=~S?3QbZarVJ}@N5PP z0A9<%I{a5MSP-^r)4E$KiH|hkf(5Gj+yWzsY-v578uOe2-?gp5|umZcvhrIcF&W2qvrq>b$Xnw+YfzoM)`UT=N zO4c0Y5Ki$GO!b=av1;Lebe@$qMm{#5BW;j|QlOSkCw^#kg+r`3@~pjGLvyJV_jM=81SG`r7PNTQ7>+0Rad#P@+B0I60)1jNx zQ|l(3uDV%vtL!FR^NcXWIWh@`Bx|cuYA%=(-b(cG0BzKU;@_c@!5@p%HQIkR)M)YC zpk<&5R~nj7IbAF+HvDMva)=Mc6;4$1U-mI+2 z`cchS1uS_C*9siq#<_%f2{Li}G2>XQx)5n9UjmNQ9$FBi5#jUmgm@PG z5Fk?bo`Hq%sFmP*7f|1P9i8i3cL+PfxamWfYQCUbe6H-kQ{TUWL@})tSRS~u+O3WcIH5*-(1Nxwf{8xP>iuteltL3#! zh0Zg=hpzk>96o{5-MoJ;%Xc1tH!=d4ooLiZfC)wo*t_pCw_1L`xzAZ-IEADOk@pr_sy8yAaT>gB!R z54Jl@HrgcWZ622oe>h!WdFqhj>{x>gIcANp=7b&=X2|wUg30IuRgQ)jCZx+@ z<~?KWh+fUgGoS_Kp0eLMSf#bkRrSQqq{QB>BgMI(Y_UHB;j*TMGA3;@XSL1(5GS@L za8Q82H(fZ~cJ;HxDC66VntW=j*PNwX;6JNPwhSH6%VKN^Uje($4A4gAMeS*4E~J^}~bV>g!U4*juYcj%8MTmQ>`l`?)}zq-;t zn#GIUKw1`0PB*MeClm)#%*e1fp&9J2@dcEdhaZ~V64UD=pN&-a81Dm<#4%W%>1E$y zY_UVMElbrv z4H6h2=cTyu_9RRPx9hl`@2ZYz`LNrjmQRS)xoi2S@2QDk6q-c(Pgi=BfxhZ=skyEM z;7zzn4e)iLY3K?`-*GdM30n+sQOs=8TnbY@=B>F9Rwg>tFd$8ONEFTR$Poh(WAMRB zbs}wBKOu>S?E_n%7@7)+TYjZw%JkgG^q@f;INb&Ro!X0K%|$6R}2JmAdEF*y-k>h@qwc2k$PyBck7`;pSX~nfM0JLt?-lD&~6& z^PbZ|>BI62N>kovG5HCC(S}e{!bMFrtsD+fB)7BA4imMZo6Fq+iS-prrV`K;fitdN z3WOy(6Ch&WAC>x4p|&WH2|qwtso$nbQ&UoGFu#%}0o}W0KE?WE`$|cZ;g}So2lad| z#U>=$gpTGMn?{#nBgL89(G^_ztnoEz{9tP(#hj-#X|Dv*V)4}2l8-Is2_6Dsg>raA zP>=~0t}!Zwi-<&&F?4V0Z1|FsK$suEz5Z_yxB-o`x|XOs;N+>njU8`L#2H=(FyJ2n zuutykpxneg@T6qe0Wpj(jA0)6s!1%{SSLLFoQly6;JV0UY?92kK|Xpeh@_V9*BXpmt1nlC7a z*TRTXF=LN0oU6qc?yF2%s)*n;I^fCzt1DY@l7%=atz%$SPdvy>UaEnGCo<~2usdS! z_KL-~kU7W^G+DNQn@<9Xqp$n21<9Y{NAAFh<>6oGt+9NX$fD5hNIseT!#cCtvhVUlYZ3g^8q$`Hb~^#3K3#UB5ep z<>BPre2a602dhfBS<=v#6b@p*ho^E6JY#XhN%3!nJn3y(g@~>v#y!OfWHF&F*N!(r zn#H=aYDAN?L^9#0R<)j=(l}rP{OXks7rV9c4GxD9W#6R_$LSWA&Ur3sVo?g_Zwzza#^*HJ9=srXkzVC|Bl!L~0{o%N2f>qK3%;y^k0+>JO9LkTV~ z7C;RUK-dO8oOQ*&=_8Q!bs#d(Nkr^Ty{iN!^*GIL(ij2)J)zO7%;P+?54OMp%p2Z6 zYh&7Y%VN%*RFumG^T+XjSnO*=u zFJtR_UaaZ^_f>1y-aUTQ>sS@bKfX>QG&CYPpuRL42!u-xYsemk_+S%5E(G61Hnk(q zWU6VK50xVpRYz4uvQvWEB;;ULGO zN7ZW!uKK`&$=p?rW-ww9V2RtGb#R5+DT$9zx{svB zi)o#z6_=!*od5$Ssxui3`Z7^4j1Dg@(69D77{G$Md1k#3W`qF9-jypFmc<9X_QOIY z92=I!4vh`#Eh`!p%w>{Z1)5Kqtxc0>YvUy`t=bAOlnuwSd;5IUYWw_61vW?SM3U%OZh;&oKg#8$QsbvtXhEA$e3OO8vFucU~Fs_1~xjj-kZ;PT8Wt& z!{FD!wEoJZvC~&n!x5CWd3_V}s<;Pq6Cfe^xwp5?U}9kcm%A|CEAJf;mElT~4A%rA zNX86TEYH$#?Ts5)mO>k1Rkld+*$(jGsu4(z3raKuJ4!R0G<`-Q;){ zamS%%N%5E-rqX>$_|M!2X!mxoP!vUR<6n5KQpphhp*9o2ih2w15_2=`Ev_WsBK7aO zgJn3g?xB{~rP0?bbRA!+T?VYq3P74B!gZxFqc?vS5rt(PtoJ6j2S>NUUL~JxD+Xm4 zqm*PuyGM$X=0xXsXm!{EMs4Tf!92ZQY>6n1>u+V#1)=MC2^ZaDYH*R(gl4Ys5M#U} zB2XgKfxl9lE^c@w$plu-Rf-C0 z-3$W)6huZwR@an5V~Bt$hiWr-K;JK69)4kn%9qHWXgF+!o-LZ=@Dj<(*F|-Fte-GU zO|CGj(2(Snjd_*Z=*t!(Tq0H71uYO4$39Zgk>(-*$EMQ9NuQ;`8@!8O<46Q$Q3^i} z6SE7YZgIf1QiBav!ksVCbkh z!jiIoVA!KK!Ji+~;i|g6yViRU#`1)stT2=Pq||x#ui79j_LOWMdrC6|JCMQKCFY3e z(q12cG8Ue=`TckenjWNbya)UKi$tzQ$6fI;>M>RP;YsNqw zXU&$_XkTC#?Jf>h`+!W9FTq)1IE^Hubbv~sfQ`ADzz_jfLcZ)T+|De*kldJJ(meKI5=Fv(G>0e~ zd*u<*_HuJV83yR6uyK!iO))to1|XBtp3d?624Zw?OX$4NSK7u!-`Msl#%|PNP?LDw zD}vEFgy=@zjlCK;VvGfmOjok|_7$%fwMP~K*3SbpJj z12|g1BB= z%?pSt$%iHLy4J-aEgDzh5E?6$*Mn+I$QF+^>X`(eO{W`Q9X^{XA#7b`1RP(E-<3XS zz{N$T3sp}HtJ8_d z^Xl)+tKMJhU#-7fb=!dN`t#~94#ig)zSh55f7g%n_kyawuC0Rifvj+s519#VYO(qBa<&1f|k+S5?6@kLV8Bc$g9JH5`>g^mzvsqY$4e;16Rw^c&3s3}XL!2th%t zE_K(QlFNFZO)WD_v!@YguP)XUYXSD)+6DghUk%=R*4)HK^#2S;xOQZO98f>f>kagE zm2l*emEef*r1@WkHJhTiHTj}J&bHv|~i}8*Q5`GroF>8(K$) z7%9!S*{fGUl1*I80`gk-lH|8unRJllSf02dPKfUflW8>8~bBi>K3 zFjKcQVYk(g!>AaL@6v_^&)b+RUQt8DgRf=?XX5Ha`xe0$7=C&Kg*n(y+Z2=fKw&rr z1-QpJ6vide+s_UPAqxMzp&&NcoQ}Qc*%2Yj3a6v)*bx7%OPtk}#5os704v{PGW0B^ z^I3CJ8$k`zA%n(~yR+==I|gZBmu6trc+h zz^ZLXwIMR3#t;?99EKPMClA}mzzAa)o13#5n6+B#1+6xE!7=VSdDTJ zKr2u!?Q|Uhl5;SP3Q)n&wPLwj;ftJ@?_@Iimn^%N<}Y2(k(kl&SWJ6jkAR<@nXczd z@lI!2N3m>6*p~FJxeJ68y6D%aPsxw5#L+I^CKTmH3>>y^+1394zSm9(%zW-=qr(?ByNT&0VN_ zAnfHB=do_oeFFCO1>QF3lyrOhB5&(;K#je9iMI=MsDr&d!P`2W2V-ylmbbMbY=3XT z9i?+?>_%(#>Q{MNZQCmK_9R>I?G7d@hb)Yl!^a8hQbjn)^=`oQHP5%{{9O``YdU?M zP*H#>TPQ5#KjjGKP(k)xzT?c{ZHK+0l2|jC5sYwRHQL|Ghq|>&4B!|slV%;O_i=bf=xWm6~6!PL1@nhoNY^Rq-CC zJ6_~^?5_-$NX&!Cw+JTI(E`C#@n&BqAX6*s2toS_?rP(0CB_Vopg4fZk}f^Z1OyuUkDZ!_EZ`sEwwv`aU zs&j-d=7+bOAL7)es~u)kzvyXoZUf)sfEcw8rYz{WTELcE*4BBjrBhlJy&&gzL)J(FwP-#)NaZ{U#9(k!g3dVMAtZ!i#A;8TaJ$LF>IE0f zKhLjGok+=MsQAJ#^vvn5KHat(DKuo$-S#a=nr`D0WY(oFp)#)^#HrbLao&;XCS5$b zHr0w(ORGRZRCngvlu%kT+%SNl>n5@#P#6TMx~lZ12|8k_CY5~IkC1R-CA+A$@sQBE zK||}HdX%TdBAHO{WOEkW&E8{>t@n%Fl2B^1ucQ46mp4pc(pIO6hu#&p>4h0IjoX7i z09Hl!1~YBH8SBSuu0x;Ij+!v;;?4Oc4XMxJPG@;&n z1v52LC+Ej%KDapo6`b48^a9rGM&~L`UA}?noNan=P65-OH@RtIvu3_os?n5i5dgl9RTa3I#e9_k++v>1!y^_rEv1rMznA*fC%H+e z0j$fudyE)Yj%q=(PP6xT#|$aV+_IU-{-N}M;-8LUl~72-8XJuxj|_~GXM|90gGPlq zL(cA4W5Cha3|%l>l~eGR8;jAKBIq*#>$g;XNzlY0(oGu=E;5@l3#CWc4~a&h*ta=d zi^ZcgR){4dTd1WNHbRwci$7T&u^U^Z1o#OCJb5&kJ0~sfFDV|Z!$yRMeV~;AwgUhL zd|b5IVl!+RC68}P&a?<;nvvyEfl~f1`Ok_U)s6Fd9s1P<+}|K`ji282bABF=%{>k~ zvihb~U1PKfDgq@`p>170s4gJt0roUo4x~5e)g>t1aDtoa4ukfI`NMGqe#NSY`ayE- zWM#v^U>b+ufb(Y9cZk)8B1j;i$FH+P({_1kd#4w}grY6fXs%2a_=FGWiH&WZ0y^mm zAJ7(0>$+M*0aS~&Bdf$ADp9^NkHim(jq2}PPwQ;DKY`6oa^_5%0cyluE1naQW~f?E zJFTtS5WN8S+&wu09(b?4t&lzlfDhw#UGJ^kB!iakt6*Qj5<}Nake3*j940DdmVkB7 zQYdD}Z_HChaKyKP2rk+%T-l>u1k4bRbDDG9uNhDh^z~&atcH2>avFhAx$Rw{8BqQJ zn^v3`YLkp_;+an25&BOwaWk9kz#`jugR52lBA6Ptujv907Q=31+HE@xkdW-t6u*z& zGxxzOAiiLmK>~}gd>lPRH8z!eH|}7tNi|w*Wr0EcGlZurUhz6O{$*ly!mipjXib9- zZV&hC3dyjvs;$vsJYiI+u6-$^!otc4vl13Opn|x_wN?u4g;i5}s!Op#0FV~{X5n#r zH3BX|RPaW*5b4wvx}oc0*hwv!yN|jcD6`Ob&{-(hG@dAP#iqn0B*OrL`^Jex>$(hS z6w|{-vL;G9_Ky(?G&Nd0K+d?&0dwvsMLxnd)Xy)t)Y!?4VWS*1S}UZ_p1NmceY(q( zajwV*BD+WDt(RULrUD=Fq_bc&%cEmLcfL%mh7IKgR;hY1UbAUM{)`S_60da_@#5QaF3C2X2f7Id8NoX^GU+heWm1k^jhE~TnU|My zb0P4BeFGfCY6l)MufQ_~CD9o3_?6j6HS?PKW$9u%ZatPY8rg0ST(XNN5OFDZq@u5VjmQNCGbWrCz zXpbjj&(TDq+L*|wQ~hYarmfRo=Fun@a$*o6wQySr=qjl z^ykA%2ADgk4>*tomcBtU}NKNSo2y!Gr2A3IWY%#QONckBDz*L6DkyEP0Zq z;jzb&5q?-GXy>2a_FkUI5;+ibMjCHm9$?7cXR{ejiux=gW5Y(6UV8!)5iE8mF0Kw; zx23UX@6|!4EID}}&FmGbp?A`(&NkG6r!o2E6|{>zlkQihVo-|`w)e)z@OWPdkM&ug zU`9;1^M16?Y>|PYKp8xhK9}8y>sh!T6_54Vv5J(=zFpFRr<*jn$a*bqfOL=dMGI8) zWFMU6_lf=hDMUg!48nQCw1Ipr zYkxY_etfL<0KzA_THnn16 zn$}|{KO1hSEwX6?vwUox2Q}T)b62%VJ6=|&d}h26b4B`dWxASy>q6M*E#M;*TK~km zncMc|rP>!Asc(tPHeT z<44;48R2;Z$6nsIG+^vxgqAx$y?@jF7$j)pG-41NyTrGbBmkOr(0DOd>rX;x;hRCV}~-x_Gh!7FUs__LnuHdafsGx_a_ zji{Mb5Z`)!b#Qs%qIEUVaqT*08I{ORSU=zH;k!W-5ahtvE;b&gzk~XmvJKKmxS=8H z_$#bFTmO&~3yv>&34Iu1vD=oSzZ*+v4zG>g5iKh){*W~Pn6)%%Eyb)L9o}@#Z+JtG zjo7U{d>j3??lj*nD8JEyPInBon8fXt-w^OJ_}Ln)2VEIZW-E3Tdz98$Kz{N`ns%W6 zLZbF6dInHT(p%YE zc;KW5)01SHh0DunSNcqfWiEhh%wv%ySGnt_BbGjvv)I~9LNBLyq5=o=WWV&^RaXNz zOR-(}H&=(F3kPY>im1Jtr3|IAv^|UNy^wB1Z_?Z3i~#N^JY2*Mm0}D^Pl)|01GJui z)b$GAS62A`Q?~j3GRp@}ndJjzmJgmX%LmIWA9|H~{-LtM?>S|g-&1C}<&;@&@hpQ_ z*KmK7Y2@d_sBggC@xp`y$h}*h{qBdLZ&cw((`C1q*Z0!JchK|WQdET!m@ z5+@9EOlH#B<(cB@5#6E2s$51GzMM>)+ly*heD1d~e6ox42&92;p(Q|a8c}rpLUnmJ z32o>|nzq+vzka(w_eT>r9DUsh&B!<^e&#oH4=(_!|HmK+o4YWHTWMQ=qULe5y1s<_ zUuLq6ibRWwhgS21fg2Ss0YDd8|6`6P+yPPX`@m9)L&DB149T^A5wC60f(aW7F8+9p z#-;oMFdiHUoyd}51AKwUFolXPOruziEoP(i_PRl%6uD>3oWTlK#3XOKlbniPpnfh` z$k;nkzd-j_#rYv%x-sJdn(EzwCFy=RQ-)rk^D~lpst2>*k+ne3nE|0f@a`8tdZL&ByttvPd-MM zX5ZHBo=DgNr2D8T@I&`psXj**`EU)WGU!YT~$4t(<|kg_ZEbc3?pi3E-n*J!1^|M9KZPc>8zHi^IKh=xCc7A5{7M&93#qk; zM%9I1Ipb78&bwa1frL$tr~}mQ5|S4QA4KIzA`feC@+8TX)xwk1sXR&M=J8_kB*{3J z3k*hqi$#N~x{_91(G{%nDdAh9$MO$Omp&!00kF%bB*`rH3W^(hC9_0scj!v`Y9i%h z3>0Y%6mSw*eI~$@Y&ANJn2Ra5@dS97*DSqV&`4}piF^rD1`DY{d`CXXTY>ioN5cYh z`m&VyhF2|duUcAp)ntx_jxb&^7iK8s{s91zrl5IuPrcA;&@GnxD z_OrDNM!qZ`69-sDy88={j1p8r8oXv%AtVMw!O}T8xPxcMF3mJ0N4&HK*nd2gPTd{f z8Gj5>v=6IpYb1*i&D(r7@MbB`kg4gpy4guj;n;Jy;4VJ^oiw%$u>`1INH+6>)E9#U zy728xTm$@-MeYwi@;PG8$fv16!_hR^ ztf|Ozvyg+yd}$Bk^O~n`N;YyO-Soe{e^0X0nxWR2e}e!390CCr?l-47Up}>(swDNL zSXip^e_E+KU8x9@Nh;WaF0T&!%x_1oump%&qG@`r#gNmRE&dgHkES~ggUWX1#+!wM zl8DkkNzsgF-yyFr_d5w^@N871|ZJj!lO$SFfFu9v;;f2Q+eqW znn`wF>`U_IZ$Ss;HY!vIwtB@h@b#2savPK?D5#VQL|xXHitJ845Im-x(@6TvqU)Rq()A1rMB|f(QGC z36EIuhsKIObcW)Oc<~nufG2Xn)kPrSc&VP~4idr0XU=kx>3ycPqvX}ojq3UMKrK<& z8>#F=^+X(EB!()5F(>jauKk(|5*^wXBTmW}DITY;4PB5Ob3x964d#NJJ+%vRma=j| z%1d}!7o^rjrjTzda6xjYMAHQ+@7mu47bFl4E=UPnQ|8- zKXO5Kikb@&wu389PTHFO61SG(N&Nk^1!2FabO1}Y)7K0ZFb&|(tB1DR+epfw3{AUs?$_D(qOavQ3LJm z5i6J5BkID3z9ZsFyxVS70{+0;ZoRems4@jp57nPAP%}VeF@(i$WND7YTZ5C3wFtuOJqS%3vRSAWY~UqT!qO}z)hgf>)v4Tf<=HSjMvPSfLW@KjKU#eK z6$-;Pj4*dvQ#*_68gqs?l~{!nkj6Hx$**;RwAqy@`c4*Gaa2o+VDei z)p328&%(IRYB5*x!04#Hj;ofPHuSVS2t7d_RGQS87jqxfDi+k@*0fZ9GY2q3aAeKD zJua`LCR@|5d#1M*A|};k>2sxBvx^{R^QG>tWrfF;ZJ(X$S{me;1+ zLZWnkrjxW-Z+55oG|N#he5NhGj-n^fBiA9nSgOnTK}XoEkP5BcOy|>AB-zy|;!RH* zuTJIkBOK`vb`0EB54b`7f#uUaV#U{ad_fs=#Z^33T(Z@h;8S9Ig;^vDGQspHA~sdy z(BcgS$=iwW_Rv7ydD)nc+7s@8;n0qdZc z)ADDk{#8$htEUI5rz6$VBh}N<>gloS=~(sjWc75sdU~#W%A+fijur;t3|A!h`-KRs zB_U=9qC!^2T{EfEZ7Q@L$4U) zD?q`zd4z7Ne-DK29#Q15C0GbC19{Z&k_W8=SechKc;$IWDS7<%IOivQd%T68*4txZ zGXw$Ps!V9g*>=cZ%T{??Oe5<4M+JYuGBSM1q()lY(ZukrK(kx$Nr1gT9|QOw3sVCq zk6KvRj*0J02C)tf1`@n(P!4!3tF=0mQqTBng1-bBhIdI}qB4@HE2hj_>bZj25-Pw~ zLyY3mU`AXv#svwlh|!L5JC&=u%kfh7Cfpt7kR>=lE>Z8qgKV=Cw-&qH>RZ{OA}waT zLHjD$Y_(;te3+p#k|DPYn}->uM>1@-3>$|TrbaU0&!P|Oh8fx;8GLVjHq4--IchzM>1%S1fIcRh5-1g38W7hm=d=MQi3SUJ_t;5!P>;) zZ@Y)6Rbe>}gJon$qzkW@T+K?hnt3Af8%`YK_p@K2-gaIM5$mA>yF3veo3b46pBw#$ z_(vsvz<)mEId9?3)~3Ts^;EHp8b4(nqT6&)Wem0Uf1F6!?CRtND1>-R3&k}TYjy)Z zbY-(IQW&07mNNh21LUbzc_YarNAtGOTw(s6{-o9v(&EYZCa6P%9Z6_;))rYK`R0JB%h7YFrqD z-693Rs8)*+7TxjAU=w9Br?jQTmP3%?+0VyH5{a+l2c1BB+@UATyV!_*0fJh`3!hG3~ z*>e(!C4oa?A;3c@kJQFhcPhi#s(@-a4U8Orzb{IH4Q8Fiv$xQazOSS)iVBTD=8WmVMzgK3nwEECNy);o3dI3Jx$OQUg2?n8=0;qvT<- z`iOmlW+s7cw#jD2~UT3EgV^Euxl+o0IXYHt4nS`<|iWn zWcGpP*!vTOeh>|Rx{ps$l;s=aX)SdUPlF*Royok@M*YkK8jBPydonf5o=i2fCsWt# z$y7LdGPTa0Ox3d|Q~&Jga8=*E)zfnIWa^~lGZoXGOzpHMQ$_8`)KhyhmDQe1jkPCJ zZSCnXsi*dIw0e4^dOA`)Jy1OzuAc6#o|da8Q^&17Q_=0o)OLF^RoT?DCq&OqNAd9l{jot?jKYg1^a5BiSp+2z4gz;jEmn} zX`;ya{7S!8nwa$J^NaTRWc@R4lIrsb`}}|+=PsTZ<_q5gYEH(Kq8@@i#sEN%2r>W_QVNFk3O;6QpVh2OjWgKACeXQPPmU*hr zEd22K(fVf=k*d!uEAjbA{WFVH)n}Hi_%r=ULjRSNG04zu&Rw;SX4l_9~EEwLcBeK;T(iZKK}*kk2V$0*{{&L`&08C zyGqm=dP%}8S%hryxm86gyKEC4@noO=qvro^!4g_wwAWb$t)Nd_6J1FJpwt=Mx?78c z#d|n&QcT|}zv!a-9$>x}h%t?`csr%AwYIA8ZniIL{Ouw~_fWJ8)<108cBmD9<}GTs z5337)eU=*4T5_3RF9gVxMU;>1Gw;?~DyI(&JAv@6bt3oHH+o+-vy7dsr*(REO>_w@ zY=n_h0j(u8)gI|uT>R$Kh#CNtGw^MgRw|LF+oMZR&!U5a7SSbK@y%#j3)yAGSHBz; z^Vwxm#G>pP5INxvNz(uLs~96IuH}FHdqNq?TK;=n{C||TK2Ysmdb*;n{2^VL@k;h) zT=aKtUHL(VKU>yP>q@Y?_JtUeESKfA5(u57TXWfE#2c`*u_!?4GQp3?^N-2niGX(l zI0bkU121|YdTZ{(WGj*z_Z`#k5(; z?ByX!8rM+jX0K0UdQ+0uU$)xIw<{E5MWcLqts_5ms-dZXdS#2M=RD+4lXfhw)xv??S!W(1Oun^2&a?RV35< zkQ}f48LAEYM~Zv@oUyY;U{=1knXT#;_gS(hT0owsW2+?El{=OFqWB@Ta|XeFZTkJN z?UWeS`+^!^c*P@s!UOD3dgY@WyOJmJZXkg4gYmDQp8sqm*8_j**_FJVcbt>ESdhGw z$2}pKDcLvrUmml-%sR&<`D5K*bhJZ=P+m&!>Ahl*bY%Cer#2S8G(5lsH|!69OuKrxzgfdKkWUhGs?rnflO>xVh;en z3LV8=+$w(l?n6cAR!tB(h(2fy2C3#R16Jy979u6=ykqxb_Bla~$Kvs);_P=4mX=XL zD27I{I*z2}@ex31k$30r=tlX83`cV5dQd3L!23!TFzA|y-Ew7}&MW*gBS?xrYl15> zEvz^kD{w!9Zx{Ks{FzxQ+V8%Vge*A_>EFH|-uLNOrhL%}$KZ>0>s0^9Mpyc?n7ej+s0 zM=ztJF`&ePzaY=*7U0r11qgy4UX6AUkw^@-wUEQLmmV!FZQJVg(I(;u`@G3Y-<(I# zNXnK8kqQK6KAY~zgab8gSEof~pyYV?Ii_8TbH`tkB2_SleN6m^mWnid#ywkQoUSs; zsmNI=R-fsyRG`7ILHdvmw85;h$oP-{z&)K?GUJ6+Mk&N(T<1TT|G+qOag5c+>WzQe z-Kuw?nS=4cXP>vPPT4c2AEFiYgI8Za6ku%v_)}bUT&yUDZucF*pUGtfzEBb2aHOwf zW1|2tg7M8{M`Lug=!&#Md1MwSykAk~$wK${6?^ZiqH@6EDgwdec4cb859=G|$Yvk0 z*#!z2H&{>sF=z}eBM=7*XSzHhTSc`WFJmVLKfT3liY`FOe%UV=ZK1fm0U@X2e0JiK zzQI?BzF}SotdU~cxnVHF4nu{DD|Lp0X;~=~r|_BV6)h5p^EZx>cQB)1uQ_hSDenWW zp?o@@Vf|*<50*Wkl_>>>2=A3~y9NYK`y8uz5_i%_mg}5^QJmLT=pW7{93;jI>Vo|k zQ(Ni+m<<|`)_xs*HWJ+~P-@v(ux1TxW0C8c#$=y&u?f#< z!IKR$pbqM+>bZUn{Ls+@Txg>1sdMT&V8tFF*Sf*fdyMS(x?LyF;BC}G7=cX;lyz-7 z#1xSR6Vz8tuZUJLS&%V2QGw-QXj&o5IfjZq%yrhGKix~gMMpv(D|pkRKI+MS8r~~> zfOlST%3Q@P>naZobAGGgwi-ByQ(WwWK^?Tw@!mOPy=Bxk4|j|AIWw|8oq9@H*!yG) z2R$UR+_HEwuPAu=RgVxmP4=ntAA!Ljg!JN1IqMLn&6ti8BHGO504h7EKxv6x8n9g# zR4~U&F182erLZKsfHN(QMdAdoDeXy!plC>gT9`f|vOR$iuqUP2UTJ%>z0&q%d!_A( zD|^vrly9TfH0^1#kjb8M?Mkz!t#UEg(>C)msKj;)Mc30#3pLl%E~!42Z;$C}O4IeM zjBVeNjcp%nD38D?#>5bA@+$?D&w3xDs#!j`GoLkffel7zVb=kOjW@n=Xq*7-a0t+( z7sTvo`<6Z7T0v+l4G9jbYqnGNM<>oSYH7?#SkLHwN#dEgMWf2_n6t|PH%az!LQ5=( zfr)S=I@D=~D{OWFs!c~;@@5#A7`m;e+L{K86s`rzG6LVeE%7(d%>p`*MfJb~ydF3d zh{1RiL1(qE^CPf0qzZwHTBSwtIQs#|>zZN?cMAr$~Z8V1CLP;BoM2Kz9A(Rur84j3{^idHA!qy7{dOL1| z>B&BYe$tkTOYcDTn!pSvfhQFjDL@UEMnlI0Okp)Zsf0z)9qhE@%+2VQL zc#?oQ;UDyP58tH$A@|=BWuJ^C(pifAVw`o0r^%*L%Kp?BH6D)K6d~$+_cOwC=gn=z zJV*|2=KYAUQgR1gCkO@kvftNd8@lgS>o&m<3UvL2*?5^ zEp-3HsnurEu*(kI7tY!&2wTNDe1hIJ$0&17aaX)XKvctr3h&rtm?xu1hvre35;??C zxYsEW6fH%n6=*X^4ehMjZac8y`lAw+` ze*1yO@8XhD7?|&V1eD4(1f_6oA}AxP2TWtiMOV}b6-z2O?ZW`I(Q|YTs_x2mFf|rt zRCb9PBnWD~>4RrBz^MD?iK<2MJQxHn{*1unN=Tk`KX1$r?-mqX{L9~riYNY#ae)Qn zA=&LN|1GkQP7~?JgiyN8mR)K~73ZXJOTjMg`3(@2f)=C@CHpEpm~Jl3x1+e#(mk_@ zLXXqpjI?BGs9rxNV&K5? zI3c4*3p9kV1}Sml#q@`lifMkn&!(NU|AsC%{b4LGZB%@l$T8^)aB)FE0zGENy&SA| zK8Yip1B2)*4yWJG7_xtYa7((y+k((bi$4wZ*-eEYjxv+W!!CtL-Q~5(>bqNtxFm*P zFbi#C0VH>)v{k_;VO(t2y;S{~26bmRva*Q!3fZZPoTqJf)7p=>ybwV(N(t<|6+NWZ4R2D zJ{AMN1n*tf&+N`1?1SH;&$1K#t^L}94N7&4J4(8?P92+-4TUw@pQ5EUFgs2QJ;GFf zXr@0`?Ch^C9$D`6=Yh#=@d^%aJwn z{uk%(-2Z%ZcYl5Fk}hb{=N=K#d%S~CFRkg%^*D?{IR_h*x4#}}Qr%`6Npzjo`h3Iw z|2lss?zzK|-L(r8Wd7U5f3dwM8}|PZ-`3Z@>frvbF{2lT9&{+M1wR=E7u9wM@@wte zujbXkM+fWo_dcfbMell5t-jDW^Z#gneUW1PZm|>s-ISvH;OT3NCxU-gDa0_6Puubp z4=;C$pIGi#J4N^Uh2FYu@$qXI;dHt8UHUIzE`RNwRkr}Rn^0R+1z4)l$ zyq>xH*kC=shtsrcko zp-QlH!nlCvYI|OSD=;H^c`^=%Njx7d*(m=Yx_+>F0h(6-AjB>c$8osEM~dVh^>vaL zV^S(Z;HX^NX|A4X5O?M4^3|Nzz*zocbjuAiHQ53M|PYi1=>=u7a3h0-XSaDRJ|jkj8@l*Od*BuZGL+Q$ahu_H zd~&e<6Z!g&QJxDp^tmKS2KCT8{@&bd-pkito$kz6;rIE4HF;0lr+-K^kauW>OJ(R> z?&i)aiyAV~YhQZ$wpCcN`Fml~&qo}a2Gt$je9O`oioM_a1&pVCR`2Ik@4ls4z1*pC zihBLaw*Hi~?kQcd7J&PSFN-937yf>n0pTLi*`=LZvD>mAjwR53N`MglD4|bP8Wl#8X zo)F~aopuGFOQzgTF_|vj%r^cwilKdF5TWxyk`Ecb*!NU$x@+>@PcGSsriJp;-5$j- zCJAX>s~Ylm#9r9?U+i=>(ZuteFuZAsOf&1$3S#Ho#USBl<#@<5_Mmt2?A;5-uTU6R z50iRx|Dl7eyNey|9JN3|WveF4VX;8bGYwz|YQmSeLhIe|h&OkoY6Si!jiV24Q$Sud zR2P1vvQc%hv(!o05vTlkAITLfmz%KkS}*#*Ck!ceQQm1~krmT2^#v`e>QV!IRN-@0 zn9vk-bX;L*QofX|BW*}xCqOwr9xZb zqTLR8$|oStjO)v&-jD4uX7Fo5$(y*+%YeNG28`L+{h;|OLSw-Wg7xpCL~2{&w&0|d5r-@}7k3oQN$b8?-CHZbX zJlziCmW421By}6L6p@f1G9(zn5aAHyA=ZqBr*2~6HZepHhcU?{cqUE|;SrM%5P<|| zu&w+1uf0#zseZ_^dEDfS5$>uwXFt|nd+qhwYp-o)lxi<^jFj-<;gZo~aCu}n@W6qP zfYKc2j3|8_CdEGCn7Lo>a4l^-Vw*@JB0L5C?I77ic;r^_&8p5;{n?HQ;_~6} zftxv>*n^&tT;VzopB>-eV6ei($=m(60QCt#T zm;8Jb;nG9(m3QQZZe=QXDIPSwTN{3lYb$o=?fbgbAD7PJRHYDYo3zNPm%cTm;Q-J^ zl$xBbGj_~e^gqNhqTWa$p;Z=HZe<%AYm}0e4m?iTGi(@e%`NebRf`e1rj~vfp{YAn?v%61BZ9lxg4q0+{Ba~8KwOXIG=)NQH8`OWilU`g)%nZb6R>mj((RhTpgzBzwD2#oVzJjc;? zyGuoh;+EIUAGmqH_0K2xeETD|yy^cruDR`^K~|PVZ6gc7^7g~(6JXc|v~!I5#vZP~ zGl8Cbs>T_~xUkr(!lVAt6N_jnNPpYTce3kbhO(xo(}H1CY(hZaEaI9EbQHGbFy}Ys zcr~cqTG%-ublSHBr9m^yBz7Ar&NZG^ODeXUfLSQt7K#zjVvKBwQx*arcs3YQoZi7> z?PRju2K>%dP8AOmp^?Es4wDOJ9b~ir@uUg#c_1?n*~(k})(`3fSv5aPUKzEbajIk3 zh3nx4*F%4hNZVTFfDT$zi7HjCR*$w8e`m3%eqFa^czF;`z*!O~;W8D(`#SBlNo$`X-E<=PYbX*l=^ zx^D`NaF>Oh21{>w6p(9G&~L`TQD&P{;bCxj*^vdU`&RE)LT23xzZew9{BVcRCo(0g zlUE&@S<>&z=&I$?IrqAUF+&N}K7|(mh>8JVyTg2M=vbZzH-UnTRiEJ1Lm*s+hZh*3 zF^l=dV3*_@YPR@RM1QHLs1%=3n&;s?bN4ay~F^vhx=h5lTNGxX+N&s$A zeOxDXAF4!r+b$q_iY6gU-xekuy4oW>23dBml=8nT7^B)6CG}9pV~RI>;#SGIR91RLBG6WFTV&xUHh8o*zWVuOlIlte8#S{`<4K;&_82KLNwG|x=p5TP2S+2hXf$FuLkJ+HczLzR2fR;cMA8hmL{O@DE|1pS_ENoEXC*FeU|b zuSm3xF|taP)5wik47fbzep{44_S_=>lN%6baDi&@)Z+#kfw)1f%nd{U_t_rkFmwY? z9x+dH6V7vzoV}9e7dmTFft{OPSk+pH@~4r2!6wS{C9U6(=Ow&HlqgAMKQmN=Pv84g{&AxXQW3f-Ik*k z4UKVRySpPIn7n%REbPbz9At@Hn4KgW>#T=h@c4Wtm_e{b`EzmG$xs-Zs{gp~!~R2s zjGT5`!PwL$xkyc{Md|ONN=O0Skge?tmxrBjk**^#r$5ippRBtt`?`-FjN|+p zPfvNhhx6)U2IicWA(|;p-l-JjUgppFUXXZH;9h|(@hf~oj0!2WCBCv_jZMnEJ0_E4 z%rLiPB3GKkfeA#-7)7r!RiD3*W}GE}Rc z{gBl^{GRk9HvU)QRR!|vG$9`SW13%^0+`oYB_voo)j+jKJhP+|R>!@zIuJYQuZI+H zdIEpvUaHMaX3RrA6tP%Y*X#UpoCR#nDfDYV(C$^aRpsC-C-1`PT#OTQFiecj(y?ABmYB8l8_j8<;O}4E?Y{ z2|A*g^zEV1PJVCHuW@gLZyl|lN7OrGI^F~J_r8eb_iKj72P2N8@%n6(;FquFiXpNqZY(?isU4JL-;i-sGZM1crA9FQO zB0%E=ABH^{BKf?lbIj`8W`B>`-&-PA_pGCid3$)oHTrutfU_a)c7S*=WJASUaAhhp zJW*SdICebM9U&mY)5!y-;*=@!-abVxx<2o<8uuZ%db*Aq=t=i}(cYh4_I^uDM5=*y zifxxMRC2ui7^2yj)1Obq@~xosj62;YMa-fEx+VHD_+40DfY~rCwzDQf)4=>_W-$@~ zhp==Zm=i(S`Es$QUR%3@?;Md zDr6kb%Q8+s(Akkuw$j`}K)4OIx1=pma=)V2_9fleHL2wAiKFU!yAI8-k;kk5kH=5j zL53um|ME=JlF7gj;$``?#H`jDyKf5>1fRVV>0nX!Ka z{pCY=IJEcX_0oWn0;I4$#s>!u(t{@gMVA zQGdG{d5->M`m?3N|ExYmpOxy4!VL_`0g;A)f9}IzsRvczEUwa4R7Y{{gGwwnGe^W3EBoE z+{hcE~~z@ z9P|1gZK?6wJgQtS0kF&+!2_KkO1R6HIxz)I;?2M1Z|>&@T8N-L`qzH*{%1O=n&3YP z7LkwZ*fL&qTiUP-_^7_R3zOi!DJgL=M1*gB76)AYa{knI;3A!XZ2{E`RK)iNTa(nv zlIv%#H$N486Kl_C(eW=!!78^t8(Da?1Xq(-A>qJ55Q`-fchtx)zOn{=xMq&GHqJIz zTp(Z~-e}0$k@Cf33s~+=@gr=<0HZ-@3>vC5sl-V%3&+z*fUISBG9;BTRHU+X7!p3! z7QVNFfLxyrnQX|R=Yhg)n0mMvz*X!fUf-b_G!3gSgIN9r*NA+2(;@^=z*lmQ|A(#} zcEY1gu%CG!z_4~I%{$2inGZn}g#eNrBc-Eg8ePFA-cTnBC(c%4|Bal}BdrSJc(7Z? zbIuZEvQ`9cQtpdy|L`v@nr9Wxz#G=oSr!dSq5Yl5hYIVcNtNWw1665btluiDjcHN> zDWGLe*d(B~XGx2$3zfXrnz^qEJ7WY^`LrtYYO#t)ZKJX4cov!$PFUKMK0m@BN3QI) zq|l$`2tj0F6B*%2ZD^8N*KMY(VI#4uy0_Ef+P~_aeC|e5?WE?#;L44j^EbMFK|WL= zzPguOh`LdGVExs!{_3p1T50|9U7ATUo0%YBtKQ8iv}|K0O&bPdHY6uVK_&F%QkM_G zE^vCJZh=XSk(R}@Qj!RQ&!Hw1wnrsD=`erPkaY{;1~M@~(WxqS2%jgbm_tk{6~E3B z>Q_8Q#q~@lW#+B&k!t#%shXc9^RRz$tlBla-&XCeOVRw9XkLzEf>7%$iWZYyDJHn$ z=H^VLvtHVTu6sA~!uJKrdEy3YdY%vpSNOySzZz<5u_~@o=lW+=P;vMPfMAF-D|_S zuNcm00_4=#V#PJq{BUPN)Z>BF0%AN=pYQ;lDcYRxw|UgsyrpRKh;MV=x5@048t4Ia ztlz*%Yv5GTz-_*PV>F;R->>Op4{+S;aMD+5Fr_t@EFweEeKD_OQd;T76-v8BdfH=f z5e#Yuu$GJzK#}1%mlaQ|C#}^}GQ~F-UC1tX(|;_+wKkb?#B~O4t4*Z(tP~uO6-&Ke z>pcv-2oB073$yiZt59|~bk`e%_cPJmQS0uOxKOT7!FKQz*wZ61G#tx6Kw>jT%`wgJ zL*9^ee%uI=i|DC6-EHSz4W<>)hr10ap{iHzo@HKxD|DF3c}>kzVkC(6ptaDJ2@51= zy{_X-gM*qp0~aKOTm?o1th9* zg!UR80LbFo(Vr{Uff_%N)uvhp_H}BHu|3(SRNcP6Tbuf?Z#wju-~Z^}{6_dP*Mo2T zf?Ko!Gk6%W!<9VlWn3}OS#3W8h+wniRv!8KIKd-?)^#qW45beig7y2pr1@lgN-1w(IDu*Z6!ITtct?UOKDi@@Wz7F}@{<)he*Ne!YqKz9a? zbKKW*x$D`r%Qr|g)#RJEtuMZ^E#%&4!PN3+^MajgHyAFDK!+9$w3(TYq6R{(=*rrz zv;AlyA`f(jvg(PcbK$}6@YLL)YpF7n5im}QQAQN$;&2ap%{EZcssVwiW3HN{y$nE| z=3>CAmRBU6qRC{Zwq@gvoi2#8_O$@17ajSlv*b9v)j^)z2hJ7D%l$4Mh0_1F{7Oh` zXZ72=$sxA+J7^;fs0?b1lZzl77;x`@RLsCFCLtI!L9iGe{j1eDk%e}w!@%=;GYi?o#1HX8D}L44N)ij6BItrg8HIMsf}BEJ+sW=!XAK# zo?`Zt)Qv&U2;He>m#UH~?gAEU1xhnMRpxJ?~x#lAeGwo62Z}>DfFIyO|B8)M9xYU^g&snm&LpjAG`}!Gs z$#g-PenpK6;MU|ng4QXr%bFg}x`VS>z$sZKJTj#+UGf%mn#*{QiIQ{674(~QM!*%r zVdQ!<#$Gva^4ryQcwuPl9(6`!h7$G*UMjS9k7gu369lNVGBxSl**pa6RvIV@zfM?#Nd0kozLq%)^IhzZz zsWru$wCmhmBO<8h-$p|0xQa-8qbu!EJ&%JN)A`r%Nr~*4SSLan(jAhkU9yfc;G~}aF@Y6{ z&Y2)Qw|6!ImqH_;nI1R-iDfX{2*N0?Y^v7C2F}cE&xWB;op9>^fWx{U1p5Z<4aKj2 z9R_VOgu7P+wYItOqF;$^>r$n)37Q0sxV&-A1SG&OsGIPvPMrf3ted(xbkm^iZtSwj z_EIr7kpL_qn>Y?~wgvOA&YHUwI6W~{Ibwy3TZQx5IYS}bR?j~0W8~?aSfvILun`|*~b0djSv(pPIMp& zf;LjNbnMA3dXm4b$t#`{(UeYT=W=6qQTksP0sA{(C%AHUXq4BYE@*2lWW^+HblOh~ zE_x9s4gpEh>tv2h%f6Ydr+o2I_-!LlRXqhfKa-j>>)U6a- z9wAXPwnYNAcHV1}hfFa_JkrQE{wQfpwCEaehwb8I_B}z7qn_ki)|RT!gxT;0d%l^z z4>-jH;l7NZJ|h7`mKiywSTsTd`%Jib^5-)Ebh<0y1O@=F1pvH($q=N*KOr|DbrMot z4N2R!u7=drkecL-h*@^U^Y>r@_j;s%Suz@;dJrSHQQhcQ9UmIHqz-)*6WcVn7|m1J z{uyBepf;sQ7dctlo$!0*L z)Q!-U^R;_8X6g`wOr)KZ7-o^HbF-$hQ8<`xJ7tkH2r5PW8cxQMTM#a61{wf%Y;@9a zY)q0HL*-%@I!UER?>e*5L?_Tj0y9ukky6{>$(0;-i;4_xgsy2!2q(Ii2L0kc zwyjzMR_8)HYgqd-NF-RcPGiN3wI1t+-X|UeKLt2#3B#>8TI5mGPuFXG3^W z^nNP~kV;~CC}CNQ3^eZz=Wf}@>yn3RYgV*;GQSmdzE>H-L8!+7{ofRn^W&H2!Hwy|1iI`3@rr1Xs9n=*BE;^96HESXU_4VM_9T~GTHy6 z7qiJjXui8#*hXY^W)p|A4f{w2zp>cfWa8ZRrn|?;)y0pR6h$~- zfZ4$FX10Mc5_t&nZtW^SvU_=CfFbQ!6ArT(*~m#H!FAOP4jo0OB_up7XH$}In9iH8 zmPjTpJpWR#qqB}7po*v(qCRgjjuzu!2oe%xoXKPlN&Z8BZlkQV7u9VpYuQHG2wF%( zMk@~I()ipbOz#)E7hoFQmI@NQDT2dKd^qOgJTl_lERDX3B1&A6$m!rgjKK3(r zz@Zr4u%ZKd$Ll6v(2?C?vm;*#I;A`Z)R~c@Kv4+f$HGAWQ`y9?$TOGuFK3G{4_?Ly zM|Kq3Sp39GLiA3TXM7#uWb-)PuLrdkscDXg6GZrS96{mRX&04>Q8GkLW|)m1%fg?e zfSwk?3LZ?9I52=}u9Cnj5^u>};)vazt2rS<__06-PD%VHf&rYe`go?+u&7CdcF=Tm z5Fo2DtIcc3X;iEzBC_0yVxXFRw`JI14_}41|!HC6az`}1hRl6;~OZJ zKsankvo7jA>N8D@c;k;N-k3IqAX@?*Sly)!a2OGxXe6)@>AC_(9 zt~#dSA>!62$o$CH5f%c6RoU7BJ5`*Y-E|HIxS-$R!_TMC6WKa!!rSHtdaw+nr@W?H zyOBhYC$cqIin{MJbSpv9K)!cb#A_&!N4A#X2gp|vV(7Wb@nx}cEv^(uJE5;b(3SbP`&x03H8Mnop1A9!T{xZXuc5Ysv$(7 zSLG99fb^$OG!&l0UNl~MebaxN`>xH5g1V5QIq+{3erzyW0(4d1cLXQ$uL@;4INT;6V-x*@eBd9;90yF3`elEmp zA`zl>0&E&r7GJ3-u$VQf{{2!P&W1!qnpAB+^p<)iO`OfrTJaW|pFuP6<~p7k_d-)| z)p}De&nh`CIygDn3fe%YZzWqK@NCbjupiTs{g@F`-bn8bF@us320_`#`g(VmEQHP? z>F@E%7cA8o^VQJHVy7d1(sn5Y;Vz)C<)s@99$FJff*^6TG^2_YPO=bZB;s9!-IX$LZ&pXBvoe1*QAj9+XH zm~t(JOORoIZ+^yV6>any&12WhJPE@&*uJ#W*ea~qo1a~=daw0j> z075W_$(o>tDm_g9dzgG~bC~!Povn+(*z$jn$~P5=mEUhkS&+*qkCN&9!FX0*nEpy0 z@9m-$x-2gdsFPMiB5)QyXRWl!weT^%(QrdSO|t;pp)vVNKobwsuB`~ZjqwfRKNc6;W7~`NM3DNm&-7A$Kt|$9wmi3X+TnC(RAsT=_7A{LVRKE1wB;!SIOm z@Z*<@J%0*v3lc_nXnj@kAA*t^dtcQJX7-9iSr>a|@*h=fGgKnXxFx_0_0VSQr6cM@ zYZd`$hdbPhc;NFXS4`~bqq4vn;t}&PBf}mRMF9}!@I<+_bnRjRuk6og1-jUGv7%~{PD$nMQ@2MpOH#*^h~1fZ*EkPo6= zfQ1(I#qiuqLM@yp-N00%sa52PLgDVn1{QPtB?YS{Juz-iT`**olusBV$NY}~RNjZ`dx5odwsLAe6AU4$LX*W#71v{7=~6F$TPG~Uo|9} z7nvAgp;3J}>=Ju|++{`7G$zB9j6U$FlVXtO3=Krn036JqL!*YHLST;+APYYpWCVyp zy~As?8IuwCj>1q=AFLv|5edV>IXRQn;px`3fN@hkt>bo)tr)>08eyxvCh#EvPG0#r z04|wh0w@)@Bxn=J;-^j;6;`TX`mI3281EYo%Ldp!USgfd=*!Pocsv z08EIx@XTb1vAO&hJxB;@cAbcM2+Bso4D$Jpg`Q0H>o!kjF<3MC3ay*Ghw_p3q67{N z@&#VYNb*dsEn76Td^2~h<~K3)oauo8Y{4-en|)hPs@_{VP{d|Le*Pek+-=wZ0G*Hn zLQa~ftTKBr=r)FnzClYhG~SAk1Y9>Uf$B;gIl<1-^-Eb;rabWQT(s*urR5bnWnV6U z8PwcI52IP6Ew&ye;R{em>{duL35sk=*wm2e>sN(rO_s>EKtRLIlVU+dR%H2-((w)_ zr5h%eR>Wo%2c?Fnfn%I{#TqsJ{Ma;n|1gFsXqwKS4n9Dl@{XbCRdWIj3DwNseLCF2 z?pnnC^@7#DH}sU>=IUL6dI~b32p2jAMlAp+2@YEY_44*Yi<&}Y7)=qg(XVS@Tn2(=S{l>DZbXsRV^Ww5$@y z!WX87giM{|m9;TTPG<=;>7|xAxotTe6;mvNrI>JD@y3UzSnMIH?sX=SqPWy7XQ6F2 zeCz08(WHc;xzN-MGToJueLyK*)BISMT*a7JQo|fA$SA;wLk$b!NkkWv(yd76rW-5I zs#Dy!`|XJ*c4`=iA&MIn9Oclp&*chGc^8EbLN{~)yJ+4}!8R+GLx44>ku$KM7?rAP zgD4e#@TfqW8k&960TZ)BhzU_hy91nZ@E*~y4V4HjH$Ew<_JSM_YDX{Fa1!b39wPK* z%hX8heUFV497N3Bm!t)& zg8O3yR#I`s2=uqdScyqA>h@R(A?%)&RHI2~+FLj*_N-E7C72Hel-Z18CE%;aN@(6# zNyV`ea3)q_RGtL*i2-BVkfc)%;?jZS^DVhnjMyv%??fmH$DwoooUs9eS6Bn5-K7wD)N}P zm1m=pJ?iMpn4-J_3<(E>CE@SUnLI!%(pe&YTw+^fUh-7d6vB|2S-phmT$U^uCOpwRV1*g6H2;K&jpn^Jwznd(?f(?sRPal#Tey; zGTO3b(T46=#&}F58JQdBeNvY)f@CDKS&In46&@rD?XaOZ5EdXmb0P~g<8Iqi{u*>~ zpXWH#UI5Y9+Ms6TNzv(I6vf_HLFc7owg{L${VQa&<@cj7X8`Ekv2p5)HmcZT5~_W{ zDlYEk61$Kx7}vrpXP;y!KhrK5umI0wsPkJvcle&nZ-v=M zc^ioNt@up^aZMB{FeF1!i-7WI2VC$Ho2NmqBt5){vPHoP!+S5pE8NT&saU5_55Gea zGfkWp4nQtod1{8Z#5Ltz1sf)b9miQJiOVF-W``$frzMI2>>DJlgMi}k*n-@|XrrNN zQ0~?GDv8SC>)_l8AF74LenzuJ4hc3p`kfS+i<2+A9uZRDzwyS$V*;& z9Hb#3@4{&aUCq-F1NCgtzLjXmv^h7j1dn7Fa4k| zQaK0WSH5VE5)!FF&j^H>m=JT@s>bg`zmN(pV|~c&&rtLMg*70or@&(@*4!j&fJB9( zVGD*%frAA*1x^f9Rk_B@*@8->;A}yT;zIv(g$gIY!aZH{t?8LWmq7)u5mk>9%VxqZ zK(f-lNmdRM$ryweNU|CaQdU=!tQ?Slwwy62cqoPWZ<5t8UllJx)-pwEJkz~JaC!!e z{%ZRVv?O!F5WpiwPC>>ABte2g2#PowCx&IaA`%BYFgfrLYmondO76VaPMA?JNsczy zXtM1mHlE(EwEtY`sMzhky~j0Ab8Ie!+FWA!@kxA<=oXQ|I4j+{tf&ZX$9W}9A}n~G zYjOZbVF;0_XHu}`yl~D_hEJXc$XvVma)MZV1_k6RRypV*RSVi|!7(zso9%INU5p|* z6_FP96JNcs>xhuY>4!u!1D2(82qT{GBH=!zvz40EX0gSRT2tl(vso6~leb2#I_Bj} zPdFC1^sVCBV(``gJV8TPu@8>%c}UIe13hV~Y=_1>QpDcP5j3l7(AmU@t_%Lz`?uH*%Kawmw^oP6 zfgOFzJ2 z1PThcTvvr;)Ed0vk2a+o*!C}y!ZZ;DXRTsJxlBYfjA$OPO;#lI#1p#J@uX5vdjhpX zFS7e9i26ea6_F)DzJV`*z?LeQ6V#UfH&Y(XC=)q?hzT9 zA7!NZflA+mHnBjntS2!%`IISxF$g_rN3yD)eiKVOlEscC?m|aTI2x>cK~MJEZ(=Rc z{NO4j%?~Ld&94yDAjGd;GoYR3=OOEBeo&>?`~YjvjtL~Sy}eAm6{xbT`Qb3|Qrj6@ zwzQW}rD=X{_>OIgDh*vwrNfe=N-!sr*~ryR7Zb)};XaL3R6SGNO1?NY2n-*6EcB-O zf>k|hv!v>+(5C#D>IbroP1ZnP0<=s>{FD@2&aDOri2{ylY;O9h9!s>R>J3s>q3VgU zN~#`S2kJad$}&|i_Nrb9cf~lJsz<41svg`y=7Onu7fdu|Rgd9&KMUVb^$J$jSM}s) zu~pS48gT3VEcT*DG%U!1`uXOqSV*)`_57Tz;5{Mfc%kaWIn2gXy|VYj`TN}^+NSEE z`IuIh!DTdsEEM-aCr;Iq8dbRc`_7Zdsd_Lfr|N-KtLhH+%U#h^^reGFQ;_7#$uRYh9rF z!ScZ<)oi2dF<^iwT7q}uu7=Ped?d+_N6O<6!GKRp)%Q(32x6XcFn`Nk(oebpxpUoR z7$eF<9Ubq6m%$}bzCxr#8{yX1^GIf*YPSBeAoo%(XWQ#6o*MVk(!5_vf*0+U&)Zcl`@6mD_>{XgEB|`Q zgd}j2OLF?lFh4UD7(onp1-4x&rb;6Y2y0-?B9 zG^OV*pG8bfI%eEi&HlV(qMPVA1>#BZ?F~OO+`$6H@swxv-bF0vR*l{d&bKlJt(=V7 zXg;*Ze^r71x~av00W>G}9q%^tks0nSK) z4>!U?7THcJ3GGGlF+SA&x*wPm(V3OKDO0 z13tFIS87I1EYLhZo+B4dy#xp`l!GI}0{N2DnhYfE%1YH7kr-DR1+B`sUlkj6)k z7#ecmH}l|ykWJGih>#1>#z19v!9`0ybKsuwcqP`BSJ-OWAWSn5OO`Dsz`>2Y3yP4*sGVy}UU}w?-1I zKI6M~2?wJFbrwVx3t}v$?=y;n?$Q+A?b4uLrav#4;Jp%7@l*sGAJW9Q-`DE*%U3Vu zOpHZ8xH(&UD-5n6Mv>69%xoWUKe!9S#7pIFW~Ly6(x4(gs4$B_Y8H_ZEEM(`O)(Hd zcNS?Nk@eVrt#n9n@{TmB&W$Kj*S+|!t0kER=R`&75hAB1Am}oWKPU^e$3=^4c6tx6 zKUqgJ`RnHo$o}UDlz!dJ9bOV&;m%&$pnypoD&b~VR{ph2nzbdCV&cUI=%^5PLiH{h zFQZxvzCb?W5HA_TY_hG~5&VjBh?r7cdnVfV&m{9mO$F}SrBXC$>qBs@T;2Dk9!f1` zX2fy*SHC_>%fMKr`JrM$+$9=|YzoVZq5oPtN#5xtOHGoc){`tXos}VX{ppBlw5
p)Gg6jjZj1KwrT2WE)_8ggeEYDz9F26#mg)hyuWQMk zl^sz9j;OwC^9&j}PaZ_@S>3bY^17Dtxv2X<*sHtf>XNnJ)xCFxx+f_EAgAJBUBmA!p+sB)f2Z;A+7tVFu+E3m zQz6*wH>BfOb@GvD^|38b=gtUPx}m#<(da}PXd;i1AKJWuwvWa4S6|_F>5HbaBXra% zO(7ZY4|mt=dF4PCkEec)=_jX}vWu=g!QWv-FU{VhHrEKv*$994?c1jzuTj~d1N-PY zr5tCLjDSZDlC?secgN|DtI3L|q(|hmC{6Bz+fk3dYt(T|KU^bI+2L%MW*7F6!GkYk zVdl;P)kw38igqr_S_dc&)`|uxye1o)dIWYu@54M^XSLKHpsBG+c9HsGNW7IIDQJ`< zWDTD~bSW?xbH&Dj7Q$3;Makg>l{N^tsDWz32dvgb)QVJ#hIXBBf*WZ{0(xlC7PIl3kn)ILr3n+$bh7j>_*7G9~YGhI>JS@2C`J3iAmszl4yUh;N<|u}yh1sP;x&War zZAV&VRk|m55U`UBgO4lGH^rCyr9+$5IX^Pc0BzfVwlhJt5}399z=UA55!v;Ov^Iqv zY;CCNsjB;7hk{Yaz*3~;981NZrlvE@M)hm-B@_KAMiGQZ^raXwO>m?t$S2o5nvU|4 z36TYb)sE)0kaJ!Rsw}F9)#2=jzM%=I4hoKlu8r_2DQ#_OgHTc=ZSdX@i#PJ8ZfYn8 zWPWh@EFi!7K_)Q}e<54qlol1kCTA2-pBvFv0u&)#I`_jXbgYG%=X!e{Q zN*GBpngyX>c=$vouRG38$}?=HxJ#l?)E9$8oSb;$g8|cef_8ZokjPdVQlU(Owz-4! z%>AcX#qNufXPprp3UR-L(sxoeeYES(0F>f>%7Wp{LemMw=tc!ON4mBydQ~?nuC0p) zpvd1jA5u(Y$gTFp|K_w#bShDHHx&xlOwZOR?#jHU+-R2C z;FWpScj)>SZu|Y9*0W>a`dOmRLv>Q;kD$&3&U|v}yjSB<=uNRloo8Gbv&U=!L|L70 zp)WRtzcctis)PFC3Myhr%Q%SG$&PTMv!pa)Jw_rFU0Dk~%q~$H?dH?-D2-*#v1@>j zEK?eF9{4*_8mV0?CQ5R~PG27wbKBkz0=K zYSmX1GX@XYxq`+xIm0N}LgPP_&lMdeh!ql9uxVutUg^}&NvVqpd{jGl)1vpGV2ehI?8B**k3D@T3uh@Nm`^ zr;ALX7=|U!&p#r5)y_r^bVuQ{lJjXcN>g(DI{TFOA&*B*InZlUO2`s%0M#X;rrKR& za=lPTC}U#Xbe(<3@U}`zc~NQdXk`(fOi@WrQAiw zr&dL^P>uQug}`PKtY@Y|O-LZCw&sQkQYauTY6Ah!1%f`jGSQPV!9mBsbq?C4Kak90 z&Tu41)Fc03HE0oqIL5EY52)1?fWy!(^Qwg`vAz=Bn^>>qN=%azr$fdU9eJg&iDsZv zbpl>$J>e{o=6~U0QHh2eDny;|!hMy`3JQJBg0u{M%k(E*FlQOL%=HTe$;7Amr(oi& zm12z)&IL4znrRd)SzR7%CTj2#S+Pu6jB}2y$YFy@9`3~9Vwn*D%dce>GV7Z$Ralb9 zGVM1~9#0I~3uy0{^Tjh&OTb>0K7~|x4bB(wTgXF%fdVKR>8}I*mfj~(Tc%QEGDOj* zs(r%KfnH%c<~^6ID^|pb?~#LATe=)PNG^A$xRHld*tuMRMxo^aDQ!MT6!Itm`dnK` zG=4fsb8{t%4pgNoWUisY%Yz?*H*~jMUM=*W_;|OH-^{(w`NI~ciaKyO3#KkLClaUJ zd4p7kAq1Xz*?@zon;kctZ;*5gd~*|*IRKqqsdu{6P%jRmU_prz-Td^5a{bzFMaLB@ zC$e}S)1vlq6v;&>q=v3;0ZB3V%0dSyMl_9;{E?pvojcV(5~vyoVg<{)+t678X_n}$ z&{p6y3W4ANUkny>Vlv8=IHf`^4I_Jq8aU*SMMsrJDkq^4EYz&iWNha$j=B-Ov=2bk zRCLj%z*rEmT@ULhh6!!R*dD-DAY7SxQ-I=e#fyU(s#$=PFGk!rM1MWZ_pv68UD`4v zQusm`7D`sc{qzf2uyAMcK#Xo+S>GXniWPLohXm@t*(ZU<@ot>o4CBuqws4F3)P^Hu zM59cwlVXm<&Dq@8<($q9FVMxA+_d}Ww%9c93Me4rGQvTtd4~&~i?8mI#6HSzzIiU6 zznL3SxN(OQF2(HEZT7WOV6$&Pu+Di4eNeFoXP$ z!dG(y<&Q%029ZXgp<4N|zf;YIYIe1Ar>P52ta+zIR=Q#;uZm`($#^o0AgHJ7TqNb# z)Z82$`;T23#hB%kC67clyknJJuQPo-c{=ew36R>o57c^f7v+}|pjIlrzG#cU6xu<4 z7O$e-EAHV~?Nz$^EAn!#R%_kruQsjz>dC9Wx_I?hn^%AJBdfo9+Ul>Kwfd{)t^VrL z)n9!SJzzCVaZ$;t@07!AwR)dA&$~Z5&%681^A6d)YJXoi&$}<3=N-4It=i^S&hrkp z#;WxmJkPsF&hzf|ib`2!2^=}kyPrSLyI(rbJMzA)+TX99=iNKb^X}I3ynD}i-raVd zcekJC-TTh-?gQs}_uJ=r_q*qLhtGOdoZWq%cOO5`JN)CNHe=W`veUR@WIR-Y)-ooE zgKyu_4UmS$de7WIDV^dKM~7*<9Lkb;NQoeMLm0+hY*cw*8FPl!Zu&_!37tH_GXqnv zAS&rmu`V$(1O{z_0EZq)Tb@8F;k6$qx%QQ!uik2m1I+>Q=e!QbJkdO4ig)HWSD0W>8)&n=N&6 zr94y)_ktjvNHzo-ti|H#4`s9Hp;kcnbtNDt(spbT9y$Oo20*|=qp;0dhC-I;^!~6z zTY1Q6{3M~G&ARHh_YsR`5>Kixmn@eS$JOj6G!XUbTJjw|Ycy0xXc49`U}H&dz^@`} zQ0ibFU0y81wqcj&IBpQSzFkoNQ;KaDcF`2`X8kVqwvIBo>T z9ABO!U?9Kao-qAik&#jQ-_b+(L&l;T?Ioy99|#wd9}v2t^sl%-M!n1Z$Lip1#v$|I z3iQsTpzQR^BGq1>f)(^ypJ=03DIFNk9O;4bfl1KTcn|x@B{oMZl@&z|lujS;FA(!aAW=0_GjKnwGd{GvudyI_qI zTT42(HMZty^<^XhV3*2!(p`n;?#%~X-cVVz zfe-8Nxh?=!^2uOUt-&*N1_s9`R*6D*X*eCNBTjr%|KMh$3`kxrPdhz&8F~lV=t<9= zg}>9O_epMWY@WUZ?;vF5QHU=)N#;jk23a2y-Ks{xb_^^`Amfe@{K!_I&qmiiF6b}r zQ7Uc>(U{oU-*~cT0YVyyTd7C|LkE{cj8=l=$w9=zu^KQqS67tfMThar50v=j`_=IK z9lsP40P6JSXlc`JHSN|xkiI?=d;B3Qd|oa{Tgh`TgauNt6S^6YJ|gK6LifdDbtq73 z5Qz=`Y!Vj)aD4}2u|WBs>@_S(*wS}v3a&_QF>#9mZ5#Yor*2T17wI9en2hl~eS?OV z{)+wOdxE62h*rFRwhxuQQFQPN5g-U#&~1>uozii78@}BzeKYZweEb4Ou^19Ol04UP zD~4N?WJPN>NPkm{grtqyXNbtxnZ75ACL~vg z)R1`ei;=yHjPR57dPwYX%10>#+CAq10$RbkqzKVs-xO`sJgz)G3`xMA9@PXNlhz{`c<^54 z$uR~rOH_@2kp75MhS!z!w`_X(!c5_n@&KU4q_;M;^vTfzp~$|s(-T4) zhkZ;xMD6_fzDBfV^7Ts0*7WB@hlNU`)4=-SbVOpo=aOFy?a^x8NcB<;)r6h(^e6WeQ1w>5FvMGw znbQDE?S!D}Q37#9RWw-=g7IDzme*Fk9Y*l7L{UUh)jzJurh-Jl9M=Xf+!(s&y zi$&W`OcjT@(jy`PB*l!hUmJz4S!>R~{#XHU6}o`b#0()U6ZE=z;n&3TlmOPxn42TI zRO^zo$j}+YnZu&+6D}e-M8U#nf^y(Uj^!}ykmpRN+2rE#N>xP+MHBKSQUxSt$y=i+ zoQv755OVmlWa&=Lbs7;XC?6*=ox~7!!VWChab>r+^5n3YWEq4GpavqslsnglHkS+RrI3t4(A zV9#XFE#EMXDmqC&P?fa#l-I!D8A${8%Aledau6tJn9g)`EJ&Vbyg6U^2Ob3d(^XE9 z&yU(;V?|O~-YG)OpX1ej@s0Fd)`70}6onLu7>}2${kKLY@wL=~+2_HUw1Tpb)hBhj zBr2W2Ll3WZxZlZD30#*vpD(sEd5vjKZi$bvzU?E~ zF;UH1iT4dS|2hY38e))IIBKaIIQuc0mYd=exGA02*y94h<$~VnS$SxTR$baeY(m{gme##l`2wLN6**7ct*ZMQUJ6Nf z2-CNOouIFv24y)EI5`9_kQ|ELxsFICQqY$}@B`!!TB_uboes9|CWokLa>yJULRRFY z5G!Pw?@kb@c?3~3D2Uu_=bNU}_g2I-4CPugyG3>;AXpGA4nutMT4$x)@-0W&FinSy z&7Clw%)l>{OcR=3`K91gVCrHs!1BD(XMC`_D`HWQLsK zddjGJQshJTg>K`1!9Ay5e{6pK4BCM-_waIqp0$?;?!H*-?e@w>qv`y!0m&k$`Z>H^ zy7E>E758Fstq7mlZhKz4YPWUlo+rN@$*U0O_ngL!L1H~dBIcvi02Vlfx`qaa6k^XB zmLt{V$&JQZhQ?c}Fl%hCGGI6nbn`r?zL(YdN3 zu8s-?@D&i})2PQTjk+y_tvug)3B+cvXxOw&UHR^-$;PIv-Pf)=$gMP!>6bKZZJoJY?{CW1@7vc|PkqrG(1+ZSO9dJY z0p~~Luj7&OnP#y8LmBmG#rl9jIQ}krM=j!&qLvNuweAwA9cIBCF zF{%PpPuHEX#M0>+X#nR^aSk0%bcgdlBfm+&v*G-!cKm-h|GaJsqpsvp_-_bJklxqe z2GRBDo%Y?)Z=YtrSBnYy%c9%6YgxGfC|X=;-4^t%J5<2cDukVjhve%>(#Mwny9q(i{ z>a0OfUO@X_GBm8~xVR;RFbX2!6)emZB^M3H)mj}g7|zq(`8O=xKuxl7F26bAUc8$0 zg^ah~U|z_1sh_#~c$z*g34cVFhpLKEE-UIUL?Z*W#nFwJMKXOB#RT&}-bKo9b3q?} z4naUTG;#%YRicPatStTPa>=J%)?E61fY33m5$PCAk}b@@HHAnSp`zN;Eq3{~j!|RS z9lad;VANjlL~Bd@gPWaULI#Rr?M983S=M57%)7=%D5k7Q&dI7+puDzpFUDr0*ZBb5 zEn!WDwxO4Ea#1UzWvr4VT~S0GSBZ6+e6Hg&<-gIM@&_FBcLjegzQ*zzDV@$HOQoe1+1ozGwJ+Ic1_jibG zSFIUGufP=uxbzB{a)cw|R4YWgZwcpjA-6)k~6w4f6mk}TLI^iej(m6$Bd<_X=~2gV-*hJdbuAmZ4@x_z8I zdOIKqtPQ)&ZK78$b-KFfuFWbZy6ZSJ^9mH2f;f#>&_Y0`?A;Q^x+w~!m~i=-T~t-c z*I%Dk_j1^FYjD@=?3O^Tw#w>zy4-e8sMcc{fuEi(x3vYAv#1HDS`4l-B&8rJ3x=Yp zIgYb**Xcae*sh_7#o0VDMYLo#maRLyK$*wcAw)HnjlY8VV3f3~96e1oz0})c5H*z|Qr(N){N~^}@e7IZ6zjzjI9w>K}#R%USo0=nBGy$`t zw|Cba%GT}gaMijqF|&1$`HCW{NzGv*1-0gE=dY2iMb%fI7WhytZuFI|xU&?!kzR7Je_-j;9EE5!Hu!PV$98@0vkOh6G zm7C@WtauqrXfgoU@G`(lP`9m~ptdahME{yz{aA5s%nMzp*R5o4HEVPoR55V{x@onT z$w%eaBq?Vm9b!fK42_dj0XM*#426Emiy(r3cG)L!s^CqmNn{lE%f9aTPOgQ}E$ibi z;i|i;Q5_y*W>>n`=cNae4P!DRZbDOURyOD1WbxCf2#cc#JO-PqT1F#gLrixtjZF)2 zHYhjN=-v$J=|g@1oMszA!ylPYQM*vSCAUhOKUy$zdR)UO*4A;1A+67mWS3k#p`0N;|F)Pg?3Sy+;5CpcyWuy{AfJ|NHxt? z%io4VmM%se8gd)DVKN_D>;_8R^V44lyOy;RFF>T_63QD`kt#_V$$Kr3R#rMMAa~mY zWy)0$Uq$*WI?QHopik|o(;`|YNJF2H5RX{e19w>F-6( zb*Kk4fIs#6{OCi3R1Chz|NOG0Pu}*a0M${<1-R%;u**%O#ZHuNkgsPws%yB!dfj}Y zTP5%qCAn(KyX606ru9bo(?mf`fI~v&9QVH`YYNaY?wqe%wbM5mYRJSp##e(|WcGn? zYr{`P)s}+9aXsDVaEVJ7mViNonPJrtH~8j^<0SdT#x}rdq(=NUr;5rk0K#7%8em4e zlyPn1htW6ZiFGwKKf5vc7-;gt0oX*{4D$QF&HcQ5p7o#ipAPN!H}z>zI_bv>mvfRl z1D~#Um@$U|{eEFo#CP@{9ciLS|EOJ*YJ71|7Lku>cdi=4|QL%7m zV@Bqx04A2O}hvnGoQtR<-i_6?~Z&c`!6pKT`AUCQ7FsX=%7bF~CJMKCh_7?hQQQF0@! zB)+cjp=z02GpSEp}&CNnV<9oRaCkwd0rf3)& z&m{M15ZX$VngY!WLZX-Y5JG731oKfq2zr)6_~~dMuHuupJ%0f5cAj__R}o`5N0TtC zBUQ~1U)awYjH`Hqd>QG_n?v9N<0=m8Mvz$34V&N#Tb>7PwWSY8KN*Otm|PKujQUY< zXhRnc|1P8j#>K%c?G#u-^-YY)IU&r@uGxiJ3=bqp@X2*W58Aq|1&Z6zKPmOWa1?}y zIXDdZoP-F2*Ef5nZxFe*@>mKq5-S|7Ms!~X<3amky+?l{QP6wzr@YDAyD9$}n@8Ck zDqQ1^CNwsPl?~DRc(Ox1$hff0xj1jnun$cMrDilP;tsLd5&&8VY~c^gaUZ1b!4)am z%)jY^$P|J?%WjK$d=%k2@MM#oyr<&sB^A?XfIBwYFNt*6I8NVP#m;Wz+q5UwKx4>x z%fzMsJL*WAg-5nL+M4+n14Se^rEGA+x(;Z!(mw-ZEj)#2it!|HC{sRP)QZ%wzhrfh zoz7^kc)}06#4xa2$ub56$&Mj%)rqr3JBI4y`eISG&`R1mOD8G8qW?S!w3n*fJA8lC z8A`HL1&3Ljqszd^hH--6ZG_O%FS3W^!Bm>I>6}d0Q4ipD1^yuqJiW{GRSa1+EPak6 zahfV*Iyso-il;Y1BL$W;bpY$tbeAz_Y5M08oT1aE#TuNVt-$Oy(4y$e$_#jJBgll-KuSmhJJtf4fHzgPC2|e zy4;Q@;An^TelvDVVV?cNfHBbECDDVSYyBa}G5s8r$!g(*2^=BFzXgx`OFGO?@nwM{ zc@!z)gJRnJbG!nVMB4JEjBc53^9lHkcru#g>qE4oocJPbiL1>j8;f3|X{Oh{B8S!N zo0+0LiaaX!!7JYjZQBmInuN47Fip#xyx}jH47LW}DgYNGJmqT2GY_#0B6V!lAZunf zF~}GpU80u>s5bhdYRzz4wcYFu4{~vx#uAB$WJM`D$_;?IO~1gn)vhq*I#l#eCH*E$cRq;}g`b6YTuRL`GU#r)^T27$9pK^L)>J~IUiP$QBDjHFf|8f^hfF`!^W zY`RG>nIRl2m*0BKLKfZw)}ky3>YIAfSn%C2KB(9z8e(qa^po6Q8x^IDKEPj_szbH}aL!b5&8f1xDZ#zv&Qm6`C#T&v*ihca?y5*JH|#+V5jU-h%cPUtHQi_ z30SV_M`e&>Eur(c;6D}i%BX5c4uAl=w1wYLicB!5PKvy9fT#?&)@X92>Cg+SawZR7 z=+2O9ame=Ym3U8ixA?*tlz&;j(o>QrIN^7X6aJN=TEO`Cf)m~yMr1Gb%&E#knbf~* zaGBJWE|Y3+nLvqtG1)S~I3HLh68eAzOY3d~aXFUbB8yqug6I>TrG zb8m}`3uIA{``aH%tUN(%-#udca`dmm?-j9qHH_kwxN?u+^aWOrr)8UyhxnsJif|`S zFt{N-?_Nffo_BvDQs#^@QLf6njVK?5cf$&mF(TIHs0RX0?XntY_2b+$&tkD%bjfGW ztYN9=;@Kz2^1DZtfAc-m2EY8zmn_NiQzpzgQ;1e4%O@!EyGN0K`#qG(_bsK!0|RpT z`@<#&Wp}|QSC-vUaUF-A5)Dq_so0Mr*z-lM{dG!gJ^4aKTV~QXRx^=`(*?S5MjvJ*lT9AZ?d6;%l2i4sa0fQ;Gf_iX|09PRW7m^MBN z0p2&|%R~EZ z+Hd#l`Harwb*3L149|c$3W|~9RuRVVPLxI}m!5hy0GSbw0CjH& zNb$EfW22#f9?i ziW#Yx3l-+z?>Lcgcy*LT(@|(rE`EZF)bu*1qnJjrHTW#gw+4Tq zw@v{gl3yp{_%p6QjCds-1(?47I*RnAo{qA%KS@C1hW16Z?!> zT5Sy#d8{usRAi)v>SbNxUbiy7*lU93^*V8~gd3Pt+ivu-*91oEwRgTZ-D_>$c9F)u z36QKZP1i(2XHJOdAe~CCO-;n>{gyqRGrjLQ5hJ@!glVXg&8f zs}TcGmv<0dOkE;rl}W6@in};S-V&dGgU-CHEM7V{?cBE7^{r4F{|{=TtqiG-_Cn`U zi|xCzZ4mX$lE=7xw{&ge)wlKTx9`e*$l-6Bgi>wF+jrc$76MkWeV3yz8npZ|b3+ul zeB+LeSP_65&S;}h2?{zPTO%?9wn{wyNGGoSwhseo+SJoHIz+KeQSHLHW%D_R}#Bq-2MuLVel`NAIt`8PfT zL*?FWpT}S#y_=0yQA_Mnm4&E!9D}sz2GIAhh)rXK6?V`+X-i-8@$@hR87a!Jc+A({ zV>HeDjh_%;)Qu;td;ZWfom~2j+`jPoVN@_Oh{jg=K0!do>IkQRVaWN zSFD2zSOU~7(fG4nUY9LV`fL|RyCrIn^u*ji(q1E@dZEzu4hn7Gk1evF?j?6{3aZ-{ z_dLVS%u3kFs$vKry2zVdKFQ>6@yI)>jYy2}IVgeY`ZX=Ap+PS@ZD9ku|4Qimb5^nulBn&HsPl zF%Lr~gW)j`hph3(7asG-KzIyU$SyoQW}eO1?^k%tBO?5z;W6*SuKgz;9wUDY9NKu# zbaE1NTz)lOO4kcLIn7GdGQI~lhYLM{lbf4qJ~k1jJw-jb8!hB!eR-U5DEF9>dYV=q zUOf(_PFJhMq43HHvZyD>Xfk~SHY%ai6J(N4ck4laGgJbtmcCvou!3BbpdJ`t5>2{d zg@!2Cl@o$}*VT6xg;E~$N;=>@5v*`|6pCFGltsz&d%RJ3#3B>SF3}uZ_95q`lDZM5 zzbHBHLP{dfWFIXk<)Nr6Czhn1T6puapp>shJpq8usGt6s$y$_GW z5ows(#aq=odIy#vWiEUN_kL46?<*;uG_ll!a-lo8cbIpSCZ%`|?%>{`L2Qoh=lSO7 zKE2f-1u1{}JGkB6f10;9&paI9Rb2`hDbJ z<$c7nWl8yfmy}h+i>D`9Mih(!}GH zl=qmVq)8_!%ln9i_*Y9|n z>kcEmQzg=4k7+6CJ+^HwnuPQ&WSh%-235g(2EU_iuJTw`ny@?i6IN_XY&k?6R5_3lrFXVEonB$8>i7`@IQAGHv3FT87XO8E{X~<%UbVxT3l9hK;ipyiD z+UAm(@-;T8eh(ba9n7k^aX>69d$0{;9#uc zxTFzBa%1WnQFXXL?c4v1XhPRh`4WFxF8&$(?d&qB#(zSAYcpK`^DX?;?dqu5Rrco6 zUs19Q4w7st+GRbcC;d-jhU%#tGXtBQZ*plsFl!SK1ZurBbKr*Dnj^+34K z?U0lnxcEk_7$LcjCl?o%{9sRG44EZ=(aJB|Z0VxA*)$ z&X`)g`EZu=y<+MdEMtSQns3Gc;$w1#h=6+f_88C_`4P(LPjUL13ESMQ=x88~YJz^v z9hWo!-Fa#iaff=I$+ZfQ&^u!AZ?b915_Q=>be6%+ znHDW{883~$5GVWd$>d;Zh&aHm9MYp#RpwX?p%yv~vHrFNU)-tL;`?3_eK5a)_Fn1t z(%JkhJN`M=kMf6v>2Hxto{ihRmWn1>+Iv?`2>$qI&I7<*!4e4SK=7#-IS5D@(uaTz z_eX-+{Nx7#!FHwkAkIdmHh!nCPq!j~KJgZETHA5VlR4Q5H)$S@d@^Jot z)V&RyT~&4Wzt6pQUe6?R^MXM_@y^vK)&zngF99?s$s`$>%*4zDLC|qX21q7vOeVav zwZs|~6)PfI{uU**C{a;UMCExz837+@MTClqN?WQ_&|;-6^-mvBp6_q%ea=01-ZD|! zkDcV)v(J9tYp=c5+H0@9cj)Ei44*UdW&74Pb`+>|!ALr&1a;K~tEFvhpnX@fRi2%j zR8a=o4LTSG{PnqLBU5}N$c$kG4RXmpI)4~(W7op5cr#5D=|0Hj;zCj}17$lWi?t+1 zx$xd^yDHQU2PKbaD>xc4K$3!pOTo_fRK!TfoKPKBjA}bbAV8 z+d*NyX)g!V2u?=#T0|tZmDyKcnfMmq%C#U)mQI%ymeY$}G+m4qQ9@2eXn{U`xd{4k z{tXLnoVceGq+2+8NtB~;9f-j~mRf0bCa%33sHH)v89k!RNdUFZn*eU|fmVtThj!{z z1t~R}Ds5^fR!ttD+M6)kwY7sIqdPdD3HmJ>t0ng|hGj8q4P|nbVth#UG5a+mFmXO$Sdgk|49>XB3hnBRDXoq9NQ={=fX7 zTF}OBBVdiX1CE*-UU;vD@(+vECR@lRx@u)IE(RDOAu?=~=1B?4Q?~U~xcnZ*uYj+U zL7?d^@#l+$M!&_7JCCPi!S_4QgM}jOG(AT!=c(ht>!IbuW8`SH#)|RAx5kQr4`s^l*XG6OtO7G$!N7fE{GCR2?l*+}PDTI@!H(yp?05{8 zxFXtDzPVu>M=p*g2e~B{yTsRejx17dTZ`Mz1{>k3H^HApc8V+Z-t+1Gi(YGEHGJ%? zHhJGaej{`jbXH`Du*JUfJI51#Q~4&5Fyit3$8Wr;{Bd0_GLhZqYB)8+T`{M>j^p2y zXZb6lE2~9rxlg(NO;fY|6{RaDXZv^N;4~fQU-4x(z9u==zoIz4CR4Nj6^)ZsC9way za@Cnq0$A~;!fWZOBEXnZ1X$4=N`VMY5CLvVaxws*Nuek%G*JwI|HG{Lx2@W^?US+! z{-k8@Pj=|^CHaWZHbB@prfEdvx?i#YvY$TU@PS~^RB5q~rb;uQw4p<$3?R5TetSLb zolY<)-3${kSt#l#Asy%xK5$3UK{J?FX$IYD;z9FknH4pGrkWDM27`FO{LOCbgQ%0P zRQ}6id}jff7i%HrDVYBy&`)LcJ5(gO1CVW ze&IF)Oo=oAa!Z}K$HCZp>f>&fpEPsVA};M&baL@(-a3Ak zQ72Pd6Kl&KEh2IeQJI`n*d}x31}J=!2^#bUI}$5C)F4B0zAE~;4t3g1wnNeq=Ykb- zpcvEJTp!@mb1!|OQn;gw!^k+gQRV5F7zXq)9FRFxx!gUU%Q!3dW1-yoV3qsvA_T!3 zDpSg_wCMYwBX9MFCKQcZIoZdUa%-)6N9Jp%S}6qt!m25eUp4oGlTl-bTQf^S$YSSR znm?kWt!3Io8>)u5DgewEtQZRlD}SQs-wYARl1kw)c22YtY0>yV)U`vr^y8BK{v6koUGHTFX;JvS)qYU?H4+OrSdeEI_!CnJFDu{{^ zN10=Ds5O!NanC*n&7J-6Xf)66U@EftSa~ruMvhGWk4t_8nl04Eg0DD^m6MzOe_z%- z3ODigajX%C@_f}LkI5%i{j5guX_;C``W_k1L2e)tFDbfH*>(V>krXXq7}{0-WP?Hh zrsCS|WY7<`kwSwJzl)YAja~AwgDG|KFiZMVUB^4)k}P&s(pW>(I^A4umdpu#%L>a2 zfV-+QKp}eB-4dFD*c46pYE!h@)TJ@&+~(MlbL3mKaX5)|7*Qh``Dq%is5a3I)3m9w zV+IhWX;Z~$wv$NhAY9GH;3S$Obu`(*Pfg|9+3AdzFeN($*5WZj^6|b%JiKc0XnuZ9 z%atg8dS}yGwH%LT-Qj5ST7ot4o23aN_pjI;2~2o64O84NKRL|ig>8No=+A0m{vg5| z{KR4dcsZZXW`-@5*#d7H|EyZ+%uusY=1EKp!pyKeO{o(Lg`(w3yHffoAscmogpTTq z<04&5D+LXz$qkG6dI&JnB{%IOXBg3_cgv=DLWR`dRfI0$s9YW1uNuJuoL-A%1+P=7&~bK(2W^8nXFv#i(1B6xu4Fl zlUlIKJqSDDAX2tSN&ApzCy;x3kgMLRoNOs^N#s9Nua2FlR>n>O*UQ*RV?YICCyg2z zQhucDL|0)-zA|>wOxGbo<1;loA#@@;X%Z)C@$BT_ICgR-SC2-z=dI%B`homvf3=~A z_E?`>EQ6Dc+5s#(%!!upLa4xDNM=gp8t z$jG!SIB(Ya!#*GJcYh7%X^4t+N0N=FU&XoX(5pC?`BfaC#Nesvj_{_0bk@+2C|p9% zWV)lzOLR$R4L(BMI?ioHI>4%{8AANC@w#XBZ)Lh?tiq<$J+rp0sURqUmY9RH4@3QY zYn}SpAFYA<*@Qjgoyaz1JQMZvG+71p^E5FITm7ttdOpl?k>bLcq%kuMv~MaJXf^c^ z8ffaB(?I)_XrPty5E^K!B_wNdCGwc7mD$HL18AwFf)yr*u)`JW^jp;af!UD$CPFk zGEUdCPqE*kT&3j_&6YAsG<$l@*=2{;oL%NMXQIh@)fwKDP*a^LTm*A6-5JoGR(A%? z4%LNbH^kp51m&5R&w~bXTIE@Q=QPSQMhWUDKT7f-HSL)NjsxifX@X3DW-Ua2#(R4G zS&FvPDbPIHT9s0?HI<2>ZJi3uij{O6^enhgN}B2nz}nk1E=idFv*p$yI0^PoV=&rqX2*O#fSYer@t0qpnnkRv)a8aXPeplncWq zWvW9X$qaO8S501Ssza*}R=MMKXf(;sN;sC|aJ6Vx6-MX|f9% znrUMEcWY=&_{%gj5;$nKCbWlC(&R;`OnREBp2kZ-=xGGxL+ELMR!&djQ=+F)%87a! zX=#dHPm`*sata#M7t)>N;a@un-a1^m6DCaK^f+x`MYYA(H4~4K8d(%W6_o0ATC_#k zYkm-VIdwjjrXixKUT1od?k5@9s%>CrzHJ-W(b$Xy@+C5sFv2I**f2y>>NT0_MC3^% zmgGi*_+eaSDx3OXg^W|#)Kf31Y)E3O`O~XxM4l!oH&xlx2dmuiDw{m@I$Wg<)Js|$ zYMN26ptbSTYn;{w>NOL!O&#^3ZFOoJqh5Kn&HZNoTBBZvQc--Nm{(C;m}%H;n|#=( zj+Dpoc+Lv)<*uH``*kCNs0D_PLuPuOsp+hXvEe$1^EM zR&~>q^A0pG%Gw6aRONiDn75#T+F*aCc@!D9VX%R;Wrq&Qr7M1PA&Q?0m+Z_Z6uFTN zbToHT>TzLTL53bE+H~fU9TJ8I{6m`FyNk&pb-boqRn&7Vp-K}hT0s=u8ATM#YrZ1m z(Cb1gK8D^xH;@-Z} zQ?#gH8p>|O0EmaVC(DBYj+aHJCJ3!iH(NgjvPJ<@FGVA+0hPp<27*lKEhB2MWo3&w zjj^;#0FPfHsnsPHmx#@&m+4`oc2Crbk6iuZkNxdm-*?S7oph3{!Vx;g3A@IkCMxlyBl=88`njl zucf6?`L8(@R!yXzd_AIgIU|ay=E`?gK0XIbfGu%`hc<$0@7YZehB-72DQA1qv{Nwt z^{RzLoU7K?W>T$ETCM$%Ud=jc)w-dOt5%z@R^Q=5t06&&ovYN>Cst}j*0D*ce4hwf zafw5Y59afwnm>ULi~meT3^y)sb3$=?C`aY6BQUEg)0*1 zF7sT5fzAayDxrjA3`}8Epz+eU;Br1H#sHTYEs6ZSQxRwV(yO_&6l^A*;*AZh9i+D7r)W@T_~!h?INMB(TRqVZ)^u1RQ!-V7W} z?`RQin)yGv;mdA#_NgvfP+HKips{Jef(5NS3ud>M`JH!!-26FCrYtU45G`n4u%IPg z(6(UKf_TA#IdkW84Yk?=@;9Z(-wg7%9qIkSzMTKpifs$Ds-d}=4M1(F0GKjBXc7fX zhjQfY85xthTuWn;wzpB1I;=zDTNr3ay+V&>qb(f;H5`%?4JXH(2?gdDS6z<@c?D*o zn`l%Me_2-B5vWyGeB^sy{MemOeC?Y5gqR4Z8Po7lH}_G5qh$**1W z=%HfIQ$?F+P*E-kn!c8EXPOgDjt|x3Im+zlan&kL0>7Vf`Ox(BDl03ya&vrFK>onx zj%Mo$SPdI&e9hp)zB6Pn?mGi7L;5zBCe5zvkUe|ap(-|;jxrqaBR|qml8C^b7*K-` z0&T<#O>DILvF=B=@vkfr1h}4Q`F$#FoWy0_3*xG%qB5@GbhBqFERukED(yXmVKL8; zm9<#SH^n(I7&@S@(O77OcFzcSR2AzAFgIz_3(n}FMo3BecJpmcV!^|+bHd}ejk~Cu zk}H4dj&<%NClr3uFWrmX6bKuq=*_&PDY^QWx;<6`mTDxZT<8WoTZOy$^+rfT)D zHjX#>Ks-IyU6}G`9iNRt-HBJn(x)AT$krk?^#mZA1c4iKKrDMo73u?sw`P?h1 z8+vn{dE{XcD7$4A-c}nE<*yfY*t9raeXWhF(eHV#)|~P#9q!$Th9Pw#{I0h4&JR>T_ zha+*@&2bEClZrgA@+`NA^fY!!UACUH~4n#8RVp4Ii=F-@(BzO*hUasMhJP9|}u`%P)P ziPVJNViLFVx+O^5whhLD{q{>p#SA2FJ9x03cpXCGK2Z{PIQbuY028*8dw!*JeNQeP z2|A7icNzC>!HupbIT+l+$Qq&0HL2(+@As0p83{DRC)UTwjk8H4aVb1VKO?EvpExOY zJ*hDMt%(BWa)!?#g>jCc{EdY13Dv3>#=kR@YE2@Hr`7s(h4H#-jTgqhJF!xA!ua?8 zYlU%9gPbt_D+%KoGC>%BpeBqn9AJxiVO(h$9(iFrOJ669Kfo%@L}C1w6f>1D{?j0g zFXf)@R2W}8K^Oy{*Jn2lGiD~wFGhHpPM)`c@8$WxVPQ1c zaRsm?iQ$v5#7X3Niu!HI^S|V#(cg|d|Hv<0viO-+HyO$=7Lydpn+(7IR}y7){dZGx zUB;x5?K37lagsYf&B5gPX}fDi@_bHeV24X6SQV;C4UFz-DwK`lyu6>)E1Cqs|BK}P z8PLF*$e&iQ{M~wyKlMkE9{;Bk`4@YUf2nj& zrTAS1uRGhT={r6WVV~0ekTyR#Dlj*|t4-QBG_B>oV=^mkXEB?e;6REr!+gzfm4H2A z#q!nCC!#oDj~M4(paJG}bVsvKSEMM!4=MEF&^Bpj*3j%X8&H_3yg8hLIHv9z>_}tlXF}9@uNehI9QIzP zgVu#q?Np45kY@8LEpuFCpDbGDI4gmPeq%CA>do2g)Mg&1jUI@_66rrK)iKQ|nv%Qx z9s;yzil@!Ij;0jbNzS4LG|T4VCQ{1+9Lq|-v8Pz;k^M#W2%wWyjfWk(DwOBZ)=gEQ zDKmqjj`zqqs<;AyzDy+)Ccs$VNHfL+(k#sXCeoH5YTVJ7^(Qr=UqbgAKJB+FCdh>r zsRPiv-y^HOMjd7!K-h#P`wFIW>239>E+jvw(M6fw2(|t@@J7(buvK`YN!x!l-q10$ zEQ%X+Ikdm%eqZ6JxDBq9a1}W_wvUQGP*YFSb%o_Hsh@LKuQoI2qx=cK6DKNv1Z?n^ z`x=r*<(ms2e;G>@?6uoudd$1Is!5@Dx0OF>2qc4Kx*g;ze@24>tVM~;=@_`1ww6C? zk;-o&AHzRJQu)(b%5lD;fAZG7m6O1{W?jch#e6#+qw3F9J76*_zko|B7VXvJV0Ann zH>z7IRo*A7Xt`_6{t0Oxj{MF^%*6A}E~d@CQX>f1O>FktwOz6N4q9^PW_z^tYJX`- zDkUh576VOx+{6rB&_y8uVhCH&C8ax4T zcSJgNBr3mCcVZ|OJ!5dHL@zFQPyv*86@a=rs52Hws7x(+|K^2nfdGHvH7e>bvB>H9)m-^bVy7^&0MO@5*S_^!kz zLFAaLo46-22p6naA&c8DBcDBe(uT^KuB0V0b82xy8eI_Y-BDpVE-lt;7>1ab&O@V{ zl6RAgM&i2GGQ?D%{8QU2+mt;1b+5~On}YxG>t30;SM_faedhNa_WN_URa;}4v;{-L z1{aYiim#hWl(t%xIJR(YWS}2Te(2bFsOseWDEc#z%$>9w0*-0#4h;+G#Fo$!u7gzP z>ZBp30lifg+t!x_5XN zD^%O5OqD!0E9>NHajQ3kP_77?i*xy~E(>bIb)wGdV^demj%K-L;X2w}Wn2%lSG1M) z_j%9b{XO1u{D_HEb9NYMKyz*n#I5}EVwHnYifovnS4z;ZG~j9Wj+wjsR-mD=tfM(X zs_zskvnK}5BR_wwo5|NA>#Q4Tyh zk|x-4WQ&Xwj8v8qPTlC32L=?S*)0NfzwTC84#q$rW%^J<9Lyq|4*ID5^W9k~vUMI2 zXLdv6O2r1&0g4Gb)V03A*!HFg^r$Y);`3jMY_N+LyK?z+4Z5*0AbJfKu}ZY`jncm6 zN{7VP^6Q+{IBAC308ia#vr>bi$x4?MM`bo_%}$lkfc2}tjebDShKebA5}mn_72QT9 z$7rxV`K-y3+ohbdNUrGlH#m8al(deBJ3TO#+D2TEog)Uz64Dyh# zq_DaYFL48jTf?bkB;w*Se@vVQMl7lMXGJ@W#b~Zpt?3ymCj%jJRRSF($EHY<5c_>P zqFI1#1u484iU8Ld4vfo{pa_*1)`aCxrA(8div*WLe#$Ljcn+6;QS4BJYo%RO_0r)z zUxHNmy$ytx^n!s^=HL(~8`dRL9dj!4J&w-Na!J}aJG4!rDd)GTc^-Qet}4-%x|XrM zE{ki8%b}3E{)cAPV+{c^HFPj&_*3#K^Ezi0t$2UtUR{Q%b)R4FWJKs1HmgCtAZ@$P zY!GCd1FYPXwFOSU!0m@Jj`!4h|_EsRYVAVnMdx(!gpTRzc*d@=w7 zUg67xTm(*9qAVst94UZ$(Eb+RF%qT(c0ePrgI+2)!T{ySU>pbDigH?XuA7}$US#7I zm?h*3@v?J0Ti2Oc+7uw*%3V*Frhao;R;vh^yNY^9HQY=$2?yzHMnV}bmWAMj z#Pm-EMJv;LdGOHP%0{DCY;%_V&bHq+`<-jQ?UHOX@fG$I0TActh{BTf)g{e~aB8M2 ziK+bKXw1)c`S6Fa6#!&Bn^+b>z;*EtB7ZDo*jwt#&uBb%khvJYTBX@4i&lQ7(nZBl z5R9tASLk>cW)ABXViIOT8nYH9ZlP|+>0TbkY!wesq5RpX+GNu&f~0hC`|!AT({CFWt@!P5H>X%urp9}Pdnoh!KYaM6_W!=TahKzsI^V((0yN;AFM{V+PzWw zRBfD53lrq%-<1Xmm_YoGE}q!NI~u(0rt}rr684qA$RtkQ5+^wjLmDF|&4so*Yi`kk z3qio97IJy(JCIn47?)fn$(e5Pk^HQ}aTzz@S4!J5jb4N~MQM3%o`tI7oi-071&l?@ zyUexY}C0UGR}bFy%%)TsdhTB4VT7}%z$-;V;BnT&D6}R zvHU(Pj|)%_(C*{xxDcW?%7`lbU_?b~h|4t%qNbdD1p7Qw<3uiwSYXD%J1YOXOb?i+ zJSFoK5Zw&1u;tc7qU0eXM}Q1T&?Nka$+W;lvT~tn_g=OdA?t{IRsC6azMfU7h~C2> z8I~-dH8%>3RGcrZuBpRZ~}39OJ?XRAQmR=#zKrly)PkxCPCU{Mp1_cdDO1=vA5>NGz5?@m-y|)NyE0Q^Q|Xy; zs4Lrnw&nL0d=&H#h2>tW1GFo43a3;eD9LOqFBe{-SSjkzOK1}WOClDoiVX1?(VESe zh2o!!#-aCV@R{i*c| z10XC&Wfa!(kfy+^JpgP_1?l`1MuvpGYt>W(;!$e3*Ydo_bUm5dR6~AH*_bY&<-noA z5tAsn^>66cLj9r1i|0Um>yA;b$S2!cE@NPbt);)&r$05*#|E2rz$4h13X^j9460RW zMPPIVt2msbNwp|#jpv)LRRb`>gTy4T%2U~27Hzi^E@LwQAbz^&OMH^4a;6q}9Kecj zJ)tRlP>bASx`_Mjx26^u<2$HDaB?{vRWh~69T8);DS3ik(r80CQA|(3nvy&Cpk8=$ z+&I6Fz+Lv*5yUmM$mbROk3lVRkjC(N&|-6DAMU-B$L5lms73B(`~#8U8oJww=r?NuD%Or4avM#!8ZW=Cz3_W6_i(Yb$ct>5@T7!dYX}C`l9= zlq9EbEk9N?CCO5ANlEeob4f{Zq`C4+l81tlzB?+acN|La4E+q*Q=W!WIgojwAY6_>DD`vw5pcsBWEPEUTA&tlB)gvUF zH8J7ukYXgS4LGD?#GkU#3e3c(>a1qbv2nT)pQSRC zI5S*+M+q*)r0cMBBM9Krs7FeOSSo-Y=;B26NON&HovrGsGUy+&xOM6gGrTZVP*dtq z!Qc^^ovB79$!wA-@i^6p3aP0^u;`KzC1^jjY6SH~UNz!(enQMdmnKz>MCywE--cSm z8)<5!kfRhVza_QE{PAiLtkr-)3j4FCQUw$hM?;h9SRRr%z&z9I`#ge5#76(&szm;k z>4NHzSBZFVBZdpyrV^QNDv|lWO_fNl`BI12HPlnVAV5Gpe`s|`+cOFZbXORCyQaM} zoi>~0C(OoAn{Q{%B(YPIomA=^KW#o(l*~D^X|qIdO`8E3YowD+o3$3IX)~nK$C$yi z`PKsb%uk!yem#ELTw>a6v?`r0i>`+0aw-i@GF{$R%BIVIgVJZ>bXm*2l3)%!V}1)7 z!wEBHvyyzP1j~|NL6!qbt5!>*&nC@yLL@YEegJJzI(OEtr-^gteWgRsoo$&~)8}7I zm_Dm}n6Ow3Gbn$vS87Z;gZ^Ln88n!kpFs<6*ar?~uo$G0JRN4xV`dUj zFk^s#-!5JV;wKS(>NID>_@(>-lpMoMf#dj^LblJ>Pqp8rEuF|EhnQ+(I5g!{JDTZK z`|S;Ws$I0HHZ}(~)#eDiY^seVDpR^&Al{d%^q!{FSRRj7IrSu)aTi$DAOh1O`Z%#O zQ-Oc^PXVppl)_6n9%ADCzH~3E?x-;G;H}aNd(_EzZS|AmyZz+&rYHlPX2+NtpmGdz zat#gv+3H|O2Dk`A^<-3MoUsDCj%0^X5DK%JnGWs3^1^b(UtMiL%~aw+O@rb~`WPj7 z+?WEnM#NJT7&!6G@Ihe(6PJCZZ}*ix-OsPlYE3hv7v_qmjGxs1s1(K0%GBs1=M@@# z9&|3aE%Mm6OYD+lj zne5sYPjjO0tWrs(s|xeLu@-Ob;E&Q$0CVAF$?6U^z-b}d=fEf>AD4XIe!2GrH`8cl zmR0FZulG(g;JGDPLlUDNS3#;OO*#TBhE!1_?)-^38LgQw z3Q+_p9EA}Uq0S$K?I@FRh1q(g%!$DQSsN0rheaD$T4gDfwCW+#-ol_z`Ik`Vawz;( zrkQG?wQaFO1;Qfa=Mc5fWzql@UVazio{}T==tuT$B^|KL$!nV6$F@|_92P9JoZ;aN z!D?0bEd2)NW?0&acZ)zl%?lVDXbHR`p|sUA4Xh8aKcL34J_vqTAA}1> zFbR;KN*9De_`9`Jcw8Fh+Y{43b12kXC2%QDuu2HIFyZE?0Og)5B`pH01b;h9U0@+t zC18B=KffVN$OUmzR6bTa=jRAIj2=~B(JUAiAQ?XgYX$l&EXCtG0=M0uM%*J{HVJ$b zn-P|!ZJDWjwcmPGw9A0nx&MbW;9XK-A<1GuYE^-l)T%*)NM-tuo_vlpR|0f(#Tl-_nKq3LzC{)}O*tJ zr>;@LLlxF>r0I*RrH=L@HAmuYUkCNpg)No#+EPCY8(TZtNrX`X^%E7c=%q@#7A?vW zsHpZZXH7xq^c>;8%7}P;53W6w)!DvXzr9!ImrY)XC+J zIR+u$A!(K7*s?E4=6EW{JZEclzLqu09rF}FuFUrO}KNQ=QK*fH3P_j3e-cz=|wOPI;ECI+&2X70|03y~z5JD2zC{B+dI z&8cizI~YOh4n(GgjfLfjgTWz=mOm9CxY*@*FmW}`L8Ens3!m!ZsG@ktFl|KjXAGJq ztg%B90d~OQQ1qx?!GEk2{0Hjl4Ex4j+>DrQ^^d~e?=87S_>a`j(U7`7GxN`KM}wE? zBStlKFzH0Hp_Wm!RMB7tC91Pk2N6I~Y)K1-U>?S46dy8XBO2CFvjIJ4;EgK`O!UE4WT})w?^M;9H zo!}g#)|N6*_E7=*QAuc?2$wb=wtW-bx7d9&g8ws#vI^#SH&Td1*1)^DD9)7g#QzBjEX?t#Ks#o1jV83$(b#%Y=I+ z4?SJ}atMy``a^QeQ`+d}YAFhbY)YJVLpGNP+T(=7{mnBH4&R0rfH5;;;gF>e6W^$V;4~xQFqbA3 z4n?EAa46T|35U7tpt;^;l~w)!`3=bnhwo|3uIZ4Gp%)I55}c2#VxI$Jke#cf#3RN_ ziSu((;(RY9zN3WStwBnBe_l$&@Z3v@O_NB8-g2=al@RqtN<3o5QX&d5re0oXXouvg ztK01u?Qv3~=|`uGn@WjIUP^4rONn)j5<+HD;&ZUz)fF7n86*BoN@PVfUH8zLnEsM3 z+0u#+S>keKc91SvIhVNDE?Giy5HcHSSYwwYI+vD}$)P$&&B9DguQ>=pk~-Uiym%`{ z5y*>(mP%5lyV^rZKCLAxS1gNA!rYL>1i0y(#+cSnt5l4f2EbE^k#mp-sYAy+>Y|)X zjBKyW5f-#t(P@vValUD-yhy_Gov7kGNm}zHMz(vgGp@`VCq|ky>b)gKaW{*=tFui@r)lYZl%&0)ARbQY62aEItX;ikA<*9$aFfFXHuC?GAaU4 z*w#~sKNe)TM^c@7@-S>LuvVNh(x{W+Yy?3^mv9JZPJUA=mpqiRP~7*M`);xb@|zeZ z>{RmG&E6>?;{eW-olYyi9Vpfda0j%#-Xye%5*(S*n;NC{BAooEmf>m)cIIN7aau3Q zS>ul_JZPNuerA@bBzGXsX^|XKQO=HB4x*emZDUw8@oE?WA5QBMFxJ9yB zL;0VJ@s}efii6hD7Qjq{D*Ph2evj4TW|l_B%c_r8DV;UcHd!^4{eCm1E6V*Nros%W z-)xf=qALcZw)G4mQ`=-^(;yg!Wy?;n74X;umUJOtrNF zAtaV3?7`dksIdaLb|d=wj;nS2Cp9oc*+kKkEYpk=Ke@tZ3f0iMm8Uk>u;^3hC>EDn z#uzo(b&$k1giEXkisesH)#M7X40xiSDq3aLZ#HpsbYFZ!P0G+7D@@_En68pkhOARL zt0)5MsbN$B)Tt`s4fGNgnw|=`$&`>5i#JxHD%2N(3TOlL${(`joHjD&VsP$g zRi;fGU*uctr~2B%TfVM=0vhd3@baHG7-5PokKa31 zsE~^25T8JAul!LsP`dWlmYF>p6>o-5TV@!VmOo$%DLRr#yZ!wlvG-wq&y(C_$sq-jwjdjnGV8Lo3v`8oG@8cS8%gHMf*(kp^jqJ zR1mF{ys(#o8A%dRPL5xAm#0D9YD&4=N(#7U(C+U5U`(L?@rVIK~* zdU{JwA}}(H4ys93eZpN8lV@wCiUa8S(RD3*$~QF7!ZwufFHmEJTS5U1Xx|Tvb|E3O zlaVUoVk(`I?gU~imTyFlMIzx(w_27rSh#&IQCY#8&zT3cga*`$-b{ehM&-jI6e@ga7u2zH)1jm4a!D9a$~)h znWl<9wJE(Yx2=4A2^F4)jZY^9p(Lfv3;1e>! zAsxvvpozB*ws9@8nH-~`ZHhqKdu*oQ>TOvUXsD-5hC+nFsT4-K4>42{Y`@xh8P$x` z56Ql-yYgod(1CSw{kLI+v?F=?8V@A%dHAoR@`t&Mx0KwNhF|yI5H6obv+$ckxEic8 z8q#(rPk4+eB>SH=NJNRE-hOYI@$G5G4|%Rj7(TaV;diIuPrfr0ET6lx@Owiz1qWuY zt04sQC{ftGSgv;mAEd22_{OL5kd>+oipG?Cad3Q)J zpC_{Lr$ab3{nSJ5vu`WH!7+hi5%sVvRa-|^j2Ev)#|-o1Or8cr56C3~;5 z5(@NYNT!I-WXWz0$&%aB-jdG~S#RB%h97)isH%LP%EE6?!}tAJ2$#<@S@_*)_>VWLWOQA56m^|BDbV9~rLu@Q2gzhd&&`<)dY6AO2_>e*a&F zaQWPwg+Gyo-+f~Um(RUf_)}^46CVlT@_8@|ekA=nod9%3esek_E`=ZP%*?lk=2kB4yiJe7tc z6&SH;6rE&1Cj0NjTn3H;-8)KDRU`?S$MgK;03O6Bf4n3j9Kw*`@Ac$glunczxjnaQ zp(O6K$a6OcyjZ|N67v{0Fv*utiLftlO#Y#k<;O7H06c|Jk)*A}t3(&GZx@~)$7`IJ z8e%sbz@isD7qT>#XDyi$s8$jz#K86P2Tw;_zFS;gST546-I`LHs8~Eyty&h8Y%B0e zS}<{<5T7<#Qt56crZwMu+9tv1){=2}xb;7{i~0QpqR0hZ3*#5&+D04I8sZvU^HsMz zK3@tV9AcOX#4p7JgDWGT<;HK7(MGME`)9Vt_TR{lOz%Q6< zWl~#lkqql#zSyQRf#DREOSoyS+6tOm;<#3UjoAhs$zfhRxZT79Yw#U@j#CFT7Lk%4 zMUy~|_LT47L?W_NJ<_&VMt7EELBzir2MU4>*HZ;jCcIcQX+sCVZ(($(D!vrCnXQ+0CEJ^8*BIki327#ZoKV-n1}|oPFiOebs4Y1~YMA+u5Tau)!@AweT4ics8c)n(B#@QG zh4(jf%=N+ZY&s|jyc(-YbM(`iFvVEdF$*#=PpxjjKA^<8_*nkB@?S;OR+FAt;ceFu z3N28YS&7cwVWu_fOtvPs_++i+KcTU+Dy_p^dhKPkLgdZ>_YWO=K<$ zFyabJ)Wg*|%#)Sza{5N(2mPdn^;|6lm(A?~1c=(JEnv&+f@`KU4@WAFN`hjzW`miN z`pW=QzPD6mWm>*|l7{`0P0}EhMxC5gnjxqq1R3m^viL4kt{sp(`i-L^W|ItH3Fukg zCG#Z?%aBAKt~7VeYNSTGxmdPUOzwOMRb7K3nn70z_jTMnbK%@n0+E&+D5GjfYuJ=l zL^Y6UB@sGjF;?QFs7g0iufX zS}Mf`jhJLFm{Dz62+FlEc}1g)yIeymRaGN`j+>PfF0lpJSzMNSCjOwXEjDm5H#5~T z$!(A*rG-nQ71kKr!1mdGu(%GkkYhAX7YOJYlqz-2!s`5C>QLtF3DgTH?q@L^ zbX_UMFa#MLvvp!ki_Us((J*0Xh=#Pwx({ERHgIRz!0niAU|ddq3|eaPr2?ZB%S69f z4(PVpSZQ>m;|>b|q9KTB20fr`xd=;h`&PSas*Q@$S=uJXpo~@4Y??pwGx?~V;t+pFv0B|6F>5xTrB-;`F)8Mr(t;|(7+c>+g zRBfP1vx`lxK#c;j(-9maCrodYF`&>~b!_k>A`Izv!PpOYLoc&ovEj_%X7`dLN`!{A z96>kH;Ywk^Y9I!TwQ-4lZQQt=#o6?R=epa*@Z2a$;4qOummiX{g_!F{Q8OD{HKY~) z71>bqx;EoPHANaj5#~cR87Xuy?6M^IhPiMtz9ycP(1jDJdzrqOo8G_7_Ld zYCf=;g}SJM!=O3ZETW^mM398U7e%_nENv)>L5p+&E0HcG2I`)Bw?!iKD5s^qHWE>c z*Xn=;<4s{pa|BvYs79o82>ck4QA1L#r$ifL6p=RnmLEVKS{<+Orx&6p^f?HH>vHIz z-#Huaw!08DVPwuJ50RIAF3wDg3EV<=HC)UlAiW^fG(&sKh_Q8+$w44P*h zOqynD>x7_FMRsuAFpo$bX#EL}(4V3NL~j>QuSMlJY$@AwQIp0?*l0W=42VLGwS1CS zUYzW;z>wXiO-88YSDct%+a<{(Q|3ouS(Y;?@AE3pnybD_D2}0Ud?bpv_vs>)yREne zsv0U34<{wXXic7Nx|r6tj#?~SV@($$HMEY7jBqN*E6)@m1_(0zRr7USdAp(74=vR=h|P`hhZ-1% zo}cGX8?~B`1!{9?HEs|%?Le)nd+FFPov{lYhZlqCaBKSYKYK3A~1@hGK==;SeGLwniuBYl4}a3yl%Xfj4WDI3jR@%fogPKm0P z_^V;oV#ml*^@#FQ)44_|RD_J%z(Q3e9RBtc@(9!}tqOOitfl9zF|A`A2CPt{C!=A^g$s}( zst{}ExW8YnmztQ*)l{lcm5QxW5-n9J%MEk>tWpv+5zx#Z)2^JqNmh)qqVb(hnu0f;j?7;K>WZADrs(VbbrB}q|f3!~K* z6-MIb(Gdvg=@*lD4DCj;_n@MK3!q{L<0TG!8T1iy3WsQzNx@wvHu04d4vC*1Ekb%d z@>S6d&@vYn)xS&%CI4Zb0QWGGEE7cdqsKe3PLFI6Z$maPMQbH%p&i7FGNAEE4F&ap zRz4y{SwtD-VAL4t{_08as=?zG(;3YK8Vs*&>8`=LP||)~NySi-utpOasszbHQ;(g6 zJ_bknG+2B)Xgi z0u0Sl%z(Q>>mVi)=(OVPKdnb$#KSSm`la}-rA#o$5tGUIq;+A&Cv}A|`06K#Agaek z@=f;cf)*UqTm;Y)5SS+f$Fn+&USXc7b!baQ-2?L^dY*Y|#vvM^%i~kBU6{x`^MQ3V zJ(S1va=jWXA(v}e8$CR zoFzcF!nR1f;2ZXrcx=OSb|KU+Jdli&Y0&Z%>hSfnjg3;JXaYQ z&s0FG$kSpYT!FE)2=NgWJX=AS3|wWW7gjVb$1#-_8-2}zsWb3 z_+EAiy{sOlD#isUMYMlHVWGgf-sYP7ngC(6A7x8Q`+b?v{#u!$k!ksIgMf``k2chL z)Cm=>M?-(2`xeFLgisyykGP#FqDAO0Dt0u0bRj zg%zZ>VM0#5&};CCX#@MhRl?&Wv$;3u?QO-Z`d_S7|5ji9Vc9%HuN3=6CfpBsRbI6*eiwdzmxwDiG2YVo}Y zu2+5?1ar*G_I+IpqCHOT`G$O?5XR+~#FG8@Mah3Ommg=D4A(Q}x((O&%yl=eADHWY zTo0J*VO(!+QHsZLJz;)N;rit)`Ryg=56_nCDqOeDk?T5KkIa?pMqJ;tvULcB7|z{;>t0LoAg=FO=p(pp ziIw&VTz_G%r*VDET>JhOn*eiNjqB5f!`I{bz&xcmfa_ZpdMmDfFnk@u<;%Sn*PATG zL%43ST0M&ED^}Adas9+b$1}J-=y9D^e#2^YEw1-l89>FO0Z>V3ywHG`&;X#+(7^DY z07HX&h_pWi=k+N#@BdZ`PFw+;2PtUprwnCp$GP7-@46?^C9oN7w6;N`4G;hz4K9= zSN@eHdlF};!!tOq^S)Qoo&(-_EzaA#b3e{|yz^$94|(TpI3M@UyKz1p;-+8*S_wcA zn0X1z0ILRO8*Ky_nESCENTGaV3gxFWDB}uHegxOAPBkRM^?h@Z(swK=6C$WYUN*k- zC0fT4U?rYKt%Gvva4`j>z$0#_*Ex-UmC<%E~mIu;ViSQhJ6V%=*TPM#qFo=U(=cH%MFemP5kE5y3d zXUi+i_Wmr^-Nbs*XNzY@fTyzMW!Ykb@ko~7L1KMpJ~D&+LVWxbpI2JIlUe*niFNJU zC0HbQh6H#j0k5=xz4xU6e~MWDGD`*E7vkfm_`K2ruFm4`Bi7@-06aqiJe7c#6(CWe z{I&*}721hHE|HoUZXL|a&FRg{F$X~S=)&+s?_Smkq|iwI_~NQOWT_~R)eD&{#qo1x zyuc|TVJT6v3-lZmh+nE`x*SF!jvWsd2XVS_6e9LTUDS$=7B9N?IEM)?$&69zFKmmv);q^|;NcULTQitV- zSk-~(j=X2tmcM34c!h6D_*$f?O<13e;umH4iJekezh;7rdu>C97jOl__&D_s3R{=T zu;ZdzNMNNz*HNo@sf*#zI;`d7te^k^&esn>Fc+F7t1v%xa9EM0^PA2AnIK1hF+1TX zBTn!&j*iA#S&X}JOPrlGGrQG_bs^M0DKaUWaOsexR2K-D%ie?oNLa5|{E4l!Mf(>1 zTxWO$_w@~NS5`OLR9Id>e(`t0GXgKe;08sY4Wr8>Toi=dHP9P&3&}<2V!tne29P<^ zzddHbE*W<5E=l zt6m!tV-MqdP|5H;iW8xMV+HIgF0XJh3mDcxE~G)Ir8j)NjXuc!)J%+k;&9ToJ$?^3 z93^+`J43=sDa>&EFuYszNtE(O8^U3}H^~ttkLju^g>dH0jw&|YT4jRVxoyK` zi=spaeB2w})tE-U`o4T@zKCwI6#Zj9`mr<XqF}pGa?2hcx!8_OoN%3#vg8oTCPYm z%Rsq61}JZ{%$#NBD$UyD#0EH7VHAd0svw44&;s2p`iV)ShykRaXat~A*kvmLI#*1l zBFR!lQ6Vv-FV&4|Bu6u;w)hMv7XPZ8zYJO1qT5k8$vq*n;R*{>g`=cu?4Zq>EF~B_ z0gyscUbm1+`FA878on55h=@`jGFaI!4_-+JQ7N!^&r+OaD4b88{4xbFS`&dIf#w0x zcx!Um#d>!wtU_D2O5*_xb#Kd2phWXEf>@CQfhBk9xT2%*39i=5J!`E3K@F%U?%TY%V5;wHR zHt-m@!<`dBCmyfLhNtJ+T%6HP3as)9AeJn8$p;mUEeL~nbRJ`GYlk0Pfw?Rq6UZ6I z*yoOjQ%nwtlP16piH|=Kj=hHxagx73gdSrCkgRs5eJj`6n<+s3SZm5ftkwi`#D))BPzSx zh0)Dk7`2?j{R38Sor~XWyQtc|%Fa|Np4#}1(e9SQa{dX@?<_z;7~HK?P6y&?{Dfl< zZP&IAo5C7Y`n;$!HRDNiwU@m&+Kvp5xY zs$Da}&bMQxtDbq6EDEN@&UX-Fa_rRMkA|J7xKad_ACzbUf@+~06I>l{DWxz6!O3#T z^uuV?gsYH(aEK&BEgT|wNR*W*t=plLQ8@F{V=aeD)?w}cQt#JcElI)IdaU(|<{4t` zTcqLs^{|$XSCtKM;c#yjy*Dz+WKM|7T)_Nn4xv34$^9IM^cnP>ZY$SZRs7a)29q&> z)n0H#%1&$onEIEmiaO(4f;r3m+#dw4tHF#q5EYEQy#clgOAyTu`vT3nj7o^#FxW68 zYaZ6SNkm*cNT&#CNU$AM0U{l6!Db@fcDv6LZZE#r(NtJoDT0pLAlDHA`{m@yXe)9p zqIQHp&?49nW4;zf{&qKm_Uz5~K;dXZW$ou)Y`q0m3O(AtUf^GgecaRedJ~(q^cS66 zI8ilL#o4qfz+!KiP)EB72P!y+1rvQDQXY-Or5TB8hMZNLE7Mw7o}pF@ z^A6a0G9QcUi$T_X*2mYz(W3dsBG}TAe^_6)67KIDFvr=;| zmb1eacU57o*#x$@79+3mBBqRbaFHCBWjNo@`m9xvIKH=hRNf|0X$nC$O{5Ae(yAvRq(Ma%JS2faE>IcT$Nre~i zMX9GyrFO(AAjy}Vgn0_OIenDAZImV`C5!S;B85$HE zNo*;93AN74$aB&l;#1*A5XUK=GrFL5V(_^=Ok55gf=ZXu?r zAK0aRrzw&YVpnk?poIM3(5J}Bf<*!Y#Eunks;E#dEWell@uYC^!h99H8b}+h;$1d_ zo~8|LS`2|bQ7PZIveZdv>bxR`;EHl2GFB0QXVKKElLTSt78NRy06W_cM8Hg- zemU8A)^A-SuM_d2`eme4^>5mvAVSv7^oq^mm3EmZ;c4 zu#c-$g)9kmun}QB?CWz9b1z2)s4x%>=)!o?Ru)5&qgi(;nXq8sLJrGe!&kuG!gAGL zfwa~Fm7Q?TpWz_)d_M-&3W$(eSOHfUE*evWFV;<>RKY`>nzR{!i$(HQZno(FN~#F~ zMC!EYL^=Tgn9x)zf0YkGoxmmT<)M@%?nIAVR8I1ystQEAgJ|7T?u^~iKzk?u3Sc~m*kj=(a>DbXAvpAnU z?AD4D!epSKO;eUBfkZ@SJ}(j+YZT(xtm4k+0$IUj)Fh72wDG0E&fUy=fG@1(V#*VF zL~y^;wgCW!bjZR%B^P3AZG+YiXU~*S?n#zbUa;RifLa|xUKyF_kU2#yuQ2=(tr-3c zQ9?ifxJ>-C2BB(;N@F4x`=A-&uq2i`9Hvvr*05MWFa)L4loB!mvzmBDYiMdcU`VB& zIT7NgttY5FK(py#ZXFRwxrh09(p%T?_}Uq_98TyPGsWc81b5{h4G&kumkg8=Ma)ykI+4Ln~D!GX}D^LF}5^^c)5W}HZb}+(T_W3r+(a# z3$%bhz*%j@T1sLSnN;HulfXa<5%3mpNCaFbvM?qa)1eVj@m7yrG{zH+lvw!Afm)c7 z!YGKGBE-JGv%&8x;ft*_jgW#i_!?E3?GqVH+@Z13V%&k+YkXMa5Y**5F+MfJ)yW`} zLoSB~-h`AH|Aa_Zpun>G(!aN$K;whnLGzGLUEi$`{k?z!aB%P#)| zw`Io#TXt+2z1*!HI)7x(;K=3fRf9YHd(XDZUH?UUMs{x=#Ia|{-me+jyu-Wt21oad zD5!7G4!zdxwAbp9E%t@aqV2~o+I;+?%iWTfR4SFFXD_|XEm?Z@OO~FEd&$zvUb6JE z3SLVuTXdNl7}zm%+33KokuBSYDmyP38o6NG&P!d-&P!AScitYC?748y?oqdC=MH|? z4DA>i85|wz+B~#lbjt->hDN%#;Cg6HZ z!BI!m-Fd{{v3s|B{)O9io}^#}Ht>6z~j< z9KYjIpULq%21mDCGIYHE+O%`~u5Ck?ZP_%q?J!d8QmaQthK3F!4LCQrZPU)phm&TD zI(zr7p-ol}aC3{gmMvPhY*Alj(Jr@nr|{6dif3d9#N0vWZ(g=+=(0@!c+1Wmj(*S! zEOpxlx9o5`28qqHgIX-wRXKOt;Q2$_&ZsWhecleYy1SqLz99Qw^TO4=a}$A^m)U>5 zyLuFPbN0XHg{yD9!sO`Ru&nZ;MY~^wyZ;<~gZou`wz(a9wrvw`ZQ16YPvtKe|IGQhT|5%`@yGBh~s7;A3P7I*&O=7GVHk-^IuM3)Y18`^Q< z=ta(FAmrI}(G2?D@PeF=yGTQgEO&3&G{E?wT+s-(`Kv(nzLJIG`+UXxr`~cLAdie=uL& zIOLwsFy6xZ(u=li8_LGK4YGdF%{_n1j!oP4Y#ws!M~2SYvU|&DN)}eqrEbrTog<96 zq0Ix^2X`%7HaNPhGCXv7Wyj9Z$^|>2SZ>kM-`}>4m;JtEk-1-T+=+NyvUAI3w{0iG zV94U{-m`1h&Jl*RgZjB-^JX`?Xz7WY-O!??Cy>E8OBQWkvS_pG+_0gSPR3=ZXT7qG zY#bw7wZ3S=ZUq zKd^3NcYoLV?sJ5a8&~#k+|W6&KH1Pe(6_#GW!LI++?k!{yry@4-bWt?%vYIy;NKvbU$N-@T@*e{EOKKwm#?vckH%@J%+X*=S##XRqJT zNlnPu0x~#Ifn=Tc>mjhKr>lQpRp-iX@0EC9k&XX8E7{PMtN=8YNqqvs%r|sKT0&)2 z=W69j(Uo;wRH0{0#R~20@7z$yr&yPCukPKju5;BC;iR(EU8?|Q*Xpiu$$NS$8@kr4 z?XRrZkgPnjv%f-tRJ^VT;&gYeo;FHaO4`)A^y@eDt^r<^mA&iM_ipT2RmtF8N&5A% zp?_TGrnpJT8AR44T|E{4_pRK}wZ4C{7*MvpmANP@dV9M&lb(T|-u|rLiIXPn>NzXv z?#jWfuL2}1HPmw}*LQF1qt-$Ow=#7Eq)A&-!=4nKlAKrQ*Azar%xgeM>qBGvI@fir z?Cn+`tX4;7fJ)<}`E2N9AOMRLano=$AoHxOOnPX0Wkn|q>+bG-4M?)$oJvyZ+1TA( zid}ZsXM#-NPJjLU6B|PZUEg^PXxq@4V}rE zmEMj0eGD4K=7|fUpcE6jLUGkR_i1e z9ZJ;?Oongq({{CL|A`q(26v{0E7V->V<0EdQ97~bK z!Qqi|pu0Afp^*v9!KL6#x(7BwGhJv1HCI=1x965%Xr&3zwp_&aYa9* z8~PLgKVY4kCG}sqW&+}keR&wI>s_@GI+ynn-AmDXJgKRyP5LU(Do9bXPV6X)nf61) zNcFmnef`8etMd?%J=H!$Y%y2LGk&}_gTYjNI#s^iy=%Hw0+pG?rUw0M!Hceyhf1(02xoc3>)qf&aRWFz&!!{$y3Xp< zhxKauk;CV+3CnQ*EJh9A>97i)@^L?x4Dn8wfXqm^rE0-Pyp z!^WO7dwO3J1P6LNYmW2eWS}M{GOL7RP0&WxBwVrwcr3y1p`xF7Da8u7^@ej8J0>%@wVh{Y z?sSZ09=$6WJ=s^t(*&y8h!9avKuIq_&>Ej_h#cfoBhH-?JdhM5aWELh#Y}Oq(v?a= zo^wDg^AoF8U8`5q3d&1mi_TZ)zSi)S5|UNDhz~Y&GB3{&6yM|>n}51YfX|{$%5)Im z(&^p!h#9u$07&sC!5fxD3Wo?tS|b+mr^)p zb@UW2O|@#{`ffM_y^uy62XGG@n;8e@oylr-o>~2BTs|#Bv@-><&^s$BClRD^sk}{f zCymq7xyF#7)?wYf)E%PiQWiTm+i#qLRZ zghi_cx={`d^sh}n*D!B{*Lt7z>zv1jp#2D6DQ-%Km8^3n17*X@#C%Q8Q;e<=Y*VO! z{e*R|97t+WfKgs!5avXc?qo%0md&_0MsF%V5Ss>8Fc8mlfyDU_$eVYhq|JXB(7iKYNGi|NWK(H~I+6M% zfUaEINzNfE!=-n_2IRv`#`aTguiJvmK*sa2{XE!MQa@}41%Rmvh?0^k(-SbZS9Wz} ze!dxLnPH4bJs}-M%Gfd$LSMxzlPXgrOM7$51X%$62T5JAaZOrufA5){Oazz$p-#$t zA!{fi#WjH#)Kq#GDFj}F)Xp@=ZAf0DxsjY{ZPV|x)rO=YPU;svnMJJC{Mu*Gov7U2 z)vl{&bq1dxX7+V<*ZjIxrZq&&zXrPDk5aw7!)tj;WRs~R)A zPM0x6TE%BtPuk=?0!|p(Ft|;oKuuN?B`V#f+DI!V;iujw9mwM+yQbg?v&FhBvIGb# zs3~i6%qdeC?xCqutvB>)>d?QoFP(`dpfS3atZCxw#@nTz&wK^Y?8CsbI>~zpFVi*} zeKaHwb7Rd_`fa97k9u)EjXMcto)E`V<;gQd58aJCszEm{XY|98jgVHSj+0K3D>i}d ze@)lQPRk2@#B>=>C@ae+Eiy$t$+>A$)%EFEFabCXNaxErNu(}3%RT9aF|0br*ESvS zE5W_2XR^-Ino7;r08#r)dsyo&H9^W4$v_WnPb-#Tnl;Poa??eGd_1)*tE2^_bV*WcB>sxvPFt?D`p#^!p@Vid{|24hf$ro)?+85Hs& zP}adF@~-WrtJA^lKj<1nUGJ`GKz}! zs-&U0T5B0;G9P=Q?pG@uXod65NB(g+5h+u6$UmqMx>jYt7j?)!(n-440A=2(B+K*) zqCorr(N}FmR{`x5q?!2CRA?F7=+k^iO4Q1#u0Es+tq~kfYU67YlS*n2bF!S^1YkQi zXry}98YHZ&Jfnj(F)PGYR)IpAK$b<%Ml%#KjNi28Ib|IrJ*RKCuCJ->9CEE&>FBj} z2@AO_V6%K&8LVvDHn@9tg%$0KcJ3Li4DP6Si;P#w+#=N?X2lPjn)Sm3g+*?Kd1AU# zrc8H=TY22Z{?$uPnV9J0DHENX6*e)|NmHgeX=3D;PZ{~;6C$>kQXSkqN;a-KvgN{yyldOg1>UiHba2z~`kiK$p*Y0egf&rc zZo@7jI4_{WmPuB}uFdwXN(QG{J%wty#TEC)R=0TzK;CsxC9~ccpcnqI)m3-x#F7F) zlLw#M7A<`#rY%cP*3T)I*-xvxr1lY9yD^Vyb-OW{@h%)`bX+eZb@1P15qJ1(Nz#+K zh+t*mxoEdcvoNJFclwqerVlSpzjJP1KdWT^r!}?iS@H@DIlP_Erk&e%j+}8J1|&OP zcbbn-Id}I(gS&>#7#Z3`pQpYU1x-kXIf;U+`tk5Pw-wX2N-!SEY*R2X8KL&7@p(JW z+fl7W!XD&|(eQaW)bNbWJN@ScJF#xs@&`j_oVc`A+4rnkVWXziy>W4?dmRrbfCblX z-!~`VQRQiIOAF5R9O2vvygxeMxtH?(huFE7@&3|mhY7rMcfG)29q-(o__O!HZ6*H6 zygyfU?iAjej&|-;-e>S$#`|K@oyPkH;-Aj@4|$)#`$)oH!TSeo&b^ZNhbzu4=l#K| za|!R~{+@Fyc)zXPxs|-%z!vz>hpTu zzdy^l0p914{tdj>9Oc{~@6SKix$}AVKM$DleqGhM&Ai`AzC*mf&HDo0ZTMfv`{lIv zBHl~+-oktRk@OAk&r{AY@AuN4ZSp7HcHRp}zk~PdsozfC&jn7qc;8C>F6RAJ+B?Gg zG5T*e?@MX#DDQs&FZS?0hJL?<_d@D>DenvMU)Jc{<)lB2_m%YT>Ad$*{u#W>wBr@L zze_z{$@@PkcRBADQqP3<>FRIZZ{WR>cO!850cqb&`9I|SCgAZX@2%wX|MPArlOJWC zCj8<3Pr@JGPf_n{snh$xgZJ@1oA*t;F(P(19qZgz$oGTfc>(?LA>NOW*8$$QfLE8( z#ma_bcL^Lm&Kr_g851XLjxU&rQTVi|0>x{v8;7i#lEoOg{&X{SD7a_+Lc7kC48J z@CyiA!*_*zR^fLuWxtZL-^2St+V&yJzz*82B;F$4-@yM4+VIajkJ2xz$?xxZf10#U z@V<-pQ#@~_E}sQfdvSk*_a6}dT|B?!``v`SpZ9&>;6)38A?ZHB^Elss$ag!>PkGMZ zS;X^gp0^Tq4ewv^KEV5So)6&u63-`iD%9h4%4q{eO?;2XjUQ2-@Z)W~j|2{j1vA=r zkY^6*L~zAoNJ}L_0;wG>J#d+mU?vHUd>xD72eIm{Y`M--+14^a~k;wCvT@5 z;o(g2u1sFS*|j|1U~E5!a$m-?h-U@Q@szugI-E@z>|%Du@_q$%coTj8CBAooALsBS zz$D`P5yJ1H4x_ZE1bQ^^H1T|npD#AUCwUa`Z!OLp^+yPWsW`b6smI;lSkPAet~x^wYwK;E!Lz{zGxfnk81&| z`Qw+cPZJi+B|qNBFhn2(`e|W=@W(Iz!EkrfQJm%WZ$z4%ep!STm;B{V$zeV@@je2= zfe4|W7RDKW{1Wzeit`+o{FwKP7|hPuPYZOOKYsaN>&;}vO0)xO`eG7zpK8NQ`Y!8zZ<{F>iseN^L76M-{b550Dk&wUgqH~q!d~Ssf0R09Km1R ze*}-ZSbd?fBP$aT=@8r?nRro)TcZDY{uLF0L zCtu$4`Br%^;8A(%`|DoM{D6G+)9F2Zqc0m6c~A->sI zd7Sbpe4ohk4DK{tzR%Kh`94#9*OEqlX?+8*)mADzU5h8Lv#PAV`+eRT!|ImwW z!lA+sulV13Y}!+5DmFHFaKJmBTo|#BFb0`4}5P7dNc;x7=wn6F{Z~D zV`GfzF~;;5V|t7+HpZCN)MAV=J;oRtV@!`R#>S4~S;)gU9%Jl|9mB&|9i#Zqfctk* z{#}%R7vlOo)@GEQ z;$U>I#W=awVVccGhjYx0*+8-eJJRG4ayy~MtNgx4&#^8$`z1?ut>4nMqbI*_%-ahj z`+uoZ6c$m;cAn#TmQ`~czw?NxDF#DBVW4R$=b?M59L_nsJ4~eix#;K$e(AFINHLxd4)(i(ZRZiB z)Ba5E*Djbg`=03wIW3OG&_YN+XYL|64vvQt;1y7xeFt+2ok;m4NZ^%lGAseDkW)Zu zA#$%GKNS)<4S0Fz>4(!Hg<)6$E1?9X7N~6ihM=xLh-0m~@m45JT~^hut4DgIf4-5= z8plQBSgU1pb&ei4SF_?(lFr>*{k?{}rU3zr$v)L${PFa2^-)?ea+s~^{ z5LS=eY~4n?X|t`WvHF>^(Zo$8*O&}FuZ09OshT`ZuqJmEtcEopA0l0oNKGG3rA}pI zC)96*^Hsw~=ece7_b8J~3dPT*{KJ-h+l2BzSYk z*t`%O39N&+!+N*~-U07~i=mqT$=F=lJkMsa@z61WCF3)jMRuo*rF*Td&w3w!~-2#R}_UO`FCxEGqb z&bU`Ax~_3oEn^;dncC`+S2hZxZ{oN|PljudS4>}m1a5#Y!&l&|uoZ5Euff+rHg4+@ z$J~W9lA3WWUs=!J;H2m85Tj3V^o`YR=C9H|GJkwOx3+DY`9omr{B1x+v2KF|z5zGE z&9EK53Aezv;8swqHyGQ~Dc9#}b@xNLGuHN;b&GZ4Ih*%#l#wQmb#%_wBL8jVzXJ(; z7jA>^!S~?@a69}E9^mOz@;~DE$M6&QDf|q64!;1!xykr2gK{0`PU;l*oJIVZH4<+$ z%pNRLUYw}XdV3JvX8htxA8)9XTNXbD9dEa>n9731hT@%d z+{48?I`{l8rsp2|{RI;EE6C@9dL_+QJ%5{2*Xiq27bU9X>t=MCxv}fHK_xTSPCID7 zm&3n70{4OZn|VA3q}}pwDhsKtzGp3VGLG+u1a`vT;UDl%cmVzd|Azm-gCPGlcJXg3 zb@F#4-fB-D^OCzTv-CEj#$-EkV`au(cjleY_UR#XCGcPPA85f(gXu5>X2KruD3DJP z{gmWGJ*N-jlP#Z=)*G9TMpr_47WtmA7tDseVIO!5JQn7FY;KyQ&DCZcWK&Oo8QJ5| zm5@K4{0T4@o(NBZePJFv8J+^NIiG$?yBjAqN8(&!Z0?7y1ReX6Kh@}6(@n3bGxHUX zY|}KQJB{|5*pAM6{`C-2@BCC~>e6$y@$(tR&u5Y!VEo+P#m_k>wtXM#=hUw;@^c&O=*=XZ`um^M z9>1oq9(5|4F^HCxLqojiRUd3fTDA{ErXC}=7HC{`hH1}`eV(y<2>J8j1;*~Bld)^! z(e$r`v!H+!UI$9Ldl-anZ5n#@D`5ya`<`stRImQy$w|+dAYChl#I@o&h|y7eiiw6I{HkT^o%Fd99P7ud62B^Db-_8`_&vPwb$`$UXA@*W(+DzpL|l{Zi3_9jn}dlu5P_2x^=HQU~K$b+TNY$x$H4} zA*qvnye~)e+;aJ$l`{TVmStOx zc#iJ`PUu8V>{_nvIwCWM2Y%>B zejHeV9XNp-c!3`TK^R0q99p3rI-whSp&tfe7)D_nS&-sv7YS5;5r?akMl3a;UJXTGLR)Syi`NMw%Pr(K!~Km;R;NFj8#}c#JGTqFv|FA2X`YX_{tfo)&4DwlXWTGbeL1 zFY~h?3$rNWGw&?R@~p_ptd(22ojbXkd%2$nd6-9eoTqt~=XsHrd8@DryKoA(@Cv^O zim-@^xJZkv$cv&Vi&klscIlLE>6LyNlwlc_ahaAG`*{{+S+-hCVT);KF_bNaqeVz9 z+-jk^MRR=~YYi)D9V=-qE9uKlO8UZ+lD_n$RDJPD2YmTS*~l8-FW$e#MGK^Y$c9&YpAsDdgwgwDFvaWaP%d`_4areBEhl7UUQyuDb5}JN7}rg)wcBFO=8Em-MZJ$Y7uKAPoSr7zJCv@n?Lg8? zmsR_d_G^RE1+pReK9~h#)znL#w$VK*P1`o=WpnYcV|CqDR1T1K zA|umB@#koe-k#HIy|z6tcn152wztNmrRPA}B!5gp-l9%=77yD_d(+ZJ2V|F+KF2ot z6pcRodZK@@)xUyY@#wX`iuqjHiA$ecRVP+Y? Date: Sat, 2 May 2026 15:13:29 -0400 Subject: [PATCH 2/2] Replace nwnsc subprocess with WASM compiler for diagnostics PR #62's intent was to migrate from spawning the native nwnsc binary to the in-process Beamdog nwn_script_comp; this commit accomplishes that goal but uses our WebAssembly build instead, which: - has multi-error recovery (one compile pass, every diagnostic in the file plus its #include'd helpers) - has no entry-point requirement (helper / include scripts can be edited and validated without a void main) - is ~210KB (vs 4-5MB native binary per platform) - works on every platform that runs Node, no separate Linux/Mac/ Windows binaries to ship DiagnosticsProvider rewritten: - Loads server/wasm/nwscript_compiler.{js,wasm} once on first use. - Per publish, creates a fresh compiler instance, sets collect-all-errors and require-entry-point=false, runs compile, drains the captured-error vector. - Resolver callback consults a per-call cache first then asks the workspace file system for any name the compiler requests, so nwscript.nss and #include'd files are picked up automatically. - Errors that fire inside an include are routed to the include's own URI (when we can resolve it via the workspace) rather than being attached to the file we were asked to check; the user sees the squiggle on the file that actually contains the bug. - Pre-seeds an empty diagnostic list for the target plus all transitive includes, so fixing an error clears the squiggle immediately. Removed: - spawn(child_process) machinery - getExecutablePath / hasSupportedOS - the WASM is platform-neutral - nwnsc command-line flag construction (-y -c -l -r -h -n -i) - stdout/stderr line-by-line parser (replaced by the collected-errors API) The compiler config keeps `enabled` and `verbose`; `os`, `nwnHome`, `nwnInstallation`, `reportWarnings` are now no-ops (kept in Config.ts for backwards-compat with any user settings.json that sets them). server/resources/compiler/{linux,mac,windows}/ binaries are no longer referenced; left in place so this commit can be reverted cleanly if the WASM approach hits a snag. --- server/src/Providers/DiagnosticsProvider.ts | 380 +++++++++++--------- server/wasm/nwscript_compiler.js | 4 +- server/wasm/nwscript_compiler.wasm | Bin 307952 -> 215005 bytes 3 files changed, 219 insertions(+), 165 deletions(-) diff --git a/server/src/Providers/DiagnosticsProvider.ts b/server/src/Providers/DiagnosticsProvider.ts index 7295e7a..7c94ee0 100644 --- a/server/src/Providers/DiagnosticsProvider.ts +++ b/server/src/Providers/DiagnosticsProvider.ts @@ -1,198 +1,252 @@ -import { spawn } from "child_process"; -import { type } from "os"; -import { join, dirname, basename } from "path"; -import { fileURLToPath } from "url"; +import { readFileSync } from "fs"; +import { basename, join } from "path"; +import { fileURLToPath, pathToFileURL } from "url"; import { Diagnostic, DiagnosticSeverity } from "vscode-languageserver"; +import { ServerManager } from "../ServerManager"; import Provider from "./Provider"; -const lineNumber = /\(([^)]+)\)/; -const lineMessage = /(Error|Warning):(.*)/; -const lineFilename = /^[^(]+/; +// Resource type IDs the NWN script compiler API expects. +const RT_NSS = 2009; +const RT_NCS = 2010; +const RT_NDB = 2064; -enum OS { - linux = "Linux", - mac = "Darwin", - windows = "Windows_NT", -} +// Diagnostic line format from the compiler: +// filename.nss(line): ERROR: MESSAGE [optional context] +// or, for some errors with no line attached: +// filename.nss: ERROR: MESSAGE +const LINE_RE = /^(?[^()]+?)(?:\((?\d+)\))?:\s*ERROR:\s*(?.+?)\s*$/m; type FilesDiagnostics = { [uri: string]: Diagnostic[] }; + export default class DiagnoticsProvider extends Provider { - private generateDiagnostics(uris: string[], files: FilesDiagnostics, severity: DiagnosticSeverity) { - return (line: string) => { - const uri = uris.find((uri) => basename(fileURLToPath(uri)) === lineFilename.exec(line)![0]); - - if (uri) { - const linePosition = Number(lineNumber.exec(line)![1]) - 1; - const diagnostic = { - severity, - range: { - start: { line: linePosition, character: 0 }, - end: { line: linePosition, character: Number.MAX_VALUE }, - }, - message: lineMessage.exec(line)![2].trim(), - }; - - files[uri].push(diagnostic); - } - }; - } + private modulePromise: Promise | null = null; - private hasSupportedOS() { - return ([...Object.values(OS).filter((item) => isNaN(Number(item)))] as string[]).includes(type()); + constructor(server: ServerManager) { + super(server); } - private getExecutablePath(os: OS | null) { - const specifiedOs = os || type(); - - switch (specifiedOs) { - case OS.linux: - return "../resources/compiler/linux/nwnsc"; - case OS.mac: - return "../resources/compiler/mac/nwnsc"; - case OS.windows: - return "../resources/compiler/windows/nwnsc.exe"; - default: - return ""; + /** Load the WASM module exactly once. */ + private async getModule(): Promise { + if (!this.modulePromise) { + const wasmPath = join(__dirname, "..", "..", "wasm", "nwscript_compiler.js"); + // eslint-disable-next-line @typescript-eslint/no-var-requires + const NWScriptCompiler = require(wasmPath); + this.modulePromise = NWScriptCompiler(); } + return this.modulePromise; } - // eslint-disable-next-line @typescript-eslint/promise-function-async - public publish(uri: string) { - return new Promise((resolve, reject) => { - const { enabled, nwnHome, reportWarnings, nwnInstallation, verbose, os } = this.server.config.compiler; - if (!enabled || uri.includes("nwscript.nss")) { - return resolve(true); - } - - if (!this.hasSupportedOS()) { - const errorMessage = "Unsupported OS. Cannot provide diagnostics."; - this.server.logger.error(errorMessage); - return reject(new Error(errorMessage)); - } - - const document = this.server.documentsCollection.getFromUri(uri); + /** + * Resolve a script name to its source bytes. Looks up `name` (no + * extension) via the workspace-file-system glob, returns null if + * not found or unreadable. + */ + private resolveScriptSource(name: string): string | null { + try { + const path = this.server.workspaceFilesSystem?.getFilePath(name); + if (!path) return null; + return readFileSync(path).toString(); + } catch { + return null; + } + } - if (!this.server.configLoaded || !document) { - if (!this.server.documentsWaitingForPublish.includes(uri)) { - this.server.documentsWaitingForPublish?.push(uri); + /** + * Run the WASM compiler over `uri` in collect-all-errors mode and + * record per-file diagnostics into `files`. + */ + private async compile(uri: string, files: FilesDiagnostics): Promise { + const Module = await this.getModule(); + + const filePath = fileURLToPath(uri); + const fileBaseName = basename(filePath, ".nss"); + + // The compiler hands us the bare filename (no extension); we map + // it back to source via the workspace, with the requested document + // taking precedence over a same-named file elsewhere in the tree. + const sources: { [name: string]: string } = {}; + sources[fileBaseName] = readFileSync(filePath).toString(); + + let compilerPtr = 0; + let deliveryBuf = 0; + let loadCb = 0; + let writeCb = 0; + const owned: number[] = []; + + try { + // Resolver: hand the compiler script source, looking it up in + // our local cache first then in the workspace. + loadCb = Module.addFunction((fnPtr: number) => { + try { + const fn = Module.UTF8ToString(fnPtr); + let src: string | null = sources[fn] ?? null; + if (src === null) { + src = this.resolveScriptSource(fn); + if (src !== null) sources[fn] = src; + } + if (src === null) return 0; + + const len = Module.lengthBytesUTF8(src); + if (deliveryBuf) Module._free(deliveryBuf); + deliveryBuf = Module._malloc(len + 1); + owned.push(deliveryBuf); + Module.stringToUTF8(src, deliveryBuf, len + 1); + Module._scriptCompApiDeliverFile(compilerPtr, deliveryBuf, len); + return 1; + } catch { + return 0; } - return resolve(true); + }, "iii"); + + // We don't care about output bytes; signal success so the + // compiler doesn't treat the write as an error. + writeCb = Module.addFunction(() => 0, "iiiiii"); + + const newCompiler = Module.cwrap("scriptCompApiNewCompiler", "number", + ["number", "number", "number", "number", "number"]); + const initCompiler = Module.cwrap("scriptCompApiInitCompiler", null, + ["number", "string", "boolean", "number", "number", "string"]); + const setCollectAll = Module.cwrap("scriptCompApiSetCollectAllErrors", + null, ["number", "boolean"]); + const setRequireEntry = Module.cwrap( + "scriptCompApiSetRequireEntryPoint", null, ["number", "boolean"]); + const compile = Module.cwrap("wasmCompile", "number", + ["number", "string"]); + const errorCount = Module.cwrap("wasmGetCollectedErrorCount", "number", + ["number"]); + const errorAt = Module.cwrap("wasmGetCollectedError", "string", + ["number", "number"]); + const lastError = Module.cwrap("wasmGetLastError", "string", ["number"]); + + compilerPtr = newCompiler(RT_NSS, RT_NCS, RT_NDB, writeCb, loadCb); + if (!compilerPtr) throw new Error("scriptCompApiNewCompiler returned null"); + + // writeDebug=false: we don't want NDB output. maxIncludeDepth=16 + // matches the historic compiler default. + initCompiler(compilerPtr, "nwscript", false, 16, 0, "scriptout"); + setCollectAll(compilerPtr, true); + // Allow files with no entry point (helper / include scripts) to + // validate cleanly - the LSP wants diagnostics on every editable + // file, not just main scripts. + setRequireEntry(compilerPtr, false); + + compile(compilerPtr, fileBaseName); + + const messages: string[] = []; + const n = errorCount(compilerPtr); + for (let i = 0; i < n; i++) { + messages.push(errorAt(compilerPtr, i)); + } + // Some hard-fail paths (e.g. file-not-found, lexer panic) bypass + // the multi-error vector and only report through the captured + // single-error string. Pick that up too. + if (messages.length === 0) { + const single = lastError(compilerPtr); + if (single) messages.push(single); } - const children = document.getChildren(); - const files: FilesDiagnostics = { [document.uri]: [] }; - const uris: string[] = []; - children.forEach((child) => { - const fileUri = this.server.documentsCollection?.get(child)?.uri; - if (fileUri) { - files[fileUri] = []; - uris.push(fileUri); + for (const raw of messages) { + for (const line of raw.split("\n")) { + const m = LINE_RE.exec(line); + if (!m) continue; + this.recordDiagnostic(uri, files, m.groups!); + break; } - }); - - if (verbose) { - this.server.logger.info(`Compiling ${document.uri}:`); - } - // The compiler command: - // - y; continue on error - // - c; compile includes - // - l; try to load resources if paths are not supplied - // - r; don't generate the compiled file - // - h; game home path - // - n; game installation path - // - i; includes directories - const args = ["-y", "-c", "-l", "-r", "SKIP_OUTPUT"]; - if (Boolean(nwnHome)) { - args.push("-h"); - args.push(`"${nwnHome}"`); - } else if (verbose) { - this.server.logger.info("Trying to resolve Neverwinter Nights home directory automatically."); - } - if (Boolean(nwnInstallation)) { - args.push("-n"); - args.push(`"${nwnInstallation}"`); - } else if (verbose) { - this.server.logger.info("Trying to resolve Neverwinter Nights installation directory automatically."); } - if (children.length > 0) { - args.push("-i"); - args.push(`"${[...new Set(uris.map((uri) => dirname(fileURLToPath(uri))))].join(";")}"`); + } finally { + if (compilerPtr) { + try { Module._scriptCompApiDestroyCompiler(compilerPtr); } + catch { /* ignore */ } } - args.push(`"${fileURLToPath(uri)}"`); - - let stdout = ""; - let stderr = ""; - - if (verbose) { - this.server.logger.info(this.getExecutablePath(os)); - this.server.logger.info(JSON.stringify(args, null, 4)); + for (const p of owned) { + try { Module._free(p); } catch { /* ignore */ } } + if (loadCb) Module.removeFunction(loadCb); + if (writeCb) Module.removeFunction(writeCb); + } + } - const child = spawn(join(__dirname, this.getExecutablePath(os)), args, { shell: true }); - - child.stdout.on("data", (chunk: string) => (stdout += chunk)); - child.stderr.on("data", (chunk: string) => (stderr += chunk)); - - child.on("error", (e: any) => { - this.server.logger.error(e.message); - reject(e); - }); + /** + * Map a parsed diagnostic line to an LSP Diagnostic and stash it + * under the right URI. Errors raised in #include'd files are routed + * to that file's URI when we can resolve it; otherwise they're + * attached to the document we were asked to check. + */ + private recordDiagnostic( + targetUri: string, + files: FilesDiagnostics, + parts: { [k: string]: string } + ) { + const file = (parts.file ?? "").trim(); + const line = Number(parts.line ?? "1"); + const message = (parts.message ?? "").trim(); + + let uri = targetUri; + const base = file.replace(/\.nss$/, ""); + const path = this.server.workspaceFilesSystem?.getFilePath(base); + if (path) uri = pathToFileURL(path).href; + + if (!files[uri]) files[uri] = []; + + const linePos = Math.max(0, line - 1); + files[uri].push({ + severity: DiagnosticSeverity.Error, + range: { + start: { line: linePos, character: 0 }, + end: { line: linePos, character: Number.MAX_VALUE }, + }, + message, + source: "nwscript", + }); + } - child.on("close", (_) => { - const lines = stdout - .toString() - .split("\n") - .filter((line) => line !== "\r" && line !== "\n" && Boolean(line)); - const errors: string[] = []; - const warnings: string[] = []; + public async publish(uri: string): Promise { + const { enabled, verbose } = this.server.config.compiler; + if (!enabled || uri.includes("nwscript.nss")) { + return true; + } - lines.forEach((line) => { - if (verbose && !line.includes("Compiling:")) { - this.server.logger.info(line); - } + const document = this.server.documentsCollection?.getFromUri(uri); + if (!this.server.configLoaded || !document) { + if (!this.server.documentsWaitingForPublish.includes(uri)) { + this.server.documentsWaitingForPublish?.push(uri); + } + return true; + } - // Diagnostics - if (line.includes("Error:")) { - errors.push(line); - } - if (reportWarnings && line.includes("Warning:")) { - warnings.push(line); - } + if (verbose) { + this.server.logger.info(`Compiling ${uri}`); + } - // Actual errors - if (line.includes("NOTFOUND")) { - return this.server.logger.error("Unable to resolve nwscript.nss. Are your Neverwinter Nights home and/or installation directories valid?"); - } - if (line.includes("Failed to open .key archive")) { - return this.server.logger.error("Unable to open nwn_base.key Is your Neverwinter Nights installation directory valid?"); - } - if (line.includes("Unable to read input file")) { - if (Boolean(nwnHome) || Boolean(nwnInstallation)) { - return this.server.logger.error("Unable to resolve provided Neverwinter Nights home and/or installation directories. Ensure the paths are valid in the extension settings."); - } else { - return this.server.logger.error("Unable to automatically resolve Neverwinter Nights home and/or installation directories."); - } - } - }); + // Pre-seed empty diagnostic lists for the target plus all of its + // transitive includes - so that fixing an error in an include + // immediately clears any prior squiggle on it. + const files: FilesDiagnostics = { [uri]: [] }; + for (const child of document.getChildren()) { + const childUri = this.server.documentsCollection?.get(child)?.uri; + if (childUri) files[childUri] = []; + } - if (verbose) { - this.server.logger.info("Done.\n"); - } + try { + await this.compile(uri, files); + } catch (e: any) { + this.server.logger.error(`Compile failed: ${e?.message ?? e}`); + } - uris.push(document.uri); - errors.forEach(this.generateDiagnostics(uris, files, DiagnosticSeverity.Error)); - if (reportWarnings) warnings.forEach(this.generateDiagnostics(uris, files, DiagnosticSeverity.Warning)); + for (const [u, diagnostics] of Object.entries(files)) { + this.server.connection.sendDiagnostics({ uri: u, diagnostics }); + } - for (const [uri, diagnostics] of Object.entries(files)) { - void this.server.connection.sendDiagnostics({ uri, diagnostics }); - } - resolve(true); - }); - }); + if (verbose) { + this.server.logger.info("Done."); + } + return true; } public async processDocumentsWaitingForPublish() { - return await Promise.all(this.server.documentsWaitingForPublish.map(async (uri) => await this.publish(uri))); + return await Promise.all( + this.server.documentsWaitingForPublish.map(async (uri) => await this.publish(uri)) + ); } } diff --git a/server/wasm/nwscript_compiler.js b/server/wasm/nwscript_compiler.js index 861b1ab..4aee334 100644 --- a/server/wasm/nwscript_compiler.js +++ b/server/wasm/nwscript_compiler.js @@ -1,2 +1,2 @@ -async function NWScriptCompiler(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=true;var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName;if(typeof __filename!="undefined"){_scriptName=__filename}else{}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("node:fs");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");var readyPromiseResolve,readyPromiseReject;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.initialized)FS.init();TTY.init();wasmExports["__wasm_call_ctors"]();FS.ignorePermissions=false}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("nwscript_compiler.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={env:wasmImports,wasi_snapshot_preview1:wasmImports};return imports}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(inst,mod)=>{resolve(receiveInstance(inst,mod))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var ___assert_fail=(condition,filename,line,func)=>abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"]);class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var syscallGetVarargI=()=>{var ret=HEAP32[+SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret};var syscallGetVarargP=syscallGetVarargI;var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.slice(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.slice(0,-1)}return root+dir},basename:path=>path&&path.match(/([^\/]+|\/)\/*$/)[1],join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(ENVIRONMENT_IS_NODE){var nodeCrypto=require("node:crypto");return view=>nodeCrypto.randomFillSync(view)}return view=>crypto.getRandomValues(view)};var randomFill=view=>{(randomFill=initRandomFill())(view)};var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).slice(1);to=PATH_FS.resolve(to).slice(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var intArrayFromString=(stringy,dontAddNull,length)=>{var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array};var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf,0,BUFSIZE)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output?.length>0){err(UTF8ArrayToString(tty.output));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16895,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.atime=node.mtime=node.ctime=Date.now();if(parent){parent.contents[name]=node;parent.atime=parent.mtime=parent.ctime=node.atime}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.atime);attr.mtime=new Date(node.mtime);attr.ctime=new Date(node.ctime);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){for(const key of["mode","atime","mtime","ctime"]){if(attr[key]!=null){node[key]=attr[key]}}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){if(!MEMFS.doesNotExistError){MEMFS.doesNotExistError=new FS.ErrnoError(44);MEMFS.doesNotExistError.stack=""}throw MEMFS.doesNotExistError},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){if(FS.isDir(old_node.mode)){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}FS.hashRemoveNode(new_node)}delete old_node.parent.contents[old_node.name];new_dir.contents[new_name]=old_node;old_node.name=new_name;new_dir.ctime=new_dir.mtime=old_node.parent.ctime=old_node.parent.mtime=Date.now()},unlink(parent,name){delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},readdir(node){return[".","..",...Object.keys(node.contents)]},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var asyncLoad=async url=>{var arrayBuffer=await readAsync(url);return new Uint8Array(arrayBuffer)};var FS_createDataFile=(...args)=>FS.createDataFile(...args);var getUniqueRunDependency=id=>id;var runDependencies=0;var dependenciesFulfilled=null;var removeRunDependency=id=>{runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}};var addRunDependency=id=>{runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)};var preloadPlugins=[];var FS_handledByPreloadPlugin=async(byteArray,fullname)=>{if(typeof Browser!="undefined")Browser.init();for(var plugin of preloadPlugins){if(plugin["canHandle"](fullname)){return plugin["handle"](byteArray,fullname)}}return byteArray};var FS_preloadFile=async(parent,name,url,canRead,canWrite,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);addRunDependency(dep);try{var byteArray=url;if(typeof url=="string"){byteArray=await asyncLoad(url)}byteArray=await FS_handledByPreloadPlugin(byteArray,fullname);preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}}finally{removeRunDependency(dep)}};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{FS_preloadFile(parent,name,url,canRead,canWrite,dontCreateFile,canOwn,preFinish).then(onload).catch(onerror)};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,filesystems:null,syncFSRequests:0,readFiles:{},ErrnoError:class{name="ErrnoError";constructor(errno){this.errno=errno}},FSStream:class{shared={};get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{node_ops={};stream_ops={};readMode=292|73;writeMode=146;mounted=null;constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.rdev=rdev;this.atime=this.mtime=this.ctime=Date.now()}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){if(!path){throw new FS.ErrnoError(44)}opts.follow_mount??=true;if(!PATH.isAbs(path)){path=FS.cwd()+"/"+path}linkloop:for(var nlinks=0;nlinks<40;nlinks++){var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){if(!FS.isDir(dir.mode)){return 54}try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&(512|64)){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},checkOpExists(op,err){if(!op){throw new FS.ErrnoError(err)}return op},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},doSetAttr(stream,node,attr){var setattr=stream?.stream_ops.setattr;var arg=setattr?stream:node;setattr??=node.node_ops.setattr;FS.checkOpExists(setattr,63);setattr(arg,attr)},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}for(var mount of mounts){if(mount.type.syncfs){mount.type.syncfs(mount,populate,done)}else{done(null)}}},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type,opts,mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);for(var[hash,current]of Object.entries(FS.nameTable)){while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}}node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name){throw new FS.ErrnoError(28)}if(name==="."||name===".."){throw new FS.ErrnoError(20)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},statfs(path){return FS.statfsNode(FS.lookupPath(path,{follow:true}).node)},statfsStream(stream){return FS.statfsNode(stream.node)},statfsNode(node){var rtn={bsize:4096,frsize:4096,blocks:1e6,bfree:5e5,bavail:5e5,files:FS.nextInode,ffree:FS.nextInode-1,fsid:42,flags:2,namelen:255};if(node.node_ops.statfs){Object.assign(rtn,node.node_ops.statfs(node.mount.opts.root))}return rtn},create(path,mode=438){mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode=511){mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var dir of dirs){if(!dir)continue;if(d||PATH.isAbs(path))d+="/";d+=dir;try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev(path,mode,dev){if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name);old_node.parent=new_dir}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var readdir=FS.checkOpExists(node.node_ops.readdir,54);return readdir(node)},unlink(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return link.node_ops.readlink(link)},stat(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;var getattr=FS.checkOpExists(node.node_ops.getattr,63);return getattr(node)},fstat(fd){var stream=FS.getStreamChecked(fd);var node=stream.node;var getattr=stream.stream_ops.getattr;var arg=getattr?stream:node;getattr??=node.node_ops.getattr;FS.checkOpExists(getattr,63);return getattr(arg)},lstat(path){return FS.stat(path,true)},doChmod(stream,node,mode,dontFollow){FS.doSetAttr(stream,node,{mode:mode&4095|node.mode&~4095,ctime:Date.now(),dontFollow})},chmod(path,mode,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChmod(null,node,mode,dontFollow)},lchmod(path,mode){FS.chmod(path,mode,true)},fchmod(fd,mode){var stream=FS.getStreamChecked(fd);FS.doChmod(stream,stream.node,mode,false)},doChown(stream,node,dontFollow){FS.doSetAttr(stream,node,{timestamp:Date.now(),dontFollow})},chown(path,uid,gid,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChown(null,node,dontFollow)},lchown(path,uid,gid){FS.chown(path,uid,gid,true)},fchown(fd,uid,gid){var stream=FS.getStreamChecked(fd);FS.doChown(stream,stream.node,false)},doTruncate(stream,node,len){if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}FS.doSetAttr(stream,node,{size:len,timestamp:Date.now()})},truncate(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}FS.doTruncate(null,node,len)},ftruncate(fd,len){var stream=FS.getStreamChecked(fd);if(len<0||(stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.doTruncate(stream,stream.node,len)},utime(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var setattr=FS.checkOpExists(node.node_ops.setattr,63);setattr(node,{atime,mtime})},open(path,flags,mode=438){if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS_modeStringToFlags(flags):flags;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;var isDirPath;if(typeof path=="object"){node=path}else{isDirPath=path.endsWith("/");var lookup=FS.lookupPath(path,{follow:!(flags&131072),noent_okay:true});node=lookup.node;path=lookup.path}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else if(isDirPath){throw new FS.ErrnoError(31)}else{node=FS.mknod(path,mode|511,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node,path:FS.getPath(node),flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(created){FS.chmod(node,mode&511)}if(Module["logReadFiles"]&&!(flags&1)){if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed(stream){return stream.fd===null},llseek(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},mmap(stream,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}if(!length){throw new FS.ErrnoError(28)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync(stream,buffer,offset,length,mmapFlags){if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){abort(`Invalid encoding type "${opts.encoding}"`)}var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){buf=UTF8ArrayToString(buf)}FS.close(stream);return buf},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){data=new Uint8Array(intArrayFromString(data,true))}if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{abort("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length,llseek:()=>0});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomFill(randomBuffer);randomLeft=randomBuffer.byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16895,73);node.stream_ops={llseek:MEMFS.stream_ops.llseek};node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path},id:fd+1};ret.parent=ret;return ret},readdir(){return Array.from(FS.streams.entries()).filter(([k,v])=>v).map(([k,v])=>k.toString())}};return node}},{},"/proc/self/fd")},createStandardStreams(input,output,error){if(input){FS.createDevice("/dev","stdin",input)}else{FS.symlink("/dev/tty","/dev/stdin")}if(output){FS.createDevice("/dev","stdout",null,output)}else{FS.symlink("/dev/tty","/dev/stdout")}if(error){FS.createDevice("/dev","stderr",null,error)}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS}},init(input,output,error){FS.initialized=true;input??=Module["stdin"];output??=Module["stdout"];error??=Module["stderr"];FS.createStandardStreams(input,output,error)},quit(){FS.initialized=false;for(var stream of FS.streams){if(stream){FS.close(stream)}}},findObject(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath(parent,path,canRead,canWrite){parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){if(e.errno!=20)throw e}parent=current}return current},createFile(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile(parent,name,data,canRead,canWrite,canOwn){var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))abort("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)abort("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)abort("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))abort("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")abort("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(globalThis.XMLHttpRequest){if(!ENVIRONMENT_IS_WORKER)abort("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};for(const[key,fn]of Object.entries(node.stream_ops)){stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}}function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var SYSCALLS={calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return dir+"/"+path},writeStat(buf,stat){HEAPU32[buf>>2]=stat.dev;HEAPU32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAPU32[buf+12>>2]=stat.uid;HEAPU32[buf+16>>2]=stat.gid;HEAPU32[buf+20>>2]=stat.rdev;HEAP64[buf+24>>3]=BigInt(stat.size);HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();HEAP64[buf+40>>3]=BigInt(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3*1e3;HEAP64[buf+56>>3]=BigInt(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3*1e3;HEAP64[buf+72>>3]=BigInt(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3*1e3;HEAP64[buf+88>>3]=BigInt(stat.ino);return 0},writeStatFs(buf,stats){HEAPU32[buf+4>>2]=stats.bsize;HEAPU32[buf+60>>2]=stats.bsize;HEAP64[buf+8>>3]=BigInt(stats.blocks);HEAP64[buf+16>>3]=BigInt(stats.bfree);HEAP64[buf+24>>3]=BigInt(stats.bavail);HEAP64[buf+32>>3]=BigInt(stats.files);HEAP64[buf+40>>3]=BigInt(stats.ffree);HEAPU32[buf+48>>2]=stats.fsid;HEAPU32[buf+64>>2]=stats.flags;HEAPU32[buf+56>>2]=stats.namelen},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=syscallGetVarargI();if(arg<0){return-28}while(FS.streams[arg]){arg++}var newStream;newStream=FS.dupStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=syscallGetVarargI();stream.flags|=arg;return 0}case 12:{var arg=syscallGetVarargP();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0}return-28}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=syscallGetVarargP();HEAP32[argp>>2]=termios.c_iflag||0;HEAP32[argp+4>>2]=termios.c_oflag||0;HEAP32[argp+8>>2]=termios.c_cflag||0;HEAP32[argp+12>>2]=termios.c_lflag||0;for(var i=0;i<32;i++){HEAP8[argp+i+17]=termios.c_cc[i]||0}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=syscallGetVarargP();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag,c_oflag,c_cflag,c_lflag,c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=syscallGetVarargP();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21537:case 21531:{var argp=syscallGetVarargP();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=syscallGetVarargP();HEAP16[argp>>1]=winsize[0];HEAP16[argp+2>>1]=winsize[1]}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?syscallGetVarargI():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var __abort_js=()=>abort("");var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var MONTH_DAYS_LEAP_CUMULATIVE=[0,31,60,91,121,152,182,213,244,274,305,335];var MONTH_DAYS_REGULAR_CUMULATIVE=[0,31,59,90,120,151,181,212,243,273,304,334];var ydayFromDate=date=>{var leap=isLeapYear(date.getFullYear());var monthDaysCumulative=leap?MONTH_DAYS_LEAP_CUMULATIVE:MONTH_DAYS_REGULAR_CUMULATIVE;var yday=monthDaysCumulative[date.getMonth()]+date.getDate()-1;return yday};var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>numINT53_MAX?NaN:Number(num);function __localtime_js(time,tmPtr){time=bigintToI53Checked(time);var date=new Date(time*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var yday=ydayFromDate(date)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst}var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var __tzset_js=(timezone,daylight,std_name,dst_name)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);var extractZone=timezoneOffset=>{var sign=timezoneOffset>=0?"-":"+";var absOffset=Math.abs(timezoneOffset);var hours=String(Math.floor(absOffset/60)).padStart(2,"0");var minutes=String(absOffset%60).padStart(2,"0");return`UTC${sign}${hours}${minutes}`};var winterName=extractZone(winterOffset);var summerName=extractZone(summerOffset);if(summerOffsetDate.now();var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(globalThis.navigator?.language??"C").replace("-","_")+".UTF-8";var env={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:lang,_:getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;var envp=0;for(var string of getEnvStrings()){var ptr=environ_buf+bufSize;HEAPU32[__environ+envp>>2]=ptr;bufSize+=stringToUTF8(string,ptr,Infinity)+1;envp+=4}return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;for(var string of strings){bufSize+=lengthBytesUTF8(string)+1}HEAPU32[penviron_buf_size>>2]=bufSize;return 0};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);HEAP64[newOffset>>3]=BigInt(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};var wasmTableMirror=[];var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var updateTableMap=(offset,count)=>{if(functionsInTableMap){for(var i=offset;i{if(!functionsInTableMap){functionsInTableMap=new WeakMap;updateTableMap(0,wasmTable.length)}return functionsInTableMap.get(func)||0};var freeTableIndexes=[];var getEmptyTableSlot=()=>{if(freeTableIndexes.length){return freeTableIndexes.pop()}return wasmTable["grow"](1)};var setWasmTableEntry=(idx,func)=>{wasmTable.set(idx,func);wasmTableMirror[idx]=wasmTable.get(idx)};var uleb128EncodeWithLen=arr=>{const n=arr.length;return[n%128|128,n>>7,...arr]};var wasmTypeCodes={i:127,p:127,j:126,f:125,d:124,e:111};var generateTypePack=types=>uleb128EncodeWithLen(Array.from(types,type=>{var code=wasmTypeCodes[type];return code}));var convertJsFunctionToWasm=(func,sig)=>{var bytes=Uint8Array.of(0,97,115,109,1,0,0,0,1,...uleb128EncodeWithLen([1,96,...generateTypePack(sig.slice(1)),...generateTypePack(sig[0]==="v"?"":sig[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);var module=new WebAssembly.Module(bytes);var instance=new WebAssembly.Instance(module,{e:{f:func}});var wrappedFunc=instance.exports["f"];return wrappedFunc};var addFunction=(func,sig)=>{var rtn=getFunctionAddress(func);if(rtn){return rtn}var ret=getEmptyTableSlot();try{setWasmTableEntry(ret,func)}catch(err){if(!(err instanceof TypeError)){throw err}var wrapped=convertJsFunctionToWasm(func,sig);setWasmTableEntry(ret,wrapped)}functionsInTableMap.set(func,ret);return ret};FS.createPreloadedFile=FS_createPreloadedFile;FS.preloadFile=FS_preloadFile;FS.staticInit();{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["preloadPlugins"])preloadPlugins=Module["preloadPlugins"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["addFunction"]=addFunction;Module["UTF8ToString"]=UTF8ToString;Module["stringToUTF8"]=stringToUTF8;Module["lengthBytesUTF8"]=lengthBytesUTF8;var _free,_scriptCompApiGetABIVersion,_scriptCompApiNewCompiler,_scriptCompApiInitCompiler,_scriptCompApiCompileFile,_scriptCompApiDeliverFile,_scriptCompApiGetOptimizationFlags,_scriptCompApiSetOptimizationFlags,_scriptCompApiSetGenerateDebuggerOutput,_scriptCompApiCompileFileSimple,_scriptCompApiGetLastError,_scriptCompApiGetParseTreeJSON,_scriptCompApiDestroyCompiler,_malloc,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,memory,__indirect_function_table,wasmMemory,wasmTable;function assignWasmExports(wasmExports){_free=Module["_free"]=wasmExports["free"];_scriptCompApiGetABIVersion=Module["_scriptCompApiGetABIVersion"]=wasmExports["scriptCompApiGetABIVersion"];_scriptCompApiNewCompiler=Module["_scriptCompApiNewCompiler"]=wasmExports["scriptCompApiNewCompiler"];_scriptCompApiInitCompiler=Module["_scriptCompApiInitCompiler"]=wasmExports["scriptCompApiInitCompiler"];_scriptCompApiCompileFile=Module["_scriptCompApiCompileFile"]=wasmExports["scriptCompApiCompileFile"];_scriptCompApiDeliverFile=Module["_scriptCompApiDeliverFile"]=wasmExports["scriptCompApiDeliverFile"];_scriptCompApiGetOptimizationFlags=Module["_scriptCompApiGetOptimizationFlags"]=wasmExports["scriptCompApiGetOptimizationFlags"];_scriptCompApiSetOptimizationFlags=Module["_scriptCompApiSetOptimizationFlags"]=wasmExports["scriptCompApiSetOptimizationFlags"];_scriptCompApiSetGenerateDebuggerOutput=Module["_scriptCompApiSetGenerateDebuggerOutput"]=wasmExports["scriptCompApiSetGenerateDebuggerOutput"];_scriptCompApiCompileFileSimple=Module["_scriptCompApiCompileFileSimple"]=wasmExports["scriptCompApiCompileFileSimple"];_scriptCompApiGetLastError=Module["_scriptCompApiGetLastError"]=wasmExports["scriptCompApiGetLastError"];_scriptCompApiGetParseTreeJSON=Module["_scriptCompApiGetParseTreeJSON"]=wasmExports["scriptCompApiGetParseTreeJSON"];_scriptCompApiDestroyCompiler=Module["_scriptCompApiDestroyCompiler"]=wasmExports["scriptCompApiDestroyCompiler"];_malloc=Module["_malloc"]=wasmExports["malloc"];__emscripten_stack_restore=wasmExports["_emscripten_stack_restore"];__emscripten_stack_alloc=wasmExports["_emscripten_stack_alloc"];_emscripten_stack_get_current=wasmExports["emscripten_stack_get_current"];memory=wasmMemory=wasmExports["memory"];__indirect_function_table=wasmTable=wasmExports["__indirect_function_table"]}var wasmImports={__assert_fail:___assert_fail,__cxa_throw:___cxa_throw,__syscall_fcntl64:___syscall_fcntl64,__syscall_ioctl:___syscall_ioctl,__syscall_openat:___syscall_openat,_abort_js:__abort_js,_localtime_js:__localtime_js,_tzset_js:__tzset_js,emscripten_date_now:_emscripten_date_now,emscripten_resize_heap:_emscripten_resize_heap,environ_get:_environ_get,environ_sizes_get:_environ_sizes_get,fd_close:_fd_close,fd_read:_fd_read,fd_seek:_fd_seek,fd_write:_fd_write};function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}var wasmExports;wasmExports=await (createWasm());run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})} -;return moduleRtn}if(typeof exports==="object"&&typeof module==="object"){module.exports=NWScriptCompiler;module.exports.default=NWScriptCompiler}else if(typeof define==="function"&&define["amd"])define([],()=>NWScriptCompiler); +var NWScriptCompiler=(()=>{var _scriptName=globalThis.document?.currentScript?.src;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=!!globalThis.window;var ENVIRONMENT_IS_WORKER=!!globalThis.WorkerGlobalScope;var ENVIRONMENT_IS_NODE=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename}else{}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("node:fs");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");class EmscriptenEH{}class EmscriptenSjLj extends EmscriptenEH{}var readyPromiseResolve,readyPromiseReject;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.initialized)FS.init();TTY.init();wasmExports["__wasm_call_ctors"]();FS.ignorePermissions=false}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what=`Aborted(${what})`;err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("nwscript_compiler.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={env:wasmImports,wasi_snapshot_preview1:wasmImports};return imports}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(inst,mod)=>{resolve(receiveInstance(inst,mod))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var HEAP16;var HEAP32;var HEAP64;var HEAP8;var HEAPF32;var HEAPF64;var HEAPU16;var HEAPU32;var HEAPU64;var HEAPU8;var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var ___assert_fail=(condition,filename,line,func)=>abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"]);class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);uncaughtExceptionCount++;abort()};var syscallGetVarargI=()=>{var ret=HEAP32[+SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret};var syscallGetVarargP=syscallGetVarargI;var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.slice(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.slice(0,-1)}return root+dir},basename:path=>path&&path.match(/([^\/]+|\/)\/*$/)[1],join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(ENVIRONMENT_IS_NODE){var nodeCrypto=require("node:crypto");return view=>nodeCrypto.randomFillSync(view)}return view=>(crypto.getRandomValues(view),0)};var randomFill=view=>(randomFill=initRandomFill())(view);var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).slice(1);to=PATH_FS.resolve(to).slice(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var intArrayFromString=(stringy,dontAddNull,length)=>{var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array};var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf,0,BUFSIZE)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}}else if(globalThis.window?.prompt){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output?.length>0){err(UTF8ArrayToString(tty.output));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16895,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=MEMFS.emptyFileContents??=new Uint8Array(0)}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.atime=node.mtime=node.ctime=Date.now();if(parent){parent.contents[name]=node;parent.atime=parent.mtime=parent.ctime=node.atime}return node},getFileDataAsTypedArray(node){return node.contents.subarray(0,node.usedBytes)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents.length;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity)newCapacity=Math.max(newCapacity,256);var oldContents=MEMFS.getFileDataAsTypedArray(node);node.contents=new Uint8Array(newCapacity);node.contents.set(oldContents)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;var oldContents=node.contents;node.contents=new Uint8Array(newSize);node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)));node.usedBytes=newSize},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.atime);attr.mtime=new Date(node.mtime);attr.ctime=new Date(node.ctime);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){for(const key of["mode","atime","mtime","ctime"]){if(attr[key]!=null){node[key]=attr[key]}}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){if(!MEMFS.doesNotExistError){MEMFS.doesNotExistError=new FS.ErrnoError(44);MEMFS.doesNotExistError.stack=""}throw MEMFS.doesNotExistError},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){if(FS.isDir(old_node.mode)){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}FS.hashRemoveNode(new_node)}delete old_node.parent.contents[old_node.name];new_dir.contents[new_name]=old_node;old_node.name=new_name;new_dir.ctime=new_dir.mtime=old_node.parent.ctime=old_node.parent.mtime=Date.now()},unlink(parent,name){delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.ctime=parent.mtime=Date.now()},readdir(node){return[".","..",...Object.keys(node.contents)]},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);buffer.set(contents.subarray(position,position+size),offset);return size},write(stream,buffer,offset,length,position,canOwn){if(buffer.buffer===HEAP8.buffer){canOwn=false}if(!length)return 0;var node=stream.node;node.mtime=node.ctime=Date.now();if(canOwn){node.contents=buffer.subarray(offset,offset+length);node.usedBytes=length}else if(node.usedBytes===0&&position===0){node.contents=buffer.slice(offset,offset+length);node.usedBytes=length}else{MEMFS.expandFileStorage(node,position+length);node.contents.set(buffer.subarray(offset,offset+length),position);node.usedBytes=Math.max(node.usedBytes,position+length)}return length},llseek(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){position+=stream.node.usedBytes}}if(position<0){throw new FS.ErrnoError(28)}return position},mmap(stream,length,position,prot,flags){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}var ptr;var allocated;var contents=stream.node.contents;if(!(flags&2)&&contents.buffer===HEAP8.buffer){allocated=false;ptr=contents.byteOffset}else{allocated=true;ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}if(contents){if(position>0||position+length{if(typeof str!="string")return str;var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_fileDataToTypedArray=data=>{if(typeof data=="string"){data=intArrayFromString(data,true)}if(!data.subarray){data=new Uint8Array(data)}return data};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var asyncLoad=async url=>{var arrayBuffer=await readAsync(url);return new Uint8Array(arrayBuffer)};var FS_createDataFile=(...args)=>FS.createDataFile(...args);var getUniqueRunDependency=id=>id;var runDependencies=0;var dependenciesFulfilled=null;var removeRunDependency=id=>{runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}};var addRunDependency=id=>{runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)};var preloadPlugins=[];var FS_handledByPreloadPlugin=async(byteArray,fullname)=>{if(typeof Browser!="undefined")Browser.init();for(var plugin of preloadPlugins){if(plugin["canHandle"](fullname)){return plugin["handle"](byteArray,fullname)}}return byteArray};var FS_preloadFile=async(parent,name,url,canRead,canWrite,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);addRunDependency(dep);try{var byteArray=url;if(typeof url=="string"){byteArray=await asyncLoad(url)}byteArray=await FS_handledByPreloadPlugin(byteArray,fullname);preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}}finally{removeRunDependency(dep)}};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{FS_preloadFile(parent,name,url,canRead,canWrite,dontCreateFile,canOwn,preFinish).then(onload).catch(onerror)};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,filesystems:null,syncFSRequests:0,ErrnoError:class{name="ErrnoError";constructor(errno){this.errno=errno}},FSStream:class{shared={};get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{node_ops={};stream_ops={};readMode=292|73;writeMode=146;mounted=null;constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.rdev=rdev;this.atime=this.mtime=this.ctime=Date.now()}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){if(!path){throw new FS.ErrnoError(44)}opts.follow_mount??=true;if(!PATH.isAbs(path)){path=FS.cwd()+"/"+path}linkloop:for(var nlinks=0;nlinks<40;nlinks++){var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}if(perms.includes("w")&&!(node.mode&146)){return 2}if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){if(!FS.isDir(dir.mode)){return 54}try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else if(FS.isDir(node.mode)){return 31}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}var mode=FS.flagsToPermissionString(flags);if(FS.isDir(node.mode)){if(mode!=="r"||flags&(512|64)){return 31}}return FS.nodePermissions(node,mode)},checkOpExists(op,err){if(!op){throw new FS.ErrnoError(err)}return op},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},doSetAttr(stream,node,attr){var setattr=stream?.stream_ops.setattr;var arg=setattr?stream:node;setattr??=node.node_ops.setattr;FS.checkOpExists(setattr,63);try{setattr(arg,attr)}catch(e){if(e instanceof RangeError){throw new FS.ErrnoError(22)}throw e}},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}for(var mount of mounts){if(mount.type.syncfs){mount.type.syncfs(mount,populate,done)}else{done(null)}}},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type,opts,mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);for(var[hash,current]of Object.entries(FS.nameTable)){while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}}node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name){throw new FS.ErrnoError(28)}if(name==="."||name===".."){throw new FS.ErrnoError(20)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},statfs(path){return FS.statfsNode(FS.lookupPath(path,{follow:true}).node)},statfsStream(stream){return FS.statfsNode(stream.node)},statfsNode(node){var rtn={bsize:4096,frsize:4096,blocks:1e6,bfree:5e5,bavail:5e5,files:FS.nextInode,ffree:FS.nextInode-1,fsid:42,flags:2,namelen:255};if(node.node_ops.statfs){Object.assign(rtn,node.node_ops.statfs(node.mount.opts.root))}return rtn},create(path,mode=438){mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode=511){mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var dir of dirs){if(!dir)continue;if(d||PATH.isAbs(path))d+="/";d+=dir;try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev(path,mode,dev){if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name);old_node.parent=new_dir}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var readdir=FS.checkOpExists(node.node_ops.readdir,54);return readdir(node)},unlink(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return link.node_ops.readlink(link)},stat(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;var getattr=FS.checkOpExists(node.node_ops.getattr,63);return getattr(node)},fstat(fd){var stream=FS.getStreamChecked(fd);var node=stream.node;var getattr=stream.stream_ops.getattr;var arg=getattr?stream:node;getattr??=node.node_ops.getattr;FS.checkOpExists(getattr,63);return getattr(arg)},lstat(path){return FS.stat(path,true)},doChmod(stream,node,mode,dontFollow){FS.doSetAttr(stream,node,{mode:mode&4095|node.mode&~4095,ctime:Date.now(),dontFollow})},chmod(path,mode,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChmod(null,node,mode,dontFollow)},lchmod(path,mode){FS.chmod(path,mode,true)},fchmod(fd,mode){var stream=FS.getStreamChecked(fd);FS.doChmod(stream,stream.node,mode,false)},doChown(stream,node,dontFollow){FS.doSetAttr(stream,node,{timestamp:Date.now(),dontFollow})},chown(path,uid,gid,dontFollow){var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}FS.doChown(null,node,dontFollow)},lchown(path,uid,gid){FS.chown(path,uid,gid,true)},fchown(fd,uid,gid){var stream=FS.getStreamChecked(fd);FS.doChown(stream,stream.node,false)},doTruncate(stream,node,len){if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}FS.doSetAttr(stream,node,{size:len,timestamp:Date.now()})},truncate(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}FS.doTruncate(null,node,len)},ftruncate(fd,len){var stream=FS.getStreamChecked(fd);if(len<0||(stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.doTruncate(stream,stream.node,len)},utime(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;var setattr=FS.checkOpExists(node.node_ops.setattr,63);setattr(node,{atime,mtime})},open(path,flags,mode=438){if(path===""){throw new FS.ErrnoError(44)}flags=FS_modeStringToFlags(flags);if(flags&64){mode=mode&4095|32768}else{mode=0}var node;var isDirPath;if(typeof path=="object"){node=path}else{isDirPath=path.endsWith("/");var lookup=FS.lookupPath(path,{follow:!(flags&131072),noent_okay:true});node=lookup.node;path=lookup.path}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else if(isDirPath){throw new FS.ErrnoError(31)}else{node=FS.mknod(path,mode|511,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node,path:FS.getPath(node),flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(created){FS.chmod(node,mode&511)}return stream},close(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed(stream){return stream.fd===null},llseek(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},mmap(stream,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}if(!length){throw new FS.ErrnoError(28)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync(stream,buffer,offset,length,mmapFlags){if(!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){abort(`Invalid encoding type "${opts.encoding}"`)}var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){buf=UTF8ArrayToString(buf)}FS.close(stream);return buf},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);data=FS_fileDataToTypedArray(data);FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn);FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length,llseek:()=>0});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomFill(randomBuffer);randomLeft=randomBuffer.byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16895,73);node.stream_ops={llseek:MEMFS.stream_ops.llseek};node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path},id:fd+1};ret.parent=ret;return ret},readdir(){return Array.from(FS.streams.entries()).filter(([k,v])=>v).map(([k,v])=>k.toString())}};return node}},{},"/proc/self/fd")},createStandardStreams(input,output,error){if(input){FS.createDevice("/dev","stdin",input)}else{FS.symlink("/dev/tty","/dev/stdin")}if(output){FS.createDevice("/dev","stdout",null,output)}else{FS.symlink("/dev/tty","/dev/stdout")}if(error){FS.createDevice("/dev","stderr",null,error)}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS}},init(input,output,error){FS.initialized=true;input??=Module["stdin"];output??=Module["stdout"];error??=Module["stderr"];FS.createStandardStreams(input,output,error)},quit(){FS.initialized=false;for(var stream of FS.streams){if(stream){FS.close(stream)}}},findObject(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(!ret.exists){return null}return ret.object},analyzePath(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath(parent,path,canRead,canWrite){parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){if(e.errno!=20)throw e}parent=current}return current},createFile(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile(parent,name,data,canRead,canWrite,canOwn){var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS_getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){data=FS_fileDataToTypedArray(data);FS.chmod(node,mode|146);var stream=FS.open(node,577);FS.write(stream,data,0,data.length,0,canOwn);FS.close(stream);FS.chmod(node,mode)}},createDevice(parent,name,input,output){var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS_getMode(!!input,!!output);FS.createDevice.major??=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open(stream){stream.seekable=false},close(stream){if(output?.buffer?.length){output(10)}},read(stream,buffer,offset,length,pos){var bytesRead=0;for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))abort("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)abort("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)abort("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))abort("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")abort("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(globalThis.XMLHttpRequest){if(!ENVIRONMENT_IS_WORKER)abort("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc");var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};for(const[key,fn]of Object.entries(node.stream_ops)){stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}}function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var SYSCALLS={currentUmask:18,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return dir+"/"+path},writeStat(buf,stat){HEAPU32[buf>>2]=stat.dev;HEAPU32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAPU32[buf+12>>2]=stat.uid;HEAPU32[buf+16>>2]=stat.gid;HEAPU32[buf+20>>2]=stat.rdev;HEAP64[buf+24>>3]=BigInt(stat.size);HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();HEAP64[buf+40>>3]=BigInt(Math.floor(atime/1e3));HEAPU32[buf+48>>2]=atime%1e3*1e3*1e3;HEAP64[buf+56>>3]=BigInt(Math.floor(mtime/1e3));HEAPU32[buf+64>>2]=mtime%1e3*1e3*1e3;HEAP64[buf+72>>3]=BigInt(Math.floor(ctime/1e3));HEAPU32[buf+80>>2]=ctime%1e3*1e3*1e3;HEAP64[buf+88>>3]=BigInt(stat.ino);return 0},writeStatFs(buf,stats){HEAPU32[buf+4>>2]=stats.bsize;HEAPU32[buf+60>>2]=stats.bsize;HEAP64[buf+8>>3]=BigInt(stats.blocks);HEAP64[buf+16>>3]=BigInt(stats.bfree);HEAP64[buf+24>>3]=BigInt(stats.bavail);HEAP64[buf+32>>3]=BigInt(stats.files);HEAP64[buf+40>>3]=BigInt(stats.ffree);HEAPU32[buf+48>>2]=stats.fsid;HEAPU32[buf+64>>2]=stats.flags;HEAPU32[buf+56>>2]=stats.namelen},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=syscallGetVarargI();if(arg<0){return-28}while(FS.streams[arg]){arg++}var newStream;newStream=FS.dupStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=syscallGetVarargI();var mask=289792;stream.flags=stream.flags&~mask|arg&mask;return 0}case 12:{var arg=syscallGetVarargP();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0}return-28}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=syscallGetVarargP();HEAP32[argp>>2]=termios.c_iflag||0;HEAP32[argp+4>>2]=termios.c_oflag||0;HEAP32[argp+8>>2]=termios.c_cflag||0;HEAP32[argp+12>>2]=termios.c_lflag||0;for(var i=0;i<32;i++){HEAP8[argp+i+17]=termios.c_cc[i]||0}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=syscallGetVarargP();var c_iflag=HEAP32[argp>>2];var c_oflag=HEAP32[argp+4>>2];var c_cflag=HEAP32[argp+8>>2];var c_lflag=HEAP32[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag,c_oflag,c_cflag,c_lflag,c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=syscallGetVarargP();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21537:case 21531:{var argp=syscallGetVarargP();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=syscallGetVarargP();HEAP16[argp>>1]=winsize[0];HEAP16[argp+2>>1]=winsize[1]}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?syscallGetVarargI():0;if(flags&64){mode&=~SYSCALLS.currentUmask}return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var __abort_js=()=>abort("");var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var MONTH_DAYS_LEAP_CUMULATIVE=[0,31,60,91,121,152,182,213,244,274,305,335];var MONTH_DAYS_REGULAR_CUMULATIVE=[0,31,59,90,120,151,181,212,243,273,304,334];var ydayFromDate=date=>{var leap=isLeapYear(date.getFullYear());var monthDaysCumulative=leap?MONTH_DAYS_LEAP_CUMULATIVE:MONTH_DAYS_REGULAR_CUMULATIVE;var yday=monthDaysCumulative[date.getMonth()]+date.getDate()-1;return yday};var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>numINT53_MAX?NaN:Number(num);function __localtime_js(time,tmPtr){time=bigintToI53Checked(time);var date=new Date(time*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var yday=ydayFromDate(date)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst}var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var __tzset_js=(timezone,daylight,std_name,dst_name)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);var extractZone=timezoneOffset=>{var sign=timezoneOffset>=0?"-":"+";var absOffset=Math.abs(timezoneOffset);var hours=String(Math.floor(absOffset/60)).padStart(2,"0");var minutes=String(absOffset%60).padStart(2,"0");return`UTC${sign}${hours}${minutes}`};var winterName=extractZone(winterOffset);var summerName=extractZone(summerOffset);if(summerOffsetDate.now();var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);try{if(isNaN(offset))return 22;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);HEAP64[newOffset>>3]=BigInt(stream.position);if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};var wasmTableMirror=[];var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var updateTableMap=(offset,count)=>{if(functionsInTableMap){for(var i=offset;i{if(!functionsInTableMap){functionsInTableMap=new WeakMap;updateTableMap(0,wasmTable.length)}return functionsInTableMap.get(func)||0};var freeTableIndexes=[];var getEmptyTableSlot=()=>{if(freeTableIndexes.length){return freeTableIndexes.pop()}return wasmTable["grow"](1)};var setWasmTableEntry=(idx,func)=>{wasmTable.set(idx,func);wasmTableMirror[idx]=wasmTable.get(idx)};var uleb128EncodeWithLen=arr=>{const n=arr.length;return[n%128|128,n>>7,...arr]};var wasmTypeCodes={i:127,p:127,j:126,f:125,d:124,e:111};var generateTypePack=types=>uleb128EncodeWithLen(Array.from(types,type=>{var code=wasmTypeCodes[type];return code}));var convertJsFunctionToWasm=(func,sig)=>{var bytes=Uint8Array.of(0,97,115,109,1,0,0,0,1,...uleb128EncodeWithLen([1,96,...generateTypePack(sig.slice(1)),...generateTypePack(sig[0]==="v"?"":sig[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);var module=new WebAssembly.Module(bytes);var instance=new WebAssembly.Instance(module,{e:{f:func}});var wrappedFunc=instance.exports["f"];return wrappedFunc};var addFunction=(func,sig)=>{var rtn=getFunctionAddress(func);if(rtn){return rtn}var ret=getEmptyTableSlot();try{setWasmTableEntry(ret,func)}catch(err){if(!(err instanceof TypeError)){throw err}var wrapped=convertJsFunctionToWasm(func,sig);setWasmTableEntry(ret,wrapped)}functionsInTableMap.set(func,ret);return ret};var removeFunction=index=>{functionsInTableMap.delete(getWasmTableEntry(index));setWasmTableEntry(index,null);freeTableIndexes.push(index)};FS.createPreloadedFile=FS_createPreloadedFile;FS.preloadFile=FS_preloadFile;FS.staticInit();{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["preloadPlugins"])preloadPlugins=Module["preloadPlugins"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["addFunction"]=addFunction;Module["removeFunction"]=removeFunction;Module["UTF8ToString"]=UTF8ToString;Module["stringToUTF8"]=stringToUTF8;Module["lengthBytesUTF8"]=lengthBytesUTF8;var _free,_scriptCompApiGetABIVersion,_scriptCompApiNewCompiler,_scriptCompApiInitCompiler,_scriptCompApiDeliverFile,_scriptCompApiSetRequireEntryPoint,_scriptCompApiSetCollectAllErrors,_scriptCompApiDestroyCompiler,_wasmCompile,_wasmGetLastError,_wasmGetCollectedErrorCount,_wasmGetCollectedError,_wasmGetCollectedErrorCode,_malloc,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,memory,__indirect_function_table,wasmMemory,wasmTable;function assignWasmExports(wasmExports){_free=Module["_free"]=wasmExports["free"];_scriptCompApiGetABIVersion=Module["_scriptCompApiGetABIVersion"]=wasmExports["scriptCompApiGetABIVersion"];_scriptCompApiNewCompiler=Module["_scriptCompApiNewCompiler"]=wasmExports["scriptCompApiNewCompiler"];_scriptCompApiInitCompiler=Module["_scriptCompApiInitCompiler"]=wasmExports["scriptCompApiInitCompiler"];_scriptCompApiDeliverFile=Module["_scriptCompApiDeliverFile"]=wasmExports["scriptCompApiDeliverFile"];_scriptCompApiSetRequireEntryPoint=Module["_scriptCompApiSetRequireEntryPoint"]=wasmExports["scriptCompApiSetRequireEntryPoint"];_scriptCompApiSetCollectAllErrors=Module["_scriptCompApiSetCollectAllErrors"]=wasmExports["scriptCompApiSetCollectAllErrors"];_scriptCompApiDestroyCompiler=Module["_scriptCompApiDestroyCompiler"]=wasmExports["scriptCompApiDestroyCompiler"];_wasmCompile=Module["_wasmCompile"]=wasmExports["wasmCompile"];_wasmGetLastError=Module["_wasmGetLastError"]=wasmExports["wasmGetLastError"];_wasmGetCollectedErrorCount=Module["_wasmGetCollectedErrorCount"]=wasmExports["wasmGetCollectedErrorCount"];_wasmGetCollectedError=Module["_wasmGetCollectedError"]=wasmExports["wasmGetCollectedError"];_wasmGetCollectedErrorCode=Module["_wasmGetCollectedErrorCode"]=wasmExports["wasmGetCollectedErrorCode"];_malloc=Module["_malloc"]=wasmExports["malloc"];__emscripten_stack_restore=wasmExports["_emscripten_stack_restore"];__emscripten_stack_alloc=wasmExports["_emscripten_stack_alloc"];_emscripten_stack_get_current=wasmExports["emscripten_stack_get_current"];memory=wasmMemory=wasmExports["memory"];__indirect_function_table=wasmTable=wasmExports["__indirect_function_table"]}var wasmImports={__assert_fail:___assert_fail,__cxa_throw:___cxa_throw,__syscall_fcntl64:___syscall_fcntl64,__syscall_ioctl:___syscall_ioctl,__syscall_openat:___syscall_openat,_abort_js:__abort_js,_localtime_js:__localtime_js,_tzset_js:__tzset_js,emscripten_date_now:_emscripten_date_now,emscripten_resize_heap:_emscripten_resize_heap,fd_close:_fd_close,fd_read:_fd_read,fd_seek:_fd_seek,fd_write:_fd_write};function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}var wasmExports;wasmExports=await (createWasm());run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})} +;return moduleRtn}})();if(typeof exports==="object"&&typeof module==="object"){module.exports=NWScriptCompiler;module.exports.default=NWScriptCompiler}else if(typeof define==="function"&&define["amd"])define([],()=>NWScriptCompiler); diff --git a/server/wasm/nwscript_compiler.wasm b/server/wasm/nwscript_compiler.wasm index d9ebfbc0b80fa2bf04342d68b9a3ef175c526014..344ec14029aef5bc7602b8a5ec470910e19259c6 100755 GIT binary patch literal 215005 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 ZsC4&0Tt5ZWyFJvqDh1sw z4ylf151jzi_ZM(Y3ucV#J(b3bfcnlN)O!SVwF`A8Vr|1Q{}-t5^-$mKppMs&xe_r) zjA>0wVPCjuta(P8+2BDwn@YEu4%JS$BQtIX>tGV5I%VPJ)-adbnQzLAB=(VA<^i|k za|2Cc>qK{X4)W(pF_zl`9<51Lu`C=)+%)TS*p}wN6>vsrtp8&LHJO*q!c0w+w;20@ zHlgN9D~#9B9Q262B05~(M6s+H(fqD7){;(5oTI{sX~wu&nwOSn0%uhqXekRTZdE}8C-SfE z%u|l)2EFlc(hhCvUg{<*GPhDgwTzUpBr0RTaG%S_ltN}8X8&_Y={9eXww|Ho0Sw~1 z8HvlsvJVtqM|!t;hzmd)bC@iq);Nym#;MSF5o+^y8+_dAr` zXSmz@2-6<@%u!YGfTix6lzLbt==DSP`q78GALX+l*Sl8jZMo}_)LpN37iO_G*CN6b zF>8HT-}@_HWPwjJ`%o!6I=>mRd}%IW4j*&u;HBY1A=`SO16Y}#9Sl&jcy);%W3w5{ zrinD0bw#wMFMW+>2q3E{EI%<@7j&I2i`*rZuD&o>?{cnliOfV*mh-ttbBwOSa>Y{B zIE$(2>i;N(Rol=b!WKkpRLJ;99E6dZh5bEAKW>%lga^!EN8Vsp1UV@Tvsxo6-eBXre0u-}plJcd|1j_{>$=&4e%4~0 zF5;b&QAE6Dd0D~7KjH;oh9u%m>P!@^+}tJaPF+GT?3oPCPktu1y;s-r#yF9 zIqG3$*iWpiVqs-lnv2D^WrY;witGPabL^wq@6U;=^RMT`HSZ&wpq`wqxLRLfl9+0J zx%gNzX;LBu9avvMJF%e9=_C-1(eMdNVzv4mnfr{FIj`lA9-D8X4?+}%?TDl;tJDj@ zw4nYv!r78MhUi0+M=p}bD3`|wc?>0usg_6<`%?m<+3c1T!VU zN+-@>ty&i_FRuS%gSDfDD^hf5VJx>+C!7A2jZy!w9ckqry;4nbvHgEEpR20v8Qh;9 zF_c9gL9Rhru0it*2(~k9#M&H-I<)4Tp_Zd&dDvxKo!s;sO6#6#gcNo*!qRXX8zc;$25OT?QwbjxLlUVe3c#| z*;?J{N;kWs+9*D1uBz2O^v3u!wpUKx<2J5XwA@V8u8$_|Q3*@XJXcuexuw0zbibQk z-RPAp@%!kzTNMyR>Zn^)&Q5zDWrEW@*<9A6SF+MJ7AH3st02E>+m+QGU2lY{Wp}F# zD4CbQ4Ii~D*$zrlZTs4CNh{eM{&~ND-sztY`ez`t{DVdY4D&t2z#9<1$Jj|m8Gb~L^plzvw z*`D{iXTfaG2i>z^w&z1_@R%+lRHf3JX{EWaH3|kD*uscjjRNbWH1mq{G~|k$NK(7b zn!7sM4PULswhDoi8Ot82FRipnku?bfI|9GDjmr!@AS7?t#DrbAw95yvwro30T=&Wa z{h_@&NJMZlWCu`Q6uc>z?US-c44z=FJ7|d96B}d?Xle z52L|{v&Yy-8P3tjIjlLH9p=isRxP50(T0f+m>Xrh!X5>13(_dC#4QypKi0|G1n0RI zVk%1{R4K8y+?_;)AK6wYPlPXI-YT%0UeFJRw{$1Q4ab?MEEbh|(pEHhZaeNNIRjLc z0m|;Y2lqg+az+MR8w=loA8d)jU*CkzBboo!05inzbVf+Dt*d9iV)3rP4BVlW&O>AV+)~saPxW~3N>ezO9AH1rz*&Gj(7B?3=6{iAG3Ixd| z>=F=S6t))%JG|T8Kc|@5u&LOR$%Y~Y4#dqfE=So6JRnMK^o$KbD2ZVilAw`B6qIn#CvepxLl~63j2#Uh9CgDdN^xb; z1YRJztXOAE$rq<~*gaz&G%wmF)6549B%v_TWnFb9$%3oyv~?{tWrqIL;Oc7&C8HE685Zm<#)gn4rC|(uiq7ai@IM{4rOm6m zb(VYU>@7DP0P^H=dq8&KSs;O6UJttFYZ<%z6VZov+`1 z^E$4SPcmOB`@MHNu(7!2*T_f5?ki98W$tpy5)3=Tj8(VsTSaC}`@|T-!qn!m1=&kv znwpm=+4~A8=vIVr*@IC}a1S2u?DqQDgBH0CvZD{W(6`>%uCLl^0!Drtm!~!T;7V@p z_!pYP4j|%FB8b{%kko}^W7$r7BlAYbbz$)pj#r{BNJ`EBjq9X6Nv=-g?$}qM^v6{V zTU%uJYG%tKZrGshzC@u`7hSi@3ip({%W87nso5W7SEe;QV`bM9H2*Gc7mj70Ka8i| ze4aErPk+kpw$0AdeP0f;AwA*3>uuCzCtcmVubO{Dr=!&T*(m#)2U#BkKJmeYD_XuJ z19@C+bDYH72?pgJv`KI>^m?5pXJaxKYp3-j+u^W>TeA=spoqO)UF_wpS$q$D4_7H3 zeR6Jav2)!(?;6^&B3kY1^~j2~En}(qIgMJg)&nA|dM4>;4@=J&8hu0=EuxzvE#;iL zO7lt=6F}g{ZMQ9BS#2FMj9)L*bUD_g7{f|+iMuE9t8&1vb~%NpG}}M7iS{&8^|Xd< zZw)RNFv$BwdKB%XdAh5{Ue)dCAvR{PiiWdu$Fl!qnIqq`m_g>*m&^4c+q}=5-{Fi; z6v9IPc6}(hIN666WS<*?aLu2x9q*38+{>U1h9HYT@aKlI7x-778^XoRz7bs3!rDjK zM7V`t-an;pwej=B1luTE(qH)`p7sY@$i$cJm~St&d~6CRPXAZ`SapwI;}QR}y7sr? zRdJBrwH@87LL;^iY{saQ_g>3Zdzm1FSx|-Y;!%b)ik@joKMMg)$J?dlbQ_P?wmXM( zs6ay!pi?7^;S;_V$e(M#-WKTxQbe~&FDjd;YCC88 zp}O62->R6g^$g!oy}1N}H|#6nPkMrmXhVDbT+KxT^yl*)0k}xnG8Wx1<_|N*Y}~3I zH>E5Z`wh@Tk-u;+^DLSrk{j7D1*jl;gDbdTftPckxReWh=6d#ja*aj;)m^FF2RR26XH8&pyTqBmT;e9ll$t4( z#2M>ZTMKAP!@m_O=8JL*Y)nS3(1LV65fV8Xpfcf6+gp}Z2xTI_kTK*cTa`!d>l+lET9Iv@gjqBeKg$C$Ie zNMQ>10@Uu2?)tBzB%r`(wtImRaV=QW(>}F$jR>+!U;UcCVv!Qa(2FW6lgmP)FI<|6 z_vlX#^|tm_6zdU{e z*JWI>k?HAN*K=LMRd(&u0%Xm2bHd_7OZ=yTMmeq}$Db(25x|+CKpML)=NbuKlKs4( zJ>LO)HhV^~FjcwE7mvp2;#F}L1fXbdt~SxxR}Q)F_Nl<20(Ny7`Nx4;6u}1vY&j<#Wl-DP*zhvm19Pw zCIq)B5ZrWA8EOovE23+)^_ko7S3nWMfTqK0>~cZ5f~J{mc4o=(Z&_MAfCUL;OyCSV zFwB7B8#B36d(An=(uVhmo3@iHrI938k>1gt)2Jx6fvF2IvvLd>LIbqwSu*+gh z^+xFR;LhKsR`5M$1d9ar;G_IA(0>bFzkP-)uFq`xpZkor$HJc1Pl0;T>`6MtPs3h` zMn)jALW|a~QZ&YzVI))E|fCm?=}!j()JjKDF-97uz(h zby~c}%Z|qiW67+m2P=^s4a34}zFC-_qL|(Y`{F`m++mLAD#OrP13zh5LH>}L&gGQnZR^`L+esU);s&fLGy1M( zUoLCh(TYSYlQOrz))+f2%#b*ZhE|dpv%`PrZ<1px1i>lv+$tT*4Elz{r2hHzgOL8UQ#pGKEAT6y^Rj*N?)5RW1PX$yR zR^|G(PNRVFcclv<(2%`EJwse}8O;{Gv$xAksnFL7h}gW}`sAHHcF)TyFHMUP(N$%| zmlp=6@=yY;1&U`;ThrJI&EoTVNf%m~y;K7@2|kb2=Ig=dw+^?a*(m@0@5cT8Uff$D zlnuZYGCM`0e+qlCn)wN|m80LqJ+i)<*L7(iFYsvU=#GZWMkL$~H+tlin%b$TLW!ev zJTXigVMEa^Z4Hv4)}`X9&OfZn3&cM-B4@XkxfXgvWONL%0 z?`;ii+lb!nY`eBS*>cA6@m7mbO_-XIH{r(GC#T-EZ(-iP)1aWWk0`?s4KW1UPTn?{ zpVD~W>R9*IYOY=@qAqANR+&#ln^O=#YrgC)XjJQ^Kb>jD#S|jo-U24>Z%x7k3Bttv zE!X6Mm=Iyb61Rb28VOGsk{pNK&8Uic@4UEI11vrVO2|7c?h7O=+@?_%h5GPa$jc28 zN4^Jq3P>_uxZQ+Vfsq%bL7U|4ptLH$X(GPi$6_Y&ahW&?##9u@nNa%G@Fr|7-VAP z2X29x`3R0ER-lx&+zqy<0&7|5!+S|#>;6?V-`s5u-%fthhL=^h}02eW$Ny`Ly- zT@W$Nly-j$&mwRBLoKJY5MaXs0xqwvZ0#AMKJy6pMe*+%m$lY$WM@`1T1m|aS?^;v}vwj=c8^z zdpx|FLjJNqOOWHjNAqO6(-Y>?8{#XUK9kc2$(XEefBFs zF3Sq3+%L8_ac~M%GMM*FoT<6S5eBYxlN|0B#q6V_sl_l#>PqjE=cw{@Wh8X3uJoS? za6LeeA{!dZ{`Fx@goQGG(oO~wE6_z+AuZ^jxW==ElP_36c!ADngQU6G!9`XF7xD>Y z=mA9s?pAelZuZEDXK~6W9uBg5sV`nil?pSsD&=FMN(i+Sq}0LTp^$Vq0l224e`tD# zUnQk6Xq7k+L-3w02B0cRBYRUoSr(ML9a18^TdE_XVX*EqyeO*C!Hd@7z-#6*7u1SZ z06hTHBq;(eb*BbO*;Dj|#43w6Ijew*L6w{r2>r)+7qc@s1L<+|``nnKE6)KgtZH5z zWe{lqgh1e0KCM!YR;s9fIZYW|miY!|;2& z4LSG6eI=xUB1y+4$E9!MLKx;+YjF0HMt_BKpntYR#TXK0Gj(oYwuA``QbYt7oCtbo zjGJrZs*$UuL(OtTig!FB$+XV6*P4FBSc9~y@mq-S0r8_Gk??vaYP36|-T7X*lD1;| z$WIY!(bW$44;%2zweZXf=tsg1fnhWbJu%`?QirrELZlVt42|6et#cIYke?}8V_ib# zCKMBb5V~WRIH!qdS!;y$L6DtoiuE?byg-9~qAgqDY)4LiGC$CQt$9HS1gy}|I^#j5 z9BPRHsvx538Q^iB)#;um^Cx4m$MPquODG#sAz}&j2c0N2@tjF~s0EMb9KrC>MX&;1 z*=jCm%?r5TET1pmdo24KlPm&x(hH6!a>?;V*U`qxlxEAt&g6=Qs6xOQC|7!g5$u>s zjbl3h1Vh5t?({jdHqbD! z!eL@L7h->@L&z5mAp|WuijuN0yd48_H0^JZBfvb#Yj$57MTlObbA?5LixGLDze)2R z9EMf|`_B|Sn(l_m*5t@k&(P8%GsC-?SHX&y^T&@kjzKf-p|2Y zu1La8vQ=qpK}uJq%|R<139M=)dPs~qlWH9k-Jp@Bp=Bc%Rz-LehB)&bOtrPV3b3HIo|dDXF)>pb3+k45Z?WCuL~6Su4YG4RGbl zZOwz6C*h3fgu6D=nC$l%cs8EnK|$CL-BY?SFmbem7lj{G!mui}1e?~7DQp2~#k30p zO*3P{WJGn5COm59qhp~8EJPrf>1f761gKq<92O!z(qW+xioj)JB7Ta6XJHzOiNXT0 z6o!fjl2eb$rVg>tu(42-vk(*AC{S|?%q-D_NjN6ONawpl#y2*28rh7&G}Od`QA=I~ zsI;w8J6K`XJ&oPPNR|3Yq3g+(vOCbz^H64H-rH3hP@+v{cib2khNo>IIvi(AH5#2G z&bYV3bMeQZ6ccc&I>np7CA0y}R$BJozZ^7|Ktty`oU(*+#ZXT3xK#1D)LI2^LhH&1 z^_8;iwPwqIRFGroPxOTJC*q9$%>LdC6Uy_R10^y*(Pav*gy%ux1KD?t1qNkao^B*6eizh$4cx6oe`U+useyptg& zLOXnE39{d;UPJM2s-~NTjt68xB)k`f)D@jVNU~o&tbz9mBkJb+@T<4#IceIt2ISF< zq~ve4^U%lG6&b&WL3rVP7(_sW+9TyW4F2iP+&?t`Nzgxk^@;o~$slrXTf#NMgwRl@|gdSnU)lG~hVxe=3%ugGlY;iVSh~+_T zcO&9JW-W5?vk2DMay(5YNNu1z$xa>5=5qqF)Kj)%d}Lt|hj9@1{0s05$bEqZ#Zh#O z+lgoM6x0_ZYxH65O-(i*60NjU7nIT?EfgD}`2vPw<}qTRm_BegNLIU(xRDxVh_pt9 zT$eRsUPojfNrHs`tX36p`{s;s6vLOTpdt6EGQ8LVf}y5Vsh@4w6QvDF*73r#dzc7J!#CqZt3EHe>Hh|8s@D4?R#7ylYiCLAX_>X9A>o%3h(`OqApy2L1ztf-CZY|&GiFyZ6A?V-{h~?D4x&rwF=^M{UHU$ zx&EMl;<`aPtFp7kBB$*&*&kdJi-ke>juCeb_L{!*HQo{g&Mwm?i7bIxU04O8OA1D8 zopT^bS?3a0yUY1pI_sQ8a9_hJBS{Y&p~;!0_rPK4z+qP`i>hQxVh4v^nAGjyK)s*H zdh5g)CxV=s;~46gq(Ddu)5>ZZ6=s^!0QMkz2U(hKf~YL88OnOFF`D@{<3R1okt+YM zkWZ>dTGxb&0knCo04^~8rSzQsLoDvLf3PYn$P^hZqUr2^0%#;?wSf!C$u}pc%a~Po z1ZuF(zwmGVsZzJ`mMplezK~n4GO?F!t}k#e z>htZowLZ_To9kNZ#Rzzv1I)QzRv)qJRdr^p@O*_19p}2fPP4dPDJkW;O;XDB9gpr>W<1ywHRGEh#tibBRJXDgW{&AY1I z&e6n9AVb)j^UV6R*W~nPQhU|T)XB(y|HYscg0iQB*C31mJy|*yKU7Ltzi@`$|E_<3 zR`>O;H`{Cb{E&bBSmE(Pj_x%~7b-WP~476VG4N*k8G|s%b3KU>qRxZOU#B8L?%8u)q z5pi}TR?ol$M|m;~a>&5MKl)^Ao?1t($ipXhr}KVLk@GA|c+Wf%JJRP=~dyrP?kwkRS4GG+g+sq&e5S&r-)A-IFmrS^zP#PmNa(Qioqu30P zPkP8ysN4n-z^atbawEu6;aQla`W=7kIKlZWx_oI~Lk*Dl>T*thwo=V6Nn^%~s7Iuq zP+i;-Td{+onNno+w%EG*!BE{x%GdlPOLY^E@+`y5bR>_BvC8V;^7<3c;WQDJeHW-4 zBDRKrx_Tp{S;ioWbQ5hgSC2lC$RVuHCyR--c1dQXGhFZN!rVOaVl&#M{0o z)nJQ%(5>tiM$`cXQ=x}*WEj32S53y3p~+rRd~=0((V?^L*r**FV_=fIvh!*{BLFIR z=vGL85Ijd3@s>3~CK?=*vn+HuICbZGFr^%aCIip{ItyoA{%x1K6%Uds?Gga4tT;hp zqkd*C7|atU#H3w`AteiI7X}HlGOZ6)!5eN@P(K=Zl45f6{$-zY3}|V+FF|*C3+ZSP z+!{~A&1uQ$mj-c%kiQbd)m`b9TH829NN^#6&YeEBJ~6CPj;ReUVR0OOBm0k-HYp2h zXeN(vdRF2YF2Xd|Atof5Lo98A1k-p5pdyl^nv)_O<&HDB86<_TnF)BN;|#8oflBVV zhsxawD)Cgc`P-%Jr{_06QECU-!Tlyan1lUby=mjz`mXL5*#`KOl@!lQ%wNg=V?LpL zy8pFoe_2NJa#WuxM`X- z$PTw{NnrLuX02plD-gj`8Z~xa!2U)Gq%ob0l7})=G`1pJ<)+#0bm)`scSqD$KbfkM zH2Xk1-kpY|65BwDlqi<@aM)~m%*2$$$zUyw$dpEW5d=TDwD$QZG`kKc$h0+-eFvyt zey}?w7md_>2?)$zr&`Zs+B{_L4+<*#wRgJ-q-QbHODi^8Y}Rb+11ax7n{u?PA5vbG z1nW;et<2^~6ohas*)*CF+dw(57OHZEKP*TLcUyTfmRVbKts)s4k`ZxYkvHhA^<-Va z%iFe~T(BIV+9FT6@v8bz+x7zq^bM1N z-Q+5UA$$`_c@@!g1EE&CNbL8~cOzirW;Z_Hgyt2}LP7H~YwQ{(30|>O`$1@7Et}Y7 zfw@G#6^EUkffaC&19Bzr!P@dFYQQm2{~RDUY;MPdVW25k&;-Hk(7QnzbpkE3^XT!5 zIkWTaHpTmVxJ@a)f!R!5Nuw$#CiXkiGXA}B+Ts|FKzEtG&Z?(e)G&&?+{LgR3S2hyY4ZV-A@n*yMo1KnmwHwi?oZG_eU=7}kCej@ z6v%v+vL``KC9<$nNQd3kiY>L=2!#9vK85o6Dtyl;YffQRE5|I_X6Sc@HH6jIx zmK;K8Rbn>0iFw+tNVbeH{nSFoxLm_nGX#(Ju zl2{9Y$#xuS!!!Vv{qmPsyHw{Cr|dt6wg2R(pUYidZuNMQR`J`MovjJOq?J?Q>Cq-b5&w>T=*j!ZlUvX?xC3x%^V*& zJt|H97k3iCW7ckkWNl+z)NI2PuCN+~UuTM&k&N>K0gREpFkqo^%7~Sk34NHM&g3#{ za@MrfmDT2l!+X>^*YvJ-2rvYuNcfuVTMb))h)K=!7T7KS8lTN{3+$HR-5I+rHKLy2 zM?$%Hl#iedJ=x`?ppYQG#91xpl2_MJWjU}}Tfkc7MoBHOy<({pnpT6&NDHw8ffQq2 zRW3**pc+iU`l@`6ysAi?icLzgFL_%4+mdJPlXOvmAT(>ks*&Ee|JHfS=Xg<45gh}F z*3zGsnt0@einfRR>xsEf^+p;IX4h0^KU1zYHl zl>a(pVIUBnpcK-OAVY9XfQ>f{;OvFd+BQ|F5%T7DGu9fPsFp#ny_TWQRWso`_oed$ z#00NK;Y|X&E1`NNUlo2le{d_rs%ju8ldhXNFt#MYM#4;G3gzZZx!FsH+O8Ywy|38W z)w1XcQPFg3Jg+;?YU=mSYZ~|-eE_E<&T@y@Uz^l0DacuBPtfM81X%M`m{4VbTd|?? zBg~5+?Q6k!wnUx7F#B_}IAMlsl`RIpe3(NTt??3;!14??=>v6C>_Vpj4s#i@GVmBz z#1f1Xv;?t03cT@w95FgVi#|-vG+(7Bfed>S5Si&8Eo+UB{Ln~p>f(9P;_47v-INvw zi#z`o&99F(PU}4O-wZFVE$mP2rj+B#DU0#4yr?-u1y%=nU7dlnWGP&yz>QnB~DD+Wo6Vz=0DDm&V@#PZB~tZ{xjG}C)nOPRsFCz{TDohicGW|;1g6RU0IOQn37#o zBfN6n_{h9aZhhe&9ThP9Co@M*0kwZT^REm1Lu?wVKC?1HlbEnELuM%|g+8gHM5b3h z!zHp1_8BgbWhc*YiI2>jxW_}}S7uve*DdzuI?m2fS5Q76Q!-*NVVn`6SsRYUPnj`h zO6K@w=jcP{Je@YfGGqsk>y9z`ieyI$9$Gyl3^HJ5x#n%!lXKXcHX zB*(C->=`Et2p_d#XW|1MsbM1eAlK=yX3p!!qugK5u1M{Tkyy-NEn^nL)TTK~#K#_vqail= zMn4fF($=dCf!PwHM?b=<`}OMe+s?1HNn~c@+uPd1zp-}V?d_3!(vh|49rr9{h68`^6y+LqvGN~iEas6hxK$iNgK8ym0v zbL2;*AOVCqmmr!g;^+SSw#^)4*mYt7)-~HPu|Ncjpa?Ne20&H%YB!1PB6kVgg*gS{ znx?xHCZh5ITSXC1ojf7+e6n^Yy6NKy^67e|yS(0Au5p*QxXUJ26stcC7S?^*^$vf% zjafyro zn%hHx+O+;$cdPyC&yS2g%x9+!US!C%#)f|7gW$=!EbBxV>0?0lYnGsnCb}@g17Ks@ z9aFo0vk?m;J``e6V;cmA1NFv6U}6Z(+l%$&RVQWcL2e#bL zz6Ux0VWiI5x57_t1-NRca}HBL1dde&KOwXcQ@ zhBFOc<6Wk;SSD|CVO4_NnNqMjQwrQM|6CKA?QYp>=3m-fx;jeT-SX8;#B{u$P zwVv2m81b>Vwsr@~P#0sZx)OB5637h6*LL=xi#s=oB3=`% z(Y6}_Sg|9JPNV&FT)I_W3mQ2|IsjQwmiGeakqom`|9m_vz`J5Qq>U?YuDvdl3b7O$KByV3Zb;@R#) znxt93aT02nU4S6D=>aya$FSN(RhaoLh`FIdmPM_Y2HRe39W1!rEMN~?Lk@CVHiZ_1 zfL}jHiXFJpT9$0nSro!RNFzwNI{WqQ?8xQjg=sd}7zk4iCRT+AW#32PbRVIkwHrTU z+n0H4O3G#E95TD$F#pqm!w^vioRR}4?g3{KM&H(l(YMVSqmasZJBCqI5M$i(`-D-k zmoN@%cou`%wzWOjw64oy;Wk$0vBuK1i0Rxpi&=_iu^8?`=Xp%kgd2C(4Rc3SaEC!v zuxGSMD0pih3f}r{M*&OeJMAo>Al{ZuAZ49bGe?2e=sN^D@g0nU8~RXiLym&^xyr${ zd8JIOGeu4wH}-wEG5?O83#HWt$fK>7S!iaor?9v5750|Aus`h4k+xzPbLe2WzVEZ^ z^Updkcqb)0f;BbIB$R%Uzl!9_aV|FM&3y&Fd2oTqXx2A;8{zzq=btE?Khy{359M$cxRVC-lHmvY z$nb;tXOB(8)YtTVc1`}-SN&(2M`v!#KcFPTto+)>cggNDFLuujaAxGN9y*M7P3W8Y zN`6x5$xzh2jGBHUm4ZDEo^Api4`#v(LPnl?!iF@1)5@N;@kP zBZ=WA#lYh5DBGoAIQxo5G*S8VCN61QBUv!>O}DmLzeZEiOtIu14>P-(7b|yt5M1X1 zm%=aUDm*2FE$x9#3&OLX?7&vSk*N9UejTuy@_UX8mh-=~MtW*!F7nWvuSIDF4c*NG zrq1t$rhq9op~J{mQe4<0L5-2yhsB?!+ADpv`=QV}S1(8})T>qZeOS=?q5^Sdf(542 zO#{v~9-Kpf^Lhu))ji;7zndaF1w3eOx+6?h#KUrr2Vx%6RJ_Soe1wYM;wrwjr{W{U zirL=!^)Lg67QWus_?18&pl8fC_A=%h2MEP&zP@ABx6RdeOHX}lnv^&62L^UWJP(G} z^$3F4jfcBQy*;x?V$J(a5|`#j&Gq0@dh_~Rd2xL&1NSes3%|D9S4)H13?OQofymr7 z;(Iu3+u9Y2?=8D0UDk>3m0%o1*mW}G&{dcb1@0+#WtN@K_w>8 z(zT&itf{mX+Os?B#oL|r;_c2tdn&+%_D;SG`cB$Mj@hDG-e6nXrEW{%*@9O~>lT}{ zWyiMKsufxv1r<7?*|O@qFm;*$6TNOdGDlS^&-L)=1gs6UQZ-up5vR!lVV5jKSZp8X zk~?~0YI2l|V3V1Obb zto=loME-82-&d>@dNk{=Cq^fK>~#)joYiPPkVs~<>VEqJecvLWeN=nG1N=DG3|)KF z1AL?x;3EdG`K)g!7-m!6?MiM0wFe4Dkn{SswMYAnAoD|b=Zzr8a5}BaWphhs+Il01 zbo!HgtFtqL7_C_wLG7Z-?kp79>0H%%}CJ|l$#!8p9y-au@JVoOTHSFXSJFpv7oV6eTASgs?Qbo z*^?;FE2ctm^7UPdT~jf$Xx!HWNuj5U=CkAu0n}_ZU}?&Bd=CYn6~D)WHFFQ-`}=zJ z-(S#kIsJO5$ci&fk*)OpD+l5Mt;rdwMV(hMdLwjHj}y*!aM(+6Eu?2xIGUJ`)9RS_ zPMjl!tjc!oz-*nkMw-Qz?G*#FbvPj9crKN8(35UbtsT;)xI@bKxxx85-d;*~8^TN~ z<_*HaTo*~2juD#~Ys-#L-n9+|*Br)23Qnwxv zEu)s}BYlrI5aU^*{ZG8Z=X`BN_r9lB=Y0F;77)D6VpWAwRY^1IH&Kr?`BCNS;T?>FQHJpTj=U_+_C0`Nev=$AIWSMHJ3 zTy&4Rdcb<4=mB$&uI^P29B|p0)iI|Yo&)OPSLW2iv#TD?oL)V=w&>$K55KSgPPbjn zaMp1J`;3BSIJ2V}zAx7d%TJ(yxT6`m1q{{*UC}pcx|sncWr# z48J_55uRO*U_0N(E`Bq>VYsT-VbHquQh>j}LUr#Uw2mvrrx*0V8U1>oeF6n^^+2}( z#vWWG;hYmFpzC6E3m~X6z_sXV3{xa%3{xam^(vC9<`l_uOOf0)r%0Y%MRNM|uElF| zMM5aX4cjc#uJd8cba*evIvQa5zQ(eGCON%dlcXn5Kv$D=3+QMPoi=ei2)df2Tfpn{ zCY*5s1!!c?b(gvYyl$W>>gpU*Md%z;MX%{qMV#?H*UNb>`82;Yr;46kRm4K)&Y08y zpXSP*Ud|%FT;D69Wyh7^r3EFltfPcpm#YAsf;hbnS(N&Z6ZprO0&dKewE4OUcF`e9A;pKKkS8f*{S8f*<VE~mD?-kxkW%tZrAt9?fN;neQwF^2j}GW*_B)N*PKpnFY|J%bHIFH>(t}Q z?WqO1J*^|R3NQD|ZC5}|ZV^zE+sk_8mSbxsg{GN>Ik#qTrb`+-6EJ5zA@&1Zxt*I2 zd$LO!JLEWt`LOKf%Isw~ANDdoA6Cnr{A5@+GWJ)UrNu#ZiV0Yw1uDoVmxz@LICrfbOh9?}3g$Sklm>L>81^+WBU+X8K;* z(H*8zE}hdIviZ-Q^~SrW(j7WTahm1du_oW=E8mX0{F~LDT52_mwZfg{-zQ(j)XTqT z3tq48u$6CxwGFo3+txO8mmM=$Y%AXoeC?%Ca?8IyRVvEJQ4jqr23kOOBE!2TRLDj@XeSUR&^pLtCDb zug0H~4q3bt+bp0%4zsMYk&Z%Op-7H7>6pph4IOgKS~?2x*&;bgb~5yw?f7;}M`4(& zNRBz_cy^?tFk7HVjydT#DRRu(b`<7s70EFt9VbPOS=)}n%-$k7=A`4K$T4f_D6H5h zl4DLfPKq3}mX5-bx*|E|q~oN>F>C24EPyVOBc9QwY;0tFyiM6kg&@hv^r(p=&bC*s z{khpudf=vPvjeZU-_h9@h_ImF`Jvk#@7t6uEd*FE?F+C*Yx3m>Y;(SBeB|;ln9aYi z`;R?NrU<)o-y;Gl*^z>bG(nj5eOYgOCPa8EjcKMknx389>Y zlS8vR*=*IeIb-9a9ol%6jd~`ud0RI$I}vG*tp~N)7!g;R+8qa4=mW~5Yy?;8iyo6( z$(Oc<88#wn*NWXp5)JqhMWv}_IoqFV0GOTG^0)4^h_Ct#XLT}g=79U$Wq8bI_^wU{ z)KoFUpZW~X>trbRX81Fo;rX2mmEH`TSZhEo>13$(W;o(AEbe3&>do*qpJ7oa!*Fkg zzwjAaoeZ^Nh9Fx={O2#p#CaZByOXJ&XCi`B%Z~c@=XBmT*yoXfHoh56*=SLe0sY#x zs2khYd{J%nb4kv{nRew$OYo66io;Fy7-Ua9oQx?UX`a^4K6k+~+U@L4u@2j`?e;9R ztCxj#84JB%Ec9w8N0CtLw(HQ=O9cFFv$)m9`Iq!Y?=P8)-aogZ_rEYz^u9cOxOi^2 z(7KCWYH!(&VKP5qW`>EgAhBL<)g2CI+>1j9RaefZPv{R&~r*?<8db)t&dSLRXx$E_)rz-!TFaIH5{{G(b_jk)*U+ahNKL7RI{_8!xU+=N6ZTDe6 zVW=~U$L$*pMy)5;YN#uP=Cio~y4N|Jq0Zsdd2e(-LQdjbJMB~rms688*r^!mwA^fg z?uPyJP4c~p^9}oB_@g^xqdfB|0xF;<7;zG13<^e!+Fr%81ur*Q^;c=?Qsz2fnePXQ zX|tR~wRLQ>o)yHP(@m?7kHkTEF}?ZG$;|nfC;wqj{zJXwKQxK_bK8nO``e2C92P5` z+g0@0a|MeQEAzpLd}^cZA}=#D1Eu)gb4n2lVQ#?8rXti|A*HB2yRk)ia7aqAW4E1B zTvJqvoE7SVe)tEY9sfX)FZrHXh(?zk%D zw*QjOL90O)QZ7eWC}e42OLq9SGkqH&I-JNU$Exb+-lF&6V8#_9gs%+xfd4Gyr2}BS zC&Om_Fqw|nytI~$OxEj9c)fnq>-8hOdi{v$_0KB2cFBORpVn8LrSO!lgdU#sr5x)m zqBH=gn2CBr) zMzFbZ!)(|4?{-S(yS;R}b4%t3HH(w8o?$|LcSq-YZ69S%Xz0Z2q`GO(fMF%wXt<+} z3X8JS$6H}8?F=zp-Uzb#WF>Q-S2A~dC9|hj$?P#D^OtW%w@S(6e`z>!rj9q8w56$g z410GseW?Sg)qf!HR0oh=*4H7vEZ-8S?oSi&g_^;jrLXcQIMG_efv~_STdwOIf`}}+ zJlUSzAO+&{X79l$aqc<7S+>C#RG2%b$WE+4Qr0(o$jhCHXE1(J4fKm04hx`PJOHkJ zf=kC8G5&eKhiz{!YhZ?J7?Xw_%cfw6t2-3YaAwri{(a5 zF6t4C`{{lNv%{5}bXcm35DGuW5_+}ifUYKb! zkEj3V58^7Ue;MGSL8?(4*1?By{S-QR4;woN(Hgo=ac50Z(yA5)ndkNU%T;}lFA*b7 zS)j>+ewtK!2BA2OYo=?GR6tL_@g&NCp*f_p_i(fY7I2&`cv6@1r1rX}aYMssUN|8{L}pprN#o(Hgk)N#v(#TGV)UI=S)>E_qP79iXrm%S22&k1DYZTLh)oz|xX<%0 z<9lgYF!9g3xmOo|kNVc#F8-dfy7+d)rp4x_IBGIqE3Epv2W1bcbD!!V7V?0u#6s@( z_3rJhcdylJ=Sp^Bf31QzLe#A^Z6PxzqYBXY915ZNG74gWy)* zh+WV%pb4*=1e|(@#A-9wntda7CsBqEI1$SkYd2HLC`cSIVmI@mr8TubO8o^!NYeod zXidR9J1d@fbW+?79xQBGfudcVHc^pId-M8)O-}lom?~Kq3!nQ z*wu@UU4{-*Bx^dIGKrM0o8iu?7Z%A1X6d5b_i!Wobmb5julpK4mO+q^7`qzkMzCGT zb<+6tIUQ*jaMHY&20wny5Kx~q6vD6nuZ>?nU(!%;=xm_OP3Pr><`5eNHIJA;NLTyu zGIaVc*O5|*901Ck4pba^5Lr{%y&>}AHUtAg)w`TZb$mO?~^FQd*1`7GF$LEROy}V+wB#1J7Nk| zE!;%hY7#m8z{QXTE^MguLZ_rJluo=b*NJYt@xqQK&9x|fH|2XpZ@yPdFKYwTVvnpH zcL$c)?l@D}@*{>N0G`WChqR8n<;O`EEviu=0+>;lwfx+R~f!85NuaI?v!(AckTkADsWOTt{q{oH@Uygub*2e4at#n^pRH%eYSh?{4o# z?df%+_Lv)GgW=3T>HB)0zEZzeSM_^+DSLZM+1oAUm7SJ&6*8MS0NoKLyfQUk!~X8z z8qBfH&2< zrn=ti1o5!1?@(`jhr0E3M-V)n6Gqt}_8G6CLG<6YWlZhbm26&m3GRXoxoxJu+2g8C z8{$HknPR!TV_^sA;$9b3VXnC;mbnh7x0p?o)u*I>X)>oh;W_Q7r~Hv#${#Vx->X2w zMb7!{ojR)k0ljtg+Igc6N+o;2*Q#((dv~p&B1alhF=ALbDU;JbO(KMhZf_V~U zOg;Hyw&3MHRQ+@jpf7@HlCEi63OKEX96-|3U4=OML+QSfn9yYUKP~#_n-qE;IM&Mp z$BYLoB8T*wiC760i8rjoGFq)@nw7npW~I}kxa3`f&_9zs?!ZRL#X?*kcO|t<26$)H zsm2{#EzD4*&4n;SRbd93>y14#Q>1auw5b>d|0mgqTSYu|S8IUEnREZ@>IJQcdY15= z{9dZjD(hn@-pCAuIrpzS`G4k~Wv=>J@H}{Kz%=e(ac;oNoPKAts%r5*n@*S%=RmH; zV_{Ww>o_xdGMr_i@S4^63S!ce1^6xru=h9qfA-!#+^*}a@7zDmx%b?A&b`|DVM*4N z<$aE2TTY}{!HO&#wb51-Td|$kL(_Qzgc4}};JMd8tm%5Bd zJlFvPni4XG8logF7-~SIc4ELhRf|j9r-o6%P(M!%na}rq*WPFEbB?4d$-xFJC->~V z_WJp*_xF0&TK5McKHMbY!$!pahosIm>XmoMPF!u-Mtn$K%i)z*j)ur~YLb4#d*bBF z3Mi|CB4lQMgrr{`?+G!*@}8t`Q1xqP)VX`bjk-Y9Xl+hJwvyK>X3-E)oMn`4GwncB ztsrf4mm7Jd#Z-vn9aK{K4Kh0~A8M(}!5d-K=i{VA>k^qsfaY(I+G|H@tUy-5bw+AV zWwy|28NpLCEY?E4z`YkC|D zUC7Wri)2)PeKZ)L4+Y)zNK7(p~Y2ns4qZ@9S0Sm4);W0C&!xXfC6yP7A3Viq!YA)iF-vfu!)0tr5wx&2J=!F%*p0pPTFA1 zf$RjQh%kJ|elVc>yKP2O#ZihwU8sA^hKp>L=3I+|21C$rEr8Y*XM*2c45JnvIpdf{w=L6Hr#&pSHuJVh03@?_)4j>Sc~Dg=a81AXdG8NR z9d0&t*qVCSCmXO3bDE&$5OX@GpX=r};AiLVvwlnuRaCz)Lb1UCp>zCYUoc)o#ij}u z{eKqTz)nVOW?!8XfQx45U+jVdrSV!z=1q$PyYjVVMp6b=a7|wkb2;33R}~BA=Jp`1 zV&Pi74O)px6~=SHcvNVsjHQQR-Z)3lt}QZ>TOH)*P=7r?VXMn3K2N7C&LA?%7^^fV z4*qOoHbz+9In@zXqSza>IGD~?fxO*(eGu#C*FA~#3lPt}b(PkdPZ5j@2_OD6!C}|W zWz1<)q|~>qOi-H|+g6$}Y&Ers{ZIzq4$C(se9tK+Misc)l%8{3O^9I&@YU&|-Q3lt z^X*=xHZ^zo4Y#cf18RJSOl_ARQER2z)LU(e!sxz};+uj(vo`SD(;RZNx|dbUv=cTP zg=N~X(ZtjYCcduo*7SjL@=~9?aM94YY!ay^@7(K{G| zYAd0EUdViBw?KKW&C;p-Kj zXcxb?I#UR2h$EYt+uqwzd)wB#qN0V)+{MHUkkjt#?9MIpHVfhE;oO%HFEXrZJ&b+$ zwnm^1p`oq0`Q9qMiHWhOG}D{ao9z_q%*8sxWW%V6-gBWST>+Wc;>RehCVb1~<~Olf ztXzS!J!bCUUEO8p8Dfdi&RSW6F3V$PdZK*k4y-umXhzm!wDSb2GMhjPqiBPxnAFui zO|kC%ObL&%0MylzTx-T9*R%?hDA3{2L>51X`WNsPL>4*vbBL^If^mndkK&5phw+k? z9b;n^I7wLSX`L&~t?3Mrp#-pvwhv-Gk5}LxS zG=+$Pm<~69YBVK@Pl>(B)eeS7Js5C8N8^4f77I;1H6Z_5=>$pf&BGJ=WM`S+hBqW)h0i>=`=4B+9sTz zL+mF^$_annvtgH^=PM;N;pTcUTC^pW#FRjIoztP@RBhg&0~l7Adp0y^?mO-Y>QrW7t4pvot9Lz;*m7^P@0buvccp$!SPKtA-O+ z?ssv=VYz4aT+Uj|A@f^njQ1SsKoD#DbR(eHRhjeco@hwX0NRunL?=gy@iJAHZ@kaT zQE!6H=1DH0x<6HHRy!(8s3jFK<-vFo-Yf2{1#+Cy4vvp zANOHK5dihdYytrwNcpy1V$AOtiih#kCD8jk{G&gDhp>2&AKZduJ@$(5^5Q!Mq964oHxZx8v1p%wu z1`~pGk>i*UK@V>8Xfm9iL+tOJEA`+~0$`Na8&SQx*_#lLieZ7JgI09vS^VjvS@3Qsv|PTCUshq zIzdO%q#_2~xRK6algf`Kb^34Nq*|EfIZSFj)EEEl`AsVPT9aDaBm2gr!looy&f0@g zN`Iu*S;ueB8aX?q;%MrYH5h?A`-Om4;(rP(7?z=l)iG48Gl~UoXi#g{eNP)it5~#>|(-oJ$Bl~a~vM2Q!bv>A(A*qpALsf z9#;^=aDDQ)9VYq7U(m@h*zo2!VF{t zvueWe8&A;z6E<2ceIoScShF|BtT%Rg&ODqj1f2O=q1=B5rF+YP;2^cFlfvxGgVd&_ zXE6kJx=FQao{D6}=SEB0qCg;|Q4<&6Q~v@dD~#5Oi;?Aei#aMP!%5qk>SpeG-fG_6 zRX9h^*PCV)G$`yG)@{O?3&$fa4ps&4t}jTQZ}&uDwjjxTm0o=#-6p*_BfMag5uQm8 z70D=2KwR*GFnO+shDFT_G+pb*xu6y`IX$v;$dXN5ke@^S3;7wDqp)fyjp&@@2TtX3 zQS;pEm^4QhIw%{Oc*?<Z79zU_Her6BM^b{wS=|s8y@We8`j-FVig+3iB-Knrrt3RV61+#nV+Wv*C zJC0-Lql|k0C*eSfyLu>q;7Ah$M+^l2n@LryY~g07ft%lC-huj{zd^^eRRqv60@w+T zM#WnL8R#6_`3XaOuI=dZEWZW(;Ay=Bxa0Ea4AJFyTj=tr2#`UJAb(Mv(baJUA@pQO zc9U9uF|_=Ge$iT<4=tZ)wtT``HnO8-Ay}uzf68Dwi&l5S>UbcX`Y>_Cuh5RPrI$my zFNJnbHrqXE?HXzuS<jgsW$}w4 z)R%|HFb33`xpvU8vm64}B6GbfH4a$PoVlD(RE+jwDt-(95AQrdpU665bG7SC9El?r z`TZS{Ex9~LRP5m4O0Psjrpl^t+DV+_K@COxM?>Ufll#Na4mXE(czA{*+>~YKIybfB zUTIf-GA?P8Y11G`o8w}V2DiSZ!A(#Jf(FN8KCJ4L8r-I#28aI8Up=P5tvYM#a$JKu zhdP3Guv!}2>ihz;kv5rj(A410zG~@h(hh)LcnVi$tSW7$nkl<}#Tp#eQEA2=4$=JU z8yegypRV=N;5LnGa01T#0X3gBZV zfDMD}!fLZae64R1Ut;c?F1AxzmdM>vzO-f%Us`htM}YVePMXrPB%AmWKMF@)Q}U$} zKhBr%asIs8e97^{t^f1wUS;z){c9`YOBRoknB!E)wQ*?AnOf)ae@2wOLixX@CjU=E z-=~-Ve~W3{P@!b)ZxW;HceVCiLsHD*jr+h0C+c){g6pL4?EKPbI>Mb0}G~ z!f#*K4%#&n)cdpd{R(x20zKA?k;MVZlTV<3v=q#`|Ky<{n2$6C^AQuwpD>SyR;JM% z4Q0Y#(<94?J?C@jM{D)tnPs7jei30*{1X?*bg?_hjsNa>$<8`}ou<fhXG^S=BydVA-}dU0PM;(Pfm2&%d#5b<)8 zh?k9se>wCbEABePYMTjioXV9mVr0sDV{C-o3uA2L!O(*T^a~rgKlI>mvj>N*2fw5q zbk8?#3%8Zn2uC!R$A-NTw{<>d(YXfWG21MGc-$6y%FZtsFYFmS{KljL$@2^;lW2Gq zCe@w6+FZz1K^cVaC8TJ=?$Y~W=jZq8SBr7_g-DlW9n==%Vl9FGmX<&*XiJRpvTC7U zXD}elS@D-s8VC?GrBL*X3tfih$Ia(jM#I8*XBTdFWOi{YCn0x#^Wu2sZgH{YPgCQz zP1ysrY$kzTt7Z1QO-9=}68 zeka7^vmTzx!=B+Fm5Zh{)yiM(46>3GE7GO;tD_{1r_SPE+w!(h?9*bfJ6R_cKP@iR zQ(I4$=&7Zrt$Kp=(&92b;bKmUJv{NVc~Sj9{@TcW#0(Tg(TCnw96H-(_v*YL#Ql*w zQ12K}F}Fws!a)N`aW`jQBN%`THtJx?cB?UbZQ7C{IhZ2UFsx6o&=AvD3?TV}arvms^*dJklor;sF zeHQ;(mN#V$BWM3HKU?@|b&HGnNxQ|{_#uj6H$Q+T9RW>|E-GMLhg&eFZOP5~6d=AP zVgmvj(g(BU*k|+*kZ@b_{zWPChJJenpwb?8=H1PI?1=SM9POpQPq1$ldlm;YI~Q*f zya{b&I+fV%le!~1XxeV^kI7pQ>Dcya>dG)!#k zaf%@}NANzzmqJf;K48-xod~k$U31WZ(l#?^Kd2FCavGnCKbXx}VMSQ$iy@HC5-Fav z15${TR9vL$7(|eMlwF|Z(p1U9?rq7wvGjeK7Y|1j!q5Z#K#BU<=s!7G;%lOVp7Vew z(vGt1^o2So}@)i zp0@6xPxXPd7+7nEqwdcTe4LO1nt-cl=x>alwKO{*AuQYIynOCQj=%5ko zph;w}!7d800|WPsr2{+rj(+a2vmXvVaoE{UP8Nfmi)H!(V zhZ_wYy!Mlm#lUMh5BRq|{yr+DXwPvNrpERwMpr{5c`fOx zIRmGfneSm{)OWL5>m5JM&@r5S=&-8xTzg12YbMYQX>ZWYIM-X*?0isk^D)P*HO7tJ zlx#HF2m|8rzOGo{aN3Y?!r0d@)y$Nr(-G>xu|+j@@WpTtuYaQXP>{&b#F13u3x>$Gh|Pttg(R zwsCZUKTKBM(eve@#Vk9(mLlkzgx$%(BEl>|Ni~ZE?2~3DNyj0^K}jh(i*Ave>T7pU zmyJPE!rfI3lDVnGsnWe(cb%P$>Thmw47*&!T^)5JOC^@2k|Um7gU_~P--I3UPwo(7 z^PyvzqH~wedU$d`lhXJ^YbfAzvGhFT6?(NS8+2Mb962uj`5k?X)@{jw0TDwgTA2U` zaEY>v(vhGlo!4oKU8C$bv)67%6b)4Gu#hZ;@J0UAnA2V9B-!6b73pn*wyERq%WAaj10ao@w~tDzL`U68X&)qjkFhg>5#9OA zucvb9f8H&dZ;N9y=bwJ2C2XSvhuWIi|1Mm`&p^Mb3~z+R-C{5*3b(vyo7&0Jk5US1 zmp^K zugTV|S+kb^+rL)Czjpa%zft{foTSR(|AyISyKClG4PR?dbM}v*yyD02=qKu(`f>78 zt@&28Ze5I#4r=U9UilO=pb6p&6P)O*F!DJj@Bom*)Fha+@I5dkDR${eSd|DEnB|GK zjM>U91;Aym!upIR zrD>ywz7r_tg=^oHrpSK21Mp~j^q+NH*3Km&-~srL-%&)s@R}uA+r^*9?_QuuO!Sc{ zE0U%8B#Nyr;(Dp8Hq!byPjY}WtS+)0hFTp7SrrCf)|r%uP{drY9cM|#zsURk;8%?`O6~@JH*dw+@T>Pdz z!sg=Qx9kyN7Z=Cv5k927HL4c}T+G%_Jt96});#gE*-=^yH8%g8;H6101g}p5$lfo} znc3j{8hIDx3K6+!5{eApsjzPp&e>bNUwjw9b`b z{LYnO#)j6g=Ie#fAfGr(I2Dpgg_SVFPBd@-*oHLTx8iAV8ULY9lRVv5rpRjqX{L>j zc(>&#ys>q65wV4#NDuX=9e#b0P7Do96|I|KU{l2_*v-?2`ZJ_Y!TH(YdkaEAN7x`* zk1gtzr?`4bs;88v<44jZL8xePn2;((*~w>+yJ$)Z0iZ@zrmC!JF+j_&!-tIRz)(5m z677P0ADqLdT<=}rZ**{>tHXRBaGHcP2MHb4!KlIoo!g7&P<6=gPj6V@a1|X3Lq>*| zGJ1r6qK&%Ll_#%s=@O8FW(Sgc5=Zi_MzEvwHmFyXqe###^||OQWfuq!tZTMBqsT8) zASilkXg2m{>4hlYpny;=Yoa=@E#nXy!zv%BvFX4Gz)M&fz0%%7Y7U~{#ZSq}Wj&TS zh?n}a&cX10GCUKeo!Idws_>`JuthQ)_U^pzm*L?WwIo8CvpW&wMzXIf2G`+2<0+f# zNy}q1II~jb=%5i4cdI8jlR1}1=amYFsXdREfKs$0dU{aoV5iwaA2JbP3W5Rix(6wV zBD4fb3iGVTN#0#5?v%4U>TBaUL%7qiE>1O`3hTB2k*TGM$s5<% zsZ>p&PCpZ$2doFcSs`Ae7u?$>FnIhx9$}RQaU)*qG;Ng1BiLYgtTV*J*MJpiCD#H@ zL_Pk+acm6-Ecm4%7J#=E4qS4bIK6P7+kIygEx)5bA8;k)VwY#YgT(ManLghawq<{( zze=#u)Y|lVe~b3g{Is}Qnuw{XEti@=agjimRrl|~i|mZtq~Zu8&zW%p^E^#O(RVN} z9Q=iSR6=^+5-_D^OTD>-^zkT6Km}??`7jJ#-mig`zz3TQ?j(IMPs)Bp8jsDFiwOgi zioN98K+G03WNd5x|4lroDVHM}HB9Fb$5yCk(dgX^FFogI8=&mrEV&%><1q;3H$_w zc@Pz@=ti!p2U-KCe7cK`rUvs4Q;T{iEMxU6?QH9>&?(d(-VL45gvQ!X+S#@-9K+Ve z7*Maq>Q~yS>rVoVf;rQ~*^-=xME%sD_@iiPek#HMLw}TcyV-kSI_~FIWmvY*4cOTH z@=L437f`491ZiLq;pk zK2daHW~qoJ2+hDUlf3GIZh{~~=mE;HSf4A5c1ae`BRHQH`;5QbC!0@7h?ZVaYeeo; zC6$y0AVW0~f*4ivCYJ)yLMorgrsd-e z$o*6@(=@mWo@Uml=l4o^p%459_mGrdyHBG;Qj`HeQK+}`OU1_yp)$kZF{~A$kaT~! z6|cG*uS2#pNJxm(|Be2`z|=;kAG-`H9vUoWTk`12cyk`Fj%{5OHw?}z>uhJS_`O#4 zcFO+Wckt(a$s~$DK42i6VfQxD9we>!)31V3o_4_|JFDGPDt$w_1+H*Z_Aaj*%o89m z#o2-#tx5Y#k!hd<)cJmYJebu}2UVosrXHzR7IaC9&W~o0ceCnJB)Zu^#U<7NaA%PN zsi&8+Vt`VvQvPKcT;OjL+It|i14J3wpv8j>l`8GJhZTiX;l?dHJ~t4GfM)a*19J^ zv7T3_##2AHio=8n0nm_Lqeg@0KV~y4Xe*SVYWhHc11B6ZC3^LiM4jXFHPR9adY4hm z)2MJW6aK{AAN)^ooN?bg$Qyicakks>DXTfLEUv)$p8w5bi8lN_^5;dGgO`7zt@$K% zn;#LZ<14YNwj~FH)=r>?Ety54EYuU}E;sUngXADTNGxjfro#kn9HTCoJEXO;F6{?OWzk&okpl{dBiTA66gc20db-R;CF`l?`4g^uo z2cB_aKrBSaGTPO~Fb$hLm@3() z&h_j>PtHeJEIvnttD`7evq>l$lCrl`KKMfYl9D!RhH$A5h~$CSd@>qH(ZDG`x!;js zov|sSk2IwrxpR0*mie8;-QWqhjqWqeuENA*h_dfgZooSL^xy!Tz$aJz9{tHWg4V2J4kIz1n ztwN322W@Z>bEa2R{Q4aj)!!n{pjau(sx#?JFm>rWb#CvP0!e0G4Y)8&!5C_@vYI)e zJ@uBrqS4Zq`E&Ru`OeRkaz)g|Sn#i=auZ^O`H|5+NU{bWxFzEl7xx#gD`ZRU4ISeK z6ViX$UI!1lNgoMXdr!&RR1S%coYj--4v`M2c z;`&@dh}aA()V8mqtzMenh`FTu+D89H2tw9NtOQgKp%vVWAa{mVQI>?CJhZY)jGq)= z_((O87sHagsV}zhXOHyXkl)32Z8NDe(&1SNiLXB&7JG~}C_$gHgHVY5u7Z^S8 zFt;$u)y6BzLiV1Kg2hF^MIakZ$E6%QJE!CT89|c>%c)SaHnhK|CxzK~yXM2DesCIg zEff>WPNcM*Gt-XM(;CxuryT<*nYITbPO}yWY6^jB{6xAx9TrJz1&^B01M}${>3bk~Xi9xM|9^{f8DS9{z2D8`O^DIi9(UH;BQ^;j`Vhov3#~hiY z?qQhsJG6)zxipvssX2G#n%c6zqiofM4Fny#vqHVLk=nsbqKB6UmNt<~z*IM%l&a0y7u zaIQ&(uNr$0z(lhpWpOSvRBDbd7{y{i^U$?&iEl_d3p{etP?=~S?3QbZarVJ}@N5PP z0A9<%I{a5MSP-^r)4E$KiH|hkf(5Gj+yWzsY-v578uOe2-?gp5|umZcvhrIcF&W2qvrq>b$Xnw+YfzoM)`UT=N zO4c0Y5Ki$GO!b=av1;Lebe@$qMm{#5BW;j|QlOSkCw^#kg+r`3@~pjGLvyJV_jM=81SG`r7PNTQ7>+0Rad#P@+B0I60)1jNx zQ|l(3uDV%vtL!FR^NcXWIWh@`Bx|cuYA%=(-b(cG0BzKU;@_c@!5@p%HQIkR)M)YC zpk<&5R~nj7IbAF+HvDMva)=Mc6;4$1U-mI+2 z`cchS1uS_C*9siq#<_%f2{Li}G2>XQx)5n9UjmNQ9$FBi5#jUmgm@PG z5Fk?bo`Hq%sFmP*7f|1P9i8i3cL+PfxamWfYQCUbe6H-kQ{TUWL@})tSRS~u+O3WcIH5*-(1Nxwf{8xP>iuteltL3#! zh0Zg=hpzk>96o{5-MoJ;%Xc1tH!=d4ooLiZfC)wo*t_pCw_1L`xzAZ-IEADOk@pr_sy8yAaT>gB!R z54Jl@HrgcWZ622oe>h!WdFqhj>{x>gIcANp=7b&=X2|wUg30IuRgQ)jCZx+@ z<~?KWh+fUgGoS_Kp0eLMSf#bkRrSQqq{QB>BgMI(Y_UHB;j*TMGA3;@XSL1(5GS@L za8Q82H(fZ~cJ;HxDC66VntW=j*PNwX;6JNPwhSH6%VKN^Uje($4A4gAMeS*4E~J^}~bV>g!U4*juYcj%8MTmQ>`l`?)}zq-;t zn#GIUKw1`0PB*MeClm)#%*e1fp&9J2@dcEdhaZ~V64UD=pN&-a81Dm<#4%W%>1E$y zY_UVMElbrv z4H6h2=cTyu_9RRPx9hl`@2ZYz`LNrjmQRS)xoi2S@2QDk6q-c(Pgi=BfxhZ=skyEM z;7zzn4e)iLY3K?`-*GdM30n+sQOs=8TnbY@=B>F9Rwg>tFd$8ONEFTR$Poh(WAMRB zbs}wBKOu>S?E_n%7@7)+TYjZw%JkgG^q@f;INb&Ro!X0K%|$6R}2JmAdEF*y-k>h@qwc2k$PyBck7`;pSX~nfM0JLt?-lD&~6& z^PbZ|>BI62N>kovG5HCC(S}e{!bMFrtsD+fB)7BA4imMZo6Fq+iS-prrV`K;fitdN z3WOy(6Ch&WAC>x4p|&WH2|qwtso$nbQ&UoGFu#%}0o}W0KE?WE`$|cZ;g}So2lad| z#U>=$gpTGMn?{#nBgL89(G^_ztnoEz{9tP(#hj-#X|Dv*V)4}2l8-Is2_6Dsg>raA zP>=~0t}!Zwi-<&&F?4V0Z1|FsK$suEz5Z_yxB-o`x|XOs;N+>njU8`L#2H=(FyJ2n zuutykpxneg@T6qe0Wpj(jA0)6s!1%{SSLLFoQly6;JV0UY?92kK|Xpeh@_V9*BXpmt1nlC7a z*TRTXF=LN0oU6qc?yF2%s)*n;I^fCzt1DY@l7%=atz%$SPdvy>UaEnGCo<~2usdS! z_KL-~kU7W^G+DNQn@<9Xqp$n21<9Y{NAAFh<>6oGt+9NX$fD5hNIseT!#cCtvhVUlYZ3g^8q$`Hb~^#3K3#UB5ep z<>BPre2a602dhfBS<=v#6b@p*ho^E6JY#XhN%3!nJn3y(g@~>v#y!OfWHF&F*N!(r zn#H=aYDAN?L^9#0R<)j=(l}rP{OXks7rV9c4GxD9W#6R_$LSWA&Ur3sVo?g_Zwzza#^*HJ9=srXkzVC|Bl!L~0{o%N2f>qK3%;y^k0+>JO9LkTV~ z7C;RUK-dO8oOQ*&=_8Q!bs#d(Nkr^Ty{iN!^*GIL(ij2)J)zO7%;P+?54OMp%p2Z6 zYh&7Y%VN%*RFumG^T+XjSnO*=u zFJtR_UaaZ^_f>1y-aUTQ>sS@bKfX>QG&CYPpuRL42!u-xYsemk_+S%5E(G61Hnk(q zWU6VK50xVpRYz4uvQvWEB;;ULGO zN7ZW!uKK`&$=p?rW-ww9V2RtGb#R5+DT$9zx{svB zi)o#z6_=!*od5$Ssxui3`Z7^4j1Dg@(69D77{G$Md1k#3W`qF9-jypFmc<9X_QOIY z92=I!4vh`#Eh`!p%w>{Z1)5Kqtxc0>YvUy`t=bAOlnuwSd;5IUYWw_61vW?SM3U%OZh;&oKg#8$QsbvtXhEA$e3OO8vFucU~Fs_1~xjj-kZ;PT8Wt& z!{FD!wEoJZvC~&n!x5CWd3_V}s<;Pq6Cfe^xwp5?U}9kcm%A|CEAJf;mElT~4A%rA zNX86TEYH$#?Ts5)mO>k1Rkld+*$(jGsu4(z3raKuJ4!R0G<`-Q;){ zamS%%N%5E-rqX>$_|M!2X!mxoP!vUR<6n5KQpphhp*9o2ih2w15_2=`Ev_WsBK7aO zgJn3g?xB{~rP0?bbRA!+T?VYq3P74B!gZxFqc?vS5rt(PtoJ6j2S>NUUL~JxD+Xm4 zqm*PuyGM$X=0xXsXm!{EMs4Tf!92ZQY>6n1>u+V#1)=MC2^ZaDYH*R(gl4Ys5M#U} zB2XgKfxl9lE^c@w$plu-Rf-C0 z-3$W)6huZwR@an5V~Bt$hiWr-K;JK69)4kn%9qHWXgF+!o-LZ=@Dj<(*F|-Fte-GU zO|CGj(2(Snjd_*Z=*t!(Tq0H71uYO4$39Zgk>(-*$EMQ9NuQ;`8@!8O<46Q$Q3^i} z6SE7YZgIf1QiBav!ksVCbkh z!jiIoVA!KK!Ji+~;i|g6yViRU#`1)stT2=Pq||x#ui79j_LOWMdrC6|JCMQKCFY3e z(q12cG8Ue=`TckenjWNbya)UKi$tzQ$6fI;>M>RP;YsNqw zXU&$_XkTC#?Jf>h`+!W9FTq)1IE^Hubbv~sfQ`ADzz_jfLcZ)T+|De*kldJJ(meKI5=Fv(G>0e~ zd*u<*_HuJV83yR6uyK!iO))to1|XBtp3d?624Zw?OX$4NSK7u!-`Msl#%|PNP?LDw zD}vEFgy=@zjlCK;VvGfmOjok|_7$%fwMP~K*3SbpJj z12|g1BB= z%?pSt$%iHLy4J-aEgDzh5E?6$*Mn+I$QF+^>X`(eO{W`Q9X^{XA#7b`1RP(E-<3XS zz{N$T3sp}HtJ8_d z^Xl)+tKMJhU#-7fb=!dN`t#~94#ig)zSh55f7g%n_kyawuC0Rifvj+s519#VYO(qBa<&1f|k+S5?6@kLV8Bc$g9JH5`>g^mzvsqY$4e;16Rw^c&3s3}XL!2th%t zE_K(QlFNFZO)WD_v!@YguP)XUYXSD)+6DghUk%=R*4)HK^#2S;xOQZO98f>f>kagE zm2l*emEef*r1@WkHJhTiHTj}J&bHv|~i}8*Q5`GroF>8(K$) z7%9!S*{fGUl1*I80`gk-lH|8unRJllSf02dPKfUflW8>8~bBi>K3 zFjKcQVYk(g!>AaL@6v_^&)b+RUQt8DgRf=?XX5Ha`xe0$7=C&Kg*n(y+Z2=fKw&rr z1-QpJ6vide+s_UPAqxMzp&&NcoQ}Qc*%2Yj3a6v)*bx7%OPtk}#5os704v{PGW0B^ z^I3CJ8$k`zA%n(~yR+==I|gZBmu6trc+h zz^ZLXwIMR3#t;?99EKPMClA}mzzAa)o13#5n6+B#1+6xE!7=VSdDTJ zKr2u!?Q|Uhl5;SP3Q)n&wPLwj;ftJ@?_@Iimn^%N<}Y2(k(kl&SWJ6jkAR<@nXczd z@lI!2N3m>6*p~FJxeJ68y6D%aPsxw5#L+I^CKTmH3>>y^+1394zSm9(%zW-=qr(?ByNT&0VN_ zAnfHB=do_oeFFCO1>QF3lyrOhB5&(;K#je9iMI=MsDr&d!P`2W2V-ylmbbMbY=3XT z9i?+?>_%(#>Q{MNZQCmK_9R>I?G7d@hb)Yl!^a8hQbjn)^=`oQHP5%{{9O``YdU?M zP*H#>TPQ5#KjjGKP(k)xzT?c{ZHK+0l2|jC5sYwRHQL|Ghq|>&4B!|slV%;O_i=bf=xWm6~6!PL1@nhoNY^Rq-CC zJ6_~^?5_-$NX&!Cw+JTI(E`C#@n&BqAX6*s2toS_?rP(0CB_Vopg4fZk}f^Z1OyuUkDZ!_EZ`sEwwv`aU zs&j-d=7+bOAL7)es~u)kzvyXoZUf)sfEcw8rYz{WTELcE*4BBjrBhlJy&&gzL)J(FwP-#)NaZ{U#9(k!g3dVMAtZ!i#A;8TaJ$LF>IE0f zKhLjGok+=MsQAJ#^vvn5KHat(DKuo$-S#a=nr`D0WY(oFp)#)^#HrbLao&;XCS5$b zHr0w(ORGRZRCngvlu%kT+%SNl>n5@#P#6TMx~lZ12|8k_CY5~IkC1R-CA+A$@sQBE zK||}HdX%TdBAHO{WOEkW&E8{>t@n%Fl2B^1ucQ46mp4pc(pIO6hu#&p>4h0IjoX7i z09Hl!1~YBH8SBSuu0x;Ij+!v;;?4Oc4XMxJPG@;&n z1v52LC+Ej%KDapo6`b48^a9rGM&~L`UA}?noNan=P65-OH@RtIvu3_os?n5i5dgl9RTa3I#e9_k++v>1!y^_rEv1rMznA*fC%H+e z0j$fudyE)Yj%q=(PP6xT#|$aV+_IU-{-N}M;-8LUl~72-8XJuxj|_~GXM|90gGPlq zL(cA4W5Cha3|%l>l~eGR8;jAKBIq*#>$g;XNzlY0(oGu=E;5@l3#CWc4~a&h*ta=d zi^ZcgR){4dTd1WNHbRwci$7T&u^U^Z1o#OCJb5&kJ0~sfFDV|Z!$yRMeV~;AwgUhL zd|b5IVl!+RC68}P&a?<;nvvyEfl~f1`Ok_U)s6Fd9s1P<+}|K`ji282bABF=%{>k~ zvihb~U1PKfDgq@`p>170s4gJt0roUo4x~5e)g>t1aDtoa4ukfI`NMGqe#NSY`ayE- zWM#v^U>b+ufb(Y9cZk)8B1j;i$FH+P({_1kd#4w}grY6fXs%2a_=FGWiH&WZ0y^mm zAJ7(0>$+M*0aS~&Bdf$ADp9^NkHim(jq2}PPwQ;DKY`6oa^_5%0cyluE1naQW~f?E zJFTtS5WN8S+&wu09(b?4t&lzlfDhw#UGJ^kB!iakt6*Qj5<}Nake3*j940DdmVkB7 zQYdD}Z_HChaKyKP2rk+%T-l>u1k4bRbDDG9uNhDh^z~&atcH2>avFhAx$Rw{8BqQJ zn^v3`YLkp_;+an25&BOwaWk9kz#`jugR52lBA6Ptujv907Q=31+HE@xkdW-t6u*z& zGxxzOAiiLmK>~}gd>lPRH8z!eH|}7tNi|w*Wr0EcGlZurUhz6O{$*ly!mipjXib9- zZV&hC3dyjvs;$vsJYiI+u6-$^!otc4vl13Opn|x_wN?u4g;i5}s!Op#0FV~{X5n#r zH3BX|RPaW*5b4wvx}oc0*hwv!yN|jcD6`Ob&{-(hG@dAP#iqn0B*OrL`^Jex>$(hS z6w|{-vL;G9_Ky(?G&Nd0K+d?&0dwvsMLxnd)Xy)t)Y!?4VWS*1S}UZ_p1NmceY(q( zajwV*BD+WDt(RULrUD=Fq_bc&%cEmLcfL%mh7IKgR;hY1UbAUM{)`S_60da_@#5QaF3C2X2f7Id8NoX^GU+heWm1k^jhE~TnU|My zb0P4BeFGfCY6l)MufQ_~CD9o3_?6j6HS?PKW$9u%ZatPY8rg0ST(XNN5OFDZq@u5VjmQNCGbWrCz zXpbjj&(TDq+L*|wQ~hYarmfRo=Fun@a$*o6wQySr=qjl z^ykA%2ADgk4>*tomcBtU}NKNSo2y!Gr2A3IWY%#QONckBDz*L6DkyEP0Zq z;jzb&5q?-GXy>2a_FkUI5;+ibMjCHm9$?7cXR{ejiux=gW5Y(6UV8!)5iE8mF0Kw; zx23UX@6|!4EID}}&FmGbp?A`(&NkG6r!o2E6|{>zlkQihVo-|`w)e)z@OWPdkM&ug zU`9;1^M16?Y>|PYKp8xhK9}8y>sh!T6_54Vv5J(=zFpFRr<*jn$a*bqfOL=dMGI8) zWFMU6_lf=hDMUg!48nQCw1Ipr zYkxY_etfL<0KzA_THnn16 zn$}|{KO1hSEwX6?vwUox2Q}T)b62%VJ6=|&d}h26b4B`dWxASy>q6M*E#M;*TK~km zncMc|rP>!Asc(tPHeT z<44;48R2;Z$6nsIG+^vxgqAx$y?@jF7$j)pG-41NyTrGbBmkOr(0DOd>rX;x;hRCV}~-x_Gh!7FUs__LnuHdafsGx_a_ zji{Mb5Z`)!b#Qs%qIEUVaqT*08I{ORSU=zH;k!W-5ahtvE;b&gzk~XmvJKKmxS=8H z_$#bFTmO&~3yv>&34Iu1vD=oSzZ*+v4zG>g5iKh){*W~Pn6)%%Eyb)L9o}@#Z+JtG zjo7U{d>j3??lj*nD8JEyPInBon8fXt-w^OJ_}Ln)2VEIZW-E3Tdz98$Kz{N`ns%W6 zLZbF6dInHT(p%YE zc;KW5)01SHh0DunSNcqfWiEhh%wv%ySGnt_BbGjvv)I~9LNBLyq5=o=WWV&^RaXNz zOR-(}H&=(F3kPY>im1Jtr3|IAv^|UNy^wB1Z_?Z3i~#N^JY2*Mm0}D^Pl)|01GJui z)b$GAS62A`Q?~j3GRp@}ndJjzmJgmX%LmIWA9|H~{-LtM?>S|g-&1C}<&;@&@hpQ_ z*KmK7Y2@d_sBggC@xp`y$h}*h{qBdLZ&cw((`C1q*Z0!JchK|WQdET!m@ z5+@9EOlH#B<(cB@5#6E2s$51GzMM>)+ly*heD1d~e6ox42&92;p(Q|a8c}rpLUnmJ z32o>|nzq+vzka(w_eT>r9DUsh&B!<^e&#oH4=(_!|HmK+o4YWHTWMQ=qULe5y1s<_ zUuLq6ibRWwhgS21fg2Ss0YDd8|6`6P+yPPX`@m9)L&DB149T^A5wC60f(aW7F8+9p z#-;oMFdiHUoyd}51AKwUFolXPOruziEoP(i_PRl%6uD>3oWTlK#3XOKlbniPpnfh` z$k;nkzd-j_#rYv%x-sJdn(EzwCFy=RQ-)rk^D~lpst2>*k+ne3nE|0f@a`8tdZL&ByttvPd-MM zX5ZHBo=DgNr2D8T@I&`psXj**`EU)WGU!YT~$4t(<|kg_ZEbc3?pi3E-n*J!1^|M9KZPc>8zHi^IKh=xCc7A5{7M&93#qk; zM%9I1Ipb78&bwa1frL$tr~}mQ5|S4QA4KIzA`feC@+8TX)xwk1sXR&M=J8_kB*{3J z3k*hqi$#N~x{_91(G{%nDdAh9$MO$Omp&!00kF%bB*`rH3W^(hC9_0scj!v`Y9i%h z3>0Y%6mSw*eI~$@Y&ANJn2Ra5@dS97*DSqV&`4}piF^rD1`DY{d`CXXTY>ioN5cYh z`m&VyhF2|duUcAp)ntx_jxb&^7iK8s{s91zrl5IuPrcA;&@GnxD z_OrDNM!qZ`69-sDy88={j1p8r8oXv%AtVMw!O}T8xPxcMF3mJ0N4&HK*nd2gPTd{f z8Gj5>v=6IpYb1*i&D(r7@MbB`kg4gpy4guj;n;Jy;4VJ^oiw%$u>`1INH+6>)E9#U zy728xTm$@-MeYwi@;PG8$fv16!_hR^ ztf|Ozvyg+yd}$Bk^O~n`N;YyO-Soe{e^0X0nxWR2e}e!390CCr?l-47Up}>(swDNL zSXip^e_E+KU8x9@Nh;WaF0T&!%x_1oump%&qG@`r#gNmRE&dgHkES~ggUWX1#+!wM zl8DkkNzsgF-yyFr_d5w^@N871|ZJj!lO$SFfFu9v;;f2Q+eqW znn`wF>`U_IZ$Ss;HY!vIwtB@h@b#2savPK?D5#VQL|xXHitJ845Im-x(@6TvqU)Rq()A1rMB|f(QGC z36EIuhsKIObcW)Oc<~nufG2Xn)kPrSc&VP~4idr0XU=kx>3ycPqvX}ojq3UMKrK<& z8>#F=^+X(EB!()5F(>jauKk(|5*^wXBTmW}DITY;4PB5Ob3x964d#NJJ+%vRma=j| z%1d}!7o^rjrjTzda6xjYMAHQ+@7mu47bFl4E=UPnQ|8- zKXO5Kikb@&wu389PTHFO61SG(N&Nk^1!2FabO1}Y)7K0ZFb&|(tB1DR+epfw3{AUs?$_D(qOavQ3LJm z5i6J5BkID3z9ZsFyxVS70{+0;ZoRems4@jp57nPAP%}VeF@(i$WND7YTZ5C3wFtuOJqS%3vRSAWY~UqT!qO}z)hgf>)v4Tf<=HSjMvPSfLW@KjKU#eK z6$-;Pj4*dvQ#*_68gqs?l~{!nkj6Hx$**;RwAqy@`c4*Gaa2o+VDei z)p328&%(IRYB5*x!04#Hj;ofPHuSVS2t7d_RGQS87jqxfDi+k@*0fZ9GY2q3aAeKD zJua`LCR@|5d#1M*A|};k>2sxBvx^{R^QG>tWrfF;ZJ(X$S{me;1+ zLZWnkrjxW-Z+55oG|N#he5NhGj-n^fBiA9nSgOnTK}XoEkP5BcOy|>AB-zy|;!RH* zuTJIkBOK`vb`0EB54b`7f#uUaV#U{ad_fs=#Z^33T(Z@h;8S9Ig;^vDGQspHA~sdy z(BcgS$=iwW_Rv7ydD)nc+7s@8;n0qdZc z)ADDk{#8$htEUI5rz6$VBh}N<>gloS=~(sjWc75sdU~#W%A+fijur;t3|A!h`-KRs zB_U=9qC!^2T{EfEZ7Q@L$4U) zD?q`zd4z7Ne-DK29#Q15C0GbC19{Z&k_W8=SechKc;$IWDS7<%IOivQd%T68*4txZ zGXw$Ps!V9g*>=cZ%T{??Oe5<4M+JYuGBSM1q()lY(ZukrK(kx$Nr1gT9|QOw3sVCq zk6KvRj*0J02C)tf1`@n(P!4!3tF=0mQqTBng1-bBhIdI}qB4@HE2hj_>bZj25-Pw~ zLyY3mU`AXv#svwlh|!L5JC&=u%kfh7Cfpt7kR>=lE>Z8qgKV=Cw-&qH>RZ{OA}waT zLHjD$Y_(;te3+p#k|DPYn}->uM>1@-3>$|TrbaU0&!P|Oh8fx;8GLVjHq4--IchzM>1%S1fIcRh5-1g38W7hm=d=MQi3SUJ_t;5!P>;) zZ@Y)6Rbe>}gJon$qzkW@T+K?hnt3Af8%`YK_p@K2-gaIM5$mA>yF3veo3b46pBw#$ z_(vsvz<)mEId9?3)~3Ts^;EHp8b4(nqT6&)Wem0Uf1F6!?CRtND1>-R3&k}TYjy)Z zbY-(IQW&07mNNh21LUbzc_YarNAtGOTw(s6{-o9v(&EYZCa6P%9Z6_;))rYK`R0JB%h7YFrqD z-693Rs8)*+7TxjAU=w9Br?jQTmP3%?+0VyH5{a+l2c1BB+@UATyV!_*0fJh`3!hG3~ z*>e(!C4oa?A;3c@kJQFhcPhi#s(@-a4U8Orzb{IH4Q8Fiv$xQazOSS)iVBTD=8WmVMzgK3nwEECNy);o3dI3Jx$OQUg2?n8=0;qvT<- z`iOmlW+s7cw#jD2~UT3EgV^Euxl+o0IXYHt4nS`<|iWn zWcGpP*!vTOeh>|Rx{ps$l;s=aX)SdUPlF*Royok@M*YkK8jBPydonf5o=i2fCsWt# z$y7LdGPTa0Ox3d|Q~&Jga8=*E)zfnIWa^~lGZoXGOzpHMQ$_8`)KhyhmDQe1jkPCJ zZSCnXsi*dIw0e4^dOA`)Jy1OzuAc6#o|da8Q^&17Q_=0o)OLF^RoT?DCq&OqNAd9l{jot?jKYg1^a5BiSp+2z4gz;jEmn} zX`;ya{7S!8nwa$J^NaTRWc@R4lIrsb`}}|+=PsTZ<_q5gYEH(Kq8@@i#sEN%2r>W_QVNFk3O;6QpVh2OjWgKACeXQPPmU*hr zEd22K(fVf=k*d!uEAjbA{WFVH)n}Hi_%r=ULjRSNG04zu&Rw;SX4l_9~EEwLcBeK;T(iZKK}*kk2V$0*{{&L`&08C zyGqm=dP%}8S%hryxm86gyKEC4@noO=qvro^!4g_wwAWb$t)Nd_6J1FJpwt=Mx?78c z#d|n&QcT|}zv!a-9$>x}h%t?`csr%AwYIA8ZniIL{Ouw~_fWJ8)<108cBmD9<}GTs z5337)eU=*4T5_3RF9gVxMU;>1Gw;?~DyI(&JAv@6bt3oHH+o+-vy7dsr*(REO>_w@ zY=n_h0j(u8)gI|uT>R$Kh#CNtGw^MgRw|LF+oMZR&!U5a7SSbK@y%#j3)yAGSHBz; z^Vwxm#G>pP5INxvNz(uLs~96IuH}FHdqNq?TK;=n{C||TK2Ysmdb*;n{2^VL@k;h) zT=aKtUHL(VKU>yP>q@Y?_JtUeESKfA5(u57TXWfE#2c`*u_!?4GQp3?^N-2niGX(l zI0bkU121|YdTZ{(WGj*z_Z`#k5(; z?ByX!8rM+jX0K0UdQ+0uU$)xIw<{E5MWcLqts_5ms-dZXdS#2M=RD+4lXfhw)xv??S!W(1Oun^2&a?RV35< zkQ}f48LAEYM~Zv@oUyY;U{=1knXT#;_gS(hT0owsW2+?El{=OFqWB@Ta|XeFZTkJN z?UWeS`+^!^c*P@s!UOD3dgY@WyOJmJZXkg4gYmDQp8sqm*8_j**_FJVcbt>ESdhGw z$2}pKDcLvrUmml-%sR&<`D5K*bhJZ=P+m&!>Ahl*bY%Cer#2S8G(5lsH|!69OuKrxzgfdKkWUhGs?rnflO>xVh;en z3LV8=+$w(l?n6cAR!tB(h(2fy2C3#R16Jy979u6=ykqxb_Bla~$Kvs);_P=4mX=XL zD27I{I*z2}@ex31k$30r=tlX83`cV5dQd3L!23!TFzA|y-Ew7}&MW*gBS?xrYl15> zEvz^kD{w!9Zx{Ks{FzxQ+V8%Vge*A_>EFH|-uLNOrhL%}$KZ>0>s0^9Mpyc?n7ej+s0 zM=ztJF`&ePzaY=*7U0r11qgy4UX6AUkw^@-wUEQLmmV!FZQJVg(I(;u`@G3Y-<(I# zNXnK8kqQK6KAY~zgab8gSEof~pyYV?Ii_8TbH`tkB2_SleN6m^mWnid#ywkQoUSs; zsmNI=R-fsyRG`7ILHdvmw85;h$oP-{z&)K?GUJ6+Mk&N(T<1TT|G+qOag5c+>WzQe z-Kuw?nS=4cXP>vPPT4c2AEFiYgI8Za6ku%v_)}bUT&yUDZucF*pUGtfzEBb2aHOwf zW1|2tg7M8{M`Lug=!&#Md1MwSykAk~$wK${6?^ZiqH@6EDgwdec4cb859=G|$Yvk0 z*#!z2H&{>sF=z}eBM=7*XSzHhTSc`WFJmVLKfT3liY`FOe%UV=ZK1fm0U@X2e0JiK zzQI?BzF}SotdU~cxnVHF4nu{DD|Lp0X;~=~r|_BV6)h5p^EZx>cQB)1uQ_hSDenWW zp?o@@Vf|*<50*Wkl_>>>2=A3~y9NYK`y8uz5_i%_mg}5^QJmLT=pW7{93;jI>Vo|k zQ(Ni+m<<|`)_xs*HWJ+~P-@v(ux1TxW0C8c#$=y&u?f#< z!IKR$pbqM+>bZUn{Ls+@Txg>1sdMT&V8tFF*Sf*fdyMS(x?LyF;BC}G7=cX;lyz-7 z#1xSR6Vz8tuZUJLS&%V2QGw-QXj&o5IfjZq%yrhGKix~gMMpv(D|pkRKI+MS8r~~> zfOlST%3Q@P>naZobAGGgwi-ByQ(WwWK^?Tw@!mOPy=Bxk4|j|AIWw|8oq9@H*!yG) z2R$UR+_HEwuPAu=RgVxmP4=ntAA!Ljg!JN1IqMLn&6ti8BHGO504h7EKxv6x8n9g# zR4~U&F182erLZKsfHN(QMdAdoDeXy!plC>gT9`f|vOR$iuqUP2UTJ%>z0&q%d!_A( zD|^vrly9TfH0^1#kjb8M?Mkz!t#UEg(>C)msKj;)Mc30#3pLl%E~!42Z;$C}O4IeM zjBVeNjcp%nD38D?#>5bA@+$?D&w3xDs#!j`GoLkffel7zVb=kOjW@n=Xq*7-a0t+( z7sTvo`<6Z7T0v+l4G9jbYqnGNM<>oSYH7?#SkLHwN#dEgMWf2_n6t|PH%az!LQ5=( zfr)S=I@D=~D{OWFs!c~;@@5#A7`m;e+L{K86s`rzG6LVeE%7(d%>p`*MfJb~ydF3d zh{1RiL1(qE^CPf0qzZwHTBSwtIQs#|>zZN?cMAr$~Z8V1CLP;BoM2Kz9A(Rur84j3{^idHA!qy7{dOL1| z>B&BYe$tkTOYcDTn!pSvfhQFjDL@UEMnlI0Okp)Zsf0z)9qhE@%+2VQL zc#?oQ;UDyP58tH$A@|=BWuJ^C(pifAVw`o0r^%*L%Kp?BH6D)K6d~$+_cOwC=gn=z zJV*|2=KYAUQgR1gCkO@kvftNd8@lgS>o&m<3UvL2*?5^ zEp-3HsnurEu*(kI7tY!&2wTNDe1hIJ$0&17aaX)XKvctr3h&rtm?xu1hvre35;??C zxYsEW6fH%n6=*X^4ehMjZac8y`lAw+` ze*1yO@8XhD7?|&V1eD4(1f_6oA}AxP2TWtiMOV}b6-z2O?ZW`I(Q|YTs_x2mFf|rt zRCb9PBnWD~>4RrBz^MD?iK<2MJQxHn{*1unN=Tk`KX1$r?-mqX{L9~riYNY#ae)Qn zA=&LN|1GkQP7~?JgiyN8mR)K~73ZXJOTjMg`3(@2f)=C@CHpEpm~Jl3x1+e#(mk_@ zLXXqpjI?BGs9rxNV&K5? zI3c4*3p9kV1}Sml#q@`lifMkn&!(NU|AsC%{b4LGZB%@l$T8^)aB)FE0zGENy&SA| zK8Yip1B2)*4yWJG7_xtYa7((y+k((bi$4wZ*-eEYjxv+W!!CtL-Q~5(>bqNtxFm*P zFbi#C0VH>)v{k_;VO(t2y;S{~26bmRva*Q!3fZZPoTqJf)7p=>ybwV(N(t<|6+NWZ4R2D zJ{AMN1n*tf&+N`1?1SH;&$1K#t^L}94N7&4J4(8?P92+-4TUw@pQ5EUFgs2QJ;GFf zXr@0`?Ch^C9$D`6=Yh#=@d^%aJwn z{uk%(-2Z%ZcYl5Fk}hb{=N=K#d%S~CFRkg%^*D?{IR_h*x4#}}Qr%`6Npzjo`h3Iw z|2lss?zzK|-L(r8Wd7U5f3dwM8}|PZ-`3Z@>frvbF{2lT9&{+M1wR=E7u9wM@@wte zujbXkM+fWo_dcfbMell5t-jDW^Z#gneUW1PZm|>s-ISvH;OT3NCxU-gDa0_6Puubp z4=;C$pIGi#J4N^Uh2FYu@$qXI;dHt8UHUIzE`RNwRkr}Rn^0R+1z4)l$ zyq>xH*kC=shtsrcko zp-QlH!nlCvYI|OSD=;H^c`^=%Njx7d*(m=Yx_+>F0h(6-AjB>c$8osEM~dVh^>vaL zV^S(Z;HX^NX|A4X5O?M4^3|Nzz*zocbjuAiHQ53M|PYi1=>=u7a3h0-XSaDRJ|jkj8@l*Od*BuZGL+Q$ahu_H zd~&e<6Z!g&QJxDp^tmKS2KCT8{@&bd-pkito$kz6;rIE4HF;0lr+-K^kauW>OJ(R> z?&i)aiyAV~YhQZ$wpCcN`Fml~&qo}a2Gt$je9O`oioM_a1&pVCR`2Ik@4ls4z1*pC zihBLaw*Hi~?kQcd7J&PSFN-937yf>n0pTLi*`=LZvD>mAjwR53N`MglD4|bP8Wl#8X zo)F~aopuGFOQzgTF_|vj%r^cwilKdF5TWxyk`Ecb*!NU$x@+>@PcGSsriJp;-5$j- zCJAX>s~Ylm#9r9?U+i=>(ZuteFuZAsOf&1$3S#Ho#USBl<#@<5_Mmt2?A;5-uTU6R z50iRx|Dl7eyNey|9JN3|WveF4VX;8bGYwz|YQmSeLhIe|h&OkoY6Si!jiV24Q$Sud zR2P1vvQc%hv(!o05vTlkAITLfmz%KkS}*#*Ck!ceQQm1~krmT2^#v`e>QV!IRN-@0 zn9vk-bX;L*QofX|BW*}xCqOwr9xZb zqTLR8$|oStjO)v&-jD4uX7Fo5$(y*+%YeNG28`L+{h;|OLSw-Wg7xpCL~2{&w&0|d5r-@}7k3oQN$b8?-CHZbX zJlziCmW421By}6L6p@f1G9(zn5aAHyA=ZqBr*2~6HZepHhcU?{cqUE|;SrM%5P<|| zu&w+1uf0#zseZ_^dEDfS5$>uwXFt|nd+qhwYp-o)lxi<^jFj-<;gZo~aCu}n@W6qP zfYKc2j3|8_CdEGCn7Lo>a4l^-Vw*@JB0L5C?I77ic;r^_&8p5;{n?HQ;_~6} zftxv>*n^&tT;VzopB>-eV6ei($=m(60QCt#T zm;8Jb;nG9(m3QQZZe=QXDIPSwTN{3lYb$o=?fbgbAD7PJRHYDYo3zNPm%cTm;Q-J^ zl$xBbGj_~e^gqNhqTWa$p;Z=HZe<%AYm}0e4m?iTGi(@e%`NebRf`e1rj~vfp{YAn?v%61BZ9lxg4q0+{Ba~8KwOXIG=)NQH8`OWilU`g)%nZb6R>mj((RhTpgzBzwD2#oVzJjc;? zyGuoh;+EIUAGmqH_0K2xeETD|yy^cruDR`^K~|PVZ6gc7^7g~(6JXc|v~!I5#vZP~ zGl8Cbs>T_~xUkr(!lVAt6N_jnNPpYTce3kbhO(xo(}H1CY(hZaEaI9EbQHGbFy}Ys zcr~cqTG%-ublSHBr9m^yBz7Ar&NZG^ODeXUfLSQt7K#zjVvKBwQx*arcs3YQoZi7> z?PRju2K>%dP8AOmp^?Es4wDOJ9b~ir@uUg#c_1?n*~(k})(`3fSv5aPUKzEbajIk3 zh3nx4*F%4hNZVTFfDT$zi7HjCR*$w8e`m3%eqFa^czF;`z*!O~;W8D(`#SBlNo$`X-E<=PYbX*l=^ zx^D`NaF>Oh21{>w6p(9G&~L`TQD&P{;bCxj*^vdU`&RE)LT23xzZew9{BVcRCo(0g zlUE&@S<>&z=&I$?IrqAUF+&N}K7|(mh>8JVyTg2M=vbZzH-UnTRiEJ1Lm*s+hZh*3 zF^l=dV3*_@YPR@RM1QHLs1%=3n&;s?bN4ay~F^vhx=h5lTNGxX+N&s$A zeOxDXAF4!r+b$q_iY6gU-xekuy4oW>23dBml=8nT7^B)6CG}9pV~RI>;#SGIR91RLBG6WFTV&xUHh8o*zWVuOlIlte8#S{`<4K;&_82KLNwG|x=p5TP2S+2hXf$FuLkJ+HczLzR2fR;cMA8hmL{O@DE|1pS_ENoEXC*FeU|b zuSm3xF|taP)5wik47fbzep{44_S_=>lN%6baDi&@)Z+#kfw)1f%nd{U_t_rkFmwY? z9x+dH6V7vzoV}9e7dmTFft{OPSk+pH@~4r2!6wS{C9U6(=Ow&HlqgAMKQmN=Pv84g{&AxXQW3f-Ik*k z4UKVRySpPIn7n%REbPbz9At@Hn4KgW>#T=h@c4Wtm_e{b`EzmG$xs-Zs{gp~!~R2s zjGT5`!PwL$xkyc{Md|ONN=O0Skge?tmxrBjk**^#r$5ippRBtt`?`-FjN|+p zPfvNhhx6)U2IicWA(|;p-l-JjUgppFUXXZH;9h|(@hf~oj0!2WCBCv_jZMnEJ0_E4 z%rLiPB3GKkfeA#-7)7r!RiD3*W}GE}Rc z{gBl^{GRk9HvU)QRR!|vG$9`SW13%^0+`oYB_voo)j+jKJhP+|R>!@zIuJYQuZI+H zdIEpvUaHMaX3RrA6tP%Y*X#UpoCR#nDfDYV(C$^aRpsC-C-1`PT#OTQFiecj(y?ABmYB8l8_j8<;O}4E?Y{ z2|A*g^zEV1PJVCHuW@gLZyl|lN7OrGI^F~J_r8eb_iKj72P2N8@%n6(;FquFiXpNqZY(?isU4JL-;i-sGZM1crA9FQO zB0%E=ABH^{BKf?lbIj`8W`B>`-&-PA_pGCid3$)oHTrutfU_a)c7S*=WJASUaAhhp zJW*SdICebM9U&mY)5!y-;*=@!-abVxx<2o<8uuZ%db*Aq=t=i}(cYh4_I^uDM5=*y zifxxMRC2ui7^2yj)1Obq@~xosj62;YMa-fEx+VHD_+40DfY~rCwzDQf)4=>_W-$@~ zhp==Zm=i(S`Es$QUR%3@?;Md zDr6kb%Q8+s(Akkuw$j`}K)4OIx1=pma=)V2_9fleHL2wAiKFU!yAI8-k;kk5kH=5j zL53um|ME=JlF7gj;$``?#H`jDyKf5>1fRVV>0nX!Ka z{pCY=IJEcX_0oWn0;I4$#s>!u(t{@gMVA zQGdG{d5->M`m?3N|ExYmpOxy4!VL_`0g;A)f9}IzsRvczEUwa4R7Y{{gGwwnGe^W3EBoE z+{hcE~~z@ z9P|1gZK?6wJgQtS0kF&+!2_KkO1R6HIxz)I;?2M1Z|>&@T8N-L`qzH*{%1O=n&3YP z7LkwZ*fL&qTiUP-_^7_R3zOi!DJgL=M1*gB76)AYa{knI;3A!XZ2{E`RK)iNTa(nv zlIv%#H$N486Kl_C(eW=!!78^t8(Da?1Xq(-A>qJ55Q`-fchtx)zOn{=xMq&GHqJIz zTp(Z~-e}0$k@Cf33s~+=@gr=<0HZ-@3>vC5sl-V%3&+z*fUISBG9;BTRHU+X7!p3! z7QVNFfLxyrnQX|R=Yhg)n0mMvz*X!fUf-b_G!3gSgIN9r*NA+2(;@^=z*lmQ|A(#} zcEY1gu%CG!z_4~I%{$2inGZn}g#eNrBc-Eg8ePFA-cTnBC(c%4|Bal}BdrSJc(7Z? zbIuZEvQ`9cQtpdy|L`v@nr9Wxz#G=oSr!dSq5Yl5hYIVcNtNWw1665btluiDjcHN> zDWGLe*d(B~XGx2$3zfXrnz^qEJ7WY^`LrtYYO#t)ZKJX4cov!$PFUKMK0m@BN3QI) zq|l$`2tj0F6B*%2ZD^8N*KMY(VI#4uy0_Ef+P~_aeC|e5?WE?#;L44j^EbMFK|WL= zzPguOh`LdGVExs!{_3p1T50|9U7ATUo0%YBtKQ8iv}|K0O&bPdHY6uVK_&F%QkM_G zE^vCJZh=XSk(R}@Qj!RQ&!Hw1wnrsD=`erPkaY{;1~M@~(WxqS2%jgbm_tk{6~E3B z>Q_8Q#q~@lW#+B&k!t#%shXc9^RRz$tlBla-&XCeOVRw9XkLzEf>7%$iWZYyDJHn$ z=H^VLvtHVTu6sA~!uJKrdEy3YdY%vpSNOySzZz<5u_~@o=lW+=P;vMPfMAF-D|_S zuNcm00_4=#V#PJq{BUPN)Z>BF0%AN=pYQ;lDcYRxw|UgsyrpRKh;MV=x5@048t4Ia ztlz*%Yv5GTz-_*PV>F;R->>Op4{+S;aMD+5Fr_t@EFweEeKD_OQd;T76-v8BdfH=f z5e#Yuu$GJzK#}1%mlaQ|C#}^}GQ~F-UC1tX(|;_+wKkb?#B~O4t4*Z(tP~uO6-&Ke z>pcv-2oB073$yiZt59|~bk`e%_cPJmQS0uOxKOT7!FKQz*wZ61G#tx6Kw>jT%`wgJ zL*9^ee%uI=i|DC6-EHSz4W<>)hr10ap{iHzo@HKxD|DF3c}>kzVkC(6ptaDJ2@51= zy{_X-gM*qp0~aKOTm?o1th9* zg!UR80LbFo(Vr{Uff_%N)uvhp_H}BHu|3(SRNcP6Tbuf?Z#wju-~Z^}{6_dP*Mo2T zf?Ko!Gk6%W!<9VlWn3}OS#3W8h+wniRv!8KIKd-?)^#qW45beig7y2pr1@lgN-1w(IDu*Z6!ITtct?UOKDi@@Wz7F}@{<)he*Ne!YqKz9a? zbKKW*x$D`r%Qr|g)#RJEtuMZ^E#%&4!PN3+^MajgHyAFDK!+9$w3(TYq6R{(=*rrz zv;AlyA`f(jvg(PcbK$}6@YLL)YpF7n5im}QQAQN$;&2ap%{EZcssVwiW3HN{y$nE| z=3>CAmRBU6qRC{Zwq@gvoi2#8_O$@17ajSlv*b9v)j^)z2hJ7D%l$4Mh0_1F{7Oh` zXZ72=$sxA+J7^;fs0?b1lZzl77;x`@RLsCFCLtI!L9iGe{j1eDk%e}w!@%=;GYi?o#1HX8D}L44N)ij6BItrg8HIMsf}BEJ+sW=!XAK# zo?`Zt)Qv&U2;He>m#UH~?gAEU1xhnMRpxJ?~x#lAeGwo62Z}>DfFIyO|B8)M9xYU^g&snm&LpjAG`}!Gs z$#g-PenpK6;MU|ng4QXr%bFg}x`VS>z$sZKJTj#+UGf%mn#*{QiIQ{674(~QM!*%r zVdQ!<#$Gva^4ryQcwuPl9(6`!h7$G*UMjS9k7gu369lNVGBxSl**pa6RvIV@zfM?#Nd0kozLq%)^IhzZz zsWru$wCmhmBO<8h-$p|0xQa-8qbu!EJ&%JN)A`r%Nr~*4SSLan(jAhkU9yfc;G~}aF@Y6{ z&Y2)Qw|6!ImqH_;nI1R-iDfX{2*N0?Y^v7C2F}cE&xWB;op9>^fWx{U1p5Z<4aKj2 z9R_VOgu7P+wYItOqF;$^>r$n)37Q0sxV&-A1SG&OsGIPvPMrf3ted(xbkm^iZtSwj z_EIr7kpL_qn>Y?~wgvOA&YHUwI6W~{Ibwy3TZQx5IYS}bR?j~0W8~?aSfvILun`|*~b0djSv(pPIMp& zf;LjNbnMA3dXm4b$t#`{(UeYT=W=6qQTksP0sA{(C%AHUXq4BYE@*2lWW^+HblOh~ zE_x9s4gpEh>tv2h%f6Ydr+o2I_-!LlRXqhfKa-j>>)U6a- z9wAXPwnYNAcHV1}hfFa_JkrQE{wQfpwCEaehwb8I_B}z7qn_ki)|RT!gxT;0d%l^z z4>-jH;l7NZJ|h7`mKiywSTsTd`%Jib^5-)Ebh<0y1O@=F1pvH($q=N*KOr|DbrMot z4N2R!u7=drkecL-h*@^U^Y>r@_j;s%Suz@;dJrSHQQhcQ9UmIHqz-)*6WcVn7|m1J z{uyBepf;sQ7dctlo$!0*L z)Q!-U^R;_8X6g`wOr)KZ7-o^HbF-$hQ8<`xJ7tkH2r5PW8cxQMTM#a61{wf%Y;@9a zY)q0HL*-%@I!UER?>e*5L?_Tj0y9ukky6{>$(0;-i;4_xgsy2!2q(Ii2L0kc zwyjzMR_8)HYgqd-NF-RcPGiN3wI1t+-X|UeKLt2#3B#>8TI5mGPuFXG3^W z^nNP~kV;~CC}CNQ3^eZz=Wf}@>yn3RYgV*;GQSmdzE>H-L8!+7{ofRn^W&H2!Hwy|1iI`3@rr1Xs9n=*BE;^96HESXU_4VM_9T~GTHy6 z7qiJjXui8#*hXY^W)p|A4f{w2zp>cfWa8ZRrn|?;)y0pR6h$~- zfZ4$FX10Mc5_t&nZtW^SvU_=CfFbQ!6ArT(*~m#H!FAOP4jo0OB_up7XH$}In9iH8 zmPjTpJpWR#qqB}7po*v(qCRgjjuzu!2oe%xoXKPlN&Z8BZlkQV7u9VpYuQHG2wF%( zMk@~I()ipbOz#)E7hoFQmI@NQDT2dKd^qOgJTl_lERDX3B1&A6$m!rgjKK3(r zz@Zr4u%ZKd$Ll6v(2?C?vm;*#I;A`Z)R~c@Kv4+f$HGAWQ`y9?$TOGuFK3G{4_?Ly zM|Kq3Sp39GLiA3TXM7#uWb-)PuLrdkscDXg6GZrS96{mRX&04>Q8GkLW|)m1%fg?e zfSwk?3LZ?9I52=}u9Cnj5^u>};)vazt2rS<__06-PD%VHf&rYe`go?+u&7CdcF=Tm z5Fo2DtIcc3X;iEzBC_0yVxXFRw`JI14_}41|!HC6az`}1hRl6;~OZJ zKsankvo7jA>N8D@c;k;N-k3IqAX@?*Sly)!a2OGxXe6)@>AC_(9 zt~#dSA>!62$o$CH5f%c6RoU7BJ5`*Y-E|HIxS-$R!_TMC6WKa!!rSHtdaw+nr@W?H zyOBhYC$cqIin{MJbSpv9K)!cb#A_&!N4A#X2gp|vV(7Wb@nx}cEv^(uJE5;b(3SbP`&x03H8Mnop1A9!T{xZXuc5Ysv$(7 zSLG99fb^$OG!&l0UNl~MebaxN`>xH5g1V5QIq+{3erzyW0(4d1cLXQ$uL@;4INT;6V-x*@eBd9;90yF3`elEmp zA`zl>0&E&r7GJ3-u$VQf{{2!P&W1!qnpAB+^p<)iO`OfrTJaW|pFuP6<~p7k_d-)| z)p}De&nh`CIygDn3fe%YZzWqK@NCbjupiTs{g@F`-bn8bF@us320_`#`g(VmEQHP? z>F@E%7cA8o^VQJHVy7d1(sn5Y;Vz)C<)s@99$FJff*^6TG^2_YPO=bZB;s9!-IX$LZ&pXBvoe1*QAj9+XH zm~t(JOORoIZ+^yV6>any&12WhJPE@&*uJ#W*ea~qo1a~=daw0j> z075W_$(o>tDm_g9dzgG~bC~!Povn+(*z$jn$~P5=mEUhkS&+*qkCN&9!FX0*nEpy0 z@9m-$x-2gdsFPMiB5)QyXRWl!weT^%(QrdSO|t;pp)vVNKobwsuB`~ZjqwfRKNc6;W7~`NM3DNm&-7A$Kt|$9wmi3X+TnC(RAsT=_7A{LVRKE1wB;!SIOm z@Z*<@J%0*v3lc_nXnj@kAA*t^dtcQJX7-9iSr>a|@*h=fGgKnXxFx_0_0VSQr6cM@ zYZd`$hdbPhc;NFXS4`~bqq4vn;t}&PBf}mRMF9}!@I<+_bnRjRuk6og1-jUGv7%~{PD$nMQ@2MpOH#*^h~1fZ*EkPo6= zfQ1(I#qiuqLM@yp-N00%sa52PLgDVn1{QPtB?YS{Juz-iT`**olusBV$NY}~RNjZ`dx5odwsLAe6AU4$LX*W#71v{7=~6F$TPG~Uo|9} z7nvAgp;3J}>=Ju|++{`7G$zB9j6U$FlVXtO3=Krn036JqL!*YHLST;+APYYpWCVyp zy~As?8IuwCj>1q=AFLv|5edV>IXRQn;px`3fN@hkt>bo)tr)>08eyxvCh#EvPG0#r z04|wh0w@)@Bxn=J;-^j;6;`TX`mI3281EYo%Ldp!USgfd=*!Pocsv z08EIx@XTb1vAO&hJxB;@cAbcM2+Bso4D$Jpg`Q0H>o!kjF<3MC3ay*Ghw_p3q67{N z@&#VYNb*dsEn76Td^2~h<~K3)oauo8Y{4-en|)hPs@_{VP{d|Le*Pek+-=wZ0G*Hn zLQa~ftTKBr=r)FnzClYhG~SAk1Y9>Uf$B;gIl<1-^-Eb;rabWQT(s*urR5bnWnV6U z8PwcI52IP6Ew&ye;R{em>{duL35sk=*wm2e>sN(rO_s>EKtRLIlVU+dR%H2-((w)_ zr5h%eR>Wo%2c?Fnfn%I{#TqsJ{Ma;n|1gFsXqwKS4n9Dl@{XbCRdWIj3DwNseLCF2 z?pnnC^@7#DH}sU>=IUL6dI~b32p2jAMlAp+2@YEY_44*Yi<&}Y7)=qg(XVS@Tn2(=S{l>DZbXsRV^Ww5$@y z!WX87giM{|m9;TTPG<=;>7|xAxotTe6;mvNrI>JD@y3UzSnMIH?sX=SqPWy7XQ6F2 zeCz08(WHc;xzN-MGToJueLyK*)BISMT*a7JQo|fA$SA;wLk$b!NkkWv(yd76rW-5I zs#Dy!`|XJ*c4`=iA&MIn9Oclp&*chGc^8EbLN{~)yJ+4}!8R+GLx44>ku$KM7?rAP zgD4e#@TfqW8k&960TZ)BhzU_hy91nZ@E*~y4V4HjH$Ew<_JSM_YDX{Fa1!b39wPK* z%hX8heUFV497N3Bm!t)& zg8O3yR#I`s2=uqdScyqA>h@R(A?%)&RHI2~+FLj*_N-E7C72Hel-Z18CE%;aN@(6# zNyV`ea3)q_RGtL*i2-BVkfc)%;?jZS^DVhnjMyv%??fmH$DwoooUs9eS6Bn5-K7wD)N}P zm1m=pJ?iMpn4-J_3<(E>CE@SUnLI!%(pe&YTw+^fUh-7d6vB|2S-phmT$U^uCOpwRV1*g6H2;K&jpn^Jwznd(?f(?sRPal#Tey; zGTO3b(T46=#&}F58JQdBeNvY)f@CDKS&In46&@rD?XaOZ5EdXmb0P~g<8Iqi{u*>~ zpXWH#UI5Y9+Ms6TNzv(I6vf_HLFc7owg{L${VQa&<@cj7X8`Ekv2p5)HmcZT5~_W{ zDlYEk61$Kx7}vrpXP;y!KhrK5umI0wsPkJvcle&nZ-v=M zc^ioNt@up^aZMB{FeF1!i-7WI2VC$Ho2NmqBt5){vPHoP!+S5pE8NT&saU5_55Gea zGfkWp4nQtod1{8Z#5Ltz1sf)b9miQJiOVF-W``$frzMI2>>DJlgMi}k*n-@|XrrNN zQ0~?GDv8SC>)_l8AF74LenzuJ4hc3p`kfS+i<2+A9uZRDzwyS$V*;& z9Hb#3@4{&aUCq-F1NCgtzLjXmv^h7j1dn7Fa4k| zQaK0WSH5VE5)!FF&j^H>m=JT@s>bg`zmN(pV|~c&&rtLMg*70or@&(@*4!j&fJB9( zVGD*%frAA*1x^f9Rk_B@*@8->;A}yT;zIv(g$gIY!aZH{t?8LWmq7)u5mk>9%VxqZ zK(f-lNmdRM$ryweNU|CaQdU=!tQ?Slwwy62cqoPWZ<5t8UllJx)-pwEJkz~JaC!!e z{%ZRVv?O!F5WpiwPC>>ABte2g2#PowCx&IaA`%BYFgfrLYmondO76VaPMA?JNsczy zXtM1mHlE(EwEtY`sMzhky~j0Ab8Ie!+FWA!@kxA<=oXQ|I4j+{tf&ZX$9W}9A}n~G zYjOZbVF;0_XHu}`yl~D_hEJXc$XvVma)MZV1_k6RRypV*RSVi|!7(zso9%INU5p|* z6_FP96JNcs>xhuY>4!u!1D2(82qT{GBH=!zvz40EX0gSRT2tl(vso6~leb2#I_Bj} zPdFC1^sVCBV(``gJV8TPu@8>%c}UIe13hV~Y=_1>QpDcP5j3l7(AmU@t_%Lz`?uH*%Kawmw^oP6 zfgOFzJ2 z1PThcTvvr;)Ed0vk2a+o*!C}y!ZZ;DXRTsJxlBYfjA$OPO;#lI#1p#J@uX5vdjhpX zFS7e9i26ea6_F)DzJV`*z?LeQ6V#UfH&Y(XC=)q?hzT9 zA7!NZflA+mHnBjntS2!%`IISxF$g_rN3yD)eiKVOlEscC?m|aTI2x>cK~MJEZ(=Rc z{NO4j%?~Ld&94yDAjGd;GoYR3=OOEBeo&>?`~YjvjtL~Sy}eAm6{xbT`Qb3|Qrj6@ zwzQW}rD=X{_>OIgDh*vwrNfe=N-!sr*~ryR7Zb)};XaL3R6SGNO1?NY2n-*6EcB-O zf>k|hv!v>+(5C#D>IbroP1ZnP0<=s>{FD@2&aDOri2{ylY;O9h9!s>R>J3s>q3VgU zN~#`S2kJad$}&|i_Nrb9cf~lJsz<41svg`y=7Onu7fdu|Rgd9&KMUVb^$J$jSM}s) zu~pS48gT3VEcT*DG%U!1`uXOqSV*)`_57Tz;5{Mfc%kaWIn2gXy|VYj`TN}^+NSEE z`IuIh!DTdsEEM-aCr;Iq8dbRc`_7Zdsd_Lfr|N-KtLhH+%U#h^^reGFQ;_7#$uRYh9rF z!ScZ<)oi2dF<^iwT7q}uu7=Ped?d+_N6O<6!GKRp)%Q(32x6XcFn`Nk(oebpxpUoR z7$eF<9Ubq6m%$}bzCxr#8{yX1^GIf*YPSBeAoo%(XWQ#6o*MVk(!5_vf*0+U&)Zcl`@6mD_>{XgEB|`Q zgd}j2OLF?lFh4UD7(onp1-4x&rb;6Y2y0-?B9 zG^OV*pG8bfI%eEi&HlV(qMPVA1>#BZ?F~OO+`$6H@swxv-bF0vR*l{d&bKlJt(=V7 zXg;*Ze^r71x~av00W>G}9q%^tks0nSK) z4>!U?7THcJ3GGGlF+SA&x*wPm(V3OKDO0 z13tFIS87I1EYLhZo+B4dy#xp`l!GI}0{N2DnhYfE%1YH7kr-DR1+B`sUlkj6)k z7#ecmH}l|ykWJGih>#1>#z19v!9`0ybKsuwcqP`BSJ-OWAWSn5OO`Dsz`>2Y3yP4*sGVy}UU}w?-1I zKI6M~2?wJFbrwVx3t}v$?=y;n?$Q+A?b4uLrav#4;Jp%7@l*sGAJW9Q-`DE*%U3Vu zOpHZ8xH(&UD-5n6Mv>69%xoWUKe!9S#7pIFW~Ly6(x4(gs4$B_Y8H_ZEEM(`O)(Hd zcNS?Nk@eVrt#n9n@{TmB&W$Kj*S+|!t0kER=R`&75hAB1Am}oWKPU^e$3=^4c6tx6 zKUqgJ`RnHo$o}UDlz!dJ9bOV&;m%&$pnypoD&b~VR{ph2nzbdCV&cUI=%^5PLiH{h zFQZxvzCb?W5HA_TY_hG~5&VjBh?r7cdnVfV&m{9mO$F}SrBXC$>qBs@T;2Dk9!f1` zX2fy*SHC_>%fMKr`JrM$+$9=|YzoVZq5oPtN#5xtOHGoc){`tXos}VX{ppBlw5
p)Gg6jjZj1KwrT2WE)_8ggeEYDz9F26#mg)hyuWQMk zl^sz9j;OwC^9&j}PaZ_@S>3bY^17Dtxv2X<*sHtf>XNnJ)xCFxx+f_EAgAJBUBmA!p+sB)f2Z;A+7tVFu+E3m zQz6*wH>BfOb@GvD^|38b=gtUPx}m#<(da}PXd;i1AKJWuwvWa4S6|_F>5HbaBXra% zO(7ZY4|mt=dF4PCkEec)=_jX}vWu=g!QWv-FU{VhHrEKv*$994?c1jzuTj~d1N-PY zr5tCLjDSZDlC?secgN|DtI3L|q(|hmC{6Bz+fk3dYt(T|KU^bI+2L%MW*7F6!GkYk zVdl;P)kw38igqr_S_dc&)`|uxye1o)dIWYu@54M^XSLKHpsBG+c9HsGNW7IIDQJ`< zWDTD~bSW?xbH&Dj7Q$3;Makg>l{N^tsDWz32dvgb)QVJ#hIXBBf*WZ{0(xlC7PIl3kn)ILr3n+$bh7j>_*7G9~YGhI>JS@2C`J3iAmszl4yUh;N<|u}yh1sP;x&War zZAV&VRk|m55U`UBgO4lGH^rCyr9+$5IX^Pc0BzfVwlhJt5}399z=UA55!v;Ov^Iqv zY;CCNsjB;7hk{Yaz*3~;981NZrlvE@M)hm-B@_KAMiGQZ^raXwO>m?t$S2o5nvU|4 z36TYb)sE)0kaJ!Rsw}F9)#2=jzM%=I4hoKlu8r_2DQ#_OgHTc=ZSdX@i#PJ8ZfYn8 zWPWh@EFi!7K_)Q}e<54qlol1kCTA2-pBvFv0u&)#I`_jXbgYG%=X!e{Q zN*GBpngyX>c=$vouRG38$}?=HxJ#l?)E9$8oSb;$g8|cef_8ZokjPdVQlU(Owz-4! z%>AcX#qNufXPprp3UR-L(sxoeeYES(0F>f>%7Wp{LemMw=tc!ON4mBydQ~?nuC0p) zpvd1jA5u(Y$gTFp|K_w#bShDHHx&xlOwZOR?#jHU+-R2C z;FWpScj)>SZu|Y9*0W>a`dOmRLv>Q;kD$&3&U|v}yjSB<=uNRloo8Gbv&U=!L|L70 zp)WRtzcctis)PFC3Myhr%Q%SG$&PTMv!pa)Jw_rFU0Dk~%q~$H?dH?-D2-*#v1@>j zEK?eF9{4*_8mV0?CQ5R~PG27wbKBkz0=K zYSmX1GX@XYxq`+xIm0N}LgPP_&lMdeh!ql9uxVutUg^}&NvVqpd{jGl)1vpGV2ehI?8B**k3D@T3uh@Nm`^ zr;ALX7=|U!&p#r5)y_r^bVuQ{lJjXcN>g(DI{TFOA&*B*InZlUO2`s%0M#X;rrKR& za=lPTC}U#Xbe(<3@U}`zc~NQdXk`(fOi@WrQAiw zr&dL^P>uQug}`PKtY@Y|O-LZCw&sQkQYauTY6Ah!1%f`jGSQPV!9mBsbq?C4Kak90 z&Tu41)Fc03HE0oqIL5EY52)1?fWy!(^Qwg`vAz=Bn^>>qN=%azr$fdU9eJg&iDsZv zbpl>$J>e{o=6~U0QHh2eDny;|!hMy`3JQJBg0u{M%k(E*FlQOL%=HTe$;7Amr(oi& zm12z)&IL4znrRd)SzR7%CTj2#S+Pu6jB}2y$YFy@9`3~9Vwn*D%dce>GV7Z$Ralb9 zGVM1~9#0I~3uy0{^Tjh&OTb>0K7~|x4bB(wTgXF%fdVKR>8}I*mfj~(Tc%QEGDOj* zs(r%KfnH%c<~^6ID^|pb?~#LATe=)PNG^A$xRHld*tuMRMxo^aDQ!MT6!Itm`dnK` zG=4fsb8{t%4pgNoWUisY%Yz?*H*~jMUM=*W_;|OH-^{(w`NI~ciaKyO3#KkLClaUJ zd4p7kAq1Xz*?@zon;kctZ;*5gd~*|*IRKqqsdu{6P%jRmU_prz-Td^5a{bzFMaLB@ zC$e}S)1vlq6v;&>q=v3;0ZB3V%0dSyMl_9;{E?pvojcV(5~vyoVg<{)+t678X_n}$ z&{p6y3W4ANUkny>Vlv8=IHf`^4I_Jq8aU*SMMsrJDkq^4EYz&iWNha$j=B-Ov=2bk zRCLj%z*rEmT@ULhh6!!R*dD-DAY7SxQ-I=e#fyU(s#$=PFGk!rM1MWZ_pv68UD`4v zQusm`7D`sc{qzf2uyAMcK#Xo+S>GXniWPLohXm@t*(ZU<@ot>o4CBuqws4F3)P^Hu zM59cwlVXm<&Dq@8<($q9FVMxA+_d}Ww%9c93Me4rGQvTtd4~&~i?8mI#6HSzzIiU6 zznL3SxN(OQF2(HEZT7WOV6$&Pu+Di4eNeFoXP$ z!dG(y<&Q%029ZXgp<4N|zf;YIYIe1Ar>P52ta+zIR=Q#;uZm`($#^o0AgHJ7TqNb# z)Z82$`;T23#hB%kC67clyknJJuQPo-c{=ew36R>o57c^f7v+}|pjIlrzG#cU6xu<4 z7O$e-EAHV~?Nz$^EAn!#R%_kruQsjz>dC9Wx_I?hn^%AJBdfo9+Ul>Kwfd{)t^VrL z)n9!SJzzCVaZ$;t@07!AwR)dA&$~Z5&%681^A6d)YJXoi&$}<3=N-4It=i^S&hrkp z#;WxmJkPsF&hzf|ib`2!2^=}kyPrSLyI(rbJMzA)+TX99=iNKb^X}I3ynD}i-raVd zcekJC-TTh-?gQs}_uJ=r_q*qLhtGOdoZWq%cOO5`JN)CNHe=W`veUR@WIR-Y)-ooE zgKyu_4UmS$de7WIDV^dKM~7*<9Lkb;NQoeMLm0+hY*cw*8FPl!Zu&_!37tH_GXqnv zAS&rmu`V$(1O{z_0EZq)Tb@8F;k6$qx%QQ!uik2m1I+>Q=e!QbJkdO4ig)HWSD0W>8)&n=N&6 zr94y)_ktjvNHzo-ti|H#4`s9Hp;kcnbtNDt(spbT9y$Oo20*|=qp;0dhC-I;^!~6z zTY1Q6{3M~G&ARHh_YsR`5>Kixmn@eS$JOj6G!XUbTJjw|Ycy0xXc49`U}H&dz^@`} zQ0ibFU0y81wqcj&IBpQSzFkoNQ;KaDcF`2`X8kVqwvIBo>T z9ABO!U?9Kao-qAik&#jQ-_b+(L&l;T?Ioy99|#wd9}v2t^sl%-M!n1Z$Lip1#v$|I z3iQsTpzQR^BGq1>f)(^ypJ=03DIFNk9O;4bfl1KTcn|x@B{oMZl@&z|lujS;FA(!aAW=0_GjKnwGd{GvudyI_qI zTT42(HMZty^<^XhV3*2!(p`n;?#%~X-cVVz zfe-8Nxh?=!^2uOUt-&*N1_s9`R*6D*X*eCNBTjr%|KMh$3`kxrPdhz&8F~lV=t<9= zg}>9O_epMWY@WUZ?;vF5QHU=)N#;jk23a2y-Ks{xb_^^`Amfe@{K!_I&qmiiF6b}r zQ7Uc>(U{oU-*~cT0YVyyTd7C|LkE{cj8=l=$w9=zu^KQqS67tfMThar50v=j`_=IK z9lsP40P6JSXlc`JHSN|xkiI?=d;B3Qd|oa{Tgh`TgauNt6S^6YJ|gK6LifdDbtq73 z5Qz=`Y!Vj)aD4}2u|WBs>@_S(*wS}v3a&_QF>#9mZ5#Yor*2T17wI9en2hl~eS?OV z{)+wOdxE62h*rFRwhxuQQFQPN5g-U#&~1>uozii78@}BzeKYZweEb4Ou^19Ol04UP zD~4N?WJPN>NPkm{grtqyXNbtxnZ75ACL~vg z)R1`ei;=yHjPR57dPwYX%10>#+CAq10$RbkqzKVs-xO`sJgz)G3`xMA9@PXNlhz{`c<^54 z$uR~rOH_@2kp75MhS!z!w`_X(!c5_n@&KU4q_;M;^vTfzp~$|s(-T4) zhkZ;xMD6_fzDBfV^7Ts0*7WB@hlNU`)4=-SbVOpo=aOFy?a^x8NcB<;)r6h(^e6WeQ1w>5FvMGw znbQDE?S!D}Q37#9RWw-=g7IDzme*Fk9Y*l7L{UUh)jzJurh-Jl9M=Xf+!(s&y zi$&W`OcjT@(jy`PB*l!hUmJz4S!>R~{#XHU6}o`b#0()U6ZE=z;n&3TlmOPxn42TI zRO^zo$j}+YnZu&+6D}e-M8U#nf^y(Uj^!}ykmpRN+2rE#N>xP+MHBKSQUxSt$y=i+ zoQv755OVmlWa&=Lbs7;XC?6*=ox~7!!VWChab>r+^5n3YWEq4GpavqslsnglHkS+RrI3t4(A zV9#XFE#EMXDmqC&P?fa#l-I!D8A${8%Aledau6tJn9g)`EJ&Vbyg6U^2Ob3d(^XE9 z&yU(;V?|O~-YG)OpX1ej@s0Fd)`70}6onLu7>}2${kKLY@wL=~+2_HUw1Tpb)hBhj zBr2W2Ll3WZxZlZD30#*vpD(sEd5vjKZi$bvzU?E~ zF;UH1iT4dS|2hY38e))IIBKaIIQuc0mYd=exGA02*y94h<$~VnS$SxTR$baeY(m{gme##l`2wLN6**7ct*ZMQUJ6Nf z2-CNOouIFv24y)EI5`9_kQ|ELxsFICQqY$}@B`!!TB_uboes9|CWokLa>yJULRRFY z5G!Pw?@kb@c?3~3D2Uu_=bNU}_g2I-4CPugyG3>;AXpGA4nutMT4$x)@-0W&FinSy z&7Clw%)l>{OcR=3`K91gVCrHs!1BD(XMC`_D`HWQLsK zddjGJQshJTg>K`1!9Ay5e{6pK4BCM-_waIqp0$?;?!H*-?e@w>qv`y!0m&k$`Z>H^ zy7E>E758Fstq7mlZhKz4YPWUlo+rN@$*U0O_ngL!L1H~dBIcvi02Vlfx`qaa6k^XB zmLt{V$&JQZhQ?c}Fl%hCGGI6nbn`r?zL(YdN3 zu8s-?@D&i})2PQTjk+y_tvug)3B+cvXxOw&UHR^-$;PIv-Pf)=$gMP!>6bKZZJoJY?{CW1@7vc|PkqrG(1+ZSO9dJY z0p~~Luj7&OnP#y8LmBmG#rl9jIQ}krM=j!&qLvNuweAwA9cIBCF zF{%PpPuHEX#M0>+X#nR^aSk0%bcgdlBfm+&v*G-!cKm-h|GaJsqpsvp_-_bJklxqe z2GRBDo%Y?)Z=YtrSBnYy%c9%6YgxGfC|X=;-4^t%J5<2cDukVjhve%>(#Mwny9q(i{ z>a0OfUO@X_GBm8~xVR;RFbX2!6)emZB^M3H)mj}g7|zq(`8O=xKuxl7F26bAUc8$0 zg^ah~U|z_1sh_#~c$z*g34cVFhpLKEE-UIUL?Z*W#nFwJMKXOB#RT&}-bKo9b3q?} z4naUTG;#%YRicPatStTPa>=J%)?E61fY33m5$PCAk}b@@HHAnSp`zN;Eq3{~j!|RS z9lad;VANjlL~Bd@gPWaULI#Rr?M983S=M57%)7=%D5k7Q&dI7+puDzpFUDr0*ZBb5 zEn!WDwxO4Ea#1UzWvr4VT~S0GSBZ6+e6Hg&<-gIM@&_FBcLjegzQ*zzDV@$HOQoe1+1ozGwJ+Ic1_jibG zSFIUGufP=uxbzB{a)cw|R4YWgZwcpjA-6)k~6w4f6mk}TLI^iej(m6$Bd<_X=~2gV-*hJdbuAmZ4@x_z8I zdOIKqtPQ)&ZK78$b-KFfuFWbZy6ZSJ^9mH2f;f#>&_Y0`?A;Q^x+w~!m~i=-T~t-c z*I%Dk_j1^FYjD@=?3O^Tw#w>zy4-e8sMcc{fuEi(x3vYAv#1HDS`4l-B&8rJ3x=Yp zIgYb**Xcae*sh_7#o0VDMYLo#maRLyK$*wcAw)HnjlY8VV3f3~96e1oz0})c5H*z|Qr(N){N~^}@e7IZ6zjzjI9w>K}#R%USo0=nBGy$`t zw|Cba%GT}gaMijqF|&1$`HCW{NzGv*1-0gE=dY2iMb%fI7WhytZuFI|xU&?!kzR7Je_-j;9EE5!Hu!PV$98@0vkOh6G zm7C@WtauqrXfgoU@G`(lP`9m~ptdahME{yz{aA5s%nMzp*R5o4HEVPoR55V{x@onT z$w%eaBq?Vm9b!fK42_dj0XM*#426Emiy(r3cG)L!s^CqmNn{lE%f9aTPOgQ}E$ibi z;i|i;Q5_y*W>>n`=cNae4P!DRZbDOURyOD1WbxCf2#cc#JO-PqT1F#gLrixtjZF)2 zHYhjN=-v$J=|g@1oMszA!ylPYQM*vSCAUhOKUy$zdR)UO*4A;1A+67mWS3k#p`0N;|F)Pg?3Sy+;5CpcyWuy{AfJ|NHxt? z%io4VmM%se8gd)DVKN_D>;_8R^V44lyOy;RFF>T_63QD`kt#_V$$Kr3R#rMMAa~mY zWy)0$Uq$*WI?QHopik|o(;`|YNJF2H5RX{e19w>F-6( zb*Kk4fIs#6{OCi3R1Chz|NOG0Pu}*a0M${<1-R%;u**%O#ZHuNkgsPws%yB!dfj}Y zTP5%qCAn(KyX606ru9bo(?mf`fI~v&9QVH`YYNaY?wqe%wbM5mYRJSp##e(|WcGn? zYr{`P)s}+9aXsDVaEVJ7mViNonPJrtH~8j^<0SdT#x}rdq(=NUr;5rk0K#7%8em4e zlyPn1htW6ZiFGwKKf5vc7-;gt0oX*{4D$QF&HcQ5p7o#ipAPN!H}z>zI_bv>mvfRl z1D~#Um@$U|{eEFo#CP@{9ciLS|EOJ*YJ71|7Lku>cdi=4|QL%7m zV@Bqx04A2O}hvnGoQtR<-i_6?~Z&c`!6pKT`AUCQ7FsX=%7bF~CJMKCh_7?hQQQF0@! zB)+cjp=z02GpSEp}&CNnV<9oRaCkwd0rf3)& z&m{M15ZX$VngY!WLZX-Y5JG731oKfq2zr)6_~~dMuHuupJ%0f5cAj__R}o`5N0TtC zBUQ~1U)awYjH`Hqd>QG_n?v9N<0=m8Mvz$34V&N#Tb>7PwWSY8KN*Otm|PKujQUY< zXhRnc|1P8j#>K%c?G#u-^-YY)IU&r@uGxiJ3=bqp@X2*W58Aq|1&Z6zKPmOWa1?}y zIXDdZoP-F2*Ef5nZxFe*@>mKq5-S|7Ms!~X<3amky+?l{QP6wzr@YDAyD9$}n@8Ck zDqQ1^CNwsPl?~DRc(Ox1$hff0xj1jnun$cMrDilP;tsLd5&&8VY~c^gaUZ1b!4)am z%)jY^$P|J?%WjK$d=%k2@MM#oyr<&sB^A?XfIBwYFNt*6I8NVP#m;Wz+q5UwKx4>x z%fzMsJL*WAg-5nL+M4+n14Se^rEGA+x(;Z!(mw-ZEj)#2it!|HC{sRP)QZ%wzhrfh zoz7^kc)}06#4xa2$ub56$&Mj%)rqr3JBI4y`eISG&`R1mOD8G8qW?S!w3n*fJA8lC z8A`HL1&3Ljqszd^hH--6ZG_O%FS3W^!Bm>I>6}d0Q4ipD1^yuqJiW{GRSa1+EPak6 zahfV*Iyso-il;Y1BL$W;bpY$tbeAz_Y5M08oT1aE#TuNVt-$Oy(4y$e$_#jJBgll-KuSmhJJtf4fHzgPC2|e zy4;Q@;An^TelvDVVV?cNfHBbECDDVSYyBa}G5s8r$!g(*2^=BFzXgx`OFGO?@nwM{ zc@!z)gJRnJbG!nVMB4JEjBc53^9lHkcru#g>qE4oocJPbiL1>j8;f3|X{Oh{B8S!N zo0+0LiaaX!!7JYjZQBmInuN47Fip#xyx}jH47LW}DgYNGJmqT2GY_#0B6V!lAZunf zF~}GpU80u>s5bhdYRzz4wcYFu4{~vx#uAB$WJM`D$_;?IO~1gn)vhq*I#l#eCH*E$cRq;}g`b6YTuRL`GU#r)^T27$9pK^L)>J~IUiP$QBDjHFf|8f^hfF`!^W zY`RG>nIRl2m*0BKLKfZw)}ky3>YIAfSn%C2KB(9z8e(qa^po6Q8x^IDKEPj_szbH}aL!b5&8f1xDZ#zv&Qm6`C#T&v*ihca?y5*JH|#+V5jU-h%cPUtHQi_ z30SV_M`e&>Eur(c;6D}i%BX5c4uAl=w1wYLicB!5PKvy9fT#?&)@X92>Cg+SawZR7 z=+2O9ame=Ym3U8ixA?*tlz&;j(o>QrIN^7X6aJN=TEO`Cf)m~yMr1Gb%&E#knbf~* zaGBJWE|Y3+nLvqtG1)S~I3HLh68eAzOY3d~aXFUbB8yqug6I>TrG zb8m}`3uIA{``aH%tUN(%-#udca`dmm?-j9qHH_kwxN?u+^aWOrr)8UyhxnsJif|`S zFt{N-?_Nffo_BvDQs#^@QLf6njVK?5cf$&mF(TIHs0RX0?XntY_2b+$&tkD%bjfGW ztYN9=;@Kz2^1DZtfAc-m2EY8zmn_NiQzpzgQ;1e4%O@!EyGN0K`#qG(_bsK!0|RpT z`@<#&Wp}|QSC-vUaUF-A5)Dq_so0Mr*z-lM{dG!gJ^4aKTV~QXRx^=`(*?S5MjvJ*lT9AZ?d6;%l2i4sa0fQ;Gf_iX|09PRW7m^MBN z0p2&|%R~EZ z+Hd#l`Harwb*3L149|c$3W|~9RuRVVPLxI}m!5hy0GSbw0CjH& zNb$EfW22#f9?i ziW#Yx3l-+z?>Lcgcy*LT(@|(rE`EZF)bu*1qnJjrHTW#gw+4Tq zw@v{gl3yp{_%p6QjCds-1(?47I*RnAo{qA%KS@C1hW16Z?!> zT5Sy#d8{usRAi)v>SbNxUbiy7*lU93^*V8~gd3Pt+ivu-*91oEwRgTZ-D_>$c9F)u z36QKZP1i(2XHJOdAe~CCO-;n>{gyqRGrjLQ5hJ@!glVXg&8f zs}TcGmv<0dOkE;rl}W6@in};S-V&dGgU-CHEM7V{?cBE7^{r4F{|{=TtqiG-_Cn`U zi|xCzZ4mX$lE=7xw{&ge)wlKTx9`e*$l-6Bgi>wF+jrc$76MkWeV3yz8npZ|b3+ul zeB+LeSP_65&S;}h2?{zPTO%?9wn{wyNGGoSwhseo+SJoHIz+KeQSHLHW%D_R}#Bq-2MuLVel`NAIt`8PfT zL*?FWpT}S#y_=0yQA_Mnm4&E!9D}sz2GIAhh)rXK6?V`+X-i-8@$@hR87a!Jc+A({ zV>HeDjh_%;)Qu;td;ZWfom~2j+`jPoVN@_Oh{jg=K0!do>IkQRVaWN zSFD2zSOU~7(fG4nUY9LV`fL|RyCrIn^u*ji(q1E@dZEzu4hn7Gk1evF?j?6{3aZ-{ z_dLVS%u3kFs$vKry2zVdKFQ>6@yI)>jYy2}IVgeY`ZX=Ap+PS@ZD9ku|4Qimb5^nulBn&HsPl zF%Lr~gW)j`hph3(7asG-KzIyU$SyoQW}eO1?^k%tBO?5z;W6*SuKgz;9wUDY9NKu# zbaE1NTz)lOO4kcLIn7GdGQI~lhYLM{lbf4qJ~k1jJw-jb8!hB!eR-U5DEF9>dYV=q zUOf(_PFJhMq43HHvZyD>Xfk~SHY%ai6J(N4ck4laGgJbtmcCvou!3BbpdJ`t5>2{d zg@!2Cl@o$}*VT6xg;E~$N;=>@5v*`|6pCFGltsz&d%RJ3#3B>SF3}uZ_95q`lDZM5 zzbHBHLP{dfWFIXk<)Nr6Czhn1T6puapp>shJpq8usGt6s$y$_GW z5ows(#aq=odIy#vWiEUN_kL46?<*;uG_ll!a-lo8cbIpSCZ%`|?%>{`L2Qoh=lSO7 zKE2f-1u1{}JGkB6f10;9&paI9Rb2`hDbJ z<$c7nWl8yfmy}h+i>D`9Mih(!}GH zl=qmVq)8_!%ln9i_*Y9|n z>kcEmQzg=4k7+6CJ+^HwnuPQ&WSh%-235g(2EU_iuJTw`ny@?i6IN_XY&k?6R5_3lrFXVEonB$8>i7`@IQAGHv3FT87XO8E{X~<%UbVxT3l9hK;ipyiD z+UAm(@-;T8eh(ba9n7k^aX>69d$0{;9#uc zxTFzBa%1WnQFXXL?c4v1XhPRh`4WFxF8&$(?d&qB#(zSAYcpK`^DX?;?dqu5Rrco6 zUs19Q4w7st+GRbcC;d-jhU%#tGXtBQZ*plsFl!SK1ZurBbKr*Dnj^+34K z?U0lnxcEk_7$LcjCl?o%{9sRG44EZ=(aJB|Z0VxA*)$ z&X`)g`EZu=y<+MdEMtSQns3Gc;$w1#h=6+f_88C_`4P(LPjUL13ESMQ=x88~YJz^v z9hWo!-Fa#iaff=I$+ZfQ&^u!AZ?b915_Q=>be6%+ znHDW{883~$5GVWd$>d;Zh&aHm9MYp#RpwX?p%yv~vHrFNU)-tL;`?3_eK5a)_Fn1t z(%JkhJN`M=kMf6v>2Hxto{ihRmWn1>+Iv?`2>$qI&I7<*!4e4SK=7#-IS5D@(uaTz z_eX-+{Nx7#!FHwkAkIdmHh!nCPq!j~KJgZETHA5VlR4Q5H)$S@d@^Jot z)V&RyT~&4Wzt6pQUe6?R^MXM_@y^vK)&zngF99?s$s`$>%*4zDLC|qX21q7vOeVav zwZs|~6)PfI{uU**C{a;UMCExz837+@MTClqN?WQ_&|;-6^-mvBp6_q%ea=01-ZD|! zkDcV)v(J9tYp=c5+H0@9cj)Ei44*UdW&74Pb`+>|!ALr&1a;K~tEFvhpnX@fRi2%j zR8a=o4LTSG{PnqLBU5}N$c$kG4RXmpI)4~(W7op5cr#5D=|0Hj;zCj}17$lWi?t+1 zx$xd^yDHQU2PKbaD>xc4K$3!pOTo_fRK!TfoKPKBjA}bbAV8 z+d*NyX)g!V2u?=#T0|tZmDyKcnfMmq%C#U)mQI%ymeY$}G+m4qQ9@2eXn{U`xd{4k z{tXLnoVceGq+2+8NtB~;9f-j~mRf0bCa%33sHH)v89k!RNdUFZn*eU|fmVtThj!{z z1t~R}Ds5^fR!ttD+M6)kwY7sIqdPdD3HmJ>t0ng|hGj8q4P|nbVth#UG5a+mFmXO$Sdgk|49>XB3hnBRDXoq9NQ={=fX7 zTF}OBBVdiX1CE*-UU;vD@(+vECR@lRx@u)IE(RDOAu?=~=1B?4Q?~U~xcnZ*uYj+U zL7?d^@#l+$M!&_7JCCPi!S_4QgM}jOG(AT!=c(ht>!IbuW8`SH#)|RAx5kQr4`s^l*XG6OtO7G$!N7fE{GCR2?l*+}PDTI@!H(yp?05{8 zxFXtDzPVu>M=p*g2e~B{yTsRejx17dTZ`Mz1{>k3H^HApc8V+Z-t+1Gi(YGEHGJ%? zHhJGaej{`jbXH`Du*JUfJI51#Q~4&5Fyit3$8Wr;{Bd0_GLhZqYB)8+T`{M>j^p2y zXZb6lE2~9rxlg(NO;fY|6{RaDXZv^N;4~fQU-4x(z9u==zoIz4CR4Nj6^)ZsC9way za@Cnq0$A~;!fWZOBEXnZ1X$4=N`VMY5CLvVaxws*Nuek%G*JwI|HG{Lx2@W^?US+! z{-k8@Pj=|^CHaWZHbB@prfEdvx?i#YvY$TU@PS~^RB5q~rb;uQw4p<$3?R5TetSLb zolY<)-3${kSt#l#Asy%xK5$3UK{J?FX$IYD;z9FknH4pGrkWDM27`FO{LOCbgQ%0P zRQ}6id}jff7i%HrDVYBy&`)LcJ5(gO1CVW ze&IF)Oo=oAa!Z}K$HCZp>f>&fpEPsVA};M&baL@(-a3Ak zQ72Pd6Kl&KEh2IeQJI`n*d}x31}J=!2^#bUI}$5C)F4B0zAE~;4t3g1wnNeq=Ykb- zpcvEJTp!@mb1!|OQn;gw!^k+gQRV5F7zXq)9FRFxx!gUU%Q!3dW1-yoV3qsvA_T!3 zDpSg_wCMYwBX9MFCKQcZIoZdUa%-)6N9Jp%S}6qt!m25eUp4oGlTl-bTQf^S$YSSR znm?kWt!3Io8>)u5DgewEtQZRlD}SQs-wYARl1kw)c22YtY0>yV)U`vr^y8BK{v6koUGHTFX;JvS)qYU?H4+OrSdeEI_!CnJFDu{{^ zN10=Ds5O!NanC*n&7J-6Xf)66U@EftSa~ruMvhGWk4t_8nl04Eg0DD^m6MzOe_z%- z3ODigajX%C@_f}LkI5%i{j5guX_;C``W_k1L2e)tFDbfH*>(V>krXXq7}{0-WP?Hh zrsCS|WY7<`kwSwJzl)YAja~AwgDG|KFiZMVUB^4)k}P&s(pW>(I^A4umdpu#%L>a2 zfV-+QKp}eB-4dFD*c46pYE!h@)TJ@&+~(MlbL3mKaX5)|7*Qh``Dq%is5a3I)3m9w zV+IhWX;Z~$wv$NhAY9GH;3S$Obu`(*Pfg|9+3AdzFeN($*5WZj^6|b%JiKc0XnuZ9 z%atg8dS}yGwH%LT-Qj5ST7ot4o23aN_pjI;2~2o64O84NKRL|ig>8No=+A0m{vg5| z{KR4dcsZZXW`-@5*#d7H|EyZ+%uusY=1EKp!pyKeO{o(Lg`(w3yHffoAscmogpTTq z<04&5D+LXz$qkG6dI&JnB{%IOXBg3_cgv=DLWR`dRfI0$s9YW1uNuJuoL-A%1+P=7&~bK(2W^8nXFv#i(1B6xu4Fl zlUlIKJqSDDAX2tSN&ApzCy;x3kgMLRoNOs^N#s9Nua2FlR>n>O*UQ*RV?YICCyg2z zQhucDL|0)-zA|>wOxGbo<1;loA#@@;X%Z)C@$BT_ICgR-SC2-z=dI%B`homvf3=~A z_E?`>EQ6Dc+5s#(%!!upLa4xDNM=gp8t z$jG!SIB(Ya!#*GJcYh7%X^4t+N0N=FU&XoX(5pC?`BfaC#Nesvj_{_0bk@+2C|p9% zWV)lzOLR$R4L(BMI?ioHI>4%{8AANC@w#XBZ)Lh?tiq<$J+rp0sURqUmY9RH4@3QY zYn}SpAFYA<*@Qjgoyaz1JQMZvG+71p^E5FITm7ttdOpl?k>bLcq%kuMv~MaJXf^c^ z8ffaB(?I)_XrPty5E^K!B_wNdCGwc7mD$HL18AwFf)yr*u)`JW^jp;af!UD$CPFk zGEUdCPqE*kT&3j_&6YAsG<$l@*=2{;oL%NMXQIh@)fwKDP*a^LTm*A6-5JoGR(A%? z4%LNbH^kp51m&5R&w~bXTIE@Q=QPSQMhWUDKT7f-HSL)NjsxifX@X3DW-Ua2#(R4G zS&FvPDbPIHT9s0?HI<2>ZJi3uij{O6^enhgN}B2nz}nk1E=idFv*p$yI0^PoV=&rqX2*O#fSYer@t0qpnnkRv)a8aXPeplncWq zWvW9X$qaO8S501Ssza*}R=MMKXf(;sN;sC|aJ6Vx6-MX|f9% znrUMEcWY=&_{%gj5;$nKCbWlC(&R;`OnREBp2kZ-=xGGxL+ELMR!&djQ=+F)%87a! zX=#dHPm`*sata#M7t)>N;a@un-a1^m6DCaK^f+x`MYYA(H4~4K8d(%W6_o0ATC_#k zYkm-VIdwjjrXixKUT1od?k5@9s%>CrzHJ-W(b$Xy@+C5sFv2I**f2y>>NT0_MC3^% zmgGi*_+eaSDx3OXg^W|#)Kf31Y)E3O`O~XxM4l!oH&xlx2dmuiDw{m@I$Wg<)Js|$ zYMN26ptbSTYn;{w>NOL!O&#^3ZFOoJqh5Kn&HZNoTBBZvQc--Nm{(C;m}%H;n|#=( zj+Dpoc+Lv)<*uH``*kCNs0D_PLuPuOsp+hXvEe$1^EM zR&~>q^A0pG%Gw6aRONiDn75#T+F*aCc@!D9VX%R;Wrq&Qr7M1PA&Q?0m+Z_Z6uFTN zbToHT>TzLTL53bE+H~fU9TJ8I{6m`FyNk&pb-boqRn&7Vp-K}hT0s=u8ATM#YrZ1m z(Cb1gK8D^xH;@-Z} zQ?#gH8p>|O0EmaVC(DBYj+aHJCJ3!iH(NgjvPJ<@FGVA+0hPp<27*lKEhB2MWo3&w zjj^;#0FPfHsnsPHmx#@&m+4`oc2Crbk6iuZkNxdm-*?S7oph3{!Vx;g3A@IkCMxlyBl=88`njl zucf6?`L8(@R!yXzd_AIgIU|ay=E`?gK0XIbfGu%`hc<$0@7YZehB-72DQA1qv{Nwt z^{RzLoU7K?W>T$ETCM$%Ud=jc)w-dOt5%z@R^Q=5t06&&ovYN>Cst}j*0D*ce4hwf zafw5Y59afwnm>ULi~meT3^y)sb3$=?C`aY6BQUEg)0*1 zF7sT5fzAayDxrjA3`}8Epz+eU;Br1H#sHTYEs6ZSQxRwV(yO_&6l^A*;*AZh9i+D7r)W@T_~!h?INMB(TRqVZ)^u1RQ!-V7W} z?`RQin)yGv;mdA#_NgvfP+HKips{Jef(5NS3ud>M`JH!!-26FCrYtU45G`n4u%IPg z(6(UKf_TA#IdkW84Yk?=@;9Z(-wg7%9qIkSzMTKpifs$Ds-d}=4M1(F0GKjBXc7fX zhjQfY85xthTuWn;wzpB1I;=zDTNr3ay+V&>qb(f;H5`%?4JXH(2?gdDS6z<@c?D*o zn`l%Me_2-B5vWyGeB^sy{MemOeC?Y5gqR4Z8Po7lH}_G5qh$**1W z=%HfIQ$?F+P*E-kn!c8EXPOgDjt|x3Im+zlan&kL0>7Vf`Ox(BDl03ya&vrFK>onx zj%Mo$SPdI&e9hp)zB6Pn?mGi7L;5zBCe5zvkUe|ap(-|;jxrqaBR|qml8C^b7*K-` z0&T<#O>DILvF=B=@vkfr1h}4Q`F$#FoWy0_3*xG%qB5@GbhBqFERukED(yXmVKL8; zm9<#SH^n(I7&@S@(O77OcFzcSR2AzAFgIz_3(n}FMo3BecJpmcV!^|+bHd}ejk~Cu zk}H4dj&<%NClr3uFWrmX6bKuq=*_&PDY^QWx;<6`mTDxZT<8WoTZOy$^+rfT)D zHjX#>Ks-IyU6}G`9iNRt-HBJn(x)AT$krk?^#mZA1c4iKKrDMo73u?sw`P?h1 z8+vn{dE{XcD7$4A-c}nE<*yfY*t9raeXWhF(eHV#)|~P#9q!$Th9Pw#{I0h4&JR>T_ zha+*@&2bEClZrgA@+`NA^fY!!UACUH~4n#8RVp4Ii=F-@(BzO*hUasMhJP9|}u`%P)P ziPVJNViLFVx+O^5whhLD{q{>p#SA2FJ9x03cpXCGK2Z{PIQbuY028*8dw!*JeNQeP z2|A7icNzC>!HupbIT+l+$Qq&0HL2(+@As0p83{DRC)UTwjk8H4aVb1VKO?EvpExOY zJ*hDMt%(BWa)!?#g>jCc{EdY13Dv3>#=kR@YE2@Hr`7s(h4H#-jTgqhJF!xA!ua?8 zYlU%9gPbt_D+%KoGC>%BpeBqn9AJxiVO(h$9(iFrOJ669Kfo%@L}C1w6f>1D{?j0g zFXf)@R2W}8K^Oy{*Jn2lGiD~wFGhHpPM)`c@8$WxVPQ1c zaRsm?iQ$v5#7X3Niu!HI^S|V#(cg|d|Hv<0viO-+HyO$=7Lydpn+(7IR}y7){dZGx zUB;x5?K37lagsYf&B5gPX}fDi@_bHeV24X6SQV;C4UFz-DwK`lyu6>)E1Cqs|BK}P z8PLF*$e&iQ{M~wyKlMkE9{;Bk`4@YUf2nj& zrTAS1uRGhT={r6WVV~0ekTyR#Dlj*|t4-QBG_B>oV=^mkXEB?e;6REr!+gzfm4H2A z#q!nCC!#oDj~M4(paJG}bVsvKSEMM!4=MEF&^Bpj*3j%X8&H_3yg8hLIHv9z>_}tlXF}9@uNehI9QIzP zgVu#q?Np45kY@8LEpuFCpDbGDI4gmPeq%CA>do2g)Mg&1jUI@_66rrK)iKQ|nv%Qx z9s;yzil@!Ij;0jbNzS4LG|T4VCQ{1+9Lq|-v8Pz;k^M#W2%wWyjfWk(DwOBZ)=gEQ zDKmqjj`zqqs<;AyzDy+)Ccs$VNHfL+(k#sXCeoH5YTVJ7^(Qr=UqbgAKJB+FCdh>r zsRPiv-y^HOMjd7!K-h#P`wFIW>239>E+jvw(M6fw2(|t@@J7(buvK`YN!x!l-q10$ zEQ%X+Ikdm%eqZ6JxDBq9a1}W_wvUQGP*YFSb%o_Hsh@LKuQoI2qx=cK6DKNv1Z?n^ z`x=r*<(ms2e;G>@?6uoudd$1Is!5@Dx0OF>2qc4Kx*g;ze@24>tVM~;=@_`1ww6C? zk;-o&AHzRJQu)(b%5lD;fAZG7m6O1{W?jch#e6#+qw3F9J76*_zko|B7VXvJV0Ann zH>z7IRo*A7Xt`_6{t0Oxj{MF^%*6A}E~d@CQX>f1O>FktwOz6N4q9^PW_z^tYJX`- zDkUh576VOx+{6rB&_y8uVhCH&C8ax4T zcSJgNBr3mCcVZ|OJ!5dHL@zFQPyv*86@a=rs52Hws7x(+|K^2nfdGHvH7e>bvB>H9)m-^bVy7^&0MO@5*S_^!kz zLFAaLo46-22p6naA&c8DBcDBe(uT^KuB0V0b82xy8eI_Y-BDpVE-lt;7>1ab&O@V{ zl6RAgM&i2GGQ?D%{8QU2+mt;1b+5~On}YxG>t30;SM_faedhNa_WN_URa;}4v;{-L z1{aYiim#hWl(t%xIJR(YWS}2Te(2bFsOseWDEc#z%$>9w0*-0#4h;+G#Fo$!u7gzP z>ZBp30lifg+t!x_5XN zD^%O5OqD!0E9>NHajQ3kP_77?i*xy~E(>bIb)wGdV^demj%K-L;X2w}Wn2%lSG1M) z_j%9b{XO1u{D_HEb9NYMKyz*n#I5}EVwHnYifovnS4z;ZG~j9Wj+wjsR-mD=tfM(X zs_zskvnK}5BR_wwo5|NA>#Q4Tyh zk|x-4WQ&Xwj8v8qPTlC32L=?S*)0NfzwTC84#q$rW%^J<9Lyq|4*ID5^W9k~vUMI2 zXLdv6O2r1&0g4Gb)V03A*!HFg^r$Y);`3jMY_N+LyK?z+4Z5*0AbJfKu}ZY`jncm6 zN{7VP^6Q+{IBAC308ia#vr>bi$x4?MM`bo_%}$lkfc2}tjebDShKebA5}mn_72QT9 z$7rxV`K-y3+ohbdNUrGlH#m8al(deBJ3TO#+D2TEog)Uz64Dyh# zq_DaYFL48jTf?bkB;w*Se@vVQMl7lMXGJ@W#b~Zpt?3ymCj%jJRRSF($EHY<5c_>P zqFI1#1u484iU8Ld4vfo{pa_*1)`aCxrA(8div*WLe#$Ljcn+6;QS4BJYo%RO_0r)z zUxHNmy$ytx^n!s^=HL(~8`dRL9dj!4J&w-Na!J}aJG4!rDd)GTc^-Qet}4-%x|XrM zE{ki8%b}3E{)cAPV+{c^HFPj&_*3#K^Ezi0t$2UtUR{Q%b)R4FWJKs1HmgCtAZ@$P zY!GCd1FYPXwFOSU!0m@Jj`!4h|_EsRYVAVnMdx(!gpTRzc*d@=w7 zUg67xTm(*9qAVst94UZ$(Eb+RF%qT(c0ePrgI+2)!T{ySU>pbDigH?XuA7}$US#7I zm?h*3@v?J0Ti2Oc+7uw*%3V*Frhao;R;vh^yNY^9HQY=$2?yzHMnV}bmWAMj z#Pm-EMJv;LdGOHP%0{DCY;%_V&bHq+`<-jQ?UHOX@fG$I0TActh{BTf)g{e~aB8M2 ziK+bKXw1)c`S6Fa6#!&Bn^+b>z;*EtB7ZDo*jwt#&uBb%khvJYTBX@4i&lQ7(nZBl z5R9tASLk>cW)ABXViIOT8nYH9ZlP|+>0TbkY!wesq5RpX+GNu&f~0hC`|!AT({CFWt@!P5H>X%urp9}Pdnoh!KYaM6_W!=TahKzsI^V((0yN;AFM{V+PzWw zRBfD53lrq%-<1Xmm_YoGE}q!NI~u(0rt}rr684qA$RtkQ5+^wjLmDF|&4so*Yi`kk z3qio97IJy(JCIn47?)fn$(e5Pk^HQ}aTzz@S4!J5jb4N~MQM3%o`tI7oi-071&l?@ zyUexY}C0UGR}bFy%%)TsdhTB4VT7}%z$-;V;BnT&D6}R zvHU(Pj|)%_(C*{xxDcW?%7`lbU_?b~h|4t%qNbdD1p7Qw<3uiwSYXD%J1YOXOb?i+ zJSFoK5Zw&1u;tc7qU0eXM}Q1T&?Nka$+W;lvT~tn_g=OdA?t{IRsC6azMfU7h~C2> z8I~-dH8%>3RGcrZuBpRZ~}39OJ?XRAQmR=#zKrly)PkxCPCU{Mp1_cdDO1=vA5>NGz5?@m-y|)NyE0Q^Q|Xy; zs4Lrnw&nL0d=&H#h2>tW1GFo43a3;eD9LOqFBe{-SSjkzOK1}WOClDoiVX1?(VESe zh2o!!#-aCV@R{i*c| z10XC&Wfa!(kfy+^JpgP_1?l`1MuvpGYt>W(;!$e3*Ydo_bUm5dR6~AH*_bY&<-noA z5tAsn^>66cLj9r1i|0Um>yA;b$S2!cE@NPbt);)&r$05*#|E2rz$4h13X^j9460RW zMPPIVt2msbNwp|#jpv)LRRb`>gTy4T%2U~27Hzi^E@LwQAbz^&OMH^4a;6q}9Kecj zJ)tRlP>bASx`_Mjx26^u<2$HDaB?{vRWh~69T8);DS3ik(r80CQA|(3nvy&Cpk8=$ z+&I6Fz+Lv*5yUmM$mbROk3lVRkjC(N&|-6DAMU-B$L5lms73B(`~#8U8oJww=r?NuD%Or4avM#!8ZW=Cz3_W6_i(Yb$ct>5@T7!dYX}C`l9= zlq9EbEk9N?CCO5ANlEeob4f{Zq`C4+l81tlzB?+acN|La4E+q*Q=W!WIgojwAY6_>DD`vw5pcsBWEPEUTA&tlB)gvUF zH8J7ukYXgS4LGD?#GkU#3e3c(>a1qbv2nT)pQSRC zI5S*+M+q*)r0cMBBM9Krs7FeOSSo-Y=;B26NON&HovrGsGUy+&xOM6gGrTZVP*dtq z!Qc^^ovB79$!wA-@i^6p3aP0^u;`KzC1^jjY6SH~UNz!(enQMdmnKz>MCywE--cSm z8)<5!kfRhVza_QE{PAiLtkr-)3j4FCQUw$hM?;h9SRRr%z&z9I`#ge5#76(&szm;k z>4NHzSBZFVBZdpyrV^QNDv|lWO_fNl`BI12HPlnVAV5Gpe`s|`+cOFZbXORCyQaM} zoi>~0C(OoAn{Q{%B(YPIomA=^KW#o(l*~D^X|qIdO`8E3YowD+o3$3IX)~nK$C$yi z`PKsb%uk!yem#ELTw>a6v?`r0i>`+0aw-i@GF{$R%BIVIgVJZ>bXm*2l3)%!V}1)7 z!wEBHvyyzP1j~|NL6!qbt5!>*&nC@yLL@YEegJJzI(OEtr-^gteWgRsoo$&~)8}7I zm_Dm}n6Ow3Gbn$vS87Z;gZ^Ln88n!kpFs<6*ar?~uo$G0JRN4xV`dUj zFk^s#-!5JV;wKS(>NID>_@(>-lpMoMf#dj^LblJ>Pqp8rEuF|EhnQ+(I5g!{JDTZK z`|S;Ws$I0HHZ}(~)#eDiY^seVDpR^&Al{d%^q!{FSRRj7IrSu)aTi$DAOh1O`Z%#O zQ-Oc^PXVppl)_6n9%ADCzH~3E?x-;G;H}aNd(_EzZS|AmyZz+&rYHlPX2+NtpmGdz zat#gv+3H|O2Dk`A^<-3MoUsDCj%0^X5DK%JnGWs3^1^b(UtMiL%~aw+O@rb~`WPj7 z+?WEnM#NJT7&!6G@Ihe(6PJCZZ}*ix-OsPlYE3hv7v_qmjGxs1s1(K0%GBs1=M@@# z9&|3aE%Mm6OYD+lj zne5sYPjjO0tWrs(s|xeLu@-Ob;E&Q$0CVAF$?6U^z-b}d=fEf>AD4XIe!2GrH`8cl zmR0FZulG(g;JGDPLlUDNS3#;OO*#TBhE!1_?)-^38LgQw z3Q+_p9EA}Uq0S$K?I@FRh1q(g%!$DQSsN0rheaD$T4gDfwCW+#-ol_z`Ik`Vawz;( zrkQG?wQaFO1;Qfa=Mc5fWzql@UVazio{}T==tuT$B^|KL$!nV6$F@|_92P9JoZ;aN z!D?0bEd2)NW?0&acZ)zl%?lVDXbHR`p|sUA4Xh8aKcL34J_vqTAA}1> zFbR;KN*9De_`9`Jcw8Fh+Y{43b12kXC2%QDuu2HIFyZE?0Og)5B`pH01b;h9U0@+t zC18B=KffVN$OUmzR6bTa=jRAIj2=~B(JUAiAQ?XgYX$l&EXCtG0=M0uM%*J{HVJ$b zn-P|!ZJDWjwcmPGw9A0nx&MbW;9XK-A<1GuYE^-l)T%*)NM-tuo_vlpR|0f(#Tl-_nKq3LzC{)}O*tJ zr>;@LLlxF>r0I*RrH=L@HAmuYUkCNpg)No#+EPCY8(TZtNrX`X^%E7c=%q@#7A?vW zsHpZZXH7xq^c>;8%7}P;53W6w)!DvXzr9!ImrY)XC+J zIR+u$A!(K7*s?E4=6EW{JZEclzLqu09rF}FuFUrO}KNQ=QK*fH3P_j3e-cz=|wOPI;ECI+&2X70|03y~z5JD2zC{B+dI z&8cizI~YOh4n(GgjfLfjgTWz=mOm9CxY*@*FmW}`L8Ens3!m!ZsG@ktFl|KjXAGJq ztg%B90d~OQQ1qx?!GEk2{0Hjl4Ex4j+>DrQ^^d~e?=87S_>a`j(U7`7GxN`KM}wE? zBStlKFzH0Hp_Wm!RMB7tC91Pk2N6I~Y)K1-U>?S46dy8XBO2CFvjIJ4;EgK`O!UE4WT})w?^M;9H zo!}g#)|N6*_E7=*QAuc?2$wb=wtW-bx7d9&g8ws#vI^#SH&Td1*1)^DD9)7g#QzBjEX?t#Ks#o1jV83$(b#%Y=I+ z4?SJ}atMy``a^QeQ`+d}YAFhbY)YJVLpGNP+T(=7{mnBH4&R0rfH5;;;gF>e6W^$V;4~xQFqbA3 z4n?EAa46T|35U7tpt;^;l~w)!`3=bnhwo|3uIZ4Gp%)I55}c2#VxI$Jke#cf#3RN_ ziSu((;(RY9zN3WStwBnBe_l$&@Z3v@O_NB8-g2=al@RqtN<3o5QX&d5re0oXXouvg ztK01u?Qv3~=|`uGn@WjIUP^4rONn)j5<+HD;&ZUz)fF7n86*BoN@PVfUH8zLnEsM3 z+0u#+S>keKc91SvIhVNDE?Giy5HcHSSYwwYI+vD}$)P$&&B9DguQ>=pk~-Uiym%`{ z5y*>(mP%5lyV^rZKCLAxS1gNA!rYL>1i0y(#+cSnt5l4f2EbE^k#mp-sYAy+>Y|)X zjBKyW5f-#t(P@vValUD-yhy_Gov7kGNm}zHMz(vgGp@`VCq|ky>b)gKaW{*=tFui@r)lYZl%&0)ARbQY62aEItX;ikA<*9$aFfFXHuC?GAaU4 z*w#~sKNe)TM^c@7@-S>LuvVNh(x{W+Yy?3^mv9JZPJUA=mpqiRP~7*M`);xb@|zeZ z>{RmG&E6>?;{eW-olYyi9Vpfda0j%#-Xye%5*(S*n;NC{BAooEmf>m)cIIN7aau3Q zS>ul_JZPNuerA@bBzGXsX^|XKQO=HB4x*emZDUw8@oE?WA5QBMFxJ9yB zL;0VJ@s}efii6hD7Qjq{D*Ph2evj4TW|l_B%c_r8DV;UcHd!^4{eCm1E6V*Nros%W z-)xf=qALcZw)G4mQ`=-^(;yg!Wy?;n74X;umUJOtrNF zAtaV3?7`dksIdaLb|d=wj;nS2Cp9oc*+kKkEYpk=Ke@tZ3f0iMm8Uk>u;^3hC>EDn z#uzo(b&$k1giEXkisesH)#M7X40xiSDq3aLZ#HpsbYFZ!P0G+7D@@_En68pkhOARL zt0)5MsbN$B)Tt`s4fGNgnw|=`$&`>5i#JxHD%2N(3TOlL${(`joHjD&VsP$g zRi;fGU*uctr~2B%TfVM=0vhd3@baHG7-5PokKa31 zsE~^25T8JAul!LsP`dWlmYF>p6>o-5TV@!VmOo$%DLRr#yZ!wlvG-wq&y(C_$sq-jwjdjnGV8Lo3v`8oG@8cS8%gHMf*(kp^jqJ zR1mF{ys(#o8A%dRPL5xAm#0D9YD&4=N(#7U(C+U5U`(L?@rVIK~* zdU{JwA}}(H4ys93eZpN8lV@wCiUa8S(RD3*$~QF7!ZwufFHmEJTS5U1Xx|Tvb|E3O zlaVUoVk(`I?gU~imTyFlMIzx(w_27rSh#&IQCY#8&zT3cga*`$-b{ehM&-jI6e@ga7u2zH)1jm4a!D9a$~)h znWl<9wJE(Yx2=4A2^F4)jZY^9p(Lfv3;1e>! zAsxvvpozB*ws9@8nH-~`ZHhqKdu*oQ>TOvUXsD-5hC+nFsT4-K4>42{Y`@xh8P$x` z56Ql-yYgod(1CSw{kLI+v?F=?8V@A%dHAoR@`t&Mx0KwNhF|yI5H6obv+$ckxEic8 z8q#(rPk4+eB>SH=NJNRE-hOYI@$G5G4|%Rj7(TaV;diIuPrfr0ET6lx@Owiz1qWuY zt04sQC{ftGSgv;mAEd22_{OL5kd>+oipG?Cad3Q)J zpC_{Lr$ab3{nSJ5vu`WH!7+hi5%sVvRa-|^j2Ev)#|-o1Or8cr56C3~;5 z5(@NYNT!I-WXWz0$&%aB-jdG~S#RB%h97)isH%LP%EE6?!}tAJ2$#<@S@_*)_>VWLWOQA56m^|BDbV9~rLu@Q2gzhd&&`<)dY6AO2_>e*a&F zaQWPwg+Gyo-+f~Um(RUf_)}^46CVlT@_8@|ekA=nod9%3esek_E`=ZP%*?lk=2kB4yiJe7tc z6&SH;6rE&1Cj0NjTn3H;-8)KDRU`?S$MgK;03O6Bf4n3j9Kw*`@Ac$glunczxjnaQ zp(O6K$a6OcyjZ|N67v{0Fv*utiLftlO#Y#k<;O7H06c|Jk)*A}t3(&GZx@~)$7`IJ z8e%sbz@isD7qT>#XDyi$s8$jz#K86P2Tw;_zFS;gST546-I`LHs8~Eyty&h8Y%B0e zS}<{<5T7<#Qt56crZwMu+9tv1){=2}xb;7{i~0QpqR0hZ3*#5&+D04I8sZvU^HsMz zK3@tV9AcOX#4p7JgDWGT<;HK7(MGME`)9Vt_TR{lOz%Q6< zWl~#lkqql#zSyQRf#DREOSoyS+6tOm;<#3UjoAhs$zfhRxZT79Yw#U@j#CFT7Lk%4 zMUy~|_LT47L?W_NJ<_&VMt7EELBzir2MU4>*HZ;jCcIcQX+sCVZ(($(D!vrCnXQ+0CEJ^8*BIki327#ZoKV-n1}|oPFiOebs4Y1~YMA+u5Tau)!@AweT4ics8c)n(B#@QG zh4(jf%=N+ZY&s|jyc(-YbM(`iFvVEdF$*#=PpxjjKA^<8_*nkB@?S;OR+FAt;ceFu z3N28YS&7cwVWu_fOtvPs_++i+KcTU+Dy_p^dhKPkLgdZ>_YWO=K<$ zFyabJ)Wg*|%#)Sza{5N(2mPdn^;|6lm(A?~1c=(JEnv&+f@`KU4@WAFN`hjzW`miN z`pW=QzPD6mWm>*|l7{`0P0}EhMxC5gnjxqq1R3m^viL4kt{sp(`i-L^W|ItH3Fukg zCG#Z?%aBAKt~7VeYNSTGxmdPUOzwOMRb7K3nn70z_jTMnbK%@n0+E&+D5GjfYuJ=l zL^Y6UB@sGjF;?QFs7g0iufX zS}Mf`jhJLFm{Dz62+FlEc}1g)yIeymRaGN`j+>PfF0lpJSzMNSCjOwXEjDm5H#5~T z$!(A*rG-nQ71kKr!1mdGu(%GkkYhAX7YOJYlqz-2!s`5C>QLtF3DgTH?q@L^ zbX_UMFa#MLvvp!ki_Us((J*0Xh=#Pwx({ERHgIRz!0niAU|ddq3|eaPr2?ZB%S69f z4(PVpSZQ>m;|>b|q9KTB20fr`xd=;h`&PSas*Q@$S=uJXpo~@4Y??pwGx?~V;t+pFv0B|6F>5xTrB-;`F)8Mr(t;|(7+c>+g zRBfP1vx`lxK#c;j(-9maCrodYF`&>~b!_k>A`Izv!PpOYLoc&ovEj_%X7`dLN`!{A z96>kH;Ywk^Y9I!TwQ-4lZQQt=#o6?R=epa*@Z2a$;4qOummiX{g_!F{Q8OD{HKY~) z71>bqx;EoPHANaj5#~cR87Xuy?6M^IhPiMtz9ycP(1jDJdzrqOo8G_7_Ld zYCf=;g}SJM!=O3ZETW^mM398U7e%_nENv)>L5p+&E0HcG2I`)Bw?!iKD5s^qHWE>c z*Xn=;<4s{pa|BvYs79o82>ck4QA1L#r$ifL6p=RnmLEVKS{<+Orx&6p^f?HH>vHIz z-#Huaw!08DVPwuJ50RIAF3wDg3EV<=HC)UlAiW^fG(&sKh_Q8+$w44P*h zOqynD>x7_FMRsuAFpo$bX#EL}(4V3NL~j>QuSMlJY$@AwQIp0?*l0W=42VLGwS1CS zUYzW;z>wXiO-88YSDct%+a<{(Q|3ouS(Y;?@AE3pnybD_D2}0Ud?bpv_vs>)yREne zsv0U34<{wXXic7Nx|r6tj#?~SV@($$HMEY7jBqN*E6)@m1_(0zRr7USdAp(74=vR=h|P`hhZ-1% zo}cGX8?~B`1!{9?HEs|%?Le)nd+FFPov{lYhZlqCaBKSYKYK3A~1@hGK==;SeGLwniuBYl4}a3yl%Xfj4WDI3jR@%fogPKm0P z_^V;oV#ml*^@#FQ)44_|RD_J%z(Q3e9RBtc@(9!}tqOOitfl9zF|A`A2CPt{C!=A^g$s}( zst{}ExW8YnmztQ*)l{lcm5QxW5-n9J%MEk>tWpv+5zx#Z)2^JqNmh)qqVb(hnu0f;j?7;K>WZADrs(VbbrB}q|f3!~K* z6-MIb(Gdvg=@*lD4DCj;_n@MK3!q{L<0TG!8T1iy3WsQzNx@wvHu04d4vC*1Ekb%d z@>S6d&@vYn)xS&%CI4Zb0QWGGEE7cdqsKe3PLFI6Z$maPMQbH%p&i7FGNAEE4F&ap zRz4y{SwtD-VAL4t{_08as=?zG(;3YK8Vs*&>8`=LP||)~NySi-utpOasszbHQ;(g6 zJ_bknG+2B)Xgi z0u0Sl%z(Q>>mVi)=(OVPKdnb$#KSSm`la}-rA#o$5tGUIq;+A&Cv}A|`06K#Agaek z@=f;cf)*UqTm;Y)5SS+f$Fn+&USXc7b!baQ-2?L^dY*Y|#vvM^%i~kBU6{x`^MQ3V zJ(S1va=jWXA(v}e8$CR zoFzcF!nR1f;2ZXrcx=OSb|KU+Jdli&Y0&Z%>hSfnjg3;JXaYQ z&s0FG$kSpYT!FE)2=NgWJX=AS3|wWW7gjVb$1#-_8-2}zsWb3 z_+EAiy{sOlD#isUMYMlHVWGgf-sYP7ngC(6A7x8Q`+b?v{#u!$k!ksIgMf``k2chL z)Cm=>M?-(2`xeFLgisyykGP#FqDAO0Dt0u0bRj zg%zZ>VM0#5&};CCX#@MhRl?&Wv$;3u?QO-Z`d_S7|5ji9Vc9%HuN3=6CfpBsRbI6*eiwdzmxwDiG2YVo}Y zu2+5?1ar*G_I+IpqCHOT`G$O?5XR+~#FG8@Mah3Ommg=D4A(Q}x((O&%yl=eADHWY zTo0J*VO(!+QHsZLJz;)N;rit)`Ryg=56_nCDqOeDk?T5KkIa?pMqJ;tvULcB7|z{;>t0LoAg=FO=p(pp ziIw&VTz_G%r*VDET>JhOn*eiNjqB5f!`I{bz&xcmfa_ZpdMmDfFnk@u<;%Sn*PATG zL%43ST0M&ED^}Adas9+b$1}J-=y9D^e#2^YEw1-l89>FO0Z>V3ywHG`&;X#+(7^DY z07HX&h_pWi=k+N#@BdZ`PFw+;2PtUprwnCp$GP7-@46?^C9oN7w6;N`4G;hz4K9= zSN@eHdlF};!!tOq^S)Qoo&(-_EzaA#b3e{|yz^$94|(TpI3M@UyKz1p;-+8*S_wcA zn0X1z0ILRO8*Ky_nESCENTGaV3gxFWDB}uHegxOAPBkRM^?h@Z(swK=6C$WYUN*k- zC0fT4U?rYKt%Gvva4`j>z$0#_*Ex-UmC<%E~mIu;ViSQhJ6V%=*TPM#qFo=U(=cH%MFemP5kE5y3d zXUi+i_Wmr^-Nbs*XNzY@fTyzMW!Ykb@ko~7L1KMpJ~D&+LVWxbpI2JIlUe*niFNJU zC0HbQh6H#j0k5=xz4xU6e~MWDGD`*E7vkfm_`K2ruFm4`Bi7@-06aqiJe7c#6(CWe z{I&*}721hHE|HoUZXL|a&FRg{F$X~S=)&+s?_Smkq|iwI_~NQOWT_~R)eD&{#qo1x zyuc|TVJT6v3-lZmh+nE`x*SF!jvWsd2XVS_6e9LTUDS$=7B9N?IEM)?$&69zFKmmv);q^|;NcULTQitV- zSk-~(j=X2tmcM34c!h6D_*$f?O<13e;umH4iJekezh;7rdu>C97jOl__&D_s3R{=T zu;ZdzNMNNz*HNo@sf*#zI;`d7te^k^&esn>Fc+F7t1v%xa9EM0^PA2AnIK1hF+1TX zBTn!&j*iA#S&X}JOPrlGGrQG_bs^M0DKaUWaOsexR2K-D%ie?oNLa5|{E4l!Mf(>1 zTxWO$_w@~NS5`OLR9Id>e(`t0GXgKe;08sY4Wr8>Toi=dHP9P&3&}<2V!tne29P<^ zzddHbE*W<5E=l zt6m!tV-MqdP|5H;iW8xMV+HIgF0XJh3mDcxE~G)Ir8j)NjXuc!)J%+k;&9ToJ$?^3 z93^+`J43=sDa>&EFuYszNtE(O8^U3}H^~ttkLju^g>dH0jw&|YT4jRVxoyK` zi=spaeB2w})tE-U`o4T@zKCwI6#Zj9`mr<XqF}pGa?2hcx!8_OoN%3#vg8oTCPYm z%Rsq61}JZ{%$#NBD$UyD#0EH7VHAd0svw44&;s2p`iV)ShykRaXat~A*kvmLI#*1l zBFR!lQ6Vv-FV&4|Bu6u;w)hMv7XPZ8zYJO1qT5k8$vq*n;R*{>g`=cu?4Zq>EF~B_ z0gyscUbm1+`FA878on55h=@`jGFaI!4_-+JQ7N!^&r+OaD4b88{4xbFS`&dIf#w0x zcx!Um#d>!wtU_D2O5*_xb#Kd2phWXEf>@CQfhBk9xT2%*39i=5J!`E3K@F%U?%TY%V5;wHR zHt-m@!<`dBCmyfLhNtJ+T%6HP3as)9AeJn8$p;mUEeL~nbRJ`GYlk0Pfw?Rq6UZ6I z*yoOjQ%nwtlP16piH|=Kj=hHxagx73gdSrCkgRs5eJj`6n<+s3SZm5ftkwi`#D))BPzSx zh0)Dk7`2?j{R38Sor~XWyQtc|%Fa|Np4#}1(e9SQa{dX@?<_z;7~HK?P6y&?{Dfl< zZP&IAo5C7Y`n;$!HRDNiwU@m&+Kvp5xY zs$Da}&bMQxtDbq6EDEN@&UX-Fa_rRMkA|J7xKad_ACzbUf@+~06I>l{DWxz6!O3#T z^uuV?gsYH(aEK&BEgT|wNR*W*t=plLQ8@F{V=aeD)?w}cQt#JcElI)IdaU(|<{4t` zTcqLs^{|$XSCtKM;c#yjy*Dz+WKM|7T)_Nn4xv34$^9IM^cnP>ZY$SZRs7a)29q&> z)n0H#%1&$onEIEmiaO(4f;r3m+#dw4tHF#q5EYEQy#clgOAyTu`vT3nj7o^#FxW68 zYaZ6SNkm*cNT&#CNU$AM0U{l6!Db@fcDv6LZZE#r(NtJoDT0pLAlDHA`{m@yXe)9p zqIQHp&?49nW4;zf{&qKm_Uz5~K;dXZW$ou)Y`q0m3O(AtUf^GgecaRedJ~(q^cS66 zI8ilL#o4qfz+!KiP)EB72P!y+1rvQDQXY-Or5TB8hMZNLE7Mw7o}pF@ z^A6a0G9QcUi$T_X*2mYz(W3dsBG}TAe^_6)67KIDFvr=;| zmb1eacU57o*#x$@79+3mBBqRbaFHCBWjNo@`m9xvIKH=hRNf|0X$nC$O{5Ae(yAvRq(Ma%JS2faE>IcT$Nre~i zMX9GyrFO(AAjy}Vgn0_OIenDAZImV`C5!S;B85$HE zNo*;93AN74$aB&l;#1*A5XUK=GrFL5V(_^=Ok55gf=ZXu?r zAK0aRrzw&YVpnk?poIM3(5J}Bf<*!Y#Eunks;E#dEWell@uYC^!h99H8b}+h;$1d_ zo~8|LS`2|bQ7PZIveZdv>bxR`;EHl2GFB0QXVKKElLTSt78NRy06W_cM8Hg- zemU8A)^A-SuM_d2`eme4^>5mvAVSv7^oq^mm3EmZ;c4 zu#c-$g)9kmun}QB?CWz9b1z2)s4x%>=)!o?Ru)5&qgi(;nXq8sLJrGe!&kuG!gAGL zfwa~Fm7Q?TpWz_)d_M-&3W$(eSOHfUE*evWFV;<>RKY`>nzR{!i$(HQZno(FN~#F~ zMC!EYL^=Tgn9x)zf0YkGoxmmT<)M@%?nIAVR8I1ystQEAgJ|7T?u^~iKzk?u3Sc~m*kj=(a>DbXAvpAnU z?AD4D!epSKO;eUBfkZ@SJ}(j+YZT(xtm4k+0$IUj)Fh72wDG0E&fUy=fG@1(V#*VF zL~y^;wgCW!bjZR%B^P3AZG+YiXU~*S?n#zbUa;RifLa|xUKyF_kU2#yuQ2=(tr-3c zQ9?ifxJ>-C2BB(;N@F4x`=A-&uq2i`9Hvvr*05MWFa)L4loB!mvzmBDYiMdcU`VB& zIT7NgttY5FK(py#ZXFRwxrh09(p%T?_}Uq_98TyPGsWc81b5{h4G&kumkg8=Ma)ykI+4Ln~D!GX}D^LF}5^^c)5W}HZb}+(T_W3r+(a# z3$%bhz*%j@T1sLSnN;HulfXa<5%3mpNCaFbvM?qa)1eVj@m7yrG{zH+lvw!Afm)c7 z!YGKGBE-JGv%&8x;ft*_jgW#i_!?E3?GqVH+@Z13V%&k+YkXMa5Y**5F+MfJ)yW`} zLoSB~-h`AH|Aa_Zpun>G(!aN$K;whnLGzGLUEi$`{k?z!aB%P#)| zw`Io#TXt+2z1*!HI)7x(;K=3fRf9YHd(XDZUH?UUMs{x=#Ia|{-me+jyu-Wt21oad zD5!7G4!zdxwAbp9E%t@aqV2~o+I;+?%iWTfR4SFFXD_|XEm?Z@OO~FEd&$zvUb6JE z3SLVuTXdNl7}zm%+33KokuBSYDmyP38o6NG&P!d-&P!AScitYC?748y?oqdC=MH|? z4DA>i85|wz+B~#lbjt->hDN%#;Cg6HZ z!BI!m-Fd{{v3s|B{)O9io}^#}Ht>6z~j< z9KYjIpULq%21mDCGIYHE+O%`~u5Ck?ZP_%q?J!d8QmaQthK3F!4LCQrZPU)phm&TD zI(zr7p-ol}aC3{gmMvPhY*Alj(Jr@nr|{6dif3d9#N0vWZ(g=+=(0@!c+1Wmj(*S! zEOpxlx9o5`28qqHgIX-wRXKOt;Q2$_&ZsWhecleYy1SqLz99Qw^TO4=a}$A^m)U>5 zyLuFPbN0XHg{yD9!sO`Ru&nZ;MY~^wyZ;<~gZou`wz(a9wrvw`ZQ16YPvtKe|IGQhT|5%`@yGBh~s7;A3P7I*&O=7GVHk-^IuM3)Y18`^Q< z=ta(FAmrI}(G2?D@PeF=yGTQgEO&3&G{E?wT+s-(`Kv(nzLJIG`+UXxr`~cLAdie=uL& zIOLwsFy6xZ(u=li8_LGK4YGdF%{_n1j!oP4Y#ws!M~2SYvU|&DN)}eqrEbrTog<96 zq0Ix^2X`%7HaNPhGCXv7Wyj9Z$^|>2SZ>kM-`}>4m;JtEk-1-T+=+NyvUAI3w{0iG zV94U{-m`1h&Jl*RgZjB-^JX`?Xz7WY-O!??Cy>E8OBQWkvS_pG+_0gSPR3=ZXT7qG zY#bw7wZ3S=ZUq zKd^3NcYoLV?sJ5a8&~#k+|W6&KH1Pe(6_#GW!LI++?k!{yry@4-bWt?%vYIy;NKvbU$N-@T@*e{EOKKwm#?vckH%@J%+X*=S##XRqJT zNlnPu0x~#Ifn=Tc>mjhKr>lQpRp-iX@0EC9k&XX8E7{PMtN=8YNqqvs%r|sKT0&)2 z=W69j(Uo;wRH0{0#R~20@7z$yr&yPCukPKju5;BC;iR(EU8?|Q*Xpiu$$NS$8@kr4 z?XRrZkgPnjv%f-tRJ^VT;&gYeo;FHaO4`)A^y@eDt^r<^mA&iM_ipT2RmtF8N&5A% zp?_TGrnpJT8AR44T|E{4_pRK}wZ4C{7*MvpmANP@dV9M&lb(T|-u|rLiIXPn>NzXv z?#jWfuL2}1HPmw}*LQF1qt-$Ow=#7Eq)A&-!=4nKlAKrQ*Azar%xgeM>qBGvI@fir z?Cn+`tX4;7fJ)<}`E2N9AOMRLano=$AoHxOOnPX0Wkn|q>+bG-4M?)$oJvyZ+1TA( zid}ZsXM#-NPJjLU6B|PZUEg^PXxq@4V}rE zmEMj0eGD4K=7|fUpcE6jLUGkR_i1e z9ZJ;?Oongq({{CL|A`q(26v{0E7V->V<0EdQ97~bK z!Qqi|pu0Afp^*v9!KL6#x(7BwGhJv1HCI=1x965%Xr&3zwp_&aYa9* z8~PLgKVY4kCG}sqW&+}keR&wI>s_@GI+ynn-AmDXJgKRyP5LU(Do9bXPV6X)nf61) zNcFmnef`8etMd?%J=H!$Y%y2LGk&}_gTYjNI#s^iy=%Hw0+pG?rUw0M!Hceyhf1(02xoc3>)qf&aRWFz&!!{$y3Xp< zhxKauk;CV+3CnQ*EJh9A>97i)@^L?x4Dn8wfXqm^rE0-Pyp z!^WO7dwO3J1P6LNYmW2eWS}M{GOL7RP0&WxBwVrwcr3y1p`xF7Da8u7^@ej8J0>%@wVh{Y z?sSZ09=$6WJ=s^t(*&y8h!9avKuIq_&>Ej_h#cfoBhH-?JdhM5aWELh#Y}Oq(v?a= zo^wDg^AoF8U8`5q3d&1mi_TZ)zSi)S5|UNDhz~Y&GB3{&6yM|>n}51YfX|{$%5)Im z(&^p!h#9u$07&sC!5fxD3Wo?tS|b+mr^)p zb@UW2O|@#{`ffM_y^uy62XGG@n;8e@oylr-o>~2BTs|#Bv@-><&^s$BClRD^sk}{f zCymq7xyF#7)?wYf)E%PiQWiTm+i#qLRZ zghi_cx={`d^sh}n*D!B{*Lt7z>zv1jp#2D6DQ-%Km8^3n17*X@#C%Q8Q;e<=Y*VO! z{e*R|97t+WfKgs!5avXc?qo%0md&_0MsF%V5Ss>8Fc8mlfyDU_$eVYhq|JXB(7iKYNGi|NWK(H~I+6M% zfUaEINzNfE!=-n_2IRv`#`aTguiJvmK*sa2{XE!MQa@}41%Rmvh?0^k(-SbZS9Wz} ze!dxLnPH4bJs}-M%Gfd$LSMxzlPXgrOM7$51X%$62T5JAaZOrufA5){Oazz$p-#$t zA!{fi#WjH#)Kq#GDFj}F)Xp@=ZAf0DxsjY{ZPV|x)rO=YPU;svnMJJC{Mu*Gov7U2 z)vl{&bq1dxX7+V<*ZjIxrZq&&zXrPDk5aw7!)tj;WRs~R)A zPM0x6TE%BtPuk=?0!|p(Ft|;oKuuN?B`V#f+DI!V;iujw9mwM+yQbg?v&FhBvIGb# zs3~i6%qdeC?xCqutvB>)>d?QoFP(`dpfS3atZCxw#@nTz&wK^Y?8CsbI>~zpFVi*} zeKaHwb7Rd_`fa97k9u)EjXMcto)E`V<;gQd58aJCszEm{XY|98jgVHSj+0K3D>i}d ze@)lQPRk2@#B>=>C@ae+Eiy$t$+>A$)%EFEFabCXNaxErNu(}3%RT9aF|0br*ESvS zE5W_2XR^-Ino7;r08#r)dsyo&H9^W4$v_WnPb-#Tnl;Poa??eGd_1)*tE2^_bV*WcB>sxvPFt?D`p#^!p@Vid{|24hf$ro)?+85Hs& zP}adF@~-WrtJA^lKj<1nUGJ`GKz}! zs-&U0T5B0;G9P=Q?pG@uXod65NB(g+5h+u6$UmqMx>jYt7j?)!(n-440A=2(B+K*) zqCorr(N}FmR{`x5q?!2CRA?F7=+k^iO4Q1#u0Es+tq~kfYU67YlS*n2bF!S^1YkQi zXry}98YHZ&Jfnj(F)PGYR)IpAK$b<%Ml%#KjNi28Ib|IrJ*RKCuCJ->9CEE&>FBj} z2@AO_V6%K&8LVvDHn@9tg%$0KcJ3Li4DP6Si;P#w+#=N?X2lPjn)Sm3g+*?Kd1AU# zrc8H=TY22Z{?$uPnV9J0DHENX6*e)|NmHgeX=3D;PZ{~;6C$>kQXSkqN;a-KvgN{yyldOg1>UiHba2z~`kiK$p*Y0egf&rc zZo@7jI4_{WmPuB}uFdwXN(QG{J%wty#TEC)R=0TzK;CsxC9~ccpcnqI)m3-x#F7F) zlLw#M7A<`#rY%cP*3T)I*-xvxr1lY9yD^Vyb-OW{@h%)`bX+eZb@1P15qJ1(Nz#+K zh+t*mxoEdcvoNJFclwqerVlSpzjJP1KdWT^r!}?iS@H@DIlP_Erk&e%j+}8J1|&OP zcbbn-Id}I(gS&>#7#Z3`pQpYU1x-kXIf;U+`tk5Pw-wX2N-!SEY*R2X8KL&7@p(JW z+fl7W!XD&|(eQaW)bNbWJN@ScJF#xs@&`j_oVc`A+4rnkVWXziy>W4?dmRrbfCblX z-!~`VQRQiIOAF5R9O2vvygxeMxtH?(huFE7@&3|mhY7rMcfG)29q-(o__O!HZ6*H6 zygyfU?iAjej&|-;-e>S$#`|K@oyPkH;-Aj@4|$)#`$)oH!TSeo&b^ZNhbzu4=l#K| za|!R~{+@Fyc)zXPxs|-%z!vz>hpTu zzdy^l0p914{tdj>9Oc{~@6SKix$}AVKM$DleqGhM&Ai`AzC*mf&HDo0ZTMfv`{lIv zBHl~+-oktRk@OAk&r{AY@AuN4ZSp7HcHRp}zk~PdsozfC&jn7qc;8C>F6RAJ+B?Gg zG5T*e?@MX#DDQs&FZS?0hJL?<_d@D>DenvMU)Jc{<)lB2_m%YT>Ad$*{u#W>wBr@L zze_z{$@@PkcRBADQqP3<>FRIZZ{WR>cO!850cqb&`9I|SCgAZX@2%wX|MPArlOJWC zCj8<3Pr@JGPf_n{snh$xgZJ@1oA*t;F(P(19qZgz$oGTfc>(?LA>NOW*8$$QfLE8( z#ma_bcL^Lm&Kr_g851XLjxU&rQTVi|0>x{v8;7i#lEoOg{&X{SD7a_+Lc7kC48J z@CyiA!*_*zR^fLuWxtZL-^2St+V&yJzz*82B;F$4-@yM4+VIajkJ2xz$?xxZf10#U z@V<-pQ#@~_E}sQfdvSk*_a6}dT|B?!``v`SpZ9&>;6)38A?ZHB^Elss$ag!>PkGMZ zS;X^gp0^Tq4ewv^KEV5So)6&u63-`iD%9h4%4q{eO?;2XjUQ2-@Z)W~j|2{j1vA=r zkY^6*L~zAoNJ}L_0;wG>J#d+mU?vHUd>xD72eIm{Y`M--+14^a~k;wCvT@5 z;o(g2u1sFS*|j|1U~E5!a$m-?h-U@Q@szugI-E@z>|%Du@_q$%coTj8CBAooALsBS zz$D`P5yJ1H4x_ZE1bQ^^H1T|npD#AUCwUa`Z!OLp^+yPWsW`b6smI;lSkPAet~x^wYwK;E!Lz{zGxfnk81&| z`Qw+cPZJi+B|qNBFhn2(`e|W=@W(Iz!EkrfQJm%WZ$z4%ep!STm;B{V$zeV@@je2= zfe4|W7RDKW{1Wzeit`+o{FwKP7|hPuPYZOOKYsaN>&;}vO0)xO`eG7zpK8NQ`Y!8zZ<{F>iseN^L76M-{b550Dk&wUgqH~q!d~Ssf0R09Km1R ze*}-ZSbd?fBP$aT=@8r?nRro)TcZDY{uLF0L zCtu$4`Br%^;8A(%`|DoM{D6G+)9F2Zqc0m6c~A->sI zd7Sbpe4ohk4DK{tzR%Kh`94#9*OEqlX?+8*)mADzU5h8Lv#PAV`+eRT!|ImwW z!lA+sulV13Y}!+5DmFHFaKJmBTo|#BFb0`4}5P7dNc;x7=wn6F{Z~D zV`GfzF~;;5V|t7+HpZCN)MAV=J;oRtV@!`R#>S4~S;)gU9%Jl|9mB&|9i#Zqfctk* z{#}%R7vlOo)@GEQ z;$U>I#W=awVVccGhjYx0*+8-eJJRG4ayy~MtNgx4&#^8$`z1?ut>4nMqbI*_%-ahj z`+uoZ6c$m;cAn#TmQ`~czw?NxDF#DBVW4R$=b?M59L_nsJ4~eix#;K$e(AFINHLxd4)(i(ZRZiB z)Ba5E*Djbg`=03wIW3OG&_YN+XYL|64vvQt;1y7xeFt+2ok;m4NZ^%lGAseDkW)Zu zA#$%GKNS)<4S0Fz>4(!Hg<)6$E1?9X7N~6ihM=xLh-0m~@m45JT~^hut4DgIf4-5= z8plQBSgU1pb&ei4SF_?(lFr>*{k?{}rU3zr$v)L${PFa2^-)?ea+s~^{ z5LS=eY~4n?X|t`WvHF>^(Zo$8*O&}FuZ09OshT`ZuqJmEtcEopA0l0oNKGG3rA}pI zC)96*^Hsw~=ece7_b8J~3dPT*{KJ-h+l2BzSYk z*t`%O39N&+!+N*~-U07~i=mqT$=F=lJkMsa@z61WCF3)jMRuo*rF*Td&w3w!~-2#R}_UO`FCxEGqb z&bU`Ax~_3oEn^;dncC`+S2hZxZ{oN|PljudS4>}m1a5#Y!&l&|uoZ5Euff+rHg4+@ z$J~W9lA3WWUs=!J;H2m85Tj3V^o`YR=C9H|GJkwOx3+DY`9omr{B1x+v2KF|z5zGE z&9EK53Aezv;8swqHyGQ~Dc9#}b@xNLGuHN;b&GZ4Ih*%#l#wQmb#%_wBL8jVzXJ(; z7jA>^!S~?@a69}E9^mOz@;~DE$M6&QDf|q64!;1!xykr2gK{0`PU;l*oJIVZH4<+$ z%pNRLUYw}XdV3JvX8htxA8)9XTNXbD9dEa>n9731hT@%d z+{48?I`{l8rsp2|{RI;EE6C@9dL_+QJ%5{2*Xiq27bU9X>t=MCxv}fHK_xTSPCID7 zm&3n70{4OZn|VA3q}}pwDhsKtzGp3VGLG+u1a`vT;UDl%cmVzd|Azm-gCPGlcJXg3 zb@F#4-fB-D^OCzTv-CEj#$-EkV`au(cjleY_UR#XCGcPPA85f(gXu5>X2KruD3DJP z{gmWGJ*N-jlP#Z=)*G9TMpr_47WtmA7tDseVIO!5JQn7FY;KyQ&DCZcWK&Oo8QJ5| zm5@K4{0T4@o(NBZePJFv8J+^NIiG$?yBjAqN8(&!Z0?7y1ReX6Kh@}6(@n3bGxHUX zY|}KQJB{|5*pAM6{`C-2@BCC~>e6$y@$(tR&u5Y!VEo+P#m_k>wtXM#=hUw;@^c&O=*=XZ`um^M z9>1oq9(5|4F^HCxLqojiRUd3fTDA{ErXC}=7HC{`hH1}`eV(y<2>J8j1;*~Bld)^! z(e$r`v!H+!UI$9Ldl-anZ5n#@D`5ya`<`stRImQy$w|+dAYChl#I@o&h|y7eiiw6I{HkT^o%Fd99P7ud62B^Db-_8`_&vPwb$`$UXA@*W(+DzpL|l{Zi3_9jn}dlu5P_2x^=HQU~K$b+TNY$x$H4} zA*qvnye~)e+;aJ$l`{TVmStOx zc#iJ`PUu8V>{_nvIwCWM2Y%>B zejHeV9XNp-c!3`TK^R0q99p3rI-whSp&tfe7)D_nS&-sv7YS5;5r?akMl3a;UJXTGLR)Syi`NMw%Pr(K!~Km;R;NFj8#}c#JGTqFv|FA2X`YX_{tfo)&4DwlXWTGbeL1 zFY~h?3$rNWGw&?R@~p_ptd(22ojbXkd%2$nd6-9eoTqt~=XsHrd8@DryKoA(@Cv^O zim-@^xJZkv$cv&Vi&klscIlLE>6LyNlwlc_ahaAG`*{{+S+-hCVT);KF_bNaqeVz9 z+-jk^MRR=~YYi)D9V=-qE9uKlO8UZ+lD_n$RDJPD2YmTS*~l8-FW$e#MGK^Y$c9&YpAsDdgwgwDFvaWaP%d`_4areBEhl7UUQyuDb5}JN7}rg)wcBFO=8Em-MZJ$Y7uKAPoSr7zJCv@n?Lg8? zmsR_d_G^RE1+pReK9~h#)znL#w$VK*P1`o=WpnYcV|CqDR1T1K zA|umB@#koe-k#HIy|z6tcn152wztNmrRPA}B!5gp-l9%=77yD_d(+ZJ2V|F+KF2ot z6pcRodZK@@)xUyY@#wX`iuqjHiA$ecRVP+Y?