From 3f48f5467f3b1506bdbcdfae88ffa38c028402af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20BR=C3=89ZOT?= Date: Tue, 10 Oct 2023 14:36:47 +0200 Subject: [PATCH 01/10] fix: wasm error fix: `in_memory` backend fix: WASM sqlite backend fix: formatting --- scripts/download_wasm.py | 60 +- src/findex/findex.ts | 207 +++++ src/findex/findex_cloud.ts | 110 --- src/findex/in_memory.ts | 119 ++- src/findex/init.ts | 674 +--------------- src/findex/sqlite.ts | 59 +- src/findex/types.ts | 490 ++++++++++++ src/index.ts | 1 - src/pkg/cover_crypt/.gitignore | 1 - .../cover_crypt/cloudproof_cover_crypt.d.ts | 171 ++++ src/pkg/cover_crypt/cloudproof_cover_crypt.js | 750 ++++++++++++++++++ .../cloudproof_cover_crypt_bg.wasm | Bin 0 -> 468243 bytes .../cloudproof_cover_crypt_bg.wasm.d.ts | 20 + tests/errors.test.js | 220 +---- tests/findex.bench.ts | 56 +- tests/findex.test.ts | 643 +++++---------- 16 files changed, 2015 insertions(+), 1566 deletions(-) create mode 100644 src/findex/findex.ts delete mode 100644 src/findex/findex_cloud.ts create mode 100644 src/findex/types.ts delete mode 100644 src/pkg/cover_crypt/.gitignore create mode 100644 src/pkg/cover_crypt/cloudproof_cover_crypt.d.ts create mode 100644 src/pkg/cover_crypt/cloudproof_cover_crypt.js create mode 100644 src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm create mode 100644 src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm.d.ts diff --git a/scripts/download_wasm.py b/scripts/download_wasm.py index 6949975f..35de2e44 100644 --- a/scripts/download_wasm.py +++ b/scripts/download_wasm.py @@ -8,27 +8,27 @@ def files_to_be_copied(name: str): """List of files to be copied""" - source_dir = f"tmp/wasm32-unknown-unknown/{name}" + source_dir = f'tmp/wasm32-unknown-unknown/{name}' return { - f"{source_dir}/cloudproof_{name}.d.ts": f"src/pkg/{name}/cloudproof_{name}.d.ts", - f"{source_dir}/cloudproof_{name}_bg.wasm": f"src/pkg/{name}/cloudproof_{name}_bg.wasm", - f"{source_dir}/cloudproof_{name}.js": f"src/pkg/{name}/cloudproof_{name}.js", - f"{source_dir}/cloudproof_{name}_bg.wasm.d.ts": f"src/pkg/{name}/cloudproof_{name}_bg.wasm.d.ts", + f'{source_dir}/cloudproof_{name}.d.ts': f'src/pkg/{name}/cloudproof_{name}.d.ts', + f'{source_dir}/cloudproof_{name}_bg.wasm': f'src/pkg/{name}/cloudproof_{name}_bg.wasm', + f'{source_dir}/cloudproof_{name}.js': f'src/pkg/{name}/cloudproof_{name}.js', + f'{source_dir}/cloudproof_{name}_bg.wasm.d.ts': f'src/pkg/{name}/cloudproof_{name}_bg.wasm.d.ts', } def download_wasm(version: str) -> bool: """Download and extract wasm""" - print(f"Download WASM {version}") + print(f'Download WASM {version}') ssl._create_default_https_context = ssl._create_unverified_context - to_be_copied = files_to_be_copied("aesgcm") - to_be_copied.update(files_to_be_copied("anonymization")) - to_be_copied.update(files_to_be_copied("cover_crypt")) - to_be_copied.update(files_to_be_copied("fpe")) - to_be_copied.update(files_to_be_copied("findex")) - to_be_copied.update(files_to_be_copied("ecies")) + to_be_copied = files_to_be_copied('aesgcm') + to_be_copied.update(files_to_be_copied('anonymization')) + to_be_copied.update(files_to_be_copied('cover_crypt')) + to_be_copied.update(files_to_be_copied('fpe')) + to_be_copied.update(files_to_be_copied('findex')) + to_be_copied.update(files_to_be_copied('ecies')) missing_files = False for key, value in to_be_copied.items(): @@ -37,40 +37,42 @@ def download_wasm(version: str) -> bool: break if not missing_files: - print("Files are present, skip.") + print('Files are present, skip.') return True - url = f"https://package.cosmian.com/cloudproof_rust/{version}/wasm.zip" + url = f'https://package.cosmian.com/cloudproof_rust/{version}/wasm.zip' try: response = urllib.request.urlopen(url) if response.getcode() != 200: - print(f"Cannot get cloudproof_rust {version} ({response.getcode()})") + print( + f'Cannot get cloudproof_rust {version} ({response.getcode()})' + ) else: - print(f"Copying new files from cloudproof_rust {version}") - if path.exists("tmp"): - shutil.rmtree("tmp") - if path.exists("wasm.zip"): - remove("wasm.zip") + print(f'Copying new files from cloudproof_rust {version}') + if path.exists('tmp'): + shutil.rmtree('tmp') + if path.exists('wasm.zip'): + remove('wasm.zip') - open("wasm.zip", "wb").write(response.read()) - with zipfile.ZipFile("wasm.zip", "r") as zip_ref: - zip_ref.extractall("tmp") + open('wasm.zip', 'wb').write(response.read()) + with zipfile.ZipFile('wasm.zip', 'r') as zip_ref: + zip_ref.extractall('tmp') for key, value in to_be_copied.items(): - print(f"OK: copy {key} to {value}...") + print(f'OK: copy {key} to {value}...') shutil.copyfile(key, value) - shutil.rmtree("tmp") - remove("wasm.zip") + shutil.rmtree('tmp') + remove('wasm.zip') return True # pylint: disable=broad-except except Exception as exception: - print(f"Cannot get cloudproof_rust {version} ({exception})") + print(f'Cannot get cloudproof_rust {version} ({exception})') return False if __name__ == "__main__": - RET = download_wasm("v2.3.0") + RET = download_wasm("v2.4.0") if RET is False and getenv("GITHUB_ACTIONS"): - download_wasm("last_build/feature/edit_policy") + download_wasm("last_build/feature/findex_v6_ffi") diff --git a/src/findex/findex.ts b/src/findex/findex.ts new file mode 100644 index 00000000..edb51fb3 --- /dev/null +++ b/src/findex/findex.ts @@ -0,0 +1,207 @@ +import { + FindexKey, + indexedEntriesToBytes, + IndexedEntry, + Keyword, + Label, + SearchResults, +} from "./types" +import { + WasmCallbacks, + WasmFindex, + webassembly_logger_init, +} from "../pkg/findex/cloudproof_findex" +import { IntermediateSearchResults, Interrupt } from "./types" +import { loadWasm } from "./init" +import { SymmetricKey } from "cloudproof_kms_js" + +let loggerInit = false + +/** + * Findex definition + * @returns {Promise} results found at every node while the search walks the search graph + */ +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export class Findex { + readonly wasmFindex: WasmFindex + + private constructor(wasm_findex: WasmFindex) { + this.wasmFindex = wasm_findex + } + + /** + * Instantiates a Findex instance usin the given callbacks. + */ + static async new_with_wasm_backend( + entry_callbacks: WasmCallbacks, + chain_callbacks: WasmCallbacks, + ) { + await loadWasm() + return new Findex( + await WasmFindex.new_with_wasm_backend(entry_callbacks, chain_callbacks), + ) + } + + /** + * Instantiates a Findex instance using the token and URL. + */ + static async new_with_cloud_backend(token: string, url: string) { + await loadWasm() + return new Findex(await WasmFindex.new_with_rest_backend(token, url)) + } + + /** + * Add the following entries in the index. + * + * @param {FindexKey | SymmetricKey} masterKey Findex's key + * @param {Label} label public label for the index + * @param {IndexedEntry[]} additions new entries to upsert in indexes + * @param options Additional optional options + * @param options.verbose the optional verbose bool parameter + * @returns {Keyword[]} the list of the newly inserted keywords in the index + */ + async add( + masterKey: FindexKey | SymmetricKey | Uint8Array, + label: Label | Uint8Array, + additions: IndexedEntry[], + options: { verbose?: false } = {}, + ): Promise { + if (options.verbose === undefined && !loggerInit) { + await webassembly_logger_init() + loggerInit = true + } + + if (masterKey instanceof SymmetricKey) { + masterKey = new FindexKey(masterKey.bytes()) + } + if (masterKey instanceof Uint8Array) { + masterKey = new FindexKey(masterKey) + } + + if (label instanceof Uint8Array) { + label = new Label(label) + } + + const additionsBytes = indexedEntriesToBytes(additions, "additions") + + const newIds: Uint8Array[] = await this.wasmFindex.add( + masterKey.bytes, + label.bytes, + additionsBytes, + ) + + return newIds.map((value: Uint8Array) => new Keyword(value)) + } + + /** + * Delete the following entries from the index. + * + * @param {FindexKey | SymmetricKey} masterKey Findex's key + * @param {Label} label public label for the index + * @param {IndexedEntry[]} deletions new entries to upsert in indexes + * @param options Additional optional options + * @param options.verbose the optional verbose bool parameter + * @returns {Keyword[]} the list of the newly inserted keywords in the index + */ + async delete( + masterKey: FindexKey | SymmetricKey | Uint8Array, + label: Label | Uint8Array, + deletions: IndexedEntry[], + options: { verbose?: false } = {}, + ): Promise { + if (options.verbose === undefined && !loggerInit) { + await webassembly_logger_init() + loggerInit = true + } + + if (masterKey instanceof SymmetricKey) { + masterKey = new FindexKey(masterKey.bytes()) + } + if (masterKey instanceof Uint8Array) { + masterKey = new FindexKey(masterKey) + } + + if (label instanceof Uint8Array) { + label = new Label(label) + } + + const deletionBytes = indexedEntriesToBytes(deletions, "deletions") + + const newIds: Uint8Array[] = await this.wasmFindex.delete( + masterKey.bytes, + label.bytes, + deletionBytes, + ) + return newIds.map((value: Uint8Array) => new Keyword(value)) + } + + /** + * Search indexed keywords and return the corresponding IndexedValues + * @param {FindexKey | SymmetricKey} masterKey Findex's key + * @param {Label} label public label for the index + * @param keywords keywords to search inside the indexes + * @param options Additional optional options to the search + * @param options.userInterrupt the optional callback of found values as the search graph is walked. Returning `true` stops the walk + * @param options.verbose the optional verbose bool parameter + * @returns the search results + */ + async search( + masterKey: FindexKey | SymmetricKey | Uint8Array, + label: Label | Uint8Array, + keywords: Set | Array, + options: { + userInterrupt?: Interrupt + verbose?: false + } = {}, + ): Promise { + if (options.verbose === undefined && !loggerInit) { + await webassembly_logger_init() + loggerInit = true + } + + // convert key to a single representation + if (masterKey instanceof SymmetricKey) { + masterKey = new FindexKey(masterKey.bytes()) + } + if (masterKey instanceof Uint8Array) { + masterKey = new FindexKey(masterKey) + } + + if (label instanceof Uint8Array) { + label = new Label(label) + } + + const kws: Uint8Array[] = [] + for (const k of keywords) { + if (k instanceof Uint8Array) { + kws.push(k) + } else { + kws.push(Keyword.fromString(k).bytes) + } + } + + // Never interrupt the search if no interrupt function is passed. + const userInterrupt: Interrupt = + typeof options.userInterrupt === "undefined" + ? async (_) => false + : options.userInterrupt + + const resultsPerKeywords = await this.wasmFindex.search( + masterKey.bytes, + label.bytes, + kws, + async ( + indexedValuesPerKeywords: Array<{ + keyword: Uint8Array + results: Uint8Array[] + }>, + ) => { + return await userInterrupt( + new IntermediateSearchResults(indexedValuesPerKeywords), + ) + }, + ) + + return new SearchResults(resultsPerKeywords) + } +} diff --git a/src/findex/findex_cloud.ts b/src/findex/findex_cloud.ts deleted file mode 100644 index ce960570..00000000 --- a/src/findex/findex_cloud.ts +++ /dev/null @@ -1,110 +0,0 @@ -/* eslint-disable jsdoc/require-param */ -/* eslint-disable jsdoc/require-returns */ -import { - Findex, - IndexedEntry, - Keyword, - Label, - SearchResults, - indexedEntriesToBytes, -} from "./init" - -import { - webassembly_derive_new_token, - webassembly_generate_new_token, - webassembly_search_cloud, - webassembly_upsert_cloud, -} from "../pkg/findex/cloudproof_findex" - -/** - */ -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -export async function FindexCloud() { - await Findex() - - return { - generateNewToken: ( - indexId: string, - fetchEntriesKey: Uint8Array, - fetchChainsKey: Uint8Array, - upsertEntriesKey: Uint8Array, - insertChainsKey: Uint8Array, - ): string => { - return webassembly_generate_new_token( - indexId, - fetchEntriesKey, - fetchChainsKey, - upsertEntriesKey, - insertChainsKey, - ) - }, - - deriveNewToken: ( - token: string, - permissions: { - search: boolean - index: boolean - }, - ): string => { - return webassembly_derive_new_token( - token, - permissions.search, - permissions.index, - ) - }, - - upsert: async ( - token: string, - label: Uint8Array | Label, - additions: IndexedEntry[], - deletions: IndexedEntry[], - options: { - baseUrl?: string - } = {}, - ) => { - if (label instanceof Uint8Array) { - label = new Label(label) - } - - const additionsBytes = indexedEntriesToBytes(additions, "additions") - const deletionsBytes = indexedEntriesToBytes(deletions, "deletions") - - return ( - await webassembly_upsert_cloud( - token, - label.bytes, - additionsBytes, - deletionsBytes, - options.baseUrl, - ) - ).map((value: Uint8Array) => new Keyword(value)) - }, - - search: async ( - token: string, - label: Uint8Array | Label, - keywords: Set | Array, - options: { - baseUrl?: string - } = {}, - ) => { - if (label instanceof Uint8Array) { - label = new Label(label) - } - - const kws: Uint8Array[] = [] - for (const k of keywords) { - kws.push(k instanceof Uint8Array ? k : new TextEncoder().encode(k)) - } - - const resultsPerKeywords = await webassembly_search_cloud( - token, - label.bytes, - kws, - options.baseUrl, - ) - - return new SearchResults(resultsPerKeywords) - }, - } -} diff --git a/src/findex/in_memory.ts b/src/findex/in_memory.ts index 6916e974..fe8daa8a 100644 --- a/src/findex/in_memory.ts +++ b/src/findex/in_memory.ts @@ -1,92 +1,91 @@ -import { bytesEquals } from "../utils/utils" -import { - FetchChains, - FetchEntries, - InsertChains, - UidsAndValues, - UidsAndValuesToUpsert, - UpsertEntries, -} from "./init" +import { WasmCallbacks } from "../pkg/findex/cloudproof_findex" +import { loadWasm, UidsAndValues } from "./init" /** * @returns the callbacks */ -export function callbacksExamplesInMemory(): { - fetchEntries: FetchEntries - fetchChains: FetchChains - upsertEntries: UpsertEntries - insertChains: InsertChains -} { - const entries: UidsAndValues = [] - const chains: UidsAndValues = [] +export async function callbacksExamplesInMemory(): Promise<{ + entryCallbacks: WasmCallbacks + chainCallbacks: WasmCallbacks + dumpTables: () => void + dropTables: () => Promise +}> { + const entries: Map = new Map() + const chains: Map = new Map() const fetchCallback = async ( - table: UidsAndValues, + table: Map, uids: Uint8Array[], ): Promise => { const results: UidsAndValues = [] for (const requestedUid of uids) { - for (const { uid, value } of table) { - if (bytesEquals(uid, requestedUid)) { - results.push({ uid, value }) - break - } + const requestedValue = table.get(requestedUid.toString()) + if (requestedValue !== undefined) { + results.push({ uid: requestedUid, value: requestedValue }) } } return results } + const upsertEntries = async ( - uidsAndValues: UidsAndValuesToUpsert, + oldValues: UidsAndValues, + newValues: UidsAndValues, ): Promise => { const rejected = [] as UidsAndValues - uidsAndValuesLoop: for (const { - uid: newUid, - oldValue, - newValue, - } of uidsAndValues) { - for (const tableEntry of entries) { - if (bytesEquals(tableEntry.uid, newUid)) { - if (bytesEquals(tableEntry.value, oldValue)) { - tableEntry.value = newValue - } else { - rejected.push(tableEntry) - } - continue uidsAndValuesLoop - } - } - // The uid doesn't exist yet. - if (oldValue !== null) { + // Add old values in a map to efficiently search for matching UIDs. + let mapOfOldValues = new Map() + for (const { uid, value } of oldValues) { + mapOfOldValues.set(uid.toString(), value) + } + + for (const { uid, value: newValue } of newValues) { + let oldValue = mapOfOldValues.get(uid.toString()) + let actualValue = entries.get(uid.toString()) + + if (actualValue?.toString() === oldValue?.toString()) { + entries.set(uid.toString(), newValue) + } else if (actualValue === undefined) { throw new Error( "Rust shouldn't send us an oldValue if the table never contained a value… (except if there is a compact between)", ) + } else { + rejected.push({ uid, value: actualValue }) } - - entries.push({ uid: newUid, value: newValue }) } - return rejected } + const insertChains = async (uidsAndValues: UidsAndValues): Promise => { for (const { uid: newUid, value: newValue } of uidsAndValues) { - for (const tableEntry of chains) { - if (bytesEquals(tableEntry.uid, newUid)) { - tableEntry.value = newValue - break - } - } - - // The uid doesn't exist yet. - chains.push({ uid: newUid, value: newValue }) + chains.set(newUid.toString(), newValue) } } - return { - fetchEntries: async (uids: Uint8Array[]) => - await fetchCallback(entries, uids), - fetchChains: async (uids: Uint8Array[]) => - await fetchCallback(chains, uids), - upsertEntries, - insertChains, + const dumpTables = () => { + console.log("entry table length: ", entries.size) + console.log("chain table length: ", chains.size) + } + + const dropTables = async () => { + entries.clear() + chains.clear() } + + // Load WASM file before using it. + await loadWasm() + + let entryCallbacks = new WasmCallbacks() + entryCallbacks.fetch = async (uids: Uint8Array[]) => { + return await fetchCallback(entries, uids) + } + entryCallbacks.upsert = upsertEntries + + let chainCallbacks = new WasmCallbacks() + chainCallbacks.fetch = async (uids: Uint8Array[]) => { + return await fetchCallback(chains, uids) + } + chainCallbacks.insert = insertChains + + return { entryCallbacks, chainCallbacks, dumpTables, dropTables } } diff --git a/src/findex/init.ts b/src/findex/init.ts index c9b404ad..38c7d03a 100644 --- a/src/findex/init.ts +++ b/src/findex/init.ts @@ -1,676 +1,30 @@ -import init, { - webassembly_logger_init, - webassembly_search, - webassembly_upsert, -} from "../pkg/findex/cloudproof_findex" +import init, { WasmCallbacks } from "../pkg/findex/cloudproof_findex" -import { fromByteArray } from "base64-js" -import { parse as parseUuid, stringify as stringifyUuid } from "uuid" -import { bytesEquals, hexEncode } from "../utils/utils" +import { callbacksExamplesInMemory } from "./in_memory" +import { callbacksExamplesBetterSqlite3 } from "./sqlite" +import { Findex } from "./findex" -export * from "./in_memory" -export * from "./sqlite" +export * from "./types" let initialized: Promise | undefined -let loggerInit = false let wasmInit: (() => any) | undefined + export const setFindexInit = (arg: () => any): void => { wasmInit = arg } -export class Index { - uid: Uint8Array - value: Uint8Array - - constructor(uid: Uint8Array, value: Uint8Array) { - this.uid = uid - this.value = value - } -} - -/* tslint:disable:max-classes-per-file */ -export class IndexedValue { - static L_PREFIX = 108 - static W_PREFIX = 119 - - bytes: Uint8Array - constructor(bytes: Uint8Array) { - this.bytes = bytes - } - - static fromLocation(location: Location): IndexedValue { - const prefix = new Uint8Array(location.bytes.length + 1) - prefix[0] = IndexedValue.L_PREFIX - for (let index = 0; index < location.bytes.length; index++) { - prefix[index + 1] = location.bytes[index] - } - - return new IndexedValue(prefix) - } - - static fromNextWord(keyword: Keyword): IndexedValue { - const prefix = new Uint8Array(keyword.bytes.length + 1) - prefix[0] = IndexedValue.W_PREFIX - for (let index = 0; index < keyword.bytes.length; index++) { - prefix[index + 1] = keyword.bytes[index] - } - - return new IndexedValue(prefix) - } - - toBase64(): string { - return fromByteArray(this.bytes) - } - - getLocation(): Location | null { - if (this.bytes[0] === IndexedValue.L_PREFIX) { - return new Location(this.bytes.slice(1)) - } - - return null - } - - getNextWord(): Keyword | null { - if (this.bytes[0] === IndexedValue.W_PREFIX) { - return new Keyword(this.bytes.slice(1)) - } - - return null - } -} - -export class Location { - bytes: Uint8Array - constructor(bytes: Uint8Array) { - this.bytes = bytes - } - - static fromString(value: string): Location { - return new Location(new TextEncoder().encode(value)) - } - - /** - * Numbers are encoded in big-endian 8 bytes. - * JS `number` type cannot encode the all 64 bits numbers because it uses floating point representation - * that's why we use `BigInt` internally but we convert to `number` (it's theoretically wrong) because `number` - * is easier to use in JS that BigInt. If we insert a really big 64bits number in Java for example, JS will - * not be able to read it. - * @param value number - * @returns location - */ - static fromNumber(value: number): Location { - const buffer = new ArrayBuffer(8) - new DataView(buffer).setBigInt64(0, BigInt(value), false) - - return new Location(new Uint8Array(buffer)) - } - - /** - * Convert UUIDv4 only because they are more common. - * @param uuidv4 uuid - * @returns location - */ - static fromUuid(uuidv4: string): Location { - return new Location(Uint8Array.from(parseUuid(uuidv4))) - } - - toString(): string { - return new TextDecoder().decode(this.bytes) - } - - toNumber(): number { - if (this.bytes.length !== 8) { - throw new Error( - `The location is of length ${this.bytes.length}, 8 bytes expected for a number.`, - ) - } - - return Number(new DataView(this.bytes.buffer).getBigInt64(0, false)) - } - - toUuidString(): string { - return stringifyUuid(this.bytes) - } -} -export class Keyword { - bytes: Uint8Array - constructor(bytes: Uint8Array) { - this.bytes = bytes - } - - static fromString(value: string): Keyword { - return new Keyword(new TextEncoder().encode(value)) - } - - static fromUuid(value: string): Keyword { - return new Keyword(Uint8Array.from(parseUuid(value))) - } - - toBase64(): string { - return fromByteArray(this.bytes) - } - - toString(): string { - return new TextDecoder().decode(this.bytes) - } -} -export class FindexKey { - _bytes: Uint8Array - constructor(bytes: Uint8Array) { - this._bytes = bytes - } - - toBase64(): string { - return fromByteArray(this.bytes) - } - - public get bytes(): Uint8Array { - return this._bytes - } -} - -export class Label { - bytes: Uint8Array - constructor(value: string | Uint8Array) { - if (value instanceof Uint8Array) { - this.bytes = value - } else { - this.bytes = new TextEncoder().encode(value) - } - } - - static fromString(value: string): Label { - return new Label(new TextEncoder().encode(value)) - } -} - -/** - * A new value to index for a given set of keywords: - * IndexedValue -> Set - */ -export interface IndexedEntry { - indexedValue: IndexedValue | Location | Keyword - keywords: Set | Keyword[] | string[] -} - -/** - * Generates aliases for a keyword to use in upsert - * If keyword is "Thibaud" and minChars is 3 return these aliases ["Thi" => "Thib", "Thib" => "Thiba", "Thiba" => "Thibau", "Thibau" => "Thibaud"] - * @param keyword Generate aliases to this keyword - * @param minChars Start at this number of characters - * @param maxChars Do not generate alias of greater length than maxChars, last alias will target the original keyword - * @returns IndexedEntry to add with upsert - */ -export function generateAliases( - keyword: string, - minChars: number = 3, - maxChars: number = 8, -): IndexedEntry[] { - const entries = [] - - const endIndex = maxChars + 1 > keyword.length ? keyword.length : maxChars + 1 - - for (let charsIndex = minChars; charsIndex < endIndex; charsIndex++) { - const from = keyword.slice(0, charsIndex) - - // If we are at the last loop, target the original keyword - const to = - charsIndex === endIndex - 1 ? keyword : keyword.slice(0, charsIndex + 1) - - entries.push({ - indexedValue: IndexedValue.fromNextWord(Keyword.fromString(to)), - keywords: new Set([Keyword.fromString(from)]), - }) - } - - return entries -} - -/** - * A helper class to create a {@link IndexedEntry} when - * indexing a {@link Location} with keywords supplied - * as arrays of strings or bytes - */ -export class LocationIndexEntry implements IndexedEntry { - indexedValue: IndexedValue - keywords: Set - constructor( - location: string | Uint8Array, - keywords: string[] | Uint8Array[], - ) { - if (location instanceof Uint8Array) { - this.indexedValue = IndexedValue.fromLocation(new Location(location)) - } else { - this.indexedValue = IndexedValue.fromLocation( - new Location(new TextEncoder().encode(location)), - ) - } - this.keywords = new Set( - keywords.map((v) => { - if (v instanceof Uint8Array) { - return new Keyword(v) - } - return new Keyword(new TextEncoder().encode(v)) - }), - ) - } -} - -/** - * A helper class to create a {@link IndexedEntry} when - * indexing a {@link Keyword} to point to another {@link Keyword} - */ -export class KeywordIndexEntry implements IndexedEntry { - indexedValue: IndexedValue - keywords: Set - constructor(source: string | Uint8Array, destination: string | Uint8Array) { - if (destination instanceof Uint8Array) { - this.indexedValue = IndexedValue.fromNextWord(new Keyword(destination)) - } else { - this.indexedValue = IndexedValue.fromNextWord( - new Keyword(new TextEncoder().encode(destination)), - ) - } - if (source instanceof Uint8Array) { - this.keywords = new Set([new Keyword(source)]) - } else { - this.keywords = new Set([new Keyword(new TextEncoder().encode(source))]) - } - } -} - -/** - * Represents a `(uid, value)` tuple, i.e. a line, in the Entry or Chain table - */ -export type UidsAndValues = Index[] - -/** - * Represents a `(uid, oldValue, newValue)` tuple to upsert - * (do not upsert if oldValue is not coherent with the database) - */ -export type UidsAndValuesToUpsert = Array<{ - uid: Uint8Array - oldValue: Uint8Array | null - newValue: Uint8Array -}> - -/** - * Fetch a uid in the Entry table and return the (uid, value) column - */ -export type FetchEntries = (uids: Uint8Array[]) => Promise - -/** - * Fetch a uid in the Chain table and return the (uid, value) column - */ -export type FetchChains = (uids: Uint8Array[]) => Promise - -/** - * Insert, or update an existing, (uid, value) line in the Entry table - */ -export type UpsertEntries = ( - uidsAndValues: UidsAndValuesToUpsert, -) => Promise - -/** - * Insert, or update an existing, (uid, value) line in the Chain table - */ -export type InsertChains = (uidsAndValues: UidsAndValues) => Promise - -/** - * Called with results found at every node while the search walks the search graph. - * Returning false, stops the walk. - */ -export type Progress = (indexedValues: ProgressResults) => Promise - -/** - * Findex definition - * @returns {Promise} results found at every node while the search walks the search graph - */ -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -export async function Findex() { +export async function loadWasm() { if (initialized === undefined) { - if (wasmInit === undefined) { - throw new Error("Please provide a WASM init function") - } - - const loadModule = wasmInit() - initialized = init(loadModule).then(() => undefined) + // @ts-expect-error @ts-ignore-error + initialized = init(wasmInit()) } - await initialized - - /** - * Insert or update existing (a.k.a upsert) entries in the index - * @param {FindexKey} masterKey Findex's key - * @param {Label} label public label for the index - * @param {IndexedEntry[]} additions new entries to upsert in indexes - * @param {IndexedEntry[]} deletions entries to remove from the indexes - * @param {FetchEntries} fetchEntries callback to fetch the entries table - * @param {UpsertEntries} upsertEntries callback to upsert inside entries table - * @param {InsertChains} insertChains callback to upsert inside chains table - * @param options Additional optional options to the upsert - * @param options.verbose the optional verbose bool parameter - * @returns {Keyword[]} the list of the newly inserted keywords in the index - */ - const upsert = async ( - masterKey: FindexKey | Uint8Array, - label: Label | Uint8Array, - additions: IndexedEntry[], - deletions: IndexedEntry[], - fetchEntries: FetchEntries, - upsertEntries: UpsertEntries, - insertChains: InsertChains, - options: { verbose?: false } = {}, - ): Promise => { - const verbose = options.verbose === undefined ? false : options.verbose - if (verbose && !loggerInit) { - await webassembly_logger_init() - loggerInit = true - } - // convert key to a single representation - if (masterKey instanceof Uint8Array) { - masterKey = new FindexKey(masterKey) - } - - if (label instanceof Uint8Array) { - label = new Label(label) - } - - const additionsBytes = indexedEntriesToBytes(additions, "additions") - const deletionsBytes = indexedEntriesToBytes(deletions, "deletions") - - const newIds: Uint8Array[] = await webassembly_upsert( - masterKey.bytes, - label.bytes, - additionsBytes, - deletionsBytes, - async (uids: Uint8Array[]) => { - return await fetchEntries(uids) - }, - async (uidsAndValues: UidsAndValuesToUpsert) => { - return await upsertEntries(uidsAndValues) - }, - async (uidsAndValues: UidsAndValues) => { - return await insertChains(uidsAndValues) - }, - ) - return newIds.map((value: Uint8Array) => new Keyword(value)) - } - - /** - * Search indexed keywords and return the corresponding IndexedValues - * @param {FindexKey} masterKey Findex's key - * @param {Label} label public label for the index - * @param keywords keywords to search inside the indexes - * @param {FetchEntries} fetchEntries callback to fetch the entries table - * @param {FetchChains} fetchChains callback to fetch the chains table - * @param options Additional optional options to the search - * @param options.progress the optional callback of found values as the search graph is walked. Returning false stops the walk - * @param options.verbose the optional verbose bool parameter - * @returns the search results - */ - const search = async ( - masterKey: FindexKey | Uint8Array, - label: Label | Uint8Array, - keywords: Set | Array, - fetchEntries: FetchEntries, - fetchChains: FetchChains, - options: { - progress?: Progress - verbose?: false - } = {}, - ): Promise => { - const verbose = options.verbose === undefined ? false : options.verbose - if (verbose && !loggerInit) { - await webassembly_logger_init() - loggerInit = true - } - - // convert key to a single representation - if (masterKey instanceof Uint8Array) { - masterKey = new FindexKey(masterKey) - } - - if (label instanceof Uint8Array) { - label = new Label(label) - } - - const kws: Uint8Array[] = [] - for (const k of keywords) { - kws.push(k instanceof Uint8Array ? k : new TextEncoder().encode(k)) - } - - const progress_: Progress = - typeof options.progress === "undefined" - ? async () => true - : options.progress - - const resultsPerKeywords = await webassembly_search( - masterKey.bytes, - label.bytes, - kws, - async ( - indexedValuesPerKeywords: Array<{ - keyword: Uint8Array - results: Uint8Array[] - }>, - ) => { - return await progress_(new ProgressResults(indexedValuesPerKeywords)) - }, - async (uids: Uint8Array[]) => { - return await fetchEntries(uids) - }, - async (uids: Uint8Array[]) => { - return await fetchChains(uids) - }, - ) - - return new SearchResults(resultsPerKeywords) - } - - return { - upsert, - search, - } } -export class SearchResults { - locationsPerKeywords: Array<{ - keyword: Uint8Array - locations: Location[] - }> - - constructor( - resultsPerKeywords: Array<{ keyword: Uint8Array; results: Uint8Array[] }>, - ) { - this.locationsPerKeywords = resultsPerKeywords.map( - ({ keyword, results }) => ({ - keyword, - locations: results.map((bytes) => new Location(bytes)), - }), - ) - } - - get(keyword: string | Uint8Array): Location[] { - const keywordAsBytes = - typeof keyword === "string" ? new TextEncoder().encode(keyword) : keyword - - for (const { keyword: keywordInResults, locations } of this - .locationsPerKeywords) { - if (bytesEquals(keywordAsBytes, keywordInResults)) { - return locations - } - } - - const keywordAsString = - keyword instanceof Uint8Array ? hexEncode(keyword) : keyword - throw new Error(`Cannot find ${keywordAsString} inside the search results.`) - } - - locations(): Location[] { - return Array.from(this) - } - - toNumbers(): number[] { - return this.locations().map((location) => location.toNumber()) - } - - toStrings(): string[] { - return this.locations().map((location) => location.toString()) - } - - toUuidStrings(): string[] { - return this.locations().map((location) => location.toUuidString()) - } - - total(): number { - return this.locations().length - } - - *[Symbol.iterator](): Generator { - const alreadyYields = new Set() // Do not yield multiple times the same location if returned from multiple keywords - - for (const { locations } of this.locationsPerKeywords) { - for (const location of locations) { - const locationEncoded = hexEncode(location.bytes) - - if (!alreadyYields.has(locationEncoded)) { - alreadyYields.add(locationEncoded) - yield location - } - } - } - } -} - -export class ProgressResults { - indexedValuesPerKeywords: Array<{ - keyword: Uint8Array - indexedValues: IndexedValue[] - }> - - constructor( - resultsPerKeywords: Array<{ keyword: Uint8Array; results: Uint8Array[] }>, - ) { - this.indexedValuesPerKeywords = resultsPerKeywords.map( - ({ keyword, results }) => ({ - keyword, - indexedValues: results.map((bytes) => new IndexedValue(bytes)), - }), - ) - } - - getLocations(keyword: string | Uint8Array): Location[] { - return this.getAllIndexedValues(keyword) - .map((result) => result.getLocation()) - .filter((location) => location !== null) as Location[] - } - - getKeywords(keyword: string | Uint8Array): Keyword[] { - return this.getAllIndexedValues(keyword) - .map((result) => result.getNextWord()) - .filter((kw) => kw !== null) as Keyword[] - } - - getAllIndexedValues(keyword: string | Uint8Array): IndexedValue[] { - const keywordAsBytes = - typeof keyword === "string" ? new TextEncoder().encode(keyword) : keyword - - for (const { keyword: keywordInResults, indexedValues } of this - .indexedValuesPerKeywords) { - if (bytesEquals(keywordAsBytes, keywordInResults)) { - return indexedValues - } - } - - const keywordAsString = - keyword instanceof Uint8Array ? hexEncode(keyword) : keyword - throw new Error(`Cannot find ${keywordAsString} inside the search results.`) - } - - indexedValues(): IndexedValue[] { - return Array.from(this) - } - - total(): number { - return this.indexedValues().length - } - - *[Symbol.iterator](): Generator { - const alreadyYields = new Set() // Do not yield multiple times the same location if returned from multiple keywords - - for (const { indexedValues } of this.indexedValuesPerKeywords) { - for (const indexedValue of indexedValues) { - const ivEncoded = hexEncode(indexedValue.bytes) - - if (!alreadyYields.has(ivEncoded)) { - alreadyYields.add(ivEncoded) - yield indexedValue - } - } - } - } -} - -/** - * - * @param indexedEntries JS new indexed entries - * @param debugName Name of the parameter to show in errors - * @returns wasm formatted indexed values to keywords - */ -export function indexedEntriesToBytes( - indexedEntries: IndexedEntry[], - debugName: string, -): Array<{ - indexedValue: Uint8Array - keywords: Uint8Array[] -}> { - if (!Array.isArray(indexedEntries)) { - throw new Error( - `During Findex upsert: \`${debugName}\` should be an array, ${typeof indexedEntries} received.`, - ) - } - - return indexedEntries.map(({ indexedValue, keywords }) => { - let indexedValueBytes - if (indexedValue instanceof IndexedValue) { - indexedValueBytes = indexedValue.bytes - } else if (indexedValue instanceof Location) { - indexedValueBytes = IndexedValue.fromLocation(indexedValue).bytes - } else if (indexedValue instanceof Keyword) { - indexedValueBytes = IndexedValue.fromNextWord(indexedValue).bytes - } else { - throw new Error( - `During Findex upsert: all the \`indexedValue\` inside the \`${debugName}\` array should be of type IndexedValue, Location or Keyword, ${typeof indexedValue} received (${JSON.stringify( - indexedValue, - )}).`, - ) - } - - if (!(Symbol.iterator in Object(keywords))) { - throw new Error( - `During Findex upsert: all the elements inside the \`${debugName}\` array should have an iterable property \`keywords\`, ${typeof keywords} received (${JSON.stringify( - keywords, - )}).`, - ) - } - - return { - indexedValue: indexedValueBytes, - keywords: [...keywords].map((keyword) => { - if (keyword instanceof Keyword) { - return keyword.bytes - } else if (typeof keyword === "string") { - return Keyword.fromString(keyword).bytes - } else { - throw new Error( - `During Findex upsert: all the \`keywords\` inside the \`${debugName}\` array should be of type \`Keyword\` or string, ${typeof keyword} received (${JSON.stringify( - keyword, - )}).`, - ) - } - }), - } - }) +export { + Findex, + WasmCallbacks, + callbacksExamplesInMemory, + callbacksExamplesBetterSqlite3, } diff --git a/src/findex/sqlite.ts b/src/findex/sqlite.ts index 9468b182..259093d9 100644 --- a/src/findex/sqlite.ts +++ b/src/findex/sqlite.ts @@ -1,13 +1,6 @@ import { Database, Statement } from "better-sqlite3" -import { - FetchChains, - FetchEntries, - Index, - InsertChains, - UidsAndValues, - UidsAndValuesToUpsert, - UpsertEntries, -} from "./init" +import { WasmCallbacks } from "../pkg/findex/cloudproof_findex" +import { Index, loadWasm, UidsAndValues } from "./init" /** * @param db the SQLite3 connection @@ -15,22 +8,21 @@ import { * @param chainsTableName name of the chains table * @returns the callbacks */ -export function callbacksExamplesBetterSqlite3( +export async function callbacksExamplesBetterSqlite3( db: Database, entriesTableName: string = "entries", chainsTableName: string = "chains", -): { - fetchEntries: FetchEntries - fetchChains: FetchChains - upsertEntries: UpsertEntries - insertChains: InsertChains -} { +): Promise<{ + entryCallbacks: WasmCallbacks + chainCallbacks: WasmCallbacks +}> { db.prepare( `CREATE TABLE IF NOT EXISTS ${entriesTableName} (uid BLOB PRIMARY KEY, value BLOB NOT NULL)`, ).run() db.prepare( `CREATE TABLE IF NOT EXISTS ${chainsTableName} (uid BLOB PRIMARY KEY, value BLOB NOT NULL)`, ).run() + // // Prepare some useful SQL requests on different databases // `prepare` a statement is a costly operation we don't want to do on every line (or in every callback) @@ -87,10 +79,19 @@ export function callbacksExamplesBetterSqlite3( } const upsertEntries = async ( - uidsAndValues: UidsAndValuesToUpsert, + oldValues: UidsAndValues, + newValues: UidsAndValues, ): Promise => { const rejected = [] - for (const { uid, oldValue, newValue } of uidsAndValues) { + + // Add old values in a map to efficiently search for matching UIDs. + let mapOfOldValues = new Map() + for (const { uid, value } of oldValues) { + mapOfOldValues.set(uid.toString(), value) + } + + for (const { uid, value: newValue } of newValues) { + let oldValue = mapOfOldValues.get(uid.toString()) const result = upsertIntoEntriesTableStmt.run( uid, newValue, @@ -114,12 +115,18 @@ export function callbacksExamplesBetterSqlite3( } } - return { - fetchEntries: async (uids: Uint8Array[]) => - await fetchCallback(entriesTableName, uids), - fetchChains: async (uids: Uint8Array[]) => - await fetchCallback(chainsTableName, uids), - upsertEntries, - insertChains, - } + // Load WASM file before using it. + await loadWasm() + + let entryCallbacks = new WasmCallbacks() + entryCallbacks.fetch = async (uids: Uint8Array[]) => + await fetchCallback(entriesTableName, uids) + entryCallbacks.upsert = upsertEntries + + let chainCallbacks = new WasmCallbacks() + chainCallbacks.fetch = async (uids: Uint8Array[]) => + await fetchCallback(chainsTableName, uids) + chainCallbacks.insert = insertChains + + return { entryCallbacks, chainCallbacks } } diff --git a/src/findex/types.ts b/src/findex/types.ts new file mode 100644 index 00000000..dcef4022 --- /dev/null +++ b/src/findex/types.ts @@ -0,0 +1,490 @@ +import { parse as parseUuid, stringify as stringifyUuid } from "uuid" +import { fromByteArray } from "base64-js" +import { bytesEquals, hexEncode } from "../utils/utils" + +export class Index { + uid: Uint8Array + value: Uint8Array + + constructor(uid: Uint8Array, value: Uint8Array) { + this.uid = uid + this.value = value + } +} + +/* tslint:disable:max-classes-per-file */ +export class IndexedValue { + static L_PREFIX = 108 + static W_PREFIX = 119 + + bytes: Uint8Array + constructor(bytes: Uint8Array) { + this.bytes = bytes + } + + static fromLocation(location: Location): IndexedValue { + const prefix = new Uint8Array(location.bytes.length + 1) + prefix[0] = IndexedValue.L_PREFIX + for (let index = 0; index < location.bytes.length; index++) { + prefix[index + 1] = location.bytes[index] + } + + return new IndexedValue(prefix) + } + + static fromNextWord(keyword: Keyword): IndexedValue { + const prefix = new Uint8Array(keyword.bytes.length + 1) + prefix[0] = IndexedValue.W_PREFIX + for (let index = 0; index < keyword.bytes.length; index++) { + prefix[index + 1] = keyword.bytes[index] + } + + return new IndexedValue(prefix) + } + + toBase64(): string { + return fromByteArray(this.bytes) + } + + getLocation(): Location | null { + if (this.bytes[0] === IndexedValue.L_PREFIX) { + return new Location(this.bytes.slice(1)) + } + + return null + } + + getNextWord(): Keyword | null { + if (this.bytes[0] === IndexedValue.W_PREFIX) { + return new Keyword(this.bytes.slice(1)) + } + + return null + } +} + +export class Location { + bytes: Uint8Array + constructor(bytes: Uint8Array) { + this.bytes = bytes + } + + static fromString(value: string): Location { + return new Location(new TextEncoder().encode(value)) + } + + /** + * Numbers are encoded in big-endian 8 bytes. + * JS `number` type cannot encode the all 64 bits numbers because it uses floating point representation + * that's why we use `BigInt` internally but we convert to `number` (it's theoretically wrong) because `number` + * is easier to use in JS that BigInt. If we insert a really big 64bits number in Java for example, JS will + * not be able to read it. + * @param value number + * @returns location + */ + static fromNumber(value: number): Location { + const buffer = new ArrayBuffer(8) + new DataView(buffer).setBigInt64(0, BigInt(value), false) + + return new Location(new Uint8Array(buffer)) + } + + /** + * Convert UUIDv4 only because they are more common. + * @param uuidv4 uuid + * @returns location + */ + static fromUuid(uuidv4: string): Location { + return new Location(Uint8Array.from(parseUuid(uuidv4))) + } + + toString(): string { + return new TextDecoder().decode(this.bytes) + } + + toNumber(): number { + if (this.bytes.length !== 8) { + throw new Error( + `The location is of length ${this.bytes.length}, 8 bytes expected for a number.`, + ) + } + + return Number(new DataView(this.bytes.buffer).getBigInt64(0, false)) + } + + toUuidString(): string { + return stringifyUuid(this.bytes) + } +} + +export class Keyword { + bytes: Uint8Array + constructor(bytes: Uint8Array) { + this.bytes = bytes + } + + static fromString(value: string): Keyword { + return new Keyword(new TextEncoder().encode(value)) + } + + static fromUuid(value: string): Keyword { + return new Keyword(Uint8Array.from(parseUuid(value))) + } + + toBase64(): string { + return fromByteArray(this.bytes) + } + + toString(): string { + return new TextDecoder().decode(this.bytes) + } +} + +export class FindexKey { + _bytes: Uint8Array + constructor(bytes: Uint8Array) { + this._bytes = bytes + } + + toBase64(): string { + return fromByteArray(this.bytes) + } + + public get bytes(): Uint8Array { + return this._bytes + } +} + +export class Label { + bytes: Uint8Array + constructor(value: string | Uint8Array) { + if (value instanceof Uint8Array) { + this.bytes = value + } else { + this.bytes = new TextEncoder().encode(value) + } + } + + static fromString(value: string): Label { + return new Label(new TextEncoder().encode(value)) + } +} + +/** + * A new value to index for a given set of keywords: + * IndexedValue -> Set + */ +export interface IndexedEntry { + indexedValue: IndexedValue | Location | Keyword + keywords: Set | Keyword[] | string[] +} + +/** + * Generates aliases for a keyword to use in upsert + * If keyword is "Thibaud" and minChars is 3 return these aliases ["Thi" => "Thib", "Thib" => "Thiba", "Thiba" => "Thibau", "Thibau" => "Thibaud"] + * @param keyword Generate aliases to this keyword + * @param minChars Start at this number of characters + * @param maxChars Do not generate alias of greater length than maxChars, last alias will target the original keyword + * @returns IndexedEntry to add with upsert + */ +export function generateAliases( + keyword: string, + minChars: number = 3, +): IndexedEntry[] { + const entries = [] + + for (let charsIndex = minChars; charsIndex < keyword.length; charsIndex++) { + entries.push({ + indexedValue: IndexedValue.fromNextWord( + Keyword.fromString(keyword.slice(0, charsIndex + 1)), + ), + keywords: new Set([Keyword.fromString(keyword.slice(0, charsIndex))]), + }) + } + + return entries +} + +/** + * A helper class to create a {@link IndexedEntry} when + * indexing a {@link Location} with keywords supplied + * as arrays of strings or bytes + */ +export class LocationIndexEntry implements IndexedEntry { + indexedValue: IndexedValue + keywords: Set + constructor( + location: string | Uint8Array, + keywords: string[] | Uint8Array[], + ) { + if (location instanceof Uint8Array) { + this.indexedValue = IndexedValue.fromLocation(new Location(location)) + } else { + this.indexedValue = IndexedValue.fromLocation( + new Location(new TextEncoder().encode(location)), + ) + } + this.keywords = new Set( + keywords.map((v) => { + if (v instanceof Uint8Array) { + return new Keyword(v) + } + return new Keyword(new TextEncoder().encode(v)) + }), + ) + } +} + +/** + * A helper class to create a {@link IndexedEntry} when + * indexing a {@link Keyword} to point to another {@link Keyword} + */ +export class KeywordIndexEntry implements IndexedEntry { + indexedValue: IndexedValue + keywords: Set + constructor(source: string | Uint8Array, destination: string | Uint8Array) { + if (destination instanceof Uint8Array) { + this.indexedValue = IndexedValue.fromNextWord(new Keyword(destination)) + } else { + this.indexedValue = IndexedValue.fromNextWord( + new Keyword(new TextEncoder().encode(destination)), + ) + } + if (source instanceof Uint8Array) { + this.keywords = new Set([new Keyword(source)]) + } else { + this.keywords = new Set([new Keyword(new TextEncoder().encode(source))]) + } + } +} + +/** + * Represents a `(uid, value)` tuple, i.e. a line, in the Entry or Chain table + */ +export type UidsAndValues = Index[] + +/** + * Fetch a uid in the Entry table and return the (uid, value) column + */ +export type Fetch = (uids: Uint8Array[]) => Promise + +/** + * Insert, or update an existing, (uid, value) line in the Entry table + */ +export type Upsert = ( + old_values: UidsAndValues, + new_values: UidsAndValues, +) => Promise + +/** + * Insert, or update an existing, (uid, value) line in the Chain table + */ +export type Insert = (uidsAndValues: UidsAndValues) => Promise + +/** + * Called with results found at every node while the search walks the search graph. + * Returning false, stops the walk. + */ +export type Interrupt = ( + indexedValues: IntermediateSearchResults, +) => Promise + +export class SearchResults { + locationsPerKeywords: Array<{ + keyword: Uint8Array + locations: Location[] + }> + + constructor( + resultsPerKeywords: Array<{ keyword: Uint8Array; results: Uint8Array[] }>, + ) { + this.locationsPerKeywords = resultsPerKeywords.map( + ({ keyword, results }) => ({ + keyword, + locations: results.map((bytes) => new Location(bytes)), + }), + ) + } + + get(keyword: string | Uint8Array): Location[] { + const keywordAsBytes = + typeof keyword === "string" ? new TextEncoder().encode(keyword) : keyword + + for (const { keyword: keywordInResults, locations } of this + .locationsPerKeywords) { + if (bytesEquals(keywordAsBytes, keywordInResults)) { + return locations + } + } + + const keywordAsString = + keyword instanceof Uint8Array ? hexEncode(keyword) : keyword + throw new Error(`Cannot find ${keywordAsString} inside the search results.`) + } + + locations(): Location[] { + return Array.from(this) + } + + toNumbers(): number[] { + return this.locations().map((location) => location.toNumber()) + } + + toStrings(): string[] { + return this.locations().map((location) => location.toString()) + } + + toUuidStrings(): string[] { + return this.locations().map((location) => location.toUuidString()) + } + + total(): number { + return this.locations().length + } + + *[Symbol.iterator](): Generator { + const alreadyYields = new Set() // Do not yield multiple times the same location if returned from multiple keywords + + for (const { locations } of this.locationsPerKeywords) { + for (const location of locations) { + const locationEncoded = hexEncode(location.bytes) + + if (!alreadyYields.has(locationEncoded)) { + alreadyYields.add(locationEncoded) + yield location + } + } + } + } +} + +export class IntermediateSearchResults { + indexedValuesPerKeywords: Array<{ + keyword: Uint8Array + indexedValues: IndexedValue[] + }> + + constructor( + resultsPerKeywords: Array<{ keyword: Uint8Array; results: Uint8Array[] }>, + ) { + this.indexedValuesPerKeywords = resultsPerKeywords.map( + ({ keyword, results }) => ({ + keyword, + indexedValues: results.map((bytes) => new IndexedValue(bytes)), + }), + ) + } + + getLocations(keyword: string | Uint8Array): Location[] { + return this.getAllIndexedValues(keyword) + .map((result) => result.getLocation()) + .filter((location) => location !== null) as Location[] + } + + getKeywords(keyword: string | Uint8Array): Keyword[] { + return this.getAllIndexedValues(keyword) + .map((result) => result.getNextWord()) + .filter((kw) => kw !== null) as Keyword[] + } + + getAllIndexedValues(keyword: string | Uint8Array): IndexedValue[] { + const keywordAsBytes = + typeof keyword === "string" ? new TextEncoder().encode(keyword) : keyword + + for (const { keyword: keywordInResults, indexedValues } of this + .indexedValuesPerKeywords) { + if (bytesEquals(keywordAsBytes, keywordInResults)) { + return indexedValues + } + } + + const keywordAsString = + keyword instanceof Uint8Array ? hexEncode(keyword) : keyword + throw new Error(`Cannot find ${keywordAsString} inside the search results.`) + } + + indexedValues(): IndexedValue[] { + return Array.from(this) + } + + total(): number { + return this.indexedValues().length + } + + *[Symbol.iterator](): Generator { + const alreadyYields = new Set() // Do not yield multiple times the same location if returned from multiple keywords + + for (const { indexedValues } of this.indexedValuesPerKeywords) { + for (const indexedValue of indexedValues) { + const ivEncoded = hexEncode(indexedValue.bytes) + + if (!alreadyYields.has(ivEncoded)) { + alreadyYields.add(ivEncoded) + yield indexedValue + } + } + } + } +} + +/** + * + * @param indexedEntries JS new indexed entries + * @param debugName Name of the parameter to show in errors + * @returns wasm formatted indexed values to keywords + */ +export function indexedEntriesToBytes( + indexedEntries: IndexedEntry[], + debugName: string, +): Array<{ + indexedValue: Uint8Array + keywords: Uint8Array[] +}> { + if (!Array.isArray(indexedEntries)) { + throw new Error( + `During Findex upsert: \`${debugName}\` should be an array, ${typeof indexedEntries} received.`, + ) + } + + return indexedEntries.map(({ indexedValue, keywords }) => { + let indexedValueBytes + if (indexedValue instanceof IndexedValue) { + indexedValueBytes = indexedValue.bytes + } else if (indexedValue instanceof Location) { + indexedValueBytes = IndexedValue.fromLocation(indexedValue).bytes + } else if (indexedValue instanceof Keyword) { + indexedValueBytes = IndexedValue.fromNextWord(indexedValue).bytes + } else { + throw new Error( + `During Findex upsert: all the \`indexedValue\` inside the \`${debugName}\` array should be of type IndexedValue, Location or Keyword, ${typeof indexedValue} received (${JSON.stringify( + indexedValue, + )}).`, + ) + } + + if (!(Symbol.iterator in Object(keywords))) { + throw new Error( + `During Findex upsert: all the elements inside the \`${debugName}\` array should have an iterable property \`keywords\`, ${typeof keywords} received (${JSON.stringify( + keywords, + )}).`, + ) + } + + return { + indexedValue: indexedValueBytes, + keywords: [...keywords].map((keyword) => { + if (keyword instanceof Keyword) { + return keyword.bytes + } else if (typeof keyword === "string") { + return Keyword.fromString(keyword).bytes + } else { + throw new Error( + `During Findex upsert: all the \`keywords\` inside the \`${debugName}\` array should be of type \`Keyword\` or string, ${typeof keyword} received (${JSON.stringify( + keyword, + )}).`, + ) + } + }), + } + }) +} diff --git a/src/index.ts b/src/index.ts index 3ce3adb4..5ad7f9a3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,7 +32,6 @@ export { type CoverCryptKeyGeneration, } from "./cover_crypt/key_generation" export * from "./ecies/init" -export * from "./findex/findex_cloud" export * from "./findex/init" export * from "./fpe/fpe" export { logger } from "./utils/logger" diff --git a/src/pkg/cover_crypt/.gitignore b/src/pkg/cover_crypt/.gitignore deleted file mode 100644 index f59ec20a..00000000 --- a/src/pkg/cover_crypt/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* \ No newline at end of file diff --git a/src/pkg/cover_crypt/cloudproof_cover_crypt.d.ts b/src/pkg/cover_crypt/cloudproof_cover_crypt.d.ts new file mode 100644 index 00000000..022df3b2 --- /dev/null +++ b/src/pkg/cover_crypt/cloudproof_cover_crypt.d.ts @@ -0,0 +1,171 @@ +/* tslint:disable */ +/* eslint-disable */ +/** +* @param {Uint8Array} policy_bytes +* @param {string} access_policy +* @param {Uint8Array} public_key_bytes +* @param {Uint8Array} header_metadata +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_encrypt_hybrid_header(policy_bytes: Uint8Array, access_policy: string, public_key_bytes: Uint8Array, header_metadata: Uint8Array, authentication_data: Uint8Array): Uint8Array; +/** +* Decrypt with a user decryption key an encrypted header +* of a resource encrypted using an hybrid crypto scheme. +* @param {Uint8Array} usk_bytes +* @param {Uint8Array} encrypted_header_bytes +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_decrypt_hybrid_header(usk_bytes: Uint8Array, encrypted_header_bytes: Uint8Array, authentication_data: Uint8Array): Uint8Array; +/** +* Symmetrically Encrypt plaintext data in a block. +* @param {Uint8Array} symmetric_key_bytes +* @param {Uint8Array} plaintext_bytes +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_encrypt_symmetric_block(symmetric_key_bytes: Uint8Array, plaintext_bytes: Uint8Array, authentication_data: Uint8Array): Uint8Array; +/** +* Symmetrically Decrypt encrypted data in a block. +* @param {Uint8Array} symmetric_key_bytes +* @param {Uint8Array} encrypted_bytes +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_decrypt_symmetric_block(symmetric_key_bytes: Uint8Array, encrypted_bytes: Uint8Array, authentication_data: Uint8Array): Uint8Array; +/** +* Generates both a encrypted header and a DEM encryption of the `plaintext`, +* with the header metadata as associated data. +* +* - `metadata_bytes` : serialized metadata +* - `policy_bytes` : serialized policy +* - `attribute_bytes` : serialized attributes to use in the encapsulation +* - `pk` : CoverCrypt public key +* - `plaintext` : message to encrypt with the DEM +* - `header_metadata` : additional data to symmetrically encrypt in the +* header +* - `authentication_data` : optional data used for authentication +* @param {Uint8Array} policy_bytes +* @param {string} access_policy +* @param {Uint8Array} pk +* @param {Uint8Array} plaintext +* @param {Uint8Array} header_metadata +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_hybrid_encrypt(policy_bytes: Uint8Array, access_policy: string, pk: Uint8Array, plaintext: Uint8Array, header_metadata: Uint8Array, authentication_data: Uint8Array): Uint8Array; +/** +* Decrypt the DEM ciphertext with the header encapsulated symmetric key, +* with the header metadata as associated data. +* +* - `usk_bytes` : serialized user secret key +* - `encrypted_bytes` : concatenation of the encrypted header and the DEM +* ciphertext +* - `authentication_data` : optional data used for authentication +* +* Return the decrypted data (additional data in header and cleartext) as a +* binary format: 1. LEB128 length of the additional data bytes +* 2. additional data bytes +* 3. cleartext bytes +* @param {Uint8Array} usk_bytes +* @param {Uint8Array} encrypted_bytes +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_hybrid_decrypt(usk_bytes: Uint8Array, encrypted_bytes: Uint8Array, authentication_data: Uint8Array): Uint8Array; +/** +* @param {string} name +* @param {({name: string, isHybridized: boolean})[]} attribute_properties +* @param {boolean} is_hierarchical +* @returns {string} +*/ +export function webassembly_policy_axis(name: string, attribute_properties: ({name: string, isHybridized: boolean})[], is_hierarchical: boolean): string; +/** +* @param {number} nb_creations +* @returns {Uint8Array} +*/ +export function webassembly_policy(nb_creations: number): Uint8Array; +/** +* @param {Uint8Array} policy +* @param {string} axis +* @returns {Uint8Array} +*/ +export function webassembly_add_axis(policy: Uint8Array, axis: string): Uint8Array; +/** +* Rotates attributes, changing their underlying values with that of an unused +* slot +* +* - `attributes` : user access policy (boolean expression as string) +* - `policy` : global policy data (bytes) +* +* Returns the `rotated` policy +* @param {Array} attributes +* @param {Uint8Array} policy +* @returns {Uint8Array} +*/ +export function webassembly_rotate_attributes(attributes: Array, policy: Uint8Array): Uint8Array; +/** +* Generate the master authority keys for supplied Policy +* +* - `policy` : global policy data (JSON) +* @param {Uint8Array} policy_bytes +* @returns {Uint8Array} +*/ +export function webassembly_generate_master_keys(policy_bytes: Uint8Array): Uint8Array; +/** +* Generate a user secret key. +* +* - `msk_bytes` : master secret key in bytes +* - `access_policy_str` : user access policy (boolean expression as string) +* - `policy` : global policy data (JSON) +* @param {Uint8Array} msk_bytes +* @param {string} access_policy_str +* @param {Uint8Array} policy_bytes +* @returns {Uint8Array} +*/ +export function webassembly_generate_user_secret_key(msk_bytes: Uint8Array, access_policy_str: string, policy_bytes: Uint8Array): Uint8Array; + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly memory: WebAssembly.Memory; + readonly webassembly_encrypt_hybrid_header: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void; + readonly webassembly_decrypt_hybrid_header: (a: number, b: number, c: number, d: number) => void; + readonly webassembly_encrypt_symmetric_block: (a: number, b: number, c: number, d: number) => void; + readonly webassembly_decrypt_symmetric_block: (a: number, b: number, c: number, d: number) => void; + readonly webassembly_hybrid_encrypt: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void; + readonly webassembly_hybrid_decrypt: (a: number, b: number, c: number, d: number) => void; + readonly webassembly_policy_axis: (a: number, b: number, c: number, d: number, e: number, f: number) => void; + readonly webassembly_policy: (a: number, b: number) => void; + readonly webassembly_add_axis: (a: number, b: number, c: number, d: number, e: number) => void; + readonly webassembly_rotate_attributes: (a: number, b: number, c: number, d: number) => void; + readonly webassembly_generate_master_keys: (a: number, b: number, c: number) => void; + readonly webassembly_generate_user_secret_key: (a: number, b: number, c: number, d: number, e: number, f: number) => void; + readonly __wbindgen_export_0: (a: number, b: number) => number; + readonly __wbindgen_export_1: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_add_to_stack_pointer: (a: number) => number; + readonly __wbindgen_export_2: (a: number, b: number, c: number) => void; + readonly __wbindgen_export_3: (a: number) => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; +/** +* Instantiates the given `module`, which can either be bytes or +* a precompiled `WebAssembly.Module`. +* +* @param {SyncInitInput} module +* +* @returns {InitOutput} +*/ +export function initSync(module: SyncInitInput): InitOutput; + +/** +* If `module_or_path` is {RequestInfo} or {URL}, makes a request and +* for everything else, calls `WebAssembly.instantiate` directly. +* +* @param {InitInput | Promise} module_or_path +* +* @returns {Promise} +*/ +export default function __wbg_init (module_or_path?: InitInput | Promise): Promise; diff --git a/src/pkg/cover_crypt/cloudproof_cover_crypt.js b/src/pkg/cover_crypt/cloudproof_cover_crypt.js new file mode 100644 index 00000000..5d8d3cf8 --- /dev/null +++ b/src/pkg/cover_crypt/cloudproof_cover_crypt.js @@ -0,0 +1,750 @@ +let wasm; + +const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); + +if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; + +let cachedUint8Memory0 = null; + +function getUint8Memory0() { + if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { + cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8Memory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); +} + +const heap = new Array(128).fill(undefined); + +heap.push(undefined, null, true, false); + +let heap_next = heap.length; + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + +function getObject(idx) { return heap[idx]; } + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + +let WASM_VECTOR_LEN = 0; + +const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); + +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}); + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8Memory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8Memory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + +let cachedInt32Memory0 = null; + +function getInt32Memory0() { + if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { + cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); + } + return cachedInt32Memory0; +} + +function passArray8ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 1, 1) >>> 0; + getUint8Memory0().set(arg, ptr / 1); + WASM_VECTOR_LEN = arg.length; + return ptr; +} +/** +* @param {Uint8Array} policy_bytes +* @param {string} access_policy +* @param {Uint8Array} public_key_bytes +* @param {Uint8Array} header_metadata +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_encrypt_hybrid_header(policy_bytes, access_policy, public_key_bytes, header_metadata, authentication_data) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(policy_bytes, wasm.__wbindgen_export_0); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(access_policy, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + const len1 = WASM_VECTOR_LEN; + wasm.webassembly_encrypt_hybrid_header(retptr, ptr0, len0, ptr1, len1, addHeapObject(public_key_bytes), addHeapObject(header_metadata), addHeapObject(authentication_data)); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* Decrypt with a user decryption key an encrypted header +* of a resource encrypted using an hybrid crypto scheme. +* @param {Uint8Array} usk_bytes +* @param {Uint8Array} encrypted_header_bytes +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_decrypt_hybrid_header(usk_bytes, encrypted_header_bytes, authentication_data) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.webassembly_decrypt_hybrid_header(retptr, addHeapObject(usk_bytes), addHeapObject(encrypted_header_bytes), addHeapObject(authentication_data)); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* Symmetrically Encrypt plaintext data in a block. +* @param {Uint8Array} symmetric_key_bytes +* @param {Uint8Array} plaintext_bytes +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_encrypt_symmetric_block(symmetric_key_bytes, plaintext_bytes, authentication_data) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.webassembly_encrypt_symmetric_block(retptr, addHeapObject(symmetric_key_bytes), addHeapObject(plaintext_bytes), addHeapObject(authentication_data)); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* Symmetrically Decrypt encrypted data in a block. +* @param {Uint8Array} symmetric_key_bytes +* @param {Uint8Array} encrypted_bytes +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_decrypt_symmetric_block(symmetric_key_bytes, encrypted_bytes, authentication_data) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.webassembly_decrypt_symmetric_block(retptr, addHeapObject(symmetric_key_bytes), addHeapObject(encrypted_bytes), addHeapObject(authentication_data)); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* Generates both a encrypted header and a DEM encryption of the `plaintext`, +* with the header metadata as associated data. +* +* - `metadata_bytes` : serialized metadata +* - `policy_bytes` : serialized policy +* - `attribute_bytes` : serialized attributes to use in the encapsulation +* - `pk` : CoverCrypt public key +* - `plaintext` : message to encrypt with the DEM +* - `header_metadata` : additional data to symmetrically encrypt in the +* header +* - `authentication_data` : optional data used for authentication +* @param {Uint8Array} policy_bytes +* @param {string} access_policy +* @param {Uint8Array} pk +* @param {Uint8Array} plaintext +* @param {Uint8Array} header_metadata +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_hybrid_encrypt(policy_bytes, access_policy, pk, plaintext, header_metadata, authentication_data) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(policy_bytes, wasm.__wbindgen_export_0); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(access_policy, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + const len1 = WASM_VECTOR_LEN; + wasm.webassembly_hybrid_encrypt(retptr, ptr0, len0, ptr1, len1, addHeapObject(pk), addHeapObject(plaintext), addHeapObject(header_metadata), addHeapObject(authentication_data)); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* Decrypt the DEM ciphertext with the header encapsulated symmetric key, +* with the header metadata as associated data. +* +* - `usk_bytes` : serialized user secret key +* - `encrypted_bytes` : concatenation of the encrypted header and the DEM +* ciphertext +* - `authentication_data` : optional data used for authentication +* +* Return the decrypted data (additional data in header and cleartext) as a +* binary format: 1. LEB128 length of the additional data bytes +* 2. additional data bytes +* 3. cleartext bytes +* @param {Uint8Array} usk_bytes +* @param {Uint8Array} encrypted_bytes +* @param {Uint8Array} authentication_data +* @returns {Uint8Array} +*/ +export function webassembly_hybrid_decrypt(usk_bytes, encrypted_bytes, authentication_data) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.webassembly_hybrid_decrypt(retptr, addHeapObject(usk_bytes), addHeapObject(encrypted_bytes), addHeapObject(authentication_data)); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +let cachedUint32Memory0 = null; + +function getUint32Memory0() { + if (cachedUint32Memory0 === null || cachedUint32Memory0.byteLength === 0) { + cachedUint32Memory0 = new Uint32Array(wasm.memory.buffer); + } + return cachedUint32Memory0; +} + +function passArrayJsValueToWasm0(array, malloc) { + const ptr = malloc(array.length * 4, 4) >>> 0; + const mem = getUint32Memory0(); + for (let i = 0; i < array.length; i++) { + mem[ptr / 4 + i] = addHeapObject(array[i]); + } + WASM_VECTOR_LEN = array.length; + return ptr; +} +/** +* @param {string} name +* @param {({name: string, isHybridized: boolean})[]} attribute_properties +* @param {boolean} is_hierarchical +* @returns {string} +*/ +export function webassembly_policy_axis(name, attribute_properties, is_hierarchical) { + let deferred4_0; + let deferred4_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(name, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArrayJsValueToWasm0(attribute_properties, wasm.__wbindgen_export_0); + const len1 = WASM_VECTOR_LEN; + wasm.webassembly_policy_axis(retptr, ptr0, len0, ptr1, len1, is_hierarchical); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r3 = getInt32Memory0()[retptr / 4 + 3]; + var ptr3 = r0; + var len3 = r1; + if (r3) { + ptr3 = 0; len3 = 0; + throw takeObject(r2); + } + deferred4_0 = ptr3; + deferred4_1 = len3; + return getStringFromWasm0(ptr3, len3); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export_2(deferred4_0, deferred4_1, 1); + } +} + +function getArrayU8FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len); +} +/** +* @param {number} nb_creations +* @returns {Uint8Array} +*/ +export function webassembly_policy(nb_creations) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.webassembly_policy(retptr, nb_creations); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r3 = getInt32Memory0()[retptr / 4 + 3]; + if (r3) { + throw takeObject(r2); + } + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export_2(r0, r1 * 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* @param {Uint8Array} policy +* @param {string} axis +* @returns {Uint8Array} +*/ +export function webassembly_add_axis(policy, axis) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(policy, wasm.__wbindgen_export_0); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(axis, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + const len1 = WASM_VECTOR_LEN; + wasm.webassembly_add_axis(retptr, ptr0, len0, ptr1, len1); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r3 = getInt32Memory0()[retptr / 4 + 3]; + if (r3) { + throw takeObject(r2); + } + var v3 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export_2(r0, r1 * 1); + return v3; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* Rotates attributes, changing their underlying values with that of an unused +* slot +* +* - `attributes` : user access policy (boolean expression as string) +* - `policy` : global policy data (bytes) +* +* Returns the `rotated` policy +* @param {Array} attributes +* @param {Uint8Array} policy +* @returns {Uint8Array} +*/ +export function webassembly_rotate_attributes(attributes, policy) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(policy, wasm.__wbindgen_export_0); + const len0 = WASM_VECTOR_LEN; + wasm.webassembly_rotate_attributes(retptr, addHeapObject(attributes), ptr0, len0); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r3 = getInt32Memory0()[retptr / 4 + 3]; + if (r3) { + throw takeObject(r2); + } + var v2 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export_2(r0, r1 * 1); + return v2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* Generate the master authority keys for supplied Policy +* +* - `policy` : global policy data (JSON) +* @param {Uint8Array} policy_bytes +* @returns {Uint8Array} +*/ +export function webassembly_generate_master_keys(policy_bytes) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(policy_bytes, wasm.__wbindgen_export_0); + const len0 = WASM_VECTOR_LEN; + wasm.webassembly_generate_master_keys(retptr, ptr0, len0); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* Generate a user secret key. +* +* - `msk_bytes` : master secret key in bytes +* - `access_policy_str` : user access policy (boolean expression as string) +* - `policy` : global policy data (JSON) +* @param {Uint8Array} msk_bytes +* @param {string} access_policy_str +* @param {Uint8Array} policy_bytes +* @returns {Uint8Array} +*/ +export function webassembly_generate_user_secret_key(msk_bytes, access_policy_str, policy_bytes) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(access_policy_str, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(policy_bytes, wasm.__wbindgen_export_0); + const len1 = WASM_VECTOR_LEN; + wasm.webassembly_generate_user_secret_key(retptr, addHeapObject(msk_bytes), ptr0, len0, ptr1, len1); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + wasm.__wbindgen_export_3(addHeapObject(e)); + } +} + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + + } catch (e) { + if (module.headers.get('Content-Type') != 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { + throw e; + } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + + } else { + return instance; + } + } +} + +function __wbg_get_imports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbindgen_string_new = function(arg0, arg1) { + const ret = getStringFromWasm0(arg0, arg1); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_is_null = function(arg0) { + const ret = getObject(arg0) === null; + return ret; + }; + imports.wbg.__wbindgen_object_drop_ref = function(arg0) { + takeObject(arg0); + }; + imports.wbg.__wbg_crypto_c48a774b022d20ac = function(arg0) { + const ret = getObject(arg0).crypto; + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_is_object = function(arg0) { + const val = getObject(arg0); + const ret = typeof(val) === 'object' && val !== null; + return ret; + }; + imports.wbg.__wbg_process_298734cf255a885d = function(arg0) { + const ret = getObject(arg0).process; + return addHeapObject(ret); + }; + imports.wbg.__wbg_versions_e2e78e134e3e5d01 = function(arg0) { + const ret = getObject(arg0).versions; + return addHeapObject(ret); + }; + imports.wbg.__wbg_node_1cd7a5d853dbea79 = function(arg0) { + const ret = getObject(arg0).node; + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_is_string = function(arg0) { + const ret = typeof(getObject(arg0)) === 'string'; + return ret; + }; + imports.wbg.__wbg_msCrypto_bcb970640f50a1e8 = function(arg0) { + const ret = getObject(arg0).msCrypto; + return addHeapObject(ret); + }; + imports.wbg.__wbg_require_8f08ceecec0f4fee = function() { return handleError(function () { + const ret = module.require; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbindgen_is_function = function(arg0) { + const ret = typeof(getObject(arg0)) === 'function'; + return ret; + }; + imports.wbg.__wbg_getRandomValues_37fa2ca9e4e07fab = function() { return handleError(function (arg0, arg1) { + getObject(arg0).getRandomValues(getObject(arg1)); + }, arguments) }; + imports.wbg.__wbg_randomFillSync_dc1e9a60c158336d = function() { return handleError(function (arg0, arg1) { + getObject(arg0).randomFillSync(takeObject(arg1)); + }, arguments) }; + imports.wbg.__wbg_valueOf_e39b017d2100ede0 = function(arg0) { + const ret = getObject(arg0).valueOf(); + return ret; + }; + imports.wbg.__wbg_newnoargs_581967eacc0e2604 = function(arg0, arg1) { + const ret = new Function(getStringFromWasm0(arg0, arg1)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_next_ddb3312ca1c4e32a = function() { return handleError(function (arg0) { + const ret = getObject(arg0).next(); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_done_5c1f01fb660d73b5 = function(arg0) { + const ret = getObject(arg0).done; + return ret; + }; + imports.wbg.__wbg_value_1695675138684bd5 = function(arg0) { + const ret = getObject(arg0).value; + return addHeapObject(ret); + }; + imports.wbg.__wbg_get_97b561fb56f034b5 = function() { return handleError(function (arg0, arg1) { + const ret = Reflect.get(getObject(arg0), getObject(arg1)); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_call_cb65541d95d71282 = function() { return handleError(function (arg0, arg1) { + const ret = getObject(arg0).call(getObject(arg1)); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbindgen_string_get = function(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + var len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; + }; + imports.wbg.__wbindgen_object_clone_ref = function(arg0) { + const ret = getObject(arg0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_self_1ff1d729e9aae938 = function() { return handleError(function () { + const ret = self.self; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_window_5f4faef6c12b79ec = function() { return handleError(function () { + const ret = window.window; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_globalThis_1d39714405582d3c = function() { return handleError(function () { + const ret = globalThis.globalThis; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_global_651f05c6a0944d1c = function() { return handleError(function () { + const ret = global.global; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbindgen_is_undefined = function(arg0) { + const ret = getObject(arg0) === undefined; + return ret; + }; + imports.wbg.__wbg_from_d7c216d4616bb368 = function(arg0) { + const ret = Array.from(getObject(arg0)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_values_e80af618f92c8649 = function(arg0) { + const ret = getObject(arg0).values(); + return addHeapObject(ret); + }; + imports.wbg.__wbg_call_01734de55d61e11d = function() { return handleError(function (arg0, arg1, arg2) { + const ret = getObject(arg0).call(getObject(arg1), getObject(arg2)); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_buffer_085ec1f694018c4f = function(arg0) { + const ret = getObject(arg0).buffer; + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_6da8e527659b86aa = function(arg0, arg1, arg2) { + const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_new_8125e318e6245eed = function(arg0) { + const ret = new Uint8Array(getObject(arg0)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_set_5cf90238115182c3 = function(arg0, arg1, arg2) { + getObject(arg0).set(getObject(arg1), arg2 >>> 0); + }; + imports.wbg.__wbg_length_72e2208bbc0efc61 = function(arg0) { + const ret = getObject(arg0).length; + return ret; + }; + imports.wbg.__wbg_newwithlength_e5d69174d6984cd7 = function(arg0) { + const ret = new Uint8Array(arg0 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_subarray_13db269f57aa838d = function(arg0, arg1, arg2) { + const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + imports.wbg.__wbindgen_memory = function() { + const ret = wasm.memory; + return addHeapObject(ret); + }; + + return imports; +} + +function __wbg_init_memory(imports, maybe_memory) { + +} + +function __wbg_finalize_init(instance, module) { + wasm = instance.exports; + __wbg_init.__wbindgen_wasm_module = module; + cachedInt32Memory0 = null; + cachedUint32Memory0 = null; + cachedUint8Memory0 = null; + + + return wasm; +} + +function initSync(module) { + if (wasm !== undefined) return wasm; + + const imports = __wbg_get_imports(); + + __wbg_init_memory(imports); + + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + + const instance = new WebAssembly.Instance(module, imports); + + return __wbg_finalize_init(instance, module); +} + +async function __wbg_init(input) { + if (wasm !== undefined) return wasm; + + if (typeof input === 'undefined') { + input = new URL('cloudproof_cover_crypt_bg.wasm', import.meta.url); + } + const imports = __wbg_get_imports(); + + if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) { + input = fetch(input); + } + + __wbg_init_memory(imports); + + const { instance, module } = await __wbg_load(await input, imports); + + return __wbg_finalize_init(instance, module); +} + +export { initSync } +export default __wbg_init; diff --git a/src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm b/src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1599725d1d15ebdc33d13419fbdb95af2933391a GIT binary patch literal 468243 zcmeFa54>H)b>F-HoO{l>_uMNT{lC(cVD?5}2_ewmdnLd|TQ*=BV=(@oI1&1D1)MAX z=nn#HjN|~eoM2l?NJ|r^R$Ed?idx#|wlpQN9FsG$LHLb96T5w)ZggF z^q@V*%FuIkW6XaIo=66ikVbrL+H?7hjF!(JN8s)Yh54Xb_mMpq3J5}|&DSWpv0Z+s z%G`I~eNhFFLg{^mRi`XSs$Ae2QhXJTmeAT~{HrCr-s@kLB!4ipEWK;{P4l*Hy=(g| zx9z-X^0uw}_V2yrwwt!zHhEVR>D%nuw_EmYz3tB3yQ5Se7S%r7zP&fOWB=BjdvCvE z>)y#-(SQmpQGuJb?$~?J9s6(Jx?|mjZ4(pgwy#>VX6Kq!+je*$b8A3=?&0`P=lJS( z?7e-*{K? z+R61hSFQG?#(b&UZr?e%b@h&&6WiAB+^~M_&h3-iCN`cG4^MZCgFL!Iuiy?w#Co=Pi3Dw{F~_usJXww<@%`q6E>@0{GXb?wBiZEJRH+c>#yautu;qgas6_l5Ub z$*XSJz57G=+_q!u&K;{KH*OnWwPW@A4Qtnq@APE@Y6k@Gx?Ni**KXXtYW2j1Jlw|8z|yLL6W zt=<8-*KG5ELW!NX-!{2*{f^bUR;}K(eSCb?&WW|#*ZUHSeN%?d*45)1*N;!EU%ht2 z_=a`ccZMP+TQ_Zm7F#z?Y+pYPjP>KYR;^tJ43o;x%8qTjcW>RXeSH1;b*p!7T)%T- z^_mT9e2KHjG~hf%tagz1Ai6tt3t`Ew33q_MZ*uppt*dwKTD@~(%|=MOZF1w<4W5@l zy6*za?RRZm50|%1?i$~*dd>EUjgvcknJln$_wC!a?f&r12>9xqYd21;Ubk-5`t=*u z>|7hl1z0y(xvk^tq1yT#QH8ZU!?hE>~kjj!IYYvY<78^+g#QBbEUBC>Yf&dK%b zcaE=~T)lc{l+?!b_B(g&n%ui})rR$xuy}mqx>c(;>{u6Qx4IIgyKdQk^Y(l8Pu{+3 z*S^X9$m;IN+iu!_^Vad5+cr$DUo$bje&hBH+wR%A8kMnTeB-Y56Wg|JSi2#Rq+4Um{+svS zewUZAS+(q2CvUxd?>)%G|42`zokrYf4x}?%%|^31dmwH!(s&?E2h+I8^I)?TCyh96 z^3rNG;xtZ@fyO{1ilauLkPPq$^3g!Mkq)Hs3|=D8B%?#AI2{-eMh3sp9BDAO(wU(&9csmcbU#h!H`An* zHU>5AQe%L2q6Iv*NK^h<^(ac>ftD3fsq#U%laQsc{wZ^jQM|2{eR%gNtQ52gPx{twAl8(&Yq+W7JGM0)eL(tn$N zBlaJ@3Y1gHOYsX7_$!TXrO&1h@$}!)hti**_)j%nP5(>!pJ?GfrGozl>3>dNN&gSN z{6_L@dNKh2kJOkB?SD^xE&0XtkJ8uDe*Pb(|0Mmd)ch;yx04f9{$FXl68|Ph`EoA< z$>a0;JiVHHE&X=-zoq{^eLVeq`p5BarQb}ymHu)1-_u`AUq@4Z5oljYe-gM4Q~x*9 z*OLF4{s}tttBs%Gzppm_guf4`kEXwn{^R85`TJPPWm^}FDAz+@m%_k`TBbDV)`O){|0=YPk$}_PV!&i z!*hK3T;pi`qsf0tUP?co{F~(SjiJvyJ9;Yp*@@)S2WQ=PUR0cHOy%vRk!u&-o=dua zJ9Y8OD9RES7xASL`7XIMI^IY&x#Y^mrsAnrz8Nh`qT;*!ueGPKsr%E7BHov6?5J8i z5(6h1Pabc$_U33JJ=y?FyO({K{|ank4FUiJ~vlcXOdeU|iNqz{vRob(9kCrBS6{Q=VFqF(lc zq$f!~N%}1550TF8Wj{>v0ARP09wNPw^i`^DBYlN*JLyZLJ4jz7-AVca=_Khhq`OFu zlio!7BScG4EbV1?lek`X56R+Q_9>FrXyMbOUn9L&??Ctr z>AGHaAIa-vA0&O6^iZq}zJE4OH@U&$ifbC1+_*S*sT*IPM4R2`@*ktj`sB&vf&53} z&FQ`Q=itSg&;jYocyzF8(n4Rys*#&NCc8Qypt>S$( z@9*G!1Mh1DvN^oZ<^5dV z7x6wT;C)f($9bV&D?>lu6~12)zHbWOi|~DO`2Ozj{XOCPmErqUFlMQ1x#hil`7t-- zmi6*w$KcBYZpJa!v8M+``=WbSKBJd+$aC`o(UsTfd>*WG&%F$ z7=GKsKL$3Qr3E=x*P+j=po`;0OAQS5avE6X23_Lb*~{l0a|_&hb;Y{ij=6QA5@IEE zT`wPWgU4JqNRsjfdwJKFPpDoi55kF?*UJ|iD@$7!Al3Q`{$Q;<2n&7i4P8fHFyj#%A!9l`7UySadH&-8XE>sPo16?{u8Nw5oE75UF zd->H?PK}k6R}J5nch*Ery{Xf^E}Br;#L!(`Lie2T*q}w~eevjK3*3a8=~nh~S{`%n zQcsK#7ant2K>b0_hzomphID1e+{NxeQ#N8m*2`D=8Z!Y_F_5$J~XrcEJfGg=->Q`@|kq?*cr?eI~8|3Z=m`aY)L$e9s_FofcpQ{2Qj@3Ijf5 zrSk`4U{{0cONK5Q`u>XaiJNaS|M}1pQGcdyY2uh$9QvZK^ku$7NEX8;7!tTAUbu@Z z_QJ%nFRCNl#l^BT?=6Qg^|@4UfxZBrW-l(wdro-K$v;0$>c8y!GTU9^M%E#Py!@^^3RoQ=X7xwZ?e0N8VxjD5OpgIzSGEj@0Id23XLsw{d@WOZjL+uSlI}9=erAf z`31fU!vLt&0O8?Ye$Fw}!n7^~{xTfSuayR2!9V6MC`*&Gwhp@_&jUt!!46Unrb}v& zzzQUL`4Y$tA41#YE~()Pxrb|YJg!$(rFl20zskzMnQ1M6*=1+o3IjYH^7~_8S5kk( zOUfMgKt=k*onumeIP^p^=_%({9dq*oUiu2wBMu>1h}6U0z&&yox=VWbDvupfU-m_H zgnKW4cU7AAmKuDIFHO%&(Nt;rVnT>m2I!vd9(I0sn$-WeA&hOc$Q34?v)ty24f!#* zBA_l7f#k5;(93Br^qidBt?A{ylv{Mn&8n3L%|(?+h8pC}s^CM@yjC7GhaF=C_$$g5 z$fLzG;eVkbeZPs-Zmzqcm(M!p&UKr5xd-hoKjtp2H3G^Yy!x1XN7)29aO)jb#?7U2 ztu*M)bs&6h)n#?S<KDXAs@a^SARhoB``pq6&2wt|X7QpS&>9in+7CkNU2V#+Ums$cKSmE;CIdnC z>%A@+&nsilVM6lqxL&$Q&v^2P&u5b5g>^ksnTq3JP~|5RcR6nxtS&Ol^D?VCm#0yl zrY)8m_p*3?mnv=b>)6C~C>OaK-3-6N9kkbNe&sp?+g%VNx81L4J7Ha6c{^BX*pgJ} zL~bXdY)jQ4d!1xiWlPwWz3!r~nLXV^Coi<8n`smy#-49sq2TQ?d+pKrF?*V#m6`Um zn+9gv)2#qoXiv8RY>7SH4luO6J>LN^KPlSl9)QiUr@a6hv8R0iJI9{(18jvo#l@y6 z;N|vmr+FRRrS@_F;0!@~z6;=9_t@**0H0+~_W*p6J$(w`=i1Xa^k?b$F6i@V?*vG~ zddNQCOWWSgv)9k?>Zd4sy^mL~8SFK7=H&1W4{}aPFwEEC{T^gJrL46Y#oqlv*4^%) zTUTe>q1cVqarkWPE(_yc%@p{^I=Io=J@;Y!FUkI1aXfN^Q)C@&^xS)U#jtztRQLA~ zUCAFKxVR`Fo4uEgI!*eSN%v6yuU}?d7=SCekBv=WQH`PV?qnITGQ{ z8;MX2xc*{O5#|Cco}l4o5xIde30m6?6i++@QhJrE&jJ5YrRjKr%TKOE)K|MW(&%La z>JNU#Bj}x``5Ea&4&uYv4B_9-Xa~PawjkNm|EH`*o&qSB+fj{=CtcTc$vFLM7V&t} z9tOjth(3@HT{)5zfBK)l8R58O@^wSq-$?WL%8~T+YEIQ$THLW^gt|>gOrO&3&nB)Z zL}DdfQ6D|fWB8=q!;M8WnrdB7%Uw6H4Bu#~q=6@sq@4`_=;f#c`uqOq41e+*8Eh30 z1$6aH6i`Ffg3*Kaz`2A=#X(39o-Bg|~jU;c#OCm8FxQ6k-EKxM%rp^b8ct4g3gmeSf zjPaBd?Q2PkgZqke4`eMW4nhVbLs~vnKj-o$Nk&d2nyEx~u2M$BfER7oq7E|q-jO&t zi1;K8-UmR^nv{RNFUCcT7!M~M6=VDt>gBJbKt8=pCm%3O5VQuZp*Ij!Z6b3zbPZDVe#*$>|26TZMFw_c(=G|A}_a8uei1)rTCTd>r zQhd>jdnnV+KtUA328T7Hy`pOajGjRw4b66OT*^V5Y)@EYAl2j}mDG4sE`8587=UIw z-pB`pTvSN9)DJRGG!S0WXHat#Yv2V(9Z;&;n~=0iVX600Sj$k4d8-&bfM2&&bPve2 zTO9hcbWhPffQuKkd88qaYCfbgbKH>1%q1zyl!jZrsLGlpoxTA#_Y6I(;-Mq_FuOj0 zP8)$0+3Y?m#a*=4%qvHP7M(S{I`c0RJ%rt;a0Z&-*ttd;(q^0@Du$&ZA=1$XPH@u4 z8`vWGOB4?OO=1SE>kC0)P zYPv;qGE2hbm^4g~yPs6|Pd1RYnL&dx;d%|Kt*zt<@#*!SJ04giNivCg&9ZD3M3y~9 z-G8U?)OH&$jZ{W-KiVixK7KqZ=K2!FqmS|O5;@%yl>Mt0B(v}PYuejTw#>GZ9wFU9`Vi?(Qf;|iMyf5d zn@LZQ-a@LqtRAVh%%(^WlkO(7As{lO7<|*4Aj?nkbZ_#TYLABYKQ6| zDf5K3tZ0yj&+0+DWt(FV zqJm8{JkXK0&oJL3R8{tnQZ@>|s8lv)hF&YoJTEw#pD*?U~74Yh&CvMYJQo=hLhu5u0A zI=k8pSo&VRXe(`tMC0)!d!Jt*W!Lz1QTBen9Llcs3!&@-Y^6=QAExDe30tZ^q=!Z9 zd@ac?c8juQq?eFhAZU*y`T1;XZc~wSvzy$FdKk?vcU$$aAbY1fKYN!umo2l=EVJFP z^V#e>mwmp`Ea!c(fE-Tp`Pmh2r>dNnZE`#GFfUv0w(DVeR=D}uh3>p;1$%Ex-Ewwy z=VzOFzlishyiWwYuMhqBVCdHkp`RPW_YZ~d9}eF?625;leE(SZ{_*hr6XE+0z>ZNi z$KG$Q&E@Wz($^rjp7#Pg2;Jo@U^`^gEtHcR!%#$5CYuD_)8*L4@;g{o9@hZQI(#9% zB(J0Lk@)=*Hd?Cf2Vl4F%73tze-fWrC`|^A)!_dDkJ1}%tk=GcW0|8Jgaz(=b`w5; zA5z}&Yvs{5AJBV_xvPUG!sAZy1#Su3H8`Rw+}R59o+aFY&ikutxSvP6HSDWhFZxvO z`gq)N?U7f)1@}JO8twzOjesLRZ1aK24^BgIiTboaC{_qAk}oHq2+2w^(5%rD+P}Xn zO~wN4hhF0eFr9hebhY_XYe>Q!4;dGZSQ>DdDKxX?esqb{^R^`X;j85xAo$Y6k8PFflepw|XK)=@a0Fu`FOAnw8XAw8qZt2j zA7%V&eS&zIH7NqajlKM*Vzw1SVRF{XA!Z_q^p;NON~|vz^mmFNyWAD-dP9Db`(TAU zzVr9?(ea~i9-{{IZ|b8D4a1PcQ|DcCrC2kB<@}z8yq7}8V?{wP*6@Q{#LJ#2iCr|6aPsQqj(Ye+Myx@V(wGD;P ziC%vF>0S7s0X?$|fPn}#IZ^qpZRHAV)0R_{rMv_df z&*=*Wdw5}Aed#eb-Y<<@XW|muNYh0l$Tej0`*WpS+W;Ye!4m_qrg9(!yTT5$URS+8e#v2?e20D#FLv(D^ABf z1bBc?DFa@tm)XvBNfmHMtOHzj4ociBv3{4KCRA!e8zk3gpVSCkp_r+g0n~UOR4LX_ z{}W}0p!huX@&`P08ZP(mJ(63r7Yqd|0#iA-%{z6Om}4?A?pE~08kakKEX8_h6^p`H zo-QEE9NOS?GH232p${TypE01!DF4{B9svF0z6Z-r@4*>lX5ZGsWk;ztFy~qiRuD?? z5lI9A4j%<85A+f?D*FgP^b57kgX~r$zr?Y!4LhSNsoXCOy1BMK7MG=ke{J$YhWw^* zDbr&L>_E~hl3%Eu%pgT<9+jkMn&pH3m{8lGI1hK{X7?fCLF~bYE4hB(G5791K48yA zD{v~@7rS*;Pd8JwUlvr?squ?wHI(<%55XJk#g=>OUR*8^U4UIqq+Y6h8G?x_+=Eo~ z^0n5Oq`Hg(0T3vz6QJo*ovWJx)I=XtDb?(dex&RaNJ5NW{!tH|hReM~k0$%yLcLF7 zD*I3;Hl1oRVS_K5fSQ#GxyU%#l(4`?0yP3DVB>TVxj+Iuk4EasBNuN&A4Jq?q((?S zG_40f|FG`?9G%_+m;#w=J$PRUH*eH?K!35KE^^%S8#91FqY7=Wx?(Imfl0%8R*L47=`=LPIO zk0)A|lHF1Ejh3t3pX+&gpDGh{JD#kvA|oo|tjK1bx;#~@(&lFNuF`i=-0fjY(^ig) zDHOTAtSoFrsm-#;?eiW0m4uvI5NcN0VVUZiD;Nx33*G812EXnmu(~88 zj)w(qsCtFZ3*2z^iWg#m*B}Nea_?a$!8{ARzbcuyk_>Y&knyB4t|G(y3}oEFwz0dq z1^^$%d;K6Zcn`;JiyxkP#hH0NyD@I{mXX9=Dj#%&nJbVi5G%_N`2g8MK$$ zzSa3QfO#HPoWg3CXy2*>kgoaO967}!U&S%@J2=KponLp1ZNRUL1mhCJV_`0_Pm;Tw`*H-9ajs*d9{3#N-;2OH8gYxy0lelS@plF}cL# z8k0**t}(g9NT_+l5KZq9LnysR%v@s%L;uMb7t96TBZd$}sP{{QM{K0@h$WI+ykGBj zi3HYsV~Hd+@xC#6!1|uCL_;8Zuh(ta7O!gYjQQa5YrJ~JGvKC=Zk`O$NqNACJ;q>G<_=EF?|-)u&?5Z=u>G@dED`GkypY6_dZaP!8fm1 z#cHW;g9)*|OwcbEK_=b1uziHQdBy_rHAk^-2cMFH9(i~vuVf$hK3rt6#NCTEGzg;=R3`dOq9D$dm>PvE1OpLGYh2a` z%@;_>C*e z)P^=0<5F%>Zg$ACyONo|f?+FFS;Y%vCQx;bnq`y$il1Fpgdv<259y9KxrE z>N4TIr0bw(CDt63fWW0#v*i#7fxJu?kauXi<#aMTX`s*tk#w4nAk`n8)&rn_%=h3O zr}y9tGGAH3%{%oTc%R;d-j{^5ua{@ca|}1E^B$>kid-%?B(hsc#l>>u2Co&aj`h>f z&Ex>X5$H>6RMsXhWT^D=dbwB>c77_EUM@FEAYRR{T6xsht8Gx6%aWzg-V3g}74nP) zx!!WjZSLcP$gtc2PKEoJe7vEjMc>Ek#bu2e$0a#kroGq95vN@`vOMlfMHgU~6RDSK zUxpy)ij6@k6mngfY&A0s6wS{&U8>Dj9zd<{gDRyOSM7((PMK8G%a3^IH9xOMbF;;I zbDYu?5=i#_yu)>wu)&wDhnkfN!OsgPy`Op>tL5?_6>OX?B1S00&o8~Pxk z_Sxcf^$pW{0Ca!Y2+)ph?}POKGuH`rV^BTVu*$0|42+P=%| zU41v$d3~4J@<1zdua!fb^}$Yg#CFy_VmG-E3(%8KLH;pY|Ja-SV|B+?hz{V}@!0j; zgkK6+(J6dj{ffI?*oe1pk-M()P92Kft@yy~Ag_JA4Ify);_WW%z=w)qU!J#3EC}(4 zg$?`gIc($e*2a+#HurgxN9=~GO&0%QS+>A6JcT$4-d0&n^9wmEBDYePr)pI?AdgsL9%EBCE z^Qa>SnXME#R_47x!9%tXZ%gUQ+0RPL7Jxn^`c6i!MM!uT*a6luwqW!gw!4sK@0Gfn z-hRN^xQ8aq@fW#IflS{?^l5B-@BO+LO02cQpMehY3`XugK)u7B4g$*ipAN~XW!}Qb zeKrPI-^GOU;2iw+s)_qx0i#HdI1uKCh;n=g+DT9@ZiIQk#fB$=Rek9Y!=Hc)*^>gF z!or%*3fICp!E1+iq4a{`V3;2qZkL+;%OQrd!8;vmentEa^IhK=i1%TB&6|f4BJ3v^ zei2T(0qY)&E({SfYSKg4(8qNH-L0*uK(&{6HzOILx#d7*C##fkUXT>_qp__FvgWfX<_fXezUfK-k? z*XX_msAb8ce2{NDAIR*TivdQmM8qLdl}I|P^$3MFD;_=}GE?|KYM0O+E=LOk?%pkA zmZx0>qb4vjBM4BcHkPVA4TcYaZE~O^8@7f<6vG}{V?vGBC|A^e((5AVpm#LMn#2Kn zL=~Z0G_pn!!f|m=7KB80f6{t#B*_SNln<&y5Hg|KipU3-WWQ&ffmKYT`lRmDY*Rsu z14VolK3PwljvKBuT{f)rVIrI@gc8z&t708bZ#W~Al0Zwz@|!n}SgCDjdbVa8r}voH zeqZ#A9uqEK>v0qAevckELXWQ|7MZFdnm`jz+CvNmiexGqB1!ib?WwG392aLy#2N+u z0PGh>hKUi+8XX_J+EMJcYvjq*=B&<_KLbP?diIH*;GHBH0x(ekwigh%khe7aA zmy;Sw4>gF}cf$FKJrvq|X*9#$h7WKX3va{r);v&s9w}0eK1{1I)81wu;9i%r)u;fL zEsPWvGf((^JLeb&gZZikLHmgI--Mmy^5~=Uk)TT>MZYT-ji$pX$U`07krKh<)_9S0 zASWUTRI8OYZS(<>kw>((AY}o(L-IQ^l42X{B41N&==cjKY!WvN3-e*)UB_k%FSL9? zBp*#O6V0Ougy;QXsRj)ck`c*)&Lp(;(BaU|K-PAHxoM}TV}=n`U1vO5O2Xveyw+VN zh83w;<+U~)Aw#o8k(i1$_1$H{)R^E}pkcbgu()~z8eI}a#V@`V@htftxF{0iqYnTq zR-AXn(q5kQ=I2n#l(fW zlH9^5hR-0%Y{WIEI6TnyT;iT0@7Eh8RA@&;QP&zn<*NXL3fx z%`86qBM-Ev7%ZfB?_m@T`6;a|HKbBQXOwE76i{LDwUQ>97y^Eap&J_V_=yi5ZH+OJ zTQj$$g|`e0Ig=w}eTEMEpxv-&{4A_9Th`;qwdnk!bW;)6`yI1OT<S5AqN}O<4Da!!!3;- zM2LBVa|*0Gm}Hp7 z@)ygdW+YK8S{q9Qh9_oKj0EL0c#S?_3Pgq-X59!{XS0Oixb6u{ix=Y_hr6;_JhBxE z88ebu7~&jzd>hgIj9IBSGKl@=%MLoUUYYTI-_@L;D;F* zcmHOJg;&XiEJin^6Ku#tBIA;SP2pvf194?zvScp@s;86p1_FE-im;(+qY>-_fwY!<4U5Dk1+P9$%9AAGs~Ibv^+f#=d&jgmI69X;jApDTR3N|T9M-$ zYkfa%q*T<_>!;9v*tkqUto&sZP|_ws|3rVFT;%3F23c$h>*}ec$!z$_kzq}9!@~?h zqpS_@?!SURVtpn=Xg=_6I^YF|?1{VY{2~0LmS9Y)1+UvN+*V&aFT|Aq%qlF`JjZzOI z<{1vR2lYvZ2=UW%BmkKw#>{ z3_+!URXCSWsDEpjx-7$hqTiu+z?YB8y*3;C6q&nlcZ%F97oj z!Un$=3$#e75LNSd%qT;0jx)vT5UVU#o#_@6k$PDkeq2LwNV!=bj>qt+oF6jvEzAyo zE*Z3zn2b!H$z^A=(~FjI+VtfoD%X7s%g{J0-u@-bSDKmn!w42K0*0#Y_U9_*PR&(k z&JESc(_(R9&LC*ZuoA(&O=EM{a9~*?P1&Ew(BI9HRg&ygw1N~c$A7Q6D^)a;&8vSd z>^0BA-4a)u*-Bh(W-D>EnXQlO|0`y;!7E2Fxfua6FaM%uwpIVnoZ0AWYJE*R1?RZ^ z`P&Z8OgB)@w{NZxkN;d{=Kn8Hh^D5NhN;78YEBi7xHRfKxhz@W-M2?^-!^cHG!)<` z)x~M$wP6})EW;Cue=pO5r=iG0h8YLQ8)CB_XFG~K9cMF(Bd>llO71HTlQ2lHm-Fxu z|C}whkL1cIZ=mP9|2(yV^5+mYNHNz~o-WH5OHuITI{6rWZhJGVW^_+7(-j-=S^2i5 z2UONk<-H_hx|o7h>hkm{V6JjAWSAPPRVrsDUPBR)p`w{u4Q9ydUACKlktUz%W)#D_ zd+ddoFK&)pQ}gva%rX0hg)}a3GqbLzleOK|g&JMCNw8H#8HEKA%u59W(EAAHa)?!)>F=6wnH z;QjgH>qjE1*>SUq$SwZVV?}xZKZhIGGnFq?cevodZmW=hE&@&BR4~KvWFTsbH^-lG ziv@*OjA6NapbVSPt|<#%vkMC;?0lO~LLX$nB%o^Gd65;p#4Xtze{LFX*VABIt`DyF z>Sb~yu;7II61*mE?aOFQ&8RhaCzx;08e_ty=>et3WA1UWVW-U#Jv|%S!m=eEaJ7o3 zY|iohJ>32UA*T^+477@Nmcn7$lP^xa%D8!k_s-dCn45%#Fp0U!#*KL*V-He3?P>K7 z+2jth8%?IQXGJN*B0bY$L!QBQvG73Nmj98arvO4GI5^8{Ir<@b$9txkPJ>$yTH3r!cW4Xh9BvNi(h2dK2{tUyy6cYk%I;>e_ zEZu4)evX%w5vt3`kCvl^goqn8{=9cQ>@gGr=B*v z5S&XRjTYP)5ZV^z#xd!X5&V@V`;AK?+)li#ZJDDbJmBm>DlkPz$cP`JzZK=+{ zIdGOT{ySrLF4UNVK1M&(1)Nj-bLs3Hbj~tb<&=ot{?T zGzufN9dt>t6L}jb7EkF09hgA-`=u-wuxK~cN5;+hh*aP38>l`MUMjzt>h8|u0Ud#X zHg+mCHzqYV_J(S1Ow*<55>a2iR~qxfFx4=$QNevBk~}vgDU~*Gv+UKh-2jSL+HUOr z9AGx0&!)3%y9D_}X*JOb!%>IT>wxa`5Wl4+%+1d*$!rglCFXd-1|~jN+mdFUA^Qd&9>Z(E2H5G z2jeL!7VAiB)Q+#aOd>%eGVHj9YN@D(Vd}hLibQ(FrXHL=92?7JxGk30`Yjm0j%C_> zOuGjfor|@&)QwGWSPlVOpPQ9+B$-GL!+BX}SP?C6MPO2h(_Dka=r0blfd2wzmLVf~ zs!_$`E8K$y6{M}h^b86Kj@mr&^NaK4^3i+` z7tqx>XPAr`PFkm+5V2~Zn->xzlsw1Jixi$&&qJAyspIe{%z(!1*BJN&HHg{p3_CMe ziBvp<`|(kBM$oj3nLK4)Wjn3o5d`w`^i<4Q6JWj;i1~`-EX8xwosuNV+Cqsl$hiM( zii_X8z2aw0eFt3$NGO*|I#QF4A-;}1W>dXp_gtGco=eZfgpWwdCGy@EW{>R9Fr?UM zI8#C}Y~w6}ax$9SP(b3vXiBqbHHVOY`W!NbRjN4zykH3CovG?#KN2}CYr$rJKx#@B zu0b=?UfU{S^q@nFIlba;S!BgselISWvQhCE)8qiPJD#g&KucjUV-r0zl@EA$VJ-~= zxnp1?ChU&{+5VGwm?=U8?P$1SLg$DGGrV{J14M>15f^`Hsx~~u0CQ)<<&%NS&jv0t zbWEEZkNsqbcEJm5`~Y3+k($xQ4TRyn&u4lhgQ)5ewI1e2FI2~vZR7J#5Ez@l;En7h z*p2A7G!#jcgF-mAdHBA3i8@d3mORFQU{qlI61s%IHUq`kp@eZ;sPU)z-I(jJAW`kM zJw`|d7cO>1<2&pB9p>C|!7hsC`R zHnNz>m}$Mi8tRgmEg=^xk;eT-@%5jLcWa5;?G=meEWSIr8Og$idx3*TZgbdFKIv=Q3c{s7;m83cFrr zpez$2%@W1mX)O%?#Dm5b-WnA%h|Md$^e6N)E$%i^jEfoAr$QN5srAq$0p;XuC?}z# zSOco1Uo`U_wOT{Wy>C`)$k)Ox+fgmn`btK=M=j!UXiFt$_zE-Mv;xZ|(UV2Jr`4O# zQ_irVH>J5;UHmY?o0f?wGsDePndCISU;=sGX{#h-mKR@S;V@+ma9lm`*w=zRZ-p<5d@b1XR`?=U7BT>PW{5fb@QxDf<~Nmr`MwtNHcQ24 z`&x6}wATM}mLh0q>F%4dUBAsR+s%2?GW_5j{PP2)rS9TOQNplnpKYMDZFseSOu_E~ zdA5hlVET)OjMJplcNMzLv!NT*9_Zr#`X2J{rpZ52GElr~^3Pnr4t5sH=45hA$Y!ab zjVFwB-FF=0g}}5=ML3pPN(QFBVS4h_-)!~uWbt%|bxIg-n3==@r)R@Dt&}w*GLg@M z)q_ov5ndHWqBFzcEg^F1Z+xbP$S-Tb^!5;06%aYZd>$9aqqmOAQy11S`SyXgjmb%( zkMO=k+7JVk7vBadhrgZFaQT(i+s5V95*JqJ;Bv^XZr>7zp8u(PYq@;^(mi-=?%YS>ket9TCLkZQ%0MziZa$@`sJLjmyarm*a-Zi*Ey$ z=l<)bYPfvozPF9btAs_vvqp>wa>h58983kBWAR)l+mP!vh5SVjJtB) zef;_Qy!)e{s+wiew(~bOT6xH<6j8xhyOIZzn&#C55_w3hwZ~T8rdTLAM@XT z*GZXzpNZ*yBjrrOT>rq{l7EN`YS|q zp+&l{iZAJpzNy7O5n%;OYSsqHK|O#UOM^wlxjf20at$v$Vie*Ky(y2T4zTG0pm_gO z@h%*nO`0yAe&w5yJOuU&3{ciq+1`=W>^{xTtPTT)rFXK)#oa^1J-UYcha@t~Qw#LR zkHBx5*diTsE3+TA&@VR&G?p5LIaE+j;Hgl{f{yKYpG)uBgV#dQtpe5kdq`;aXZhg@`HdUJ3m%DUN79nzN?jr! zY~YUEP(v>2zL4HLoz76um_!aW8Y_UpnS?yr-~DH5Big@5sEK&f z2o-k1A@4Lo@#+bMx2GbMQ40n`t|X9)T^1ps@)f}tlc44qU)eWC)HqniZz|z((-tGnTDg}Qe0b?xQ(P-0 z3nt1hcZO(XGQ8Ol(4IThO{g?X_-XbqQnzr_X-p#(g76?1m0;Nq#8i@WQ#G44nE!M#{KNQaD!DAy7!6-JUQmg?ZA7(bKZ4By8*=jae)u;BL)t2yB&jwLy z;4OEzx~6G}O;!8G)a57CeCAZKfSFQ^XUht1xoApu2>mOCbg)OT(TIlL3_?+6N{%V& zr<3%IiP=+xje?K+S5RJjU+YDTP#WV0-!5I{oVW)D66XaM- zMR8nDL&8q{&{;O_xzy7Po+K&+iqK|M&;wCQr_;@i$YG_cMu=geP0l_loGGGU_isVR zFp!nQKt_UV`ug;NT+^3tHjvrLkpz(p(~=Ejz)MR@LJ>%*B*UJB_XaYiv1Pn~ShA(i zU471ElolPQMB-pIUUP|D zminHdLfFSwyDF}TD*iA~rVXp499E?TgdE5~lZcBWXB}1`=VxUb#p+*aB-QDy4hCX} z^0s|d77di~+o_0x48uTJ3=JHbWHESTi%XG_!Qd$YQlinfc}^cgGG~LO^JZfR>@|i+ z_$@Rqe29rM1KLahud8$4Jy%qGa~<(KI>Jma6@5`JvY7RvwEFV0US0@alvc%F)yqra zi_)stDZRWBz9_AV9r{CFUJGB8R>cnM%j@Bb(yG`IeR+UC!cA#a>=C^@6uu~}ialKa za#SzM5rD7MUmn+sa`ffV`pc7gQI5VmQGa<#FUrxEuhn0U>qR;G@^t;>gkF@RFVECp zPU=ND`tof3<$1j*M_*pl%X8sHY4zo0y}S^bW_42jwMQK&+gkGKwUzAqGPU_{E@I`4=?AiL4H=gFb`U+;m zbX8}zg4cEmz4VplFZ^i5h1uiD>vW%Tr}Rsd zfeX-{z;2NRe()Eu4qUj~GvQENGU48e2Vzn8*Aw}UhNy%1Rzf zw6N%Ox?v@URZ_)XO*LwWrA<2=D=|9e1KmR<*Cj&)nOBq)JsJEdKes~qV(N$~?eY2v_D=7@t=TlE5cD)Ab0`pY=>XVN55FTvHS$jOhj!-Bc=vk)Rw# zO1XSmqa-K?>Pb0ZnWBM4qyj|OWyn?DV(>My0WSk5jEFTcEsk3bx}h$(&!aHkaA-|a zaAy%*8(Jo~rXFfT3*}%~p&WvOvymS9K)tFD5Bolt5`2A_ehw*S3swy)#MPLc4|V?* zOGfHQ5XDK3H+BD%ndr~MGSiu-v+eL<8>?@VZ8mm}S6w!?dF3W{tII4)eGjaIEC&X< z|J_C&f;aE&2;NzH@myc{=Du~|`yRbG7J7jo(U(KUzAy_hc?=VrAH-YCV+;>;|Dh>m z%^2brBJm{_iIf`X{x$i<$z$qh^Yb5CfVI1*FinOQrEUE0emU{1J~5bcaz<0&vo^!& zxh7Iis2FFNDZn`mJFubXYcfYd<_nf-mvosD>mD}MMx^gI^uT$ve~CWDKI#5}QZeoK zf`SDjpdR&gQK)#dJi<*O%qQ+NJ1vLn6>B*dcSc#l3(4Iw($;Zv6NAu(Nk4#24QmA0 z5g}+`BC{-co$FU{82Ro{=!Isk2un|wmzufV%S8V3&CG5fvPV3Y7C1Y^h(9d=79Z76 z*22-$)!Bh&*5EsMfy*q|4Dx_r2jOe zHZPF>OX2;OL;CfQ9uMg^Li#Hq{bop?3F)tf^q+0@t z4(V@&^khhXJEXr8(%%i~b0PgsNdI|A|3y>cJ6)z>?aMlUbcS4u=XNlOhkJ8X^5XG8 zT#3ism2}+wmWAWccQ_63{fURz&iOAdCFz0U$vfFPK1twVkQ9w`WJPjblNH-8(}IO~ z>XSpeB`OwHEm2WXl!1*@Jxv>`HvZnmh>ZIq@_sI8LpirJm>ZyHbWC{Q8X{bYS}4hh zgO{DFYP3w^*)Nk$j`RpF{`LjQJioX)M5x}prH~%t$HhFHwuP=2;F=s|G0b94;OmyI zmYcaJTM#lEY#ot{S29nF_<+BgD-{e591y5yCvowqu`IOhTds=()POe1*-z0GWZHL$ z*toQjC{MM2+|rX5o}HWPxQ@gs%O6M#b9oc2HkYhk?oVi6hZTVxq0TWqDZz1CZ(eR_ zh{Rtx&xxc{7eF+%jZvNR$b?JT2odMDN}+WDqvb8y2FJY{^?u1_EYC>C=)A}J;IFhIJ1Fz(M(NbhY1;_M*uHi|Agw`t_if6xh+=maa zQxz94RByulmGaHp>lCgsMB-ZEnefx70{jCEwLjDT{vK36tpS!DcqkSZBl}&vk7;7o z0oPPIuwQArIB0m?bRZwxgCP|cwC$SLj&aP@>OuhHZ_cfj5tcd*agGLwrOHs32XvN2 zwOZQoYk8}%t@hgc@RZZufKu8cWnS7NtgM-VY0b1Ms0{tHHN*N4WiFChw_;`v-$+Z1 zwD!?u8fooQ6T}Nx6Rl}Y)Ozy9O~|MfA)ft}I&=DO8YNucNQvYCO{TlCiY-QA4kD)0 z>2a}Il$hfcAfI}f{4FDVLePVdK?%LUqoFcqKt{;`cN(<(l<7D@t3B;F8{v__@~q2! zxK!(uH3;C}lC$_wAph`~8{ERr6;XH&G|FaMb92g~L)0T5Z%mmJnww!K#D}aY9laHR zA-2Qh)tIC6T_{d~XQRX>3+LHo{UJ5ZWm>bDV7aSe%+1)6b9=cP>2XUUG6JNo;b7vT zaU&db(O^EKgb{GSKaFV3fRF(Xe;p)mZE_hp{Lr_XKZaZkg2loy4kMBqs6kV?0;giWe0cLq`1}*YV^CXmmiMB~lDisp<_k z^=`?zFuKLM7c^EN88nic(ILaA_wa?nc8N<2YOe4hff0WJ^i zi3+s=EY&5=t&2rD0a}3e0)@>;H>@#DsZD8uCIELGd%@b}A})hlX_HN$OKg(55RMGd zoS5CbhF){UE$2>cr?;?`BxR=fkH)U@qRl}>c6wt$G9{)BqN*i2QnlpU(T?_M?OYq$ z(JUeG(hgh1Eum#?(=^@*Ly*|^QYCUAID$}K?Z`%e_kQ9PahhaE-@r{J09JSa4@}%Y zjrwOv@$+(dn3iFtAhrsr*)-IGGoWUH5&X} zapwj?zXSSqFuX(^6HJPk%~ETqj=CvkTDN`k?+bMSdn441*C76V@fvp)XkTN0|9|Aa z525*AO?k;Gvc;f2Lu@QWKpznu{U|6U>K(wNhfhfA>xF8H)O_22Yj;N447kKBHRNCj zix()Sd`;~z3U%W9T7U-|Ro>6J*I{t!rjCr8Ao%CY>s+LUAP|(y)tKVDip@lg&ag`( z@&T_n$#pZY!v(ENUC?|)IWQ6B{>UPQwF}J&_u`4tx-y++1ciAL-(@NSNtY^H6ZO*N&Nva%N8k7lF5T`0zI#QZGg z(Gvau&%mce2K_jzs9(HZ5oHGTAl)?zFr38~@D)-`Zj|X*|G9Bps*Pfj$`0}02>&Uf)Q)3t5GsqTsbSmoFCJh< zUm%qY^$sWkBc75By4Dt^3oh5WX0MD93=uGz&6lPulL4#*9_&gWt}oYoJ9`QCrw#Ct@15)L~v-2AYdK4W%mLwUTW|d)9rK<4O+XN-?iqg8iGpS#S^#N56;HDq5$zi0094?DOl*8zgU8xo!u-F7$C8;fwMX57t z`}I-DscOa=Miy!Yn)D$HEDk&CK#qP414YH$;pIiN?DL>hu@qx`=}jC#*(#xE*;cyB&?@jAw)`Jms@1Qcv?hQ$&Sm%I?tVR$OdmFn>EeAnR zN3F5o6am$ae!GC9#gaoTR^K%v2soMSO%tWl=1l9X&0?{&Xx$8rDcg76;tRv7VgQBO z?;uwSx|trMIVkP}ZiX&xo+}P&o<3cetSH|#_+Tw6nxAkZf(d}AsVLdx8OtX>LlLUP z*lcuHxmlSJ2asfG|9q7jAnp(C+_^5(kATd$76OJzticRJE5%oyDHrORu^-ag?`lfZ z9A$6M+3Kdy4qs67~N#)bXUiy z?egiT7IeXZW3fT9toz#_s~Zg3x>1u0I8v3xx&K#V7unsCcDp1!r!-;JF_h!!=@d7d zuGZuahurYWobr2&*7W7R=?#L%h8pDo%_SDyKUAg1g+VblpkocPRYUa|czwW)2(XSn``r{lV}3JuD?i!DDx`so$~HUFvA)BYER9=DjDf#>lz!t*KN`C6-v=PSy3 z;34hPSueoz1&`JUz+naI)W1 zhqH#_V$WH4*>G zg*A$2E$0w7yOlZ5StKS!eTI3vlJe-@TJF^wf(@ho|y#u5{wN5m2s#os>=ri)@R5oJh{i-d$RNUemvayn7}P*O>jS094@6du`tWLNf_{+y zY`ZR2lJ(-q7bI5JL&U1yhZB6J05s*gcNO)05N=+q-n;4_?wcMRRITm_|*ZLy*mw_il z*HXw+o$Cg7eVVG-P}pdKk%;HeXku7{7wIDwQy~ozF3qKiX*|+@B4teaiy{4|A(eJi{x5~} zmqYsXkRA`|H$wU=A^m1Zp9$%&hV-9>^w&aqBBZ|_(r<2o3dPDuZGNdHC4&;5R;KWeH)HleAyM^M)J=|z3_Ky7a@dOTz!ccM z-xQ7oI9hCvW=9{=LH)Dk{it!R_Ap@2SX@jv`k&_tQpA_2{}wB3Fn?u*enW>JYgi zRKJ%1Q^dVRNxk28HEif{b6pX$VW2G#hG~PuT%nkKZ7q|YdoWIx9URb+_9NT|)nc90 z(yyanK_uNzVHD^Feg4Udc{0uw+0fFjMYW0-aXl@U;RwlET1B<&Lj4P?tYyl2)qa!3 zmmzAq#bs7zZCWLa+?JMWRTY*@t>SPkLs8o;U8r0ZQKS3yxDEI7u9dW?P#@m=I=jr zmZvViNR;Afw3A;PF2wB=%kcWpoMVTTu#kgzTR`*4zkb}j*LWS^&H_K@F3^F(LkTPR zLcgxGKvI_$^41a%z!ZHO)8S3r3BaK=Ov&yab0Hb4K>{a8Mp>tRmfCj{K)nd4T%z0t zLSxGq+u}x^#<9(#_vI_X)uJmN!}q2YGq>O8xV~g?4Ex(e6&MkKV_XaPumHBRC7`M} zwCX-NtptUF$BMNH@?Q=!h`GyC}~jA%iYM$WGT47g6OR z=?QtgpG}#{=dj3E+aqEo^QL+`VnP>P zgOKrSsr&O`GqHFUSN%QtsT*z_tdS48{6>n|)=^+1Q!O4dyFL_PcFQOv^!J$S#tKvk zcAI`yh^HvO0Fls7d}!NxiAYnNU`(fO4j=WW?Jm$0f7<%>C{Fz`8o8LY`*R$OUK!n+ zov&lfcOzlh)ok(D_v~B`CR+;7MPbm5BDR4RZmhVdoD{}%j$>)}=i_Vz+0Mw(EtXBO z`Lp6Izp-(#Tk1X3_&}F>>JbRF6yAX);ZQ3cL*&PbrS>}0Emf}loGrTr4ML^3O>H@z z;7i=a4|Ui-ab)k7B|uJ zHW%NYF;|}myFmQi-0~+mR%(J+d4ImL{7DX@%zfZ!Q0YG4JuPN=(U`f}d(XTuu)#J8 zX&ZeRn1x%G0Qy<-Gmh!Dja)L3&y@E8hw(zbFyBa>rF#%5u~=ILGZ=f}2V-A1RhOk= zS#d{p4ze)QE$RVup*x4c?a3~ykYC{KY0RqQ{vE>*$8G;o&vA?7@Lwdq zALaayk^*qqD5+D3u&Ft0mdT#kuvHD!(ZoV+5AHndaM4}X7{-c z0(7oinGJVtkqNJJLDBIelgA#wH-e!SewU7)*L|Q7b=)QHk~4nI#QbR>i$Yr@{TS(& z0U)&$$|!4V6!R!OVSJ1hFaBNZy(4;hCJI0PHd?$uEP$PcBO4dv%Ny`dfnhOWAd4se9?uVP*>LxSN-<_1AfQkw+jO{73HF4j5<%p0G8_1z?k1p!erP{&SX(=2eV~?v!6F zYYU6uuu0%zA!v^H#WZDS{V740uz}>nE#-XJ%lTqzMxU98MkoaCIL^5rI*P_2_2Ocl zG9JVni=qk32$Z2sKaDPy@H26qj`bPnlJPVqKf#hXJMqvifK}N7cahn`<)oq?NZ>*x zq^MIIudbap^#`M3_0|BrxQ*6ve-Nw|IuWU>+?MCwjrHwhTNZiq^guSC5(Jo|f65fry$z}v2 zmQa7=pKd{A2U%l&@GSNvSYo^NZOldBs35TZ1j$J@O^E0Y{5_?OSyc;mCYr+q z@b}`X2Cm@n_i_8F3mbmW_WXL;^R4Vtl$CD6LI@JgVk=wWMb-~g6JS&los$5Yy&V*V zDW_?JTO%6b@YiU_05I%wi#6j+PxZ?egQ!o?Mm1_TU8+*OgssL0|H~JctXh4_a`kQi zlVPA+)$%Y4pNBDVL&0oNqe@jE8*>U_e`gMRl*ph_S9U%`<|YT!7s`yHVGsDURYC48 ze8Y}`-Z0}n-p_)N<1EmxREs za=Vy!uOVNIk@WNU?;M6Kt<2G)M*4}sTbp(|wkBWD{kw6tQUgMx*^h2Bz-iJmLi1|g zc1u_$YIu%R4TgM-s2kS?gyR=kRDj<`I zKxdNx>#u(| zdf;9OwD!r>lkdAiTXJe4b)}yfJoX5mx7s#Q27VDg1k%p=Sy|%Xz{xp|ZhfKgf3f%O zQGQ)lo#(yx_kLCV>Lry_dfeYtNiNxvEkYs*#U#4bjw81Nq*>`%S+kfm`GZ-LRpm7+ zdW@aLIB_L%1t~E^fJ2nTfeLZ300%VPrbn}ud!YsoEgDa^00W{Edc=^KQ7=NbdPqP4 zlg#J4&$;(^e?OI;PJm3LvVZ5?bI(1GefHUBpMCb(8`wVqV*ns#cw-b3B>*U9-DQN| zZVF1;yYLA&$`+E%NISr2?L|RasEJx_s(6k9x7@W5MB} zW$WQJ8_%_ijPcmwVZLyHF^G=R9cr7DkG)axj8d^C3(XarEQy|Hy{jNQ5P4j~XY3Z& zm@bGuBOzqdXbH%HLM24>$Pyx*kC0HJZO3GZ$GM9Cp zV(De2SF-eq4p=O`qI53Dxx&%Ek`@!?RFz)K(rY?`vGkhK0ldpkMrk%#K)O`=t&xp= z0b0pQZzz8=OK(iu$hHe(;$&OzI zhAzgw0{TOx)p*=7-XlmUHZHPp)6s@4ybe<}9Z-1@Cowk2NkDDt>oujgoDuDh#|HQZ z{LYDgsOU5C4`l8tGkqIfkZh_7&(Py?f|!QQ1deH75BiYW(VL`1O(7Q6V1%wLvSX&H%|^r))m3IyJ`bU}TGsqL)IA9-KCbqK&BK{&9->%4zQR15 zx%NDqVOD9jnVO)@w#^6Q8JlgEq>ejU0=Z_4x-{QEi=6u5VtBIQLih4PiN_auI=Yia z4~MC`YhhOAwC=<*WE79H1p><1>pb0-08FG=ejIf`INe&xWxr5@6fLCMyG!oZihHaP zOnn1=PoN)-cOqU&?i+UEdT+Mop{%y^ITMSOL>xT_+=C`H58}9hek40@LW;D*oEpMA zY8~y3K{ZFc7?3enQ9@0`nJz;-repWDWOX{X5+-5vG3Om%Is~m2jW5v4-aSZq#V14H z4O;XzuESWFYHw14>`C-ugbQJ=S|Ur5s)oH9rQb6j{2&E*`fTm$Z6TRz@b@aoXE)wN z3lp4AFow2~2d42B^NWh;P<~N+vB^#g?J_!^Y>~F3sCfp2YP=Rkvv-db5a0J)`i%f_ zm8Sd_k@4oixMzrENiazgLNcwKt5kcI0864?S|I3&5h_U#;?8Z{;fD3M-Qs4HS*}3< z!n-;!0c8H>F_Zt6fTg3E4ekNkO`c`_Zkid+xZ8H;8pWJ%;)nS_u zwr%~Zkm5L%aU$7xYA)Jur#e$oIhv9X3)FBjrzy#2r{sl-F-s7e2RzLw>1CH>dw?m4 zA8Y`oB%HWcLop?3gKc)F;;HS?1Cm?C@szTa2_&q5F+H&do(U!vt?!*Mar4$c+@0)z zJIx+0^DvSt+p-HhB! z^aJ-uoK{JHi&q;3mLP$yNS3%o>)Vhg-5ulv^Ljl(kd9jz_!=RU-a4oTn@raUCka6? zqu_pzxW)E}TjF&T3%yVkL#1bX#4W>{!x`oaR59*3l$&rt(*<1@OuAsq1(g(x_E81k zbB4+&HaJvXkrxvX1MI7$X91u?no{>`r4;#yHpHZ?L;jGm8)%r2!_5W`nbMUk0fFCA z!qhzb<-jY=rb`IKI8pe5_PM2Wsf~tdGEN95@7}S`QzFYM2}lOAXI2Y+MIsa=Df_tL zwU5u{nb#{D)P}vc%Cg7%!S4R!nJ*)0HwrPHo-V{s72+#}_{l>2L?M2xA6Icp+RvV$ zi+S0F_^CpCr4T<^h@U9LkM-kL_5qKtKt6$tC0ZMd*b>3+a~jK5)p)An==rpzoSH zkb*dAoL0NPqNCOOl?Y&xs*nhM=j5LIK~Wag`TDW@+3YCRB_{Rld*-K!$>R4t$gb{Z zucO!;F&SpQXMPtkI1*xeiE%Ek61yr9f2pLZLv6xDPpYSDawb(Aw zIHDy@CEi7h5_hRY94C{i61Q7SCEjf@m3WWERN@Yc36480rV{V9m`c2l7$xpiiFkkZ zC4QI1RO0I_rV_u~Vk+_V7E_6Du$W5RZ84R&hZrU9SBZNqRc-tpi>btY7E_6Dw3te~ z-(o89do89C-()eB_-0V}yqFabzM2Nzw+K=1UqCcFo@%xWxx4>DlW1xGBIF|U4;;(! z6#1uF$PbSt{|E~Mzvdry=%J#AwcXti(A_F)mx$>&DgT7Y@kdtt>m`I9wWNkm+N&gV zB*>*C=&VjoOFA+gjYsi61;r#T4{PR1it{Rc(a@VZ@qW5VxP5xLkj{QJ&tJ{c9Xp;n zrxgRWl9qqr>Q+j>o)7k4*Ha$)Z=Ni^;i3QLL&Y~dWN)t53aE~6ch-t}{@rN$!TxJn zQGD}c@eL1IU8CuTif?$x-VC=wvMCNFtbTd_D6is$v23HEJ6E7Z`TDuoqA`MfSog~} zSl{sbhQR#Vs-ZJCQ_am}8|V#(&`S-l_k$rP_$yFki}`IjZ`$ceEOb@Zya7^nENe90QcZV%@mG3j%bP$nVf1@_U;|0dkeM@p<5tgvid)gj{^q}u>b10%ui z7@Gm&4awkM6TgW3!xm+q%hZ5ys$%*;bu)IPZMBwG)4?hA50lt`N*IK;4F{cC=8X3# zaWoFsyi(Cg>PFf|@uv`nvS+gd8ds5KTAl!(R7ua|2^jjog5x?kUBV|70+A(!2=(Ci ztg-xx6DPh-zief?&x9F^u`^goMoMA82|pyE$~17_Ktdpk3sOsEAi()7R?1`LJa)Cx zbyZGE;piGpvbGKNT-RJ36zLgmxa zpMnMI*uEP$CwiZImSrR?VOOSA$XHpzTtDHQCBP?X#NfB!!7T-4jXdRorC?GjPq}0% zmkKGDEd{%&d7dkl!m&-3BE*R?0+}${ME7$;#z)_^r*x5MdeVJ@{!-SM6Ry}o$}vm1 z)K5`a7t3&nDuL|`zw90RpgVT2lGsD`li2L2HiwngX|_G2oG7HQ6(QwVKSlK{Rcu!> z$D5^uX{O<^O{-yPdeL2fqo6$^4qiCmME`Taf(%nfyKv_n>KLZ4k@pT;DS%hl@ecFij{v44_U(`sjVvQ}6) z%Y)PKXL)gg-sPY=DY7K=NuBK!q$IDGFvTHIa-S2N0NyF71kqqbE|R4nK`9+Tf&xLD zlf1|>&apXgvX(hXRqDKgLIzYBUR5O*Bg@jxF@;wPjTlU!5Ub%}LQk<>iQY!VuYOJn zO9zN?JMsa7uUG=(LVW*X_fMrjG!-ZN0$#>DodyoOYB^WW#9@i z;-)}#j`Z|m%XE(2RXu9IC}ADpr50E9FtR!qeW}Grn)Zl&*IiWiYqn#q>DV=IA+%Wq z_EWM}p2lj%YRx<|(9AEnX40U%nUH^M3ad66%r7@CboGlyz1_9)omnH_(QhLk`8Jxm zGrphoo${v_pz4_G({9;xpx;4&vZtUZ@Rm3lb}vnzo8GZv`k83(>y5fKdXhC7-zqv9 zv8E-B?$1Xul{yKw^}1x*&+#vrnk>fD+z=vs97i2m=GbHKQMbZsK6Wv#K>W5nBN zOyyrN`d58&^#?lA^;N_-lV5F!)dsW%+DZNM-IpR28W&nI%ZzTbbH;krTH0tgQJBZ@ zh0ubL)k#R7d_cs08=Hk_9EyI(CrfYS8uY`r#OVTX0CXOYswe`S#>a}b{gMmUb>oiq z&C2DKU$=|RMK~^MI`7G&@vk*{_CL&&s@|e^Ro5qeBI?_g7eZ8!3DS1}>#9S|Hu~b+w-=84w z4}+fd2eiM1l2GPYaOHuNopj69NU4$y4LxQ`+|p-4+Mt9E7rbo^0Ai}6-B?OJGTd!# z=@wvxgvKqvm`*DI;09pTfE03b=5oD))#O5MsM9UvhPdB+ZozK4I@j*xt7!1VwteD z@Iosa6BYnVIp0swl6I~Ilc`1N#frbpY%A{zTIEiBOe?P~c&xln$sQ}$bELU^hS$Vx zc{`?CH&?7|tyXSHyW&?~#JPUueYLRi@*S%hD8z!(5~6XmNaJ5_IXkm;XVIpXzT#eT z*+&ch>I)XCM~&|1`U_UmEm+cynkcL$pW|M`(1N8a4%t#cybYh2e}RT-clZ;#6EW~X z**?e?pe?olQBuAD5uY^#Mn@Pl+rspcf}2}?P-kbl3@seGxT{OZ#b#hB=?K25j!G~MdMl5)MQTN>NDI_ z2Im$^k})1v9;?p?d#J@#@ukgzPDO@igUe4tdgEI(xwqKlZo1{C8Ly{zTB@xvw)}Wt z<;xFV2MQ2iLAhSL)y+a~7L@B1Om16#Jan0&H=kSJC@v_C@5}{73Pk+{g;nEP3knyD zB$SaUyDXM1C|Ekr)3OC+B+V9-k$gcJNmpM`%*wr1tyLBjW-Al?8VicunERG3C};of z7L*acpxDvp$k2i^=D2VD!uDa(*-RT%r5HCJrORNUtFOhp!qHSEwvFpF)W#MdzNbjWVZzED9Gy<|6ftPtdvU0=ux{X(E9 zR%(JQgL^JyahpssXQhpyq&`>@uol;r7{K7K)qMOOd!d_7sDhmGNJ46 zJzZ;77H-DtQX~vydo`90unYC<9x)npM03`zZ*hPZL%d+7LZTf&FBxR+9BW7aVJ88e zm^|$W`ny}VV~}i;)kV$_0Gc^N;BeiXA+SS0D1)^P_0GI8Cj6er{q6a-B2$0C&tkExDKfK0 zN>NxvSRFE%*c$DRaX?|a>_}UbYWJV%t}JN*$G{u7UxBXRx?{tt!(*ni3$Gud-9=t5 zP>ep;tHqI8MXb^Yfv1ODVxraX5zmxL5qebQ3WYph7kDDo%9^4fQ zEVxD7L2soS*y8!C*jN$=V2Jss8jCkl9ELEB>i*^EQA%+K4z2tY)4?F+Y(s2G4Q=wT z{n>8>NF3Lv(=IL2JTfzMC~?Umk2EUqy}O_%gABHL+!+>CM%r1+;-Ta}de+ur)vyP#1aC@0u)4 z6}tvheAl>E7IRmKV1p`^0+*CD%~(;~s|vMQWMFd;uEDxtX(6d*eMhJj!&d?gy^f*L zI@G3v?APJUIU?h7k3SuwV0TQGMPfcf|4A^lgYtktGHzr5^nz05Te~aAI3F57C!qnO z-~>;!%w2IW3^I0edZCpb-7m3cpf;)!M0o+Xk*NZh0d)*a!n=L9+P)Xw+3pI`qyx;9 z^7iO{G$(1|T=amQ>dSLEg~X$>+JbU>UKS{2Lx%82xI^2SU3_*w^C+uHQzow|%xWSF zHBkXbV8A%w$~MQ`s>v!e0K;s+n^i#)Ss~USVBMvjh`^ZXR9zGEmW)Y~>0GU&QjsO9 z6gQz=BIh9$ke&TgWcw!xK3MeO#C>iRsjS?{a0lkiw{(zGqdhL@2{fa&=@7bsJK$^u zZUXxsx&cdFzxeyV`1{<4l@e#0C0qQG;=iQihq&&}@RW-7KbQ^7;7S~}63tkR5C{;1 zR^G@d{&zIb*w*bQXv!>sJ?#bY?e?C~Hf6SSKW2!#fer%L*yC*v?pu=!xBLsiCygNT8*Ga_XK4?_~fTt)s3Pl_a>{6guMoSu%-P!ATeRu*)GIp4O81!zgoSz zU!&cF@Ec2p?4Xz|jJlAMHu!pN3W!YW9d8FFh@cPT+@<&owO%t4b3|Zt(F`toBsSy2 z!e61W4Ar;^vpO2z+=MBhu~04B{Cs%XSNU#5Msa4W-cBG5~;f zCR}y+4u%WSp)M>ay0Xz^RgrZY4*9fr$rOy(=-`C zq}9=Wt=jYunJw2)^0{g@o)Tm{q zdwuUP{VOz{BVeZPu-fv8Ip-$k(>5{ZnEHTxmr)8R8rvwF@FDbQnr@;o#GJ+4lDa9Z zt7)Z{XddUR#6;0}(O=l?K3!qWX5RaSjShJ_w?H*A_eIJ1)<~_`Ap`C4 zs4(av$jphG@yx(3zs^z^z(9ZmL6Vnf{88u*mPlsR(;CU!jRi1{Ks(=(yY`na88@@! z6iz8epHmrbjghMZ-57UUGVV)c1dby*NU>4D`qgYgezXUU`?V4AyLI*NW^HUaqJlV# z18j&&SYXjSPYR0`0&b`|Q*yp6;OE>(&qzFcS;kGly`v^9Wfryq8Q=7ulc?z&>YXkc z0LSFFFhFF5i3eFpPZ)#eTo_|{5_uJadZMmjH&daQ+{WsfrY59-B&@ipb4xLxn_)+!{O=JzdAU65APlGs#44Is4mGpboxQDk#iMGtIn`D{yhO!%|N6 zQ-p^nQ0X#TrB8=N>%-V8DW@-*@$F-Za$YAp*TgW|xjVuhh2mJ>^hU2Su*oy`%)IsC zV>KBGrr$Nr>x>0>ifsWj3ueZ?^G2qTtJPFL;b7x0WEOsS**?4&q*&BF9#3FQwxX)Skr5$S9LWRKl+wyeFTUONxSNIUyF?bkMcvAC6+!9kp?9Y;E(YTuUTI@+bnHo#D z560kzQ8o;9h|IJ2oP>q<4aP`m-eA|1XG#f>3f#l9(ihFD?z!bdt-z=#LL+**iqL3; zl_-KLjyR(fkzA|7{E(A1R9_7Xi$*f@lq2jDGsmiukg+@)k(PPN5p4-ajn3g!$qaul8O4BZ z_{p>6iN!IQAGgW#q$s_C$-eWG=c!O;OKs738lfUg3SBrRMPnr881uf00-U%O1vsWo zU;@6-2{Taa%Bu2{+FE)J)ihaL6}bk;mUi9^fu%faDHjSU&s)mHehS|~_Y&D@*%LiwjmEkZ z)6KdJ%zHHm2&(0!SvM1s3bsbfVz4%ou~^Wcd%Ofy)`YI6bHdsrB#G%7FD$gA+ExOe zj1t9|%%&hWk;(0J*^Jb)&#fm-r_V;b&E`}UI28py^QA9Ib?9|j?kYaGF=oVQ`U0_w z=^9YXB6}2kz@;c{vLi8Ol4+>Npsp2VXRvS)B7l^3bGe(!&02DExvgx`K&SZ-rM9e6 zXWRru7*s(^Y9$5?1kBR_!!(2hTOgRT5nKiH8bb1pWw7-cLTv23hEPqtECCDOOWt@5 zAwp;8oCqwL=u5=1VP?*&<^7OA76P5^Abyrb-vZ%+h1Dqq6rNppF{7RB*k`~(U)yRT zvmExsPD6>J-vl)Rn0rcgY)MJ$4r*|~1p=*I3sl^!j)jsd%gDJ=ejQqbI<(Nv0=Q8` zzoA(yJG2P%16|1(v$xryMVKF2P=$Xh)S+3vQ4TIrg$j!uHHZ`}4Xe?Dpnxg@UelIe z^F$g#;HE8OL9cqkbRCjb2tL<`=7b=UD89{Ma}8>!kyFCsT1f~$?8A@vP^4GsKjy<9_u)r%-6a z@aKK_Tn!il-cul*AdKDkVJqdlWu?|Ua#^)ji+v;A7Hf&w{=uPJo103jqMPf(%_1Bf zd++sdj?xfmA}@q(mHjPkg_ueuN71|>De6l|Q4$x4#&U|ITzN)NOVS_$t;Phm;)wzs z3LW+t&nTJ<;WbHx9VFL8ldC1sWawvJArp~WL<=*T%#F}IEu+b$T*;=C(_{>1`+Nv- zM3W=8P>9P_9Y#zF_1GB&bRaZ3V00L;4!RH!26cy~rCV_NeiP^vrRpr;YO1Zi+?m2R zn8I>5;L!iuVhUe##c+N2W=&zEUN?)4N5hA~a&sksKF_c#0c4hQ3Nt z5xQG5lFPMi%G6a!dbVS0y@k-Y5yWgY(eq_gq@`L4TycEn>Y2;Z$Kvr1YEZQ(30e-9T5gx_qv=r}Q4mge8510Hk=gibPwj?nFq0 zf+UST-ANE;v%l|jf7SXWRM1wRG)6#20D`DBD81mW7g~u(6>M+>TC~PwDaNDhD`GMv*D?e##8&)Q7}^Rc26x397JwElAHHqCu9+kn>uB<-mE zTw~$z8*nV)=?x>}uIM!NCYG4NbjWM{4LEQ72Aq&%Bi0xq-Nd#ZRW=SSad!>l?%48* zb8;s8q*0dbaaxYM!xB74D90_!u zmN9#y^ps}#Mme}h+0tnYj`uql5KouX2lUPy1+O;>}pzle>^{qB{&Kfa1 z)yZ)tJ!2^={S;Aylbt;!Bmb{7{YKmt50R(znDfA?D2vAz9W}ThYH*%3Qf(o*AZl>V z%GNA*i^sW+qgdxV8O3_pOl_$n_MH|FBLK7q+;i)|GacRQ65VA6TDmj>PN-ri{Zk5= zHpf&UymG_gv(ODJcIppdujz#EC{F|DFjv??_TG|)5?cF0k+jkNRrB@TtkOT;PAUEhJ8q})| zeU^0Hxk@$e7S2^9=wuvC7eW#sbgkY8dQnG9)X~v`4ysmc$)PbO0Rnx!1n7oH0dX;K z6Jqok#6~{j!;kpTmMhYK%s>CQ4?pTdq;B@zPx$aBefU#8eABCR?@EIR|+J`^m!=LrxiVr{I!=LlvXMOmr4?pL_pZDQ&rW89k85r6tIiN6?jsS5Z)?&*bTg!!w`*pPpV%+6mEd)4j#-L>$^i1 zu#Q#1)WZtsVylLPH^?WXrVX~3nzpdTO?NlTHCqR!ISDs0&%+k8fsB*z>TWMr6(!T2 zzyPO{Y!kFXkW9-KMuDi;vW0$&XkF|eJ#Ia}CagbE+Ry46F?E6%^GTTd;1{BbIVKqP zl58oJF#CS$LhX^X`#+}N`0pM;-tyre0TA6slhWcFL&|2SR5J@q5t5iBq6jVfL&b8d z^Xg*1^m3_C>?huL{bJ2M=uol#a96D!Zu862g|dI@$Ss$R`Om9c{L0T4Tm1X2>y~;} zzNCf#!97$vj%I^(Rg2HO`gozqKYkm9yTP+T90td$m#c-se>S@HmS?ag94`FSU;a;p z!v9TpGlj4GvTAzvI4Jc3|tY3a$6Pvn&_xj?|s5RfAw zE+q*SqcpJsgokC7BD+L4E`U=c4q{vZv#tQy_`1CUwz&d0J-W>T=3D_RUbk7m-L3!_ zrQ0lEhbsWZy4x(^URS`#Z5M#OKJb7I(e1Y2b*_N%+b#g}fNH_yZ5OcH6|m;E3&0wo zS}=Xv1?+PL;G^a?hY`DsYQcuvF5peB0Bk1uIi1Z$ttrLnjNCq7Poxp-rgMdP%xYJI z4Q9>t<`GY?LN>q?8u}W@26&>L-agp?PgKC|lMV1h1>8Q_08doF?UN1gL;d;}^E_p~5$KyM2&Uk%J)w&Tp;TD~A>93d^#ttmj|OS!cI zN+JQUVYZjcNI+0vSUsDtidE2(t>~g5Y)XxpsH~E!;@5pT3g>F~aM7Dz;_8?fWtcQn z=}e0CrCv1tL|r$~E=OD!;WQ*lSA+qu+slka9BnV1x8HO2dp1fY=hq*5JelTt+2hF+ zt`WZRjm-xUq)1ta%%|=5l>M$m$vVrt)-tcjGb2g03>PA7x~Vi*&M4)egl(@-&0J%z z+*f*qhO520sILZV=QD6_C^`dh0p@kg@D{B>Sy{uO^g4gqd#hrp%LqLF~+@y7D_=Wi5rokrT z=74w=s6F7`tO7I{I$s^X4)Er>Ad^M&KEz}PeRceL8*gp|uN?zrVfS6v91_l*iE$bkIeK{@)sJnhR` z1^r&qs~dsy*}>vgcudbh`4Ev2TS2Zah+ZZ|M^lyV2bAF?t2Rd%fL1Th@}%SErh9qG z*aZ^o3-$?PVwX60tb-W?!D>NngIseR+Y$ex2AiwmQEQ=&ju@ zwZU$=?662yh28E_gPqY*M0dL0MFL0VlIB|idJ`obujUEpRO5S2&i2}?OsNI7OHrwb`dmU60}A}(en!hsC(7sQN_IuoU*fHp=&(Voyc zggOR`4b+_{`gLcOH@53$SNR5#sV0!aKv?%6qp$V6i;qkcCoQmHr2s9c8cE2UqdGz8d-pSR~Qy*%(-O23>vugVk1XDz&E zR@j%a%)YRT`Sba|Rb^_rRkkYAkf3-YR@i@hCCfa-LFgdz#eTL+dA31zB0fQB%dqYwpv$^hp3>Qy&^cQr3QJ=TO^~BWru!kL$I) zSO;Z`xJ+1G7m2ZTWx9+V0?BdWh)E5IJs8IhjceqmqQgv}!$MloJI-L_(L%4;o}!-= z9gf3;aqX}$Oc^edp(%T_0d$)TXIzH*VId6}l=j2WdxGcPtIA;^%n!R)Ka_B7V-6r$ zv8}^Gnjdnn-kG%ZYQ?>39~Pp#)4k%_v0lC4UR4h#!1odN>Ie%DuU>SoI)@X6;0Wy$ zw}5E~wR1!n&bkaEhm#T4PC$n4ISxz+UJ?*S4<}ecdtBcF{t1w)3*a!+aRpj&un#;( zB;t{bJj5LzgEh(1s(D&%@$-XZ!WjH@#>}tv7$1*N{|MG!0w`LxBaZ6^qq-$GvbpF8 z0cU28I3W_u>ueD-ni9A3I^D!}RA9Z;Ig`~{^CPQT@#~r;mo2$$wR*A>k1l?m$*66% zYw@U{CA=6V8xV`v+1Dg@EV)B6gTSJnF+DT-`Z;@9<)sF1efCYok}D(&Nwm|~e%bHA z*)L};Yg@iH`GgiS=AP}=^RipK{2^pCWAV7qT{<#BI*Y4L&jn!N16$Df18)4>{VQd| zvIrc3aSsgp_R>3bp%@56IurbbiD<;>d~%VhIU7X#?F%e%Di6S1RQ539MQ)O6$tzEqx$6G<2$*B0O^LBhkJxztUEBXm>_$s&3tUH@$di zNM%k~rNyJmGN58Zex>o?%H4Gs1zjiS3bn4j%dfPl`&84p#U5ttboB@Tag&8p>ZG$X zK=5ULrSbloz7rb+qr5ZUuX8+8&i?{7PFoETsHO`~2ot+R_1s{7Ur7a!jZ}Kbc)6K86rDIof zXVA^k0a(|yAL#B3#;~ zea_O6p6v|QW$Eko;fv1FaY?r`Sf8b@--l;9OUFUo&R`}>pV=48xbzvNZ^+U&?89rF zDbbm_RV+Zk-i(l_l3Ho0^h+wBZCXX%^w;or{6!Oh*yAkNa`eL?Kf zk-_Z@dRcmJU(j>uJ*6jEI$lH)m!2qnOP0Q6U$DicZ&CVemOi^Ln04v1O5d8LZ`~Jc zb?IA`zAa1NwlCP`(zhx7t}OkoeZgHW{Vuf2T3D5{Ss&7EU%VR_MhB+&dll#_x~`Hgj$X% z!A1My@bmL??}zGRss;_hvFBJ)?CvV75mR3mttx|l%~|m>zvi-YuLZ53TM}E}7Sm@^-NpS6He$aU# z1u|5SX)LVT=Vrq06A1QU)Ji7R*|0DdxZO_B#!7AY=;0KTM!#6WFS+e}Vkr|Si*_wR zo#TN*79>uG6J$7i^w0nAmp=i}Q7U7*#7C3;kIEb}6h7+cBP$J85GpiCqT+k_hr>y? zSm>C(;Fby1eDr5t#HvMtV1ggey!I8MZPNrCb^79VA5=UY- zPx4hkEILfhg~oFifvsGz9+34g=Ac>_U5lG4VN9_uJF{Xgtk4~1weP4kwZkCnxN=!* z+KO2{h1O$?>TnMelFHvY3_;@dy)1y2j~pg%FJkhHFnO3QZu=3&I^A}BGM`HQStnt3 z4VnstE_ybblYm18ZS-t618BD0V|PPBH4UCwxp+1Miga1mvh)lp@LpRDR)+2gHp1Ep zPvfUx&131Wef`z1F*C~PrpMB=A2|A<#}6KI7{aWS2I4g{F<}5)+J4NB9Yst&mR|mo z-}uod4jwve&D8-9U2yt|{kp2fy0F^^4nW!Z1tDSW7vy_EA(#&+G`LbMr0Gx(D@S>2 zs>MQb;808%jJrl#;F{GIGI9I7kf~m*iwivX#7r+g%A8D>er5?e zla4*YgUtsBC~um@H=0>0P!t337QWG(RQ(vywU74DC`?$K;h{EPpmtAf{!T3zlXua z;x+GWa>Gt@JAx;SZuE1rIplqjd^Ym$+xp^VzF=#?B+=73o|?t)VQTz)qkk{)p6&}> z$bFV47><5zaA&+P);4P2)A4*!04WadhPj2tiR#ikcAbjxsbH69R6}>eWd{hcjAZYI zr56DXj{rr!vekq+&c>Us{L<#ZgAl^j0$hJ67OJ6zT%6YkP=(qM6;fN(;x&}w8F?|6X$zfwlX-ZG|JVYr4WU)lK5;8?E~{H!d9UVSiQrqAMALYE(t=Y_1xOZoEK3k6mhHTa$ZQW9fPZKo~2%> z=hoKbyog4jh+AKg^I~d+V*Z}jvRn1c_O zR#=L^lBE?^Vh$c$zQRKMYL+&P)zgnTvPIpF!z2MyHX_SzF6iiF13NNaPr@bf+KmqM zn+#&yZT(@Jp?6KA%&ZOe4k4B(8hf_K*tD<|+2T`o3HTr3yu)hgh@X#A4xMPYzR_-l zZ#Y=dE=3JNtPejgTeG}wb3K>Wct+v0g~eQz={4*=3x=|f*)tb}*m&yMxFt3LFd-p^ zY9)+l{n=fZ=I<}v4tCO#s4bn#U0F@ZmLlIS(hBe#L(SH4z zd0X9(tD+x^Xc9Bh)wH7+nert5$Goehn-5BE;`6X`TrJONo`<2a;w5;m9y!#? ze|q@rsvu^?!obo?!GoPr^aR3v*&9IEu|9pjqFsx=FMZr{A+@H-952#&c2gm@{0F-D z)=o_=TcwL^MHhDj0j6bSpN($uu-*yEV*}R&fHU4Pspzn<`~&2xI$pLX3-4@v0V))Y zzb3+SkU;j)Cn>kL1|+DM6kP$nHXXam-cb(L`3_%{$gJzVb#DAh`{zSz0Kf8qM+CKailhhCj)}O5 z{B2P^;q5rLf@Q>^-NA~&m^Eb#uuIlEs*;*kQxuOq2z(GfJ&1wkFh(ndTAA7L6h@&5 zCM9U1LV?dJZ}+QPtGd>zE}09BwyQ6-!+#N;mhSo#>|!e|yd@kP7z#K@*xa7SjI0pHGI z%=FzFP@`l$L-e7`gX^Ivob{A6tJkED$?u%*+}Vu84-)T$=fC#E+dA6mmls=%D_{a< zjA?_9rpN*iFiwCN@L<|BuTv^h+8|u^=PaBXRXjpEjeb3b5Rh+6@%Z<-Iz>qURy(VR zd8{VjpDGO*YfhLR!hcd5QP}*-Z~n_a{exfr)c+FyASqEwGoanFK{~eBn}jluz)jSi z?j-^ftSpm~td-Wefx`8j>tJ$lgdjZbstI8{scv&VY~2py`aqv6i!C{hB3pf^qa1&! zffVy_N21~JhdXt8rmM#!c2qWjx`&fOGGv6ZVYgG=-OWB2-rBL7?Kv0#3C0rm3gb6l zMZgM>sRfs_4}pnD~IbAo}cNQa;4nXJ_GX=YHmD}6~5>4U096|bd_ zSF$XY!g!>Y22wb>NzY{|8an!^KR##OEGK~`L5p>Oxn=h0L#7&L_4KU%0*3Cdn>9YH zBj%1mCY=`)F6xId9}UBG9Y-p=JC16 z)-{jMWu>P3m*!b|`1m|>$LEn?jVv0l-^}s38Ovm2iERF+j<6ZxTRc9O2o$Ql%JI3? z&H8?`b>GzSdF>j<=Vqdj1>PN>M@F&{e6MnR{_f)Ox$OD7<8!S5qqrctnd5VcXN2we zJOW;HpG}^QO>XM=T&DbtxR_ja0EDL=|;IzEqvj?c+#$LE%r zZBBN4PP!eRTRIYz?D(8?J3hDc!tpujc6@H>h2wM5?fBf%Sw6DkbJFej+|moj=cL>5 zxuvsx*crIvbJFej+|r>~+3`8)c6@H>th(9pIq7zMZs~>NbJFej+|moj=cL>5xuqA5 z&q=rAb4!QdXUFHH+wr-j7mm+Kx8rk5FC3qfZpY`AUN}A{-Hy*Koo!)ud``L@pIdt2 z_?&b*KDYG3@j2;sd~WG$Z9VbFw;%^c7z0?RB+>bSw zD}e1FjSgM&cs8`-S;$aEZR~)$cyyY0H62H1ATZ+AjLtA`q<*v77jW$WE<2tTXb0%b z>c_K2XR_m2rWK>0am|lsEs5pKQxmqGj3LA>dqxP59lxrDuq^p$J1c57oY2Mx`38>V z`p2&|xFlM1qvKZu5OM@_t>f1}Zb$dNKYSt%utFcQ9V9#xvgso{9roZdwwF$Y&}_n$ z5NpMRC*^sL@I=Ulk?>du$O)I=%@n>D)|=ox?05*?4QovBE?9Jecd~CGcsslq!2vim zg8gh$3HJ8ZDcFT1fMBji-!Kx^Lwt_YBzCO?T{wG!Iy@Z#D|>qO{k{8GVBlVtP`MZuMc+A_vjBGB? zmyWa14&xrL`vXd7PptjPIA@SUJ`&GeH{5^XrbYbBSpA{P=P7 zU-3}2JYPSK?;pz@(>8tIJf1+gsDFO%@kE+B_2v1|<4N7+nx&`oc>bQ_I*X=X^CQO- zC=^YepE{m&U9PRm$u`x@;<$_~>%Mg5t7pw!UOWyIsAR|Sq+(f@6Dh&8m*?MfJZZCy zMs$8V z2^*H@XO1Vhsiz^W<@wp;N#tI(mid=#SWc$n&2dv{e4GGS+BFj=5}#S(CN*z;+_s0Q zWyEZZmpw2%chjCpdjJ>ip;a_M$>^$S5nWzR)(NMqadc*_#p=t+y>xq%Juvia62QtedK9GF=)dZNjmt?L(2dx` z=yEb;rLKuLSh)a-QJY)_=|jOAY=r=7z_u+TykqDYfe}j85H2$=TWx$CqA+_~8V8V; zVc)5NJXSJ-(Mwvazb)MP_;v1sXwybEbX9=Aq~#n4N+ zI%fnV;A>m{5{8If&pAs~^U|-%$dcv_1cm=mCr1o|oQ@);YOU|F+izLFY+1>aWeBZy zNxW6kmyt;#J&98E5Z*(;0VqKK+mI-SBDz0uKtFHmej`HsFp_nk&_+!|wCb*EUq5mAsW;m8?)!O~(8M zaG1>eBrN=&S){7-&Qa+V8#H?Vtz1~Vjn3`oj znP=~JMn^Mc@Xmod12eP|NUwXCLJ@TwNq=f-seG_QG+ie$B}6fVqm|%tr>&tH9ATld z8&j2BD0k#_K~O63-|)Xxl6;o(5X5cVw1H!9>EIO)!z&iNW*xjBahRBK8BvNI1T5NE z9Ob%_eFXWh%Q& zRZT?k*r#Li*s!*}?AJA8mq%>iEJ4j*ub5BSdH15%i8*2Qb{ z0><8nzTe>mik!k7UI4!2+nX2o*C)bgqq9MG7HeKD7z8#wI;C!<7ue$9AKg6lwo(k$ zAZu!&86F}EBD{#m8EL|4>2{ekp(|aohPXR~9-|VfH)Ll^Z$vsX=nP3dg7*s!N(aEns7 zXN3mBT!2(#rO9TVD^;yM!7o`9KM&h=bn{vNVq#D5&xxiNCKmWz!P&t_qJ9&Mp|0-? zE=;I{b!y}1PbRDgEZx*m)8gkp77`#6_4L2=6Lg^PM+kJ#0P`Ku<@CR!j>Oh9q`TWF`B8lXiB7S5v9bU|_(+ z0nB>Zjva8*iBpf3Q=PY{0+_U6KYU@&NDC zrHWBc=kcWqb;x4nJjSI@Q$DEDQ5Ta#R&IAJne!JDQm8dW!o;Hibv<@70%%MS&yXd* z28!>KIgzLH+W-wYAWvVgXhxoXPfzQ}0G`NA+RF+jaU~_ZS=uOEryuDD8a6P7U?iR2 zCi113b7~v2ew;2Mk%z2pTi}%2YEQN}2WclQ$qqsj#zwU4geBQoXabUJ^g7VWWE+US z4c!ek?OW6nw38PYPm4j(w^}UTrods192n8Ye(NBsBxxGqRff4(>ptUWj@r7?94UnX zf+B{fX+xy^s6t9{$pIXpY97mm2$5}`mJLxYAEKs)NZ5{`gl+mXUQ~2U!PL?1HFJ1SKSqhXTPg$}Qs861>ww3muDrP+{MD^70%L4uEReLhDDyT@)hLSaNc zn;GAwjc@5R^XVt#{iaSoB&OC3pmT|Z7BL4W8k#$bfvIMKDTJBP{2@&QC2O9vG#z#2 zrm)CnZ_8DMQH0GID*_H@s0foD6|X@8r}~LD)TZUAPtxsBbRxNhsF9esjF+P7un&=$!N2DcKQhZ=|rue za@!DFG7?x;n+6EBr_ckt2FY#z6H0xUKI5QfE_x%?5Qt%m{X^vt0}(^735_-=1Mt13((uBDu&F7YVz6W0hdz zk~Vv1rP?f=L4BCE5ql9C3)?Ez(N=nvW$a2|t2c)lI;a4GQWqxQ7nOfZ!)<#njv_1F zAIXYh_s~jZPP3JsXD{PcFODKC>zh=5&pdsWA-JF@ z!u4mRcixgo&)v~Q(umV90HX%eRs8~qe@S852BJwpcrnB=m!(*XtFFa@$D$D8o6^k7 zAG_&hvKkIF^Mr3EDB+v=v;bRdrh~SeR|0O=<`pXiK<3_LTV^}az@4y27`xC)PrKUs z02gXd|HVSeSxdQ8NI7RImkTLaG~_EBVP+*~1IJF<;Y`D!25JQCp|R9Xs4Y1{t5WwK zW(T>>l!Rf17X20qB}AjNCNdh=M~7#Ax(Mf|9XgyCMhC3)(pGfuis*2q;?QBKn!)+i z$`G7IIsqd@Mg_b~XPr-3z*tpbuatDjNo%X}z2x5;@-b0FeLXOex_ru#O=fuc<@4;r z^b#op{ar!#;i8}>oL9(U{{;`dWS#tqS~s{0#GPYyVS0pPRujRcULB#t#b7ZRM>4Vw zVoMv=Y14w9My$Yu19p+@%$I*dhitOR|Bc!~EZTh%#lge9HRu7Mr_78UxBWK&`>RC2Jhljb@J}Dv$EPdE`Dc= zi(#mb&Z>pu+oK2caZH?-Wdi9s(5Dj|jZV;~2^spGH}sf*PUcbg^eh$rIE%sK{Mj*$L>7c*>` zy8j~NkwQ^k+Tb3fJA%xi(S0eTEOKsU`|z)ojV8~kKbWl9WRVpLTuXs#ffiNHNN}J+ z)|y>Qma6n=Y`1nFCIM!#o@Q#Y+s8?6h}t462PoQT&D4q4r( zxdCZXN3*h3KPqp0P1wm(X#>(gMK^Bb>v~+R_*=!pfI;z z=bd?T;}ty?-*IPk)ZXkL6xZ{eGcHhWvGKh-czB0{a66@Mw;f7+2X}AGpWWefZV02- z!0E8xhlVD1Xy~_&hQ5Z;xic=`LfpUoarsX9GX6H(75{yV%blJ0jrWSTKQ4Emdk4DN zImovicYlX^-f;E4vjh58&hOVicki4W+z@wP19ZP*`1rlqo`Tsp48->)#`_q5+%zqAfoXtL;%|74iKHoO<`PTXW?XUl> zeL@M?Ey^Ef^Rl*PWo^yM+UCld8!BsC{t0DuDa%?mn-{q?f4?m&a$8p9oGWtsP?2+4 z#5e3yN+%|7a*$kySkGWcbqPLI^Dt1{qKC*IDhtKZ1s zqejoaneEpvRl2+MX4a}Jyos&4{LL2LzbTqiV*l$|Zeq!KUV8bHD8!*zCmlRA=QhP_ zrCYaFCu2NLNo{d+ya|21coTD*q|H)#-k={;7~AMd5|lBCL4d~qq@ca6(fiY5mw!Ws z0pE`De0tKwdt1^IE+%EriS8eiEY~~+v;xZ$PjKzdQ5#}Gi@RtOvYM1ky89OsGzN2S zQhv0O=y~`!59C5!?S3qf;f471JYD=vsj}{pwLY2Vm;iW#TKZB{#9IIE=-mXUOTJ41 z(2$E{-HmB*S&xSwGJV6|G-`sU#}|_ty?2_8TmqQxp$v#3x{QHf_Xjvw-?yNS%X6IY z)28!i_%)?ntm^>&WfDt9ZXMRrW9rDE-bSLw#}}~v&P`kH?&+(|wCpw;)sWTeEkDBWT-Chw zC^~|PrAN~vk1V9^#WaW;GfAiW%OR8;2i4yQj?RDJgHIkiv2u1Pe1C5nnQ@gH$Ynrj zKcJIeQXBzuV~J~LTV-r-7RWHr`A6?NTD)$N%nHM}+GY+bdR;oTA)a+Ue?$B?9!%{r zg;e>0QQXz7&yHfF_SpR}raiID0wTRHo;|A4?4H9`Fed!aKux@niJmb^O0YODd*NI$ zKm`}2;8Be4Vn0Z?I{-g7BbMw|UK&m-e=x1wy_tUK zl;+wlmkssf3DjPdlO|0`_jrP-o9DC>>PaW~9;I2FZ0FU_5=j6tB@prhO16aAzE^ zbNry;sU)X?jka~^031;?3j{OH$A-Y(PjMvmt1o$Rq5V zsH4yoWoNrOl2p6@Eb9J+oOD2S>SWrFPBxiBkPGGGDna+-WgbCI6r|I*`_%{%AZnU4 z+y!kBQRYwn1)UrI;_Cd;Ooj_Z%UajB8lUgJ#KaXz?&O8ea$9P2VWGE%`Whe(IsK(B zT#PcPLkQU00$uSJx~l21e*?Z&jWxDALOogi93V=Lc;j`WnxX3dp(|b8^fO%Pl3#SH zbZwjued}g>*zR)89QVz1oxqixQGl;nCuX@pZhavWrpoBX8ZP!O$jb@%jImyse3W@( z%I{x6joZ5JU603M%;k0CdRaS#tXyaG&4fkp^#ffGOBs&7UP-=E3Ji2HQcZ2C`5OK< zo*UxgV76`eRd$<|i=Ym;=prj;|1KIm#kQ)m>}C_Yp7ylYsK;w)wG8fAd$72f1HsWP zC=1R+T+g`V72F73)IaNTTkCZdP0+nY!D_V2tvl;tZf-ueAS{m%nuZ`i4aNe3*3&vA z(-!=guU7REDrOclrdhzbWv^+~{Z+FCIHEVPdab3MH~DpB-e6TtjU$9faaD8^-0K8l zN5B;f`!fYV@X*}})B+}QtXl(c8+KP3XDnooq0RMTMktgRM*@&T0bXVlXi^hYT%h{~ zJn3=))PXA99Yfsy=(Zc}YIE;0IN)4OIj*L5u(t-TKsOZ3g+K`5wyL=XLJ=x1;2kr= z$FfU~81Ku|vP+IKP@3iI-`}tKGEQ?LSuKPrwP2f60Rv$)1Kx`E7gq;ySW6Z(He|N6c z9#^5@kQsivxc6d-@XK~n>x`mY+&scByTHxNSU1wj3|1P*UISO-04`hhqBOx5R;`IR|?LUuK=qJe;rv~tH1SAbXT?Y9 z*(w-+$EqMOxno^e6d4mJkVS6+`Hoe=J5~knSQT8=!thO76@2m+;3VeKr+zWxB(85^ z*k^wx&wj_kaAsutj)mdB6AQynk3?^EKI_=;<7$9a!3pPj#MK6(2RX)cHjEBVHq+@NagZ*3y@Z#tBZr9AAGIf9(~llHv^&~C?$&PP=J=D@jaUbh zAG@R2KJNuMeWLh>NL0zYBMi9556L4#B>qU!8zWY+*f=p~?H#8+Y0c6w0uS7kZ;F_?>tyd7q|O%lT4F7G zi@yj)Mfuhda~^=#6Em;Cy%}Po_7?9yz+d?`5*xGFCSv0j+e~c2VllBvizURSEVhN% z8jH;mTWhhc#HKB_jo3Pi-9>D@#pa03SZq774Hmnb*hY)pLu`}9cF25~?A6y4U?xBT z9`qFKR1o&=RS@;=Q&8$LLU?-XeV2kt?{x~Qz3)~~>%CqZJOQ!v_lqk^#>_6NcKjM)3rN5B_yVK1G}(^ z_`CfBR!qj@*ZBt|Dr50?`3G#PbmLwAL7VmXKL5a>LNmVCJ#f~s(_&?&Fk2{@W=hOZ z5+ux%BTZ#bj@s;mJ=rjFR5I#TpkZB+6YaE&mO$`~mfQp(X&Vs{ErF1LEinX@phues z5`=C9Td*2MFpE5uV5^%Y+n6&v-Ng(dn1l8ZY=`g=+%1B+Gq?wmL$CvSL$DKbf&}+s zz7h{A>DM`x4-Tf~BZ$=<^{T`Wu@J&e5Xn85W*sC*vkv;BSqJgatb_7s)#A>cyh zBMg&Y>{AL9R&1h4kuYODR%FsUCl*z|E!K@R$TA9^!~JqVjap%p_V1BAs;8~5(cs4nREp}#br73 zldw-~C|OR1;+GuUg(x}(Vtk#qU?u>rmD4Af!i;i`HW(g*al)B4lqacyBf`bFDL*8f zNK|%kuv!HhKq1>2KnLKq%n5ddiJQLpAVi>=Zbsfp@ZSp6>S^^z+&E-8qbz4cPDH2G zBZn;idmbVq=Y46L1Ql7bjP-Q<2wqPv2M1$HFXi93JY^09a0*9;m*n9GG&Njx%?(y< zt}k0JSr4_+?GG}WTFB-i ziE3pSR(_Em<{YA$zE2*%O%lq}_YsFMIDgyU&rED_loopr(gSm@y4sv`9&ldUoa4Mh z9-BE#6zfCut(}H2WYvj?laiMm9=Uo@IVUzLptw>r=}J4HMDNr^`RL%6uwJ zJo@`hnpy~nb4qFeUBpx*B$O!!G8hfz;3O)JXI(TD!fIpTX=pRgkVa{kWnh4WFPKlp zJTjXevnL^Q+(AAfqn_M9ADcnjeqtLU&9aYc~k&9)9zeGCbKL~Y< z9U+0~GGZz=|7sfE?9*@|&Uu~akG8rWE@|n?C=K4woTqX&SB~~DqjDld>niC}43hKz z4p~YAfc5HUe9DP-G|q<55vVxa8R#%c$CKKj)pNSFzZlc*Fpy?P=r$snY~lo1r#O%2 zT@u0LXbYK?%TPSpT6U`<#^J*D7=7Wi3R;)$KhWu_E9FJJ(6%_nfC%bcQu37WfQHsn zJ|HcM(nPTZiqaCrco){%*DHfjl$KEx#Ovh9DGKkKeTqU>qjQ$^km!}s*_J$Z$JEYm zMc$zRLdhtf9AlB5f<3H)B2X!iPnWtDEu}CA_NMZKEkuVRl}rfsze%6x-5SE1;D=p|z+HkD$;*Un`3+lsbG1kBDs^m7VIASwzG8 zGvo7JL2&FjoG@B|HqtSf zm4=|}R4;1T05n))TyG8B zHL##1*Jyx@@$$pvQ0Oh4y3Vplw|XCfwXaY;{TbzdGzS)k04hKUpw?a3f?nB}1$15D z_|;-5bg9u=DNLe}b;^Vf)^cpY0$NEc=-xw}NN4+|2Ub#B9N_b})^r=IY)t)FiM(ov zET@L4Drmx>YQk8{oWP$K(q91mG36B{c(eZl}QpaB@oyG`rG#5bWs&TqXlJL-8;5ix&xC z6Jey_A<^6eZ?WRQYf60}sXQpc1tn3DqN6>iYv49B=-06njcUalz*lW(+3%#UsG8qm zW%)lDWNn79+t|!iA1J;KxTL*S39BB5=vfV+3J`Fez+r7D~*St^$a2Ft$rA%MMpJhoLpootp{ci zQa>6=B+Flf1DF$O2)K#?N_L+ASnN)rN@S>I%~Aol*LIb#ZXv)`8$_*X11{Y4hI40M zJ#!|np6*!n$cP53m$HIG!B#eQE@#+X3QcDaItnO8^YN7Xg2D0BM%u=-?Z%WR;ay=| z%eOkNfPG+GHB8qXS0QbVIgG0i!H+BRz&3o@xCU-yH9Fs5Otnkb(8|%NpJr}`$%i59 zBjbc!>py39{+=igAWyI8=@mTzdH0mRyEO35p6s1g^L{C`VS7}T-C0mym9zHlXO2+1 zsIm>H=4W9_*}(ZRAxm*cuAXB5KN%7zWf4-^?3?FU;BsLA&h}(*9v&@pm%w95B)Wnx z>!Gj}{H$p)6{!SQN+J-U-luXis<#STEe$gX%@P~Rw513zb@9C-7zTYLG z-@f0mr`6hru3_3Z;u#-Cv{D#R$*Y*I65SC{oSh@eT?JCOO$QGpD7mc{_0>shc!YzE zH->7AmJz5kv2TPA!{1?J{Rm%|A3emkOY4=CeNioZ;qoJ+phV;~8sxt$v8J%1D9swS z+F-*t4-a&;h2&ICcdUEzrHP;An5TWFjy&42%sA#_WSe z;R9ut_!OoCmNW+;lZ!b@v&Ev?egFXXnu4?@63&q<1eQxu!W&h^w@slW_7-iCqU`Nc zD1B|EP}-^#D!3kn5?$)G8IdSuBMzaK$i(P!(B+IZ{aR@eE;hnd0{dFRzanJc3cwb1 z#Fc)P5JoTk3L(s3`WJ)^iVH!+5Y`!p{dEaZE^vY_+J;Hn&srRCWS^5j_Sp+8QEm|! zo3Gn^g-!8^%*(O)u1{?GMA5+cX`k5fiBK{}B`F@>-IZCuWe%czVgcJ(+kIl65NkUI zZiamddWxNW3EwQxOfkzAvd7YbSq3$q2jum z8+lg3E&|kq_oijXmoU)ieCMLlxJ`eaIGk>LG%X+G#u&0sG@T@Nr!8U^eMvOwe(S0E zS}2i~SqI^PyW!lzYCwLVGc$6%YVH`^9uXv9@53cH)=d^aT>yjE;?S0HVxme&<(}DQ z`TJt-nVr`tvQz)Q%$5lrr6Yz5QGi?0C{Wv<29;vb7BG>;>f@l-O7(1z7c;bd&)^n?A%%Ep9cpRcnHXAR8Ma zJiBN{kfm&+la#x^UP=(?FlL5du|rYZTng8PsmR3*Z{27L=fEu(O>j}CxJ;D#tky~P z&o*WyC-)S_=;|AU6z(rF{t)ST7E9;Y#dp5|8*XD)-x<6}uT@@`fg#_$x9{!l z)7_^}pFZdGIchScs-Xzs)Ji|YU}52C?-GfJkMgs$LPKSq^N~Wjw4&!54q5x3p2T}a1~+3ed)AL5D=4l}VJtDST31AGG6A@b+G^sqWshgE4g`suQ#y~SW& z2HA$ZNdB;~4~vbLURU;C{;d_G!^Q1psf z`dNJ?%*a#WJ%^WtJh9O$RAqo<=b`oK$z%O#%`grw17}U~)wDkVay_?>8b0ZHR?ofa znFlkW^N(xxaWzTESA{%Dh41PE?1kE>DHPQ*Z)y!udr)?OP(+HMIV>$$n6Lpq&WuF! zCEJvCFgApUS+9bT8bEMVgo}$P7DkHDFD5d}VZDgH+fH8gj^;C^pq1$%F0qJx8BU~n zgcJ^~#O%Mz*0=T_L0!bV+|ZQ=6lqJto79 zXj)qrPIs~)FS_3k*38I^a?Z)2<}G##Ho{?#ET^d{Y=2shD~-B#oDRC zc!Om?4jbDEb}c=SI^UtWj&NF{^BNaa;d+9^FL0s5=C}}Iv*+)YIGad@MV@wON^(+> zF%WX1cK`+Y9g;9btt+XWalvM@Y66d~e4A3cvc3RYNWdEk1F0U_0)B17-U-G&frilL zZFE6C$9DSZTrs8@7ZWtj9f|()$#l@Pt*%LCq@XBiHup3h6c`mW5LsP#w*`F7wyI@Y zgmK{xM7Gh{qRF=fFkl#GIfe||yDbZd*YU8Jn!6KBREV5WF~qc6UB|m!lwn6e{_P&2 zM?DCV*~w%ldJKhs4oNu_5$#$^0Wpy#fJ7}L*k*uZB#-Npt7f7A9ki3>a20EqVg8XS z84|DxjMf6IC0S#GGJw%guY+A$S}$rmrYbCL;7x zi{Y@wRK?F$c#QVI>KyK_e*18bL|FYu#tB=@0L+39XfguK~t8 z;4*oCPk9A9b@qN*9V|(vQDR&6G#a(z46OwLHn6U?f!4P}4J<2=P#w%yuY)nZ>|9fO z4Q86J{!rf)aHu+6Cp6B$5JQaOyarA*k0ZIi9Sd{B_;l$O)>;08E7nNy6VTI`e<6vI zgq}hzq356Zic{jHWE9jVrc3qZO^ReCeBTF=J#an1%E=gc~@ghXokj z-d7XGks25Elj$Sz7Oca<3ga>0_jgp2kN~~+_o@}izoJPs z@$Y778F==ZxJ`C^p<zZ)sK{z1@9rbDa60Q$-cwKD2C*XHIXVE?9t1Iux04Deugp zR7yiUrN-x;Jon)_8VS1qC11VP5_)mv)Cm&=f=;PY(>2byceYv;6~e@3?o zxyqHh^E$9{(eK|9kvXsT=O~#j<@7H$q5yC%L0-@G$%Lt8DW4PO)`hvWipGCRdZSwL zI-94uZA!wflO2lPy=u8mc;@5Mzp^#fu)Jy}r{=w;F7Vai>h~AOppcR4mhsJ)>g;^7 zRfnXFT>+gNgQ-DqB$Oj{2|4N#cl_MJ3WjMDq)iJoD};{CW1vYN(&7JOj7hjw7DNt9 zN8wMlZ{i~e4_GXee1v_D0(_XVO!^fSe}l9n0J1 zP-sUsx0Y|mTL%?g&Y{qDf-y_kL*8k4tL^Sfh_eQivaPrW#=P!T!?k0GBIqFpKY-W` ze!cGS>D5-f>O#EaVhBRAU2ZJ4pU$`ANJx%lpl$GBlt;_8uiTOC*x+&qpF(iV;ymy; z1UZ7A?{r{onILp&eLk-b{&OYae<4~qlK8HXz@^3W#$cm;FhNPN{!2o0HYN7r zl%OL^9 zpiM1!-;%iKJDuX-VhlWbR~t#*+iZnARFvVOr9dCb6wS1^=ueydP$T-5));L#&SmvS z)Mrq6QHIYsHGl@(mYgsm0U^M}f(XN_&?+NSfiPGsW*~aqgB)`=h{fy#QpmY0dJhGfrY`LZbi~=knJ80`4!Cp&rOfDu^LU1JUO>SUuSeG8hM3aT7mpHj)%=zTZV4*`{ zqmMeT9FKr5AzaCbp7pt*}@I;Qjs0kNSxv%ZDih-YfJNTKdL6CA4ZOq%z6A)ZMh zeH9ZI5n9K<41q#ohG1#L48ad*TC6LIx@^hFDAwsKouqA6#I9g~85V^>wIX>(ByM4f z%cqm~$KtPS>lyjkst6NSlK_Z5a55>;8Wpos;X#rlF7R|_DcR^FN!EMq(>Qo4BPSL~ z(*d%(a09=*fr=B#)MRZ_d2j?QgOE(N86C(pydaGcL56x|-4Er>dEW3oYZ73ZFEs;T zE{d1__veE?hKwtop?%aeVCr~k%UPfALON7}s5-cxNY&Q^P+1@@2dac86{y4!9|pBG z2I|DMf!cEI+8C%=+f>Qw#`4d)vqghiAI@2{I?~M`jMV~$-ous_^(dW=IVtAZNPuZO z;)EX%%g;>2-Yai@*w{DJJS`uDcoGxP@*N+*6yu&EN*O5$z$P|JdZj2Dr_VI-eAsXlACE+5oqmUf~p_dIMjU)^{7> zo-EcA ziOF@1h@@jsAX4e)N@Q2|%9q8YA;nEi2cpJkn+W3)iEVB9jI?DUc-o^!(sy!>Qo=Qk zT1rRS<1#H@gOOR?arppihPWd{PFmHT64fy~GGW`7^kjB^>@NJt-f7G9T1B5^^!{e` zH2RL=9(pIb_FPp%BH|)oDj@6v;W?p`%r%z{dy54x2+=9*^{Z2+8K`tx3v;fseiFlf)`koRU0XbrGqsTe&m|E>aatwYH++uS8*=>GF^3tzuBa# zI4^&huDX*qSL`axIflAQ-V-+Os*mvI-MVW3NLfp4N2Q)kK{447vdyqw(@l;D4!5W5 zvvgew*Np3Bk1xL>7t3{BW_6fI zav<1A1d5y~=aL~n;KWS9xnGJ@$|8L8Qz9r+_?yH_oo?A_bNe~n!jN%$PPgbixc#hd z#qHgeoYCzBheK{l9@i}nGr3*WZJNz+`zUwQnU3_HU_xSu6mUz(d)`p^U5MASDvOU- z?e|@#;+(KN!TN3;J+*AGpJ17R2H50U38`#PMH%LY`)-3>xLhC z=2Rr|k1d87Jfj#CHoU3U5h8)xZ|If?3EZ-O!(j|;?QO{`y2U7-+n00;TgvT=Xfr93 zO>)xvTFh#lNR-Mil1fX^{K&QkK^zAdkGdCUAd4ixm48}E4$!P}9H4vo zm$-^&>_h^tA zt%YsJg-?raLv5wGnAgOiV(Fxn5WbA3BrswesD-~WO%QpsZ8CnWruQW;7QuTa@P4G& zA)1gUJ&eh=AEZ$|)p3Z%;2;f~EDpaUV+Uzqb~SQrE3m6Wq@%Ndus>r5F3hAubNt%;$3jiLK@y=~eTb$)B%+mvfE5l7N7Az1^=?{@&Q^wziqUp#nfV^*~K z7AAEVonAD%BW|8GeIT*}h+r}6{H0pldnfL4#FQKtzlPb~>bd7m-8I?N5kTvYsQ0fy z_vNT3Bw#A*NG^{v9IDcmC6?0(da?H^s30d6^tcPvOv`qeGN#$`dMW?Lj%LM_VYAyblzT@e;k0BCD{REK~Oz$3R)&Lfa3B;V2Z#iY>jRw;k*s%|E z01J}nXBWqM9`SLiEdYM5s0`Fj-6B))n3GkmoFA6V2*^Li;6>bi7fp>HmT|tGx{pBk zcmfKZ8jn=3Im{+`AgR1WC&*9@=Z?$o*DZHp({%WQwESR0ePx0dvE>n*53>sp3`LE- z3w@Z;C{0w;hw@YFou;9jNiLqbv>p|=6t8e`m%0$}R?fF3={`lCsP{80SESan$QBR= za6;|#RPSdBV0$FF9P@=Yp+^rr>eTC8@oS&tGe4&ijAVO-M}2CT)07KP+m7X`@2 z$fAHmX2YTo)ehU5kc_PfT0l$`#59vlFmvT-9+^bQC=Yu$)=7617I?3Y637vbz zBx)}V^Fg^Ex-AKIFpmgS$<~St&ULJNR--UceXkL83evCuu8#~u|o$6GW? zCt(5A=(@7zH_@eK*r;|HZKz%L^4#XV+^Hf5H7SJh)TLOMTB*~N`W{LxBTKcb@;hbu zow4$3W20EFvg8zGairQ+d7bKIy)3U@mRECl$IIK;u<&7Htm2wihOwl&mX^@V>eOA? zjVJN&mYsa`F%SuhxszG{F>C@E$w#w}XR22a4q99*A*_`UHXOp{SjCMhGyL^Q22^z~ zP$5+_-nfmsQFXJ$Q{6W`1`NWmnQV(7sE_wit?Hvj2|=TTpy?2_#vo``Stc}x-t!nh zsOekPNOlE6%w9HYm2T&E9=HHbh`Cc8lkFCW`SfFsbKpbOq()VAvxKHuLettDnm`SP zCVctfAh=Tt($ZCTEDBaZ*#UCFDk!&Rf^s3-eG>TQfvocwnqI@DW(C;*_gfZTsx>IR zYo#Nz!uF7YrYL3i$-MXIW2nPba^31`dWi#U_j2lka(a}Lk^@i$)};DJPzJoNTfOPv z`&quPX#}R3*W)kec-hd)J)68-;AK-UJDa@BcxeOMt6qkHS%5dFeKCVz!$4O7v-Yz8 zf~x<@4aw}O!~~mAf22<0r$xlj5bIJyT?7xzogcnrfpK+Gfv7wwc6_*ihdo~WC~VrX z4?YZ|<{Ana_()|Ev=M2+^L=zz-21c`aqZ#;EK)eVZ>&=!jhN1L00#yTz|zF#QFeK7 z-OJIO?OSA@S(6hQ_#vt_aGi)*GVDnWwt6r|_fWCb`Rwft(@Ward zh&I$|ULERK&BzNzYd)ar-{&=Bs9G!J=^_Abe9KIL83&=GIp>sf!E?e+qt2BA0t^H1 ztNo1H7iY7*JM{6FxS~n`fCD)Ubl)tWmIA zEYSB`W00SWg0!R}_d7_o3uXU?X@6y##kpupsI0eG%Ou}O?^MS79lHD2z`D&O^OQ=l zu%6L$?)@Tm13p=3l_?tQN20!hl<2_X7MQwoOn>wmHsx&kW51y3->Rm6gE17hxg24+ ztLZ=CV>mH7hKLr}YHIq!lejW6(eyu&A-|#t)@&0#ii>(cKMz{7Q3PU2+(r7t*AlOc z;JB=zn%M86wRV!gP{$N`1`mdxeS%HZ-$662v8>1hcI9)hxR42>9wTr$MwYFqt2G-j zQqq!6fDUgcb5{farCQ>oh9dh7_<*AVh`re%j zid3k@Nd8908WMm2RAa3}G5+;f50~R&9*zt+PH-EgXk0y(X>}Q``99Trzt;?=22ASZ?M_pQb!ifY4t8p={)vHlll99Dc z?IerhSo-IyM>eT(?>lka)Raw5A{rrJG~Y*?agVCF*MSjb1`$?ITQPsAJ{5d6(-8&* zxO%_L91&P1Qa&LA7L!}AV))@&c01hm!$YMYBCt{#$b`yL{ywEFM<-~9w^4T1B>Xoz zpfhPR)%^hmX#Q_O16Ctc4hjfnw6qV%5KrhNrzSB9emUu^U&y)_j$}_fjw+wL^MnjzZFG)w%@`3anm?WTO}hv+nJgPYOY@y63!r$p{}++ zEz5e0YGqbmkshS(qbQZsN_&qUP>cj#EBcMj_*R;56K&3OHFvqGB zzNR>SS)c2ZePG-6lG^AxGDHJz5`KnvNabxoX$3k|uSfL_|Av!NrpPGK2s~y*lFQZJ zfd#rbHP=@Ah7flwcS&*vaBQ-$jV}dNonc|i#=AIEor^wIfw-kUl^tzT*c?bC+8rGf zQwSL!B@3$prC{iJn@UyyxKL4tl7XmNxuhD6f$+H(hHAsq6%b5aW(aqG0VLBvW3?>2 z)NI@g<$qrjv!yjGAib#0U!W?g(Q!xNGkvJlg+DKqAWT&gF0a%`5 z>@D&f7@Gkx1aLd0V0wAuU}=&etFgFcikLvQNwN^Sj|&Xts=7>;0SD6u=n-qU?@j12 zGj%l+Tq(hr;-HCILfMu>21O8t;VR@GoCFqzP-j%ya8jq?3f&@HiOFlD8`);!J}=S5C6qB&#!~}Y{|cQxy|#huvdHc&GR1(m9p99`3$98&E`2k z^X9+b<~cy4Qs8OXu3g_eOKy3&ZTz=)^ZcS{>#vV(o*k>MZ=NfXQ|>3Kt?XaI=DFb4iovS`oYMZos=94JO2De~TXmcw_*1(4I;S7eg8*NR_FS1`XJ zk@4^t@74fRXR6R#tDkf-A5gXzmCu=hnx9T!-N zQpTT>@1-I?YMs??<>U9qvKNL(AaL3O2vT`9c*@ajQK(6GWcHl5q%*D+d$H#|Xm4&s zR^=6Q)cWOAAKXJx69=OmT=?ilF3sB_;(YXC{LVYyuI9sg;N-I7+-Px%Xi5 zB?B9Y4cFou(eMf6dr5hlUerk^(+)mZ22 zX0~cOVkKNVSyw-U(-eb8x-kjM85n(hyUdO;awn3E7nL2* zTLb~#bUm*#l}T?&K=D)br9j}=y5$@QaPZh+DX4LRNJqVa+q%?x;k9(Q7hVwu+-9?hQ5nRlm2ccth{ky|T1AyqtP(yqF3X1=kBYS{#nuldt#3u_RD-02}Pp z*r5J$cf)asy?*k;^FO8h?hykqWzzd0rh`TZ4DWrOAUDc?528tTm|{WhV{*u;1sy~G zNBRQiItaZanyu+rG1#cfj9-M2JZ<&MtY5bIWxHQMHhm%s3obkTvdb^?ep&F#Zok~% z7qC+qGQafwlKW+kUl#pxlV9HB7p!8G4__*}?DNabe!0aja&*x(l{5lo?>qNybL&Gma!M~U=)0m}yi6s2F>m>Y8be)9% z&0PY&jU@d4x|w6|HSy>#qe83=n}=cPsin1!`doKzpNNHrY4cMVRBdj!lgK>G7<_Cx z+&rx2)}e6OvJQ0?85&{SOie2EF$El46_Rauef_a|joXJ3Ut|s|kzgN+KQ`lQD+{cu z0xZ-nV;?Fp9@4WC(%NP0L+6I=L*<@s6Z=r{pE=%HX^q*3?v#C~c#w0Ko{u;y?KYwu zS(c3`Y>sS1Yi=V7gZqQ7=Ax@~2+DR7oE5DVgbv|AXs!4P*X_u+Yy>bf8U9PXe{^b4 z`wyAyU4v2Rp!GIRG3U5sdJ~L7<#CtlvGh`O;L4c6T;{1);X2tKXzUUNWVFwRdz3QW z?qV3aJatpAbkx*q3=(%XjCR;+W{(lD1|_^IJ)j>m3bmk+O__RumIkJFxyHyYCh{Od%z+_rZg$77m{?b z$7D}*2O~u|V;vU3@0hkT+%Li7b1{F^N)gH$ONFBoFLW1v|9K zd-e+_P4RDLo}8>z@GAH-jg9=e$%mdjQ>N?!{8@_qx}C&DJ0A8-bsg@Ni@Wk!$8_0@ zW{E`r$2mchHe!V(@4`*_Skr97YaYi>e||z3 z$DPqk9iXU?26Acb!aY74uY~%EW?BJdr@IA|f|{0)+R1Mva@Me0kYMD?Ye2vlMc(8+RIyQh*UHrvsVKQ0TE zjCjylbg7R{ZawZ^nyl|bkK zLB+X$$o-rAn9o)y3ENz4$7q*MRLE!w(xM2hBQG@n4#TN1HBo7|mbz?9_`sgq+&~Sbf-1ySubo=re$N%o@I`-@8IRI&N2v-+8kuZ!R+p#W|&zi&w(J6j%_(#Vc5rl7!KCUEEm{srploTfQ>M=e2nSP*-!3g<+5? z9O?luvLiPG#MPLXyqXHw!xfz+5Kx!V?v)^WG$FiUcb($yyH$deB~Y;2DxHcc5!#epTH zEHj<;lhyVdwyu);-V01Jcdcf4X}(=y(Cwf0IBx}j)D@z_Vvpj`l4=YlY#N7PzP(`{>7C5CrPwxHo0BOvXtOz* zVTvs@t4y&utDxu`($xsnnWjkP)+$J zr6p_Yba1Lcjc}Xl+AM^>;8K)Ut!vY?P zz69|#H;szIU58Z(!Cp*4z-|=3(b{yw3gpcm-o6bJ<#dLY#q{6p<=#)8*)au2F*t|w zGo1dt6P+Ho=swxs1&iiRz-PECoq&sNqiJ@^)3y}2k5b4BIIp><`*fe~+0<)+1;g>m zbS&?fC-9xwt~GqV;R$?hP|ahfkF1t%!B3se=Y~CjH?leR1WtJA_A&DVK8xpW#>7Bi z3UaO*rg+F1crtJXZd;WhXW+Pidn}t%6%cX5p-`Bdq_eT4qZACoLx@o(CsF80z1Ybi zpoy>*Rp2Sa9=z{nJ9SaKUO=FG)eFw*TDSvYD@k2LSY#$c&4kkgnONp54##jKIi)}l zn(q~+%}LJk#Ob?*aGX2BCFZ2O=xh1IT_|1KTG=15zay3qpSaWR;YzIQ@|Gx_iqlrs zTd5KBW;J!$WkqH49J`KiLnLJ`fmd*mdJN`Pt+ga{nXE2!N_-5BE0apk94BJ+XIn-N z_o@!+?NYC3h`fIiZK18h)S*>BCL&)$y-g%JCa0qO=!7?@W7Ds&vjfJt2SwpUsVeEc z)G2%=&|^qz^h(W+Oc9Nzlmob;Mxl5rcOJ-$>N>= z>Onb$?mYq+AqNw!{CMg?nDEh$yZU&=!^-034Da4vZkGa{@Z0GJIhi$@i;y!`Mfez> z-Q~xP%Y5urWOcOxPq!JMw8jc$Gu`{-=E;O;%sL9zHVOvekt*P8i2iW@`*p?wfaSny zxKDVivNubnt1<$?ZTiZfmM<>t1~gb{Ian-QC00O47<@>tMvObl6cDAMHyXx4x|~I4 zA-y(~j_c`A5^lAs^lL(q))+p9tm|I|>#Z?A+R{)M54-~J6m5r}Ao zA{?D_6k#7$4LM9&HRLfQqeKNsvWdhwq=YyeHl@ejgtT)W5AxYPh9mQ0j&Lt>A;C9zOb>ijHf4_{B7oh;IWSI#PUnwvp?eU08lJOj^oKjH@6m84j722^OOFqlPe815%~bbx<6_`ABj^Nar&( zqAMAvp~9NWQH>x%iZr+!MF80Opg>^MVRfVfqZZ9nV8Ac7FpmN&7U&Z4bledmcL6(U3i-%P@ds zUz!=tmL!BIKhmd#!VDW2Xy$8Bya1%SOq-nmT6H3UiBpEAY;5d<@+EYUlW@zE#Ufa$(PFZz!;R$m^D1LM|@K&c?+mcxR4i%XKX3`>&nF{s&K4PY1Sn9-1l z!;=z1(J_QG{IpInakyK9ze@5_@_1|_VI3Zqe!;`MGB3+f!rmcRJeYl4E4adG$@&2r zs_2c+u;qH{3ASAK5EzCX93kn0$1L24&OvtE6^;XFY7{Mk2uUouDMFF}l18S7=DQ)8 z21C@}BLJU@wZFh7H=b;u=M)W%inl&v;zcCQ6`b@Ty~u~>;=JwM$fcIgNZrF7?uJr* zfk)~Q(P6E|WFP-GoK$BaX^(X7Oxd}R9_w5%tv%AW2FM-i*$F8KT#m*; zXIWXlN3-_S1~XxpkdVC0F$O`Y@ENovpLV2}9!83>TqWEkQfNYq)_$jIH!Z=0v;+d2 zOu&m#g24-(kLDm`Z4i@Am=_U4uXgXB(MSzi-cfTkjC4hleSbN2JR)~%?9-dYauhXC zngBL(rl_-#V*=R7xu$1J(DYoD(08;4s%cS<9Ass*IZFc8fQqCO%Naq!wPKojWUXqHS_Oky#Cbh_XSlTQh{Rd^=jBO5OmpwVe> zlc^i@bc3mC!H3Ov1`{mq?_d^JZKy^Ey5ib8bK=oueeCZvQD$NhnvGb^g|ADhVe_&q zp}cB5ZA9m6F3wzw?rsP$CNm=%ceg=xW=wa-WZPwU_4 zzh}kFqU-uQhro%d=sF_J-rv=ins2&3$sXrJZg+8>jn&bqEpglbrQzC6L}sc9&Kf&b z^Fu1oc;h@CC-9w*F-)5vP7y@Ka!pOL zyD?(a4aA5pnF_f8k++s>TFRYJk5m@ci@hhPXE}P(&N&3)C2F-CeV(nG+(6ZA=YbH0h@=!EeE|9aB6iuxTFYZP0F@$S?n1WBRf>C9Cd$UE40vNyf}w+y z;E?tHjMxd{woHKmTe^d}x;<;#sz~D*3mNP{XOUgDyk&oz4zzG>Tg6ulu@^2w7Y~k$ z=zw>!XBb7<2h>jw+UV0{8k_CF;U)rmwfwRUU@Us{bOC=eZQHv6&=dVBDUfLV2ea+0 z=MS5{((IR}`oLe3B-2-R<;H44lmaCV719!b{UI?h#XpEeJ0$FuI4L?8zd!zLEdFC+ zvZb|aj}%l^?lpsou#H}{X;IQq*tW5bAu^|HU**kelzpQ1Y0+>17)&hq(@_#`yB6tF zK^Yqap?n5!7p_s9uSVRjK5NOav6QE0Be!0f_ zA4MJ^=LU*A+e!@bU31r>2%~FRq9}-FO_&0ZSl;S^o+iyK7v@Zli*ez-Y>##}utm2r zzVGK`5Im~0s*rd#>BYRT0i1AbP(j2nb7xB&!Ns!3T(uxFpth6AGJ z4E$lj)R8pUluWYmBVi!npUfurrFXMy1wSX{iyI}6_TQ$g=C0SDl7J+e5@cc(HZw26 zU8dOfj@AzC6A0BsgdLT9KzqYk)3^knX4xWSEp1-x4NJRV3eQxSY17YjfgT1qCe?v+ zd_w@(ySdo+#8_YxVA~LVN)r(h2nUJV;#&Zs^I8wUk$_jcCS1DIS07jr^_gT_1vpw` zdG!HmqQ9%0B;8GB>jV`R`MJL?KtCbrfunwu-FdriVxXh-%O9k5FqB%0OKp+SCM zsC-*Bi$AoK-z-O%{TXVnFSE1yxNdKaegm}lueEtQ6g{96X?oS9?9AEoX#oCXFoJ!qnr(41b9fx3A9;vIa^mOB+;1>z}k4@ z_m!(-7I(Ag>|y=T^7MTrtW$rz_~LJU@wcK6o7@MTLR;b@$}WCZ$tEsBG&U?QYC{2j zGo@oXIJE^OtYio;27O{`kgQ0d)euQ0-i27Q>F(iMjVtEC#_6FPd{%#79MuV8hD>+f9y<1gltC(8J zw~;bkt~Wpxw)5QG8ciyAs-#0eLF}8ZytrXShTrhkt#Ma21udC2Zv|GB2Me&0ZG$9) zr3*AOF%NZXawBxi)b2yke)5TXZP5(LJ7uZ~hRSeLgUvTR0%s{z_7f5u0R@6$eIvPs zJu~TBB4T-2J(ZBdYUI``m{RHLj!+LoCBLD9cP8tFxv7}i(A!GNVele95dmb9?AL^! zr)mp-I* zPn#@Wvy}+wLvM&Kt8YY?TTYKX1#)bNu;`DO9$`hqIWcJ-F$ACV2~85T*#v-+JTYn5 z?j6MvP3EmSU_BAaYUOP&%{6|P_4bFA94nk<2ex2ZY~@!Zq+OB_Civo}bSTCv{&vx! z?G+trnT@TQ8Kibwvm3&l;UDtXdxpg1%%=WUMD;Z}!8V#C3!Nxyl`56vnmCHSP44Ar z|DlMO3}!C5;G@7VBhq^eoaX(PYP(;|x_0CQDIP{>zv``sB&C};_*G*i)3X;cb ztccJpyK&iSHO^Bux579FS`WN%4PqtK^`d%L=Cg;oKF~x--jxq>&9)L0P$Q-Z2wY+T zfC-@}z7w#Z6A0L5SYSqB1K{X713RS?MO*kCr3r{S@6kty0S`s@^BReVEKCNdej2rj z`u77>{~myP(!IA^n=ikyFwc@h4JM17Jhu%|*TmnN6o@;;ZP@-7Wsj^9UWdDGN>~}N zr>TH-q`0tAC#CFc$ded$y&My168=K$2$T8CVpUepX*MICY|3l%+X_dA{8{q(XZ`+V z-M^*xZ&Gq0naFuZz#8R8z$2ZP$H`{D9=|=J~a*{G}?S}Ry>w97bb2940y8Q zqV<&+uq_twPhDj|+%xDkgMqg5>SgAe_teV)hF2>XUKzl!MDMy$Of}!d$T8N1xxCkG zZys4?+%#aCpkV1n7=ki-E5#aTvv zxf=U~HZ6g*0{(TV0}NZf^uralAUQ<14&&AJ!5iuW4TKPe6HNby z${@z=H_hwASdxDyVr-rnq#2Z+hPel?U@_ zee$F^HiSfW!hXk}v)qmoW$2StwW2+}=R(eg>!gAv?X-|P#9P9L1#gHAHJ`oLKJ4+B zTJV+$MP*XN8^lEXf>Hd!z46<&U^&QwPZBCdp?P3@`0ZM(7!T*OBim=??Iyip!IFso z%{}}wzwL~A^4#JyYlre^exrqD@o3NtzluisX@#oj?Zl%IU~27-Y_Aoq5Km~}`NfWn z-W8EfK>>=qScg?Rm*UG=xDqIO0VdEXkiXbrrnYM_vE8lYe&H2jkmR)}!GR@?z% zZE-V^?c%p#1EH`}D%bnJ&Has5u6LP-zQ)=@ZJo5%^epqd0ix(mDo%ZXoR43&k^Fk7 zr?xffCM&LH0D8P^HUd;l#3hZul!qG%gG*p8A!glTBsHuB%@90Fg99hQ?~T^vde!8N zChrO1vGWjTyJp|iRJY=6(}L=A88*x*1PHTg)Lool;kRkM#EQ;6 z3=Y3_Ymi6!@#x$U93932g!xXXR?)fpWpwV;A&^al=MWM`o!^~Eww!E*&~CG=*B+`k z-==77Mk}`4l$|jO(aRBb8s#vmFh>+O;NX5C-x*@Twenr|iNIu9XG~b$*YbHwRlGGG zqn!T54Er;Qaj4c&{e09enT`9T}Q^rHOF_hb#M6sw)VTb^> z>jH~wBJ9x!PFDe}HU{+SdH}2ON+zoqQ|SK{L`sulx=I`b=$b4;VojD{hZ5UkV0SAZ zG)=)OFVP}eu^lwn%b07E)wkWU_-!D}H0kCj7&3I6~km!k~#B3AfO-^NYZR z-$@UM)!n3}8)JF}P{wN*3oqx9>(D7!C0a4MUdbTB*dUJA#u#&iw3ERhX0`k(48mh7WC$qjcBeJj)D*z`}k| zIYtEh`ZS(207I;~K{ULi8tDze!U#A<2^5CyJM#mJMk`E3cC9cA4#>b&W3{0O0=^k> z1Srp}P-s4X67Lev(ik*hmMmBwo#YsX*Q#DrHmPF>^&Dpk!JNZV671RZj0xPBo-o$VQ^}ZMD4zL$)-6g0{FsQQM8s@Fq;?g{ zOO6=XsrL18k?Vr^Nz50fDiXe>$_AH)2^Hrt(MF^S23jK<_Se)28wZW+oBdU)fS^>+ zkCdA7j(nJmQ8Jd>aww;m&_s&nHr6eXqPZ<2MRS`fl}ORFjPnMZ%;H>wB1K2CbW+r3 z8GYxei3VUrRRx8^`IFZQPn9PwtauVkT#~+rZPMVBVq}=kZpd-+aA>8ywKXXY? zC6_y54@Y`N_+IIXs&#Sw&$GFxXTcd8yzS^5@xL%nQJsia~VXoR;RR>c{DcV ztjX3P#kZ^3h@Hy$gLl7;Q?52L<(Q>5mC9LKPB|I$^=vbz))!|WO1=LL#_gvk;=0&2 zET7X+jfxm7gw!0vk>

Esl9G>Nx0#iY%*t-_agN%AuERG5?re0#*7ky;L`fl^i!o zmp=E8INYS-k!${AjoO^Unu5(ik&X8^SQiEMvSTB_z);q4$) z63jB`BJOC7--YuxCWfMX3wgrU8XRaI%Z>H{xC#CfCwD`1E-qT&7xmQ{jr8!~L%tVz zQ3iQ{JVN}$EmZB)(m$#&j?s{(1!t2{i?)j zGq|-_*a857KAOi4yUF%AbY!ybK=Air>59c|h@!Go3dX=+b^KD**ty*WhHL!x7BV?)BAy!()F@Bm|UIu#KS$Jon>Qv6FWrJO0i z{l;&uN2Gs@&_Xajh`vnJf->t>C`lKz760y6C~3KP z<~gX(XHpJ|ZAge!kxAK8^aL7%BD(}*s~Q>)m?JQ}3{i<=t!YbQ z>Bbh6rJD(1M?H&wVe0Q3(=0sPnQZleNl zX$8(=7{Kayx||Sg0ML^*_TazT03aRIEdgZNmW}s@9`p~yo9lyeH2&DiLZVZaP`55F z^N+Ux8=I@NcuO{!0 zH!BpRgZyv)j!l7gr`qc9K=6B?$XGESI+Ffp=7R%mCGXHZ2JHh&r__>ALd`R4!0&_x zh&jiILaPmHhM~HbEd7vH5uA_xU6GCZ3bW)&_a*mZS(M7P7_j4RT8BF}^b5t3=YG-t z8pq_#4yk>YEQjbyM`{+|NH#4MQqvx(zTOFtAt*1~7Z0_M1;dozo3-z5-l3EjX&|dV z#h#F&2B5uac#6@%KA>;p1x|{D>a%S8vrM1KcvlQ?^%>SBqowuqnM}d;k!iH96Si{J zUMFn6G+ZZaVV;(h^sj=j-Jywkov;l>WV~j=_G7JN-^mym*}imLKH#`MiLW#e;@qYmbD|vS&XnSzRI?(WwUG9G^+N$&_3Eit@CR~+Gq1U z@IKA8Be$Q;7b$;k?a1`myy+hiSUBsg9hpCyW8jD!YI5z!;@SK?{&InY?%I(pXLA-V z+I^&PHs@4hR$rs$e6N2bmt)gwM_Om|X|Y&qM|PggTY5!SIzFYFj{NPjXjX}By>?{w zEIV1u`qqvtoXsb^1WfU0?2+ZOxf#`X;tX}~UOSSW%@vciDp8o}vwRJ#-OCAS zJxs5G*f*hC(?fF&WbbELc7x}!J%YW7X#x{tk>YQ%cey6d&D!AI%%&3#j1$u5W3CHw z_zQz}Fuj}0NZ3;t?mRXLQB0 z@O@m`2h-cRq<&_)d5{^(lU)JiU#?5JO+(-_O{$Xn5a`;w}W71s2 z2tp-x4)S`8YE3SWpD;O6mP{}?tbLqI1k*|YDmhFlF>~fGosB(T(d9AFx z9_nTDT-D1S!0N?rdb4_Itqah-VJ+$`<#|A>YT+tmXETt&Q)}_oH`k-yE676yfj|8V zJ?Y&WBk%0V-XY{@aY9{3<#O=LtVcl!vY4s4T0$@DP`{uEyD4@$C0dbgTM(*vb)*V= z3e`6ypT@+Gp;Fl{;7ma=Ii4~(3j>@=EFbHADWGP^!FAh`pcBIMt#5gT&{Ec)S#5xp z+?Hs`ZHboLmT0Nd)5B<~>1F7Jmmp4tn>!!BTK;y+t#%e97Oz{eZ*$*EVsQHWZkx$81!p04NWTdGFpiX+fqrg4X zZIxQ0np3>tfM&MOPAa%Ti9`*jA88i_lrScOkx?)GP1D~2MlYd+k(npsDH>^}T0QZ(EsT8L5{F z?5$Ox95#K_u0QdLJ_>=xRJHf@w2!R9ZxY}1_uwn!uD3`l4vgU=Aqw${-V#Ooh58F++D;~mD8+RzYi!9NzlQwJFF z{Bz%YKI%udhQ)@Vj#a2V-flV=QBMDK6gDEBy!&nRZTzCSyw6WnZ5-R=fmk$cvLxCC26~DioAHay*ZZ z`8=sGhPJ1SE&bVHD$@<3aP+TxTw(mXbS}pbTb<5tw300z{$U;W5lC-A)r=Eb#W#NH z>k;@SxO z%KldQpzP<(?^|O-_7_R7vR^76tnJu1*c)YE=YfOz8?wJqeq?QjE3+Kd_VPj5U*`e8 zJ7xBUnya2aGeLUQ_VU5nUOpt8B4+UW%&cOavFYvOXrLj~vph{#PuM?WuwTA=h9`~} zhA-dZX|{S=WxTdlPiJ^?SBr+EJk6BvBnV!z9fiq+IR$x1P=FLd&E6Y&c!Q!R$_&Np zJhiK*S9$7GPcQS-EuU00z`aNj6e7foy-%2s<%5Z=%Lf#o{)wPGFZJv$Za_&CK~J^f zCaNF$^PLIPNEdaE!DyKj@~5dDRxS)Llzlf1;EtqAWHcxqKo8BY_{(;`pp>S>9mPW7~( zr*8Eme@T2sp{!=o;Y9<>iYmsz3S;OPczli9XxHRp6=vnYxVRIo@T43yLsAH zJ$;;~?bXvgJng8S?&WE&db*FNoz>I*JngEU9^h%ddU}wjh3e@co_1GH$9cM;dOE?= zjnxzOZG`zOTe}KLmN&7`_{a6gMld|GKTe80)#GRNxL7^1F;0q`s>jdi@jcZeX9JRA zZ}rF#f}~jDu~_2o@jrOp`C1Tt_z9F8yeoc=uZrEC@EH`Rj`E-`_)WyoW4Kc{29m}1 ze4N1qFe?(r+P#`A39Pr~6ppgMa5*W<#DG5{&t3+dK8na9Pg*S9x)r~!?J~d)AQ^>H zwb*t$Z&_$RAc2Ib6wSUCQ;})L<5A5ot!mJEHdv^K42mp%#P|r(HET6XfGTm@9K;5K zCXa2GLnc9G+bM5hacUT@=jW0+j|HnZQ!pCIVSuwOnqsY@9&WNxx1!v67G`a1e&EwM z&E0Z`Agy7CAhB(tbJVTUFb)TcI7~aB^uhTy$}<{MDXM6GAPn@dwwq$`4VK!wM45sK zx($%U_l%ZZ>5ev(&0g5SGzLtrm>v{saa;00mR=^{)UM%xQ)Wf;+eE4$kQB#W(x`Zn zJ5lW{M{s0!bDbR7(cKxK>irDF zKlm`=it8t>CqD*m(X8UvxXy5eJ?l?{DiaJ5UzxC%>z5?Y<%(RFkhM$67bN`UdY%v> zs)i69uuJ$AG3-wZ*2=!P=jM^9zl-Z6|8Lt9!IXhj0VVLQsH3-BYI$2IA!mz*5*%v? zf+bL5vj`6?But9ZFIU@F1BkccZNTUo6ZUBt_J|*2C4ou>e;XVJaVPtn^Z|`4q%hRb zqBib~t41kju-19=XV>NbxFKICh(&@ku0eP*!9NNWO`;>qwkTxRCg@H3M{`+Q3b_to zwt9Qeh}NWxt(wEa;Tq9?Q(hmS)&8NeK*Jw0k6ml4t>^%19KPdWD!33Esz1yR+=#Ft zV#LfNk;48~9*NA;p@wO@e>?u0`V6aQ+id_F*W!a{2oQRWLG}0{jWT`+uH|Feio{BT z%xoX+6v$hMAJUL}F#CF}$Z|vmz~OGdqSH(c6P&SJW7x&cWUS`bic4Z5B^rDC14&6$_pj{2r#|r;WwCB z4G>+x5kEw?)ma^Lh5B(sj4Z%D}WF{ zwccS`VDUpNV$u+uGU*yTq}L&XhEX(x$qMm9yf_+12$6w59^fBLMf1l~lRqBZSh@{I zL-9j)S^N;fr2x~&495~?w7T0>oh)JGR(+JT(T=7&%u%zD#9U-td%v!hnqbQJsy>*C z0z*IB_%y8-^oin!>>8fpBGFY}G%A|i(zIvJnjHb+0}mQ>Rj%Yl=URv#Qc=FS@#fA6 z#04Kgjg!rkavcyrMsWvlY_fWcQ{1Y~uzFA%GhH^n0h|nfzhT9>b zSrtD7RD*r6_#r|y#Sdv{vYGp!W?#O!Xc+NB#xaX}sX4?C!Jb);Ry&GtfFmMXR>4H# zha|)CLlOyOBz0PjUWnP|VP_)-vB_Ocs<4)q-T#tm4yftL2Vdj*q6{ zFw5s4T0oYylpIFg$>k0^9Svh?oAlzjFB%7;6Vs#|KFaB2ah7hoETmLnrb^}) zDh!6i6#&&~X6iGsJ39d(R!mMCN@vm4F2ojy7=EM`TZBr2xQJaGGBh0~N4nSk3-`nx zQ<9K87E_YVi-(mAQ6-Vux^z?<{)KR`Jdr+1yZmRL6SK^uEneZu9-X@-bY>76?z-G9 z(a-F_S9*Vth_{fuSvHsNQrf?`iqb%hE0*?Z1>4n>CPm(rV0-JDO4Bl}-ZCFjRc}4@ zm9n?aV?(T78uX2p-%aa>lT}YYSLMB$)<73FFD;DQ8`o4C zRo<(ppRyoikc6LU#S5}pxa3j=gf08E5MV77^MUTLD=FS*chlUNM{)MHG5)Fac7{81 zv&K#~E?zL-KWt_Z$NMctG{sAPi%yA6DeI}E7Oa_Ex-5cRdKivynUxIymfn3#YT!ru zrvJ?_MB!->lPb3URH+})5z*UPwvD?*?l|$uUB(@b0=Qe?u8sd>%_QhDE~zzFB!lU3 z$KD*F$250c?l7z24iN{;)+BdQIHR5bUM`T-uZdtwJs}lw()&11aCz84iFwDLg%S|{ z=G)0&TVs8!RDpUohc~4&e33$U|BCg6(ul$Zm#8#YYTBhV2>HvNhNqH{hNHn(JdHh4 zNW)U&RZqh`SV&_#^qQx!VumzU>DN8&%_@x*`x~BisY+wre#6uLq)G#=-i%p|*lJr3 zU{Q>ajRo{>hLDT4OBw85S~Cn ze0wc~C)f^RfrW<;tl%$VEk))J)+5A$wJw1rvo3iq_C8rxpF{;6u2NozGa2^?6ow_Bvz{2Z zfYN$mXaid7iNO!3ttV}v9liBr{t6An^#qCqG}jYI7*L%jsESryOsoufU3IbDk^Yjg z4R1B#mhlRFg8monFG6F*heof0X7_tH%{E|W7v@7|W`(V zrjNaI!EtGhqKvQ{P{X42Nb%06-)p1*R;JFI6N6nwnO_@woHfht>IfFfRD(vpQ=v_0@SlcfLA9HUlZsitVd&#+|Ru zTCtscX~p){Su3`$&RVg3b!H)fGZ|Z*p>JB9rMK_}dX@EfWPyHWWPxUxwq;xDTsJvL zszn=W{4#@qVTd_NV*|Iu3LKX4x3x@?@Tw)ShObJ+O2TWFzykhwNO;{6SiR4Lgl|{^ zOZR6(!W)*rx_vGrylDw6+Mf#vShoNND>mLUt(HHr1eWWkpbKoUith83h~?K-qWgUzV)?bj`2k;?S$=JCe$W?ZmS0<(AM(W+&*Zi^ANR%i zd{~@M3@^@Ku*Lb&u$=vsEY2*(wm7pG+v3b(Y#qX4Y>P9CvGoXxu`SN)p-Wx}i}Q;k zi}OnuppPuh;xL)WVR06hsV85Y#cArv7iV#sdh*3t9H*XqaTeF9CtsY!dFn}vvutMU z2_iVUILinkEY9c6Y~W0@TAW4w+fEQ`57!Pu%4{WM(UY-kuQD&_{|jkX35AEl%7^XCr2I1B zOBT?^@rUjEha}wOz+%xQK}DwaVXYuO%IXE`0_F3@9kn+k5ViT=M#xE&_HAFRF;880V5}G`;GAW$l(3_!^ zNmN%RvKV*TT4Uos;9Ih)Kw79G8E3~6`x>f@&k{iJ@yOHC+&qhxqfBz5B#M#IqIk?w zwCqBgB7Q`3lCpFseV>YjlSIk|=JHObGIa-2r9EMk999EuJrwgpvLxlbnMkYz0${8t z>2CTd3gab;NT2Gf?o1L*MgWi|rziz5Y|vzGW3`SIX4NoocWL-A&lJP}p(7v+n?vY@ z>TvI-FFJqPNV=TlP7V+L=wjy9q`0}M?9`)F>*cam9-sigJobuJ)6Q$ zcM)gpqinLx_TadRn34BqK4eo&Ymnk87%~29z9WjxJdM&uc^MDwd*!^lwZf+2W0PV* zw=&$#E?!D8YQ&ASOTJt}ry1TM|z_LzsggraO z>QJ$&khZ`AoXdznB4hV?0j|(mN3C|q(D^8K@Qy?oXUg&Or0OBRA498EmO}7jmBM63 zF~zcF~=@Js@PwS1c*VG&8 zHS}BAG|lSuVN>}+tVerA1g+giDk+{GlB?4Pys%(8&>TgpHaa??3yvu@MjgRyorEII z+gzOb5N$>S_tCNDBKuc9wc5I*-&6&vrD}O6AGFXSC};*~yd=mNyt2k`XqnJqlg}|y zQCAs|?O`CrTmdBTRAYh~P@U%kJOpH?1X4lH@iz`gptakyK|<(3x0!}EwXpJI;?(kv)*kMn{si3>@Qeip1A@)sQ8Dp_!_<$;HM5`xB3Y=j zwA2Av2+NFoLFzlBInph~q4j_W&_nhy^$qqh9HO5Cby%5%h&8v5u{fC{Wm~*V(|e7V zjkwgo6p)Zp*~hSvkbO+;GWId^!}c*$xzgKcA43%9Ohz$~Th1qTa?W7|`|t1C%pQh0VfHX) z!GdUob7LO+M%^xZn1=M=iep3V*u%g9zXXpYueXzSm3Rd&(!5Wk@S5NT53#7$*jghH zu1R6W?|P;0!hl0(G)=$7`egbojwFQ`*o?P%6qQc0rl23kxquW8K_<6|RPz50GuYB9Bz~&%n7yRt~e@Qk2itb{T z4y_^+VQY^|Mt$4DY+bh15AxW$Yd+t~f|?~l?%}Ran%@ug`o2fVNEhMK#9^3YAHTYK;=7?=K(t`JM_ZXUnnL1Ephh@> zA;u6DibGw<>|bAESGp(PyoY`RpdKo&YfRhJ#{*tznd{^xho=x ztz^N=qAW9PPPm5fxMMl2Pny|$75SF$oGUc;p16`Db=YTpsVB15QH}A@Pf&7j@xyYJ zH)syEwTqpP&775$39JR~x`4GUDqfS{qq@C4j zIck;VQ=--p%E!5?%5Qu5>SxNQAC{xZvi!+I(WDZHGUcu33;JO>nl8(qJ`_zWp<9;U zwXm!zpOeEXf6B|B_VU@_FGn+F`7?(itP+=_EoJ#z4n-IuE=OC-^0yv}ut;2v#HL#R z_YOtkM=5{C%f~CW`bTUi&>@~#j<%KMZ#xtr=U2e!&b5VRcaEX&_{C_*N&9PKL0-*pH{APMtj`SXV&*aLL< zW%+pbm*Sc7cY67|ynH-Fs(eIF%hB$#{N0BlR1VA04Q2T^9ExsG!i{D5Hy(;O(Y_ol zl;tlRiZEYS`MbUR8@&7*y?lgQ%Td29zkev|DQ9hQ9@RhpB;)a zFTd~Q=U)CEFF#|!P%tK&mCPnl%ygH?t$c=R+m}XyMU@cP`4(V;ZAkYhTuNBivgE>%#gnWEL<)l}&Ofc? zOmx34EkcSXG44g$a#ESfO05^)VqMWe)N+Yx?Gg=!RwgV)Q2fflml`ksUaSW!{ukNm zu;J3j;BsSy=3>qB-%1mih;LU-=_6WBY0O>o0NUS5iK6r@saoz(Z$Q{*q54|WAkDU^ zcIgO3PSf!X(e;vicdtyivHX;cgAr~Tr?}>uKqYqIg9ED^j;_s1R zqEgf0QMNg-Gj4=GX=0S>b(QWsM))49QȀf+{_MzT_TN|vBd=A$rn3Qd_wlMTOx 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℘~n&Sf@--S?tdOc{2Gjt9DI)hIJdNRtxfC(A0XdxwE_ zUvcg171u{Ah7gQY%+vyGYge3xitERU>3y}^_ObR|bSR(R_q<#6$iEd#dx>9i>tTL3 zhtv~4p|p;VojUK(;lqdJB8ubq|Lw)R+=IabhE1dgrrOCPOFzGODe%j7Ln1B`sx#3I zJGQLhFLUJbd83q>hbyc_L?(!!MPr>J(j|g(7uGN$V%Ko^!um#}O$2V2wU0=P2+I!Z zA`!`K+KM!YG>D*3XFVmtW)W6}NR3F12y~Hkn1~5@6iJClU<55?{U*X53A#okCIVdo zdPE{3bV!T{6Y%}@q{e-P$zCP}h637e@XT)RNL-|Dhn!W})#VU1UFj%_49UITJ@FAP zYJM?G4O0U`j!}fnB3S6)!*N`tJr=}OpNsJq-{_vSV@qC{*59W;$2vX2A_-d)LfS{t*}CQ9yi=1X_wpAO(4B?bNDipgO`lp zxJvNJ8%GhE;(*mX7q5)OQ-A`qB{~i~_QO+h${u(@_)<4?ZzUgdmW0DG34g2M4E0Y1 z<1@o_ADn!?3a({p1>1egAAaZsYl63YvnGVsdRYN^^~)a!&Sf#x_`*i40cry?C<#1( zv*Gh7oQ;vw{^JOMhOFy~@W{R8?vF$+>0Pg++$X(FNtsVtiG12!N^AJEWxHLRD+-i0 z8PXD;Z}~rxwwW|`T_b~exSli*wr*nh;};{AuZpiCp zdF$+LqkKDUZ=2;?7PXBxxS4A)pDJ(`6#=m}uID|8YGe7~=~G)pc2GXJNm4}RI@ox4 z64!R~W*@>48|leK=sM~GnAvp`WD@P{au>5FoLz*_0h}? zk_5?YigL6JV5iMj)AppkYDJk+*%(^)ur-h~Eom?sJmHm-cl0%0A|+N42w8cgl64qj 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

X(ykiTuJUMCst{Q#;6)dRp9J9)laVF2 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 z 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 M{1htB1b>JB1B!kFr~m)} literal 0 HcmV?d00001 diff --git a/src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm.d.ts b/src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm.d.ts new file mode 100644 index 00000000..cc9a7099 --- /dev/null +++ b/src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm.d.ts @@ -0,0 +1,20 @@ +/* tslint:disable */ +/* eslint-disable */ +export const memory: WebAssembly.Memory; +export function webassembly_encrypt_hybrid_header(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number): void; +export function webassembly_decrypt_hybrid_header(a: number, b: number, c: number, d: number): void; +export function webassembly_encrypt_symmetric_block(a: number, b: number, c: number, d: number): void; +export function webassembly_decrypt_symmetric_block(a: number, b: number, c: number, d: number): void; +export function webassembly_hybrid_encrypt(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number): void; +export function webassembly_hybrid_decrypt(a: number, b: number, c: number, d: number): void; +export function webassembly_policy_axis(a: number, b: number, c: number, d: number, e: number, f: number): void; +export function webassembly_policy(a: number, b: number): void; +export function webassembly_add_axis(a: number, b: number, c: number, d: number, e: number): void; +export function webassembly_rotate_attributes(a: number, b: number, c: number, d: number): void; +export function webassembly_generate_master_keys(a: number, b: number, c: number): void; +export function webassembly_generate_user_secret_key(a: number, b: number, c: number, d: number, e: number, f: number): void; +export function __wbindgen_export_0(a: number, b: number): number; +export function __wbindgen_export_1(a: number, b: number, c: number, d: number): number; +export function __wbindgen_add_to_stack_pointer(a: number): number; +export function __wbindgen_export_2(a: number, b: number, c: number): void; +export function __wbindgen_export_3(a: number): void; diff --git a/tests/errors.test.js b/tests/errors.test.js index 480d6699..867c6368 100644 --- a/tests/errors.test.js +++ b/tests/errors.test.js @@ -9,234 +9,64 @@ import { expect, test } from "vitest" import { randomBytes } from "crypto" test("errors", async () => { - const callbacks = callbacksExamplesInMemory() + const callbacks = await callbacksExamplesInMemory() const toUpsert = [ { indexedValue: Location.fromNumber(42), keywords: ["Answer"] }, ] - const findex = await Findex() + const findex = await Findex.new_with_wasm_backend( + callbacks.entryCallbacks, + callbacks.chainCallbacks, + ) const masterKey = new FindexKey(randomBytes(16)) const label = new Label(randomBytes(32)) - await findex.upsert( - masterKey, - label, - toUpsert, - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(masterKey, label, toUpsert) + + await findex.delete(masterKey, label, toUpsert) + + await findex.add(masterKey, label, toUpsert) // Master key size expect(async () => { - await findex.upsert( - new FindexKey(randomBytes(72)), - label, - toUpsert, - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(new FindexKey(randomBytes(72)), label, toUpsert) }).rejects.toThrow( "While parsing master key for Findex upsert, wrong size when parsing bytes: 72 given should be 16", ) expect(async () => { - await findex.search( - new FindexKey(randomBytes(13)), - label, - "Answer", - callbacks.fetchEntries, - callbacks.fetchChains, - ) + await findex.search(new FindexKey(randomBytes(13)), label, "Answer") }).rejects.toThrow( "While parsing master key for Findex search, wrong size when parsing bytes: 13 given should be 16", ) // toUpsert argument expect(async () => { - await findex.upsert( - masterKey, - label, - undefined, - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(masterKey, label, undefined) }).rejects.toThrow( "During Findex upsert: `additions` should be an array, undefined received", ) - expect(async () => { - await findex.upsert( - masterKey, - label, - [{}], - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) - }).rejects.toThrow( - "During Findex upsert: all the `indexedValue` inside the `additions` array should be of type IndexedValue, Location or Keyword, undefined received (undefined).", - ) - expect(async () => { - await findex.upsert( - masterKey, - label, - [{ indexedValue: Location.fromNumber(42) }], - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) - }).rejects.toThrow( - "During Findex upsert: all the elements inside the `additions` array should have an iterable property `keywords`, undefined received (undefined).", - ) - expect(async () => { - await findex.upsert( - masterKey, - label, - [ - { - indexedValue: Location.fromNumber(42), - keywords: [{ name: "Thibaud" }], - }, - ], - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) - }).rejects.toThrow( - 'During Findex upsert: all the `keywords` inside the `additions` array should be of type `Keyword` or string, object received ({"name":"Thibaud"}).', - ) - // Callbacks are not functions - expect(async () => { - await findex.upsert( - masterKey, - label, - toUpsert, - [], - null, - callbacks.upsertEntries, - callbacks.insertChains, - ) - }).rejects.toThrow( - "During Findex upsert: TypeError: fetchEntries is not a function", - ) expect(async () => { - await findex.upsert( - masterKey, - label, - toUpsert, - [], - [1, 2, 3], - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(masterKey, label, [{}]) }).rejects.toThrow( - "During Findex upsert: TypeError: fetchEntries is not a function", + "During Findex upsert: all the `indexedValue` inside the `additions` array should be of type IndexedValue, Location or Keyword, undefined received (undefined).", ) - // Callbacks return - expect(async () => { - await findex.upsert( - masterKey, - label, - toUpsert, - [], - () => {}, - callbacks.upsertEntries, - callbacks.insertChains, - ) - }).rejects.toThrow( - "During Findex upsert: return value of fetchEntries is of type undefined, array expected", - ) - expect(async () => { - await findex.upsert( - masterKey, - label, - toUpsert, - [], - callbacks.fetchEntries, - () => { - return [undefined] - }, - callbacks.insertChains, - ) - }).rejects.toThrow( - "During Findex upsert: inside array returned by upsertEntries, position 0 contains undefined, object expected.", - ) expect(async () => { - await findex.upsert( - masterKey, - label, - toUpsert, - [], - callbacks.fetchEntries, - () => { - return [{}] - }, - callbacks.insertChains, - ) + await findex.add(masterKey, label, [ + { indexedValue: Location.fromNumber(42) }, + ]) }).rejects.toThrow( - "During Findex upsert: inside array returned by upsertEntries, position 0 contains an object without a `uid` property.", - ) - expect(async () => { - await findex.upsert( - masterKey, - label, - toUpsert, - [], - (uids) => { - return uids.map((uid) => ({ - uid, - value: Uint8Array.from([]), - })) - }, - callbacks.upsertEntries, - callbacks.insertChains, - ) - }).rejects.toThrow( - /During Findex upsert: fail to decrypt one of the `value` returned by the fetch entries callback \(uid was 'Uid\(\[([0-9]+(, )?)+\]\)', value was empty/, - ) - expect(async () => { - await findex.upsert( - masterKey, - label, - toUpsert, - [], - (uids) => { - return uids.map((uid) => ({ - uid, - value: Uint8Array.from([1, 2, 3, 4]), - })) - }, - callbacks.upsertEntries, - callbacks.insertChains, - ) - }).rejects.toThrow( - /During Findex upsert: fail to decrypt one of the `value` returned by the fetch entries callback \(uid was 'Uid\(\[([0-9]+(, )?)+\]\)', value was '\[([0-9]+(, )?)+\]'/, + "During Findex upsert: all the elements inside the `additions` array should have an iterable property `keywords`, undefined received (undefined).", ) expect(async () => { - await findex.upsert( - masterKey, - label, - toUpsert, - [], - (uids) => { - return uids.map((uid) => ({ - uid: uid.slice(0, 12), - value: Uint8Array.from([1, 2, 3, 4]), - })) + await findex.add(masterKey, label, [ + { + indexedValue: Location.fromNumber(42), + keywords: [{ name: "Thibaud" }], }, - callbacks.upsertEntries, - callbacks.insertChains, - ) + ]) }).rejects.toThrow( - /During Findex upsert: cannot parse the `uid` returned by `fetchEntries` at position 0 \(wrong size when parsing bytes: 12 given should be 32\)\. `uid` as hex was '[a-z0-9]+'\./, + 'During Findex upsert: all the `keywords` inside the `additions` array should be of type `Keyword` or string, object received ({"name":"Thibaud"}).', ) }) diff --git a/tests/findex.bench.ts b/tests/findex.bench.ts index ade10b20..15ed8ff0 100644 --- a/tests/findex.bench.ts +++ b/tests/findex.bench.ts @@ -12,20 +12,16 @@ import { bench, describe } from "vitest" import { USERS } from "./data/users" import { randomBytes } from "crypto" -describe("Wasm loading", async () => { - bench("Load Findex functions", async () => { - await Findex() - }) -}) - -const findex = await Findex() +const callbacks = await callbacksExamplesInMemory() +const findex = await Findex.new_with_wasm_backend( + callbacks.entryCallbacks, + callbacks.chainCallbacks, +) const masterKey = new FindexKey(randomBytes(16)) const label = new Label(randomBytes(10)) describe("Findex Upsert", async () => { bench("Upsert 10 users", async () => { - const callbacks = callbacksExamplesInMemory() - const newIndexedEntries: IndexedEntry[] = [] for (const user of USERS.slice(0, 10)) { newIndexedEntries.push({ @@ -37,20 +33,10 @@ describe("Findex Upsert", async () => { }) } - await findex.upsert( - masterKey, - label, - newIndexedEntries, - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(masterKey, label, newIndexedEntries) }) bench("Upsert 99 users", async () => { - const callbacks = callbacksExamplesInMemory() - const newIndexedEntries: IndexedEntry[] = [] for (const user of USERS) { newIndexedEntries.push({ @@ -62,21 +48,11 @@ describe("Findex Upsert", async () => { }) } - await findex.upsert( - masterKey, - label, - newIndexedEntries, - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(masterKey, label, newIndexedEntries) }) }) describe("Findex Search", async () => { - const callbacks = callbacksExamplesInMemory() - const newIndexedEntries: IndexedEntry[] = [] for (const user of USERS) { newIndexedEntries.push({ @@ -88,23 +64,9 @@ describe("Findex Search", async () => { }) } - await findex.upsert( - masterKey, - label, - newIndexedEntries, - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(masterKey, label, newIndexedEntries) bench("Search", async () => { - await findex.search( - masterKey, - label, - new Set([USERS[0].firstName]), - callbacks.fetchEntries, - callbacks.fetchChains, - ) + await findex.search(masterKey, label, new Set([USERS[0].firstName])) }) }) diff --git a/tests/findex.test.ts b/tests/findex.test.ts index 53e915ce..bf987df4 100644 --- a/tests/findex.test.ts +++ b/tests/findex.test.ts @@ -1,326 +1,49 @@ -import { fromByteArray, toByteArray } from "base64-js" +import { toByteArray } from "base64-js" import Database from "better-sqlite3" import { randomBytes } from "crypto" import * as fs from "fs" import * as os from "os" -import { createClient, defineScript } from "redis" +import { WasmToken } from "pkg/findex/cloudproof_findex" import { expect, test } from "vitest" import { - FetchChains, - FetchEntries, - Findex, - FindexCloud, - FindexKey, IndexedEntry, IndexedValue, - InsertChains, + FindexKey, + SearchResults, Keyword, - KeywordIndexEntry, Label, Location, LocationIndexEntry, - ProgressResults, - SearchResults, - UidsAndValues, - UidsAndValuesToUpsert, - UpsertEntries, + KeywordIndexEntry, + generateAliases, callbacksExamplesBetterSqlite3, callbacksExamplesInMemory, - generateAliases, + Findex, + IntermediateSearchResults, + Interrupt, + WasmCallbacks, } from ".." import { USERS } from "./data/users" const FINDEX_TEST_KEY = "6hb1TznoNQFvCWisGWajkA==" const FINDEX_TEST_LABEL = "Some Label" -test( - "Findex Cloud", - async () => { - await runInFindexCloud() - }, - { timeout: 60000 }, -) - -test("in memory", async () => { - const callbacks = callbacksExamplesInMemory() - - await runWithFindexCallbacks( - callbacks.fetchEntries, - callbacks.fetchChains, - callbacks.upsertEntries, - callbacks.insertChains, - ) -}) - -test("SQLite", async () => { - const db = new Database(":memory:") - - const callbacks = callbacksExamplesBetterSqlite3(db) - - await runWithFindexCallbacks( - callbacks.fetchEntries, - callbacks.fetchChains, - callbacks.upsertEntries, - callbacks.insertChains, - ) -}) - -test("Redis", async () => { - let url - if (typeof process.env.REDIS_HOST !== "undefined") { - url = `redis://${process.env.REDIS_HOST}:6379` - } - - const client = createClient({ - url, - scripts: { - setIfSame: defineScript({ - NUMBER_OF_KEYS: 1, - SCRIPT: ` - local value = redis.call('GET', KEYS[1]) - if (((value == false) and (ARGV[1] == "")) or (not(value == false) and (ARGV[1] == value))) - then return redis.call('SET', KEYS[1], ARGV[2]) - else return 'NA' end`, - transformArguments( - key: string, - oldValue: Uint8Array | null, - newValue: Uint8Array, - ): string[] { - return [ - key, - oldValue === null ? "" : fromByteArray(oldValue), - fromByteArray(newValue), - ] - }, - transformReply(reply: string): boolean { - return reply !== "NA" - }, - }), - }, - }) - await client.connect() - - try { - const fetchCallback = async ( - prefix: string, - uids: Uint8Array[], - ): Promise => { - const redisResults = await client.mGet( - uids.map((uid) => `findex.test.ts::${prefix}.${fromByteArray(uid)}`), - ) - - const results: UidsAndValues = [] - uids.forEach((uid, index) => { - if (redisResults[index] !== null) { - results.push({ - uid, - value: Uint8Array.from(toByteArray(redisResults[index] as string)), - }) - } - }) - return results - } - - const upsertCallback = async ( - prefix: string, - uidsAndValues: UidsAndValuesToUpsert, - ): Promise => { - const rejected = [] as UidsAndValues - await Promise.all( - uidsAndValues.map(async ({ uid, oldValue, newValue }) => { - const key = `findex.test.ts::${prefix}.${fromByteArray(uid)}` - - const updated = await client.setIfSame(key, oldValue, newValue) - - if (!updated) { - const valueInRedis = await client.get(key) - rejected.push({ - uid, - value: toByteArray(valueInRedis as string), - }) - } - }), - ) - - return rejected - } - - const insertCallback = async ( - prefix: string, - uidsAndValues: UidsAndValues, - ): Promise => { - if (uidsAndValues.length === 0) return - - const toSet = uidsAndValues.map(({ uid, value }) => [ - `findex.test.ts::${prefix}.${fromByteArray(uid)}`, - fromByteArray(value), - ]) - - await client.mSet(toSet as any) - } - - await runWithFindexCallbacks( - async (uids) => await fetchCallback("entry_table", uids), - async (uids) => await fetchCallback("chain_table", uids), - async (uidsAndValues) => - await upsertCallback("entry_table", uidsAndValues), - async (uidsAndValues) => - await insertCallback("chain_table", uidsAndValues), - ) - } finally { - await client.disconnect() - } -}) - -// eslint-disable-next-line jsdoc/require-jsdoc -async function runWithFindexCallbacks( - fetchEntries: FetchEntries, - fetchChains: FetchChains, - upsertEntries: UpsertEntries, - insertChains: InsertChains, -): Promise { - const findex = await Findex() - const masterKey = new FindexKey(randomBytes(16)) - - await run( - async (label, input) => { - return await findex.search( - masterKey, - label, - input, - fetchEntries, - fetchChains, - ) - }, - async (label, input) => { - return await findex.search( - masterKey, - label, - input, - fetchEntries, - fetchChains, - { - progress: async (progressResults: ProgressResults) => { - const locations = progressResults.getLocations(USERS[0].firstName) - expect(locations.length).toEqual(1) - expect(locations[0].toNumber()).toEqual(USERS[0].id) - return true - }, - }, - ) - }, - async (label, input) => { - return await findex.upsert( - masterKey, - label, - input, - [], - fetchEntries, - upsertEntries, - insertChains, - ) - }, - ) -} - -// eslint-disable-next-line jsdoc/require-jsdoc -async function runInFindexCloud(): Promise { - const baseUrl = `http://${process.env.FINDEX_CLOUD_HOST ?? "127.0.0.1"}:${ - process.env.FINDEX_CLOUD_PORT ?? "8080" - }` - - const response = await fetch(`${baseUrl}/indexes`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: "Test", - }), - }) - - const data = await response.json() - - const { generateNewToken, upsert, search } = await FindexCloud() - - const token = generateNewToken( - data.public_id, - Uint8Array.from(data.fetch_entries_key), - Uint8Array.from(data.fetch_chains_key), - Uint8Array.from(data.upsert_entries_key), - Uint8Array.from(data.insert_chains_key), - ) - - await run( - async (label, input) => { - return await search(token, label, input, { baseUrl }) - }, - async (label, input) => { - return await search(token, label, input, { baseUrl }) - }, - async (label, input) => { - return await upsert(token, label, input, [], { baseUrl }) - }, - ) -} - -test("generateAliases", async () => { - const checkAlias = (alias: IndexedEntry, from: string, to: string): void => { - expect(alias.indexedValue).toEqual( - IndexedValue.fromNextWord(Keyword.fromString(to)), - ) - expect(alias.keywords).toEqual(new Set([Keyword.fromString(from)])) - } - - { - const aliases = generateAliases("Thibaud") - - expect(aliases.length).toEqual(4) - - checkAlias(aliases[0], "Thi", "Thib") - checkAlias(aliases[1], "Thib", "Thiba") - checkAlias(aliases[2], "Thiba", "Thibau") - checkAlias(aliases[3], "Thibau", "Thibaud") - } - - { - const aliases = generateAliases("Thibaud", 5) - - expect(aliases.length).toEqual(2) - - checkAlias(aliases[0], "Thiba", "Thibau") - checkAlias(aliases[1], "Thibau", "Thibaud") - } - - { - const aliases = generateAliases("Thibaud", 3, 5) - - expect(aliases.length).toEqual(3) - - checkAlias(aliases[0], "Thi", "Thib") - checkAlias(aliases[1], "Thib", "Thiba") - checkAlias(aliases[2], "Thiba", "Thibaud") - } -}) - // eslint-disable-next-line jsdoc/require-jsdoc async function run( - search: ( - label: Parameters>["search"]>[1], - input: Parameters>["search"]>[2], - ) => ReturnType>["search"]>, - searchWithProgress: ( - label: Parameters>["search"]>[1], - input: Parameters>["search"]>[2], - ) => ReturnType>["search"]>, - upsert: ( - label: Parameters>["upsert"]>[1], - input: Parameters>["upsert"]>[2], - ) => ReturnType>["upsert"]>, + findex: Findex, + userInterrupt?: Interrupt, + dumpTables?: () => void, + dropTables?: () => Promise, ): Promise { const label = new Label(randomBytes(10)) + const key = new FindexKey(randomBytes(16)) { + console.log( + "test adding ", + USERS.length, + " users and searching for the first one", + ) const newIndexedEntries: IndexedEntry[] = [] for (const user of USERS) { newIndexedEntries.push({ @@ -329,11 +52,20 @@ async function run( }) } - await upsert(label, newIndexedEntries) + await findex.add(key, label, newIndexedEntries) + await findex.add(key, label, newIndexedEntries) - // Test with progress callback + if (dumpTables) { + dumpTables() + } - const results = await searchWithProgress(label, [USERS[0].firstName]) + const results = await findex.search( + key, + label, + [USERS[0].firstName, USERS[0].country], + { userInterrupt: userInterrupt }, + ) + console.log("check returned locations: ", results) const locations = results.get(USERS[0].firstName) @@ -342,9 +74,10 @@ async function run( } { - // Test with multiple results. - - const results = await search(label, ["Spain"]) + console.log("checking results for 'Spain'") + const results = await findex.search(key, label, ["Spain"], { + userInterrupt: userInterrupt, + }) expect( results @@ -359,9 +92,10 @@ async function run( } { - // Test with multiple keywords. - - const results = await search(label, ["Spain", "France"]) + console.log("Test searching for Spain and France.") + const results = await findex.search(key, label, ["Spain", "France"], { + userInterrupt: userInterrupt, + }) expect( results @@ -400,8 +134,8 @@ async function run( } { - // Test upsert an alias to the first user. - await upsert(label, [ + console.log("Test upsert an alias to the first user.") + await findex.add(key, label, [ { indexedValue: Keyword.fromString(USERS[0].firstName), keywords: ["SomeAlias"], @@ -410,7 +144,7 @@ async function run( ]) const searchAndCheck = async (keyword: string): Promise => { - const results = await search(label, [keyword]) + const results = await findex.search(key, label, [keyword]) const locations = results.get(keyword) expect(locations.length).toEqual(1) @@ -425,12 +159,19 @@ async function run( await searchAndCheck("SomeAlia") } + if (dropTables) { + await dropTables() + } + if (dumpTables) { + dumpTables() + } + const sourceIds = Array.from(Array(100).keys()).map((id) => id * id) await Promise.all( // eslint-disable-next-line @typescript-eslint/promise-function-async sourceIds.map((id) => { - return upsert(label, [ + return findex.add(key, label, [ { indexedValue: Location.fromNumber(id), keywords: ["Concurrent"], @@ -440,7 +181,11 @@ async function run( ) { - const results = await search(label, ["Concurrent"]) + const results = await findex.search(key, label, ["Concurrent"]) + + if (dumpTables) { + dumpTables() + } expect(results.total()).toEqual(100) const locations = results.locations() @@ -451,6 +196,100 @@ async function run( } } +//test( +// "Findex Cloud", +// async () => { +// await runInFindexCloud() +// }, +// { timeout: 60000 }, +//) + +test("in memory", async () => { + const callbacks = await callbacksExamplesInMemory() + callbacks.dumpTables() + await runWithFindexCallbacks( + callbacks.entryCallbacks, + callbacks.chainCallbacks, + callbacks.dumpTables, + ) + callbacks.dumpTables() +}) + +test("SQLite", async () => { + const db = new Database(":memory:") + const callbacks = await callbacksExamplesBetterSqlite3(db) + await runWithFindexCallbacks( + callbacks.entryCallbacks, + callbacks.chainCallbacks, + ) +}) + +// eslint-disable-next-line jsdoc/require-jsdoc +async function runWithFindexCallbacks( + entryCallbacks: WasmCallbacks, + chainCallbacks: WasmCallbacks, + dumpTables?: () => void, + dropTables?: () => Promise, +): Promise { + const findex = await Findex.new_with_wasm_backend( + entryCallbacks, + chainCallbacks, + ) + await run( + findex, + async (results: IntermediateSearchResults) => { + try { + const locations = results.getLocations(USERS[0].firstName) + expect(locations.length).toEqual(1) + expect(locations[0].toNumber()).toEqual(USERS[0].id) + return true + } catch { + return false + } + }, + dumpTables, + dropTables, + ) +} + +//// eslint-disable-next-line jsdoc/require-jsdoc +//async function runInFindexCloud(): Promise { +// const baseUrl = `http://${process.env.FINDEX_CLOUD_HOST ?? "127.0.0.1"}:${ +// process.env.FINDEX_CLOUD_PORT ?? "8080" +// }` +// +// let response +// try { +// response = await fetch(`${baseUrl}/indexes`, { +// method: "POST", +// headers: { +// "Content-Type": "application/json", +// }, +// body: JSON.stringify({ +// name: "Test", +// }), +// }) +// } catch (e) { +// if ( +// e instanceof TypeError && +// // @ts-expect-error +// (e.cause.message.includes("ECONNREFUSED") as boolean) +// ) { +// return +// } else { +// throw e +// } +// } +// +// const data = await response.json() +// +// const findex = await Findex.new_with_cloud_backend( +// WasmToken.random(data.public_id), +// baseUrl, +// ) +// await run(findex) +//} + test("generateAliases", async () => { const checkAlias = (alias: IndexedEntry, from: string, to: string): void => { expect(alias.indexedValue).toEqual( @@ -480,13 +319,13 @@ test("generateAliases", async () => { } { - const aliases = generateAliases("Thibaud", 3, 5) + const aliases = generateAliases("Thibaud", 3) - expect(aliases.length).toEqual(3) + expect(aliases.length).toEqual(4) checkAlias(aliases[0], "Thi", "Thib") checkAlias(aliases[1], "Thib", "Thiba") - checkAlias(aliases[2], "Thiba", "Thibaud") + checkAlias(aliases[2], "Thiba", "Thibau") } }) @@ -577,41 +416,34 @@ test("Location conversions", async () => { }) test("upsert and search cycle", async () => { - const findex = await Findex() - const masterKey = new FindexKey(randomBytes(16)) + const { entryCallbacks, chainCallbacks } = await callbacksExamplesInMemory() + const findex = await Findex.new_with_wasm_backend( + entryCallbacks, + chainCallbacks, + ) + const key = new FindexKey(randomBytes(16)) const label = new Label(randomBytes(10)) - const callbacks = callbacksExamplesInMemory() - await findex.upsert( - masterKey, - label, - [ - { - indexedValue: Keyword.fromString("B"), - keywords: ["A"], - }, - { - indexedValue: Keyword.fromString("A"), - keywords: ["B"], - }, - ], - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(key, label, [ + { + indexedValue: Keyword.fromString("B"), + keywords: ["A"], + }, + { + indexedValue: Keyword.fromString("A"), + keywords: ["B"], + }, + ]) - await findex.search( - masterKey, - label, - ["A"], - callbacks.fetchEntries, - callbacks.fetchChains, - ) + await findex.search(key, label, ["A"]) }) test("upsert and search memory", async () => { - const findex = await Findex() + const { entryCallbacks, chainCallbacks } = await callbacksExamplesInMemory() + const findex = await Findex.new_with_wasm_backend( + entryCallbacks, + chainCallbacks, + ) const entryLocation: IndexedEntry = { indexedValue: IndexedValue.fromLocation(Location.fromString("ROBERT file")), @@ -638,66 +470,34 @@ test("upsert and search memory", async () => { const entryKeyword_ = new KeywordIndexEntry("BOB", "ROBERT") expect(entryKeyword_).toEqual(entryKeyword) - const masterKey = new FindexKey(randomBytes(16)) + const key = new FindexKey(randomBytes(16)) const label = new Label("test") - const callbacks = callbacksExamplesInMemory() - await findex.upsert( - masterKey, - label, - [entryLocation, entryKeyword, arrayLocation], - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(key, label, [entryLocation, entryKeyword, arrayLocation]) - const results0 = await findex.search( - masterKey, - label, - new Set(["ROBERT"]), - callbacks.fetchEntries, - callbacks.fetchChains, - ) + const results0 = await findex.search(key, label, new Set(["ROBERT"])) expect(results0.total()).toEqual(2) const results1 = await findex.search( - masterKey, + key, label, new Set([new TextEncoder().encode("ROBERT")]), - callbacks.fetchEntries, - callbacks.fetchChains, ) expect(results1.total()).toEqual(2) - const results2 = await findex.search( - masterKey, - label, - new Set(["BOB"]), - callbacks.fetchEntries, - callbacks.fetchChains, - ) + const results2 = await findex.search(key, label, new Set(["BOB"])) expect(results2.total()).toEqual(2) // Test progress callback - const resultsEarlyStop = await findex.search( - masterKey, - label, - new Set(["BOB"]), - callbacks.fetchEntries, - callbacks.fetchChains, - { - progress: async (progressResults: ProgressResults) => { - expect(progressResults.total()).toEqual(1) - expect(progressResults.getKeywords("BOB")[0].toString()).toEqual( - "ROBERT", - ) - return false - }, + const resultsEarlyStop = await findex.search(key, label, new Set(["BOB"]), { + userInterrupt: async (results: IntermediateSearchResults) => { + expect(results.total()).toEqual(1) + expect(results.getKeywords("BOB")[0].toString()).toEqual("ROBERT") + return true }, - ) + }) expect(resultsEarlyStop.total()).toEqual(0) }) @@ -705,20 +505,20 @@ test("upsert and search memory", async () => { // This database will be checked (search + upsert) in another step of the CI: // cloudproof_java, cloudproof_flutter and cloudproof_python will verify than searching and upserting the database work test("generate non regression database", async () => { - const findex = await Findex() - const masterKey = new FindexKey(toByteArray(FINDEX_TEST_KEY)) - const label = new Label(FINDEX_TEST_LABEL) - const dbFilepath = "node_modules/sqlite.db" if (fs.existsSync(dbFilepath)) { fs.unlinkSync(dbFilepath) } const db = new Database(dbFilepath) - const callbacks = callbacksExamplesBetterSqlite3( - db, - "entry_table", - "chain_table", + const { entryCallbacks, chainCallbacks } = + await callbacksExamplesBetterSqlite3(db, "entry_table", "chain_table") + + const findex = await Findex.new_with_wasm_backend( + entryCallbacks, + chainCallbacks, ) + const masterKey = new FindexKey(toByteArray(FINDEX_TEST_KEY)) + const label = new Label(FINDEX_TEST_LABEL) { const newIndexedEntries: IndexedEntry[] = [] @@ -738,23 +538,9 @@ test("generate non regression database", async () => { }) } - await findex.upsert( - masterKey, - label, - newIndexedEntries, - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(masterKey, label, newIndexedEntries) - const results = await findex.search( - masterKey, - label, - ["France"], - callbacks.fetchEntries, - callbacks.fetchChains, - ) + const results = await findex.search(masterKey, label, ["France"]) const locations = results.get("France") expect(locations.length).toEqual(30) @@ -766,27 +552,24 @@ test("generate non regression database", async () => { * @returns nothing */ async function verify(dbFilepath: string): Promise { - const findex = await Findex() - const masterKey = new FindexKey(toByteArray(FINDEX_TEST_KEY)) - const label = new Label(FINDEX_TEST_LABEL) const db = new Database(dbFilepath) - const callbacks = callbacksExamplesBetterSqlite3( + const callbacks = await callbacksExamplesBetterSqlite3( db, "entry_table", "chain_table", ) + const findex = await Findex.new_with_wasm_backend( + callbacks.entryCallbacks, + callbacks.chainCallbacks, + ) + const key = new FindexKey(toByteArray(FINDEX_TEST_KEY)) + const label = new Label(FINDEX_TEST_LABEL) // // Verifying search results // { - const results = await findex.search( - masterKey, - label, - ["France"], - callbacks.fetchEntries, - callbacks.fetchChains, - ) + const results = await findex.search(key, label, ["France"]) const locations = results.get("France") expect(locations.length).toEqual(30) @@ -822,28 +605,14 @@ async function verify(dbFilepath: string): Promise { ], }) - await findex.upsert( - masterKey, - label, - newIndexedEntries, - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(key, label, newIndexedEntries) } // // Another search // { - const results = await findex.search( - masterKey, - label, - ["France"], - callbacks.fetchEntries, - callbacks.fetchChains, - ) + const results = await findex.search(key, label, ["France"]) const locations = results.get("France") expect(locations.length).toEqual(31) From e98a3493443a79adff2d77303bc13954c76e7901 Mon Sep 17 00:00:00 2001 From: Manuthor <32013169+Manuthor@users.noreply.github.com> Date: Mon, 13 Nov 2023 13:47:17 +0100 Subject: [PATCH 02/10] fix: findex v6 loading trouble (#149) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: wasm error fix: `in_memory` backend fix: WASM sqlite backend fix: formatting * chore: remove cc wasm file --------- Co-authored-by: Théophile BRÉZOT --- examples/full_text_search/index.mjs | 66 +- examples/nodejs_search_imdb/index.mjs | 37 +- examples/reactjs/src/App.tsx | 86 +- examples/vuejs/src/App.vue | 85 +- scripts/download_wasm.py | 56 +- src/anonymization/init.ts | 2 + src/findex/callbacks.ts | 62 ++ src/findex/findex.ts | 172 ++-- src/findex/in_memory.ts | 30 +- src/findex/init.ts | 38 +- src/findex/server_token.ts | 23 + src/findex/sqlite.ts | 19 +- src/index.ts | 3 + src/pkg/anonymization/.gitignore | 6 +- src/pkg/cover_crypt/.gitkeep | 0 .../cover_crypt/cloudproof_cover_crypt.d.ts | 171 ---- src/pkg/cover_crypt/cloudproof_cover_crypt.js | 750 ------------------ .../cloudproof_cover_crypt_bg.wasm | Bin 468243 -> 0 bytes .../cloudproof_cover_crypt_bg.wasm.d.ts | 20 - tests/errors.test.js | 17 +- tests/findex.bench.ts | 8 +- tests/findex.test.ts | 240 +++--- 22 files changed, 547 insertions(+), 1344 deletions(-) create mode 100644 src/findex/callbacks.ts create mode 100644 src/findex/server_token.ts create mode 100644 src/pkg/cover_crypt/.gitkeep delete mode 100644 src/pkg/cover_crypt/cloudproof_cover_crypt.d.ts delete mode 100644 src/pkg/cover_crypt/cloudproof_cover_crypt.js delete mode 100644 src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm delete mode 100644 src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm.d.ts diff --git a/examples/full_text_search/index.mjs b/examples/full_text_search/index.mjs index 5ce15097..242a8073 100755 --- a/examples/full_text_search/index.mjs +++ b/examples/full_text_search/index.mjs @@ -1,13 +1,6 @@ import fs from "fs" import readline from "readline" -import { - Location, - Findex, - FindexKey, - Label, - callbacksExamplesBetterSqlite3, - Keyword, -} from "cloudproof_js" +import { Location, Findex, FindexKey, Label, Keyword } from "cloudproof_js" import path from "path" import { fileURLToPath } from "url" import { randomBytes } from "crypto" @@ -31,12 +24,17 @@ for (const file of files) { } // Init Findex with random key and random label -const { upsert, search } = await Findex() -const masterKey = new FindexKey(randomBytes(16)) +const { callbacksExamplesBetterSqlite3, FindexWithWasmBackend } = await Findex() +const findexKey = new FindexKey(randomBytes(16)) const label = new Label(randomBytes(10)) const db = new Database(":memory:") -const callbacks = callbacksExamplesBetterSqlite3(db) +const callbacks = await callbacksExamplesBetterSqlite3(db) +const findex = new FindexWithWasmBackend() +await findex.createWithWasmBackend( + callbacks.entryCallbacks, + callbacks.chainCallbacks, +) const uniqueWords = new Set() @@ -83,22 +81,14 @@ for (const [name, content] of Object.entries(contents)) { } } - await upsert( - masterKey, - label, - toUpsert, - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(findexKey, label, toUpsert) } console.log("---") console.log(`Add aliases from word's stem to word…`) console.log("---") -await upsert( - masterKey, +await findex.add( + findexKey, label, Array.from(uniqueWords) .map((word) => ({ word, stem: natural.PorterStemmer.stem(word) })) @@ -107,10 +97,6 @@ await upsert( indexedValue: Keyword.fromString(word), keywords: [stem], })), - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, ) console.log("---") @@ -119,24 +105,20 @@ console.log("---") // Since phonetic is not a correct word (for example the phonetic for "Phrase" is "FRS") // we don't want a search for "FRS" to return "Phrase". To prevent that, we'll add a prefix to "FRS" // which will make searching for it highly unlikely. We'll use this prefix in our search below. -await upsert( - masterKey, +await findex.add( + findexKey, label, Array.from(uniqueWords).map((word) => ({ indexedValue: Keyword.fromString(word), keywords: ["phonetic_prefix_" + natural.Metaphone.process(word)], })), - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, ) console.log("---") console.log(`Add aliases from word's synonyms to word…`) console.log("---") -await upsert( - masterKey, +await findex.add( + findexKey, label, Array.from(uniqueWords) .map((word) => { @@ -151,10 +133,6 @@ await upsert( } }) .filter((synonymsToUpsert) => synonymsToUpsert !== null), - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, ) const rl = readline.createInterface({ @@ -171,13 +149,11 @@ while (true) { const stem = natural.PorterStemmer.stem(query) const phonetic = natural.Metaphone.process(query) - const rawResults = await search( - masterKey, - label, - [query, stem, "phonetic_prefix_" + phonetic], - callbacks.fetchEntries, - callbacks.fetchChains, - ) + const rawResults = await findex.search(findexKey, label, [ + query, + stem, + "phonetic_prefix_" + phonetic, + ]) console.log( `Searching for ${query} (${stem}, ${phonetic}), ${rawResults.total()} results.`, diff --git a/examples/nodejs_search_imdb/index.mjs b/examples/nodejs_search_imdb/index.mjs index 26baed49..23d84f55 100755 --- a/examples/nodejs_search_imdb/index.mjs +++ b/examples/nodejs_search_imdb/index.mjs @@ -1,12 +1,6 @@ import fs from "fs" import readline from "readline" -import { - Location, - Findex, - FindexKey, - Label, - callbacksExamplesBetterSqlite3, -} from "cloudproof_js" +import { Location, Findex, FindexKey, Label } from "cloudproof_js" import path from "path" import { fileURLToPath } from "url" import { randomBytes } from "crypto" @@ -37,12 +31,17 @@ if (!fs.existsSync(dataFilename)) { const input = fs.createReadStream(dataFilename) // Init Findex with random key and random label -const { upsert, search } = await Findex() -const masterKey = new FindexKey(randomBytes(16)) +const { callbacksExamplesBetterSqlite3, FindexWithWasmBackend } = await Findex() +const findexKey = new FindexKey(randomBytes(16)) const label = new Label(randomBytes(10)) const db = new Database(":memory:") -const callbacks = callbacksExamplesBetterSqlite3(db) +const callbacks = await callbacksExamplesBetterSqlite3(db) +const findex = new FindexWithWasmBackend() +await findex.createWithWasmBackend( + callbacks.entryCallbacks, + callbacks.chainCallbacks, +) // Number of movies to index in a single `upsert` call let numberOfMoviesIndexedSoFar = 0 @@ -89,15 +88,7 @@ for await (const line of readline.createInterface({ input })) { } if (toUpsert.length >= MAX_UPSERT_LINES || end) { - await upsert( - masterKey, - label, - toUpsert, - [], - callbacks.fetchEntries, - callbacks.upsertEntries, - callbacks.insertChains, - ) + await findex.add(findexKey, label, toUpsert) toUpsert = [] @@ -120,13 +111,7 @@ process.stdout.write("Search for: ") for await (const query of queries) { console.log(query) - const results = await search( - masterKey, - label, - [query], - callbacks.fetchEntries, - callbacks.fetchChains, - ) + const results = await findex.search(findexKey, label, [query]) console.log(`Searching for ${query} returned ${results.total()} results:`) for (const result of results) { diff --git a/examples/reactjs/src/App.tsx b/examples/reactjs/src/App.tsx index a39aa392..983a8288 100644 --- a/examples/reactjs/src/App.tsx +++ b/examples/reactjs/src/App.tsx @@ -6,9 +6,9 @@ import { Label, Location, PolicyKms, - UidsAndValuesToUpsert, - generateAliases, type UidsAndValues, + generateAliases, + Callbacks, } from "cloudproof_js" import { FormEvent, useEffect, useState } from "react" @@ -29,7 +29,7 @@ const FINDEX_LABEL = new Label(Uint8Array.from([1, 2, 3])) type NewUser = { first: string last: string - country: typeof COUNTRIES[0] + country: (typeof COUNTRIES)[0] email: string project: string } @@ -409,9 +409,21 @@ function App() { localMasterKey: Exclude, users: User[], ) => { - const { upsert } = await Findex() - - await upsert( + let { FindexWithWasmBackend } = await Findex() + const findex = new FindexWithWasmBackend() + const entriesCallbacks = new Callbacks() + entriesCallbacks.fetch = async (uids) => + await fetchCallback("entries", uids) + entriesCallbacks.upsert = async ( + oldValues: UidsAndValues, + newValues: UidsAndValues, + ) => await upsertCallback("entries", oldValues, newValues) + const chainsCallbacks = new Callbacks() + chainsCallbacks.insert = async (uidsAndValues) => + await insertCallback("chains", uidsAndValues) + await findex.createWithWasmBackend(entriesCallbacks, chainsCallbacks) + + await findex.add( localMasterKey, FINDEX_LABEL, users.flatMap((user) => { @@ -436,10 +448,6 @@ function App() { : []), ] }), - [], - async (uids) => await fetchCallback("entries", uids), - async (uidsAndValues) => await upsertCallback("entries", uidsAndValues), - async (uidsAndValues) => await insertCallback("chains", uidsAndValues), ) } @@ -515,23 +523,28 @@ function App() { const upsertCallback = async ( table: "entries" | "chains", - uidsAndValues: UidsAndValuesToUpsert, + oldValues: UidsAndValues, + newValues: UidsAndValues, ): Promise => { const rejected = [] - uidsAndValuesLoop: for (const { - uid: newUid, - oldValue, - newValue, - } of uidsAndValues) { + + // Add old values in a map to efficiently search for matching UIDs. + const mapOfOldValues = new Map() + for (const { uid, value } of oldValues) { + mapOfOldValues.set(uid.toString(), value) + } + + uidsAndValuesLoop: for (const { uid, value } of newValues) { for (const tableEntry of table === "entries" ? indexesEntries : indexesChains) { - if (uint8ArrayEquals(tableEntry.uid, newUid)) { + if (uint8ArrayEquals(tableEntry.uid, uid)) { + const oldValue = mapOfOldValues.get(uid.toString()) if ( oldValue !== null && uint8ArrayEquals(tableEntry.value, oldValue) ) { - tableEntry.value = newValue + tableEntry.value = value } else { rejected.push(tableEntry) } @@ -542,18 +555,12 @@ function App() { logRequest({ method: "POST", url: `/index_${table}`, - body: { uid: newUid, value: newValue }, + body: { uid: uid, value: value }, }) if (table === "entries") { - setIndexesEntries((entries) => [ - ...entries, - { uid: newUid, value: newValue }, - ]) + setIndexesEntries((entries) => [...entries, { uid: uid, value: value }]) } else { - setIndexesChains((chains) => [ - ...chains, - { uid: newUid, value: newValue }, - ]) + setIndexesChains((chains) => [...chains, { uid: uid, value: value }]) } } return rejected @@ -625,8 +632,15 @@ function App() { if (!selectedKey) return [] if (!masterKey) throw new Error("No Findex key") - const { search } = await Findex() + let { FindexWithWasmBackend } = await Findex() + const findex = new FindexWithWasmBackend() + const entriesCallbacks = new Callbacks() + entriesCallbacks.fetch = async (uids) => + await fetchCallback("entries", uids) + const chainsCallbacks = new Callbacks() + chainsCallbacks.fetch = async (uids) => await fetchCallback("chains", uids) + await findex.createWithWasmBackend(entriesCallbacks, chainsCallbacks) const decrypter = (await getEncryptorAndDecrypter()).decrypt const savedQuery = query @@ -640,24 +654,12 @@ function App() { let locations: Array | null = null if (doOr) { locations = ( - await search( - masterKey, - FINDEX_LABEL, - new Set(keywords), - async (uids) => await fetchCallback("entries", uids), - async (uids) => await fetchCallback("chains", uids), - ) + await findex.search(masterKey, FINDEX_LABEL, new Set(keywords)) ).locations() } else { for (const keyword of keywords) { const newLocations = ( - await search( - masterKey, - FINDEX_LABEL, - new Set([keyword]), - async (uids) => await fetchCallback("entries", uids), - async (uids) => await fetchCallback("chains", uids), - ) + await findex.search(masterKey, FINDEX_LABEL, new Set([keyword])) ).locations() if (locations === null) { diff --git a/examples/vuejs/src/App.vue b/examples/vuejs/src/App.vue index ba0e540d..08d1d911 100644 --- a/examples/vuejs/src/App.vue +++ b/examples/vuejs/src/App.vue @@ -3,13 +3,13 @@ import { CoverCrypt, Findex, FindexKey, - type UidsAndValues, Label, Location, KmsClient, - type UidsAndValuesToUpsert, + type UidsAndValues, generateAliases, PolicyKms, + Callbacks, } from "cloudproof_js" import { defineComponent } from "vue" import Key from "./Key.vue" @@ -32,7 +32,7 @@ const FINDEX_LABEL = new Label(Uint8Array.from([1, 2, 3])) type NewUser = { first: string last: string - country: typeof COUNTRIES[0] + country: (typeof COUNTRIES)[0] email: string project: string } @@ -370,9 +370,21 @@ export default defineComponent({ masterKey: Exclude, users: User[], ) { - let { upsert } = await Findex() - - await upsert( + let { FindexWithWasmBackend } = await Findex() + const findex = new FindexWithWasmBackend() + const entriesCallbacks = new Callbacks() + entriesCallbacks.fetch = async (uids) => + await this.fetchCallback("entries", uids) + entriesCallbacks.upsert = async ( + oldValues: UidsAndValues, + newValues: UidsAndValues, + ) => await this.upsertCallback("entries", oldValues, newValues) + const chainsCallbacks = new Callbacks() + chainsCallbacks.insert = async (uidsAndValues) => + await this.insertCallback("chains", uidsAndValues) + await findex.createWithWasmBackend(entriesCallbacks, chainsCallbacks) + + await findex.add( masterKey, FINDEX_LABEL, this.users.flatMap((user, index) => { @@ -397,12 +409,6 @@ export default defineComponent({ : []), ] }), - [], - async (uids) => await this.fetchCallback("entries", uids), - async (uidsAndValues) => - await this.upsertCallback("entries", uidsAndValues), - async (uidsAndValues) => - await this.insertCallback("chains", uidsAndValues), ) }, @@ -464,21 +470,27 @@ export default defineComponent({ async upsertCallback( table: "entries" | "chains", - uidsAndValues: UidsAndValuesToUpsert, + oldValues: UidsAndValues, + newValues: UidsAndValues, ): Promise { const rejected = [] - uidsAndValuesLoop: for (const { - uid: newUid, - oldValue, - newValue, - } of uidsAndValues) { + + // Add old values in a map to efficiently search for matching UIDs. + const mapOfOldValues = new Map() + for (const { uid, value } of oldValues) { + mapOfOldValues.set(uid.toString(), value) + } + + uidsAndValuesLoop: for (const { uid, value } of newValues) { for (const tableEntry of this.indexes[table]) { - if (this.uint8ArrayEquals(tableEntry.uid, newUid)) { + if (this.uint8ArrayEquals(tableEntry.uid, uid)) { + const oldValue = mapOfOldValues.get(uid.toString()) + if ( oldValue !== null && this.uint8ArrayEquals(tableEntry.value, oldValue) ) { - tableEntry.value = newValue + tableEntry.value = value } else { rejected.push(tableEntry) } @@ -490,17 +502,28 @@ export default defineComponent({ this.logRequest({ method: "POST", url: `/index_${table}`, - body: { uid: newUid, value: newValue }, + body: { uid: uid, value: value }, }) - this.indexes[table].push({ uid: newUid, value: newValue }) + this.indexes[table].push({ uid: uid, value: value }) } + return rejected }, async search() { if (!this.query || !this.selectedKey) return [] - let { search } = await Findex() + let { FindexWithWasmBackend } = await Findex() + const findex = new FindexWithWasmBackend() + const entriesCallbacks = new Callbacks() + entriesCallbacks.fetch = async (uids) => + await this.fetchCallback("entries", uids) + const chainsCallbacks = new Callbacks() + chainsCallbacks.fetch = async (uids) => + await this.fetchCallback("chains", uids) + + await findex.createWithWasmBackend(entriesCallbacks, chainsCallbacks) + const decrypter = (await this.getEncryptorAndDecrypter()).decrypt if (!this.masterKey) throw "No Findex key" @@ -516,24 +539,12 @@ export default defineComponent({ let locations: Array | null = null if (this.doOr) { locations = ( - await search( - this.masterKey, - FINDEX_LABEL, - keywords, - async (uids) => await this.fetchCallback("entries", uids), - async (uids) => await this.fetchCallback("chains", uids), - ) + await findex.search(this.masterKey, FINDEX_LABEL, keywords) ).locations() } else { for (const keyword of keywords) { const newLocations = ( - await search( - this.masterKey, - FINDEX_LABEL, - [keyword], - async (uids) => await this.fetchCallback("entries", uids), - async (uids) => await this.fetchCallback("chains", uids), - ) + await findex.search(this.masterKey, FINDEX_LABEL, [keyword]) ).locations() if (locations === null) { diff --git a/scripts/download_wasm.py b/scripts/download_wasm.py index 35de2e44..187073a6 100644 --- a/scripts/download_wasm.py +++ b/scripts/download_wasm.py @@ -8,27 +8,27 @@ def files_to_be_copied(name: str): """List of files to be copied""" - source_dir = f'tmp/wasm32-unknown-unknown/{name}' + source_dir = f"tmp/wasm32-unknown-unknown/{name}" return { - f'{source_dir}/cloudproof_{name}.d.ts': f'src/pkg/{name}/cloudproof_{name}.d.ts', - f'{source_dir}/cloudproof_{name}_bg.wasm': f'src/pkg/{name}/cloudproof_{name}_bg.wasm', - f'{source_dir}/cloudproof_{name}.js': f'src/pkg/{name}/cloudproof_{name}.js', - f'{source_dir}/cloudproof_{name}_bg.wasm.d.ts': f'src/pkg/{name}/cloudproof_{name}_bg.wasm.d.ts', + f"{source_dir}/cloudproof_{name}.d.ts": f"src/pkg/{name}/cloudproof_{name}.d.ts", + f"{source_dir}/cloudproof_{name}_bg.wasm": f"src/pkg/{name}/cloudproof_{name}_bg.wasm", + f"{source_dir}/cloudproof_{name}.js": f"src/pkg/{name}/cloudproof_{name}.js", + f"{source_dir}/cloudproof_{name}_bg.wasm.d.ts": f"src/pkg/{name}/cloudproof_{name}_bg.wasm.d.ts", } def download_wasm(version: str) -> bool: """Download and extract wasm""" - print(f'Download WASM {version}') + print(f"Download WASM {version}") ssl._create_default_https_context = ssl._create_unverified_context - to_be_copied = files_to_be_copied('aesgcm') - to_be_copied.update(files_to_be_copied('anonymization')) - to_be_copied.update(files_to_be_copied('cover_crypt')) - to_be_copied.update(files_to_be_copied('fpe')) - to_be_copied.update(files_to_be_copied('findex')) - to_be_copied.update(files_to_be_copied('ecies')) + to_be_copied = files_to_be_copied("aesgcm") + to_be_copied.update(files_to_be_copied("anonymization")) + to_be_copied.update(files_to_be_copied("cover_crypt")) + to_be_copied.update(files_to_be_copied("fpe")) + to_be_copied.update(files_to_be_copied("findex")) + to_be_copied.update(files_to_be_copied("ecies")) missing_files = False for key, value in to_be_copied.items(): @@ -37,38 +37,36 @@ def download_wasm(version: str) -> bool: break if not missing_files: - print('Files are present, skip.') + print("Files are present, skip.") return True - url = f'https://package.cosmian.com/cloudproof_rust/{version}/wasm.zip' + url = f"https://package.cosmian.com/cloudproof_rust/{version}/wasm.zip" try: response = urllib.request.urlopen(url) if response.getcode() != 200: - print( - f'Cannot get cloudproof_rust {version} ({response.getcode()})' - ) + print(f"Cannot get cloudproof_rust {version} ({response.getcode()})") else: - print(f'Copying new files from cloudproof_rust {version}') - if path.exists('tmp'): - shutil.rmtree('tmp') - if path.exists('wasm.zip'): - remove('wasm.zip') + print(f"Copying new files from cloudproof_rust {version}") + if path.exists("tmp"): + shutil.rmtree("tmp") + if path.exists("wasm.zip"): + remove("wasm.zip") - open('wasm.zip', 'wb').write(response.read()) - with zipfile.ZipFile('wasm.zip', 'r') as zip_ref: - zip_ref.extractall('tmp') + open("wasm.zip", "wb").write(response.read()) + with zipfile.ZipFile("wasm.zip", "r") as zip_ref: + zip_ref.extractall("tmp") for key, value in to_be_copied.items(): - print(f'OK: copy {key} to {value}...') + print(f"OK: copy {key} to {value}...") shutil.copyfile(key, value) - shutil.rmtree('tmp') - remove('wasm.zip') + shutil.rmtree("tmp") + remove("wasm.zip") return True # pylint: disable=broad-except except Exception as exception: - print(f'Cannot get cloudproof_rust {version} ({exception})') + print(f"Cannot get cloudproof_rust {version} ({exception})") return False diff --git a/src/anonymization/init.ts b/src/anonymization/init.ts index a5381c67..4c933b33 100644 --- a/src/anonymization/init.ts +++ b/src/anonymization/init.ts @@ -1,4 +1,5 @@ import init from "../pkg/anonymization/cloudproof_anonymization" + import { Hasher } from "./hash" import { NoiseWithBounds, NoiseWithParameters } from "./noise" import { NumberAggregator, NumberScaler, DateAggregator } from "./number" @@ -13,6 +14,7 @@ export const setAnonymizationInit = (arg: () => any): void => { /** * This is the main function for reusing webassembly code + * @returns initialized objects */ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type export async function Anonymization() { diff --git a/src/findex/callbacks.ts b/src/findex/callbacks.ts new file mode 100644 index 00000000..15cd6f1c --- /dev/null +++ b/src/findex/callbacks.ts @@ -0,0 +1,62 @@ +import { WasmCallbacks as WebAssemblyCallbacks } from "../pkg/findex/cloudproof_findex" +import { UidsAndValues } from "./types" + +export class Callbacks { + private readonly _callbacks: WebAssemblyCallbacks + + constructor() { + this._callbacks = new WebAssemblyCallbacks() + } + + public get delete(): (uids: Uint8Array[]) => Promise | undefined { + return this._callbacks.delete + } + + public set delete( + callback: (uids: Uint8Array[]) => Promise | undefined, + ) { + this._callbacks.delete = callback + } + + public get fetch(): ( + uids: Uint8Array[], + ) => Promise> | undefined { + return this._callbacks.fetch + } + + public set fetch( + callback: ( + uids: Uint8Array[], + ) => Promise> | undefined, + ) { + this._callbacks.fetch = callback + } + + public get upsert(): ( + oldValues: UidsAndValues, + newValues: UidsAndValues, + ) => Promise | undefined { + return this._callbacks.upsert + } + + public set upsert( + callback: ( + oldValues: UidsAndValues, + newValues: UidsAndValues, + ) => Promise | undefined, + ) { + this._callbacks.upsert = callback + } + + public get insert(): ( + uidsAndValues: UidsAndValues, + ) => Promise | undefined { + return this._callbacks.insert + } + + public set insert( + callback: (uidsAndValues: UidsAndValues) => Promise | undefined, + ) { + this._callbacks.insert = callback + } +} diff --git a/src/findex/findex.ts b/src/findex/findex.ts index edb51fb3..043e23a2 100644 --- a/src/findex/findex.ts +++ b/src/findex/findex.ts @@ -1,58 +1,87 @@ +// /* eslint-disable */ + +// TODO: rename masterKey to FindexKey + +import { SymmetricKey } from "cloudproof_kms_js" +import { + WasmCallbacks, + WasmFindex, + webassembly_logger_init, +} from "../pkg/findex/cloudproof_findex" +import { Callbacks } from "./callbacks" + import { FindexKey, - indexedEntriesToBytes, IndexedEntry, + IntermediateSearchResults, + Interrupt, Keyword, Label, SearchResults, + indexedEntriesToBytes, } from "./types" -import { - WasmCallbacks, - WasmFindex, - webassembly_logger_init, -} from "../pkg/findex/cloudproof_findex" -import { IntermediateSearchResults, Interrupt } from "./types" -import { loadWasm } from "./init" -import { SymmetricKey } from "cloudproof_kms_js" - -let loggerInit = false -/** - * Findex definition - * @returns {Promise} results found at every node while the search walks the search graph - */ -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -export class Findex { - readonly wasmFindex: WasmFindex - - private constructor(wasm_findex: WasmFindex) { - this.wasmFindex = wasm_findex - } +export interface InstantiatedFindex { + /** + * Add the given values to this Findex index for the corresponding + * keywords. + * @param {Uint8Array} key + * @param {Uint8Array} label + * @param {Array<{indexedValue: Uint8Array, keywords: Array}>} additions + * @returns {Promise>} + */ + add: ( + key: Uint8Array, + label: Uint8Array, + additions: Array<{ indexedValue: Uint8Array; keywords: Uint8Array[] }>, + ) => Promise /** - * Instantiates a Findex instance usin the given callbacks. + * Remove the given values from this Findex index for the corresponding + * keywords. + * @param {Uint8Array} key + * @param {Uint8Array} label + * @param {Array<{indexedValue: Uint8Array, keywords: Array}>} deletions + * @returns {Promise>} */ - static async new_with_wasm_backend( - entry_callbacks: WasmCallbacks, - chain_callbacks: WasmCallbacks, - ) { - await loadWasm() - return new Findex( - await WasmFindex.new_with_wasm_backend(entry_callbacks, chain_callbacks), - ) - } + delete: ( + key: Uint8Array, + label: Uint8Array, + deletions: Array<{ indexedValue: Uint8Array; keywords: Uint8Array[] }>, + ) => Promise /** - * Instantiates a Findex instance using the token and URL. + * Searches this Findex instance for the given keywords. + * + * The interrupt is called at each search graph level with the level's + * results and allows interrupting the search. + * @param {Uint8Array} key + * @param {Uint8Array} label + * @param {Array} keywords + * @param {Function} interrupt + * @returns {Promise }>>} */ - static async new_with_cloud_backend(token: string, url: string) { - await loadWasm() - return new Findex(await WasmFindex.new_with_rest_backend(token, url)) + search: ( + key: Uint8Array, + label: Uint8Array, + keywords: Uint8Array[], + interrupt: Function, + ) => Promise> +} + +/** + * Findex definition + * @returns {Promise} results found at every node while the search walks the search graph + */ +export class FindexBase { + _instantiatedFindex: InstantiatedFindex + + constructor(instantiatedFindex: InstantiatedFindex) { + this._instantiatedFindex = instantiatedFindex } /** * Add the following entries in the index. - * * @param {FindexKey | SymmetricKey} masterKey Findex's key * @param {Label} label public label for the index * @param {IndexedEntry[]} additions new entries to upsert in indexes @@ -60,15 +89,14 @@ export class Findex { * @param options.verbose the optional verbose bool parameter * @returns {Keyword[]} the list of the newly inserted keywords in the index */ - async add( + public async add( masterKey: FindexKey | SymmetricKey | Uint8Array, label: Label | Uint8Array, additions: IndexedEntry[], options: { verbose?: false } = {}, ): Promise { - if (options.verbose === undefined && !loggerInit) { + if (options.verbose !== undefined && options.verbose) { await webassembly_logger_init() - loggerInit = true } if (masterKey instanceof SymmetricKey) { @@ -84,7 +112,7 @@ export class Findex { const additionsBytes = indexedEntriesToBytes(additions, "additions") - const newIds: Uint8Array[] = await this.wasmFindex.add( + const newIds: Uint8Array[] = await this._instantiatedFindex.add( masterKey.bytes, label.bytes, additionsBytes, @@ -95,7 +123,6 @@ export class Findex { /** * Delete the following entries from the index. - * * @param {FindexKey | SymmetricKey} masterKey Findex's key * @param {Label} label public label for the index * @param {IndexedEntry[]} deletions new entries to upsert in indexes @@ -109,9 +136,8 @@ export class Findex { deletions: IndexedEntry[], options: { verbose?: false } = {}, ): Promise { - if (options.verbose === undefined && !loggerInit) { + if (options.verbose !== undefined && options.verbose) { await webassembly_logger_init() - loggerInit = true } if (masterKey instanceof SymmetricKey) { @@ -127,7 +153,7 @@ export class Findex { const deletionBytes = indexedEntriesToBytes(deletions, "deletions") - const newIds: Uint8Array[] = await this.wasmFindex.delete( + const newIds: Uint8Array[] = await this._instantiatedFindex.delete( masterKey.bytes, label.bytes, deletionBytes, @@ -154,9 +180,8 @@ export class Findex { verbose?: false } = {}, ): Promise { - if (options.verbose === undefined && !loggerInit) { + if (options.verbose !== undefined && options.verbose) { await webassembly_logger_init() - loggerInit = true } // convert key to a single representation @@ -183,10 +208,10 @@ export class Findex { // Never interrupt the search if no interrupt function is passed. const userInterrupt: Interrupt = typeof options.userInterrupt === "undefined" - ? async (_) => false + ? async () => false : options.userInterrupt - const resultsPerKeywords = await this.wasmFindex.search( + const resultsPerKeywords = await this._instantiatedFindex.search( masterKey.bytes, label.bytes, kws, @@ -205,3 +230,52 @@ export class Findex { return new SearchResults(resultsPerKeywords) } } + +export class FindexWithWasmBackend extends FindexBase { + constructor() { + super(new WasmFindex()) // TODO: revisit this impl'. + } + + public async createWithWasmBackend( + entriesCallbacks: Callbacks, + chainsCallbacks: Callbacks, + ): Promise { + const entries = new WasmCallbacks() + entries.delete = entriesCallbacks.delete + entries.fetch = entriesCallbacks.fetch + entries.insert = entriesCallbacks.insert + entries.upsert = entriesCallbacks.upsert + + const chains = new WasmCallbacks() + chains.delete = chainsCallbacks.delete + chains.fetch = chainsCallbacks.fetch + chains.insert = chainsCallbacks.insert + chains.upsert = chainsCallbacks.upsert + + this._instantiatedFindex = await WasmFindex.new_with_wasm_backend( + entries, + chains, + ) + } +} + +export class FindexWithCloudBackend extends FindexBase { + // TODO: rename to rest + constructor() { + super(new WasmFindex()) + } + + /** + * Instantiates a Findex instance using the token and URL. + * @param token findex server authorization token + * @param url findex server + * @returns initialized object + */ + public async createWithCloudBackend( + token: string, + url: string, + ): Promise { + const findex = await WasmFindex.new_with_rest_backend(token, url) + this._instantiatedFindex = findex + } +} diff --git a/src/findex/in_memory.ts b/src/findex/in_memory.ts index fe8daa8a..2176830c 100644 --- a/src/findex/in_memory.ts +++ b/src/findex/in_memory.ts @@ -1,12 +1,13 @@ -import { WasmCallbacks } from "../pkg/findex/cloudproof_findex" -import { loadWasm, UidsAndValues } from "./init" +import { logger } from "utils/logger" +import { Callbacks } from "./callbacks" +import { UidsAndValues } from "./types" /** * @returns the callbacks */ export async function callbacksExamplesInMemory(): Promise<{ - entryCallbacks: WasmCallbacks - chainCallbacks: WasmCallbacks + entryCallbacks: Callbacks + chainCallbacks: Callbacks dumpTables: () => void dropTables: () => Promise }> { @@ -34,14 +35,14 @@ export async function callbacksExamplesInMemory(): Promise<{ const rejected = [] as UidsAndValues // Add old values in a map to efficiently search for matching UIDs. - let mapOfOldValues = new Map() + const mapOfOldValues = new Map() for (const { uid, value } of oldValues) { mapOfOldValues.set(uid.toString(), value) } for (const { uid, value: newValue } of newValues) { - let oldValue = mapOfOldValues.get(uid.toString()) - let actualValue = entries.get(uid.toString()) + const oldValue = mapOfOldValues.get(uid.toString()) + const actualValue = entries.get(uid.toString()) if (actualValue?.toString() === oldValue?.toString()) { entries.set(uid.toString(), newValue) @@ -62,26 +63,23 @@ export async function callbacksExamplesInMemory(): Promise<{ } } - const dumpTables = () => { - console.log("entry table length: ", entries.size) - console.log("chain table length: ", chains.size) + const dumpTables = (): void => { + logger.log(() => `entry table length: ${entries.size}`) + logger.log(() => `chain table length: ${chains.size}`) } - const dropTables = async () => { + const dropTables = async (): Promise => { entries.clear() chains.clear() } - // Load WASM file before using it. - await loadWasm() - - let entryCallbacks = new WasmCallbacks() + const entryCallbacks = new Callbacks() entryCallbacks.fetch = async (uids: Uint8Array[]) => { return await fetchCallback(entries, uids) } entryCallbacks.upsert = upsertEntries - let chainCallbacks = new WasmCallbacks() + const chainCallbacks = new Callbacks() chainCallbacks.fetch = async (uids: Uint8Array[]) => { return await fetchCallback(chains, uids) } diff --git a/src/findex/init.ts b/src/findex/init.ts index 38c7d03a..2b0354cf 100644 --- a/src/findex/init.ts +++ b/src/findex/init.ts @@ -1,10 +1,10 @@ -import init, { WasmCallbacks } from "../pkg/findex/cloudproof_findex" +import init from "../pkg/findex/cloudproof_findex" +import { FindexWithCloudBackend, FindexWithWasmBackend } from "./findex" import { callbacksExamplesInMemory } from "./in_memory" import { callbacksExamplesBetterSqlite3 } from "./sqlite" -import { Findex } from "./findex" - -export * from "./types" +import { Callbacks } from "./callbacks" +import { ServerToken } from "./server_token" let initialized: Promise | undefined @@ -14,17 +14,29 @@ export const setFindexInit = (arg: () => any): void => { wasmInit = arg } -export async function loadWasm() { +/** + * This is the main function for reusing webassembly code + * @returns initialized objects + */ +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export async function Findex() { if (initialized === undefined) { - // @ts-expect-error @ts-ignore-error - initialized = init(wasmInit()) + if (wasmInit === undefined) { + throw new Error("Please provide a WASM init function") + } + + const loadModule = wasmInit() + initialized = init(loadModule).then(() => undefined) } + await initialized -} -export { - Findex, - WasmCallbacks, - callbacksExamplesInMemory, - callbacksExamplesBetterSqlite3, + return { + Callbacks, + callbacksExamplesInMemory, + callbacksExamplesBetterSqlite3, + FindexWithWasmBackend, + FindexWithCloudBackend, + ServerToken, + } } diff --git a/src/findex/server_token.ts b/src/findex/server_token.ts new file mode 100644 index 00000000..8040765a --- /dev/null +++ b/src/findex/server_token.ts @@ -0,0 +1,23 @@ +import { WasmToken as WebAssemblyToken } from "../pkg/findex/cloudproof_findex" + +export class ServerToken { + TOKEN_LENGTH: number = 42 + + public static new( + indexId: string, + fetchEntriesKey: Uint8Array, + fetchChainsKey: Uint8Array, + upsertEntriesKey: Uint8Array, + insertChainsKey: Uint8Array, + ): string { + const token = WebAssemblyToken.create( + indexId, + fetchEntriesKey, + fetchChainsKey, + upsertEntriesKey, + insertChainsKey, + ) + + return token + } +} diff --git a/src/findex/sqlite.ts b/src/findex/sqlite.ts index 259093d9..6f57a807 100644 --- a/src/findex/sqlite.ts +++ b/src/findex/sqlite.ts @@ -1,6 +1,6 @@ import { Database, Statement } from "better-sqlite3" -import { WasmCallbacks } from "../pkg/findex/cloudproof_findex" -import { Index, loadWasm, UidsAndValues } from "./init" +import { Callbacks } from "./callbacks" +import { Index, UidsAndValues } from "./types" /** * @param db the SQLite3 connection @@ -13,8 +13,8 @@ export async function callbacksExamplesBetterSqlite3( entriesTableName: string = "entries", chainsTableName: string = "chains", ): Promise<{ - entryCallbacks: WasmCallbacks - chainCallbacks: WasmCallbacks + entryCallbacks: Callbacks + chainCallbacks: Callbacks }> { db.prepare( `CREATE TABLE IF NOT EXISTS ${entriesTableName} (uid BLOB PRIMARY KEY, value BLOB NOT NULL)`, @@ -85,13 +85,13 @@ export async function callbacksExamplesBetterSqlite3( const rejected = [] // Add old values in a map to efficiently search for matching UIDs. - let mapOfOldValues = new Map() + const mapOfOldValues = new Map() for (const { uid, value } of oldValues) { mapOfOldValues.set(uid.toString(), value) } for (const { uid, value: newValue } of newValues) { - let oldValue = mapOfOldValues.get(uid.toString()) + const oldValue = mapOfOldValues.get(uid.toString()) const result = upsertIntoEntriesTableStmt.run( uid, newValue, @@ -115,15 +115,12 @@ export async function callbacksExamplesBetterSqlite3( } } - // Load WASM file before using it. - await loadWasm() - - let entryCallbacks = new WasmCallbacks() + const entryCallbacks = new Callbacks() entryCallbacks.fetch = async (uids: Uint8Array[]) => await fetchCallback(entriesTableName, uids) entryCallbacks.upsert = upsertEntries - let chainCallbacks = new WasmCallbacks() + const chainCallbacks = new Callbacks() chainCallbacks.fetch = async (uids: Uint8Array[]) => await fetchCallback(chainsTableName, uids) chainCallbacks.insert = insertChains diff --git a/src/index.ts b/src/index.ts index 5ad7f9a3..8d506617 100644 --- a/src/index.ts +++ b/src/index.ts @@ -33,6 +33,9 @@ export { } from "./cover_crypt/key_generation" export * from "./ecies/init" export * from "./findex/init" +export * from "./findex/callbacks" +export * from "./findex/server_token" +export * from "./findex/types" export * from "./fpe/fpe" export { logger } from "./utils/logger" export { diff --git a/src/pkg/anonymization/.gitignore b/src/pkg/anonymization/.gitignore index 982f4cb4..f59ec20a 100644 --- a/src/pkg/anonymization/.gitignore +++ b/src/pkg/anonymization/.gitignore @@ -1,5 +1 @@ -*.wasm* -*.js -*.json -*.ts -*.md +* \ No newline at end of file diff --git a/src/pkg/cover_crypt/.gitkeep b/src/pkg/cover_crypt/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/src/pkg/cover_crypt/cloudproof_cover_crypt.d.ts b/src/pkg/cover_crypt/cloudproof_cover_crypt.d.ts deleted file mode 100644 index 022df3b2..00000000 --- a/src/pkg/cover_crypt/cloudproof_cover_crypt.d.ts +++ /dev/null @@ -1,171 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** -* @param {Uint8Array} policy_bytes -* @param {string} access_policy -* @param {Uint8Array} public_key_bytes -* @param {Uint8Array} header_metadata -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_encrypt_hybrid_header(policy_bytes: Uint8Array, access_policy: string, public_key_bytes: Uint8Array, header_metadata: Uint8Array, authentication_data: Uint8Array): Uint8Array; -/** -* Decrypt with a user decryption key an encrypted header -* of a resource encrypted using an hybrid crypto scheme. -* @param {Uint8Array} usk_bytes -* @param {Uint8Array} encrypted_header_bytes -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_decrypt_hybrid_header(usk_bytes: Uint8Array, encrypted_header_bytes: Uint8Array, authentication_data: Uint8Array): Uint8Array; -/** -* Symmetrically Encrypt plaintext data in a block. -* @param {Uint8Array} symmetric_key_bytes -* @param {Uint8Array} plaintext_bytes -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_encrypt_symmetric_block(symmetric_key_bytes: Uint8Array, plaintext_bytes: Uint8Array, authentication_data: Uint8Array): Uint8Array; -/** -* Symmetrically Decrypt encrypted data in a block. -* @param {Uint8Array} symmetric_key_bytes -* @param {Uint8Array} encrypted_bytes -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_decrypt_symmetric_block(symmetric_key_bytes: Uint8Array, encrypted_bytes: Uint8Array, authentication_data: Uint8Array): Uint8Array; -/** -* Generates both a encrypted header and a DEM encryption of the `plaintext`, -* with the header metadata as associated data. -* -* - `metadata_bytes` : serialized metadata -* - `policy_bytes` : serialized policy -* - `attribute_bytes` : serialized attributes to use in the encapsulation -* - `pk` : CoverCrypt public key -* - `plaintext` : message to encrypt with the DEM -* - `header_metadata` : additional data to symmetrically encrypt in the -* header -* - `authentication_data` : optional data used for authentication -* @param {Uint8Array} policy_bytes -* @param {string} access_policy -* @param {Uint8Array} pk -* @param {Uint8Array} plaintext -* @param {Uint8Array} header_metadata -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_hybrid_encrypt(policy_bytes: Uint8Array, access_policy: string, pk: Uint8Array, plaintext: Uint8Array, header_metadata: Uint8Array, authentication_data: Uint8Array): Uint8Array; -/** -* Decrypt the DEM ciphertext with the header encapsulated symmetric key, -* with the header metadata as associated data. -* -* - `usk_bytes` : serialized user secret key -* - `encrypted_bytes` : concatenation of the encrypted header and the DEM -* ciphertext -* - `authentication_data` : optional data used for authentication -* -* Return the decrypted data (additional data in header and cleartext) as a -* binary format: 1. LEB128 length of the additional data bytes -* 2. additional data bytes -* 3. cleartext bytes -* @param {Uint8Array} usk_bytes -* @param {Uint8Array} encrypted_bytes -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_hybrid_decrypt(usk_bytes: Uint8Array, encrypted_bytes: Uint8Array, authentication_data: Uint8Array): Uint8Array; -/** -* @param {string} name -* @param {({name: string, isHybridized: boolean})[]} attribute_properties -* @param {boolean} is_hierarchical -* @returns {string} -*/ -export function webassembly_policy_axis(name: string, attribute_properties: ({name: string, isHybridized: boolean})[], is_hierarchical: boolean): string; -/** -* @param {number} nb_creations -* @returns {Uint8Array} -*/ -export function webassembly_policy(nb_creations: number): Uint8Array; -/** -* @param {Uint8Array} policy -* @param {string} axis -* @returns {Uint8Array} -*/ -export function webassembly_add_axis(policy: Uint8Array, axis: string): Uint8Array; -/** -* Rotates attributes, changing their underlying values with that of an unused -* slot -* -* - `attributes` : user access policy (boolean expression as string) -* - `policy` : global policy data (bytes) -* -* Returns the `rotated` policy -* @param {Array} attributes -* @param {Uint8Array} policy -* @returns {Uint8Array} -*/ -export function webassembly_rotate_attributes(attributes: Array, policy: Uint8Array): Uint8Array; -/** -* Generate the master authority keys for supplied Policy -* -* - `policy` : global policy data (JSON) -* @param {Uint8Array} policy_bytes -* @returns {Uint8Array} -*/ -export function webassembly_generate_master_keys(policy_bytes: Uint8Array): Uint8Array; -/** -* Generate a user secret key. -* -* - `msk_bytes` : master secret key in bytes -* - `access_policy_str` : user access policy (boolean expression as string) -* - `policy` : global policy data (JSON) -* @param {Uint8Array} msk_bytes -* @param {string} access_policy_str -* @param {Uint8Array} policy_bytes -* @returns {Uint8Array} -*/ -export function webassembly_generate_user_secret_key(msk_bytes: Uint8Array, access_policy_str: string, policy_bytes: Uint8Array): Uint8Array; - -export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; - -export interface InitOutput { - readonly memory: WebAssembly.Memory; - readonly webassembly_encrypt_hybrid_header: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void; - readonly webassembly_decrypt_hybrid_header: (a: number, b: number, c: number, d: number) => void; - readonly webassembly_encrypt_symmetric_block: (a: number, b: number, c: number, d: number) => void; - readonly webassembly_decrypt_symmetric_block: (a: number, b: number, c: number, d: number) => void; - readonly webassembly_hybrid_encrypt: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void; - readonly webassembly_hybrid_decrypt: (a: number, b: number, c: number, d: number) => void; - readonly webassembly_policy_axis: (a: number, b: number, c: number, d: number, e: number, f: number) => void; - readonly webassembly_policy: (a: number, b: number) => void; - readonly webassembly_add_axis: (a: number, b: number, c: number, d: number, e: number) => void; - readonly webassembly_rotate_attributes: (a: number, b: number, c: number, d: number) => void; - readonly webassembly_generate_master_keys: (a: number, b: number, c: number) => void; - readonly webassembly_generate_user_secret_key: (a: number, b: number, c: number, d: number, e: number, f: number) => void; - readonly __wbindgen_export_0: (a: number, b: number) => number; - readonly __wbindgen_export_1: (a: number, b: number, c: number, d: number) => number; - readonly __wbindgen_add_to_stack_pointer: (a: number) => number; - readonly __wbindgen_export_2: (a: number, b: number, c: number) => void; - readonly __wbindgen_export_3: (a: number) => void; -} - -export type SyncInitInput = BufferSource | WebAssembly.Module; -/** -* Instantiates the given `module`, which can either be bytes or -* a precompiled `WebAssembly.Module`. -* -* @param {SyncInitInput} module -* -* @returns {InitOutput} -*/ -export function initSync(module: SyncInitInput): InitOutput; - -/** -* If `module_or_path` is {RequestInfo} or {URL}, makes a request and -* for everything else, calls `WebAssembly.instantiate` directly. -* -* @param {InitInput | Promise} module_or_path -* -* @returns {Promise} -*/ -export default function __wbg_init (module_or_path?: InitInput | Promise): Promise; diff --git a/src/pkg/cover_crypt/cloudproof_cover_crypt.js b/src/pkg/cover_crypt/cloudproof_cover_crypt.js deleted file mode 100644 index 5d8d3cf8..00000000 --- a/src/pkg/cover_crypt/cloudproof_cover_crypt.js +++ /dev/null @@ -1,750 +0,0 @@ -let wasm; - -const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); - -if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; - -let cachedUint8Memory0 = null; - -function getUint8Memory0() { - if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { - cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); - } - return cachedUint8Memory0; -} - -function getStringFromWasm0(ptr, len) { - ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); -} - -const heap = new Array(128).fill(undefined); - -heap.push(undefined, null, true, false); - -let heap_next = heap.length; - -function addHeapObject(obj) { - if (heap_next === heap.length) heap.push(heap.length + 1); - const idx = heap_next; - heap_next = heap[idx]; - - heap[idx] = obj; - return idx; -} - -function getObject(idx) { return heap[idx]; } - -function dropObject(idx) { - if (idx < 132) return; - heap[idx] = heap_next; - heap_next = idx; -} - -function takeObject(idx) { - const ret = getObject(idx); - dropObject(idx); - return ret; -} - -let WASM_VECTOR_LEN = 0; - -const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); - -const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' - ? function (arg, view) { - return cachedTextEncoder.encodeInto(arg, view); -} - : function (arg, view) { - const buf = cachedTextEncoder.encode(arg); - view.set(buf); - return { - read: arg.length, - written: buf.length - }; -}); - -function passStringToWasm0(arg, malloc, realloc) { - - if (realloc === undefined) { - const buf = cachedTextEncoder.encode(arg); - const ptr = malloc(buf.length, 1) >>> 0; - getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); - WASM_VECTOR_LEN = buf.length; - return ptr; - } - - let len = arg.length; - let ptr = malloc(len, 1) >>> 0; - - const mem = getUint8Memory0(); - - let offset = 0; - - for (; offset < len; offset++) { - const code = arg.charCodeAt(offset); - if (code > 0x7F) break; - mem[ptr + offset] = code; - } - - if (offset !== len) { - if (offset !== 0) { - arg = arg.slice(offset); - } - ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; - const view = getUint8Memory0().subarray(ptr + offset, ptr + len); - const ret = encodeString(arg, view); - - offset += ret.written; - } - - WASM_VECTOR_LEN = offset; - return ptr; -} - -function isLikeNone(x) { - return x === undefined || x === null; -} - -let cachedInt32Memory0 = null; - -function getInt32Memory0() { - if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { - cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); - } - return cachedInt32Memory0; -} - -function passArray8ToWasm0(arg, malloc) { - const ptr = malloc(arg.length * 1, 1) >>> 0; - getUint8Memory0().set(arg, ptr / 1); - WASM_VECTOR_LEN = arg.length; - return ptr; -} -/** -* @param {Uint8Array} policy_bytes -* @param {string} access_policy -* @param {Uint8Array} public_key_bytes -* @param {Uint8Array} header_metadata -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_encrypt_hybrid_header(policy_bytes, access_policy, public_key_bytes, header_metadata, authentication_data) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - const ptr0 = passArray8ToWasm0(policy_bytes, wasm.__wbindgen_export_0); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(access_policy, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); - const len1 = WASM_VECTOR_LEN; - wasm.webassembly_encrypt_hybrid_header(retptr, ptr0, len0, ptr1, len1, addHeapObject(public_key_bytes), addHeapObject(header_metadata), addHeapObject(authentication_data)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - if (r2) { - throw takeObject(r1); - } - return takeObject(r0); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* Decrypt with a user decryption key an encrypted header -* of a resource encrypted using an hybrid crypto scheme. -* @param {Uint8Array} usk_bytes -* @param {Uint8Array} encrypted_header_bytes -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_decrypt_hybrid_header(usk_bytes, encrypted_header_bytes, authentication_data) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.webassembly_decrypt_hybrid_header(retptr, addHeapObject(usk_bytes), addHeapObject(encrypted_header_bytes), addHeapObject(authentication_data)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - if (r2) { - throw takeObject(r1); - } - return takeObject(r0); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* Symmetrically Encrypt plaintext data in a block. -* @param {Uint8Array} symmetric_key_bytes -* @param {Uint8Array} plaintext_bytes -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_encrypt_symmetric_block(symmetric_key_bytes, plaintext_bytes, authentication_data) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.webassembly_encrypt_symmetric_block(retptr, addHeapObject(symmetric_key_bytes), addHeapObject(plaintext_bytes), addHeapObject(authentication_data)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - if (r2) { - throw takeObject(r1); - } - return takeObject(r0); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* Symmetrically Decrypt encrypted data in a block. -* @param {Uint8Array} symmetric_key_bytes -* @param {Uint8Array} encrypted_bytes -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_decrypt_symmetric_block(symmetric_key_bytes, encrypted_bytes, authentication_data) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.webassembly_decrypt_symmetric_block(retptr, addHeapObject(symmetric_key_bytes), addHeapObject(encrypted_bytes), addHeapObject(authentication_data)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - if (r2) { - throw takeObject(r1); - } - return takeObject(r0); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* Generates both a encrypted header and a DEM encryption of the `plaintext`, -* with the header metadata as associated data. -* -* - `metadata_bytes` : serialized metadata -* - `policy_bytes` : serialized policy -* - `attribute_bytes` : serialized attributes to use in the encapsulation -* - `pk` : CoverCrypt public key -* - `plaintext` : message to encrypt with the DEM -* - `header_metadata` : additional data to symmetrically encrypt in the -* header -* - `authentication_data` : optional data used for authentication -* @param {Uint8Array} policy_bytes -* @param {string} access_policy -* @param {Uint8Array} pk -* @param {Uint8Array} plaintext -* @param {Uint8Array} header_metadata -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_hybrid_encrypt(policy_bytes, access_policy, pk, plaintext, header_metadata, authentication_data) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - const ptr0 = passArray8ToWasm0(policy_bytes, wasm.__wbindgen_export_0); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(access_policy, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); - const len1 = WASM_VECTOR_LEN; - wasm.webassembly_hybrid_encrypt(retptr, ptr0, len0, ptr1, len1, addHeapObject(pk), addHeapObject(plaintext), addHeapObject(header_metadata), addHeapObject(authentication_data)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - if (r2) { - throw takeObject(r1); - } - return takeObject(r0); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* Decrypt the DEM ciphertext with the header encapsulated symmetric key, -* with the header metadata as associated data. -* -* - `usk_bytes` : serialized user secret key -* - `encrypted_bytes` : concatenation of the encrypted header and the DEM -* ciphertext -* - `authentication_data` : optional data used for authentication -* -* Return the decrypted data (additional data in header and cleartext) as a -* binary format: 1. LEB128 length of the additional data bytes -* 2. additional data bytes -* 3. cleartext bytes -* @param {Uint8Array} usk_bytes -* @param {Uint8Array} encrypted_bytes -* @param {Uint8Array} authentication_data -* @returns {Uint8Array} -*/ -export function webassembly_hybrid_decrypt(usk_bytes, encrypted_bytes, authentication_data) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.webassembly_hybrid_decrypt(retptr, addHeapObject(usk_bytes), addHeapObject(encrypted_bytes), addHeapObject(authentication_data)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - if (r2) { - throw takeObject(r1); - } - return takeObject(r0); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -let cachedUint32Memory0 = null; - -function getUint32Memory0() { - if (cachedUint32Memory0 === null || cachedUint32Memory0.byteLength === 0) { - cachedUint32Memory0 = new Uint32Array(wasm.memory.buffer); - } - return cachedUint32Memory0; -} - -function passArrayJsValueToWasm0(array, malloc) { - const ptr = malloc(array.length * 4, 4) >>> 0; - const mem = getUint32Memory0(); - for (let i = 0; i < array.length; i++) { - mem[ptr / 4 + i] = addHeapObject(array[i]); - } - WASM_VECTOR_LEN = array.length; - return ptr; -} -/** -* @param {string} name -* @param {({name: string, isHybridized: boolean})[]} attribute_properties -* @param {boolean} is_hierarchical -* @returns {string} -*/ -export function webassembly_policy_axis(name, attribute_properties, is_hierarchical) { - let deferred4_0; - let deferred4_1; - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - const ptr0 = passStringToWasm0(name, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passArrayJsValueToWasm0(attribute_properties, wasm.__wbindgen_export_0); - const len1 = WASM_VECTOR_LEN; - wasm.webassembly_policy_axis(retptr, ptr0, len0, ptr1, len1, is_hierarchical); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - var r3 = getInt32Memory0()[retptr / 4 + 3]; - var ptr3 = r0; - var len3 = r1; - if (r3) { - ptr3 = 0; len3 = 0; - throw takeObject(r2); - } - deferred4_0 = ptr3; - deferred4_1 = len3; - return getStringFromWasm0(ptr3, len3); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - wasm.__wbindgen_export_2(deferred4_0, deferred4_1, 1); - } -} - -function getArrayU8FromWasm0(ptr, len) { - ptr = ptr >>> 0; - return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len); -} -/** -* @param {number} nb_creations -* @returns {Uint8Array} -*/ -export function webassembly_policy(nb_creations) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.webassembly_policy(retptr, nb_creations); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - var r3 = getInt32Memory0()[retptr / 4 + 3]; - if (r3) { - throw takeObject(r2); - } - var v1 = getArrayU8FromWasm0(r0, r1).slice(); - wasm.__wbindgen_export_2(r0, r1 * 1); - return v1; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* @param {Uint8Array} policy -* @param {string} axis -* @returns {Uint8Array} -*/ -export function webassembly_add_axis(policy, axis) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - const ptr0 = passArray8ToWasm0(policy, wasm.__wbindgen_export_0); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(axis, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); - const len1 = WASM_VECTOR_LEN; - wasm.webassembly_add_axis(retptr, ptr0, len0, ptr1, len1); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - var r3 = getInt32Memory0()[retptr / 4 + 3]; - if (r3) { - throw takeObject(r2); - } - var v3 = getArrayU8FromWasm0(r0, r1).slice(); - wasm.__wbindgen_export_2(r0, r1 * 1); - return v3; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* Rotates attributes, changing their underlying values with that of an unused -* slot -* -* - `attributes` : user access policy (boolean expression as string) -* - `policy` : global policy data (bytes) -* -* Returns the `rotated` policy -* @param {Array} attributes -* @param {Uint8Array} policy -* @returns {Uint8Array} -*/ -export function webassembly_rotate_attributes(attributes, policy) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - const ptr0 = passArray8ToWasm0(policy, wasm.__wbindgen_export_0); - const len0 = WASM_VECTOR_LEN; - wasm.webassembly_rotate_attributes(retptr, addHeapObject(attributes), ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - var r3 = getInt32Memory0()[retptr / 4 + 3]; - if (r3) { - throw takeObject(r2); - } - var v2 = getArrayU8FromWasm0(r0, r1).slice(); - wasm.__wbindgen_export_2(r0, r1 * 1); - return v2; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* Generate the master authority keys for supplied Policy -* -* - `policy` : global policy data (JSON) -* @param {Uint8Array} policy_bytes -* @returns {Uint8Array} -*/ -export function webassembly_generate_master_keys(policy_bytes) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - const ptr0 = passArray8ToWasm0(policy_bytes, wasm.__wbindgen_export_0); - const len0 = WASM_VECTOR_LEN; - wasm.webassembly_generate_master_keys(retptr, ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - if (r2) { - throw takeObject(r1); - } - return takeObject(r0); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* Generate a user secret key. -* -* - `msk_bytes` : master secret key in bytes -* - `access_policy_str` : user access policy (boolean expression as string) -* - `policy` : global policy data (JSON) -* @param {Uint8Array} msk_bytes -* @param {string} access_policy_str -* @param {Uint8Array} policy_bytes -* @returns {Uint8Array} -*/ -export function webassembly_generate_user_secret_key(msk_bytes, access_policy_str, policy_bytes) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - const ptr0 = passStringToWasm0(access_policy_str, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passArray8ToWasm0(policy_bytes, wasm.__wbindgen_export_0); - const len1 = WASM_VECTOR_LEN; - wasm.webassembly_generate_user_secret_key(retptr, addHeapObject(msk_bytes), ptr0, len0, ptr1, len1); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - if (r2) { - throw takeObject(r1); - } - return takeObject(r0); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -function handleError(f, args) { - try { - return f.apply(this, args); - } catch (e) { - wasm.__wbindgen_export_3(addHeapObject(e)); - } -} - -async function __wbg_load(module, imports) { - if (typeof Response === 'function' && module instanceof Response) { - if (typeof WebAssembly.instantiateStreaming === 'function') { - try { - return await WebAssembly.instantiateStreaming(module, imports); - - } catch (e) { - if (module.headers.get('Content-Type') != 'application/wasm') { - console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); - - } else { - throw e; - } - } - } - - const bytes = await module.arrayBuffer(); - return await WebAssembly.instantiate(bytes, imports); - - } else { - const instance = await WebAssembly.instantiate(module, imports); - - if (instance instanceof WebAssembly.Instance) { - return { instance, module }; - - } else { - return instance; - } - } -} - -function __wbg_get_imports() { - const imports = {}; - imports.wbg = {}; - imports.wbg.__wbindgen_string_new = function(arg0, arg1) { - const ret = getStringFromWasm0(arg0, arg1); - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_is_null = function(arg0) { - const ret = getObject(arg0) === null; - return ret; - }; - imports.wbg.__wbindgen_object_drop_ref = function(arg0) { - takeObject(arg0); - }; - imports.wbg.__wbg_crypto_c48a774b022d20ac = function(arg0) { - const ret = getObject(arg0).crypto; - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_is_object = function(arg0) { - const val = getObject(arg0); - const ret = typeof(val) === 'object' && val !== null; - return ret; - }; - imports.wbg.__wbg_process_298734cf255a885d = function(arg0) { - const ret = getObject(arg0).process; - return addHeapObject(ret); - }; - imports.wbg.__wbg_versions_e2e78e134e3e5d01 = function(arg0) { - const ret = getObject(arg0).versions; - return addHeapObject(ret); - }; - imports.wbg.__wbg_node_1cd7a5d853dbea79 = function(arg0) { - const ret = getObject(arg0).node; - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_is_string = function(arg0) { - const ret = typeof(getObject(arg0)) === 'string'; - return ret; - }; - imports.wbg.__wbg_msCrypto_bcb970640f50a1e8 = function(arg0) { - const ret = getObject(arg0).msCrypto; - return addHeapObject(ret); - }; - imports.wbg.__wbg_require_8f08ceecec0f4fee = function() { return handleError(function () { - const ret = module.require; - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbindgen_is_function = function(arg0) { - const ret = typeof(getObject(arg0)) === 'function'; - return ret; - }; - imports.wbg.__wbg_getRandomValues_37fa2ca9e4e07fab = function() { return handleError(function (arg0, arg1) { - getObject(arg0).getRandomValues(getObject(arg1)); - }, arguments) }; - imports.wbg.__wbg_randomFillSync_dc1e9a60c158336d = function() { return handleError(function (arg0, arg1) { - getObject(arg0).randomFillSync(takeObject(arg1)); - }, arguments) }; - imports.wbg.__wbg_valueOf_e39b017d2100ede0 = function(arg0) { - const ret = getObject(arg0).valueOf(); - return ret; - }; - imports.wbg.__wbg_newnoargs_581967eacc0e2604 = function(arg0, arg1) { - const ret = new Function(getStringFromWasm0(arg0, arg1)); - return addHeapObject(ret); - }; - imports.wbg.__wbg_next_ddb3312ca1c4e32a = function() { return handleError(function (arg0) { - const ret = getObject(arg0).next(); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_done_5c1f01fb660d73b5 = function(arg0) { - const ret = getObject(arg0).done; - return ret; - }; - imports.wbg.__wbg_value_1695675138684bd5 = function(arg0) { - const ret = getObject(arg0).value; - return addHeapObject(ret); - }; - imports.wbg.__wbg_get_97b561fb56f034b5 = function() { return handleError(function (arg0, arg1) { - const ret = Reflect.get(getObject(arg0), getObject(arg1)); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_call_cb65541d95d71282 = function() { return handleError(function (arg0, arg1) { - const ret = getObject(arg0).call(getObject(arg1)); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbindgen_string_get = function(arg0, arg1) { - const obj = getObject(arg1); - const ret = typeof(obj) === 'string' ? obj : undefined; - var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); - var len1 = WASM_VECTOR_LEN; - getInt32Memory0()[arg0 / 4 + 1] = len1; - getInt32Memory0()[arg0 / 4 + 0] = ptr1; - }; - imports.wbg.__wbindgen_object_clone_ref = function(arg0) { - const ret = getObject(arg0); - return addHeapObject(ret); - }; - imports.wbg.__wbg_self_1ff1d729e9aae938 = function() { return handleError(function () { - const ret = self.self; - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_window_5f4faef6c12b79ec = function() { return handleError(function () { - const ret = window.window; - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_globalThis_1d39714405582d3c = function() { return handleError(function () { - const ret = globalThis.globalThis; - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_global_651f05c6a0944d1c = function() { return handleError(function () { - const ret = global.global; - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbindgen_is_undefined = function(arg0) { - const ret = getObject(arg0) === undefined; - return ret; - }; - imports.wbg.__wbg_from_d7c216d4616bb368 = function(arg0) { - const ret = Array.from(getObject(arg0)); - return addHeapObject(ret); - }; - imports.wbg.__wbg_values_e80af618f92c8649 = function(arg0) { - const ret = getObject(arg0).values(); - return addHeapObject(ret); - }; - imports.wbg.__wbg_call_01734de55d61e11d = function() { return handleError(function (arg0, arg1, arg2) { - const ret = getObject(arg0).call(getObject(arg1), getObject(arg2)); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_buffer_085ec1f694018c4f = function(arg0) { - const ret = getObject(arg0).buffer; - return addHeapObject(ret); - }; - imports.wbg.__wbg_newwithbyteoffsetandlength_6da8e527659b86aa = function(arg0, arg1, arg2) { - const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); - return addHeapObject(ret); - }; - imports.wbg.__wbg_new_8125e318e6245eed = function(arg0) { - const ret = new Uint8Array(getObject(arg0)); - return addHeapObject(ret); - }; - imports.wbg.__wbg_set_5cf90238115182c3 = function(arg0, arg1, arg2) { - getObject(arg0).set(getObject(arg1), arg2 >>> 0); - }; - imports.wbg.__wbg_length_72e2208bbc0efc61 = function(arg0) { - const ret = getObject(arg0).length; - return ret; - }; - imports.wbg.__wbg_newwithlength_e5d69174d6984cd7 = function(arg0) { - const ret = new Uint8Array(arg0 >>> 0); - return addHeapObject(ret); - }; - imports.wbg.__wbg_subarray_13db269f57aa838d = function(arg0, arg1, arg2) { - const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0); - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_throw = function(arg0, arg1) { - throw new Error(getStringFromWasm0(arg0, arg1)); - }; - imports.wbg.__wbindgen_memory = function() { - const ret = wasm.memory; - return addHeapObject(ret); - }; - - return imports; -} - -function __wbg_init_memory(imports, maybe_memory) { - -} - -function __wbg_finalize_init(instance, module) { - wasm = instance.exports; - __wbg_init.__wbindgen_wasm_module = module; - cachedInt32Memory0 = null; - cachedUint32Memory0 = null; - cachedUint8Memory0 = null; - - - return wasm; -} - -function initSync(module) { - if (wasm !== undefined) return wasm; - - const imports = __wbg_get_imports(); - - __wbg_init_memory(imports); - - if (!(module instanceof WebAssembly.Module)) { - module = new WebAssembly.Module(module); - } - - const instance = new WebAssembly.Instance(module, imports); - - return __wbg_finalize_init(instance, module); -} - -async function __wbg_init(input) { - if (wasm !== undefined) return wasm; - - if (typeof input === 'undefined') { - input = new URL('cloudproof_cover_crypt_bg.wasm', import.meta.url); - } - const imports = __wbg_get_imports(); - - if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) { - input = fetch(input); - } - - __wbg_init_memory(imports); - - const { instance, module } = await __wbg_load(await input, imports); - - return __wbg_finalize_init(instance, module); -} - -export { initSync } -export default __wbg_init; diff --git a/src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm b/src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm deleted file mode 100644 index 1599725d1d15ebdc33d13419fbdb95af2933391a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 468243 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Ȁf+{_MzT_TN|vBd=A$rn3Qd_wlMTOx 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℘~n&Sf@--S?tdOc{2Gjt9DI)hIJdNRtxfC(A0XdxwE_ zUvcg171u{Ah7gQY%+vyGYge3xitERU>3y}^_ObR|bSR(R_q<#6$iEd#dx>9i>tTL3 zhtv~4p|p;VojUK(;lqdJB8ubq|Lw)R+=IabhE1dgrrOCPOFzGODe%j7Ln1B`sx#3I zJGQLhFLUJbd83q>hbyc_L?(!!MPr>J(j|g(7uGN$V%Ko^!um#}O$2V2wU0=P2+I!Z zA`!`K+KM!YG>D*3XFVmtW)W6}NR3F12y~Hkn1~5@6iJClU<55?{U*X53A#okCIVdo zdPE{3bV!T{6Y%}@q{e-P$zCP}h637e@XT)RNL-|Dhn!W})#VU1UFj%_49UITJ@FAP zYJM?G4O0U`j!}fnB3S6)!*N`tJr=}OpNsJq-{_vSV@qC{*59W;$2vX2A_-d)LfS{t*}CQ9yi=1X_wpAO(4B?bNDipgO`lp zxJvNJ8%GhE;(*mX7q5)OQ-A`qB{~i~_QO+h${u(@_)<4?ZzUgdmW0DG34g2M4E0Y1 z<1@o_ADn!?3a({p1>1egAAaZsYl63YvnGVsdRYN^^~)a!&Sf#x_`*i40cry?C<#1( zv*Gh7oQ;vw{^JOMhOFy~@W{R8?vF$+>0Pg++$X(FNtsVtiG12!N^AJEWxHLRD+-i0 z8PXD;Z}~rxwwW|`T_b~exSli*wr*nh;};{AuZpiCp zdF$+LqkKDUZ=2;?7PXBxxS4A)pDJ(`6#=m}uID|8YGe7~=~G)pc2GXJNm4}RI@ox4 z64!R~W*@>48|leK=sM~GnAvp`WD@P{au>5FoLz*_0h}? zk_5?YigL6JV5iMj)AppkYDJk+*%(^)ur-h~Eom?sJmHm-cl0%0A|+N42w8cgl64qj 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

X(ykiTuJUMCst{Q#;6)dRp9J9)laVF2 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 z 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 M{1htB1b>JB1B!kFr~m)} diff --git a/src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm.d.ts b/src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm.d.ts deleted file mode 100644 index cc9a7099..00000000 --- a/src/pkg/cover_crypt/cloudproof_cover_crypt_bg.wasm.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -export const memory: WebAssembly.Memory; -export function webassembly_encrypt_hybrid_header(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number): void; -export function webassembly_decrypt_hybrid_header(a: number, b: number, c: number, d: number): void; -export function webassembly_encrypt_symmetric_block(a: number, b: number, c: number, d: number): void; -export function webassembly_decrypt_symmetric_block(a: number, b: number, c: number, d: number): void; -export function webassembly_hybrid_encrypt(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number): void; -export function webassembly_hybrid_decrypt(a: number, b: number, c: number, d: number): void; -export function webassembly_policy_axis(a: number, b: number, c: number, d: number, e: number, f: number): void; -export function webassembly_policy(a: number, b: number): void; -export function webassembly_add_axis(a: number, b: number, c: number, d: number, e: number): void; -export function webassembly_rotate_attributes(a: number, b: number, c: number, d: number): void; -export function webassembly_generate_master_keys(a: number, b: number, c: number): void; -export function webassembly_generate_user_secret_key(a: number, b: number, c: number, d: number, e: number, f: number): void; -export function __wbindgen_export_0(a: number, b: number): number; -export function __wbindgen_export_1(a: number, b: number, c: number, d: number): number; -export function __wbindgen_add_to_stack_pointer(a: number): number; -export function __wbindgen_export_2(a: number, b: number, c: number): void; -export function __wbindgen_export_3(a: number): void; diff --git a/tests/errors.test.js b/tests/errors.test.js index 867c6368..50f99489 100644 --- a/tests/errors.test.js +++ b/tests/errors.test.js @@ -1,19 +1,16 @@ -import { - FindexKey, - Label, - Location, - Findex, - callbacksExamplesInMemory, -} from ".." +import { FindexKey, Label, Location, Findex } from ".." import { expect, test } from "vitest" import { randomBytes } from "crypto" +const { FindexWithWasmBackend, callbacksExamplesInMemory } = await Findex() + test("errors", async () => { const callbacks = await callbacksExamplesInMemory() const toUpsert = [ { indexedValue: Location.fromNumber(42), keywords: ["Answer"] }, ] - const findex = await Findex.new_with_wasm_backend( + const findex = new FindexWithWasmBackend() + await findex.createWithWasmBackend( callbacks.entryCallbacks, callbacks.chainCallbacks, ) @@ -30,12 +27,12 @@ test("errors", async () => { expect(async () => { await findex.add(new FindexKey(randomBytes(72)), label, toUpsert) }).rejects.toThrow( - "While parsing master key for Findex upsert, wrong size when parsing bytes: 72 given should be 16", + "Findex add: failed parsing key: try from slice error: could not convert slice to array", ) expect(async () => { await findex.search(new FindexKey(randomBytes(13)), label, "Answer") }).rejects.toThrow( - "While parsing master key for Findex search, wrong size when parsing bytes: 13 given should be 16", + "Findex search: While parsing key for Findex search, try from slice error: could not convert slice to array", ) // toUpsert argument diff --git a/tests/findex.bench.ts b/tests/findex.bench.ts index 15ed8ff0..d4692df0 100644 --- a/tests/findex.bench.ts +++ b/tests/findex.bench.ts @@ -1,19 +1,21 @@ import { - Findex, FindexKey, IndexedEntry, IndexedValue, Keyword, Label, Location, - callbacksExamplesInMemory, + Findex, } from ".." import { bench, describe } from "vitest" import { USERS } from "./data/users" import { randomBytes } from "crypto" +const { FindexWithWasmBackend, callbacksExamplesInMemory } = await Findex() + const callbacks = await callbacksExamplesInMemory() -const findex = await Findex.new_with_wasm_backend( +const findex = new FindexWithWasmBackend() +await findex.createWithWasmBackend( callbacks.entryCallbacks, callbacks.chainCallbacks, ) diff --git a/tests/findex.test.ts b/tests/findex.test.ts index bf987df4..37a9c517 100644 --- a/tests/findex.test.ts +++ b/tests/findex.test.ts @@ -1,36 +1,44 @@ -import { toByteArray } from "base64-js" -import Database from "better-sqlite3" import { randomBytes } from "crypto" -import * as fs from "fs" -import * as os from "os" -import { WasmToken } from "pkg/findex/cloudproof_findex" +import { FindexBase } from "findex/findex" import { expect, test } from "vitest" import { + Callbacks, + FindexKey, IndexedEntry, IndexedValue, - FindexKey, - SearchResults, + Findex, + IntermediateSearchResults, + Interrupt, Keyword, + KeywordIndexEntry, Label, Location, LocationIndexEntry, - KeywordIndexEntry, + SearchResults, generateAliases, - callbacksExamplesBetterSqlite3, - callbacksExamplesInMemory, - Findex, - IntermediateSearchResults, - Interrupt, - WasmCallbacks, + logger, } from ".." import { USERS } from "./data/users" +import Database from "better-sqlite3" +import * as fs from "fs" +import * as os from "os" +import { toByteArray } from "base64-js" + +const { + FindexWithWasmBackend, + FindexWithCloudBackend, + callbacksExamplesInMemory, + callbacksExamplesBetterSqlite3, + ServerToken, +} = await Findex() const FINDEX_TEST_KEY = "6hb1TznoNQFvCWisGWajkA==" const FINDEX_TEST_LABEL = "Some Label" +const LOGGER_INIT = false // eslint-disable-next-line jsdoc/require-jsdoc async function run( - findex: Findex, + findex: FindexBase, userInterrupt?: Interrupt, dumpTables?: () => void, dropTables?: () => Promise, @@ -39,10 +47,9 @@ async function run( const key = new FindexKey(randomBytes(16)) { - console.log( - "test adding ", - USERS.length, - " users and searching for the first one", + logger.log( + () => + `test adding ${USERS.length} users and searching for the first one`, ) const newIndexedEntries: IndexedEntry[] = [] for (const user of USERS) { @@ -52,10 +59,10 @@ async function run( }) } - await findex.add(key, label, newIndexedEntries) - await findex.add(key, label, newIndexedEntries) + await findex.add(key, label, newIndexedEntries, { verbose: LOGGER_INIT }) + await findex.add(key, label, newIndexedEntries, { verbose: LOGGER_INIT }) - if (dumpTables) { + if (dumpTables != null) { dumpTables() } @@ -63,9 +70,8 @@ async function run( key, label, [USERS[0].firstName, USERS[0].country], - { userInterrupt: userInterrupt }, + { userInterrupt, verbose: LOGGER_INIT }, ) - console.log("check returned locations: ", results) const locations = results.get(USERS[0].firstName) @@ -74,9 +80,10 @@ async function run( } { - console.log("checking results for 'Spain'") + logger.log(() => "checking results for 'Spain'") const results = await findex.search(key, label, ["Spain"], { - userInterrupt: userInterrupt, + userInterrupt, + verbose: LOGGER_INIT, }) expect( @@ -92,9 +99,9 @@ async function run( } { - console.log("Test searching for Spain and France.") + logger.log(() => "Test searching for Spain and France.") const results = await findex.search(key, label, ["Spain", "France"], { - userInterrupt: userInterrupt, + userInterrupt, }) expect( @@ -134,7 +141,7 @@ async function run( } { - console.log("Test upsert an alias to the first user.") + logger.log(() => "Test upsert an alias to the first user.") await findex.add(key, label, [ { indexedValue: Keyword.fromString(USERS[0].firstName), @@ -159,10 +166,10 @@ async function run( await searchAndCheck("SomeAlia") } - if (dropTables) { + if (dropTables != null) { await dropTables() } - if (dumpTables) { + if (dumpTables != null) { dumpTables() } @@ -171,7 +178,7 @@ async function run( await Promise.all( // eslint-disable-next-line @typescript-eslint/promise-function-async sourceIds.map((id) => { - return findex.add(key, label, [ + return findex.add(key.bytes, label.bytes, [ { indexedValue: Location.fromNumber(id), keywords: ["Concurrent"], @@ -183,7 +190,7 @@ async function run( { const results = await findex.search(key, label, ["Concurrent"]) - if (dumpTables) { + if (dumpTables != null) { dumpTables() } @@ -196,45 +203,15 @@ async function run( } } -//test( -// "Findex Cloud", -// async () => { -// await runInFindexCloud() -// }, -// { timeout: 60000 }, -//) - -test("in memory", async () => { - const callbacks = await callbacksExamplesInMemory() - callbacks.dumpTables() - await runWithFindexCallbacks( - callbacks.entryCallbacks, - callbacks.chainCallbacks, - callbacks.dumpTables, - ) - callbacks.dumpTables() -}) - -test("SQLite", async () => { - const db = new Database(":memory:") - const callbacks = await callbacksExamplesBetterSqlite3(db) - await runWithFindexCallbacks( - callbacks.entryCallbacks, - callbacks.chainCallbacks, - ) -}) - // eslint-disable-next-line jsdoc/require-jsdoc async function runWithFindexCallbacks( - entryCallbacks: WasmCallbacks, - chainCallbacks: WasmCallbacks, + entryCallbacks: Callbacks, + chainCallbacks: Callbacks, dumpTables?: () => void, dropTables?: () => Promise, ): Promise { - const findex = await Findex.new_with_wasm_backend( - entryCallbacks, - chainCallbacks, - ) + const findex = new FindexWithWasmBackend() + await findex.createWithWasmBackend(entryCallbacks, chainCallbacks) await run( findex, async (results: IntermediateSearchResults) => { @@ -252,43 +229,76 @@ async function runWithFindexCallbacks( ) } -//// eslint-disable-next-line jsdoc/require-jsdoc -//async function runInFindexCloud(): Promise { -// const baseUrl = `http://${process.env.FINDEX_CLOUD_HOST ?? "127.0.0.1"}:${ -// process.env.FINDEX_CLOUD_PORT ?? "8080" -// }` -// -// let response -// try { -// response = await fetch(`${baseUrl}/indexes`, { -// method: "POST", -// headers: { -// "Content-Type": "application/json", -// }, -// body: JSON.stringify({ -// name: "Test", -// }), -// }) -// } catch (e) { -// if ( -// e instanceof TypeError && -// // @ts-expect-error -// (e.cause.message.includes("ECONNREFUSED") as boolean) -// ) { -// return -// } else { -// throw e -// } -// } -// -// const data = await response.json() -// -// const findex = await Findex.new_with_cloud_backend( -// WasmToken.random(data.public_id), -// baseUrl, -// ) -// await run(findex) -//} +// eslint-disable-next-line jsdoc/require-jsdoc +async function runInFindexCloud(): Promise { + const baseUrl = `http://${process.env.FINDEX_CLOUD_HOST ?? "127.0.0.1"}:${ + process.env.FINDEX_CLOUD_PORT ?? "8080" + }` + + let response + try { + response = await fetch(`${baseUrl}/indexes`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: "Test", + }), + }) + } catch (e) { + if ( + e instanceof TypeError && + // @ts-expect-error + (e.cause.message.includes("ECONNREFUSED") as boolean) + ) { + return + } else { + throw e + } + } + + const data = await response.json() + const findex = new FindexWithCloudBackend() + const token = ServerToken.new( + data.public_id, + Uint8Array.from(data.fetch_entries_key), + Uint8Array.from(data.fetch_chains_key), + Uint8Array.from(data.upsert_entries_key), + Uint8Array.from(data.insert_chains_key), + ) + await findex.createWithCloudBackend(token, baseUrl) + await run(findex) +} + +test( + "Findex Cloud", + async () => { + await runInFindexCloud() + }, + { timeout: 60000 }, +) + +test("in memory", async () => { + const callbacks = await callbacksExamplesInMemory() + callbacks.dumpTables() + await runWithFindexCallbacks( + callbacks.entryCallbacks, + callbacks.chainCallbacks, + callbacks.dumpTables, + callbacks.dropTables, + ) + callbacks.dumpTables() +}) + +test("SQLite", async () => { + const db = new Database(":memory:") + const callbacks = await callbacksExamplesBetterSqlite3(db) + await runWithFindexCallbacks( + callbacks.entryCallbacks, + callbacks.chainCallbacks, + ) +}) test("generateAliases", async () => { const checkAlias = (alias: IndexedEntry, from: string, to: string): void => { @@ -417,10 +427,9 @@ test("Location conversions", async () => { test("upsert and search cycle", async () => { const { entryCallbacks, chainCallbacks } = await callbacksExamplesInMemory() - const findex = await Findex.new_with_wasm_backend( - entryCallbacks, - chainCallbacks, - ) + + const findex = new FindexWithWasmBackend() + await findex.createWithWasmBackend(entryCallbacks, chainCallbacks) const key = new FindexKey(randomBytes(16)) const label = new Label(randomBytes(10)) @@ -440,10 +449,8 @@ test("upsert and search cycle", async () => { test("upsert and search memory", async () => { const { entryCallbacks, chainCallbacks } = await callbacksExamplesInMemory() - const findex = await Findex.new_with_wasm_backend( - entryCallbacks, - chainCallbacks, - ) + const findex = new FindexWithWasmBackend() + await findex.createWithWasmBackend(entryCallbacks, chainCallbacks) const entryLocation: IndexedEntry = { indexedValue: IndexedValue.fromLocation(Location.fromString("ROBERT file")), @@ -513,10 +520,8 @@ test("generate non regression database", async () => { const { entryCallbacks, chainCallbacks } = await callbacksExamplesBetterSqlite3(db, "entry_table", "chain_table") - const findex = await Findex.new_with_wasm_backend( - entryCallbacks, - chainCallbacks, - ) + const findex = new FindexWithWasmBackend() + await findex.createWithWasmBackend(entryCallbacks, chainCallbacks) const masterKey = new FindexKey(toByteArray(FINDEX_TEST_KEY)) const label = new Label(FINDEX_TEST_LABEL) @@ -558,7 +563,8 @@ async function verify(dbFilepath: string): Promise { "entry_table", "chain_table", ) - const findex = await Findex.new_with_wasm_backend( + const findex = new FindexWithWasmBackend() + await findex.createWithWasmBackend( callbacks.entryCallbacks, callbacks.chainCallbacks, ) From 8a696f025bb434f28fd5e19da687b001848bcdd4 Mon Sep 17 00:00:00 2001 From: Manuthor Date: Thu, 16 Nov 2023 16:51:14 +0100 Subject: [PATCH 03/10] docs(readme): ci badge.. --- README.md | 2 +- src/pkg/cover_crypt/.gitignore | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 src/pkg/cover_crypt/.gitignore diff --git a/README.md b/README.md index cbff8602..db647f62 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cloudproof Javascript Library -![Build status](https://github.com/Cosmian/cloudproof_js/actions/workflows/ci.yml/badge.svg) +![Build status](https://github.com/Cosmian/cloudproof_js/actions/workflows/ci.yml/badge.svg?branch=main) The library provides a Typescript-friendly API to the **Cloudproof Encryption** product of the [Cosmian Ubiquitous Encryption platform](https://cosmian.com). diff --git a/src/pkg/cover_crypt/.gitignore b/src/pkg/cover_crypt/.gitignore new file mode 100644 index 00000000..982f4cb4 --- /dev/null +++ b/src/pkg/cover_crypt/.gitignore @@ -0,0 +1,5 @@ +*.wasm* +*.js +*.json +*.ts +*.md From bc91bd07da5b37a0357803b878b5c94d4dff3a76 Mon Sep 17 00:00:00 2001 From: Manuthor Date: Wed, 22 Nov 2023 10:39:04 +0100 Subject: [PATCH 04/10] fix: rename findex master key to findex key --- .../nodejs_search_imdb/index_with_stats.mjs | 6 +- examples/reactjs/src/App.tsx | 26 ++++---- examples/vuejs/src/App.vue | 30 ++++----- scripts/download_wasm.py | 62 +++++++++---------- src/findex/findex.ts | 44 +++++++------ tests/errors.test.js | 20 +++--- tests/findex.bench.ts | 16 ++--- tests/findex.test.ts | 16 ++--- 8 files changed, 109 insertions(+), 111 deletions(-) diff --git a/examples/nodejs_search_imdb/index_with_stats.mjs b/examples/nodejs_search_imdb/index_with_stats.mjs index 3094a35b..5df0522b 100755 --- a/examples/nodejs_search_imdb/index_with_stats.mjs +++ b/examples/nodejs_search_imdb/index_with_stats.mjs @@ -47,7 +47,7 @@ const csvStats = fs.createWriteStream("stats.csv", { flags: "a+" }) // Init Findex with random key and random label const { upsert, search } = await Findex() const { upsert: upsertCloud, search: searchCloud } = await FindexCloud() -const masterKey = new FindexKey(randomBytes(16)) +const findexKey = new FindexKey(randomBytes(16)) const label = new Label(randomBytes(10)) const findexCloudToken = process.env.FINDEX_CLOUD_TOKEN const baseUrl = "http://127.0.0.1:8080" @@ -172,7 +172,7 @@ for await (const line of rl) { ) { const insertFindexStart = performance.now() await upsert( - masterKey, + findexKey, label, toUpsert, [], @@ -250,7 +250,7 @@ for await (const line of rl) { const searchNow = performance.now() const results = await search( - masterKey, + findexKey, label, new Set(["Documentary"]), async (uids) => { diff --git a/examples/reactjs/src/App.tsx b/examples/reactjs/src/App.tsx index 983a8288..e8c74bfe 100644 --- a/examples/reactjs/src/App.tsx +++ b/examples/reactjs/src/App.tsx @@ -1,4 +1,5 @@ import { + Callbacks, CoverCrypt, Findex, FindexKey, @@ -6,9 +7,8 @@ import { Label, Location, PolicyKms, - type UidsAndValues, generateAliases, - Callbacks, + type UidsAndValues, } from "cloudproof_js" import { FormEvent, useEffect, useState } from "react" @@ -175,7 +175,7 @@ function App() { }[], ) - const [masterKey, setMasterKey] = useState(null as FindexKey | null) + const [findexKey, setMasterKey] = useState(null as FindexKey | null) const [indexesEntries, setIndexesEntries] = useState([] as UidsAndValues) const [indexesChains, setIndexesChains] = useState([] as UidsAndValues) @@ -406,7 +406,7 @@ function App() { } const indexUsers = async ( - localMasterKey: Exclude, + localMasterKey: Exclude, users: User[], ) => { let { FindexWithWasmBackend } = await Findex() @@ -454,10 +454,10 @@ function App() { const index = async () => { setIndexing(true) - let masterKey = new FindexKey(Uint8Array.from(Array(16).keys())) - setMasterKey(masterKey) + let findexKey = new FindexKey(Uint8Array.from(Array(16).keys())) + setMasterKey(findexKey) - indexUsers(masterKey, users) + indexUsers(findexKey, users) setIndexing(false) setIndexingDone(true) @@ -580,11 +580,11 @@ function App() { } if (indexingDone) { - if (!masterKey) + if (!findexKey) throw new Error( - "masterKey should be present when first indexing is done", + "findexKey should be present when first indexing is done", ) - await indexUsers(masterKey, [user]) + await indexUsers(findexKey, [user]) } setAddingUser(false) @@ -630,7 +630,7 @@ function App() { const doSearch = async () => { if (!query) return [] if (!selectedKey) return [] - if (!masterKey) throw new Error("No Findex key") + if (!findexKey) throw new Error("No Findex key") let { FindexWithWasmBackend } = await Findex() const findex = new FindexWithWasmBackend() @@ -654,12 +654,12 @@ function App() { let locations: Array | null = null if (doOr) { locations = ( - await findex.search(masterKey, FINDEX_LABEL, new Set(keywords)) + await findex.search(findexKey, FINDEX_LABEL, new Set(keywords)) ).locations() } else { for (const keyword of keywords) { const newLocations = ( - await findex.search(masterKey, FINDEX_LABEL, new Set([keyword])) + await findex.search(findexKey, FINDEX_LABEL, new Set([keyword])) ).locations() if (locations === null) { diff --git a/examples/vuejs/src/App.vue b/examples/vuejs/src/App.vue index 08d1d911..cedfb72a 100644 --- a/examples/vuejs/src/App.vue +++ b/examples/vuejs/src/App.vue @@ -1,15 +1,15 @@