@ibgib/space-gib 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/Dockerfile +14 -0
- package/IMPLEMENTATION.md +484 -0
- package/README.md +46 -0
- package/dist/client/bootstrap.mjs +58 -0
- package/dist/client/bootstrap.mjs.map +7 -0
- package/dist/client/chunk-CT47Z5WU.mjs +21 -0
- package/dist/client/chunk-CT47Z5WU.mjs.map +7 -0
- package/dist/client/chunk-RHEDTRKF.mjs +235 -0
- package/dist/client/chunk-RHEDTRKF.mjs.map +7 -0
- package/dist/client/index.html +147 -0
- package/dist/client/index.mjs +2 -0
- package/dist/client/index.mjs.map +7 -0
- package/dist/client/script.mjs +2 -0
- package/dist/client/script.mjs.map +7 -0
- package/dist/client/style.css +605 -0
- package/dist/respec-gib.node.mjs +5 -0
- package/dist/server/server.mjs +20157 -0
- package/dist/server/server.mjs.map +7 -0
- package/generate-version-file.js +35 -0
- package/package.json +27 -0
- package/src/client/AUTO-GENERATED-version.mts +11 -0
- package/src/client/README.md +19 -0
- package/src/client/api/function-infos.web.mts +38 -0
- package/src/client/api/space-gib-api-bridge.mts +85 -0
- package/src/client/bootstrap.mts +49 -0
- package/src/client/components/keystone-creator/keystone-creator.css +139 -0
- package/src/client/components/keystone-creator/keystone-creator.html +26 -0
- package/src/client/components/keystone-creator/keystone-creator.mts +229 -0
- package/src/client/constants.mts +76 -0
- package/src/client/custom.d.ts +11 -0
- package/src/client/dev-tools.mts +540 -0
- package/src/client/helpers.web.mts +178 -0
- package/src/client/index.html +147 -0
- package/src/client/index.mts +59 -0
- package/src/client/script.mts +13 -0
- package/src/client/style.css +605 -0
- package/src/client/types.mts +85 -0
- package/src/client/ui/shell/space-gib-shell-constants.mts +24 -0
- package/src/client/ui/shell/space-gib-shell-service.mts +233 -0
- package/src/client/ui/shell/space-gib-shell-types.mts +5 -0
- package/src/client/witness/app/space-gib/space-gib-app-v1.mts +160 -0
- package/src/client/witness/app/space-gib/space-gib-constants.mts +38 -0
- package/src/client/witness/app/space-gib/space-gib-helper.mts +72 -0
- package/src/client/witness/app/space-gib/space-gib-types.mts +47 -0
- package/src/common/keystone-policies.mts +159 -0
- package/src/respec-gib.node.mts +6 -0
- package/src/server/README.md +18 -0
- package/src/server/bootstrap-helper.mts +141 -0
- package/src/server/bootstrap-helper.respec.mts +100 -0
- package/src/server/metaspace-nodeindexedspace/metaspace-nodeindexedspace.mts +85 -0
- package/src/server/path-constants.mts +89 -0
- package/src/server/path-helper.mts +101 -0
- package/src/server/path-helper.respec.mts +94 -0
- package/src/server/serve-gib/CHANGELOG.md +29 -0
- package/src/server/serve-gib/README.md +34 -0
- package/src/server/serve-gib/constants.mts +1 -0
- package/src/server/serve-gib/handlers/api/debug/ws-echo.handler.mts +104 -0
- package/src/server/serve-gib/handlers/api/health.handler.mts +23 -0
- package/src/server/serve-gib/handlers/api/health.respec.mts +51 -0
- package/src/server/serve-gib/handlers/api/ibgib/ibgib-handler-types.mts +49 -0
- package/src/server/serve-gib/handlers/api/ibgib/ibgib.handler.mts +176 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-evolve.handler.mts +261 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts +146 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-get.handler.mts +198 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-get.respec.mts +107 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-handler-types.mts +29 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-post.handler.mts +70 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-post.respec.mts +130 -0
- package/src/server/serve-gib/handlers/error-handler.mts +36 -0
- package/src/server/serve-gib/handlers/handler-base.mts +383 -0
- package/src/server/serve-gib/handlers/static-handler.mts +82 -0
- package/src/server/serve-gib/handlers/ws/sync-upgrade.handler.mts +498 -0
- package/src/server/serve-gib/handlers/ws/ws-helper.mts +111 -0
- package/src/server/serve-gib/handlers/ws/ws-types.mts +53 -0
- package/src/server/serve-gib/serve-gib-helpers.mts +32 -0
- package/src/server/serve-gib/serve-gib-v1.mts +172 -0
- package/src/server/serve-gib/serve-gib.respec.mts +90 -0
- package/src/server/serve-gib/types.mts +102 -0
- package/src/server/server-constants.mts +2 -0
- package/src/server/server.mts +96 -0
- package/tsconfig.json +29 -0
- package/tsconfig.server.json +29 -0
- package/tsconfig.test.json +27 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../libs/helper-gib/src/constants.mts", "../../../../libs/helper-gib/src/helpers/utils-helper.mts", "../../../../libs/ts-gib/src/helper.mts", "../../../../libs/ts-gib/src/V1/sha256v1.mts", "../../../../libs/ts-gib/src/V1/types.mts", "../../../../libs/ts-gib/src/V1/constants.mts", "../../../../libs/ts-gib/src/V1/transforms/transform-helper.mts", "../../../../libs/ts-gib/src/V1/transforms/fork.mts", "../../../../libs/ts-gib/src/V1/transforms/mut8.mts", "../../../../libs/ts-gib/src/V1/transforms/rel8.mts", "../../../../libs/ts-gib/src/V1/v1-helper.mts", "../../../../libs/ts-gib/src/V1/validate-helper.mts", "../../../../libs/ts-gib/src/V1/factory.mts", "../../../../libs/core-gib/src/core-constants.mts", "../../../../libs/core-gib/src/common/other/other-types.mts", "../../../../libs/core-gib/src/witness/robbot/robbot-constants.mts", "../../../../libs/core-gib/src/witness/space/space-constants.mts", "../../../../libs/core-gib/src/common/root/root-constants.mts", "../../../../libs/core-gib/src/common/tag/tag-constants.mts", "../../../../libs/core-gib/src/common/other/other-constants.mts", "../../../../libs/core-gib/src/common/other/ibgib-constants.mts", "../../../../libs/core-gib/src/witness/app/app-constants.mts", "../../../../libs/core-gib/src/witness/space/bootstrap/bootstrap-constants.mts", "../../../../libs/encrypt-gib/src/types.mts", "../../../../libs/encrypt-gib/src/helper.mts", "../../../../libs/encrypt-gib/src/constants.mts", "../../../../libs/encrypt-gib/src/common/encrypt-decrypt-common.mts", "../../../../libs/encrypt-gib/src/stream-mode/encrypt-from-hex-stream-mode.mts", "../../../../libs/encrypt-gib/src/stream-mode/decrypt-to-hex-stream-mode.mts", "../../../../libs/encrypt-gib/src/stream-mode/decrypt-stream-mode.mts", "../../../../libs/encrypt-gib/src/stream-mode/encrypt-stream-mode.mts", "../../../../libs/encrypt-gib/src/block-mode/encrypt-from-hex-block-mode.mts", "../../../../libs/encrypt-gib/src/block-mode/decrypt-to-hex-block-mode.mts", "../../../../libs/encrypt-gib/src/block-mode/decrypt-block-mode.mts", "../../../../libs/encrypt-gib/src/block-mode/encrypt-block-mode.mts", "../../../../libs/encrypt-gib/src/encrypt-decrypt.mts", "../../../../libs/core-gib/src/common/encrypt/encrypt-constants.mts", "../../../../libs/core-gib/src/witness/space/space-types.mts", "../../../../libs/core-gib/src/common/form/form-helper.mts", "../../../../libs/core-gib/src/witness/witness-form-builder.mts", "../../../../libs/core-gib/src/witness/app/app-helper.mts", "../../../../libs/core-gib/src/witness/app/chat-app/chat-app-types.mts", "../../../../libs/core-gib/src/witness/app/raw-app/raw-app-types.mts", "../../../../libs/core-gib/src/witness/app/todo-app/todo-app-types.mts", "../../../../libs/core-gib/src/witness/space/bootstrap/bootstrap-helper.mts", "../../../../libs/core-gib/src/common/meta-stone/meta-stone-constants.mts", "../../../../libs/core-gib/src/common/meta-stone/meta-stone-helper.mts", "../../../../libs/core-gib/src/witness/witness-constants.mts", "../../../../libs/core-gib/src/witness/space/space-helper.mts", "../../../../libs/core-gib/src/common/other/ibgib-helper.mts", "../../src/client/constants.mts", "../../src/client/AUTO-GENERATED-version.mts", "../../../../libs/web-gib/src/constants.mts", "../../../../libs/core-gib/src/common/other/other-helper.web.mts", "../../../../libs/core-gib/src/common/import-export/import-export-constants.mts", "../../../../libs/core-gib/src/common/import-export/import-export-helper.web.mts", "../../../../libs/web-gib/src/ui/ui-helpers.mts", "../../../../libs/web-gib/src/helpers.mts", "../../../../libs/web-gib/src/helpers.web.mts", "../../../../libs/web-gib/src/storage/storage-helpers.web.mts", "../../src/client/helpers.web.mts", "../../../../libs/core-gib/src/keystone/keystone-types.mts", "../../../../libs/core-gib/src/keystone/strategy/keystone-strategy.mts", "../../../../libs/core-gib/src/keystone/kdf/kdf-constants.mts", "../../../../libs/core-gib/src/keystone/kdf/kdf-helpers.mts", "../../../../libs/core-gib/src/keystone/strategy/hash-reveal-v1/hash-reveal-v1.mts", "../../../../libs/core-gib/src/keystone/strategy/keystone-strategy-factory.mts", "../../../../libs/core-gib/src/keystone/keystone-constants.mts", "../../../../libs/core-gib/src/common/other/graph-helper.mts", "../../../../libs/core-gib/src/keystone/keystone-helpers.mts", "../../../../libs/core-gib/src/keystone/keystone-service-v1.mts", "../../../../libs/core-gib/src/keystone/keystone-config-builder.mts", "../../src/common/keystone-policies.mts", "../../src/client/api/space-gib-api-bridge.mts", "../../src/client/dev-tools.mts"],
|
|
4
|
+
"sourcesContent": ["\n/**\n * @internal\n * Used internally for logging.\n */\nexport const HELPER_LOG_A_LOT = false;\n\nexport const DEFAULT_UUID = undefined;\nexport const UUID_REGEXP = /^[a-zA-Z0-9_\\-.]{1,256}$/;\n\n/**\n * regular expression for a classname.\n *\n * Used in witnesses atm.\n */\nexport const CLASSNAME_REGEXP = /^[a-zA-Z0-9_]{1,255}$/;\n\n/**\n * capture groups for expected (in various places). will return `null` if\n * does not have an id section like `(E: abcdef32chars)`.\n */\nexport const ERROR_MSG_WITH_ID_CAPTURE_GROUPS_REGEXP = /^(\\[.+\\])?\\s?(\\(UNEXPECTED\\)|\\(unexpected\\))?(.+)(\\([EIWeiw]: [a-fA-F\\d]{32}\\))(\\(UNEXPECTED\\)|\\(unexpected\\))?$/;\nexport const ERROR_MSG_LOCATION_ONLY_REGEXP = /^(\\[.+\\]).+$/;\n\n/**\n * RegExp for a hexadecimal string of length 32\n */\nexport const HEXADECIMAL_HASH_STRING_REGEXP_32 = /^[0-9a-fA-F]{32}$/;\n/**\n * RegExp for a hexadecimal string of length 64\n */\nexport const HEXADECIMAL_HASH_STRING_REGEXP_64 = /^[0-9a-fA-F]{64}$/;\n\n/**\n * When you have a comma-delimited list of word characters and maybe some specials.\n *\n * @see {@link COMMA_DELIMITED_SIMPLE_STRINGS_REGEXP_DESCRIPTION}\n */\nexport const COMMA_DELIMITED_SIMPLE_STRINGS_REGEXP = /^[\\w\\-]+(,?[\\w+\\-])*$/;\n/**\n * Human-readable description to {@link COMMA_DELIMITED_SIMPLE_STRINGS_REGEXP}\n *\n * It is meant to be used with validation errors helper.\n *\n * **WARNING** obviously this can get out of sync.\n */\nexport const COMMA_DELIMITED_SIMPLE_STRINGS_REGEXP_DESCRIPTION = 'text must only be comma-delimited, no-spaces simple words like \"comment,link,pic,x,under_score,hyphens-ok-too\"';\n\n/**\n * When expressing ibgib data paths, this will be used as the delimiter\n * to indicate a sub-object.\n *\n * # notes\n *\n * This should be used with the understanding that having overly-complex data\n * maps is an indication that the ibgib may possibly be better designed as\n * multiple ibgibs linked via their rel8ns.\n *\n * That said, I think it will be common for grouping settings, especially\n * mapping from external sources (API, SDK, etc.).\n */\nexport const DEFAULT_DATA_PATH_DELIMITER = '/';\n\n/**\n * If a string has only non-alphanumerics, this may be returned when getting a safer substring.\n */\nexport const ONLY_HAS_NON_ALPHANUMERICS = '_nonalphanumerics_';\n", "import { DEFAULT_DATA_PATH_DELIMITER, HELPER_LOG_A_LOT, ONLY_HAS_NON_ALPHANUMERICS } from \"../constants.mjs\";\n\nconst logalot = HELPER_LOG_A_LOT || false;\n\nlet crypto: any = globalThis.crypto;\nlet { subtle } = crypto;\n\nexport type HashAlgorithm = 'SHA-256' | 'SHA-512';\nexport const HashAlgorithm: { [key: string]: HashAlgorithm } = {\n 'sha_256': 'SHA-256' as HashAlgorithm,\n 'sha_512': 'SHA-512' as HashAlgorithm,\n}\n\nexport function clone(obj: any) {\n return JSON.parse(JSON.stringify(obj));\n}\nexport function getTimestamp(date?: Date) {\n return (date ?? new Date()).toUTCString();\n}\n\n/**\n * Simple hash function.\n *\n * NOTE:\n * This is not used for ibGib.gib values (ATOW)\n * but rather as a helper function for generating random UUIDs.\n *\n * @param s string to hash\n * @param algorithm to use, currently only 'SHA-256'\n */\nexport async function hash({\n s,\n algorithm = 'SHA-256',\n}: {\n s: string,\n algorithm?: HashAlgorithm,\n}): Promise<string> {\n if (!s) { return ''; }\n\n try {\n const validAlgorithms = Object.values(HashAlgorithm);\n if (!validAlgorithms.includes(algorithm)) {\n throw new Error(`Only ${validAlgorithms} implemented (E: 73cb52cd4d7f70c3415fdf695ba6ba23)`);\n }\n const msgUint8 = new TextEncoder().encode(s);\n const buffer = await subtle.digest(algorithm, msgUint8);\n const asArray = Array.from(new Uint8Array(buffer));\n return asArray.map(b => b.toString(16).padStart(2, '0')).join('');\n } catch (error) {\n console.error(extractErrorMsg(error.message));\n throw error;\n // return ''; // why had I decided to return an empty string on error?\n }\n}\n\n/**\n * Simple func to generate UUID (sha-256 hash basically).\n *\n * @param seedSize size of seed for UUID generation\n */\nexport async function getUUID(seedSize = 64): Promise<string> {\n let uuid: string = '';\n if (seedSize < 32) { throw new Error(`Seed size must be at least 32`); }\n if (!globalThis.crypto) { throw new Error(`Cannot create UUID, as unknown crypto library version. If using node.js, v19+ is required. (E: c02cee3fd8a94f678d3f4ebe9dc49797)`); }\n\n const values = crypto.getRandomValues(new Uint8Array(16));\n uuid = await hash({ s: values.join('') });\n\n if (!uuid) { throw new Error(`Did not create UUID...hmm...`); }\n\n return uuid;\n}\n\n/**\n * Syntactic sugar for JSON.stringify(obj, null, 2);\n *\n * @param obj to pretty stringify\n */\nexport function pretty(obj: any): string {\n return JSON.stringify(obj, null, 2);\n}\n\n/**\n * Just delays given number of ms.\n *\n * @param ms milliseconds to delay\n */\nexport async function delay(ms: number): Promise<void> {\n return new Promise<void>(resolve => {\n setTimeout(() => {\n resolve();\n }, ms);\n });\n}\n\n/**\n * extracts the error message from an error object/string/falsy arg.\n *\n * ## notes\n *\n * * some libs throw errors, some throw just strings.\n * * who knows what else it could be.\n *\n * ## todo\n *\n * * extract inner errors/causes if we ever use this function extensively.\n *\n * @param error the error object in the catch area of the try..catch block.\n * @returns error.message if it's a string, error itself if it's a string, or canned error messages if it's falsy or none of the above.\n */\nexport function extractErrorMsg(error: any): string {\n if (!error && error !== 0) {\n return '[error is falsy]';\n } else if (typeof error === 'string') {\n return error;\n } else if (typeof error.message === 'string') {\n return error.message;\n } else if (typeof error === 'number') {\n return JSON.stringify(error);\n } else if (!!error.error) {\n // the caller has used the \"wrong\" signature type\n console.warn(`[${extractErrorMsg.name}] this fn takes the raw error object. no destructure required. change your call from extractErrorMsg({error}) to extractErrorMsg(error). (W: ea49af5fd76d4b80a55a108d73a3e9b4)`);\n return extractErrorMsg(error.error);\n } else {\n return `[error is not a string and error.message is not a string. typeof error: ${typeof error} (E: d5a7723ca59646838308bc9e53a43134)]`;\n }\n}\n\nexport function groupBy<TItem>({\n items,\n keyFn,\n}: {\n items: TItem[],\n keyFn: (x: TItem) => string,\n}): { [key: string]: TItem[] } {\n const lc = `[${groupBy.name}]`;\n try {\n const result: { [key: string]: TItem[] } = {};\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const key = keyFn(item);\n result[key] = [...(result[key] ?? []), item];\n }\n return result;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n\n/**\n * Just trying to centralize and standardize regular expressions here...\n */\nexport function getRegExp({\n min,\n max,\n chars,\n noSpaces,\n}: {\n min?: number,\n max?: number,\n chars?: string,\n noSpaces?: boolean,\n}): RegExp {\n min = min ?? 1;\n max = max ?? 999999999999;\n chars = chars ?? '';\n\n return noSpaces ?\n new RegExp(`^[\\\\w${chars}]{${min},${max}}$`) :\n new RegExp(`^[\\\\w\\\\s${chars}]{${min},${max}}$`);\n}\n\n/**\n * syntactic sugar for `(new Date()).getTime().toString()`\n * @returns ticks string\n */\nexport function getTimestampInTicks(timestamp?: string): string {\n let date: Date;\n if (timestamp) {\n date = new Date(timestamp);\n if (date.toString() === \"Invalid Date\") {\n throw new Error(`invalid date created by timestamp (${timestamp}) (E: cbd6aeefe00708184e276ea3c2532b22)`);\n }\n } else {\n date = new Date();\n }\n return date.getTime().toString();\n}\n\n/**\n * ## requires\n * at least either `startDate` or one of the intervals to be truthy.\n *\n * ## thanks\n *\n * https://stackoverflow.com/questions/8609261/how-to-determine-one-year-from-now-in-javascript\n *\n * ## tested manually eek\n```\nconsole.log(new Date().toUTCString());\n// Mon, 14 Feb 2022 14:19:32 GMT\nconsole.log(getExpirationUTCString({years: 1}));\n// Tue, 14 Feb 2023 14:19:32 GMT\nconsole.log(getExpirationUTCString({months: 13}));\n// Tue, 14 Mar 2023 13:19:32 GMT\nconsole.log(getExpirationUTCString({days: 365}));\n// Tue, 14 Feb 2023 14:19:32 GMT\nconsole.log(getExpirationUTCString({days: 45}));\n// Thu, 31 Mar 2022 13:19:32 GMT\nconsole.log(getExpirationUTCString({years: 1, days: 45, hours: 25, seconds: 70}));\n// Sat, 01 Apr 2023 14:20:42 GMT\nconsole.log(getExpirationUTCString({days: 10, hours: 10, seconds: 10}));\n// Fri, 25 Feb 2022 00:19:42 GMT\nconsole.log(getExpirationUTCString({years: 1, days: 45, hours: 25, seconds: 70}));\n// Sat, 01 Apr 2023 14:20:42 GMT\nconsole.log(getExpirationUTCString({years: 1, days: 45, hours: 25, seconds: 35}));\n// Sat, 01 Apr 2023 14:20:07 GMT\n```\n */\nexport function getExpirationUTCString({\n startDate,\n years,\n months,\n days,\n hours,\n seconds,\n}: {\n startDate?: Date,\n years?: number,\n months?: number,\n days?: number,\n hours?: number,\n seconds?: number,\n}): string {\n const lc = `[${getExpirationUTCString.name}]`;\n try {\n return addTimeToDate({\n startDate, years, months, days, hours, seconds,\n }).toUTCString();\n } catch (error) {\n console.log(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport function addTimeToDate({\n startDate,\n years,\n months,\n days,\n hours,\n seconds,\n}: {\n startDate?: Date,\n years?: number,\n months?: number,\n days?: number,\n hours?: number,\n seconds?: number,\n}): Date {\n const lc = `[${addTimeToDate.name}]`;\n try {\n if (!startDate && !years && !months && !days && !hours && !seconds) {\n // throw here because otherwise we would return an expiration\n // timestamp string with now as the expiration, which doesn't make\n // sense.\n throw new Error(`either startDate or a time interval required. (E: 30248f8b306f443ab036fa8c313c50d8)`);\n }\n\n // don't want to mutate the incoming date\n startDate = startDate ?\n new Date(startDate) :\n new Date(); // default to now\n\n /** incoming years/months/days/hours/seconds to add to start date */\n let intervalToAdd: number;\n /** start date + interval in ticks, before assigning to Date obj */\n let newDateTicks: number;\n\n if (years) {\n intervalToAdd = startDate.getFullYear() + years;\n newDateTicks = startDate.setFullYear(intervalToAdd);\n // call recursively for other interval args (if any)\n return addTimeToDate({\n startDate: new Date(newDateTicks),\n months, days, hours, seconds, // all but years (just set)\n })\n } else if (months) {\n intervalToAdd = startDate.getMonth() + months;\n newDateTicks = startDate.setMonth(intervalToAdd);\n // call recursively for other interval args (if any)\n return addTimeToDate({\n startDate: new Date(newDateTicks),\n years, days, hours, seconds, // all but months (just set)\n })\n } else if (days) {\n intervalToAdd = startDate.getDate() + days;\n newDateTicks = startDate.setDate(intervalToAdd);\n // call recursively for other interval args (if any)\n return addTimeToDate({\n startDate: new Date(newDateTicks),\n years, months, hours, seconds, // all but days (just set)\n })\n } else if (hours) {\n intervalToAdd = startDate.getHours() + hours;\n newDateTicks = startDate.setHours(intervalToAdd);\n // call recursively for other interval args (if any)\n return addTimeToDate({\n startDate: new Date(newDateTicks),\n years, months, days, seconds, // all but hours (just set)\n })\n } else if (seconds) {\n intervalToAdd = startDate.getSeconds() + seconds;\n newDateTicks = startDate.setSeconds(intervalToAdd);\n // call recursively for other interval args (if any)\n return addTimeToDate({\n startDate: new Date(newDateTicks),\n years, months, days, hours, // all but seconds (just set)\n })\n } else {\n // we've called our function recursively and all intervals args\n // falsy now, so startDate is the output date.\n return startDate;\n }\n } catch (error) {\n console.log(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport function isExpired({\n expirationTimestampUTC,\n}: {\n expirationTimestampUTC: string,\n}): boolean {\n const lc = `[${isExpired.name}]`;\n try {\n if (!expirationTimestampUTC) { throw new Error(`expirationTimestampUTC required (E: 5eeb1e29f93d64f70c71a8112080a222)`); }\n\n let expirationDate = new Date(expirationTimestampUTC);\n if (expirationDate.toUTCString() === \"Invalid Date\") { throw new Error(`invalid expirationTimestampUTC: ${expirationTimestampUTC} (E: 66a1a165bcf1f9336fe78856ab777822)`); }\n\n const now = new Date();\n const expired = expirationDate < now;\n return expired;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Creates a new array that is a unique set of incoming `arr`.\n * @param arr array to make unique\n * @returns new array with unique items\n */\nexport function unique<T>(arr: T[]): T[] {\n return Array.from(new Set<T>(arr));\n}\n\n// export function getExt(path: string): { filename: string, ext: string } {\n// const pathPieces = path.split('/');\n// const fullFilename = pathPieces[pathPieces.length-1];\n// if (fullFilename.includes('.') && !fullFilename.endsWith('.')) {\n// const lastDotIndex = fullFilename.lastIndexOf('.');\n// return {\n// filename: fullFilename.slice(0, lastDotIndex),\n// ext: fullFilename.slice(lastDotIndex+1),\n// };\n// } else {\n// return {filename: fullFilename, ext: \"\"}\n// }\n// }\n\nexport function patchObject({\n obj,\n value,\n path,\n pathDelimiter,\n logalot,\n}: {\n obj: Object,\n value: any,\n path: string,\n pathDelimiter?: string,\n logalot?: number | boolean,\n}): void {\n const lc = `[${patchObject.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!obj) { throw new Error(`obj required (E: 6a9dd32a361476e80b1bf7b91ec50522)`); }\n if (typeof obj !== 'object') { throw new Error(`obj must be type 'object' (E: 66fdc289b32c06492bd95f5d266e6a22)`); }\n if (!path) { throw new Error(`path required (at the very least should be the key in the root obj.) (E: fc779e7794ead8a0b44e5f2e776b0e22)`); }\n\n /** atow defaults to a forward slash, but could be a dot or who knows */\n pathDelimiter = pathDelimiter || DEFAULT_DATA_PATH_DELIMITER;\n\n /**\n * the target starts off at the object level itself, but we will\n * traverse the given path, updating the targetObj as we go.\n */\n let targetObj: { [key: string | number]: any } = obj;\n const pathPieces = path.split(pathDelimiter).filter(x => !!x);\n\n /** the last one is the key into the final targetObj with value */\n const key = pathPieces.pop()!;\n\n // ensure each intermediate path exists and is an object\n pathPieces.forEach(piece => {\n let currentValue = targetObj[piece];\n if (currentValue) {\n if (typeof currentValue !== 'object') { throw new Error(`invalid path into object. Each step along the path must be typeof === 'object', but typeof targetObj[\"${piece}\"] === ${typeof currentValue}. (value: ${currentValue}) (E: 38cf29c5f624a40b4b56502c2ec39d22)`); }\n } else {\n // if not exist, create it\n targetObj[piece] = {};\n }\n\n // update targetObj ref\n targetObj = targetObj[piece];\n });\n\n // reached target depth, so finally set the value\n targetObj[key] = value;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function getIdPool({\n n,\n}: {\n n: number,\n}): Promise<string[]> {\n const lc = `[${getIdPool.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n let result: string[] = [];\n for (let i = 0; i < n; i++) {\n const id = await getUUID();\n result.push(id.substring(0, 16));\n }\n return result;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getSaferSubstring({\n text,\n length,\n keepLiterals = ['-'],\n replaceMap,\n}: {\n text: string;\n length?: number,\n /**\n * list of strings that you want to keep in the resultant string verbatim (without alteration).\n *\n * ## driving use case\n *\n * I want user comments that start with a question mark (?) to signify a\n * request to a robbot, e.g. \"?start someAddr^gib\" or whatever. So I want to\n * keep the question mark. I thought of an encoding mapping, like ? =>\n * \"__qstmark__\" but it's easier just to keep it, as this function was\n * originally intended to just nerf text in general because there was no\n * reason not to. well now there is a reason.\n *\n * I'm adding in a couple other characters in common use for whenever I get around\n * to making those mean something in the app (#, @)\n */\n keepLiterals?: string[],\n /**\n *\n */\n replaceMap?: { [s: string]: string },\n}): string {\n const lc = `[${getSaferSubstring.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 27437e312e5aa621adfebb84e059c822)`); }\n if (!text) { throw new Error(`text required (E: 87e0493613c8b30dfade83e1d2862a22)`); }\n\n let saferText: string = text;\n\n // before stripping \"unsafe\" characters, replace all instances of\n // keepLiterals with a temporary token if applicable\n let tokenToKeepMap: { [token: string]: string } = {};\n keepLiterals = keepLiterals ?? [];\n for (let i = 0; i < keepLiterals.length; i++) {\n const keep = keepLiterals[i];\n let tmpToken: string;\n do {\n tmpToken = pickRandom_Letters({ count: 10 });\n } while (tmpToken.includes(keep) || keep.includes(tmpToken) || text.includes(tmpToken));\n\n // replace instances of keep literals with our token\n if (saferText.includes(keep)) {\n tokenToKeepMap[tmpToken] = keep;\n while (saferText.includes(keep)) {\n saferText = saferText.replace(keep, tmpToken);\n }\n }\n }\n\n if (replaceMap && Object.keys(replaceMap).length > 0) {\n for (let i = 0; i < Object.keys(replaceMap).length; i++) {\n const toReplace = Object.keys(replaceMap)[i];\n const replaceWith = replaceMap[toReplace];\n while (saferText.includes(toReplace)) {\n saferText = saferText.replace(toReplace, replaceWith);\n }\n }\n }\n\n // now remove every non-alphanumeric\n saferText = saferText.replace(/\\W/g, '');\n\n // before checking length, put back in our keep literals (if any)\n const tokens = Object.keys(tokenToKeepMap);\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n while (saferText.includes(token)) {\n saferText = saferText.replace(token, tokenToKeepMap[token]);\n }\n }\n\n // trim the text to length if specified\n if (length && length > 0) {\n // debugger;\n // let resText: string;\n\n if (saferText.length > length) {\n if (logalot) { console.log(`${lc} curtailing length (I: d7a28e05daa5979c7686b4c1cf519b23)`); }\n saferText = saferText.substring(0, length);\n }\n }\n\n // replace if text only has characters/nonalphanumerics (\"unsafe\").\n if (saferText.length === 0) { saferText = ONLY_HAS_NON_ALPHANUMERICS; }\n\n return saferText;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * picks a random item from an array\n */\nexport function pickRandom<T extends any>({ x }: { x: T[] }): T | undefined {\n if ((x ?? []).length === 0) { return undefined; /* <<<< returns early */ }\n let randomIndex = Math.floor(Math.random() * x.length);\n return x[randomIndex];\n}\n\n/**\n * NOT strong crypto!\n *\n * returns `count` number of letters concatenated into a string.\n */\nexport function pickRandom_Letters({ count }: { count: number }): string {\n const lc = `${pickRandom_Letters.name}]`;\n try {\n if (!Number.isInteger(count)) { throw new Error(`count required to be a number. (E: c0a21d884ebd9afc4b2e8025207e0522)`); }\n let result: string = \"\";\n for (let i = 0; i < count; i++) {\n result += pickRandom({ x: 'a b c d e f g h i j k l m n o p q r s t u v w x y z'.split(' ') });\n }\n if (result.length !== count) { throw new Error(`${lc} (UNEXPECTED) result.length !== count ? (E: 9bec4ec8f78610d8055e565415392a22)`); }\n return result;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * creates a text selection of the entire element's text.\n *\n * ty https://stackoverflow.com/questions/985272/selecting-text-in-an-element-akin-to-highlighting-with-your-mouse\n *\n * @param el element whose text we're selecting\n */\nexport function selectElementText(el: HTMLElement): void {\n const lc = `[${selectElementText.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0971989c737e5b846894357f671ab322)`); }\n if (((document as any).body).createTextRange) {\n const range = ((document as any).body).createTextRange();\n range.moveToElementText(el);\n range.select();\n } else if (window.getSelection) {\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n const range = document.createRange();\n range.selectNodeContents(el);\n selection.addRange(range);\n } else {\n throw new Error(`(UNEXPECTED) window.getSelection() returned false? (E: 722b2d3084ed43fe8da22d889ddb52b8)`);\n }\n } else {\n throw new Error(`(UNEXPECTED) cannot select element text? (E: 163a1dd811b4f4bc22dd6823db859322)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * replaces an individual character at a position.\n *\n * ## driving use case\n *\n * part of functionality to replace entire words with underscores (_'s) for blanking out\n * stimulations in wordy robbot.\n *\n * @returns string with replaced characters\n */\nexport function replaceCharAt({\n s,\n pos,\n newChar,\n}: {\n s: string,\n pos: number,\n newChar: string,\n}): string {\n const chars = s.split('');\n chars[pos] = newChar;\n return chars.join('');\n}\n\n/**\n * Apparently it's a pain to determine if a keyboard event is hitting the\n * \"enter\" key across platforms.\n *\n * @link https://bugs.chromium.org/p/chromium/issues/detail?id=79407\n * @link https://stackoverflow.com/questions/3883543/javascript-different-keycodes-on-different-browsers\n *\n * @returns true if the event is the user pressing the \"Enter\" key, else false\n */\nexport function isKeyboardEvent_Enter(event: KeyboardEvent): boolean {\n const isEnter = event.key === 'Enter' || event.code === 'Enter';\n // event.keyCode === 10 || event.keyCode === 13 ||\n // event.charCode === 10 || event.charCode === 13;\n return isEnter;\n}\n\n/**\n * https://github.com/ionic-team/capacitor/issues/1564\n *\n * Still doesn't work...hmm\n */\nexport function getFileReaderHack(): FileReader {\n const lc = `[${getFileReaderHack.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: d03faf53dd5f1cd1014f2f0e01058b22)`); }\n const fileReader = new FileReader();\n const zoneOriginalInstance = (fileReader as any)[\"__zone_symbol__originalInstance\"];\n return zoneOriginalInstance || fileReader;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * checks for mouse/trackball presence and infers keyboard when one is detected.\n *\n * ## aside\n *\n * It's amazing this isn't in an API...\n *\n * @returns true if by magical inference there is probably* a keyboard\n */\nexport function weHaveAPhysicalKeyboardProbably(): boolean {\n const lc = `${weHaveAPhysicalKeyboardProbably.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 70a952db8e1f23263ba98607def6f422)`); }\n const hasHover = window?.matchMedia?.('(hover:hover)').matches;\n const hasPointerFine = window?.matchMedia?.('(pointer:fine)').matches;\n return hasHover && hasPointerFine;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Check for either a physical keyboard or a relatively large window\n *\n * ## notes\n *\n * Such a long silly name because it's silly we don't have a better way of\n * detecting this with an official API.\n *\n * @returns true if we think that we're running on mobile\n */\nexport function weAreRunningOnMobileProbably(): boolean {\n const lc = `${weAreRunningOnMobileProbably.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5fd8deba6cb8cd40633c69371df95f22)`); }\n const keyboard = weHaveAPhysicalKeyboardProbably();\n const isMightyLargeForMobile = window.innerWidth > 810;\n return keyboard || isMightyLargeForMobile;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Combines two maps/arrays into a single one with some very basic, naive merge rules:\n *\n * 1. If a key exists in only one map, then it will be included in the output map.\n * 2. If a key exists in both maps and the type is array or map, then these will be recursively merged.\n * 3. If a key exists in both maps but is not an array or map, the dominant map's value wins.\n *\n * ## future\n *\n * In the future, if we want to keep these kinds of things around and be more\n * specific about mergers, we can always rel8 a merge strategy ibgib to be\n * referred to when performing merger.\n */\nexport function mergeMapsOrArrays_Naive<T extends {} | any[]>({\n dominant,\n recessive,\n}: {\n /**\n * when two keys are not arrays or maps themselves, this one's value is\n * chosen for output.\n */\n dominant: T,\n /**\n * when two keys are not arrays or maps themselves, this one's value is NOT\n * chosen for output.\n */\n recessive: T,\n}): T {\n const lc = `[${mergeMapsOrArrays_Naive.name}]`;\n try {\n if (Array.isArray(dominant) && Array.isArray(recessive)) {\n // arrays\n const output: any[] = clone(dominant) as any[];\n let warned = false;\n (recessive as []).forEach((recessiveItem: any) => {\n if (typeof (recessiveItem) === 'string') {\n if (!output.includes(recessiveItem)) { output.push(recessiveItem); }\n } else {\n if (!warned) {\n console.warn(`${lc} merging arrays of non-string elements. (W: d8ab113064834abc8eb5fe6c4cf87ba3)`);\n warned = true;\n }\n // we'll check the stringified version of recessive item against\n // the stringified dominant item.\n const xString = JSON.stringify(recessiveItem);\n if (!output.some(o => JSON.stringify(o) === xString)) {\n output.push(recessiveItem);\n }\n }\n });\n return (output as T);\n } else if (typeof (dominant) === 'object' && typeof (recessive) === 'object') {\n // maps\n const output: { [key: string]: any } = { ...recessive };\n const dominantKeys: string[] = Object.keys(dominant);\n const recessiveKeys: string[] = Object.keys(recessive);\n dominantKeys.forEach((key: string) => {\n if (recessiveKeys.includes(key)) {\n\n // naive merge for key that exists in both dominant & recessive\n if (Array.isArray((dominant as any)[key]) && Array.isArray((recessive as any)[key])) {\n // recursive call if both arrays\n output[key] = mergeMapsOrArrays_Naive<any[]>({\n dominant: (dominant as any)[key],\n recessive: (recessive as any)[key],\n });\n } else if (\n !!(dominant as any)[key] && !Array.isArray((dominant as any)[key]) && typeof ((dominant as any)[key]) === 'object' &&\n !!(recessive as any)[key] && !Array.isArray((recessive as any)[key]) && typeof ((recessive as any)[key]) === 'object'\n ) {\n // recursive call if both objects\n output[key] = mergeMapsOrArrays_Naive<{}>({\n dominant: (dominant as any)[key],\n recessive: (recessive as any)[key],\n });\n } else {\n (output as any)[key] = (dominant as any)[key];\n }\n } else {\n output[key] = (dominant as any)[key];\n }\n });\n\n return output as T;\n } else {\n // ? unknown matching of dominant and recessive\n console.warn(`${lc} unknown values or value types do not match. Both should either be an array or map. Dominant one wins categorically without any merging. (W: 3690ea19b81a4b89b98c1940637df62c)`);\n return (dominant as T);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n};\n", "import { Ib, Gib, IbGib, IbGibAddr, IbAndGib } from './types.mjs';\n\n\n/**\n * Gets the ib^gib address from the given ib and gib or\n * from the ibGib object.\n *\n * Need to refactor to getIbGibAddr\n */\nexport function getIbGibAddr({\n ib, gib, ibGib, delimiter = '^'\n}: {\n ib?: Ib,\n gib?: Gib,\n ibGib?: IbGib,\n delimiter?: string\n}): IbGibAddr {\n ib = ib || ibGib?.ib || '';\n gib = gib || ibGib?.gib || '';\n return ib + delimiter + gib;\n}\n\n/**\n * Get the ib and gib fields from an ibGib object or ibGibAddr\n * with the given `delimiter`.\n */\nexport function getIbAndGib({\n ibGib,\n ibGibAddr,\n delimiter = '^'\n}: {\n ibGibAddr?: IbGibAddr,\n ibGib?: IbGib,\n delimiter?: string\n}): IbAndGib {\n const lc = '[getIbAndGib]';\n if (!ibGibAddr) {\n if (ibGib) {\n ibGibAddr = getIbGibAddr({ ibGib });\n } else {\n throw new Error(`${lc} We need either an address or an ibGib object`);\n }\n }\n if (!ibGibAddr) { throw new Error(`${lc} Couldn't get ibGibAddr. ibGib invalid?`); }\n\n if (!delimiter) { delimiter = '^'; }\n\n const pieces = ibGibAddr.split(delimiter);\n if (pieces.length === 2) {\n // normal v1 case, e.g. 'ib^gib' or 'tag home^ABC123'\n return { ib: pieces[0], gib: pieces[1] };\n } else if (pieces.length === 1 && ibGibAddr.endsWith(delimiter)) {\n // normal v1 primitive, e.g. '7^' or 'name^'\n return { ib: pieces[0], gib: '' };\n } else if (pieces.length === 1 && ibGibAddr.startsWith(delimiter)) {\n // only gib/hash is provided like maybe a binary file\n // e.g. ^ABC123 or ^XYZ456 or ^some_gib_that_isnt_a_hash\n return { ib: '', gib: pieces[0] };\n } else if (pieces.length === 2 && pieces[0] === '' && pieces[1] === '') {\n // edge case of address is only the delimiter.\n // So it's the primitive for that delimiter\n return { ib: delimiter, gib: '' };\n // } else if (pieces.length === 0 ) {\n // ibGibAddr is falsy, so would have thrown earlier in this function\n // I'm just noting this case for intent ATOW\n } else {\n console.warn(`${lc} multiple delimiters found in ibGibAddr. Considering last delimiter as the demarcation of gib hash`);\n // e.g. 'ib^ABC123^gib'\n // ib: 'ib^ABC123'\n // gib: 'gib'\n return {\n ib: pieces.slice(0, pieces.length - 1).join(delimiter),\n gib: pieces.slice(pieces.length - 1)[0],\n }\n }\n}\n\n\n/**\n * Normalizes an object/value for consistent hashing.\n * - Recursively processes objects and arrays.\n * - For objects:\n * - Sorts keys alphabetically.\n * - Removes properties whose values are `undefined`.\n * - Keeps properties whose values are `null`.\n * - For arrays:\n * - Preserves element order.\n * - Recursively normalizes each element.\n * - Primitives (strings, numbers, booleans) and `null` are returned as is.\n *\n * @param value The value to normalize.\n * @returns The normalized value.\n *\n * This has been adjusted due to conversation with Gemini and working on python\n * port. The main thing here is that we normalize array members, but not the\n * array itself. This way the array's order is preserved, but any object members\n * are themselves normalized.\n */\nexport function toNormalizedForHashing(value: any): any {\n // Handle null, primitives (string, number, boolean) directly.\n // `undefined` at the top level will be handled by the caller or become part of an object/array.\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n // Handle Arrays: recursively normalize elements, preserve order\n if (Array.isArray(value)) {\n return value.map(element => toNormalizedForHashing(element));\n }\n\n // Handle Objects (plain objects)\n const normalizedObject: { [key: string]: any } = {};\n const sortedKeys = Object.keys(value).sort();\n\n for (const key of sortedKeys) {\n const propertyValue = value[key];\n if (propertyValue !== undefined) { // CRITICAL: Only omit if value is undefined\n normalizedObject[key] = toNormalizedForHashing(propertyValue);\n }\n // If propertyValue is undefined, it's omitted from normalizedObject.\n // If propertyValue is null, it's included.\n }\n return normalizedObject;\n}\n", "import { extractErrorMsg } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from \"./types.mjs\";\nimport { Ib } from \"../types.mjs\";\n\nlet crypto: any = globalThis.crypto;\nlet { subtle } = crypto;\n\n/**\n * Performs the gib hash like V1\n *\n * I have it all in one function for smallest, most independent version possible.\n *\n * #thanks https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest\n * #thanks https://stackoverflow.com/questions/49129643/how-do-i-merge-an-array-of-uint8arrays\n * #thanks https://stackoverflow.com/a/49129872/3897838 (answer to above)\n *\n * @param ibGib ibGib for which to calculate the gib\n */\nexport function sha256v1_old(ibGib: IbGib_V1, salt: string = \"\"): Promise<string> {\n // console.log('func_gib_sha256v1 executed');\n if (!salt) { salt = \"\"; }\n let hashToHex = async (message: string | undefined) => {\n if (!message) { return \"\"; }\n const msgUint8 = new TextEncoder().encode(message);\n const buffer = await subtle.digest('SHA-256', msgUint8);\n const asArray = Array.from(new Uint8Array(buffer));\n // return hashAsHex\n return asArray.map(b => b.toString(16).padStart(2, '0')).join('');\n };\n let hashToHex_Uint8Array = async (salt: string, msgUint8: Uint8Array) => {\n let tohashUint8Array: Uint8Array;\n if (salt) {\n const msgUint8_salt = new TextEncoder().encode(salt);\n tohashUint8Array = new Uint8Array(msgUint8_salt.length + msgUint8.length);\n tohashUint8Array.set(msgUint8_salt);\n tohashUint8Array.set(msgUint8, msgUint8_salt.length);\n } else {\n tohashUint8Array = msgUint8;\n }\n const hashAsBuffer = await subtle.digest('SHA-256', tohashUint8Array);\n const hashAsArray = Array.from(new Uint8Array(hashAsBuffer));\n // return hashAsHex\n return hashAsArray.map(b => b.toString(16).padStart(2, '0')).join('');\n };\n let hashFields;\n if (salt) {\n hashFields = async (ib: Ib, data: IbGibData_V1 | undefined, rel8ns: IbGibRel8ns_V1 | undefined) => {\n const hasRel8ns =\n Object.keys(rel8ns || {}).length > 0 &&\n Object.keys(rel8ns || {}).some(k => rel8ns![k] && rel8ns![k]!.length > 0);\n let hasData = !!data;\n if (hasData) {\n if (typeof data === 'string') {\n hasData = (data as string).length > 0;\n } else if (data instanceof Uint8Array) {\n hasData = true;\n } else if (typeof data === 'object') {\n hasData = Object.keys((data) || {}).length > 0;\n } else {\n hasData = true;\n }\n }\n const ibHash = (await hashToHex(salt + ib)).toUpperCase();\n // empty, null, undefined all treated the same at this level.\n const rel8nsHash: string = hasRel8ns ? (await hashToHex(salt + JSON.stringify(rel8ns))).toUpperCase() : \"\";\n // empty, null, undefined all treated the same at this level (though not farther down in data)\n\n // change this for binaries (Uint8Array data)\n // const dataHash: string = hasData ? (await hashToHex(salt + JSON.stringify(data))).toUpperCase() : \"\";\n let dataHash: string = \"\";\n if (hasData) {\n if (data instanceof Uint8Array) {\n dataHash = (await hashToHex_Uint8Array(salt, data)).toUpperCase();\n } else {\n dataHash = (await hashToHex(salt + JSON.stringify(data))).toUpperCase();\n }\n }\n\n // if the ibgib has no rel8ns or data, the hash should be just of the ib itself.\n const allHash = hasRel8ns || hasData ?\n (await hashToHex(salt + ibHash + rel8nsHash + dataHash)).toUpperCase() :\n (await hashToHex(salt + ibHash)).toUpperCase();\n return allHash;\n };\n } else {\n hashFields = async (ib: Ib, data: IbGibData_V1 | undefined, rel8ns: IbGibRel8ns_V1 | undefined) => {\n const hasRel8ns =\n Object.keys(rel8ns || {}).length > 0 &&\n Object.keys(rel8ns || {}).some(k => rel8ns![k] && rel8ns![k]!.length > 0);\n // const hasData = Object.keys((data) || {}).length > 0;\n let hasData = !!data;\n if (hasData) {\n if (typeof data === 'string') {\n hasData = (data as string).length > 0;\n } else if (data instanceof Uint8Array) {\n hasData = true;\n } else if (typeof data === 'object') {\n hasData = Object.keys((data) || {}).length > 0;\n } else {\n hasData = true;\n }\n }\n const ibHash = (await hashToHex(ib)).toUpperCase();\n // empty, null, undefined all treated the same at this level.\n const rel8nsHash: string = hasRel8ns ? (await hashToHex(JSON.stringify(rel8ns))).toUpperCase() : \"\";\n // empty, null, undefined all treated the same at this level (though not farther down in data)\n // const dataHash: string = hasData ? (await hashToHex(JSON.stringify(data))).toUpperCase() : \"\";\n let dataHash: string = \"\";\n if (hasData) {\n if (data instanceof Uint8Array) {\n dataHash = (await hashToHex_Uint8Array('', data)).toUpperCase();\n } else {\n dataHash = (await hashToHex(JSON.stringify(data))).toUpperCase();\n }\n }\n // if the ibgib has no rel8ns or data, the hash should be just of the ib itself.\n const allHash = hasRel8ns || hasData ?\n (await hashToHex(ibHash + rel8nsHash + dataHash)).toUpperCase() :\n (await hashToHex(ibHash)).toUpperCase();\n return allHash;\n }\n }\n return hashFields(ibGib.ib, ibGib?.data, ibGib?.rel8ns);\n}\n\nexport function sha256v1(ibGib: IbGib_V1, salt: string = \"\"): Promise<string> {\n // console.log('func_gib_sha256v1 executed');\n if (!salt) { salt = \"\"; }\n let hashToHex = async (message: string | undefined) => {\n if (!message) { return \"\"; }\n const msgUint8 = new TextEncoder().encode(message);\n const buffer = await subtle.digest('SHA-256', msgUint8);\n const asArray = Array.from(new Uint8Array(buffer));\n // return hashAsHex\n return asArray.map(b => b.toString(16).padStart(2, '0')).join('');\n };\n let hashToHex_Uint8Array = async (salt: string, msgUint8: Uint8Array) => {\n let tohashUint8Array: Uint8Array;\n if (salt) {\n const msgUint8_salt = new TextEncoder().encode(salt);\n tohashUint8Array = new Uint8Array(msgUint8_salt.length + msgUint8.length);\n tohashUint8Array.set(msgUint8_salt);\n tohashUint8Array.set(msgUint8, msgUint8_salt.length);\n } else {\n tohashUint8Array = msgUint8;\n }\n const hashAsBuffer = await subtle.digest('SHA-256', tohashUint8Array);\n const hashAsArray = Array.from(new Uint8Array(hashAsBuffer));\n // return hashAsHex\n return hashAsArray.map(b => b.toString(16).padStart(2, '0')).join('');\n };\n\n /**\n * THIS IS DUPLICATED CODE IN THE RESPEC FILE. ANY CHANGES HERE MUST\n * MANUALLY BE CHANGED IN THE RESPEC FILE!!!\n *\n * Normalizes an object/value for consistent hashing.\n * - Recursively processes objects and arrays.\n * - For objects:\n * - Sorts keys alphabetically.\n * - Removes properties whose values are `undefined`.\n * - Keeps properties whose values are `null`.\n * - For arrays:\n * - Preserves element order.\n * - Recursively normalizes each element.\n * - Primitives (strings, numbers, booleans) and `null` are returned as is.\n *\n * THIS IS DUPLICATED CODE IN THE RESPEC FILE. ANY CHANGES HERE MUST\n * MANUALLY BE CHANGED IN THE RESPEC FILE!!!\n *\n * @param value The value to normalize.\n * @returns The normalized value.\n */\n const toNormalizedForHashing = (value: any) => {\n // Handle null, primitives (string, number, boolean) directly.\n // `undefined` at the top level will be handled by the caller or become part of an object/array.\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n // Handle Arrays: recursively normalize elements, preserve order\n if (Array.isArray(value)) {\n return value.map(element => toNormalizedForHashing(element));\n }\n\n // Handle Objects (plain objects)\n const normalizedObject: { [key: string]: any } = {};\n const sortedKeys = Object.keys(value).sort();\n\n for (const key of sortedKeys) {\n const propertyValue = value[key];\n if (propertyValue !== undefined) { // CRITICAL: Only omit if value is undefined\n normalizedObject[key] = toNormalizedForHashing(propertyValue);\n }\n // If propertyValue is undefined, it's omitted from normalizedObject.\n // If propertyValue is null, it's included.\n }\n return normalizedObject;\n\n // if (!obj) {\n // return obj; /* <<<< returns early */\n // } else if (typeof obj === 'string' || Array.isArray(obj)) {\n // return obj.concat(); /* <<<< returns early */\n // } else if (typeof obj !== 'object') {\n // // Return non-objects as is, we don't know how to concat/copy it...hmm...\n // return obj; /* <<<< returns early */\n // }\n\n // // we have an object. we will create a new object and populate it.\n // const normalized = {};\n\n // // sort keys alphabetically\n // // NOTE: this does NOT mutate obj as Object.keys produces a new array\n // const keys = Object.keys(obj).sort();\n\n // for (const key of keys) {\n // const value = obj[key];\n // if (value !== undefined) {\n // // Recursively normalize if the value is an object\n // normalized[key] = (typeof value === 'object' && value !== null) ? toNormalizedForHashing(value) : value;\n // }\n // }\n // return normalized;\n }\n\n\n let hashFields;\n if (salt) {\n hashFields = async (ib: Ib, data: IbGibData_V1 | undefined, rel8ns: IbGibRel8ns_V1 | undefined) => {\n const hasRel8ns =\n Object.keys(rel8ns || {}).length > 0 &&\n Object.keys(rel8ns || {}).some(k => rel8ns![k] && rel8ns![k]!.length > 0);\n let hasData = !!data;\n if (hasData) {\n if (typeof data === 'string') {\n hasData = (data as string).length > 0;\n } else if (data instanceof Uint8Array) {\n hasData = true;\n } else if (typeof data === 'object') {\n hasData = Object.keys((data) || {}).length > 0;\n } else {\n hasData = true;\n }\n }\n const ibHash = (await hashToHex(salt + ib)).toUpperCase();\n // empty, null, undefined all treated the same at this level.\n const rel8nsHash: string = hasRel8ns ? (await hashToHex(salt + JSON.stringify(toNormalizedForHashing(rel8ns)))).toUpperCase() : \"\";\n // empty, null, undefined all treated the same at this level (though not farther down in data)\n\n // change this for binaries (Uint8Array data)\n // const dataHash: string = hasData ? (await hashToHex(salt + JSON.stringify(data))).toUpperCase() : \"\";\n let dataHash: string = \"\";\n if (hasData) {\n if (data instanceof Uint8Array) {\n dataHash = (await hashToHex_Uint8Array(salt, data)).toUpperCase();\n } else {\n dataHash = (await hashToHex(salt + JSON.stringify(toNormalizedForHashing(data)))).toUpperCase();\n }\n }\n\n // if the ibgib has no rel8ns or data, the hash should be just of the ib itself.\n const allHash = hasRel8ns || hasData ?\n (await hashToHex(salt + ibHash + rel8nsHash + dataHash)).toUpperCase() :\n (await hashToHex(salt + ibHash)).toUpperCase();\n return allHash;\n };\n } else {\n hashFields = async (ib: Ib, data: IbGibData_V1 | undefined, rel8ns: IbGibRel8ns_V1 | undefined) => {\n const hasRel8ns =\n Object.keys(rel8ns || {}).length > 0 &&\n Object.keys(rel8ns || {}).some(k => rel8ns![k] && rel8ns![k]!.length > 0);\n // const hasData = Object.keys((data) || {}).length > 0;\n let hasData = !!data;\n if (hasData) {\n if (typeof data === 'string') {\n hasData = (data as string).length > 0;\n } else if (data instanceof Uint8Array) {\n hasData = true;\n } else if (typeof data === 'object') {\n hasData = Object.keys((data) || {}).length > 0;\n } else {\n hasData = true;\n }\n }\n const ibHash = (await hashToHex(ib)).toUpperCase();\n // empty, null, undefined all treated the same at this level.\n const rel8nsHash: string = hasRel8ns ? (await hashToHex(JSON.stringify(toNormalizedForHashing(rel8ns)))).toUpperCase() : \"\";\n // empty, null, undefined all treated the same at this level (though not farther down in data)\n // const dataHash: string = hasData ? (await hashToHex(JSON.stringify(data))).toUpperCase() : \"\";\n let dataHash: string = \"\";\n if (hasData) {\n if (data instanceof Uint8Array) {\n dataHash = (await hashToHex_Uint8Array('', data)).toUpperCase();\n } else {\n dataHash = (await hashToHex(JSON.stringify(toNormalizedForHashing(data)))).toUpperCase();\n }\n }\n // if the ibgib has no rel8ns or data, the hash should be just of the ib itself.\n const allHash = hasRel8ns || hasData ?\n (await hashToHex(ibHash + rel8nsHash + dataHash)).toUpperCase() :\n (await hashToHex(ibHash)).toUpperCase();\n return allHash;\n }\n }\n return hashFields(ibGib.ib, ibGib?.data, ibGib?.rel8ns); // conditional nav ibGib?.data and ibGib?.rel8ns\n}\n\n/**\n * I have one large-ish sha256 function for gibbing purposes\n * (dream where metabootstrapping is better)\n * this is just testing a function that is internal to the sha256v1 func.\n * terrible as can be duplicated, but simple for now.\n */\nexport async function hashToHexCopy(\n message: string | undefined\n): Promise<string | undefined> {\n if (!message) { return \"\"; }\n try {\n const msgUint8 = new TextEncoder().encode(message);\n const buffer = await subtle.digest('SHA-256', msgUint8);\n const asArray = Array.from(new Uint8Array(buffer));\n return asArray.map(b => b.toString(16).padStart(2, '0')).join('');\n } catch (e) {\n console.error(extractErrorMsg(e.message));\n return undefined;\n }\n};\n", "/**\n * The core of the simplicity of the ibGib protocol is that you are\n * taking two (or more) ibGibs and producing other ibGibs.\n *\n * There are three primary functions: mut8, rel8, fork\n *\n * These are actually different aspects of the single function of\n * relationship and time, either:\n * 1) Creating a 'new' timeline, or...\n * 2) Extending an existing one.\n *\n * Mut8 is intrinsic, rel8 is extrinsic, fork is a new timeline.\n * Mut8 changes a timeline, rel8 changes a timeline's link(s),\n * fork creates a new timeline.\n */\nimport {\n IbGibRel8ns, IbGibAddr, IbGibWithDataAndRel8ns, Gib,\n} from '../types.mjs';\n\n/**\n * Need to see if I can remove this...\n */\nexport declare type IbGibData_V1 = {\n [key: string]: any;\n /**\n * if true, this is the very first ibgib in a timeline.\n *\n * in the future, it is possible that there will be multiple temporal\n * junction points and that this may be true for multiple ibgibs in a\n * timeline. but atow (02/2024) and the foreseeable future, this should only\n * be true for the very first ibgib.\n *\n */\n isTjp?: boolean;\n /**\n * special property meant to track evolution count. So when a transform is\n * applied to a punctiliar ibgib, this value is incremented if that ibgib\n * has a temporal junction point (tjp).\n */\n n?: number;\n /**\n * the timestamp that the ibgib was created/evolved. to get the\n * milliseconds, get/set {@link timestampMs}\n */\n timestamp?: string;\n /**\n * the ms component of {@link timestamp}\n */\n timestampMs?: number;\n /**\n * if given, this is the unique identification for the ibgib. note that\n * there is often a good use case for this when linking multiple ibgibs\n * together in some operation. but usually this is a convenience property.\n * most actual identification should often be done with the ib^gib address,\n * either the tjp or punctiliar address depending on use case.\n */\n uuid?: string;\n};\n\n/**\n * Convenience enum to avoid spelling mistakes. (optional)\n */\nexport enum Rel8n {\n past = 'past',\n ancestor = 'ancestor',\n dna = 'dna',\n identity = 'identity',\n tjp = 'tjp',\n secret = 'secret',\n encryption = 'encryption',\n}\n/**\n * shape of named edges (hard links) to other ibgibs which forms a dependency\n * graph (DAG) in V1.\n *\n * Note that all rel8ns are open-ended, because this is how rel8ns actually\n * exist. For example, consider that any relationship conceived nowadays in CS\n * as one-to-one, actually can be thought of as many-to-many when considering\n * multiple timelines.\n */\nexport interface IbGibRel8ns_V1 extends IbGibRel8ns {\n /**\n * when an ibgib is evolved, this is a rel8n to pointer(s) in the ibgib\n * timeline's history.\n *\n * depending on use case, this could only be a single pointer to the most\n * recent past (like a linked list or blockchain), or it could be the entire\n * history from inception of the ibgib.\n * @optional\n */\n [Rel8n.past]?: IbGibAddr[];\n /**\n * associate the owner/producer of the ibgib. not in use atow (02/2024), so\n * this may change or be yagni. the keystone structure will solve this.\n * @optional\n */\n [Rel8n.identity]?: IbGibAddr[];\n /**\n * when an ibgib is forked, this is the parent.\n * @optional\n */\n [Rel8n.ancestor]?: IbGibAddr[];\n /**\n * points to the dna that are the history of applied transforms that got the\n * ibgib to its current state.\n * @optional\n */\n [Rel8n.dna]?: IbGibAddr[];\n /**\n * temporal junction point of the ibgib.\n *\n * this is set if either uuid or timestamp tjp setting is used when the most\n * recent transform was applied.\n * @optional\n */\n [Rel8n.tjp]?: IbGibAddr[];\n /**\n * if there is any encryption related to this ibgib, most likely for\n * enciphering one or more properties in the ibgib's `ib` and/or `data`\n * properties, the associated secret(s) can be linked here.\n * @optional\n */\n [Rel8n.secret]?: IbGibAddr[];\n /**\n * if there is any encryption related to this ibgib, most likely for\n * enciphering one or more properties in the ibgib's `ib` and/or `data`\n * properties, the encryption ibgibs (which hold encryption details like\n * encryption algorithm + parameterization) can be linked here.\n * @optional\n */\n [Rel8n.encryption]?: IbGibAddr[];\n}\n/**\n * combined shape of the overall v1 ibgib. it has an ib, gib, data, and rel8ns. */\nexport interface IbGib_V1<TData = IbGibData_V1, TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1>\n extends IbGibWithDataAndRel8ns<TData, TRel8ns> {\n}\n\nexport interface GibInfo {\n /**\n * Hash for this ibgib frame in time.\n */\n punctiliarHash?: string;\n /**\n * The gib for this ibgib's most recent tjp.\n *\n * ## notes\n *\n * ATOW, only one tjp expected really, though I've been coding\n * with the possibility of having multiple tjp's similar to\n * checkpoints.\n */\n tjpGib?: Gib;\n /**\n * If\n */\n piecesCount?: number;\n /**\n * If a delimiter is used in this gib, this is the delimiter.\n *\n * ## notes\n *\n * ATOW, the caller already knows the delimiter. But I'm thinking that\n * I may be persisting this at some point and it would be good to include.\n */\n delimiter?: string;\n /**\n * True the gib is just 'gib' (GIB constant), else falsy.\n */\n isPrimitive?: boolean;\n}\n", "import { IbGib_V1 } from './types.mjs';\n\n/**\n * This is essentially an alias of the string literal `'ib'`\n */\nexport const IB = 'ib';\n/**\n * This is essentially an alias of the string literal `'gib'`\n *\n * When you have a primitive ibgib, this should be the `ibGib.gib` value, as\n * there is no hashing metadata for primitives.\n */\nexport const GIB = 'gib';\n/**\n * This is the root ibgib from which all ibgib are ultimately forked.\n * It has 0 and infinite data, 0 and infinite rel8ns. Its ib and gib\n * are simply 'ib' and 'gib'.\n */\nexport const ROOT: IbGib_V1 = { ib: IB, gib: GIB, }\n/**\n * The default delimiter is the caret (^) symbol. This is derived from\n * taking an ib^gib address and turning it into an ibGib object (note\n * the capitalized \"G\").\n */\nexport const IBGIB_DELIMITER = '^';\n/**\n * Gib is often just a single hash for a single ib^gib record.\n * But if the ibgib has a tjp, which implies a timeline (\"stream\"\n * in some senses), then we will include the tjp gib hash alongside the\n * individual punctilear ibgib frame.\n *\n * ATOW this has the default schema of\n *\n * @example \"comment abc^TJPHASH123\", \"comment abc^TJPHASH123.THISRECORDHASH456\"\n */\nexport const GIB_DELIMITER = '.';\n/**\n * This is the address of the ROOT ibgib with the default delimiter (caret ^).\n */\nexport const ROOT_ADDR = 'ib^gib'; // `${IB}${IBGIB_DELIMITER}${GIB}`;\n/**\n * Some rel8ns should not be able to be renamed or removed, as these have\n * \"special\" semantic meaning in the low-level graphing protocol.\n *\n * ## notes\n *\n * * Of course, this can be forged or tinkered with, and that ultimately is what\n * consensus would be utilized for.\n * * protocols built on top of this may also have reserved rel8n/data key names\n */\nexport const FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES = ['past', 'ancestor', 'dna', 'tjp'];\n\nexport const IB_MAX_LENGTH_DEFAULT = 155;\n\n/**\n * Defaults to word characters, space, tab, hyphen, and other\n * non-slash (path navigating) chars.\n *\n * Does not allow new lines or other whitespace, only tabs and spaces.\n *\n * ## atow\n *\n * `^[\\\\w\\\\t\\\\-|=+.&%\\$#@!~\\` \\\\[\\\\]\\\\(\\\\)\\\\{\\\\}]{1,${IB_MAX_LENGTH_DEFAULT}}$`\n */\nexport const IB_REGEXP_DEFAULT = new RegExp(`^[\\\\w\\\\t\\\\-|=+.&%\\$#@!~\\` \\\\[\\\\]\\\\(\\\\)\\\\{\\\\}]{1,${IB_MAX_LENGTH_DEFAULT}}$`);", "import { clone, extractErrorMsg, } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { TransformOpts, IbGib, Gib, IbGibAddr, } from \"../../types.mjs\";\nimport { getIbGibAddr, getIbAndGib, } from \"../../helper.mjs\";\nimport { sha256v1, } from \"../sha256v1.mjs\";\nimport { GibInfo, IbGib_V1, } from \"../types.mjs\";\nimport { IBGIB_DELIMITER, GIB, GIB_DELIMITER } from \"../constants.mjs\";\n\nexport async function buildDna<TSrc extends IbGib_V1, TOpts extends TransformOpts<TSrc>>(\n opts: TOpts,\n): Promise<IbGib_V1> {\n const transformData: TOpts = clone(opts);\n let lc = `[${buildDna.name}]`;\n\n // remove references to the srcAddr, as this will be captured\n // by the ibGib's `past` rel8n. This way, we can reapply dna\n // to different src's more easily, as well as have less unique dna\n if (transformData.srcAddr) { delete transformData.srcAddr; }\n\n // remove all references to actual objects in this, we just\n // want the data. ATOW, src is a reference to the src object\n // and we only want the srcAddr\n delete transformData.src;\n\n // dna is never timestamped or uniquely identified hmm...\n // or rel8d to anything...hmmm\n // so much dna, best to minimize though of course we dont\n // want to prematurely optimize...but there's a looooot of dna.\n // best to share/reuse as much as possible.\n const result: IbGib_V1 = {\n ib: transformData.type!,\n data: transformData,\n rel8ns: {\n ancestor: [\n `${transformData.type!.toString()}${IBGIB_DELIMITER}${GIB}` // e.g. fork^gib\n ]\n }\n };\n\n result.gib = await sha256v1(result);\n\n return result;\n}\n\nexport function isDna({ ibGib }: { ibGib: IbGib }): boolean {\n const lc = `[${isDna.name}]`;\n try {\n if (!ibGib) { throw new Error(`ibGib required.`); }\n\n // console.log(`${lc} ibGib: ${pretty(ibGib)}`);\n\n // ancestor is known transform is the best way for v1 ATOW\n const knownTransformPrimitiveAddrs =\n ['fork', 'mut8', 'rel8', 'plan'].map(x => `${x}^${GIB}`); // plan from prev versions\n const hasTransformAncestor =\n ((ibGib as any).rel8ns) &&\n ((ibGib as any).rel8ns.ancestor) &&\n (Array.isArray((ibGib as any).rel8ns.ancestor)) &&\n ((((ibGib as any).rel8ns.ancestor) as any) as any).\n some((x: any) => knownTransformPrimitiveAddrs.includes(x));\n\n return hasTransformAncestor || false;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nexport function isPrimitive({ ibGib, gib }: { ibGib?: IbGib_V1, gib?: Gib }): boolean {\n if (ibGib) {\n return isPrimitive({ gib: ibGib.gib });\n } else if (gib) {\n return gib === GIB;\n } else {\n // falsy gib means it's primitive or a programming error...hmm\n return true;\n }\n}\n\n/**\n * Generates the gib of a given `ibGib` depending on\n * @returns gib - either bare hash for those with no tjp; or tjp-scoped hash; or 'gib' for primitives\n */\nexport async function getGib({\n ibGib,\n hasTjp,\n tjpAddr,\n gibDelimiter,\n isPrimitive,\n hashAlgorithm,\n}: {\n /**\n * We'll take the `ib`, `data`, and `rel8ns` from this\n */\n ibGib: IbGib_V1,\n /**\n * If true, then we'll treat this as having a tjp.\n * If falsy, then we'll check the internals of the ibGib to see if it has a tjp.\n */\n hasTjp?: boolean;\n /**\n * @deprecated\n *\n * IGNORED\n *\n * This is now always searched for in the ibGib itself.\n */\n tjpAddr?: IbGibAddr,\n /**\n * What to use as the delimiter for the `gib`.\n *\n * @default GIB_DELIMITER\n *\n * ## notes\n *\n * This is not the same thing necessarily as the ib^gib delimiter.\n * In fact the default gibDelimiter ATOW ('.') is different than the\n * default ib^gib delimiter ('^').\n */\n gibDelimiter?: string,\n /**\n * If this is primitive, then the `gib` is always GIB (\"gib\" string literal).\n */\n isPrimitive?: boolean,\n /**\n * Hash algorithm to use when calculating the gib hash of the ibgib datum.\n *\n * ## notes\n *\n * * I'm just including this now to show where we will expand when working with\n * multiple hash algorithms. For now though, in all of V1, we use 'SHA-256'\n * when calculating the gib hashes. This is why I'm hard-coding the type\n * here instead of using this lib's `HashAlgorithm` type.\n * * This param is actually ignored ATOW.\n * * In my current consuming use case (ionic-gib), though,\n * I am indeed using SHA-512 when encrypting using encrypt-gib. I only note\n * this in case someone sees \"SHA-512\" code somewhere and is confused.\n */\n hashAlgorithm?: 'SHA-256',\n}): Promise<string> {\n const lc = `[${getGib.name}]`;\n try {\n if (!ibGib) { throw new Error(`ibGib required. (E: 17d073226b9d42fd841e5a94b065ef21)`); }\n if (isPrimitive) { return GIB; }\n const ibGibHash = await sha256v1(ibGib, '');\n const rel8ns = ibGib.rel8ns ?? {};\n const data = ibGib.data ?? {};\n gibDelimiter = gibDelimiter || GIB_DELIMITER;\n if (!hasTjp) { hasTjp = (rel8ns.tjp ?? []).length > 0 || data.isTjp || false; }\n if (hasTjp) {\n let tjpAddrGib: string | undefined;\n if (rel8ns.tjp) {\n if (rel8ns.tjp.length === 1) {\n if (rel8ns.tjp[0]) { // checking for empty string\n tjpAddr = rel8ns.tjp[0];\n } else {\n throw new Error(`rel8ns.tjp[0] is falsy. (E: ed879d2b039543f8b1902e8b7b5a5a7b)`);\n }\n } else if (rel8ns.tjp.length > 1) {\n if (rel8ns.tjp[rel8ns.tjp.length - 1]) {\n console.warn(`${lc} found more than one tjp addr...only expecting 1 ATOW. (W: 10ed43f716e743e0afd1954f1ab46789)`);\n tjpAddr = rel8ns.tjp[rel8ns.tjp.length - 1];\n } else {\n throw new Error(`multiple tjp addrs, and the last (most recent) one is falsy. (E: bc835dc89be24075bba8b2b6616ea069)`);\n }\n } else {\n // empty rel8ns.tjp array?\n throw new Error(`hasTjp is true but rel8ns.tjp is empty array. (E: d08b2f9e86494814b5e7d7b4602b2ab7)`);\n }\n } else if (data.isTjp) {\n // the ibGib itself is the tjp\n tjpAddr = getIbGibAddr({ ib: ibGib.ib, gib: ibGibHash });\n } else {\n throw new Error(`hasTjp is true, but both ibGib.rel8ns.tjp and ibGib.data.isTjp are falsy. (E: 4e246897e52044789594d853bb5b66ee)`)\n }\n tjpAddrGib = tjpAddr ? getIbAndGib({ ibGibAddr: tjpAddr }).gib : undefined;\n\n if (tjpAddrGib) {\n // if the ibGib IS the tjp, then the gib is only the hash\n\n // if the ibGib is NOT the tjp, then the gib is the hash plus\n // tjpGib. note in the future, if multiple tjps are going, then\n // tjpAddrGib itself may have another delim inside it, so we\n // will end up with a gib with multiple delimiters.\n return data.isTjp ? ibGibHash : `${ibGibHash}${GIB_DELIMITER}${tjpAddrGib}`;\n } else {\n throw new Error(`hasTjp is true but could not find tjpAddrGib. (E: 1863df626b754744a1d431a683cb0ba0)`);\n }\n } else {\n // no tjp, so gib is just the hash\n return ibGibHash;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n\n}\n\n/**\n * Parses gib (either via `gib` param or `ibGibAddr.gib`) and returns information\n * about it.\n *\n * @returns Information about the given `gib` (or `gib` extracted from `ibGibAddr`)\n */\nexport function getGibInfo({\n ibGibAddr,\n gib,\n gibDelimiter,\n}: {\n /**\n * If given, will extract `gib` from this.\n */\n ibGibAddr?: IbGibAddr,\n /**\n * `gib` to analyze.\n */\n gib?: Gib,\n /**\n * Delimiter among pieces of gib, if applicable.\n *\n * @default GIB_DELIMITER (ATOW '.')\n *\n * ## notes\n *\n * Some `gib` values will include tjp information, while others\n * are just the hash.\n */\n gibDelimiter?: string,\n}): GibInfo {\n const lc = `[${getGibInfo.name}]`;\n try {\n if (!ibGibAddr && !gib) { throw new Error(`Either ibGibAddr or gib required. (E: 25e3dcbe63cd44909032df12af9df75e)`); }\n gib = gib || getIbAndGib({ ibGibAddr }).gib;\n\n if (gib === GIB) { return { isPrimitive: true } }\n\n gibDelimiter = gibDelimiter ?? GIB_DELIMITER;\n\n if (gib.includes(gibDelimiter)) {\n const pieces = gib.split(gibDelimiter);\n if (pieces.some(p => p === '')) { throw new Error(`unexpected gib that contains gibDelimiter (${gibDelimiter}) but has at least one piece with empty string. (E: 75a94280045541009ee68182d12d3449)`); }\n\n const piecesCount = pieces.length;\n if (piecesCount > 2) { console.warn(`${lc} gib only expected to have two pieces ATOW. re-examine please. (W: aa4283ac5a5747a386a69966ecdad39d)`); }\n\n const punctiliarHashPiece = pieces.splice(0, 1);\n return {\n punctiliarHash: punctiliarHashPiece[0],\n tjpGib: pieces.join(gibDelimiter), // after splice, piece/s is/are tjp\n piecesCount,\n delimiter: gibDelimiter,\n }\n } else {\n return {\n punctiliarHash: gib,\n piecesCount: 1,\n delimiter: gibDelimiter,\n }\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { getIbGibAddr } from '../../helper.mjs';\nimport { clone, getUUID, getTimestamp, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { sha256v1 } from '../sha256v1.mjs';\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1, Rel8n } from '../types.mjs';\nimport { TransformOpts_Fork, TransformResult } from '../../types.mjs';\nimport { IBGIB_DELIMITER, ROOT_ADDR } from '../constants.mjs';\nimport { buildDna } from './transform-helper.mjs';\n\n/**\n * Original-ish V1 transform behavior.\n * Going to create an ibGib containing the fork data.\n * Apply that fork and create a resulting ibGib.\n *\n * Takes the src ibGib, clears its past and adds a link to\n * the src via the 'ancestor' rel8n.\n *\n * NOTE:\n * This is NOT going to do the plan^gib stuff ATM.\n * Also this does NOT add any identity information ATM.\n */\nexport async function fork(opts: TransformOpts_Fork<IbGib_V1>): Promise<TransformResult<IbGib_V1>> {\n const {\n noTimestamp, dna,\n linkedRel8ns,\n destIb, uuid, tjp,\n cloneRel8ns, cloneData,\n type = 'fork',\n } = opts;\n let src = opts.src;\n\n const lc = '[fork_v1]';\n // #region validation\n if (type !== 'fork') { throw new Error(`${lc} not a fork transform.`); }\n if (!opts.type) { opts.type = 'fork' }\n\n if (!src) { throw new Error(`${lc} src required to fork.`); }\n if (!src!.ib) { throw new Error(`${lc} src.ib required.`); }\n // destIb is not required, as it just reuses src.ib\n if (destIb && destIb.includes(IBGIB_DELIMITER)) {\n throw new Error(`${lc} destIb can't contain (hardcoded) delimiter right now.`);\n }\n if (!src!.gib) { throw new Error(`${lc} src.gib required.`); }\n\n // #endregion\n\n // we want to forget `src` proper very quickly because it may have other\n // non-IbGib properties that are not relevant to our transform.\n let dto: IbGib_V1 = { ib: src.ib, gib: src.gib, };\n if (src.data && Object.keys(src.data).length > 0) { dto.data = src.data; }\n if (src.rel8ns && Object.keys(src.rel8ns).length > 0) { dto.rel8ns = src.rel8ns; }\n src = dto;\n\n const srcAddr = getIbGibAddr({ ib: src!.ib, gib: src.gib });\n opts.srcAddr = srcAddr;\n\n const rel8ns: IbGibRel8ns_V1 =\n cloneRel8ns && src.rel8ns && Object.keys(src.rel8ns).length > 0 ?\n clone(src.rel8ns) :\n {};\n delete rel8ns.past;\n const data: any = cloneData && src?.data ? clone(src!.data) : {};\n if (opts.nCounter) { data.n = 0; }\n const ancestor = linkedRel8ns?.includes(Rel8n.ancestor) ?\n [srcAddr] :\n (rel8ns.ancestor || []).concat([srcAddr]);\n rel8ns.ancestor = ancestor;\n\n // remove tjp if exists in rel8ns\n if (rel8ns.tjp) { delete rel8ns.tjp; }\n\n const newIbGib = clone(src) as IbGib_V1<IbGibData_V1>;\n if (noTimestamp && tjp?.timestamp) {\n throw new Error(`${lc} both noTimestamp and tjp.timestamp selected.`);\n }\n if (!noTimestamp || tjp?.timestamp) {\n const date = new Date();\n data.timestamp = getTimestamp(date);\n data.timestampMs = date.getMilliseconds();\n }\n if (tjp?.uuid || uuid) { data.uuid = await getUUID(); }\n if (tjp?.uuid || tjp?.timestamp) {\n data.isTjp = true;\n } else {\n if (data.isTjp) { delete data.isTjp; }\n }\n\n newIbGib.ib = destIb || 'ib';\n // rel8ns ignored if forking from the root ib^gib\n if (srcAddr !== ROOT_ADDR) { newIbGib.rel8ns = rel8ns; }\n if (Object.keys(data).length > 0) { newIbGib.data = data; }\n\n let transformDna: IbGib_V1 | null = null;\n if (dna) {\n transformDna = await buildDna(opts);\n const dnaAddr = getIbGibAddr({ ibGib: transformDna });\n rel8ns.dna = linkedRel8ns?.includes(Rel8n.dna) ?\n rel8ns.dna = [dnaAddr] :\n rel8ns.dna = (rel8ns.dna || []).concat(dnaAddr);\n }\n\n newIbGib.gib = await sha256v1(newIbGib, '');\n\n const result: TransformResult<IbGib_V1> = { newIbGib };\n if (transformDna) { result.dnas = [transformDna!] }\n return result;\n}\n", "import { getIbGibAddr } from '../../helper.mjs';\nimport { clone, getTimestamp, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1, Rel8n } from '../types.mjs';\nimport { TransformOpts_Mut8, TransformResult } from '../../types.mjs';\nimport { IBGIB_DELIMITER, } from '../constants.mjs';\nimport { buildDna, isPrimitive, getGib } from './transform-helper.mjs';\n\n/**\n * Original-ish V1 transform behavior.\n * Going to create a new ibGib which mut8s internal data (or the ib) from the src ibgib.\n *\n * Takes the immutable src ibGib record, applies a mutation to its internal (intrinsic)\n * `data` field, creates a new ibGib with the new intrinsic data.\n *\n * ### remember, ibgib basic structure\n *\n * Remember, the ibGib has the following basic structure (here represented in JSON):\n * {\n * ib: 'some ib, can be a simple name, or other metadata, up to very complex metadata.',\n * gib: 'ABC123', // hash of the other three fields of our JSON data structure\n * rel8ns: {\n * 'link name': [ 'other ibgib^ABC345', 'yo^456789' ],\n * 'called an edge in other jargon': [ 'ib^gib' ],\n * 'past': ['ib^gib']\n * ...\n * },\n * data: {\n * 'intrinsic data': 'intrinsic value',\n * 'copied each datum': 'so should be relatively small in practice',\n * 'can...': {\n * '...also be objects if you really': ['want']\n * }\n * }\n * }\n *\n * So this transform is primarily concerned with that `data` property (though we can mut8 the ib also).\n * If it's really anything complex, most likely it would be better to do\n * another ibGib and link to it via the `rel8ns` (in the same way that in OOP it\n * is good to have single responsibility for class architecture).\n *\n * ### what we can do with mutations\n *\n * We can mutate the `ib` value. So if we need to change metadata (e.g. a 'rename'), we can.\n * This has implications for updating pointer refs and the tjp, but that's more advanced.\n *\n * We can also mutate the intrinsic `data` property, which is basically a JS object style of\n * key/value store.\n *\n * ### notes\n * * This is NOT going to do the plan^gib stuff ATM.\n * * This does NOT add any identity information ATM.\n *\n */\nexport async function mut8<TNewData = any>(\n opts: TransformOpts_Mut8<IbGib_V1, TNewData>\n): Promise<TransformResult<IbGib_V1>> {\n const {\n noTimestamp, dna, linkedRel8ns,\n dataToRename, dataToRemove, dataToAddOrPatch,\n mut8Ib,\n type = 'mut8'\n } = opts;\n let src = opts.src;\n const lc = '[mut8_v1]';\n // #region validation\n\n if (type !== 'mut8') { throw new Error(`${lc} not a mut8 transform.`); }\n if (!opts.type) { opts.type = 'mut8' }\n\n if (!src) { throw new Error(`${lc} src required to mut8.`); }\n if (!src!.ib) { throw new Error(`${lc} src.ib required.`); }\n if (src!.ib!.includes(IBGIB_DELIMITER)) {\n throw new Error(`${lc} ib can't contain hardcoded delimiter (${IBGIB_DELIMITER}) right now.`);\n }\n if (!src!.gib) { throw new Error(`${lc} src.gib required.`); }\n\n if (!mut8Ib && !dataToRename && !dataToRemove && !dataToAddOrPatch) {\n throw new Error(`${lc} gotta provide either a mut8Ib or some data to change.`);\n }\n\n const srcAddr = getIbGibAddr({ ib: src!.ib, gib: src.gib });\n if (opts.srcAddr && srcAddr !== opts.srcAddr) { throw new Error(`${lc} srcAddr from src does not equal opts.srcAddr`); }\n opts.srcAddr = srcAddr;\n\n // const srcIsPrimitive = src.gib === GIB || !src.gib;\n // if (srcIsPrimitive) { throw new Error(`${lc} cannot mutate primitive ibgib`); }\n if (isPrimitive({ ibGib: src })) { throw new Error(`${lc} cannot mutate primitive ibgib`); }\n\n // #endregion\n\n // we want to forget `src` proper very quickly because it may have other\n // non-IbGib properties that are not relevant to our transform.\n let dto: IbGib_V1 = { ib: src.ib, gib: src.gib, };\n if (src.data && Object.keys(src.data).length > 0) { dto.data = src.data; }\n if (src.rel8ns && Object.keys(src.rel8ns).length > 0) { dto.rel8ns = src.rel8ns; }\n src = dto;\n\n const newIbGib = clone(src) as IbGib_V1<IbGibData_V1>;\n\n const srcRel8ns = src.rel8ns ? src.rel8ns : {};\n const rel8ns: IbGibRel8ns_V1 = clone(srcRel8ns);\n rel8ns.past = linkedRel8ns?.includes(Rel8n.past) ?\n [srcAddr] :\n (rel8ns.past || []).concat([srcAddr]);\n\n let data: any = src?.data ? clone(src!.data) : {};\n if (dataToRename) { data = renameOrRemove(data, dataToRename, 'rename'); }\n if (dataToRemove) { data = renameOrRemove(data, dataToRemove, 'remove'); }\n if (dataToAddOrPatch) { data = patch(data, dataToAddOrPatch); }\n if (!noTimestamp) {\n const date = new Date();\n data.timestamp = getTimestamp(date);\n data.timestampMs = date.getMilliseconds();\n }\n\n // n-related\n if (opts.nCounter || Object.keys(data).includes('n')) {\n if (Object.keys(data).includes('n')) {\n if (Number.isInteger(data.n)) {\n if (data.n >= 0) {\n data.n = data.n + 1;\n } else {\n console.warn(`${lc} data.n is less than 0, which is unexpected. Resetting data.n to 0.`);\n data.n = 0;\n }\n } else {\n throw new Error('cannot increment nCounter because data.n is not a number.');\n }\n } else {\n data.n = 0;\n }\n }\n\n // tjp-related\n // let tjpAddr: IbGibAddr | undefined = undefined;\n\n // const srcIsTjp = data.isTjp && (rel8ns.tjp ?? []).length === 0; // if we only want one tjp\n const srcIsTjp = data.isTjp; // if we want to allow more than one tjp\n if (srcIsTjp) {\n // if the src is tjp, e.g. is the first ibgib after a fork,\n // then srcAddr is the tjpAddr\n const tjpRel8n: string[] = rel8ns.tjp ?? [];\n tjpRel8n.push(srcAddr);\n rel8ns.tjp = tjpRel8n;\n delete data.isTjp;\n }\n\n // dna-related\n let transformDna: IbGib_V1 | null = null;\n if (dna) {\n transformDna = await buildDna(opts);\n const dnaAddr = getIbGibAddr({ ibGib: transformDna });\n rel8ns.dna = linkedRel8ns?.includes(Rel8n.dna) ?\n rel8ns.dna = [dnaAddr] :\n rel8ns.dna = (rel8ns.dna || []).concat(dnaAddr);\n }\n\n // set final ib, data, rel8ns, gib values\n newIbGib.ib = mut8Ib ? mut8Ib : newIbGib.ib;\n newIbGib.rel8ns = rel8ns;\n if (Object.keys(data).length > 0) {\n newIbGib.data = data;\n } else {\n // we've removed the last key in the data object so delete it\n delete newIbGib.data;\n }\n const hasTjp = (rel8ns.tjp?.length ?? 0) > 0;\n newIbGib.gib = await getGib({ ibGib: newIbGib, hasTjp });\n\n // wrap in the result and return\n const result: TransformResult<IbGib_V1> = { newIbGib };\n if (transformDna) { result.dnas = [transformDna]; }\n return result;\n}\n\n\nfunction renameOrRemove(obj: any, info: any, which: 'rename' | 'remove'): any {\n const lc = `[renameOrRemove]`;\n const FORBIDDEN_RENAME_REMOVE_KEYS = ['timestamp'];\n Object.keys(info).forEach(key => {\n if (FORBIDDEN_RENAME_REMOVE_KEYS.includes(key)) {\n throw new Error(`${lc} Cannot rename to ${key}.`);\n }\n if (Object.keys(obj).includes(key)) {\n let infoVal = info[key];\n if (typeof (infoVal) === 'string') {\n // rename\n if (FORBIDDEN_RENAME_REMOVE_KEYS.includes(infoVal)) {\n throw new Error(`${lc} Cannot rename to ${infoVal}.`);\n }\n if (which === 'rename') {\n obj[infoVal] = obj[key];\n }\n delete obj[key];\n } else {\n // recurse\n obj[key] = renameOrRemove(obj[key], infoVal, which);\n }\n } else {\n console.log(`${lc} key to ${which} does not exist`);\n }\n });\n return obj;\n};\n\n/**\n * Patches obj (active mutate, does not copy) with patchObj data. Special keys\n * can rename/remove keys, otherwise is an additive patch.\n *\n * @param obj source obj to patch, possibly is a subobject in a recursive call\n * @param patchInfo data to patch into obj, possibly containing nested objects\n */\nfunction patch(obj: any, patchInfo: any): any {\n Object.keys(patchInfo).forEach(patchKey => {\n // grab the patchVal before updating patchKey\n let patchVal = patchInfo[patchKey];\n let objVal = obj[patchKey];\n if (objVal) {\n if (Array.isArray(patchVal) || Array.isArray(objVal)) {\n // both are arrays, so full replace\n obj[patchKey] = patchVal;\n } else if (typeof (patchVal) === 'object' && typeof (objVal) === 'object') {\n // {a: {b: 2}}, {a: {b: 3, c: 4}}\n // patchKey = 'a';\n // patchVal = {b: 3, c: 4}\n // objVal = {b: 2}\n // recurse\n obj[patchKey] = patch(objVal, patchVal);\n } else {\n // not both objects, so full replace\n obj[patchKey] = patchVal;\n }\n } else {\n // does not exist yet, so set new\n obj[patchKey] = patchVal;\n }\n });\n return obj;\n};\n", "import { getIbGibAddr, } from '../../helper.mjs';\nimport { clone, getTimestamp, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1, Rel8n } from '../types.mjs';\nimport { TransformOpts_Rel8, TransformResult, IbGibAddr } from '../../types.mjs';\nimport { IBGIB_DELIMITER, GIB, FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES } from '../constants.mjs';\nimport { buildDna, getGib, isPrimitive } from './transform-helper.mjs';\n/**\n * Original-ish V1 transform behavior.\n *\n * NOTE:\n * This is NOT going to do the plan^gib stuff ATM.\n * Also this does NOT add any identity information ATM.\n */\n/**\n * Relate (and/or unrelate) other ibGib(s), thus mutating it **extrinsically**.\n */\nexport async function rel8(\n opts: TransformOpts_Rel8<IbGib_V1>\n): Promise<TransformResult<IbGib_V1>> {\n const {\n noTimestamp, dna, linkedRel8ns,\n rel8nsToAddByAddr, rel8nsToRemoveByAddr,\n type = 'rel8'\n } = opts;\n let src = opts.src;\n const lc = '[rel8_v1]';\n if (type !== 'rel8') { throw new Error(`${lc} not a rel8 transform.`); }\n if (!opts.type) { opts.type = 'rel8' }\n\n // #region validation\n\n if (type !== 'rel8') { throw new Error(`${lc} not a rel8 transform.`); }\n if (!opts.type) { opts.type = 'rel8' }\n\n if (!src) { throw new Error(`${lc} src required.`); }\n if (!src!.ib) { throw new Error(`${lc} src.ib required.`); }\n if (src!.ib!.includes(IBGIB_DELIMITER)) {\n throw new Error(`${lc} ib can't contain hardcoded delimiter (${IBGIB_DELIMITER}) right now.`);\n }\n if (!src!.gib) { throw new Error(`${lc} src.gib required.`); }\n\n // if (!src.gib || src.gib === GIB) { throw new Error(`${lc} cannot relate to primitive ibGib.`); }\n if (isPrimitive({ ibGib: src })) { throw new Error(`${lc} cannot relate/unrelate primitive ibgib`); }\n\n // if neither add nor remove specified, what are we even doing?\n const isAdding = rel8nsToAddByAddr && Object.keys(rel8nsToAddByAddr!).length > 0;\n const isRemoving = rel8nsToRemoveByAddr && Object.keys(rel8nsToRemoveByAddr!).length > 0;\n if (!(isAdding || isRemoving)) {\n throw new Error(`${lc} gotta provide relations to either add or remove.`);\n }\n\n const srcAddr = getIbGibAddr({ ib: src.ib, gib: src.gib });\n if (opts.srcAddr && srcAddr !== opts.srcAddr) { throw new Error(`${lc} srcAddr from src does not equal opts.srcAddr`); }\n opts.srcAddr = srcAddr;\n\n // validate all ibgib addresses to add/remove\n const fnValidIbGibAddr = (s: string) => {\n // for now, only requiring a single character and trailing delim.\n // i.e. primitive with implied 'gib'\n return s && typeof (s) === 'string' && s.length >= 2 &&\n s.includes('^') && s.split('^')[0].length >= 1;\n };\n Object.keys(rel8nsToAddByAddr || {})\n .map(x => (rel8nsToAddByAddr || {})[x])\n .forEach(rel8ds => {\n if (!(rel8ds && rel8ds.every(rel8d => fnValidIbGibAddr(rel8d)))) {\n throw new Error(`${lc} Invalid rel8n attempt. Must be valid ibGibs. Did you include a delimiter (^)?`);\n }\n });\n Object.keys(rel8nsToRemoveByAddr || {})\n .map(x => (rel8nsToRemoveByAddr || {})[x])\n .forEach(rel8ds => {\n if (!(rel8ds && rel8ds.every(rel8d => fnValidIbGibAddr(rel8d)))) {\n throw new Error(`${lc} Invalid remove rel8n attempt. Must be valid ibGibs. Did you include a delimiter (^)?`);\n }\n });\n\n // #endregion validation\n\n // we want to forget `src` proper very quickly because it may have other\n // non-IbGib properties that are not relevant to our transform.\n let dto: IbGib_V1 = { ib: src.ib, gib: src.gib, };\n if (src.data && Object.keys(src.data).length > 0) { dto.data = src.data; }\n if (src.rel8ns && Object.keys(src.rel8ns).length > 0) { dto.rel8ns = src.rel8ns; }\n src = dto;\n\n const newIbGib = clone(src) as IbGib_V1<IbGibData_V1>;\n\n const data: any = clone(src.data || {});\n if (opts.nCounter || Object.keys(data).includes('n')) {\n if (Object.keys(data).includes('n')) {\n if (Number.isInteger(data.n)) {\n if (data.n >= 0) {\n data.n = data.n + 1;\n } else {\n console.warn(`${lc} data.n is less than 0, which is unexpected. Resetting data.n to 0.`);\n data.n = 0;\n }\n } else {\n throw new Error('cannot increment nCounter because data.n is not a number.');\n }\n } else {\n data.n = 0;\n }\n }\n\n if (!noTimestamp) {\n const date = new Date();\n data.timestamp = getTimestamp(date);\n data.timestampMs = date.getMilliseconds();\n }\n\n const rel8ns: IbGibRel8ns_V1 = clone(src.rel8ns || {});\n Object.keys(rel8nsToAddByAddr || {}).forEach(rel8nName => {\n if (FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES.includes(rel8nName)) {\n throw new Error(`${lc} Cannot manually add relationship: ${rel8nName}.`);\n }\n const existingRel8d = rel8ns[rel8nName] || [];\n const toAddRel8d = rel8nsToAddByAddr![rel8nName];\n const newRel8d = toAddRel8d!.filter(x => !existingRel8d.includes(x));\n rel8ns[rel8nName] = existingRel8d.concat(newRel8d);\n });\n Object.keys(rel8nsToRemoveByAddr || {}).forEach(rel8nName => {\n if (FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES.includes(rel8nName)) {\n throw new Error(`${lc} Cannot manually remove relationship: ${rel8nName}.`);\n }\n const existingRel8d = rel8ns[rel8nName] || [];\n const toRemoveRel8d = rel8nsToRemoveByAddr![rel8nName] || [];\n const prunedRel8d = existingRel8d.filter((x: IbGibAddr) => !toRemoveRel8d!.includes(x));\n if (prunedRel8d.length > 0) {\n rel8ns[rel8nName] = prunedRel8d;\n } else {\n delete rel8ns[rel8nName];\n }\n });\n rel8ns.past = (rel8ns.past || []).concat([srcAddr]);\n (linkedRel8ns || [])\n .filter(linkedRel8nName => Object.keys(rel8ns).includes(linkedRel8nName))\n .filter(linkedRel8nName => (rel8ns[linkedRel8nName] || []).length > 1)\n .forEach(linkedRel8nName => {\n // take the last item only, and put it in an array\n let initialLength = rel8ns[linkedRel8nName]!.length;\n rel8ns[linkedRel8nName] = [rel8ns[linkedRel8nName]![initialLength - 1]];\n });\n\n // rel8ns.past = linkedRel8ns?.includes(Rel8n.past) ?\n // [srcAddr] :\n // (rel8ns.past || []).concat([srcAddr]);\n\n if (data.isTjp) {\n let tjpRel8n: IbGibAddr[] = rel8ns['tjp'] || [];\n tjpRel8n.push(srcAddr);\n rel8ns.tjp = tjpRel8n;\n delete data.isTjp;\n }\n\n newIbGib.data = data;\n newIbGib.rel8ns = rel8ns;\n // newIbGib.gib = await sha256v1(newIbGib, '');\n const hasTjp = (rel8ns.tjp?.length ?? 0) > 0;\n\n let transformDna: IbGib_V1 | null = null;\n if (dna) {\n transformDna = await buildDna(opts);\n const dnaAddr = getIbGibAddr({ ibGib: transformDna });\n rel8ns.dna = linkedRel8ns?.includes(Rel8n.dna) ?\n rel8ns.dna = [dnaAddr] :\n rel8ns.dna = (rel8ns.dna || []).concat(dnaAddr);\n }\n\n newIbGib.gib = await getGib({ ibGib: newIbGib, hasTjp });\n\n const result: TransformResult<IbGib_V1> = { newIbGib };\n if (transformDna) { result.dnas = [transformDna]; }\n return result;\n}\n", "import { clone, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { getIbGibAddr, } from '../helper.mjs';\nimport { getGibInfo } from './transforms/transform-helper.mjs';\nimport { IbGibRel8ns_V1, IbGib_V1 } from \"./types.mjs\";\nimport { GIB, GIB_DELIMITER } from './constants.mjs';\n\n/**\n * Helper function that checks the given `ibGib` to see if it\n * either has a tjp or is a tjp itself.\n *\n * ## notes\n *\n * Only unique ibGibs are meant to have tjps, or rather, if an\n * ibGib timeline is expected to be unique over \"time\", then the\n * tjp is an extremely convenient mechanism that provides a\n * \"name\" for that timeline.\n *\n * Otherwise, if they are not unique, then successive \"different\"\n * timelines cannot be easily referenced by their first unique\n * frame in time, making it much harder to pub/sub updates among\n * other things. (If there are no unique frames, then they are\n * the same ibGib.)\n *\n * ## tjp = temporal junction point\n *\n * I've written elsewhere on this as well. Refer to B2tF2.\n *\n * @returns true if the ibGib has/is a tjp, else false\n */\nexport function hasTjp({ ibGib }: { ibGib: IbGib_V1 }): boolean {\n const lc = `[${hasTjp.name}]`;\n\n if (!ibGib) {\n console.warn(`${lc} ibGib falsy. (W: 884178562f5b4f15933ac4d98db74cc6)`);\n return false;\n }\n\n if (ibGib.data?.isTjp || ibGib.rel8ns?.tjp?.length! > 0) {\n return true;\n }\n\n // dna transforms do not have tjp\n const dnaPrimitives = ['fork^gib', 'mut8^gib', 'rel8^gib'];\n if ((ibGib.rel8ns?.ancestor ?? []).some(x => dnaPrimitives.includes(x))) {\n return false;\n }\n\n if (!ibGib.gib) {\n console.warn(`${lc} ibGib.gib falsy. (W: 6400d780822b44d992846f1196509be3)`);\n return false;\n }\n if (ibGib.gib.includes(GIB_DELIMITER)) {\n return true;\n }\n\n if (ibGib.gib === GIB) {\n // primitive\n return false;\n }\n\n // use more expensive getGibInfo call.\n // could possibly just return false at this point, but since gib info\n // would change if we change our standards for gib, this is nicer.\n const gibInfo = getGibInfo({ ibGibAddr: getIbGibAddr({ ibGib }) });\n return gibInfo.tjpGib ? true : false;\n}\n\n/**\n * If you have an ibgib object, it may also contain other properties/functions.\n *\n * This helper function takes the incoming object and returns a copy\n * @param param0\n * @returns\n */\nexport function toDto<TData, TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1>({\n ibGib,\n}: {\n ibGib: IbGib_V1,\n}): IbGib_V1<TData, TRel8ns> {\n const lc = `[${toDto.name}]`;\n if (!ibGib.ib) { console.warn(`${lc} ibGib.ib is falsy. (W: e60e41c2a1fc48268379d88ce13cb77b)`); }\n if (!ibGib.gib) { console.warn(`${lc} ibGib.gib is falsy. (W: fb3889cbf0684ae4ac51e48f28570377)`); }\n\n let dtoIbGib: IbGib_V1<TData, TRel8ns> = { ib: (ibGib.ib || '').slice() };\n if (ibGib.gib) { dtoIbGib.gib = ibGib.gib.slice(); };\n if (ibGib.data) {\n // we do not clone binaries when creating the dto.\n dtoIbGib.data =\n ibGib.data instanceof Uint8Array ?\n ibGib.data :\n clone(ibGib.data);\n }\n if (ibGib.rel8ns) { dtoIbGib.rel8ns = clone(ibGib.rel8ns); }\n\n return dtoIbGib;\n}\n", "import {\n HEXADECIMAL_HASH_STRING_REGEXP_32, HEXADECIMAL_HASH_STRING_REGEXP_64,\n} from '@ibgib/helper-gib/dist/constants.mjs';\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { Ib, IbGibAddr, } from '../types.mjs';\nimport { IbGibRel8ns_V1, IbGib_V1, } from './types.mjs';\nimport { IBGIB_DELIMITER, GIB, IB, GIB_DELIMITER, } from './constants.mjs';\nimport { isPrimitive, getGib, getGibInfo } from './transforms/transform-helper.mjs';\nimport { hasTjp, toDto } from './v1-helper.mjs';\nimport { getIbAndGib, getIbGibAddr } from '../helper.mjs';\n\nconst logalot = false;\n\n/**\n * validates the ibGib's address (`ib` and `gib` properties) and recalculates\n * the `gib` against the `ibGib.gib`.\n *\n * this validates not only that the punctiliar gib hash for this ibgib record\n * hashes to the same value, but it also checks the internal tjp address and\n * ensures that it is the same tjp gib in the gib field.\n *\n * ## notes\n *\n * * By checking the tjp gib is the same in the address as in the tjp rel8n, we\n * are providing (extremely?) good corroboration that the tjp listed in the\n * address is accurate. However, it may still be theoretically possible to\n * forge an ibgib that both hashes to the punctiliar hash and matches up this\n * tjpAddr.gib. This would be AFAICT quite challenging.\n */\nexport async function validateIbGibIntrinsically({\n ibGib\n}: {\n ibGib: IbGib_V1\n}): Promise<string[] | null> {\n const lc = `[${validateIbGibIntrinsically.name}]`;\n try {\n let errors: string[] = [];\n if (ibGib) {\n const addr = getIbGibAddr({ ibGib });\n errors = validateIbGibAddr({ addr }) ?? [];\n\n if (errors.length > 0) {\n console.error(`${lc} errors found in addr: ${addr}`);\n return errors; // <<<< returns early\n }\n\n // rest of the function assumes correctly formatted ib and gib\n\n // if it's a primitive, the caller knows (or should know!) there are no\n // metadata guarantees.\n if (isPrimitive({ gib: ibGib.gib })) { return null; }\n\n // this validates not only that the punctiliar gib hash for this ibgib record\n // hashes to the same value, but it also checks the internal tjp address and\n // ensures that it is the same tjp gib.\n // not necessary the dto here, but I'm sensitive at this point.\n let gottenGib = await getGib({ ibGib: toDto({ ibGib }), hasTjp: hasTjp({ ibGib }) });\n if (gottenGib !== ibGib.gib) {\n if (ibGib.data?.src && ibGib.data.srcAddr && ibGib.ib === 'rel8') {\n // this is NOT the place to do this, but I'm plodding through trying to think of how to fix it\n // this is what it looks like in data\n // {\n // \"rel8nsToAddByAddr\":{\n // \"comment\":[\"comment 11221^F6B9477984D31FEF5FD25297CA39126A64ADDE2C91C1A2D670CCFE3965DEC4C9.847F0E9A1B2738DC167B32AA9B2D7D9B88B76F21848B1F193E994BB21F90DAEE\"]\n // },\n // \"dna\":true,\n // \"nCounter\":true,\n // \"type\":\"rel8\"\n // }\n delete ibGib.data.src;\n delete ibGib.data.srcAddr;\n gottenGib = await getGib({ ibGib: toDto({ ibGib }), hasTjp: hasTjp({ ibGib }) });\n if (gottenGib !== ibGib.gib) {\n errors.push(`Ibgib invalid intrinsically - gottenGib (${gottenGib}) does not equal ibGib.gib (${ibGib.gib}). (E: 020b71479e944b2198fe436e7e137786)`);\n // } else {\n // debugger;\n }\n } else {\n errors.push(`Ibgib invalid intrinsically - gottenGib (${gottenGib}) does not equal ibGib.gib (${ibGib.gib}). (E: 7416db016878430ca3c5b20697f164ed)`);\n }\n }\n\n return errors.length > 0 ? errors : null;\n } else {\n errors.push(`ibGib is itself falsy. (E: 4fb98caf6ed24ef7b35a19cef56e2d7e)`);\n return errors;\n }\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Naive synchronous validation for ibgib addresses.\n *\n * @returns error string array if validation errors found, else null\n */\nexport function validateIbGibAddr({\n addr,\n delimiter,\n version,\n}: {\n addr: IbGibAddr,\n delimiter?: string,\n version?: string,\n}): string[] | null {\n const lc = `[${validateIbGibAddr.name}]`;\n try {\n let errors: string[] = [];\n if (version) { console.warn(`${lc} version not implemented yet. Ignoring. (W: 2d19db16ec0c4766b5d35248787671f3)`); }\n\n // validate as a whole\n if (!addr) {\n errors.push(`addr required. (E: e9a54041aa0b41c1bb2324d9d2d42c7f)`);\n return errors;\n }\n delimiter = delimiter || IBGIB_DELIMITER;\n if (!addr.includes(delimiter)) { errors.push(`No delimiter (${delimiter}) found. (E: 05e28dcb70ff44019edc53ed508bd1e8)`); }\n if (addr.startsWith(delimiter)) { errors.push(`addr starts with delim. (E: d29f808c5a47452f9bb3ea684694c6eb)`); }\n\n // validate pieces...\n const { ib, gib } = getIbAndGib({ ibGibAddr: addr, delimiter });\n\n // ...ib\n const resValidateIb = validateIb({ ib, ibGibAddrDelimiter: delimiter, version });\n if (resValidateIb) { errors = errors.concat(resValidateIb); }\n\n // ...gib\n const resValidateGib = validateGib({ gib, ibGibAddrDelimiter: delimiter, version });\n if (resValidateGib) { errors = errors.concat(resValidateGib); }\n\n if (errors.length > 0) {\n if (logalot) { console.log(`${lc} errors.length > 0. errors: ${errors.join('|')} (I: 9c18f993e138f15613e4c6a340d41722)`); }\n }\n\n // we're done\n return errors.length > 0 ? errors : null;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Naive validation of ib.\n *\n * @returns errors array if found, else null\n */\nexport function validateIb({\n ib,\n ibGibAddrDelimiter,\n version,\n}: {\n ib: Ib,\n ibGibAddrDelimiter?: string,\n version?: string,\n}): string[] | null {\n const lc = `[${validateIb.name}]`;\n try {\n const errors: string[] = [];\n if (version) { console.warn(`${lc} version not implemented yet. Ignoring. (W: 71228ba4ed994aaa8149910e295ab087)`); }\n\n if (!ib) {\n errors.push(`ib required. (E: a76d06c7b9c24db3a731a91dbe46acd5)`);\n return errors;\n }\n\n if (ib === IB) { return null; }\n\n ibGibAddrDelimiter = ibGibAddrDelimiter || IBGIB_DELIMITER;\n if (ib.includes(ibGibAddrDelimiter)) { errors.push(`ib contains ibGibAddrDelimiter (${ibGibAddrDelimiter}) (E: 09e61b46c3e84874bc02b6918f1f2c39)`); }\n\n return errors.length > 0 ? errors : null;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * validates a `gib` of some ibGib/ibGibAddr.\n *\n * @returns array of validation error strings (if any) or null\n */\nexport function validateGib({\n gib,\n gibDelimiter,\n ibGibAddrDelimiter,\n version,\n}: {\n /**\n * gib to validate.\n *\n * ## notes\n *\n * If the gib has a tjp embedded in it (i.e. the associated ibgib has a\n * tjp), then this will call validation on that tjpGib recursively.\n */\n gib: Ib,\n /**\n * This is a delimiter used with tjpGibs.\n *\n * atow this is a dot (`'.'`).\n *\n * ## notes\n *\n * THIS IS NOT THE SAME THING AS THE `ibGibAddrDelimiter`!\n */\n gibDelimiter?: string,\n /**\n * This is a delimiter used with the entire ibGibAddr.\n *\n * atow this is a caret (`'^'`).\n *\n * ## notes\n *\n * THIS IS NOT THE SAME THING AS THE `gibDelimiter`!\n */\n ibGibAddrDelimiter?: string,\n /**\n * Ignored atow, but in the future, probably will be used.\n * May end up being an IbGibAddr but who knows.\n */\n version?: string,\n}): string[] | null {\n const lc = `[${validateGib.name}]`;\n try {\n const errors: string[] = [];\n if (version) { console.warn(`${lc} version not implemented yet. Ignoring. (E: 90ced1db69774702b92acb261bdaee23)`); }\n\n if (!gib) {\n errors.push(`gib required. (E: e217de4035b04086827199f4bace189c)`);\n return errors;\n }\n\n ibGibAddrDelimiter = ibGibAddrDelimiter || IBGIB_DELIMITER;\n /** Need to move this to ts-gib */\n const INVALID_GIB_CHARS = [ibGibAddrDelimiter];\n const invalidCharsFound: string[] = [];\n INVALID_GIB_CHARS.forEach(invalidChar => {\n if (gib.includes(invalidChar)) { invalidCharsFound.push(invalidChar); }\n });\n if (invalidCharsFound.length > 0) {\n errors.push(`gib (${gib}}) contains invalid characters: (${JSON.stringify(invalidCharsFound.join(','))}) (E: 1e584258d9e049ba9ce7e516f3ab97f1)`);\n }\n\n // punctiliar = point, i.e., a single point in the universe, either a\n // single point in time in a tjp ibgib's timeline, or a single point in\n // space that lives outside of time (has no tjp thus no timeline).\n //\n // So if we've gotten here in code, then our gib is truthy and doesn't\n // contain invalid characters.\n\n const { punctiliarHash, tjpGib, isPrimitive } =\n getGibInfo({ gib, gibDelimiter: gibDelimiter || GIB_DELIMITER });\n\n // automatically valid if it's a primitive, as the caller should expect\n // no cryptographical guarantees\n if (isPrimitive) { return null; }\n\n // Gib is not primitive so must have at least the punctiliar hash.\n if (!punctiliarHash) { throw new Error(`${lc} punctiliarHash is falsy on a non-primitive gib. (E: 72835394918241bdb2632bf0510bdae5)`); }\n const punctiliarHashIs_32 = punctiliarHash!.match(HEXADECIMAL_HASH_STRING_REGEXP_32);\n const punctiliarHashIs_64 = punctiliarHash!.match(HEXADECIMAL_HASH_STRING_REGEXP_64);\n if (!punctiliarHashIs_32 && !punctiliarHashIs_64) {\n errors.push('gib punctiliar hash is neither a 32- or 64-char hash string. (E: d47ff6d6e14b4c02a62107090c8dad39)');\n }\n\n if (tjpGib) {\n // if it is an ibgib in a timeline, that timeline has a tjp and this\n // gib has a tjpGib component. So we must recursively validate the\n // tjpGib\n const tjpGibValidationErrors = validateGib({ gib: tjpGib });\n if ((tjpGibValidationErrors ?? []).length > 0) {\n errors.push(`tjpGib has errors (E: d6b79228d4a64c0b967cdb0efcea4d0d). tjpGibValidationErrors: ${tjpGibValidationErrors!.join('. ')}`);\n }\n }\n\n return errors.length > 0 ? errors : null;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * verifies that\n * @param param0\n * @returns\n */\nexport function validateRel8nsIntrinsically({\n rel8ns,\n}: {\n rel8ns: IbGibRel8ns_V1,\n}): string[] | null {\n const lc = `[${validateRel8nsIntrinsically.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 62b4722599798dd8ab95fcebf42c0e23)`); }\n\n let errors: string[] = [];\n\n const rel8nNames = Object.keys(rel8ns);\n for (let i = 0; i < rel8nNames.length; i++) {\n // all rel8nNames/keys are strings\n const rel8nName = Object.keys(rel8ns)[i];\n if (typeof rel8nName !== 'string') {\n errors.push(`non-string rel8nName found. all keys of rel8ns must be of type string. (E: 3b2e4582b638421681951f5475c85178)`)\n }\n\n // all values are ibgib addr arrays\n const addrs = rel8ns[rel8nName] ?? [];\n for (let j = 0; j < addrs.length; j++) {\n const addr = addrs[j];\n const addrErrors = validateIbGibAddr({ addr }) ?? [];\n if (addrErrors.length > 0) {\n errors.push(`invalid addr found for rel8nName (${rel8nName}). addr errors: ${addrErrors.join('|')} (E: 56809a746c4f462db426e90395b80364)`);\n }\n }\n }\n return errors.length > 0 ? errors : null;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "import { extractErrorMsg, getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { fork } from './transforms/fork.mjs';\nimport { mut8 } from './transforms/mut8.mjs';\nimport { rel8 } from './transforms/rel8.mjs';\nimport { Ib, IbGib, IbGibRel8ns, TransformResult, TemporalJunctionPointOptions } from '../types.mjs';\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from './types.mjs';\nimport { IB, GIB, ROOT, IB_REGEXP_DEFAULT, FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES } from './constants.mjs';\nimport { validateIb } from './validate-helper.mjs';\nimport { getGib } from './transforms/transform-helper.mjs';\n\nconst logalot = false;\n\nexport class Factory_V1 {\n static root() {\n return Factory_V1.primitive({ ib: IB });\n }\n\n /**\n * Returns an ibGib primitive with the given `ib`, e.g. \"{ib: '7', gib: 'gib'}\".\n *\n * @returns a single primitive ibGib\n */\n static primitive({\n ib\n }: {\n ib: Ib\n }): IbGib_V1 {\n return { ib, gib: GIB };\n }\n\n /**\n * generates multiple primitive ibgibs from the given `ibs` array.\n * @returns array of generated ibgibs.\n */\n static primitives({\n ibs\n }: {\n ibs: Ib[]\n }): IbGib_V1[] {\n return ibs.map(ib => Factory_V1.primitive({ ib }));\n }\n\n /**\n * Takes the incoming `parentIbGib` and forks it. Then applies the\n * `data` and/or `rel8ns` if any, depending on the other config params.\n *\n * @returns The entire transform result object that includes the newly produced ibGib as well as any derivative/intermediate ibgibs.\n */\n static async firstGen<TData = any>({\n ib = IB,\n parentIbGib = Factory_V1.root(),\n data,\n rel8ns,\n dna,\n tjp,\n linkedRel8ns,\n noTimestamp,\n nCounter,\n squash,\n }: {\n ib: Ib,\n parentIbGib: IbGib,\n data?: TData,\n rel8ns?: IbGibRel8ns,\n dna?: boolean,\n tjp?: TemporalJunctionPointOptions;\n linkedRel8ns?: string[],\n /**\n * If true, no timestamp will be\n */\n noTimestamp?: boolean,\n /**\n * if true, data.n will be set to 0 on the first frame, and 1 on the\n * second.\n */\n nCounter?: boolean,\n /**\n * ONLY USED IF {@link dna} IS FALSY.\n *\n * If {@link dna} is falsy and this is true, then the resulting 1st gen\n * ibgib will be squashed into a single frame, even if both mut8 and\n * rel8 transforms are executed.\n *\n * ## intent / driving use case\n *\n * We are working on the new, production-quality v1 sync saga and we\n * want the saga ibgib to be one frame per participant (Alice, Bob).\n * So Alice creates one frame, then Bob evolves 1 frame, etc. No dna\n * is required, because this is not meant to be merged at a later time.\n *\n * So the use case is when you don't need dna and you want a single\n * frame.\n */\n squash?: boolean,\n }): Promise<TransformResult<IbGib_V1>> {\n const lc = `[${Factory_V1.name}][${Factory_V1.firstGen.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b7152fbd94382516d9f7c591bcf4c326)`); }\n\n if (dna && squash) { throw new Error(`both dna and squash cannot be true. Squash requires that no dna exist. (E: abfc58b4a4c8654924aa5428d0831826)`); }\n\n /** * Multiple transform steps will create multiple results. */\n const interimResults: TransformResult<IbGib_V1>[] = [];\n let src: IbGib_V1 = parentIbGib || ROOT;\n let resFork = await fork({\n src,\n destIb: ib,\n tjp,\n dna,\n linkedRel8ns,\n noTimestamp,\n nCounter,\n });\n interimResults.push(resFork);\n src = resFork.newIbGib;\n\n if (data) {\n let resMut8 = await mut8({\n src,\n dataToAddOrPatch: data,\n dna,\n linkedRel8ns,\n noTimestamp,\n nCounter,\n });\n interimResults.push(resMut8);\n src = resMut8.newIbGib;\n };\n\n if (rel8ns) {\n let resRel8 = await rel8({\n src,\n rel8nsToAddByAddr: rel8ns,\n dna,\n linkedRel8ns,\n noTimestamp,\n nCounter,\n });\n interimResults.push(resRel8);\n // src = resRel8.newIbGib; // not needed because not used (this is the last step)\n }\n\n if (interimResults.length > 1) {\n const newIbGib = interimResults.slice(interimResults.length - 1)[0].newIbGib;\n const resultWithIntermediates = {\n newIbGib,\n /**\n * all the interResults except the last one go in the intermediate ibGibs\n */\n intermediateIbGibs: interimResults.slice(0, interimResults.length - 1).map(x => x.newIbGib),\n } as TransformResult<IbGib_V1>;\n\n if (dna) {\n if (squash) { (`${lc} (E: 62c595422e21ad8ce8eae658976fd826)`) }\n\n // combine all of the interim dnas\n let dnas: IbGib_V1[] = [];\n interimResults.forEach(res => { dnas = dnas.concat(res.dnas!); });\n resultWithIntermediates.dnas = dnas;\n\n return resultWithIntermediates;\n } else if (squash) {\n // manually remove past and change the tjp, if it exists, reset n\n if (!newIbGib.rel8ns) { throw new Error(`(UNEXPECTED) newIbGib.rel8ns is falsy? (E: 6b09e8057fc5b00c6cfd13be60e97f26)`); }\n\n delete newIbGib.rel8ns.past;\n\n if (newIbGib.rel8ns.tjp) {\n delete newIbGib.rel8ns.tjp;\n newIbGib.data ??= {};\n newIbGib.data.isTjp = true;\n }\n\n if (nCounter) {\n newIbGib.data ??= {};\n newIbGib.data.n = 0;\n }\n\n // recalculate the gib\n newIbGib.gib = await getGib({ ibGib: newIbGib });\n\n const resultSquashed: TransformResult<IbGib_V1> = { newIbGib };\n\n return resultSquashed;\n } else {\n // no dna and no squash\n return resultWithIntermediates;\n }\n } else if (interimResults.length === 1) {\n // for some reason the caller just used this as a fork.\n return interimResults[0];\n } else {\n throw new Error(`(UNEXPECTED) interimResults.length is not 1 and not greater than 1? 0? But we had to fork? (E: a256c88c56916a46a888796f76ef4826)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Generate an ibgib datum that has no dna and no timeline.\n * It's a one-off ibgib.\n *\n * This is similar to {@link Factory_V1.constant}, but this is not\n * necessarily deterministic. It can have a timestamp and/or uuid, though it\n * does not have dna, nCounter, or a tjp.\n *\n * ## validation\n *\n * * validates the given `ib` against `ibRegExpPattern` or default regexp.\n * * validates that rel8ns doesn't include default forbidden rel8n names or\n * atow `'tjp'`.\n *\n * ## intent\n *\n * Stones are useful for one-off ibgibs that are not part of a timeline, but\n * which still should have a timestamp and/or uuid.\n *\n * @see {@link Factory_V1.constant}\n */\n static async stone<\n TData extends IbGibData_V1 = any,\n TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1\n >({\n parentPrimitiveIb,\n ib,\n ibRegExpPattern,\n data,\n rel8ns,\n noTimestamp,\n uuid,\n }: {\n parentPrimitiveIb: Ib,\n ib: Ib,\n /**\n * for checking the stone's generated ib\n */\n ibRegExpPattern?: string,\n data?: TData,\n rel8ns?: TRel8ns,\n noTimestamp?: boolean,\n /**\n * If true, will generate a uuid for the stone. If falsy, will not.\n */\n uuid?: boolean,\n }): Promise<IbGib_V1<TData, TRel8ns>> {\n const lc = `[${Factory_V1.name}][${Factory_V1.stone.name}]`;\n try {\n // validation\n // parentPrimitiveIb\n if (!parentPrimitiveIb) { throw new Error(`parentPrimitiveIb required. (E: genuuid)`); }\n if (validateIb({ ib: parentPrimitiveIb }) !== null) { throw new Error(`Invalid parentPrimitiveIb: ${parentPrimitiveIb}. (E: genuuid)`); }\n\n // ib\n if (!ib) { throw new Error(`ib required. (E: genuuid)`); }\n const regExp = ibRegExpPattern ? new RegExp(ibRegExpPattern) : IB_REGEXP_DEFAULT;\n if (!ib.match(regExp)) { throw new Error(`invalid ib. does not match regexp (${regExp}) (E: genuuid)`); }\n\n // rel8ns\n const incomingRel8nNames = Object.keys(rel8ns ?? {});\n const forbiddenRel8nNames = [...FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES, 'tjp'];\n const rel8nsIsInvalid = incomingRel8nNames.some(x => {\n // we don't want constants trying to look like they have/are descendants/tjps/etc.\n return forbiddenRel8nNames.includes(x);\n });\n if (rel8nsIsInvalid) { throw new Error(`Invalid rel8ns. forbiddenRel8nNames: ${forbiddenRel8nNames}. rel8ns keys: ${Object.keys(rel8ns ?? {})}. (E: genuuid)`); }\n\n\n // create the stone by using the firstGen factory. Then we'll pare\n // off what we don't need.\n const resFirstGen = await Factory_V1.firstGen({\n ib,\n parentIbGib: Factory_V1.primitive({ ib: parentPrimitiveIb }),\n data,\n rel8ns,\n dna: false,\n noTimestamp,\n nCounter: false,\n });\n const stoneIbGib = resFirstGen.newIbGib as IbGib_V1<TData, TRel8ns>;\n if (uuid) {\n if (!stoneIbGib.data) { stoneIbGib.data = {} as TData; }\n stoneIbGib.data.uuid = await getUUID();\n }\n\n // remove any extraneous stuff\n if (stoneIbGib.rel8ns?.past) { delete stoneIbGib.rel8ns.past; }\n if (stoneIbGib.rel8ns?.tjp) { delete stoneIbGib.rel8ns.tjp; }\n\n // recalculate the gib hash\n stoneIbGib.gib = await getGib({\n ibGib: {\n ib: stoneIbGib.ib,\n data: stoneIbGib.data,\n rel8ns: stoneIbGib.rel8ns,\n },\n hasTjp: false,\n });\n\n return stoneIbGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Generate a deterministic ibgib datum that has no dna and no timeline.\n * It's a one-off ibgib.\n *\n * Because this is supposed to create and re-create deterministically the equivalent\n * of a non-primitive ibgib \"constant\", this function creates a single ibgib with...\n * * one ancestor\n * * no past, dna, or tjp rel8ns\n * * no tjp timestamp or uuid\n * * no nCounter\n *\n * This is similar to {@link Factory_V1.stone}, but with guaranteed no\n * timestamp or uuid (unless incoming {@link data} contains a uuid).\n *\n * @see {@link Factory_V1.stone}\n *\n * ## intent\n *\n * I want to be able to create deterministic ibGibs that I can reference at\n * runtime, similar to an ibgib primitive (e.g. \"root^gib\"), but with the\n * integrity of the `gib` hash. This way, I can reference a deterministic ibgib\n * from code at compile time, and at runtime this will have a corresponding\n * ibgib datum with gib-hashed integrity.\n *\n * ## example\n *\n * I want to create a \"hard-coded\" schema ibgib that I rel8 to some protocol\n * ibgib. So I'll create the data here, which lives in source control in a text file,\n * and then I'll render that as an ibgib that verifies integrity. If I as a coder change\n * it at all, then the `gib` of course will be different.\n */\n static async constant<\n TData extends IbGibData_V1 = any,\n TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1\n >({\n parentPrimitiveIb,\n ib,\n ibRegExpPattern,\n data,\n rel8ns,\n }: {\n parentPrimitiveIb: Ib,\n ib: Ib,\n /**\n * for checking the constant's generated ib\n */\n ibRegExpPattern?: string,\n data?: TData,\n rel8ns?: TRel8ns,\n }): Promise<IbGib_V1<TData, TRel8ns>> {\n const lc = `[${Factory_V1.name}][${Factory_V1.constant.name}]`;\n try {\n const constantIbGib = await Factory_V1.stone({\n parentPrimitiveIb,\n ib,\n ibRegExpPattern,\n data,\n rel8ns,\n noTimestamp: true,\n uuid: false,\n });\n return constantIbGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n}\n", "/**\n * @module core-constants\n *\n * # IMPORTANT!\n *\n * In order to be able to actually use this in an ionic-gib-like clone front end,\n * I want to be sure to include all of these. So I can't remove/comment it out here\n * without putting it _somewhere_. For example, the very first import atow is a\n * reference to @capacitor/filesystem. This should not go in this package (core-gib)\n * so I'm going to create another lib specific to ionic/capacitor and put it there\n * **before** removing it from/commenting it out in this file.\n *\n * # about this file\n *\n * I'm copying this lump sum from ionic-gib and am breaking it out slowly into\n * other more specific constant files. When a constant is moved into one of\n * those sub files, then I will remove it from this file.\n *\n * Ultimately, this should only contain global constants like the logalot\n * and timer settings.\n */\n\nimport { GIB } from \"@ibgib/ts-gib/dist/V1/constants.mjs\";\nimport { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\n\n\n/**\n * Naive selective logging/tracing mechanism.\n *\n * I manually switch this in individual files as needed while\n * developing/troubleshooting. I can change it here to turn on extremely verbose\n * logging application wide (and turn off individual files).\n */\nexport const GLOBAL_LOG_A_LOT: boolean | number = false;\n\n/**\n * Used in console.timeLog() calls.\n */\nexport const GLOBAL_TIMER_NAME = '[core^gib timer]';\n\n\n// export const UUID_REGEXP = /^[a-zA-Z0-9_\\-.]{1,256}$/;\n\n/**\n * regular expression for a classname.\n *\n * Used in witnesses atm.\n */\nexport const CLASSNAME_REGEXP = /^[a-zA-Z0-9_]{1,255}$/;\n\n/**\n * Much restricted list of chars in english.\n *\n * ## intent\n *\n * When sanitizing input.\n */\nexport const SAFE_SPECIAL_CHARS = `.'\",!?-`;\n\nexport const IB_MAX_LENGTH_DEFAULT = 155;\n\n/**\n * Defaults to word characters, space, tab, hyphen, and other\n * non-slash (path navigating) chars.\n *\n * Does not allow new lines or other whitespace, only tabs and spaces.\n *\n * ## atow\n *\n * `^[\\\\w\\\\t\\\\-|=+.&%\\$#@!~\\` \\\\[\\\\]\\\\(\\\\)\\\\{\\\\}]{1,${IB_MAX_LENGTH_DEFAULT}}$`\n */\nexport const IB_REGEXP_DEFAULT = new RegExp(`^[\\\\w\\\\t\\\\-|=+.&%\\$#@!~\\` \\\\[\\\\]\\\\(\\\\)\\\\{\\\\}]{1,${IB_MAX_LENGTH_DEFAULT}}$`);\n\n/**\n * Ionicons const \"enum\"\n */\nexport const IONICONS = [\n 'add',\n 'add-circle',\n 'alert',\n 'alert-circle',\n 'add',\n 'airplane',\n 'alarm',\n 'albums',\n 'alert',\n 'alert-circle',\n 'american-football',\n 'analytics',\n 'aperture',\n 'apps',\n 'archive',\n 'arrow-back',\n 'arrow-back-circle',\n 'arrow-down',\n 'arrow-down-circle',\n 'arrow-forward',\n 'arrow-forward-circle',\n 'arrow-redo',\n 'arrow-redo-circle',\n 'arrow-undo',\n 'arrow-undo-circle',\n 'arrow-up',\n 'arrow-up-circle',\n 'at',\n 'at-circle',\n 'attach',\n 'backspace',\n 'bandage',\n 'bar-chart',\n 'barbell',\n 'barcode',\n 'baseball',\n 'basket',\n 'basketball',\n 'battery-charging',\n 'battery-dead',\n 'battery-full',\n 'battery-half',\n 'beaker',\n 'bed',\n 'beer',\n 'bicycle',\n 'bluetooth',\n 'boat',\n 'body',\n 'bonfire',\n 'book',\n 'bookmark',\n 'bookmarks',\n 'briefcase',\n 'browsers',\n 'brush',\n 'bug',\n 'build',\n 'bulb',\n 'bus',\n 'business',\n 'cafe',\n 'calculator',\n 'calendar',\n 'call',\n 'camera',\n 'camera-reverse',\n 'car',\n 'car-sport',\n 'card',\n 'caret-back',\n 'caret-back-circle',\n 'caret-down',\n 'caret-down-circle',\n 'caret-forward',\n 'caret-forward-circle',\n 'caret-up',\n 'caret-up-circle',\n 'cart',\n 'cash',\n 'cellular',\n 'chatbox',\n 'chatbox-ellipses',\n 'chatbubble',\n 'chatbubble-ellipses',\n 'chatbubbles',\n 'checkbox',\n 'checkmark',\n 'checkmark-circle',\n 'checkmark-done',\n 'checkmark-done-circle',\n 'chevron-back',\n 'chevron-back-circle',\n 'chevron-down',\n 'chevron-down-circle',\n 'chevron-forward',\n 'chevron-forward-circle',\n 'chevron-up',\n 'chevron-up-circle',\n 'clipboard',\n 'close',\n 'close-circle',\n 'cloud',\n 'cloud-circle',\n 'cloud-done',\n 'cloud-download',\n 'cloud-offline',\n 'cloud-upload',\n 'cloudy',\n 'cloudy-night',\n 'code',\n 'code-download',\n 'code-slash',\n 'code-working',\n 'cog',\n 'color-fill',\n 'color-filter',\n 'color-palette',\n 'color-wand',\n 'compass',\n 'construct',\n 'contract',\n 'contrast',\n 'copy',\n 'create',\n 'crop',\n 'cube',\n 'cut',\n 'desktop',\n 'disc',\n 'document',\n 'document-attach',\n 'document-text',\n 'documents',\n 'download',\n 'duplicate',\n 'ear',\n 'earth',\n 'easel',\n 'egg',\n 'ellipse',\n 'ellipsis-horizontal',\n 'ellipsis-horizontal-circle',\n 'ellipsis-vertical',\n 'ellipsis-vertical-circle',\n 'enter',\n 'exit',\n 'expand',\n 'eye',\n 'eye-off',\n 'eyedrop',\n 'fast-food',\n 'female',\n 'file-tray',\n 'file-tray-full',\n 'file-tray-stacked',\n 'film',\n 'filter',\n 'finger-print',\n 'fitness',\n 'flag',\n 'flame',\n 'flash',\n 'flash-off',\n 'flashlight',\n 'flask',\n 'flower',\n 'folder',\n 'folder-open',\n 'football',\n 'funnel',\n 'game-controller',\n 'gift',\n 'git-branch',\n 'git-commit',\n 'git-compare',\n 'git-merge',\n 'git-network',\n 'git-pull-request',\n 'glasses',\n 'globe',\n 'golf',\n 'grid',\n 'hammer',\n 'hand-left',\n 'hand-right',\n 'happy',\n 'hardware-chip',\n 'headset',\n 'heart',\n 'heart-circle',\n 'heart-dislike',\n 'heart-dislike-circle',\n 'heart-half',\n 'help',\n 'help-buoy',\n 'help-circle',\n 'home',\n 'hourglass',\n 'ice-cream',\n 'image',\n 'images',\n 'infinite',\n 'information',\n 'information-circle',\n 'journal',\n 'key',\n 'keypad',\n 'language',\n 'laptop',\n 'layers',\n 'leaf',\n 'library',\n 'link',\n 'list',\n 'list-circle',\n 'locate',\n 'location',\n 'lock-closed',\n 'lock-open',\n 'log-in',\n 'magnet',\n 'mail',\n 'mail-open',\n 'mail-unread',\n 'male',\n 'male-female',\n 'man',\n 'map',\n 'medal',\n 'medical',\n 'medkit',\n 'megaphone',\n 'menu',\n 'mic',\n 'mic-circle',\n 'mic-off',\n 'mic-off-circle',\n 'moon',\n 'move',\n 'musical-note',\n 'musical-notes',\n 'navigate',\n 'navigate-circle',\n 'newspaper',\n 'notifications',\n 'notifications-circle',\n 'notifications-off',\n 'notifications-off-circle',\n 'nuclear',\n 'nutrition',\n 'open',\n 'options',\n 'paper-plane',\n 'partly-sunny',\n 'pause',\n 'pause-circle',\n 'paw',\n 'pencil',\n 'people',\n 'people-circle',\n 'person',\n 'person-add',\n 'person-circle',\n 'person-remove',\n 'phone-landscape',\n 'phone-portrait',\n 'pie-chart',\n 'pin',\n 'pint',\n 'pizza',\n 'planet',\n 'play',\n 'play-back',\n 'play-back-circle',\n 'play-circle',\n 'play-forward',\n 'play-forward-circle',\n 'play-skip-back',\n 'play-skip-back-circle',\n 'play-skip-forward',\n 'play-skip-forward-circle',\n 'podium',\n 'power',\n 'pricetag',\n 'pricetags',\n 'print',\n 'pulse',\n 'push',\n 'qr-code',\n 'radio',\n 'radio-button-off',\n 'radio-button-on',\n 'rainy',\n 'reader',\n 'receipt',\n 'recording',\n 'refresh',\n 'refresh-circle',\n 'reload',\n 'reload-circle',\n 'remove',\n 'remove-circle',\n 'reorder-four',\n 'reorder-three',\n 'reorder-two',\n 'repeat',\n 'resize',\n 'restaurant',\n 'return-down-back',\n 'return-down-forward',\n 'return-up-back',\n 'return-up-forward',\n 'ribbon',\n 'rocket',\n 'rose',\n 'sad',\n 'save',\n 'scan',\n 'scan-circle',\n 'school',\n 'search',\n 'search-circle',\n 'send',\n 'server',\n 'settings',\n 'shapes',\n 'share',\n 'share-social',\n 'shield',\n 'shield-checkmark',\n 'shirt',\n 'shuffle',\n 'skull',\n 'snow',\n 'speedometer',\n 'square',\n 'star',\n 'star-half',\n 'stats-chart',\n 'stop',\n 'stop-circle',\n 'stopwatch',\n 'subway',\n 'sunny',\n 'swap-horizontal',\n 'swap-vertical',\n 'sync',\n 'sync-circle',\n 'tablet-landscape',\n 'tablet-portrait',\n 'tennisball',\n 'terminal',\n 'text',\n 'thermometer',\n 'thumbs-down',\n 'thumbs-up',\n 'thunderstorm',\n 'time',\n 'timer',\n 'today',\n 'toggle',\n 'trail-sign',\n 'train',\n 'transgender',\n 'trash',\n 'trash-bin',\n 'trending-down',\n 'trending-up',\n 'triangle',\n 'trophy',\n 'tv',\n 'umbrella',\n 'videocam',\n 'volume-high',\n 'volume-low',\n 'volume-medium',\n 'volume-mute',\n 'volume-off',\n 'walk',\n 'wallet',\n 'warning',\n 'watch',\n 'water',\n 'wifi',\n 'wine',\n 'woman',\n];\n\n// #region other robbot related\n\n/**\n * Robbot.data.name regexp\n */\nexport const ROBBOT_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,255}$/;\nexport const ROBBOT_PREFIX_SUFFIX_REGEXP = /^[a-zA-Z0-9_\\-.\\s\uD83D\uDC40\uD83E\uDD16:;&]{1,64}$/;\nexport const ROBBOT_PREFIX_SUFFIX_REGEXP_DESC =\n `0 to 64 alphanumerics, spaces, select special characters and emojis.`;\n\n// #endregion other robbot related\n\n// #region gestures\n\nexport const GESTURE_DOUBLE_CLICK_THRESHOLD_MS = 500;\n/**\n * If a gesture's move threshold is less than this, then it can still be\n * considered a single punctiliar click. Otherwise, it's a move event.\n *\n * IOW, a click gesture only is considered a \"click\" if the onMove is triggered\n * less than this many times. If onMove is detected more than this many times,\n * then a move gesture will be triggered.\n */\nexport const GESTURE_CLICK_TOLERANCE_ONMOVE_THRESHOLD_COUNT = 5;\n\n// #endregion gestures\n\nexport const SIMPLE_CONFIG_KEY_APP_VISIBLE = 'appBarVisible';\nexport const SIMPLE_CONFIG_KEY_APP_SELECTED = 'appBarSelectedApp';\nexport const SIMPLE_CONFIG_KEY_ROBBOT_VISIBLE = 'robbotBarVisible';\nexport const SIMPLE_CONFIG_KEY_ROBBOT_SELECTED_ADDR = 'robbotBarSelectedAddr';\n\n// #region app\n\nexport const DEFAULT_APP_ICON = 'apps-outline';\n\n// #endregion app\n\nexport const YOUTUBE_LINK_REG_EXP = /^https:\\/\\/youtu\\.be\\/\\w+$/;\n\nexport const WEB_1_PATHS = ['welcome', 'about-us', 'your-data'];\n", "// #region from common/types/legacy.ts\n\n// todo: clean up legacy get/put functions\n// I started ionic-gib without a clear architectural design, so this is \"legacy\"\n// with respect to that. I had several functions that used these types, and I\n// left them as-is at the time. after this refactor, this needs to be cleaned\n// up. Perhaps this goes in capacitor-gib even?\n\nimport { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';\n\nexport interface FileResult {\n success?: boolean;\n /**\n * If errored, this will contain the errorMsg.\n */\n errorMsg?: string;\n /**\n * True if failed due to timing out.\n */\n timedOut?: boolean;\n}\n\n/**\n * Options for retrieving data from the file system.\n */\nexport interface GetIbGibOpts {\n /**\n * If getting ibGib object, this is its address.\n */\n addr?: IbGibAddr;\n /**\n * If getting multiple ibGibs, use this array of addrs.\n */\n addrs?: IbGibAddr[];\n /**\n * Are we looking for a DNA ibgib?\n */\n isDna?: boolean;\n /**\n * space from which to get the ibgib\n *\n * @default localUserSpace\n */\n space?: IbGibSpaceAny,\n /**\n * If supplied, first acquires the lock with this scope on the\n * given `space` (which defaults to localUserSpace).\n */\n lockScope?: string,\n /**\n * Cancels if can't acquire lock after approximately this time.\n */\n lockTimeoutMs?: number,\n /**\n * If true, will not get from cache and will force retrieval from the real\n * bucket. In Ionic space, this means will look in ionic storage proper.\n */\n force?: boolean;\n}\n\n/**\n * Result for retrieving an ibGib from the file system.\n */\nexport interface GetIbGibResult extends FileResult {\n /**\n * ibGibs if retrieving a \"regular\" ibGib.\n *\n * This is used when you're not getting a pic, e.g.\n */\n ibGibs?: IbGib_V1[];\n /**\n * This is used when you're getting a pic's binary content.\n */\n // binData?: any;\n /**\n * access to raw result ibgib that caller must cast to the correct shape.\n */\n rawResultIbGib?: IbGib_V1;\n}\n\nexport interface PutIbGibOpts {\n /**\n * ibGib to put.\n *\n * If you only want to do just one, use this param. Otherwise, use the\n * `ibGibs` array param.\n */\n ibGib?: IbGib_V1;\n /**\n * ibGibs to put in the space.\n *\n * If you want to put more than one ibGib, use this param. If you only\n * want to put a single ibGib, you could also use the `ibGib` param.\n */\n ibGibs?: IbGib_V1[];\n /**\n * if true, will store this data in the bin folder with its hash.\n */\n // binData?: string;\n /**\n * If true, will store in a different folder.\n */\n isDna?: boolean;\n /**\n * extension to store the bindata with.\n */\n // binExt?: string;\n /**\n * If true, will replace an existing ibGib file\n */\n force?: boolean;\n /**\n * space into which we shall put the ibgib.\n *\n * @default localCurrentSpace\n */\n space?: IbGibSpaceAny,\n}\n\n/**\n * Result for putting ibgib.\n */\nexport interface PutIbGibResult extends FileResult {\n binHash?: string;\n}\n\nexport interface DeleteIbGibOpts extends GetIbGibOpts { }\nexport interface DeleteIbGibResult extends FileResult { }\n\n// #endregion from common/types/legacy.ts\n\n/**\n * Special ibgib types, used for metadata within a space.\n *\n * Unsure where to place this in core-gib...\n *\n * ## notes\n *\n * * 10/2023\n * * I'm changing this to also be unioned with 'string' because I am working\n * on ibgib app and I need to consume the create special ibgib. so this\n * should be extensible per use case in consuming apps.\n */\nexport type SpecialIbGibType =\n \"tags\" | \"aliases\" | \"roots\" |\n \"outerspaces\" | \"secrets\" |\n \"encryptions\" | \"autosyncs\" | \"robbots\" | \"apps\" | \"history\" |\n string;\n/**\n * Special ibgib types, used for metadata within a space.\n *\n * Unsure where to place this...\n *\n * @see {@link SPECIAL_IBGIB_TYPE_REGEXP}\n */\nexport const SpecialIbGibType = {\n /** indexes all tag ibgibs within a space */\n tags: \"tags\" as SpecialIbGibType,\n /** indexes all aliases within a space */\n aliases: \"aliases\" as SpecialIbGibType,\n /** indexes all root ibgibs within a space */\n roots: \"roots\" as SpecialIbGibType,\n /** indexes all outerspace ibgibs, including sync spaces, within a space */\n outerspaces: \"outerspaces\" as SpecialIbGibType,\n /** indexes all secret ibgibs within a space */\n secrets: \"secrets\" as SpecialIbGibType,\n /** indexes all encryption setting ibgibs within a space */\n encryptions: \"encryptions\" as SpecialIbGibType,\n /** indexes all tjp addresses that automatically sync. */\n autosyncs: \"autosyncs\" as SpecialIbGibType,\n robbots: \"robbots\" as SpecialIbGibType,\n apps: \"apps\" as SpecialIbGibType,\n /** timelines history */\n history: \"history\" as SpecialIbGibType,\n}\n\n/**\n * There has been a new ibGib that is the latest for a given tjp timeline.\n */\nexport interface IbGibTimelineUpdateInfo extends IbGib_V1 {\n ib: 'IbGibTimelineUpdateInfo',\n tjpAddr?: IbGibAddr;\n latestAddr: IbGibAddr;\n latestIbGib?: IbGib_V1<any>;\n}\n\n/**\n * Serializing helper type for compressing dependency graphs.\n */\nexport type SerializedUint8Array = {\n _dataType: 'Uint8Array_Base64';\n value: string;\n};\n", "/**\n * In a Robbot's rel8ns, this is the rel8n name that links to tags that the\n * Robbot uses for tagging its output.\n */\nexport const ROBBOT_TAG_TJP_ADDRS_REL8N_NAME = 'tagTjpAddrs';\n/**\n * A spaces ibGib uses this rel8n name for related sync spaces, used\n * in replicating ibgib spaces.\n */\nexport const ROBBOT_REL8N_NAME = 'robbot';\n/**\n * When a robbot witnesses an ibgib, it will \"remember\" the ibgib\n * by relating the target ibgib to itself via this rel8nName.\n */\nexport const DEFAULT_ROBBOT_TARGET_REL8N_NAME = 'x';\n\n/**\n * wah wah wah...\n */\nexport const IBGIB_ROBBOT_NAME_DEFAULT = 'i';\n\n/**\n * Icon for a single robbot\n */\nexport const DEFAULT_ROBBOT_ICON = 'body-outline';\n", "import { GIB } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\n/**\n * Zero space is a default space that uses default values that should be\n * reproducible and not break or something...it's all in flux really.\n */\nexport const ZERO_SPACE_ID = 'zero';\n\n/**\n * was 000_default_space in MVP. need to add a conversion\n */\nexport const IBGIB_SPACE_NAME_DEFAULT = 'zerospace';\n// export const IBGIB_SPACE_NAME_DEFAULT = 'default_space';\n\n\n/**\n * For use with documentation and UX help.\n *\n * This is probably scoped to a particular schema...(e.g. v1)\n */\nexport const VALID_SPACE_NAME_EXAMPLES = [\n 'justLetters', 'valid_here', 'hyphens-allowed', '0CanStartOrEndWithNumbers9'\n];\n/**\n * For use with documentation and UX help.\n *\n * This is probably scoped to a particular schema...(e.g. v1)\n */\nexport const INVALID_SPACE_NAME_EXAMPLES = [\n 'IHaveASymbol!', 'invalid hereWithSpace', '-cantStartWithHyphen', '_OrUnderscore'\n];\n\n/**\n *\n */\nexport const PERSIST_OPTS_AND_RESULTS_IBGIBS_DEFAULT = false;\n\n/**\n * Yep, this one starts with default instead of ending with it.\n */\nexport const DEFAULT_LOCAL_SPACE_DESCRIPTION = `This is a local space. There are many like it, but this one is mine.`;\n\n/**\n * The main roots^gib ibgib uses this rel8n name to keep track of roots.\n */\nexport const SPACE_REL8N_NAME = 'space';\n\n/**\n * rel8n name in a space ibgib to the config ibgib(s?)\n */\nexport const SPACE_REL8N_NAME_CONFIG = `config`;\n/**\n * note that atow this is implied in the regexp not derivative\n * @see {@link SPACE_NAME_REGEXP}\n */\nexport const SPACE_NAME_MAX_LENGTH = 64;\n/**\n * alphanumerics start + end, middle can also contain hyphens atow.\n *\n * NOTE: this implies the value of {@link SPACE_NAME_MAX_LENGTH} but this is not\n * derived from the value. so if you change this, be sure to change/check that\n *\n * @see {@link SPACE_NAME_MAX_LENGTH}\n */\nexport const SPACE_NAME_REGEXP = /^[a-zA-Z][\\w\\-]{0,62}[a-zA-Z]$/;\n\n/**\n * A spaces ibGib uses this rel8n name for related sync spaces, used\n * in replicating ibgib spaces.\n */\nexport const SYNC_SPACE_REL8N_NAME = 'syncSpace';\n\n/**\n * ...?\n */\nexport const DEFAULT_SPACE_TEXT = 'space';\n/**\n * Default icon specifically for spaces.\n */\nexport const DEFAULT_SPACE_ICON = 'sparkles-outline';\n/**\n * Default description specifically for spaces.\n */\nexport const DEFAULT_SPACE_DESCRIPTION =\n `This is a space ibgib, which is basically a special ibgib who has behavior\nto interface with data stores and/or other space(s) to provide concrete location\nfor ibgibs. All ibgibs can have relationships with other ibgibs, but this one\nspecifically either implies a physical interface to things like databases,\nfile systems, and similar; OR, when this space interfaces with other spaces, this\nis a logical organization of ibgib locations, like when configuring clusters or\nconsensus algorithms.`;\n/**\n * rel8n name used inside the root to those ibgib it contains.\n *\n * @example\n * ```json\n * {\n * ib: root,\n * gib: ABC123,\n * data: {...},\n * rel8ns: {\n * [rel8nName]: [\"a^1\", \"b^2\"]\n * }\n * }\n * ```\n */\nexport const DEFAULT_SPACE_REL8N_NAME = 'x';\n\n/**\n * Interval in ms between polling for updates (\"notifications\") between local\n * space (ibgibs service) and dynamo sync space(s), or for use within a single\n * space for checking its internal state.\n *\n * Of course, long polling is very hacky, but so is using DynamoDB in the cloud\n * for a sync space. Obviously need to progress to a more mature and robust sync\n * space/outer space architecture.\n */\nexport const DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS = 30_000;\nexport const DEFAULT_LOCAL_SPACE_POLLING_DELAY_FIRST_RUN_MS = 10_000;\n\n/**\n * it's a space\n */\nexport const SPACE_ATOM = 'space';\n\n/**\n * {@link DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS} but for outer spaces, so\n * longer interval atow.\n */\nexport const DEFAULT_OUTER_SPACE_POLLING_INTERVAL_MS = 20_000;\n/**\n * Amount of time to delay for FIRST poll execution.\n */\nexport const DEFAULT_OUTER_SPACE_POLLING_DELAY_FIRST_RUN_MS = 10_000;\n\n/**\n * When a status is first created, this is used to indicate that\n * the tjp has not been set.\n */\nexport const STATUS_UNDEFINED_TJP_GIB = GIB;\n/**\n * When a status is first created, this is used to indicate that\n * the txId has not been set.\n */\nexport const STATUS_UNDEFINED_TX_ID = '0';\n\nexport const SPACE_LOCK_IB_TERM = 'space_lock';\n/**\n * When attempting to acquire a lock ona space, and it is already lock, it will\n * wait a random amount of ms before trying to lock again. This is the default\n * max amount of ms before reattempting.\n */\nexport const DEFAULT_MAX_DELAY_MS_RETRY_LOCK_ACQUIRE = 100;\n/**\n * Will retry this many times before giving up...\n */\nexport const DEFAULT_MAX_DELAY_RETRY_LOCK_ACQUIRE_ATTEMPTS = 100;\n/**\n * We don't want someone locking a space forever by accident.\n */\nexport const MAX_LOCK_SECONDS_VALID = 60 * 2; // two minutes\n/**\n * Default value for secondsValid when acquiring/releasing lock in/on LOCAL\n * space.\n */\nexport const DEFAULT_SECONDS_VALID_LOCAL = 30;\n/**\n * Default value for secondsValid when acquiring/releasing lock in/on\n * OUTER space, e.g. sync spaces like aws dynamo sync space.\n */\nexport const DEFAULT_SECONDS_VALID_OUTER = 30;\n\n/**\n * retry count when calling getDependencyGraph.\n *\n * ## driving use case\n *\n * dependency graph fails when concurrent merges made in sync space.\n * need to wait until previous graph merger happens then retry.\n */\nexport const DEFAULT_MAX_RETRIES_GET_DEPENDENCY_GRAPH_OUTERSPACE = 5;\n/**\n * when getting dependency graph, sometimes we have to wait to retry\n */\nexport const DEFAULT_MS_BETWEEN_RETRIES_GET_DEPENDENCY_GRAPH_OUTERSPACE = 5000;\n/**\n * retry count when calling getDependencyGraph.\n *\n * ## driving use case\n *\n * dependency graph fails when concurrent merges made in sync space.\n * need to wait until previous graph merger happens then retry.\n */\nexport const DEFAULT_MAX_RETRIES_GET_DEPENDENCY_GRAPH_LOCAL = 3;\n/**\n * when getting dependency graph, sometimes we have to wait to retry\n */\nexport const DEFAULT_MS_BETWEEN_RETRIES_GET_DEPENDENCY_GRAPH_LOCAL = 1000;\n\n/**\n * currently not used in ionic-gib.\n */\nexport const DEFAULT_TX_ID_LENGTH = 5;\n", "/**\n * The main roots^gib ibgib uses this rel8n name to keep track of roots.\n *\n * NOTE: This is different than the rel8nName that a root ibgib uses to link to its ibgibs!\n * {@link DEFAULT_ROOT_REL8N_NAME}\n */\nexport const ROOT_REL8N_NAME = 'root';\n\n/**\n * rel8n name used inside the root to those ibgib it contains. (root.rel8ns.x = [pic1^gib, comment2^gib, ...])\n *\n *\n * NOTE: This is different than the rel8nName 'root' that the roots^gib uses. (roots.rel8ns.root = [root1^gib, root2^gib, ...])\n * {@link ROOT_REL8N_NAME}\n *\n * @example\n * ```json\n * {\n * ib: root,\n * gib: ABC123,\n * data: {...},\n * rel8ns: {\n * [rel8nName]: [\"a^1\", \"b^2\"]\n * }\n * }\n * ```\n */\nexport const DEFAULT_ROOT_REL8N_NAME = 'x';\n\n/**\n *\n */\nexport const DEFAULT_ROOT_TEXT = 'root';\n/**\n * Default icon specifically for roots.\n */\nexport const DEFAULT_ROOT_ICON = 'analytics-outline';\n/**\n * Default description specifically for roots.\n */\nexport const DEFAULT_ROOT_DESCRIPTION = 'This is a root ibgib, which is basically like a root folder that is primarily responsible for \"containing\" other ibgibs.';\n", "// export const TAGS_IB = 'tags';\n// export const TAGS_IBGIB_ADDR = `${TAGS_IB}^${GIB}`;\n// export const TAGS_IBGIB_ADDR_KEY = `key ${TAGS_IBGIB_ADDR}`;\n\n/**\n * The main tags^gib ibgib uses this rel8n name to keep track of tags.\n */\nexport const TAG_REL8N_NAME = 'tag';\n\n/**\n * A tag ibGib uses this rel8n name for the ibgibs that it targets.\n */\nexport const TAG_TARGET_REL8N_NAME = 'target';\n\n\nexport const ILLEGAL_TAG_TEXT_CHARS = [\n '^', '?', '/', '\\\\', `|`,\n];\n\nexport const ILLEGAL_TAG_DESC_CHARS = [\n '^',\n];\n\n/**\n * Default icon when creating a tag.\n */\nexport const DEFAULT_TAG_ICON = 'pricetag-outline';\n/**\n * Default description when creating a tag.\n */\nexport const DEFAULT_TAG_DESCRIPTION = 'This is a tag used for organizing data.';\n\n// export const TAG_TEXT_REGEXP = /^\\w[\\w .\\-?!]{1,30}[\\w.?!]$/;\n// export const TAG_TEXT_REGEXP_DESCRIPTION = `tag text must start and end with an alphanumeric, and can contain a hyphen, question mark, dot or space.`;\n", "/**\n * @module\n *\n * not quite sure where these go.\n *\n * todo: check after the project is building where these other-constants fit.\n */\n\n/**\n * default id settings where...?\n */\nexport const DEFAULT_UUID = undefined;\n\nimport { ROBBOT_REL8N_NAME } from '../../witness/robbot/robbot-constants.mjs';\nimport { SYNC_SPACE_REL8N_NAME } from '../../witness/space/space-constants.mjs';\nimport { DEFAULT_ROOT_REL8N_NAME, ROOT_REL8N_NAME } from '../root/root-constants.mjs';\nimport { TAG_TARGET_REL8N_NAME, TAG_REL8N_NAME } from '../tag/tag-constants.mjs';\n\nexport const AUTOSYNC_ALWAYS_REL8N_NAME = 'always';\nexport const ARCHIVE_REL8N_NAME = 'archive';\nexport const TRASH_REL8N_NAME = 'trash';\n\n/**\n * These rel8n names are shown in a list view by default.\n *\n * This should perhaps go into a chat or common ux constants?\n */\nexport const DEFAULT_LIST_REL8N_NAMES: string[] = [\n 'pic', 'comment', 'link',\n 'result', 'import',\n 'tagged',\n TAG_TARGET_REL8N_NAME,\n TAG_REL8N_NAME,\n ROOT_REL8N_NAME, // hack for now to get all to show\n DEFAULT_ROOT_REL8N_NAME,\n ROBBOT_REL8N_NAME,\n SYNC_SPACE_REL8N_NAME,\n];\n\n/**\n *\n */\nexport const CURRENT_VERSION = '1';\n\n/**\n * List of common special chars for english.\n *\n * ## intent\n *\n * When sanitizing input.\n */\nexport const ALLISH_SPECIAL_CHARS = `\\`~!@#$%^&*()_\\\\-+=|\\\\\\\\\\\\]}[{\"':;?/>.<,`;\nexport const FILENAME_SPECIAL_CHARS = ` \\`~!@#$%&*()_\\\\-+=|\\\\]}[{\"';?>.<,`;\n\n/**\n * If this matches, then we will encode the data field in our storage (aws\n * anyway atow)\n */\nexport const IBGIB_DATA_REGEX_INDICATES_NEED_TO_ENCODE = /[^\\w\\s\\d`~!@#$%\\^&*()_\\\\\\-+=|\\]\\}\\[\\{\"':;?/>.<,]/;\n\n/**\n * hacky scroll to bottom after items load per platform\n */\nexport const DEFAULT_SCROLL_DELAY_MS_WEB_HACK = 5_000;\n/**\n * hacky scroll to bottom after items load per platform\n */\nexport const DEFAULT_SCROLL_DELAY_MS_ANDROID_HACK = 3_000;\n/**\n * hacky scroll to bottom after items load per platform\n */\nexport const DEFAULT_SCROLL_DELAY_MS_IOS_HACK = 2_000;\n\n/**\n * when you create a meta special ibgib, it must just be some alphanumerics.\n */\nexport const SPECIAL_IBGIB_TYPE_REGEXP = /^\\w{1,32}$/;\n\n/**\n * big weird decision in JS this one...\n */\nexport const INVALID_DATE_STRING = \"Invalid Date\";\n", "import { GIB } from \"@ibgib/ts-gib/dist/V1/constants.mjs\"\nimport { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\"\n\n/**\n * primitive ibgib for indicating a true value\n */\nexport const TRUE_GIB: IbGib_V1 = { ib: 'true', gib: GIB }\n/**\n * primitive ibgib for indicating a truthy value\n */\nexport const TRUTHY_GIB: IbGib_V1 = { ib: 'truthy', gib: GIB };\n/**\n * primitive ibgib for indicating a false value\n */\nexport const FALSE_GIB: IbGib_V1 = { ib: 'false', gib: GIB }\n/**\n * primitive ibgib for indicating a falsy value\n */\nexport const FALSY_GIB: IbGib_V1 = { ib: 'falsy', gib: GIB }\n\n/**\n * config entries in space rel8ns/data will start with this\n */\nexport const CONFIG_KEY_ATOM = 'config_key';\n", "import { Ib } from '@ibgib/ts-gib/dist/types.mjs';\n\nexport const DEFAULT_META_IB_STARTS: Ib[] = [\n 'tags', 'tag ', 'settings', 'setting ', 'witness space ',\n]\nexport const SPECIAL_URLS = [\n 'tags', 'home'\n];\n\n/**\n * When showing a menu item, this is the max length\n */\nexport const MENU_ITEM_IB_SUBSTRING_LENGTH = 20;\n\nexport const QUERY_PARAM_PAUSED = 'paused';\nexport const QUERY_PARAM_ROBBOT = 'robbot';\n\nexport const APP_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,32}$/;\nexport const APP_REL8N_NAME = 'app';\n", "import { GIB } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\n/**\n * See {@link BootstrapIbGib}\n */\nexport const BOOTSTRAP_IBGIB_ADDR = `bootstrap^${GIB}`;\n/**\n * {@see BootstrapData}\n */\nexport const BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY = `defaultSpaceId`;\n/**\n * Key for index tracking known spaceIds in a bootstrap ibgib.\n * {@see BootstrapData}\n */\nexport const BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY = `spaceIds`;\n", "/**\n * There are multiple ways to incorporate the salt into the overall algorithm.\n * See the individual constant properties for details.\n *\n * {@link SaltStrategy} constant\n */\nexport type SaltStrategy =\n 'prependPerHash' | 'appendPerHash' |\n 'initialPrepend' | 'initialAppend';\n/**\n * enum-like constant for use in tandem with `SaltStrategy` type.\n *\n * See the individual constant properties for details.\n */\nexport const SaltStrategy = {\n /**\n * EACH time we hash anything in a round function or initial key-stretching,\n * we will prepend the salt via string concatenation with the secret, if\n * initial (salt + secret), else with the previous hash (salt + prev).\n */\n prependPerHash: 'prependPerHash' as SaltStrategy,\n /**\n * EACH time we hash anything in a round function or initial key-stretching,\n * we will append the salt via string concatenation with the secret, if\n * initial (secret + salt), else with the previous hash (prev + salt).\n */\n appendPerHash: 'appendPerHash' as SaltStrategy,\n /**\n * We will only prepend the salt to the secret (salt + secret) via string\n * concatenation ONLY in the initial key-stretching recurions phase.\n */\n initialPrepend: 'initialPrepend' as SaltStrategy,\n /**\n * We will only append the salt to the secret (secret + salt) via string\n * concatenation ONLY in the initial key-stretching recurions phase.\n */\n initialAppend: 'initialAppend' as SaltStrategy,\n} as const satisfies { [key: string]: SaltStrategy };\n/**\n * convenience constant array containing all of `Object.values(SaltStrategy)`\n */\nexport const SALT_STRATEGIES: SaltStrategy[] = Object.values(SaltStrategy);\n\n/**\n * Hash algorithm type.\n *\n * atow this is only SHA-256 and SHA-512 because both of these are relatively\n * strong and are supported in both node and browser environments. I have found\n * conflicting information on whether or not these are post-quantum secure.\n */\nexport type HashAlgorithm = 'SHA-256' | 'SHA-512';\n/**\n * enum-like constant for use in tandem with `HashAlgorithm` type.\n */\nexport const HashAlgorithm = {\n 'sha_256': 'SHA-256' as HashAlgorithm,\n 'sha_512': 'SHA-512' as HashAlgorithm,\n} satisfies { [key: string]: HashAlgorithm };\nexport const HASH_ALGORITHMS: HashAlgorithm[] = Object.values(HashAlgorithm);\n\nexport type AlphabetIndexingMode = 'indexOf' | 'lastIndexOf';\n/**\n * when iterating characters, this determines whether we are using `'indexOf'` or\n * `'lastIndexOf'` on the alphabet string.\n *\n * So if the JIT hex alphabet is abc123abc456 and our character is b:\n *\n * abc123abc456\n * ^ ^\n * 1\n * * `'indexOf'` -> 1\n * * `'lastIndexOf'` -> 7\n *\n * with immediately expanding JIT alphabets, this shouldn't make much of a\n * difference. But when mitigating brute force short-circuit attacks, where\n * the brute forcer only decrypts the first couple of characters of data, we\n * may combine `'lastIndexOf'` with a \"multipass\" expanding alphabet to\n * ensure that a larger portion of the plaintext (up to 100% of the\n * plaintext), is required to be processed before any short-circuiting\n * decryption can occur. @see {@link BlockModeOptions}\n *\n * To help understand this, here is an example. Say we use a multi-pass\n * alphabet that requires a minimum of 3 expansions. We encipher the first\n * character of plaintext we first convert that character to hex. Say this\n * hex is 'a'. Now we create our corresponding alphabet by recursively\n * rounding on the initial `prevHash` (after key stretching with\n * `initialRecursions` has occurred). Say one round produces a hash\n * '123a56ba90' for our one-time JIT alphabet. If this were an immediately\n * expanding JIT alphabet with no minimum expansions and the ciphertext is\n * already present, then additional rounds won't be needed for the attacker\n * - they already have the index and the alphabet that has the plaintext.\n *\n * With `lastIndexOf` + multipass blocks, then the attacker is forced to\n * calculate at least the entire section's hashing because the encrypted\n * index will most likely be at the end of the alphabet.\n *\n * abc123...[200ish hex character]...bac231\n * ^\n * The first `indexOf('2')` would just be 4, and no other alphabet\n * extensions would be required (not a single one in the section). Whereas\n * the `lastIndexOf('2')` would be a 200+ index. This would require multiple\n * hashes for every previous character in the section, and would thus harder\n * to short-circuit.\n *\n * @default `'indexOf'`\n */\nexport const AlphabetIndexingMode = {\n indexOf: 'indexOf',\n lastIndexOf: 'lastIndexOf',\n} satisfies { [key: string]: AlphabetIndexingMode };\nexport const ALPHABET_INDEXING_MODES: AlphabetIndexingMode[] = Object.values(AlphabetIndexingMode);\n\n/**\n * # tl;dr\n *\n * Block mode is stronger but slower relative to the stream mode.\n *\n * When block mode is enabled, we do multiple passes on sections of plaintext\n * when encrypting/decrypting.\n *\n * This is one way to help mitigate against short-circuit brute force\n * attacks.\n *\n * # how it works\n *\n * The block-mode algorithm works as follows:\n *\n * ## encrypting\n *\n * * plaintext characters - p0, p1, .., pi\n * * JIT alphabet hashes - [a0.0, a0.1, a0.2, .., a0.j], [a1.0, a1.1, a1.2, .., a1.j], .., [ai.0, ai.1, ai.2, .., ai.j]\n * * i = plaintext index\n * * j = alphabet expansion index\n * * passes - PASS1, PASS2, .., PASSn\n *\n * 1. First we iterate through the plaintext data in multipass blocks, the\n * size of which is parameterized by `maxBlockSize`. If this is larger\n * than data, then the entire plaintext will be used.\n *\n * 2. Then we create the initial alphabets for the entire section, determined by\n * our pass section size and the number of passes.\n *\n * 3. We then extend any individual alphabets that do not contain an instance of\n * the plaintext character yet. We are extending only those alphabets in need of\n * extending, as opposed to the previous step where we extended all alphabets in\n * the pass section.\n *\n * 4. We get the index of each plaintext character into its corresponding\n * alphabet and store each index in an array for the entire multipass block.\n * We then concat this new section with any previous sections encrypted,\n * building out our entire result `encryptedData` array section by section.\n *\n * 5. Lastly, we return the array as a string, joining each index with the\n * parameterized delimiter (comma by default).\n *\n * ## decrypting\n *\n * The decryption process is very similar.\n *\n * 1. First we iterate through the ciphertext data in multipass blocks, the\n * size of which must be the same as the encryption process (all parameters\n * should be the same encrypting and decrypting. these are automatically stored\n * in encryption output file).\n *\n * 2. Next we create our alphabets for the entire section. The first phase of\n * this is to build out the minimum sized alphabets per parameters\n * (`numOfPasses`).\n *\n * 3. Next we iterate through the encryped indexes for the section. While the\n * index is larger than the existing alphabet, the alphabet is JIT extended by\n * the hash round function. Once the alphabet is large enough (i.e. the\n * encrypted index can index into it), the the encrypted index is used in the\n * alphabet and the plaintext hex character is stored in a result array for the\n * section.\n *\n * 4. Once the entire section is decrypted to hex, the section's plaintext array\n * is added to the previously decrypted sections' plaintext results.\n *\n * 5. Once all sections are decrypted to hex, the plaintext array is converted to a\n * hex string and then decoded to the original plaintext.\n */\nexport interface BlockModeOptions {\n /**\n * Maximum number of **hex-encoded** plaintext characters per section when\n * making multiple passes. Each pass extends the JIT alphabet for each\n * character in that pass by the length of the hash digest being used (since\n * the hashes are what the alphabets are made of).\n *\n * * If this is greater than the hex-encoded `dataToEncrypt` length, then\n * each pass section will be the length of data (it's goin to do the whole\n * plaintext in one section).\n * * Barring internal JS voodoo, each pass should require additional memory\n * roughly linearly proportional to\n * * `dataToEncrypt`/`maxBlockSize` length (whichever is smaller)\n * * `numOfPasses` to make\n * * length of the hash used in creating the JIT alphabets (`hashAlgorithm`)\n * * The larger `maxBlockSize` & `numOfPasses` is, the more a brute\n * force attack has to calculate - and the more memory it is going to take\n * - before determining if a secret guess is correct.\n */\n maxBlockSize: number;\n /**\n * @deprecated\n *\n * use {@link maxBlockSize}\n */\n maxPassSectionLength?: number;\n /**\n * Number of \"passes\" to make over the pass section. Each pass will extend\n * the JIT alphabet for each character in the pass section by the length of\n * the hash digest string used in `hashAlgorithm`.\n *\n * This should be especially effective in mitigating against brute force\n * cracking when used in tandem with an `indexingMode` of `lastIndexOf`.\n * This is because at least `(numOfPasses - 1) * maxBlockSize`\n * number of hash rounds must be calculated before the very first plaintext\n * character can be deciphered. This is even more expensive if\n * `recursionsPerHash` is larger.\n */\n numOfPasses: number;\n}\n\n/**\n * Shared interface among both args and results.\n *\n * ## notes\n *\n * Silly name... naming things hrmm.\n */\ninterface BaseBase {\n /**\n * how to index into the jit alphabet\n *\n * @see {@link AlphabetIndexingMode}\n */\n indexingMode?: AlphabetIndexingMode;\n /**\n * Settings to use if we want to use multiple passes when\n * encrypting/decrypting.\n *\n * This is one way to help mitigate against short-circuit brute force\n * attacks.\n *\n * @see {@link BlockModeOptions}\n */\n blockMode?: BlockModeOptions;\n /**\n * @deprecated\n *\n * Use `blockMode` instead.\n */\n multipass?: BlockModeOptions;\n /**\n * The hash algorithm to use.\n *\n * ATOW, this is either 'SHA-256' or 'SHA-512'.\n *\n * @see {@link HashAlgorithm} for current values.\n */\n hashAlgorithm?: HashAlgorithm;\n /**\n * The amount of recursions from the secret + salt to start actual\n * encryption mapping.\n *\n * The bigger this is, the more time it takes to try guesses for an\n * attacker, depending on how expensive the hash function is. But also the\n * more time it would take on the legitimate user's password attempt.\n */\n initialRecursions: number;\n /**\n * The number of recursive hashes we perform for each round function of\n * hashing (except the initial recursions, see `initialRecursions` param).\n *\n * This includes both when we hash each hex character of our hex-encoded\n * data, as well as each time we JIT extend the alphabet when the plaintext\n * hex character isn't found in the current JIT hash alphabet.\n *\n * So, if the initial hash alphabet is all a's (e.g. \"aaa...a\", a very\n * contrived hash!), but our hex data is a b, then we will hash the all-a\n * hash {recursionsPerHash} times to expand the alphabet.\n *\n * @example\n * So if we have a data character of 'b', and its immediate hash alphabet is\n * all a's, and we recurse 3 times per hash (ignoring salts for this\n * example), here is some simplified pseudo code to give the gist:\n *\n * ```javascript\n * dataCharToMap = 'b';\n * alphabet = hash(prevHash) // say it gives us 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';\n * needExpandAlphabet = alphabet.includes(dataCharToMap) // false in this case\n * if (needExpandAlphabet) {\n * hashToAdd = alphabet;\n * for (i = 0; i < recursionsPerHash; i++) { hashToAdd = hash(hashToAdd); }\n * alphabet = alphabet + hashToAdd; // say it's now 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab';\n * }\n * index = alphabet.indexOf(dataCharToMap); // 63\n * ```\n *\n * In actuality, the code will include salt and saltStrategy, and track how\n * many times the alphabet expands to get the correct index.\n *\n * Note that this does not add on each and every recursive hash produced. It\n * only adds on the last hash after recursionsPerHash number of hashes (i.e.\n * the alphabet is JIT extended the length of a single hash digest - the\n * last one).\n */\n recursionsPerHash?: number;\n /**\n * text to prepend/append to hashes for increased security.\n *\n * {@link SaltStrategy}\n */\n salt: string;\n\n /**\n * {@link SaltStrategy}\n */\n saltStrategy?: SaltStrategy;\n /**\n * Encrypted data is just an array of numbers (positive integers).\n * This array is converted to a string by joining with a delimiter.\n * This is that delimiter.\n *\n * @default DEFAULT_ENCRYPTED_DATA_DELIMITER in constants.ts\n */\n encryptedDataDelimiter?: string;\n}\n\n/**\n * Args-specific info, in contrast to result-specific info\n *\n * @see {@link BaseResult}\n */\nexport interface BaseArgs extends BaseBase {\n secret: string;\n}\n\n/**\n * Info passed to the `encrypt` function.\n */\nexport interface EncryptArgs extends BaseArgs {\n /**\n * Plaintext data string\n */\n dataToEncrypt: string;\n /**\n * If true, will decrypt back and confirm that the decryption was\n * successfully performed and the original plaintext is recoverable via the\n * decryption process.\n *\n * Takes more time & resources.\n */\n confirm?: boolean;\n}\n\n/**\n * Info passed to the `decrypt` function.\n */\nexport interface DecryptArgs extends BaseArgs {\n /**\n * String of delimited encrypted indexes.\n */\n encryptedData: string;\n}\n\n/**\n * Result-specific info, in contrast to args-specific info\n *\n * @see {@link BaseArgs}\n */\ninterface BaseResult extends BaseBase {\n /**\n * If truthy, there were big problems...\n */\n errors?: string[];\n /**\n * If truthy, there were issues...\n */\n warnings?: string[];\n}\n\n/**\n * Result info from `encrypt` function.\n */\nexport interface EncryptResult extends BaseResult {\n /**\n String of delimited encrypted indexes.\n */\n encryptedData?: string;\n}\n\n/**\n * Result info from `decrypt` function.\n */\nexport interface DecryptResult extends BaseResult {\n decryptedData?: string;\n}\n", "/**\n * @module helper utility functions specific to encrypt-gib\n *\n * THANK YOU Stack Overflow, Simon Buchan, and others at https://stackoverflow.com/questions/21647928/javascript-unicode-string-to-hex\n */\n\nimport { extractErrorMsg } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\n\n\n/**\n * Convert some string to a string with only hex characters.\n *\n * Should (hopefully!) be reversible.\n *\n * @param s string to convert to hex string\n * @returns string that only contains hexidecimal characters (0-9, a-f)\n */\nexport function encodeStringToHexString(s: string): Promise<string> {\n const lc = `[${encodeStringToHexString.name}]`;\n return new Promise((resolve, reject) => {\n try {\n let bytes = stringToUTF8Bytes(s);\n let hexString = bytesToHexString(bytes);\n resolve(hexString);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n reject(error);\n }\n });\n}\n\nfunction stringToUTF8Bytes(s: string): Uint8Array {\n const lc = `[${stringToUTF8Bytes.name}]`;\n try {\n return new TextEncoder().encode(s);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nfunction bytesToHexString(bytes: Uint8Array): string {\n const lc = `[${bytesToHexString.name}]`;\n try {\n return Array.from(\n bytes,\n byte => byte.toString(16).padStart(2, '0')\n ).join(\"\");\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Decodes the hex-encoded string back to the original text.\n *\n * @param hexString Encoded x of some some data string\n * @returns Decoded (original hopefully!) text\n */\nexport function decodeHexStringToString(hexString: string): Promise<string> {\n const lc = `[${decodeHexStringToString.name}]`;\n return new Promise((resolve, reject) => {\n try {\n // console.log(`${lc} hexString (len: ${hexString.length}): ${hexString}`);\n const bytes = hexStringToBytes(hexString);\n const s = utf8BytesToString(bytes);\n resolve(s);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n reject(error);\n }\n });\n}\n\n/**\n * Converts hex to bytes.\n *\n * Ty also https://stackoverflow.com/questions/14603205/how-to-convert-hex-string-into-a-bytes-array-and-a-bytes-array-in-the-hex-strin\n *\n * @param hexString string that (obviously) should be hex to convert to bytes\n */\nfunction hexStringToBytes(hexString: string): Uint8Array {\n const lc = `[${hexStringToBytes.name}]`;\n try {\n // console.log(`${lc} hexString (len: ${hexString.length}): ${hexString}`);\n if (hexString.length % 2 !== 0) { throw new Error(`invalid hex string. length %2 !== 0`); }\n const numBytes = hexString.length / 2;\n const bytes = new Uint8Array(numBytes);\n for (let i = 0; i < numBytes; i++) {\n bytes[i] = parseInt(hexString.substr(i * 2, 2), 16);\n }\n return bytes;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\nfunction utf8BytesToString(bytes: Uint8Array): string {\n const lc = `[${utf8BytesToString.name}]`;\n try {\n return new TextDecoder().decode(bytes);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { AlphabetIndexingMode, HashAlgorithm, SaltStrategy } from \"./index.mjs\";\n\nexport const ENCRYPT_LOG_A_LOT = false;\n\nexport var DEFAULT_SALT_STRATEGY: SaltStrategy = SaltStrategy.appendPerHash;\n// export var DEFAULT_HASH_ALGORITHM: HashAlgorithm = 'SHA-256';\nexport var DEFAULT_HASH_ALGORITHM: HashAlgorithm = 'SHA-512';\nexport var DEFAULT_GETUUID_SEEDSIZE: number = 1024;\nexport var DEFAULT_INITIAL_RECURSIONS: number = 20000;\nexport var DEFAULT_RECURSIONS_PER_HASH: number = 1;\n/**\n * This must be indexOf for backwards compatibility.\n */\nexport var DEFAULT_ALPHABET_INDEXING_MODE_LEGACY: AlphabetIndexingMode = 'indexOf';\n/**\n * In multipass, which is being developed to help mitigate against short-circuit\n * brute force attacks, I believe it's safer to use `lastIndexOf` in order to\n * leverage the alphabet extensions in other options. This may turn out to be\n * unnecessary.\n */\nexport var DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE: AlphabetIndexingMode = 'lastIndexOf';\n/**\n * Default value for the maximum size of a block, when using block mode (if the\n * total plaintext data is smaller than this, then the effective block size is\n * that data's length).\n *\n * This is essentially how many groups of hex-encoded plaintext characters are\n * we going to iterate on at one time with multiple passes. So if you have a\n * block size of 1000, then the block mode encryption will have to keep in\n * memory (or store/retrieve dynamically if an attacker rewrites this library's\n * internals) at least 1000 hashes for the entire block before being able to\n * compute the second pass's hash of the first character. So for 2 passes and a\n * hashLength (digestLength) of 64 bytes, this would be roughly 1000 *\n * hashLength bytes * (numOfPasses - 1)~~> 64 kB of memory. (though really I\n * think this is 128 kB because current implementation just treats the digest as\n * a string)\n *\n * Used in block mode.\n */\nexport var DEFAULT_MAX_BLOCK_SIZE: number = 5_000_000;\n/**\n * Default value for the number of passes when using block mode.\n *\n * Used in block mode\n */\nexport var DEFAULT_NUM_OF_PASSES: number = 4;\n\nexport var DEFAULT_ENCRYPTED_DATA_DELIMITER: string = ',';\n", "import { extractErrorMsg, hash as hashFn } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { HashAlgorithm, SaltStrategy } from \"../types.mjs\";\n\n/**\n * Builds the string that we will hash to get the next hash alphabet.\n *\n * @example\n * if we're prepending every hash, and this is the initial hash,\n * then we'll return `salt + secret`.\n *\n * @returns the string we're going to hash to get the next alphabet\n */\nexport function getPreHash({\n secret,\n prevHash,\n salt,\n saltStrategy,\n}: {\n secret?: string,\n prevHash?: string,\n salt: string,\n saltStrategy: SaltStrategy,\n}): string {\n if (!(prevHash || secret)) { throw new Error(`Either secret or prevHash is required, but both are falsy (E: bee2849729ff410081d963777dcedb49))`); }\n // either prevHash or secret is guaranteed for all the following cases\n switch (saltStrategy) {\n case SaltStrategy.prependPerHash:\n return salt + (prevHash || secret)\n case SaltStrategy.appendPerHash:\n return (prevHash || secret) + salt;\n case SaltStrategy.initialPrepend:\n return prevHash ? prevHash : salt + secret;\n case SaltStrategy.initialAppend:\n return prevHash ? prevHash : secret + salt;\n default:\n throw new Error(`Unknown saltStrategy: ${saltStrategy} (E: 235136af1a6c40eb9c17b2ca41c08a01)`);\n }\n}\n\nexport async function execRound_getNextHash({\n secret,\n prevHash,\n count,\n salt,\n saltStrategy,\n hashAlgorithm,\n}: {\n secret?: string,\n prevHash?: string,\n count: number,\n salt: string,\n saltStrategy: SaltStrategy,\n hashAlgorithm: HashAlgorithm,\n}): Promise<string> {\n const lc = `[${execRound_getNextHash.name}]`;\n try {\n let hash = prevHash || undefined;\n for (let i = 0; i < count; i++) {\n const preHash = getPreHash({ secret, prevHash: hash, salt, saltStrategy });\n hash = await hashFn({ s: preHash, algorithm: hashAlgorithm });\n }\n if (!hash) { throw new Error(`hash was not created (E: 09dfdfd644734727a34a1bc0bd8e93b9)`); }\n return hash;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Creates the first \"alphabet\" that we will index into.\n *\n * We have this separate, because the initialRecursions help us\n * chug on the secret.\n *\n * If the data's hex character is not in this alphabet, it will\n * be expanded just as any\n */\nexport async function doInitialRecursions_keystretch({\n secret,\n initialRecursions,\n salt,\n saltStrategy,\n hashAlgorithm,\n}: {\n secret: string,\n initialRecursions: number,\n salt: string,\n saltStrategy: SaltStrategy,\n hashAlgorithm: HashAlgorithm,\n}): Promise<string> {\n const lc = `[${doInitialRecursions_keystretch.name}]`;\n try {\n const hash = await execRound_getNextHash({\n secret,\n count: initialRecursions,\n salt, saltStrategy, hashAlgorithm,\n })\n return hash;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { doInitialRecursions_keystretch, execRound_getNextHash, } from \"../common/encrypt-decrypt-common.mjs\";\nimport { AlphabetIndexingMode, HashAlgorithm, SaltStrategy } from \"../types.mjs\";\n\n/**\n * Does the actual encryption from hexEncodedData with the given params.\n *\n * @returns encryptedData\n */\nexport async function encryptFromHex_stream({\n hexEncodedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n indexingMode,\n}: {\n hexEncodedData: string,\n initialRecursions: number,\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n secret: string,\n hashAlgorithm: HashAlgorithm,\n encryptedDataDelimiter: string,\n indexingMode: AlphabetIndexingMode,\n}): Promise<string> {\n const lc = `[${encryptFromHex_stream.name}]`;\n\n try {\n // set up \"prevHash\" as a starting point, similar to key-stretching\n let prevHash = await doInitialRecursions_keystretch({\n secret,\n initialRecursions,\n salt,\n saltStrategy: saltStrategy!,\n hashAlgorithm: hashAlgorithm!,\n });\n // console.log(`${lc} first prevHash: ${prevHash}`);\n\n const getIndex: (alphabet: string, hexChar: string) => number =\n indexingMode === 'indexOf' ?\n (alphabet: string, hexChar: string) => { return alphabet.indexOf(hexChar) } :\n (alphabet: string, hexChar: string) => { return alphabet.lastIndexOf(hexChar) };\n // console.log(`${lc} using getIndex (indexingMode: ${indexingMode})`);\n\n // we have our prevHash starting point, so now we can iterate through the data\n let encryptedDataIndexes: number[] = [];\n for (let i = 0; i < hexEncodedData.length; i++) {\n // this is the character of data that we want to map to an index into the generated alphabet\n const hexCharFromData: string = hexEncodedData[i];\n let alphabet: string = \"\";\n let hash: string;\n while (!alphabet.includes(hexCharFromData)) {\n // if (alphabet.length > 64) {\n // console.log(`alphabet is extending past 64... alphabet.length: ${alphabet.length}`);\n // }\n // console.log(`${lc} doing iteration...`);\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash!;\n prevHash = hash;\n // console.log(`${lc} alphabet: ${alphabet}`); // debug\n }\n\n // we now have the alphabet, so find the index of hex character\n // const charIndex = alphabet.indexOf(hexCharFromData);\n const charIndex = getIndex(alphabet, hexCharFromData);\n // console.log(`${lc} charIndex: ${charIndex}`);\n encryptedDataIndexes.push(charIndex);\n }\n\n const encryptedData = encryptedDataIndexes.join(encryptedDataDelimiter);\n return encryptedData;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { doInitialRecursions_keystretch, execRound_getNextHash, getPreHash } from \"../common/encrypt-decrypt-common.mjs\";\nimport { HashAlgorithm, SaltStrategy } from \"../types.mjs\";\n\n/**\n * Takes a given encryptedData, in the form of a delimited string\n * of indexes, and decrypts it back into encoded hex (not the original\n * unencrypted data!).\n *\n * it does this by iterating\n *\n * @returns unencrypted, but still encoded, hex string of the original unencrypted data\n */\nexport async function decryptToHex_stream({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n}: {\n encryptedData: string,\n initialRecursions: number,\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n secret: string,\n hashAlgorithm: HashAlgorithm,\n encryptedDataDelimiter: string,\n}): Promise<string> {\n const lc = `[${decryptToHex_stream.name}]`;\n\n try {\n // set up \"prevHash\" as a starting point, similar to key-stretching\n let prevHash = await doInitialRecursions_keystretch({\n secret,\n initialRecursions,\n salt,\n saltStrategy: saltStrategy!,\n hashAlgorithm: hashAlgorithm!,\n });\n // console.log(`${lc} first prevHash: ${prevHash}`);\n\n // we have our prevHash starting point, so now we can iterate through the data\n // console.log(`${lc} encryptedDataDelimiter: ${encryptedDataDelimiter}`);\n let encryptedDataIndexes: number[] =\n encryptedData.split(encryptedDataDelimiter).map((nString: string) => parseInt(nString));\n // console.log(`${lc} encryptedDataIndexes: ${encryptedDataIndexes.toString()}`);\n let decryptedDataArray: string[] = [];\n for (let i = 0; i < encryptedDataIndexes.length; i++) {\n // this is the index of the character of data that we want to get\n // out of the alphabet map but to generate the alphabet, we may need\n // to do multiple hash iterations, depending on how big the index\n // is. So if we don't hit a '7' until the third hash, then we need\n // to keep building out the alphabet until that third hash.\n\n // HACK: I'm going to do this with a while loop instead of a for\n // because I want to get it working first.\n\n let charIndex = encryptedDataIndexes[i];\n // console.log(`${lc} charIndex: ${charIndex}`);\n let alphabet: string = \"\";\n let hash: string;\n while (charIndex >= alphabet.length) {\n // console.log(`${lc} doing iteration...`);\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash;\n prevHash = hash;\n // console.log(`${lc} alphabet: ${alphabet}`); // debug\n }\n\n // we now have the alphabet, so index into it to get the decrypted hex char\n let hexChar: string = alphabet[charIndex];\n decryptedDataArray.push(hexChar);\n }\n\n // console.log(`${lc} decryptedDataArray: ${decryptedDataArray.toString()}`);\n // reconstitute the decryptedHex\n const decryptedHex: string = decryptedDataArray.join('');\n // console.log(`${lc} decryptedHex: ${decryptedHex.toString()}`);\n return decryptedHex;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport * as c from '../constants.mjs';\nimport { decodeHexStringToString } from '../helper.mjs';\nimport { DecryptArgs, DecryptResult, HashAlgorithm, SALT_STRATEGIES } from \"../types.mjs\";\nimport { decryptToHex_stream } from './decrypt-to-hex-stream-mode.mjs';\n\n/**\n * Does the actual decryption work using the original stream code.\n *\n * I'm trying to change this as little as possible for reference and sanity\n * checks.\n *\n * {@link decrypt}\n * {@link DecryptArgs}\n * {@link DecryptResult}\n *\n * @returns a `DecryptResult` info object\n */\nexport async function decryptImpl_stream({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n}: DecryptArgs): Promise<DecryptResult> {\n const lc = `[${decryptImpl_stream.name}]`;\n // console.log(`${lc} encryptedDataDelimiter: ${encryptedDataDelimiter}`);\n\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // #region set args defaults\n\n initialRecursions = initialRecursions || c.DEFAULT_INITIAL_RECURSIONS;\n recursionsPerHash = recursionsPerHash || c.DEFAULT_RECURSIONS_PER_HASH;\n saltStrategy = saltStrategy || c.DEFAULT_SALT_STRATEGY;\n hashAlgorithm = hashAlgorithm || c.DEFAULT_HASH_ALGORITHM;\n salt = salt || await getUUID(c.DEFAULT_GETUUID_SEEDSIZE);\n encryptedDataDelimiter = encryptedDataDelimiter || c.DEFAULT_ENCRYPTED_DATA_DELIMITER;\n\n // #endregion\n\n // #region args validation\n\n const lcv = `[validation]`;\n\n if (!initialRecursions || initialRecursions < 1) { const e = `${lcv} initialRecursions required, and greater than 0`; console.error(e); errors.push(e); }\n if (!recursionsPerHash || recursionsPerHash < 1) { const e = `${lcv} recursionsPerHash required, and greater than 0`; console.error(e); errors.push(e); }\n if (!encryptedData) { const e = `${lcv} encryptedData required`; console.error(e); errors.push(e); }\n if (!salt) { const e = `${lcv} salt required`; console.error(e); errors.push(e); }\n if (!saltStrategy) { const e = `${lcv} saltStrategy required`; console.error(e); errors.push(e); }\n if (!secret) { const e = `${lcv} secret required`; console.error(e); errors.push(e); }\n if (!encryptedDataDelimiter) { const e = `${lcv} encryptedDataDelimiter required`; console.error(e); errors.push(e); }\n\n // if (hashAlgorithm !== 'SHA-256') { const e = `${lcv} only SHA-256 implemented`; console.error(e); errors.push(e); }\n if (!Object.values(HashAlgorithm).includes(hashAlgorithm)) {\n const e = `${lcv} only ${Object.values(HashAlgorithm)} hash algorithms implemented`; console.error(e); errors.push(e);\n }\n\n if (saltStrategy && !SALT_STRATEGIES.includes(saltStrategy!)) {\n const e = `${lcv} unknown saltStrategy: ${saltStrategy}`; console.error(e); errors.push(e);\n }\n\n if (errors.length > 0) {\n return {\n errors,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n hashAlgorithm,\n encryptedDataDelimiter,\n }\n }\n\n // #endregion\n\n // decrypt from indices into hex\n // console.log(`${lc} encryptedData: ${encryptedData}`);\n let hexEncodedData: string = await decryptToHex_stream({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n });\n\n // console.log(`${lc} hexEncodedData: ${hexEncodedData}`);\n // decode hex back into original data\n const decryptedData: string = await decodeHexStringToString(hexEncodedData);\n\n return {\n decryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n hashAlgorithm,\n encryptedDataDelimiter,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n", "import { getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport * as c from '../constants.mjs';\nimport { decodeHexStringToString, encodeStringToHexString } from '../helper.mjs';\nimport { ALPHABET_INDEXING_MODES, EncryptArgs, EncryptResult, HashAlgorithm, SALT_STRATEGIES } from \"../types.mjs\";\nimport { encryptFromHex_stream } from './encrypt-from-hex-stream-mode.mjs';\nimport { decryptImpl_stream } from './decrypt-stream-mode.mjs';\n\n/**\n * Does the actual encryption work using the original \"stream\" streaming\n * encryption.\n *\n * {@link encrypt}\n * {@link EncryptArgs}\n * {@link EncryptResult}\n *\n * @returns a `EncryptResult` info object\n */\nexport async function encryptImpl_stream({\n dataToEncrypt,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n confirm,\n indexingMode,\n}: EncryptArgs): Promise<EncryptResult> {\n const lc = `[${encryptImpl_stream.name}]`;\n\n const errors: string[] = [];\n let warnings: string[] = [];\n\n // #region set args defaults\n\n if (!initialRecursions) {\n console.warn(`${lc} initial recursions required. defaulting to ${c.DEFAULT_INITIAL_RECURSIONS}`);\n initialRecursions = c.DEFAULT_INITIAL_RECURSIONS;\n }\n recursionsPerHash = recursionsPerHash || c.DEFAULT_RECURSIONS_PER_HASH;\n saltStrategy = saltStrategy || c.DEFAULT_SALT_STRATEGY;\n hashAlgorithm = hashAlgorithm || c.DEFAULT_HASH_ALGORITHM;\n salt = salt || await getUUID(c.DEFAULT_GETUUID_SEEDSIZE);\n encryptedDataDelimiter = encryptedDataDelimiter || c.DEFAULT_ENCRYPTED_DATA_DELIMITER;\n indexingMode = indexingMode || c.DEFAULT_ALPHABET_INDEXING_MODE_LEGACY;\n\n // #endregion\n\n // #region args validation\n\n const lcv = `[validation]`;\n\n if (!initialRecursions || initialRecursions < 1) { const e = `${lcv} initialRecursions required, and greater than 0`; console.error(e); errors.push(e); }\n if (!recursionsPerHash || recursionsPerHash < 1) { const e = `${lcv} recursionsPerHash required, and greater than 0`; console.error(e); errors.push(e); }\n if (!dataToEncrypt) { const e = `${lcv} dataToEncrypt required`; console.error(e); errors.push(e); }\n if (!salt) { const e = `${lcv} salt required`; console.error(e); errors.push(e); }\n if (!saltStrategy) { const e = `${lcv} saltStrategy required`; console.error(e); errors.push(e); }\n if (!secret) { const e = `${lcv} secret required`; console.error(e); errors.push(e); }\n if (!encryptedDataDelimiter) { const e = `${lcv} encryptedDataDelimiter required`; console.error(e); errors.push(e); }\n if (!ALPHABET_INDEXING_MODES.includes(indexingMode)) { const e = `${lcv} invalid indexingMode (${indexingMode}). Must be one of ${ALPHABET_INDEXING_MODES} (E: 5955c46755434982982823c97adcf076)`; console.error(e); errors.push(e); }\n\n\n // if (hashAlgorithm !== 'SHA-256') { const e = `${lcv} only SHA-256 implemented`; console.error(e); errors.push(e); }\n if (!Object.values(HashAlgorithm).includes(hashAlgorithm)) {\n const e = `${lcv} only ${Object.values(HashAlgorithm)} hash algorithms implemented`; console.error(e); errors.push(e);\n }\n\n if (saltStrategy && !SALT_STRATEGIES.includes(saltStrategy!)) {\n const e = `${lcv} unknown saltStrategy: ${saltStrategy}`; console.error(e); errors.push(e);\n }\n\n if (errors.length > 0) {\n return {\n errors,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n hashAlgorithm,\n encryptedDataDelimiter,\n }\n }\n\n // #endregion\n\n // #region encode data to just hex (i.e. only have 0-9, a-f)\n\n // console.log(`${lc} hex encoding dataToEncrypt: ${dataToEncrypt}`);\n const hexEncodedData: string = await encodeStringToHexString(dataToEncrypt);\n if (confirm) {\n // confirm data can be converted back into the original data\n // console.log(`${lc} hex decoding back to check with dataToEncrypt: ${hexEncodedData}`);\n const confirmDecodedData = await decodeHexStringToString(hexEncodedData);\n // console.log(`${lc} checkDecodedData: ${confirmDecodedData}`);\n if (confirmDecodedData !== dataToEncrypt) {\n throw new Error(`decoding encoded hex failed for this data: The encoded hex did not reverse to the original data.`);\n }\n }\n\n // #endregion\n\n // #region encrypt hex\n\n // comma-delimited indexes string\n let encryptedData: string = await encryptFromHex_stream({\n hexEncodedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n indexingMode: 'indexOf',\n });\n\n if (confirm) {\n const resDecrypt = await decryptImpl_stream({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n });\n if ((resDecrypt.errors || []).length > 0) {\n return {\n errors: [`Confirm check found that decrypt had errors.`, ...resDecrypt.errors!],\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n hashAlgorithm,\n encryptedDataDelimiter,\n };\n } else if (!resDecrypt.decryptedData) {\n throw new Error(`Confirm check call to decrypt produced falsy decryptedData`);\n } else if (resDecrypt.decryptedData !== dataToEncrypt) {\n // DO NOT LEAVE THIS IN PROD!!!\n // console.log(`resDecrypt.decryptedData: ${resDecrypt.decryptedData}`); // DO NOT LEAVE THIS IN PROD!!!\n // console.log(`dataToEncrypt: ${dataToEncrypt}`); // DO NOT LEAVE THIS IN PROD!!!\n // DO NOT LEAVE THIS IN PROD!!!\n throw new Error(`The ENCRYPTED data did not decrypt back to the original data.`);\n } else {\n // console.log(`${lc} decrypt confirmed.`);\n }\n if ((resDecrypt.warnings || []).length > 0) {\n warnings = warnings.concat([`Confirm check call to decrypt had warnings.`, ...resDecrypt.warnings!])\n }\n }\n\n // #endregion\n\n return {\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n hashAlgorithm,\n encryptedDataDelimiter,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { doInitialRecursions_keystretch, execRound_getNextHash, } from \"../common/encrypt-decrypt-common.mjs\";\nimport { AlphabetIndexingMode, HashAlgorithm, SaltStrategy } from \"../types.mjs\";\n\n// import { ENCRYPT_LOG_A_LOT } from '../constants.mjs';\n// const logalot = ENCRYPT_LOG_A_LOT || true;\n\n/**\n * Internal function that performs the encryption part of the overall `encrypt`\n * function when using the `multipass` option.\n *\n * @returns ciphertext string\n */\nexport async function encryptFromHex_blockMode({\n hexEncodedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n indexingMode,\n maxBlockSize,\n numOfPasses,\n}: {\n hexEncodedData: string,\n initialRecursions: number,\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n secret: string,\n hashAlgorithm: HashAlgorithm,\n encryptedDataDelimiter: string,\n indexingMode: AlphabetIndexingMode,\n maxBlockSize: number,\n numOfPasses: number,\n}): Promise<string> {\n const lc = `[${encryptFromHex_blockMode.name}]`;\n\n try {\n // set up \"prevHash\" as a starting point, similar to key-stretching\n let prevHash = await doInitialRecursions_keystretch({\n secret,\n initialRecursions,\n salt,\n saltStrategy: saltStrategy!,\n hashAlgorithm: hashAlgorithm!,\n });\n // console.warn(`${lc} first prevHash: ${prevHash}`);\n // if (logalot) { console.warn(`${lc} doInitialRecursions_keystretch result prevHash: ${prevHash} (W: 0a7979f8f0c6193e7a68d9573143e423)`); }\n\n /**\n * closure for avoiding checking `indexingMode` in a tight loop.\n *\n * usually I don't go for early optimization but this is low hanging\n * fruit in a very tight loop.\n */\n const getIndexOfCharInAlphabet: (alphabet: string, hexChar: string) => number =\n indexingMode === 'indexOf' ?\n (alphabet: string, hexChar: string) => { return alphabet.indexOf(hexChar) } :\n (alphabet: string, hexChar: string) => { return alphabet.lastIndexOf(hexChar) };\n // if (logalot) { console.warn(`${lc} using getIndexOfCharInAlphabet (indexingMode: ${indexingMode})`); }\n\n /**\n * ultimate indexes that will be stored in output.\n *\n * The index into this array corresponds to the index into\n * `hexEncodedData` array (`indexData`).\n */\n let encryptedDataIndexes: number[] = [];\n\n // set the initial pass length.\n let totalLength = hexEncodedData.length;\n let blockSize = maxBlockSize;\n if (blockSize > totalLength) { blockSize = totalLength; }\n // if (logalot) { console.warn(`${lc} totalLength (hexEncodedData.length): ${totalLength}, blockSize: ${blockSize} (W: 1529570c6b474ad1a24f3a4c5b7eceb0)`); }\n\n /**\n * We are doing multiple passes, but possibly only on subsets of\n * hexEncodedData. This variable is the number of sections that we're\n * doing. The final section may be less than a full pass section.\n *\n * _note: I am avoiding the use of \"block\" since that is an overloaded term in cryptography._\n */\n let blockSections = Math.ceil(totalLength / blockSize);\n // if (logalot) { console.warn(`${lc} blockSections: ${blockSections}`); }\n /**\n * the final pass may be less than the pass length.\n */\n // let finalBlockSize = (blockSize - ((blockSections * blockSize) - totalLength)) || blockSize; // if 0, then the last pass is full length\n let finalBlockSize = (totalLength % blockSize) || blockSize; // if 0, then the last pass is full length\n // if (logalot) { console.warn(`${lc} finalBlockSize: ${finalBlockSize}`); }\n /**\n * index into hexEncodedData at the start of each pass.\n *\n * This will be adjusted after each pass in the loop in preparation for\n * next iteration.\n */\n let indexHexEncodedDataAtStartOfPass = 0;\n\n // iterate through each pass \"section\" and create the alphabets for the\n // entire section. once the alphabets are created, iterate the plaintext\n // hexEncodedData and map them to the indices into those alphabets.\n // todo: add parameterized step to encode indices into characters?\n for (let indexOfBlock = 0; indexOfBlock < blockSections; indexOfBlock++) {\n\n // adjust the blockSize if it's the final one which might be shorter\n const isFinalBlock = indexOfBlock === blockSections - 1;\n if (isFinalBlock) { blockSize = finalBlockSize; }\n // if (logalot) { console.warn(`${lc} blockSize: ${blockSize}`); }\n\n const resGetAlphabets = await getAlphabetsThisBlock({\n blockSize,\n indexHexEncodedDataAtStartOfPass,\n numOfPasses,\n hexEncodedData,\n recursionsPerHash,\n salt,\n saltStrategy,\n prevHash,\n hashAlgorithm,\n });\n\n let alphabetsThisBlock = resGetAlphabets.alphabetsThisBlock;\n // if (logalot) { console.warn(`${lc} alphabetsThisBlock: ${pretty(alphabetsThisBlock)} (W: 8c37818b9658d4c6a418b62ec38bd923)`); }\n prevHash = resGetAlphabets.prevHash;\n // if (logalot) { console.warn(`${lc} prevHash after alphabets created: ${prevHash} (W: 0b2ffc3ba7a19ecba74fcec8788a6c23)`); }\n\n const encryptedIndexesThisBlock = await getEncryptedIndexesThisBlock({\n alphabetsThisBlock,\n blockSize,\n indexHexEncodedDataAtStartOfPass,\n hexEncodedData,\n getIndexOfCharInAlphabet,\n });\n\n // if (logalot) { console.warn(`${lc} encryptedIndexesThisBlock: ${encryptedIndexesThisBlock} (W: f84c9d05e4160241664051b946ad3f23)`); }\n\n // if (logalot) { console.warn(`${lc} info before add to encryptedDataIndexes info: ${pretty({ indexOfBlock, isFinalBlock, blockSize, prevHash, encryptedDataIndexes, encryptedIndexesThisBlock })}`); }\n encryptedDataIndexes = encryptedDataIndexes.concat(encryptedIndexesThisBlock);\n // if (logalot) { console.warn(`${lc} encryptedDataIndexes so far: ${encryptedDataIndexes} (W: 58f9bbabce8eeb90a213ab1fa0d88123)`); }\n\n indexHexEncodedDataAtStartOfPass += blockSize;\n }\n\n // we now have populated encryptedDataIndexes fully.\n const resEncryptedData = encryptedDataIndexes.join(encryptedDataDelimiter);\n // if (logalot) { console.warn(`${lc} final resEncryptedData: ${resEncryptedData} (W: 681bf4eccdf6cddf675ee608804a7e23)`); }\n // console.warn(`${lc} resEncryptedData: ${resEncryptedData}`);\n return resEncryptedData;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nasync function getAlphabetsThisBlock({\n blockSize,\n numOfPasses,\n indexHexEncodedDataAtStartOfPass,\n hexEncodedData,\n recursionsPerHash,\n salt,\n saltStrategy,\n prevHash,\n hashAlgorithm,\n}: {\n /** size of the pass, i.e. number of characters to process */\n blockSize: number,\n /** number of times to iterate over the pass section */\n numOfPasses: number,\n indexHexEncodedDataAtStartOfPass: number,\n hexEncodedData: string,\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n prevHash: string,\n hashAlgorithm: HashAlgorithm,\n}): Promise<{ alphabetsThisBlock: string[], prevHash: string }> {\n const lc = `[${getAlphabetsThisBlock.name}]`;\n try {\n // if (logalot) { console.warn(`${lc} info: ${pretty({ blockSize, numOfPasses, indexHexEncodedDataAtStartOfPass, prevHash })}`); }\n /**\n * one alphabet per plaintext character (hex only atow).\n *\n * index into this is index in this pass (`indexPass`).\n *\n * Instead of building each plaintext character's alphabet until at\n * least one instance of that character is found, we will build up\n * each of the alphabets for the entire pass. Then we will add on to\n * those alphabets, depending on if the character is found (and once\n * I implement it, additionalSuperfluousAlphabetExtensions).\n */\n let alphabetsThisBlock: string[] = [];\n /** index into the `hexEncodedData` that we're working with */\n let indexHexEncodedData: number;\n let hash: string;\n // first construct all alphabets for this pass section using the\n // given number of passes. Note that zero or more of these alphabets\n // may NOT include the hex character to encode, but this will be\n // addressed in the next step.\n for (let passNum = 0; passNum < numOfPasses; passNum++) {\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n indexHexEncodedData = indexHexEncodedDataAtStartOfPass + indexIntoBlock;\n // if (logalot) { console.warn(`${lc} passNum: ${passNum}, indexIntoBlock: ${indexIntoBlock} (W: 13d09af12647907d4497842616915223)`); }\n let alphabet = alphabetsThisBlock[indexIntoBlock] ?? '';\n\n // if (logalot) { console.warn(`${lc} starting alphabet: ${alphabet} (W: b5a3ba3203e679ac454a854c32846723)`); }\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash;\n prevHash = hash;\n // if (logalot) { console.warn(`${lc} extended alphabet: ${alphabet} (W: c0228b716a324761b581d38a805d192b)`); }\n\n alphabetsThisBlock[indexIntoBlock] = alphabet;\n // if (logalot) { console.warn(`${lc} alphabetsThisBlock: ${pretty(alphabetsThisBlock)} (W: 1bef26a111a4df4a6d501d5a662dd223)`); }\n }\n }\n // if (logalot) { console.warn(`${lc} initial alphabetsThisBlock (${alphabetsThisBlock.length}): ${pretty(alphabetsThisBlock)} (W: ce1f77a7065e45cfb12995f097f70af4)`); }\n\n // if (logalot) { console.warn(`${lc} at this point, each alphabet is the same size (numOfPasses * hash size), but it's not guaranteed that each alphabet will contain the plaintext character. so go through and extend any alphabets that do not yet contain the plaintext character (I: c75085603497ea684865010dfd8a3b23)`); }\n\n // at this point, each alphabet is the same size (numOfPasses * hash\n // size), but it's not guaranteed that each alphabet will contain the\n // plaintext character. so go through and extend any alphabets that do\n // not yet contain the plaintext character\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n indexHexEncodedData = indexHexEncodedDataAtStartOfPass + indexIntoBlock;\n const hexCharFromData: string = hexEncodedData[indexHexEncodedData];\n let alphabet = alphabetsThisBlock[indexIntoBlock];\n\n while (!alphabet.includes(hexCharFromData)) {\n // if (logalot) { console.warn(`${lc} alphabet (${alphabet}) has to be extended because it does not contain hexChar (${hexCharFromData}). (W: a8040eb78f4d123cfa423de33a7f3b23)`); }\n // only executes if alphabet doesnt already contain hexChar\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash!;\n prevHash = hash;\n }\n\n alphabetsThisBlock[indexIntoBlock] = alphabet;\n // if (logalot) { console.warn(`${lc} alphabetsThisBlock (length ${alphabetsThisBlock.length}): ${pretty(alphabetsThisBlock)} (W: a86e76aa398d7e4b44dbe0fbb79c1623)`); }\n }\n // if (logalot) { console.warn(`${lc} guaranteed alphabetsThisBlock (${alphabetsThisBlock.length}): ${pretty(alphabetsThisBlock)} (W: 8d684c05b116467aa92e946b03160310)`); }\n\n // if (logalot) { console.warn(`${lc} at this point, each alphabet is at least the minimum size and is guaranteed to have at least once instance of the plaintext hexChar. (W: c6f31445402b1c561670a2dd59530523)`); }\n // at this point, each alphabet is at least the minimum size and is\n // guaranteed to have at least once instance of the plaintext hexChar.\n // if (logalot) { console.warn(`${lc} return prevHash: ${prevHash}`) }\n return { alphabetsThisBlock, prevHash };\n } catch (error) {\n console.error(`${lc} error: ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nasync function getEncryptedIndexesThisBlock({\n alphabetsThisBlock,\n blockSize,\n indexHexEncodedDataAtStartOfPass,\n hexEncodedData,\n getIndexOfCharInAlphabet,\n}: {\n alphabetsThisBlock: string[],\n blockSize: number,\n indexHexEncodedDataAtStartOfPass: number,\n hexEncodedData: string,\n getIndexOfCharInAlphabet: (alphabet: string, hexChar: string) => number,\n}): Promise<number[]> {\n const lc = `[${getEncryptedIndexesThisBlock.name}]`;\n try {\n const resIndexes: number[] = [];\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n const indexHexEncodedData = indexHexEncodedDataAtStartOfPass + indexIntoBlock;\n const alphabet = alphabetsThisBlock[indexIntoBlock];\n const encryptedIndexIntoAlphabet = getIndexOfCharInAlphabet(alphabet, hexEncodedData[indexHexEncodedData]);\n resIndexes.push(encryptedIndexIntoAlphabet);\n }\n\n return resIndexes;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { doInitialRecursions_keystretch, execRound_getNextHash, getPreHash } from \"../common/encrypt-decrypt-common.mjs\";\nimport { AlphabetIndexingMode, HashAlgorithm, SaltStrategy } from \"../types.mjs\";\n\n/**\n * Internal function that takes a given encryptedData, in the form of a\n * delimited string of indexes, and decrypts it back into encoded hex (not the\n * original unencrypted data!).\n *\n * It does this by reconstructing the JIT alphabets for each section, just as\n * was done in the encrypting process. It then uses the encrypted indexes into\n * these alphabets and rebuilds the multipass section's plaintext **hex**.\n *\n * For documentation on args, see `DecryptArgs`.\n *\n * @returns unencrypted, but still hex-encoded plaintext string\n */\nexport async function decryptToHex_blockMode({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n maxBlockSize,\n numOfPasses,\n}: {\n encryptedData: string,\n initialRecursions: number,\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n secret: string,\n hashAlgorithm: HashAlgorithm,\n encryptedDataDelimiter: string,\n maxBlockSize: number,\n numOfPasses: number,\n}): Promise<string> {\n const lc = `[${decryptToHex_blockMode.name}]`;\n\n try {\n // set up \"prevHash\" as a starting point, similar to key-stretching\n let prevHash = await doInitialRecursions_keystretch({\n secret,\n initialRecursions,\n salt,\n saltStrategy: saltStrategy!,\n hashAlgorithm: hashAlgorithm!,\n });\n\n // we have our prevHash starting point, so now we can iterate through the data\n let encryptedDataIndexes: number[] =\n encryptedData.split(encryptedDataDelimiter).map((nString: string) => parseInt(nString));\n let decryptedDataArray: string[] = [];\n\n // re-play multipass building of alphabets. Section by section, first\n // create the minimum number of alphabets. Then iterate through each\n // cipher index, extending individual alphabets JIT/on demand depending\n // on the cipher index, i.e., if the index is larger than the existing\n // alphabet, then we extend it another round.\n\n // set the initial pass length.\n let totalLength = encryptedDataIndexes.length;\n let blockSize = maxBlockSize;\n if (blockSize > totalLength) { blockSize = totalLength; }\n\n /**\n * We are doing multiple passes, but possibly only on subsets of\n * encryptedDataIndexes. This variable is the number of sections that we're\n * doing. The final section may be less than a full pass section.\n *\n * _note: I am avoiding the use of \"block\" since that is an overloaded term in cryptography and is usually related to padding._\n */\n let blockSections = Math.ceil(totalLength / blockSize);\n /**\n * the final pass may be less than the pass length.\n */\n let finalBlockSize = (totalLength % blockSize) || blockSize; // if 0, then the last pass is full length\n /**\n * index into encryptedDataIndexes at the start of each pass.\n *\n * This will be adjusted after each pass in the loop in preparation for\n * next iteration.\n */\n let indexEncryptedDataIndexesAtStartOfPass = 0;\n\n // iterate through each pass \"section\" and create the alphabets for the\n // entire section. once the alphabets are created, iterate the plaintext\n // hexEncodedData and map them to the indices into those alphabets.\n // todo: add parameterized step to encode indices into characters?\n for (let indexOfBlock = 0; indexOfBlock < blockSections; indexOfBlock++) {\n\n // adjust the blockSize if it's the final one which might be shorter\n const isFinalBlock = indexOfBlock === blockSections - 1;\n if (isFinalBlock) { blockSize = finalBlockSize; }\n\n const resGetAlphabets = await getAlphabetsThisBlock({\n blockSize,\n indexEncryptedDataIndexesAtStartOfPass,\n numOfPasses,\n encryptedDataIndexes,\n recursionsPerHash,\n salt,\n saltStrategy,\n prevHash,\n hashAlgorithm,\n });\n\n let alphabetsThisBlock = resGetAlphabets.alphabetsThisBlock;\n prevHash = resGetAlphabets.prevHash; // used in next section if there is one\n\n const decryptedDataArrayThisBlock = await getDecryptedDataArrayThisBlock({\n alphabetsThisBlock,\n blockSize,\n indexEncryptedDataIndexesAtStartOfPass,\n encryptedDataIndexes,\n });\n\n decryptedDataArray = decryptedDataArray.concat(decryptedDataArrayThisBlock);\n\n indexEncryptedDataIndexesAtStartOfPass += blockSize;\n }\n\n // reconstitute the decryptedHex\n const decryptedHex: string = decryptedDataArray.join('');\n return decryptedHex;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * internal function that builds the JIT alphabets for a given multipass\n * section.\n *\n * @returns alphabetsThisBlock array of alphabets and the final `prevHash` for use in the next multipass section (if any).\n */\nasync function getAlphabetsThisBlock({\n blockSize,\n numOfPasses,\n indexEncryptedDataIndexesAtStartOfPass,\n encryptedDataIndexes,\n recursionsPerHash,\n salt,\n saltStrategy,\n prevHash,\n hashAlgorithm,\n}: {\n /**\n * Size of the multipass section, i.e. number of characters to\n * encrypt/decrypt as a whole.\n */\n blockSize: number,\n /**\n * Number of times to iterate over the multipass section\n */\n numOfPasses: number,\n indexEncryptedDataIndexesAtStartOfPass: number,\n encryptedDataIndexes: number[],\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n prevHash: string,\n hashAlgorithm: HashAlgorithm,\n}): Promise<{ alphabetsThisBlock: string[], prevHash: string }> {\n const lc = `[${getAlphabetsThisBlock.name}]`;\n try {\n /**\n * one alphabet per plaintext character (hex only atow).\n *\n * index into this is index in this pass (`indexPass`).\n *\n * Instead of building each plaintext character's alphabet until at\n * least one instance of that character is found, we will build up\n * each of the alphabets for the entire pass. Then we will add on to\n * those alphabets, depending on if the character is found (and once\n * I implement it, additionalSuperfluousAlphabetExtensions).\n */\n let alphabetsThisBlock: string[] = [];\n /** index into the `encryptedDataIndexes` that we're working with */\n let indexEncryptedDataIndexes: number;\n let hash: string;\n // first construct all alphabets for this pass section using the\n // given number of passes. Note that zero or more of these alphabets\n // may NOT include the hex character to encode, but this will be\n // addressed in the next step.\n for (let passNum = 0; passNum < numOfPasses; passNum++) {\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n indexEncryptedDataIndexes = indexEncryptedDataIndexesAtStartOfPass + indexIntoBlock;\n let alphabet = alphabetsThisBlock[indexIntoBlock] ?? '';\n\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash;\n prevHash = hash;\n\n alphabetsThisBlock[indexIntoBlock] = alphabet;\n }\n }\n\n // at this point, each alphabet is the same size (numOfPasses * hash\n // size), but it's not guaranteed that each alphabet will contain the\n // plaintext character. so go through and extend any alphabets that do\n // not yet contain the plaintext character\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n indexEncryptedDataIndexes = indexEncryptedDataIndexesAtStartOfPass + indexIntoBlock;\n const encryptedIndex: number = encryptedDataIndexes[indexEncryptedDataIndexes];\n let alphabet = alphabetsThisBlock[indexIntoBlock];\n\n // while (!alphabet.includes(hexCharFromData)) {\n while (alphabet.at(encryptedIndex) === undefined) {\n // only executes if alphabet isn't long enough for index\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash;\n prevHash = hash;\n }\n\n alphabetsThisBlock[indexIntoBlock] = alphabet;\n }\n\n // at this point, each alphabet is at least the minimum size and is\n // guaranteed to have at least once instance of the plaintext hexChar.\n return { alphabetsThisBlock, prevHash };\n } catch (error) {\n console.error(`${lc} error: ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Takes the incoming encrypted indexes for a multipass section and maps them to\n * plaintext.\n *\n * @param args see individual param docs\n * @returns plaintext as an array of strings\n */\nasync function getDecryptedDataArrayThisBlock({\n alphabetsThisBlock,\n blockSize,\n indexEncryptedDataIndexesAtStartOfPass,\n encryptedDataIndexes,\n}: {\n /**\n * All alphabets for this multipass section that we have already created in\n * a previous step.\n */\n alphabetsThisBlock: string[],\n /**\n * Size of the multipass section that we are processing as a whole.\n */\n blockSize: number,\n /**\n * Start of the multipass section, used to index into {@link encryptedDataIndexes}.\n */\n indexEncryptedDataIndexesAtStartOfPass: number,\n /**\n * Reference to the entire encrypted data array.\n *\n * We will index into this array and get the \"encrypted data index\" which is\n * the index into the alphabet for that encrypted character.\n */\n encryptedDataIndexes: number[],\n}): Promise<string[]> {\n const lc = `[${getDecryptedDataArrayThisBlock.name}]`;\n try {\n const resDataArray: string[] = [];\n\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n let indexEncryptedDataIndexes = indexEncryptedDataIndexesAtStartOfPass + indexIntoBlock;\n const encryptedIndex: number = encryptedDataIndexes[indexEncryptedDataIndexes];\n let alphabet = alphabetsThisBlock[indexIntoBlock];\n let decryptedCharString = alphabet[encryptedIndex];\n resDataArray.push(decryptedCharString);\n }\n\n return resDataArray;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport * as c from '../constants.mjs';\nimport { decodeHexStringToString } from '../helper.mjs';\nimport { ALPHABET_INDEXING_MODES, DecryptArgs, DecryptResult, HashAlgorithm, SALT_STRATEGIES } from \"../types.mjs\";\nimport { decryptToHex_blockMode } from './decrypt-to-hex-block-mode.mjs';\n\n/**\n * Does the actual decryption work using shortCircuit mitigation strategies.\n *\n// * {@link decrypt}\n * {@link DecryptArgs}\n * {@link DecryptResult}\n *\n * @returns a `DecryptResult` info object\n */\nexport async function decryptImpl_blockMode(args: DecryptArgs): Promise<DecryptResult> {\n const lc = `[${decryptImpl_blockMode.name}]`;\n let {\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n indexingMode,\n blockMode,\n multipass,\n } = args;\n\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (blockMode && multipass) { throw new Error(`blockMode and multipass set. blockMode was a refactored name of multipass, so these should not both be present. multipass is deprecated. (E: b9b3cd1f701c700835c0419260278223)`); }\n if (!blockMode && !!multipass) {\n console.warn(`${lc}[WARNING] \"multipass\" option is deprecated. this has been refactored to \"blockMode\". This will use multipass as blockMode. (W: b77c9773e30549cbb389ce61f31eb6d3)`);\n blockMode = multipass; // to support older versions that use refactored \"multipass\"\n }\n if (!blockMode) { throw new Error(`(UNEXPECTED) blockMode required. This should be truthy in order to get to this impl fn. (E: 306bce36afd64b7182ca2b46ac04a261)`); }\n\n // #region set args defaults\n\n initialRecursions = initialRecursions || c.DEFAULT_INITIAL_RECURSIONS;\n recursionsPerHash = recursionsPerHash || c.DEFAULT_RECURSIONS_PER_HASH;\n saltStrategy = saltStrategy || c.DEFAULT_SALT_STRATEGY;\n hashAlgorithm = hashAlgorithm || c.DEFAULT_HASH_ALGORITHM;\n salt = salt || await getUUID(c.DEFAULT_GETUUID_SEEDSIZE);\n encryptedDataDelimiter = encryptedDataDelimiter || c.DEFAULT_ENCRYPTED_DATA_DELIMITER;\n\n indexingMode = indexingMode || c.DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE;\n\n let { maxBlockSize, maxPassSectionLength, numOfPasses } = blockMode;\n if (!maxBlockSize && !!maxPassSectionLength) {\n console.warn(`${lc}[WARNING] \"maxPassSectionLength\" option is deprecated. this has been refactored to \"maxBlockSize\". This will use maxPassSectioLength as maxBlockSize. (W: e2c83d78a3464704a6067e0f767f20b0)`);\n maxBlockSize = maxPassSectionLength;\n }\n maxBlockSize = maxBlockSize || c.DEFAULT_MAX_BLOCK_SIZE;\n numOfPasses = numOfPasses || c.DEFAULT_NUM_OF_PASSES;\n\n // #endregion\n\n // #region args validation\n\n const lcv = `[validation]`;\n\n if (!initialRecursions || initialRecursions < 1) { const e = `${lcv} initialRecursions required, and greater than 0`; console.error(e); errors.push(e); }\n if (!recursionsPerHash || recursionsPerHash < 1) { const e = `${lcv} recursionsPerHash required, and greater than 0`; console.error(e); errors.push(e); }\n if (!encryptedData) { const e = `${lcv} encryptedData required`; console.error(e); errors.push(e); }\n if (!salt) { const e = `${lcv} salt required`; console.error(e); errors.push(e); }\n if (!saltStrategy) { const e = `${lcv} saltStrategy required`; console.error(e); errors.push(e); }\n if (!secret) { const e = `${lcv} secret required`; console.error(e); errors.push(e); }\n if (!encryptedDataDelimiter) { const e = `${lcv} encryptedDataDelimiter required`; console.error(e); errors.push(e); }\n if (!indexingMode) { const e = `${lcv} indexingMode required (E: a6fe15f8ba414e21b5355d23e808b976)`; console.error(e); errors.push(e); }\n if (!ALPHABET_INDEXING_MODES.includes(indexingMode)) { const e = `${lcv} invalid indexingMode (${indexingMode}). Must be one of ${ALPHABET_INDEXING_MODES} (E: 17435268651444e0b7a594135635fc58)`; console.error(e); errors.push(e); }\n if (maxBlockSize < 1) { const e = `${lcv} maxBlockSize must be greater than 0 (E: 0870831aa86b4bfa939aeee9f252326a)`; console.error(e); errors.push(e); }\n if (numOfPasses < 1) { const e = `${lcv} numOfPasses must be greater than 0 (E: 691d3c3765584c6f8c9aba1ee378df00)`; console.error(e); errors.push(e); }\n\n // if (hashAlgorithm !== 'SHA-256') { const e = `${lcv} only SHA-256 implemented`; console.error(e); errors.push(e); }\n if (!Object.values(HashAlgorithm).includes(hashAlgorithm)) {\n const e = `${lcv} only ${Object.values(HashAlgorithm)} hash algorithms implemented`; console.error(e); errors.push(e);\n }\n\n if (saltStrategy && !SALT_STRATEGIES.includes(saltStrategy!)) {\n const e = `${lcv} unknown saltStrategy: ${saltStrategy}`; console.error(e); errors.push(e);\n }\n\n if (errors.length > 0) {\n let result = { ...args, errors: errors };\n delete (result as any).encryptedData;\n delete (result as any).secret;\n return result;\n }\n\n // #endregion args validation\n\n // decrypt from indices into hex\n let hexEncodedData: string = await decryptToHex_blockMode({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n maxBlockSize,\n numOfPasses,\n });\n\n // decode hex back into original data\n const decryptedData: string = await decodeHexStringToString(hexEncodedData);\n\n const result: DecryptResult = {\n ...args,\n decryptedData,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n delete (result as any).encryptedData;\n delete (result as any).secret;\n return result;\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { decodeHexStringToString, encodeStringToHexString } from '../helper.mjs';\nimport { ALPHABET_INDEXING_MODES, EncryptArgs, EncryptResult, HashAlgorithm, SALT_STRATEGIES } from \"../types.mjs\";\nimport { encryptFromHex_blockMode } from './encrypt-from-hex-block-mode.mjs';\nimport { decryptImpl_blockMode } from './decrypt-block-mode.mjs';\nimport {\n DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE,\n DEFAULT_ENCRYPTED_DATA_DELIMITER, DEFAULT_INITIAL_RECURSIONS,\n DEFAULT_MAX_BLOCK_SIZE, DEFAULT_NUM_OF_PASSES,\n ENCRYPT_LOG_A_LOT\n} from '../constants.mjs';\n\n// const logalot = ENCRYPT_LOG_A_LOT || true;\n\n/**\n * Does the actual encryption work using the original \"stream\" streaming\n * encryption.\n *\n * {@link encrypt}\n * {@link EncryptArgs}\n * {@link EncryptResult}\n *\n * @returns a `EncryptResult` info object\n */\nexport async function encryptImpl_blockMode(args: EncryptArgs): Promise<EncryptResult> {\n const lc = `[${encryptImpl_blockMode.name}]`;\n\n let {\n dataToEncrypt,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n confirm,\n indexingMode,\n blockMode,\n multipass,\n } = args;\n\n const errors: string[] = [];\n let warnings: string[] = [];\n\n if (blockMode && multipass) { throw new Error(`blockMode and multipass set. blockMode was a refactored name of multipass, so these should not both be present. multipass is deprecated. (E: bde5efd1a3e449dca549c5bff147f09b)`); }\n if (!blockMode && !!multipass) {\n console.warn(`${lc}[WARNING] \"multipass\" option is deprecated. this has been refactored to \"blockMode\". This will use multipass as blockMode. (W: 046b55a6d1304155b2e5352a9e6140b0)`);\n blockMode = multipass; // to support older versions that use refactored \"multipass\"\n }\n if (!blockMode) { throw new Error(`(UNEXPECTED) blockMode required. This should be truthy in order to get to this impl fn. (E: 0b87871f81d849ef8f0263b7775bd3e3)`); }\n\n // #region set args defaults\n\n if (!initialRecursions) {\n console.warn(`${lc} initial recursions required. defaulting to ${DEFAULT_INITIAL_RECURSIONS}`);\n initialRecursions = DEFAULT_INITIAL_RECURSIONS;\n }\n encryptedDataDelimiter = encryptedDataDelimiter || DEFAULT_ENCRYPTED_DATA_DELIMITER;\n indexingMode = indexingMode || DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE;\n\n // let { maxPassSectionLength, numOfPasses } = blockMode;\n // maxPassSectionLength = maxPassSectionLength || DEFAULT_MAX_BLOCK_SIZE;\n // numOfPasses = numOfPasses || DEFAULT_NUM_OF_PASSES;\n let { maxBlockSize, maxPassSectionLength, numOfPasses } = blockMode;\n if (!maxBlockSize && !!maxPassSectionLength) {\n console.warn(`${lc}[WARNING] \"maxPassSectionLength\" option is deprecated. this has been refactored to \"maxBlockSize\". This will use maxPassSectioLength as maxBlockSize. (W: c28fe476105643e184d0ddd5d2aa8a5d)`);\n maxBlockSize = maxPassSectionLength;\n }\n maxBlockSize = maxBlockSize || DEFAULT_MAX_BLOCK_SIZE;\n numOfPasses = numOfPasses || DEFAULT_NUM_OF_PASSES;\n\n // #endregion set args defaults\n\n // #region args validation\n\n const lcv = `[validation]`;\n\n if (!initialRecursions || initialRecursions < 1) { const e = `${lcv} initialRecursions required, and greater than 0 (E: dd96a75f0c504f34b1f9f2f32e011c50)`; console.error(e); errors.push(e); }\n if (!recursionsPerHash || recursionsPerHash < 1) { const e = `${lcv} recursionsPerHash required, and greater than 0 (E: 64cf53e0bf9f4963be6b165ca4e6566d)`; console.error(e); errors.push(e); }\n if (!salt) { const e = `${lcv} salt required (E: 136a5d237e0f4b1d89f8c87ac12a1507)`; console.error(e); errors.push(e); }\n if (!saltStrategy) { const e = `${lcv} saltStrategy required (E: 457ed117bf224b9f86fe81ab6bc35381)`; console.error(e); errors.push(e); }\n if (!secret) { const e = `${lcv} secret required (E: 5c363255055a45cfb07656e2f4854ed7)`; console.error(e); errors.push(e); }\n if (!encryptedDataDelimiter) { const e = `${lcv} encryptedDataDelimiter required (E: 1bbeb4dce19e4ac2bbe7d1e373739298)`; console.error(e); errors.push(e); }\n if (!indexingMode) { const e = `${lcv} indexingMode required (E: 693ebd2be64a438aa3b075d0cb0d92bf)`; console.error(e); errors.push(e); }\n if (!ALPHABET_INDEXING_MODES.includes(indexingMode)) { const e = `${lcv} invalid indexingMode (${indexingMode}). Must be one of ${ALPHABET_INDEXING_MODES} (E: 17435268651444e0b7a594135635fc58)`; console.error(e); errors.push(e); }\n if (maxBlockSize < 1) { const e = `${lcv} maxBlockSize must be greater than 0 (E: 9f268207ae274b958fb91855331be259)`; console.error(e); errors.push(e); }\n if (numOfPasses < 1) { const e = `${lcv} numOfPasses must be greater than 0 (E: c3bcab79bb024d65b84947806290a7d4)`; console.error(e); errors.push(e); }\n\n // if (hashAlgorithm !== 'SHA-256') { const e = `${lcv} only SHA-256 implemented`; console.error(e); errors.push(e); }\n if (!Object.values(HashAlgorithm).includes(hashAlgorithm!)) {\n const e = `${lcv} only ${Object.values(HashAlgorithm)} hash algorithms implemented`; console.error(e); errors.push(e);\n }\n\n if (saltStrategy && !SALT_STRATEGIES.includes(saltStrategy!)) {\n const e = `${lcv} unknown saltStrategy: ${saltStrategy}`; console.error(e); errors.push(e);\n }\n\n if (errors.length > 0) {\n let result = { ...args, errors: errors };\n delete (result as any).dataToEncrypt;\n delete (result as any).secret;\n return result;\n }\n\n // #endregion args validation\n\n // #region encode data to just hex (i.e. only have 0-9, a-f)\n\n // console.log(`${lc} hex encoding dataToEncrypt: ${dataToEncrypt}`);\n const hexEncodedData: string = await encodeStringToHexString(dataToEncrypt);\n if (confirm) {\n // confirm data can be converted back into the original data\n // console.log(`${lc} hex decoding back to check with dataToEncrypt: ${hexEncodedData}`);\n // if (logalot) { console.log(`${lc} hexEncodedData: ${hexEncodedData} (I: 5568ee9bad6bfaa6f266bc9c5b5fc423)`); }\n const confirmDecodedData = await decodeHexStringToString(hexEncodedData);\n // console.log(`${lc} checkDecodedData: ${confirmDecodedData}`);\n if (confirmDecodedData !== dataToEncrypt) {\n throw new Error(`decoding encoded hex failed for this data: The encoded hex did not reverse to the original data.`);\n }\n }\n\n // #endregion encode data to just hex (i.e. only have 0-9, a-f)\n\n // #region encrypt hex\n\n // comma-delimited indexes string\n const encryptedData: string = await encryptFromHex_blockMode({\n hexEncodedData,\n initialRecursions,\n recursionsPerHash: recursionsPerHash!,\n salt,\n saltStrategy: saltStrategy!,\n secret,\n hashAlgorithm: hashAlgorithm!,\n encryptedDataDelimiter,\n indexingMode,\n maxBlockSize,\n numOfPasses,\n });\n\n // DO NOT LEAVE THIS IN PROD!!!\n // console.warn(`${lc} TAKE THIS OUT!! encryptedData: ${encryptedData}`); // DO NOT LEAVE THIS IN PROD!!!\n // DO NOT LEAVE THIS IN PROD!!!\n\n if (confirm) {\n try {\n const resDecrypt = await decryptImpl_blockMode({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n indexingMode,\n blockMode,\n });\n if (!resDecrypt.decryptedData) {\n throw new Error(`Confirm check call to decrypt produced falsy decryptedData (E: a4fe82dee61f497e9dea188ea9c287a4)`);\n } else if (resDecrypt.decryptedData !== dataToEncrypt) {\n // DO NOT LEAVE THIS IN PROD!!!\n // console.warn(`resDecrypt.decryptedData: ${resDecrypt.decryptedData}`); // DO NOT LEAVE THIS IN PROD!!!\n // console.warn(`dataToEncrypt: ${dataToEncrypt}`); // DO NOT LEAVE THIS IN PROD!!!\n // DO NOT LEAVE THIS IN PROD!!!\n throw new Error(`The ENCRYPTED data did not decrypt back to the original data. (E: 16b5f1a11e4f438ab38a7f124178a7b8)`);\n // } else {\n // console.log(`${lc} decrypt confirmed.`);\n }\n if ((resDecrypt.warnings || []).length > 0) {\n warnings = warnings.concat([`Confirm check call to decrypt had warnings.`, ...resDecrypt.warnings!])\n }\n } catch (error) {\n throw new Error(`${lc} confirm failed. decrypt error: ${extractErrorMsg(error)} (E: 782a84d9dc294ce9a6a325e3ab293adf)`);\n }\n }\n\n // #endregion\n\n const result: EncryptResult = {\n ...args,\n encryptedData,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n delete (result as any).dataToEncrypt;\n delete (result as any).secret;\n return result;\n}\n", "import { getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport * as c from './constants.mjs';\nimport {\n EncryptArgs, EncryptResult,\n DecryptArgs, DecryptResult,\n} from './types.mjs';\nimport { encryptImpl_stream } from './stream-mode/encrypt-stream-mode.mjs'\nimport { encryptImpl_blockMode } from './block-mode/encrypt-block-mode.mjs';\nimport { decryptImpl_stream } from './stream-mode/decrypt-stream-mode.mjs';\nimport { decryptImpl_blockMode } from './block-mode/decrypt-block-mode.mjs';\n\n/**\n * Encrypts given `dataToEncrypt` using the secret and other\n * given algorithm parameters.\n *\n * NOTE: These parameters must be the same when the call to `decrypt` happens!\n *\n * @see {@link DecryptArgs}\n * @see {@link DecryptResult}\n *\n * @returns `EncryptResult` info object with either `dataToEncrypt` or a populated `errors` array.\n */\nexport async function encrypt(args: EncryptArgs): Promise<EncryptResult> {\n const lc = `[${encrypt.name}]`;\n try {\n // initial common validation\n if (!args) { throw new Error('args required (E: 22e58e03c78f4c27bf18295b8d2cdd3a)'); }\n if (!args.dataToEncrypt) { throw new Error(`dataToEncrypt required (E: 168c9076e5434c83ba81e3485ee6f3e4)`); }\n\n // common defaults\n args.salt = args.salt || await getUUID(c.DEFAULT_GETUUID_SEEDSIZE);\n args.saltStrategy = args.saltStrategy || c.DEFAULT_SALT_STRATEGY;\n args.hashAlgorithm = args.hashAlgorithm || c.DEFAULT_HASH_ALGORITHM;\n args.recursionsPerHash = args.recursionsPerHash || c.DEFAULT_RECURSIONS_PER_HASH;\n\n // route to appropriate implementor\n let result: EncryptResult;\n if (args.blockMode) {\n result = await encryptImpl_blockMode(args);\n } else {\n result = await encryptImpl_stream(args);\n }\n\n // print out warnings/errors if necessary\n if ((result.errors ?? []).length > 0) { result.errors!.forEach(e => console.warn(`${lc} ${e}`)); }\n if ((result.warnings ?? []).length > 0) { result.warnings!.forEach(w => console.warn(`${lc} ${w}`)); }\n\n // we're done\n return result;\n } catch (error) {\n console.error(`${lc}${error.message}`);\n throw error;\n // const result = { ...args, errors: [error] };\n // delete (result as any).dataToEncrypt;\n // delete (result as any).secret;\n // return result;\n }\n}\n\n/**\n * Decrypts given `encryptedData` using the secret and other\n * given algorithm parameters.\n *\n * NOTE: These parameters must be the same as what the `encrypt` call used!\n *\n * @see {@link DecryptArgs}\n * @see {@link DecryptResult}\n *\n * @returns `DecryptResult` info object with either `decryptedData` or a populated `errors` array.\n */\nexport async function decrypt(args: DecryptArgs): Promise<DecryptResult> {\n const lc = `[${decrypt.name}]`;\n try {\n // initial common validation\n if (!args) { throw new Error('args required (E: fcd9b4aad85c4deba5fe5fde0b9ecb30)'); }\n if (!args.encryptedData) { throw new Error(`encryptedData required (E: f879f612428b4283bae089acee929a58)`); }\n\n // common defaults\n args.salt = args.salt || await getUUID(c.DEFAULT_GETUUID_SEEDSIZE);\n args.saltStrategy = args.saltStrategy || c.DEFAULT_SALT_STRATEGY;\n args.hashAlgorithm = args.hashAlgorithm || c.DEFAULT_HASH_ALGORITHM;\n args.recursionsPerHash = args.recursionsPerHash || c.DEFAULT_RECURSIONS_PER_HASH;\n\n // route to appropriate implementor\n let result: DecryptResult;\n if (args.blockMode || args.multipass) {\n result = await decryptImpl_blockMode(args);\n } else {\n result = await decryptImpl_stream(args);\n }\n\n // print out warnings/errors if necessary\n if ((result.warnings ?? []).length > 0) { result.warnings!.forEach(w => console.warn(`${lc} ${w}`)); }\n if ((result.errors ?? []).length > 0) { result.errors!.forEach(e => console.warn(`${lc} ${e}`)); }\n\n // we're done\n return result;\n // console.log(`${lc} encryptedDataDelimiter: ${encryptedDataDelimiter}`);\n } catch (error) {\n console.error(`${lc}${error.message}`);\n throw error;\n // const result = { ...args, errors: [error] };\n // delete (result as any).encryptedData;\n // delete (result as any).secret;\n // return result;\n }\n}\n", "import { SaltStrategy } from '@ibgib/encrypt-gib/dist/index.mjs';\n\nexport const DEFAULT_ENCRYPTION_INITIAL_RECURSIONS = 50000;\nexport const MIN_ENCRYPTION_INITIAL_RECURSIONS = 1000;\nexport const MAX_ENCRYPTION_INITIAL_RECURSIONS = 10000000;\nexport const MIN_ENCRYPTION_RECURSIONS_PER_HASH = 1;\nexport const MAX_ENCRYPTION_RECURSIONS_PER_HASH = 1000;\nexport const MIN_ENCRYPTION_SALT_LENGTH = 50;\nexport const MAX_ENCRYPTION_SALT_LENGTH = 99999;\nexport const MIN_ENCRYPTION_PASSWORD_LENGTH = 8;\nexport const MAX_ENCRYPTION_PASSWORD_LENGTH = 9999999;\nexport const DEFAULT_ENCRYPTION_SALT_STRATEGY: SaltStrategy = SaltStrategy.appendPerHash;\nexport const DEFAULT_ENCRYPTION_RECURSIONS_PER_HASH = 10;\nexport const DEFAULT_ENCRYPTION_HASH_ALGORITHM = 'SHA-256';\n\n/**\n * atom at the start of encryption ibgibs' `ib`.\n */\nexport const ENCRYPTION_ATOM = 'encryption';\n\n/**\n * default regexp for a simple name string.\n */\nexport const ENCRYPTION_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,255}$/;\n\n/**\n * An encryptions ibgib uses this rel8n name for its children encryptions.\n */\nexport const ENCRYPTION_REL8N_NAME = 'encryption';\n\n/**\n * atom for ciphertext...hmm\n */\nexport const CIPHERTEXT_ATOM = 'ciphertext';\n/**\n * Related encrypted ciphertext ibgibs will use this rel8n name.\n * Those ciphertext ibgibs will then relate to the encryption used.\n */\nexport const CIPHERTEXT_REL8N_NAME = 'ciphertext';\n", "import { IbGibRel8ns_V1, IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { IbGibAddr, IbGib, IbGibRel8ns, TjpIbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\n\nimport {\n Witness,\n WitnessData_V1, WitnessResultData, WitnessResultIbGib, WitnessResultRel8ns,\n} from '../witness-types.mjs';\nimport { IbGibSpaceAny } from './space-base-v1.mjs';\nimport { ENCRYPTION_REL8N_NAME } from '../../common/encrypt/encrypt-constants.mjs';\nimport { WitnessCmdData, WitnessCmdIbGib, WitnessCmdRel8ns, } from '../witness-cmd/witness-cmd-types.mjs';\n\n/**\n * Marker type to show intent that it should be the spaceId, i.e.\n * space.data.uuid.\n */\nexport type SpaceId = string;\n\nexport type SpaceLocation = \"local\" | \"sync\";\nexport const SpaceLocation = {\n /**\n * space is a local space, with lower latency and direct usage with\n * metaspace. To be used as the primary local user space.\n *\n * no real proxy is involved, rather, we should be speaking \"directly\" with\n * the local location.\n */\n local: 'local' as SpaceLocation,\n /**\n * space is an outerspace, with higher latency, probably some kind of proxy\n * client access. More intended to be used with syncing...\n */\n outerspace: 'outerspace' as SpaceLocation,\n /**\n * in-memory-only space.\n *\n * Note: I haven't really incorporated this, but I have sketched an\n * in-memory innerspace and in the future, I think this will be heavily\n * utilized.\n */\n innerspace: 'innerspace' as SpaceLocation,\n}\nexport const VALID_SPACE_LOCATIONS = Object.values(SpaceLocation).concat();\n\nexport type SpaceType = \"user\" | \"sync\";\nexport const SpaceType = {\n /**\n * user space that usually (always?) acts locally as the main type of\n * storage for a user.\n *\n * This means that the user is actively working in this space, and it isn't\n * a derivative space. perhaps \"source\" would be better?\n */\n user: 'user' as SpaceType,\n /**\n * this is a derivative user space that is used to synchronize ibgib\n * timelines among two or more other spaces.\n */\n sync: 'sync' as SpaceType,\n}\n/**\n * Object.values(SpaceType).concat()\n *\n * for now, you can add valid space types here in initialization code to\n * manually extend this.\n */\nexport const VALID_SPACE_TYPES = Object.values(SpaceType).concat();\n\nexport type UserSpaceSubtype = 'node-filesystem';\n/**\n * specific/concrete subtype implementations\n */\nexport const UserSpaceSubtype = {\n /**\n * local user space is driven by a node filesystem concrete implementation.\n *\n * Note: This is actually implemented elsewhere, but I am deferring the\n * additional architectural requirements for putting the node filesystem and\n * extending this to include it. so I'm just putting this here. But in the\n * future, this should be moved to a node-specific library and brought in if\n * the app requires it.\n */\n node_filesystem: 'node-filesystem' as UserSpaceSubtype,\n}\nexport type SyncSpaceSubtype = 'aws-dynamodb';\nexport const SyncSpaceSubtype = {\n aws_dynamodb: 'aws-dynamodb' as SyncSpaceSubtype,\n}\n\nexport type SpaceSubtype = UserSpaceSubtype | SyncSpaceSubtype; // extend with logical OR types here\n/**\n * specific, concrete implementation of space\n */\nexport const SpaceSubtype = {\n ...UserSpaceSubtype,\n ...SyncSpaceSubtype,\n}\n/**\n * Object.values(SpaceSubtype).concat()\n *\n * for now, you can add valid subtypes here in initialization code to manually\n * extend this.\n */\nexport const VALID_SPACE_SUBTYPES = Object.values(SpaceSubtype).concat();\n\n/**\n * Common data among all ibgib spaces.\n */\nexport interface IbGibSpaceData extends WitnessData_V1 {\n /**\n * redeclaration for the name of the space, to make it required as opposed\n * to the base declaration which is optional.\n *\n * does NOT have to be unique.\n */\n name: string;\n /**\n * Redeclared over {@link WitnessData_V1.uuid} just for code readability,\n * showing the id to be a {@link SpaceId}, as well making it a required\n * field.\n */\n uuid: SpaceId;\n /**\n * if not given, defaults to \"user\" by convention.\n * @see {@link SpaceType}\n */\n type?: SpaceType;\n /**\n * should be required if {@link type} is set (truthy).\n * @see {@link SpaceSubtype}\n */\n subtype?: SpaceSubtype | undefined;\n /**\n * If true, when this space receives a command that includes incoming ibGibs\n * and ibGibAddrs, we will ensure the ibGibs have a 1-to-1 correspondence to\n * the addrs we're logging, and that the gib hashes are verified against the\n * ibGibs themselves.\n *\n * Otherwise, someone could pass in a bunch of legitimate addresses and\n * illegitimate ibGibs (that have little to do with the addresses). This\n * could at best be a coding mistake & at worst be malicious.\n */\n validateIbGibAddrsMatchIbGibs?: boolean;\n /**\n * interval between polling calls made to other spaces, e.g. sync spaces,\n * or used within a space to check inside itself for updates.\n *\n * ## notes\n *\n * * use as needed\n * * I want to just have this as a sync space setting, but since they are\n * enciphered, I don't want to just have them sitting around in plaintext.\n * * So I'm going to have it in the local app space, which the ibgibs\n * service will check in order for it to decide on interval.\n * * definitely a code smell, but I'm still resolving what a local app\n * space is vs the service that accesses it.\n */\n longPollingIntervalMs?: number;\n}\n\n/**\n * Specifically for ibgib spaces that are implemented via a path/subpath\n * strategy, i.e., using a filesystem-like addressing mechanism.\n */\nexport interface IbGibSpaceData_Subpathed extends IbGibSpaceData {\n /**\n * Redeclared here to make this required (not optional)\n */\n uuid: SpaceId;\n baseDir: string | any;\n encoding: string | any;\n /**\n * this is to help mitigate against too long path limits\n */\n mitigateLongPaths?: boolean;\n /**\n * if mitigating against long path lengths, this is the deciding split.\n *\n * so if the longPathLength is 250, and a full path would be 250, then\n * that is now a long path. 249 would be a short path and would not need\n * mitigation.\n */\n longPathLength?: number;\n baseSubPath: string;\n spaceSubPath: string;\n /**\n * if a filepath is too long, things get stuffed in here\n *\n * this is to help mitigate against too long path limits\n */\n longSubPath?: string;\n ibgibsSubPath: string;\n metaSubPath: string;\n binSubPath: string;\n dnaSubPath: string;\n n?: number;\n timestamp?: string;\n}\n\nexport interface IbGibSpaceRel8ns extends IbGibRel8ns_V1 {\n [ENCRYPTION_REL8N_NAME]?: IbGibAddr[];\n}\n\n\n/**\n * Cmds for interacting with ibgib spaces.\n *\n * Not all of these will be implemented for every space.\n *\n * ## todo\n *\n * change these commands to better structure, e.g., verb/do/mod, can/get/addrs\n * */\nexport type IbGibSpaceOptionsCmd =\n 'get' | 'put' | 'delete';\n/** Cmds for interacting with ibgib spaces. */\nexport const IbGibSpaceOptionsCmd = {\n /** Retrieve ibGib(s) out of the space (does not remove them). */\n get: 'get' as IbGibSpaceOptionsCmd,\n /** Registers/imports ibGib(s) into the space. */\n put: 'put' as IbGibSpaceOptionsCmd,\n /** Delete an ibGib from a space */\n delete: 'delete' as IbGibSpaceOptionsCmd,\n}\n\n/**\n * Flags to affect the command's interpretation.\n */\nexport type IbGibSpaceOptionsCmdModifier =\n 'can' | 'addrs' | 'latest' | 'watch' | 'unwatch' | 'tjps' | 'dependency-graph';\n/**\n * Flags to affect the command's interpretation.\n */\nexport const IbGibSpaceOptionsCmdModifier = {\n /**\n * Only interested if possibility to do command.\n *\n * This can be due to authorization or other.\n */\n can: 'can' as IbGibSpaceOptionsCmdModifier,\n /**\n * Only return the addresses of ibgibs\n */\n addrs: 'addrs' as IbGibSpaceOptionsCmdModifier,\n /**\n * Only interested in the latest one(s).\n *\n * The incoming addr(s) should be the tjp(s), since \"latest\"\n * only makes sense with unique timelines which are referenced by\n * their tjps.\n *\n * ## notes\n *\n * ATOW I'm actually using this in the aws dynamodb ibgib space to\n * get \"newer\" ibgibs, not just the latest.\n */\n latest: 'latest' as IbGibSpaceOptionsCmdModifier,\n /**\n * Ask to get updates on tjps in ibGibAddrs.\n */\n watch: 'watch' as IbGibSpaceOptionsCmdModifier,\n /*\n * Ask to stop getting updates on tjps in ibGibAddrs.\n */\n unwatch: 'unwatch' as IbGibSpaceOptionsCmdModifier,\n /**\n * Get the tjp ibgibs/addrs for given ibgib(s)\n */\n tjps: 'tjps' as IbGibSpaceOptionsCmdModifier,\n /**\n * Modifies the get command to retrieve a dependency graph.\n */\n dependencyGraph: 'dependency-graph' as IbGibSpaceOptionsCmdModifier,\n}\n\n/** Information for interacting with spaces. */\nexport interface IbGibSpaceOptionsData\n extends WitnessCmdData<IbGibSpaceOptionsCmd, IbGibSpaceOptionsCmdModifier> {\n /**\n * If putting, this will force replacing the file.\n *\n * ## intent\n * atow this is just for `put` commands.\n */\n force?: boolean;\n /**\n */\n catchAllErrors?: boolean;\n /**\n */\n trace?: boolean;\n}\n\nexport interface IbGibSpaceOptionsRel8ns extends WitnessCmdRel8ns {\n}\n\nexport interface IbGibSpaceOptionsIbGib<\n TIbGib extends IbGib = IbGib_V1,\n TOptsData extends IbGibSpaceOptionsData = IbGibSpaceOptionsData,\n // TOptsRel8ns extends IbGibSpaceOptionsRel8ns = IbGibSpaceOptionsRel8ns\n TOptsRel8ns extends IbGibSpaceOptionsRel8ns = IbGibSpaceOptionsRel8ns,\n> extends WitnessCmdIbGib<TIbGib, IbGibSpaceOptionsCmd, IbGibSpaceOptionsCmdModifier, TOptsData, TOptsRel8ns> {\n}\n\n/**\n * Shape of result data common to all (most) space interactions.\n *\n * This is in addition of course to {@link WitnessResultData}.\n */\nexport interface IbGibSpaceResultData extends WitnessResultData {\n /**\n * If the `cmd` is `canGet` or `canPut`, this holds the result that indicates\n * if you can or can't.\n */\n can?: boolean;\n /**\n * Addresses not found in a get.\n */\n addrsNotFound?: IbGibAddr[];\n /**\n * Addresses that are already in the space when requesting `put` or `canPut`.\n */\n addrsAlreadyHave?: IbGibAddr[];\n /**\n * Result map used when\n *\n * Mapping of incoming ibGibAddr -> latestAddr | null\n *\n * If there is a tjp/timeline -> maps to the latest in the store.\n * If there is no tjp -> maps to the incoming addr.\n * If the incoming addr is not found in the store -> maps to null.\n */\n latestAddrsMap?: { [addr: string]: IbGibAddr | null }\n /**\n * Map of TjpAddr -> newer LatestIbGibAddr notification.\n *\n * ## about\n *\n * When using the `watch` command modifier, a caller can subscribe to\n * updates/notifications to a timeline. When an update occurs in the space\n * via a `put` cmd that ends up creating/storing a newer ibgib address than\n * the one the receiving space knows the caller is aware of, it will try to\n * make the caller aware of the update.\n *\n * There are two ways to do this:\n * 1. Store the notification info locally until the next interaction between\n * the space and the caller.\n * 2. Send the notification actively to the caller.\n *\n * For the first implementation of notifications, only the first will be\n * implemented. Local notifications will be implemented, but active\n * internodal notification in the general sense will be implemented at a\n * later time.\n *\n * ## notes\n *\n * * may also implement a dedicated command to watch subscriptions.\n */\n watchTjpUpdateMap?: { [tjpAddr: string]: IbGibAddr; }\n}\n\nexport interface IbGibSpaceResultRel8ns extends WitnessResultRel8ns { }\n\nexport interface IbGibSpaceResultIbGib<\n TIbGib extends IbGib,\n TResultData extends IbGibSpaceResultData,\n TResultRel8ns extends IbGibSpaceResultRel8ns\n>\n extends WitnessResultIbGib<TIbGib, TResultData, TResultRel8ns> {\n}\n\n/**\n* Data space adapter/provider, such that a space should only have one type of...\n* * ibGib shape\n* * witness arg shape (which brings in external ibGibs)\n* * witness result shape\n*\n* So this interface facilitates that belief.\n*/\nexport interface IbGibSpace<\n TIbGib extends IbGib,\n TOptionsData extends IbGibSpaceOptionsData,\n TOptionsRel8ns extends IbGibSpaceOptionsRel8ns,\n TOptionsIbGib extends IbGibSpaceOptionsIbGib<TIbGib, TOptionsData, TOptionsRel8ns>,\n TResultData extends IbGibSpaceResultData,\n TResultRel8ns extends IbGibSpaceResultRel8ns,\n TResultIbGib extends IbGibSpaceResultIbGib<TIbGib, TResultData, TResultRel8ns>,\n TData extends IbGibSpaceData = IbGibSpaceData,\n TRel8ns extends IbGibSpaceRel8ns = IbGibRel8ns,\n>\n extends Witness<TOptionsIbGib, TResultIbGib, TData, TRel8ns> {\n witness(arg: TOptionsIbGib): Promise<TResultIbGib | undefined>;\n}\n\nexport type SpaceLockAction = 'lock' | 'unlock';\nexport type SpaceLockScope = 'all' | TjpIbGibAddr;\n\n/**\n * Data shape for {@link IbGibSpaceLockIbGib}.\n *\n * This includes the options passed in and contains any result data of the lock\n * as well.\n */\nexport interface IbGibSpaceLockData {\n /**\n * In-memory unique identifier associated with the lock.\n *\n * ## intent\n *\n * I intend this mainly as a device for differentiating among multiple\n * tabs open on the same browser. These share the same IndexedDB instance\n * (and thus the same space bucket), but they have different caching\n * mechanisms and interfaces to this bucket.\n */\n instanceId?: string;\n /**\n * self-explanatory\n */\n // action?: SpaceLockAction;\n /**\n * When setting the lock, this was the maximum amount of time the lock is\n * valid.\n *\n * {@link expirationUTC}\n */\n secondsValid?: number;\n /**\n * When setting the lock, this was the calculated expiration string based on\n * {@link secondsValid}.\n *\n * If the lock is not manually released, this will determine if the lock is\n * adhered to.\n */\n expirationUTC?: string;\n /**\n * The scope to which the lock applies.\n */\n scope: SpaceLockScope;\n /**\n * True if space was already locked.\n */\n alreadyLocked?: boolean;\n /**\n * True if caller's request to lock the space was executed.\n */\n success?: boolean;\n /**\n * If errored, this is the message.\n */\n errorMsg?: string;\n}\n\n/**\n * Options for the function that locks a space.\n\n * {@link IbGibSpaceLockData}\n * {@link IbGibSpaceLockIbGib}\n */\nexport interface IbGibSpaceLockOptions extends IbGibSpaceLockData {\n /**\n * the space to lock/unlock\n */\n space: IbGibSpaceAny;\n}\n\n/**\n * Rel8ns shape for {@link IbGibSpaceLockIbGib}\n *\n * marker interface atm\n */\nexport interface IbGibSpaceLockRel8ns extends IbGibRel8ns_V1 { }\n\n/**\n * When locking a space, this is the ibGib that contains informatino regarding\n * the process. This includes if the lock was successful, how long the lock is\n * good for, etc.\n *\n * ## notes\n *\n * * This is meant to be completely ephemeral and there will be no gib. There\n * may be many calls to lock/release in tight loops and atow it wouldn't seem\n * provide us with much benefit to store this kind of metadata.\n */\nexport interface IbGibSpaceLockIbGib\n extends IbGib_V1<IbGibSpaceLockData, IbGibSpaceLockRel8ns> {\n\n}\n\n/**\n * Marker type to indicate that a string is meant to be a transmission id.\n */\nexport type TxId = 'string';\n\n/**\n * we have a getDependencyGraph wrapper in the space base. This is the type of\n * that's result data.\n */\nexport interface GetDependencyGraphResultData extends IbGibSpaceResultData {\n count: number;\n}", "import { UUID_REGEXP } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { getRegExp, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { DynamicForm, FormItemInfo } from './form-items.mjs';\nimport { GLOBAL_LOG_A_LOT, SAFE_SPECIAL_CHARS } from '../../core-constants.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n/**\n * Fluent-style builder helper class.\n *\n * I'm making this to share common fields' settings among witness classes.\n *\n * Descend from this class for sharing other commonalities.\n */\nexport class DynamicFormBuilder {\n protected lc: string = `[${DynamicFormBuilder.name}]`;\n\n protected items: FormItemInfo[] = [];\n protected what: string = '';\n /**\n * pool of uuids pre-calculated to be passed in to the builder. if this is\n * falsy, then it will use a Math.random() based approach.\n */\n protected idPool: string[] = [];\n\n /**\n * hacky wrapper for this.idPool.pop()\n */\n protected getNewId(): string {\n const lc = `${this.lc}[${this.getNewId.name}]`;\n if (this.idPool?.length > 0) {\n return this.idPool.pop() ?? '';\n } else {\n // weak implementation...\n let resultArray: string[] = [];\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n const charLength = chars.length;\n for (let i = 0; i < 32; i++) {\n let charIndex = Math.floor(Math.random() * charLength);\n resultArray.push(chars[charIndex]);\n }\n let id = resultArray.join('');\n if (logalot) { console.log(`${lc} id: ${id} (I: c6591ffee6d5bbea79ed19cfa6630422)`); }\n return id;\n }\n }\n\n /**\n * Start fluent calls with this.\n */\n forA({\n what,\n }: {\n /**\n * Common name for the reified concrete type of the witness.\n *\n * Used in things like placeholders, descriptions, etc.\n *\n * @example \"robbot\" or \"space\"\n */\n what: string,\n }): DynamicFormBuilder {\n this.what = what || 'thingy';\n return this;\n }\n\n protected addItem(item: FormItemInfo) {\n if (!item.uuid) { item.uuid = this.getNewId(); }\n this.items.push(item);\n }\n\n /**\n * Empty function simply for more natural looking fluent syntax.\n *\n * You can override this for custom form builders that descend from this\n * class.\n *\n * @returns this\n */\n with<T extends DynamicFormBuilder>({\n idPool,\n }: {\n /**\n * pre-built pool of uuids to draw from. this builder\n * will mutate this array.\n */\n idPool?: string[],\n }): T {\n if (idPool) { this.idPool = idPool; }\n return this as any as T;\n }\n\n /**\n * I'm not a great fluent builder writer for TypeScript,\n * and this function acts as a caster for which members of\n * which concrete classes to expose for the proceeding builder lines.\n *\n *\n * Basically, you use this to typecast the builder, possibly redundantly since\n * I don't have any ordering implemented atow.\n *\n * @returns typecasted fluent builder\n */\n and<T extends DynamicFormBuilder>(): T { return this as any as T; }\n\n name<T extends DynamicFormBuilder>({\n of: value,\n required = true,\n defaultValue,\n }: {\n of: string,\n required?: boolean,\n defaultValue?: string,\n }): T {\n this.addItem({\n // witness.data.name\n name: \"name\",\n description: `What to call this ${this.what}. Doesn't have to be unique, no spaces, up to 32 alphanumerics/underscores in length.`,\n label: \"Name\",\n placeholder: `e.g. \"bob_the_cool\"`,\n regexp: getRegExp({ min: 1, max: 32, noSpaces: true }),\n regexpErrorMsg: '1 to 32 characters, no spaces, underscores allowed.',\n required,\n dataType: 'text',\n value,\n defaultValue,\n });\n return this as any as T;\n }\n\n description({\n of: value,\n required,\n defaultValue,\n }: {\n of: string,\n required?: boolean,\n defaultValue?: string,\n }): DynamicFormBuilder {\n this.addItem({\n // witness.data.description\n name: \"description\",\n description: `Description/notes for this ${this.what}.`,\n label: \"Description\",\n placeholder: `Describe these ${this.what} settings here...`,\n regexp: getRegExp({ min: 0, max: 155, chars: SAFE_SPECIAL_CHARS }),\n regexpErrorMsg: `0 to 155 alphanumerics or any of ${SAFE_SPECIAL_CHARS}`,\n // regexpSource: getRegExp({min: 0, max: 155, chars: SAFE_SPECIAL_CHARS}).source,\n dataType: 'textarea',\n required,\n value,\n defaultValue,\n });\n return this;\n }\n\n classname({\n of,\n required = true,\n }: {\n of: string,\n required?: boolean,\n }): DynamicFormBuilder {\n this.addItem({\n // witness.data.classname\n name: \"classname\",\n description: `Technical setting that is the name of the ${this.what}'s class in computer code.`,\n label: \"Classname\",\n regexp: getRegExp({ min: 1, max: 128, noSpaces: true }),\n regexpErrorMsg: `1 to 128 alphanumerics or underscores without spaces`,\n // regexpSource: getRegExp({min: 1, max: 128, noSpaces: true}).source,\n dataType: 'text',\n value: of,\n readonly: true,\n required,\n });\n return this;\n }\n\n uuid({\n of,\n label,\n required,\n }: {\n of: string,\n label?: string,\n required?: boolean,\n }): DynamicFormBuilder {\n this.addItem({\n // witness.data.uuid\n name: \"uuid\",\n description: `Unique(ish) id of the ${this.what}.`,\n label: label ?? \"ID\",\n dataType: 'text',\n value: of,\n regexp: UUID_REGEXP,\n regexpErrorMsg: '1 to 256 alphanumerics, underscores, dots, hyphens allowed.',\n readonly: true,\n required,\n });\n return this;\n }\n\n version({\n of,\n required,\n }: {\n of: string | undefined,\n required?: boolean,\n }): DynamicFormBuilder {\n this.addItem({\n // witness.data.version\n name: \"version\",\n description: `Technical setting indicating the version of the ${this.what}.`,\n label: \"Version\",\n dataType: 'text',\n value: of || '',\n readonly: true,\n required,\n });\n return this;\n }\n\n /**\n * To pass in a completely customized item info.\n *\n * @returns `this` for fluent builder\n */\n customItem(item: FormItemInfo): DynamicFormBuilder {\n this.addItem(item);\n return this;\n }\n\n\n outputItems(): FormItemInfo[] {\n return this.items;\n }\n\n outputForm({\n formName,\n label,\n }: {\n formName: string,\n label?: string,\n }): DynamicForm {\n return {\n name: formName,\n // description: this.description ?? `This is a form for a ${this.what}`,\n description: `This is a form for a ${this.what}`,\n label: label ?? this.what,\n items: this.items,\n } as DynamicForm;\n }\n}\n", "import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';\nimport { DynamicFormBuilder } from '../common/form/form-helper.mjs';\nimport { WitnessData_V1 } from '../witness/witness-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n/**\n * Fluent-style builder helper class.\n *\n * I'm making this to share common fields' settings among witness classes.\n *\n * Descend from this class for sharing other commonalities.\n */\nexport class WitnessFormBuilder extends DynamicFormBuilder {\n protected lc: string = `[${WitnessFormBuilder.name}]`;\n\n allowPrimitiveArgs({\n of,\n required = true,\n }: {\n of: boolean | undefined,\n required?: boolean,\n }): WitnessFormBuilder {\n this.addItem({\n // witness.data.allowPrimitiveArgs\n name: \"allowPrimitiveArgs\",\n description: `Technical setting on if this ${this.what} accepts primitive incoming ibgibs`,\n label: \"Allow Primitive Args\",\n dataType: 'toggle',\n value: of ?? true,\n readonly: true,\n required,\n });\n return this;\n }\n\n catchAllErrors({\n of,\n required = true,\n }: {\n of: boolean | undefined,\n required?: boolean,\n }): WitnessFormBuilder {\n this.addItem({\n // witness.data.catchAllErrors\n name: \"catchAllErrors\",\n description: `Technical setting on what the ${this.what} does when it encounters an internal error.`,\n label: \"Catch All Errors\",\n dataType: 'toggle',\n value: of ?? true,\n readonly: true,\n required,\n });\n return this;\n }\n\n persistOptsAndResultIbGibs({\n of,\n required = true,\n }: {\n of: boolean | undefined,\n required?: boolean,\n }): WitnessFormBuilder {\n this.addItem({\n // witness.data.persistOptsAndResultIbGibs\n name: \"persistOptsAndResultIbGibs\",\n description: `Technical setting on if the ${this.what} maintains an audit trail of all of its inputs/outputs.`,\n label: \"Persist Opts and Result IbGibs\",\n dataType: 'toggle',\n value: of ?? false,\n readonly: true,\n required,\n });\n return this;\n }\n\n trace({\n of,\n required,\n }: {\n of: boolean | undefined,\n required?: boolean,\n }): WitnessFormBuilder {\n this.addItem({\n // witness.data.trace\n name: \"trace\",\n description: `Technical setting on if the ${this.what}'s activity should be traced (logged to the console).`,\n label: \"Trace\",\n dataType: 'toggle',\n value: of ?? false,\n readonly: true,\n required,\n });\n return this;\n }\n\n /**\n * Includes common witness fields.\n *\n * All common fields default to `true`, so set any you want to skip to\n * `false`.\n *\n * @returns `this` for fluent builder\n */\n commonWitnessFields({\n data,\n allowPrimitiveArgs = true,\n catchAllErrors = true,\n persistOptsAndResultIbGibs = true,\n trace = true,\n version = true,\n }: {\n data: WitnessData_V1,\n allowPrimitiveArgs?: boolean,\n catchAllErrors?: boolean,\n persistOptsAndResultIbGibs?: boolean,\n trace?: boolean,\n version?: boolean,\n }): WitnessFormBuilder {\n if (allowPrimitiveArgs) { this.allowPrimitiveArgs({ of: data.allowPrimitiveArgs }); }\n if (catchAllErrors) { this.catchAllErrors({ of: data.catchAllErrors }); }\n if (persistOptsAndResultIbGibs) { this.persistOptsAndResultIbGibs({ of: data.persistOptsAndResultIbGibs }); }\n if (trace) { this.trace({ of: data.trace }); }\n if (version) { this.version({ of: data.version }); }\n return this;\n }\n\n}\n", "import { getTimestampInTicks, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { UUID_REGEXP } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { Gib, Ib, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\nimport { AppData_V1, AppIbGib_V1, AppPromptResult, } from './app-types.mjs';\nimport { APP_NAME_REGEXP, APP_REL8N_NAME, } from './app-constants.mjs';\nimport { IbGibAppAny } from './app-base-v1.mjs';\nimport { IbGibSpaceAny } from '../space/space-base-v1.mjs';\nimport { WitnessFormBuilder } from '../witness-form-builder.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { IbGibTimelineUpdateInfo } from '../../common/other/other-types.mjs';\nimport { persistTransformResult, registerNewIbGib, rel8ToSpecialIbGib } from '../space/space-helper.mjs';\nimport { MetaspaceService } from '../space/metaspace/metaspace-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n\nexport function getAppResultMetadata({ app }: { app: IbGibAppAny }): string {\n return `${app.ib} ${getTimestampInTicks()}`;\n}\n\nexport function validateCommonAppData({\n appData,\n}: {\n appData: AppData_V1 | undefined,\n}): string[] {\n const lc = `[${validateCommonAppData.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!appData) { throw new Error(`appData required (E: 3df782b29bc4406a87e4895cfcea28ed)`); }\n const errors: string[] = [];\n const {\n name, uuid, classname,\n } =\n appData;\n\n if (name) {\n if (!name.match(APP_NAME_REGEXP)) {\n errors.push(`name must match regexp: ${APP_NAME_REGEXP}`);\n }\n } else {\n errors.push(`name required.`);\n }\n\n if (uuid) {\n if (!uuid.match(UUID_REGEXP)) {\n errors.push(`uuid must match regexp: ${UUID_REGEXP}`);\n }\n } else {\n errors.push(`uuid required.`);\n }\n\n if (classname) {\n if (!classname.match(APP_NAME_REGEXP)) {\n errors.push(`classname must match regexp: ${APP_NAME_REGEXP}`);\n }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getAppIb({\n appData,\n classname,\n}: {\n appData: AppData_V1,\n classname?: string,\n}): Ib {\n const lc = `[${getAppIb.name}]`;\n try {\n const validationErrors = validateCommonAppData({ appData });\n if (validationErrors.length > 0) { throw new Error(`invalid appData: ${validationErrors} (E: 9aff04f0cfc54a5188ca8bc40764160d)`); }\n if (classname) {\n if (appData.classname && appData.classname !== classname) { throw new Error(`classname does not match appData.classname (E: 66f1447eef97485fba521c40980f5eb5)`); }\n } else {\n classname = appData.classname;\n if (!classname) { throw new Error(`classname required (E: 5f6ffb4317044125b94f662070e1f40b)`); }\n }\n\n const { name, uuid } = appData;\n return `app ${classname} ${name} ${uuid}`;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Current schema is `app ${classname} ${name} ${uuid}`\n *\n * NOTE this is space-delimited\n */\nexport function getInfoFromAppIb({\n appIb,\n}: {\n appIb: Ib,\n}): {\n appClassname: string,\n appName: string,\n appId: string,\n} {\n const lc = `[${getInfoFromAppIb.name}]`;\n try {\n if (!appIb) { throw new Error(`appIb required (E: 6b065aee67e641ba9f9c6db367ebb0fb)`); }\n\n const pieces = appIb.split(' ');\n\n return {\n appClassname: pieces[1],\n appName: pieces[2],\n appId: pieces[3],\n };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport function getAppInfoIb({\n appData,\n appTjpGib,\n classname,\n}: {\n appData: AppData_V1,\n appTjpGib: Gib,\n /**\n * Not sure why i have this here, since it should always be in the appData.classname...\n */\n classname?: string,\n}): Ib {\n const lc = `[${getAppIb.name}]`;\n try {\n const validationErrors = validateCommonAppData({ appData });\n if (validationErrors.length > 0) { throw new Error(`invalid appData: ${validationErrors} (E: 7be1f54ce8af4e4982966b2dedb4cf6e)`); }\n if (classname) {\n if (appData.classname && appData.classname !== classname) { throw new Error(`classname does not match appData.classname (E: 64bd9eaef1f94be8856e18b791d4ae52)`); }\n } else {\n classname = appData.classname;\n if (!classname) { throw new Error(`classname required (E: 8d194cf8fb3f4c8eb2f708e0ccfe187c)`); }\n }\n\n const { name, uuid } = appData;\n return `info_app ${classname} ${name} ${uuid} ${appTjpGib ?? 0}`;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Current schema is `info_app ${classname} ${name} ${uuid} ${appTjpGib ?? 0}`\n *\n * NOTE this is space-delimited\n */\nexport function getInfoFromAppInfoIb({\n appInfoIb,\n}: {\n appInfoIb: Ib,\n}): {\n appClassname: string;\n appName: string;\n appId: string;\n appTjpGib: Gib;\n} {\n const lc = `[${getInfoFromAppIb.name}]`;\n try {\n if (!appInfoIb) { throw new Error(`appInfoIb required (E: d12756f218144d22acb14c794dd3eeef)`); }\n\n const pieces = appInfoIb.split(' ');\n\n if (pieces.length !== 5) { throw new Error(`invalid appInfoIb. Expected space-delimited pieces.length === 5 (E: 21bfc58e4d88c298680ea95bc6dfc622)`); }\n\n return {\n appClassname: pieces[1],\n appName: pieces[2],\n appId: pieces[3],\n appTjpGib: pieces[4],\n };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n\n/**\n * Prompts the user a form to build the app.\n *\n * Once prompted, the app is:\n * 1. validated\n * 2. persisted in the given {@link space}\n * 3. registered with the space\n * 4. related to the space's special apps index\n * 5. new app is returned\n *\n * @returns newly created app ibgib (witness)\n */\nexport async function createNewApp({\n fnPromptApp,\n ibgibs,\n space,\n}: {\n /**\n * factory function for creating/editing an app ibgib.\n *\n * @param space space within which we're working\n * @param ibGib set if editing app, null if creating\n * @returns TransformResult<IbGibAppAny> for app ibgib created/edited\n */\n fnPromptApp: (space: IbGibSpaceAny, ibGib: AppIbGib_V1 | null) => Promise<AppPromptResult | undefined>,\n /**\n * Either {@link common} or {@link ibgibs} is required\n * @hack\n */\n ibgibs?: MetaspaceService,\n /**\n * space within which to create the app. if not provided, the\n * defaults to the local user space via {@link common} or {@link ibgibs}.\n */\n space: IbGibSpaceAny,\n}): Promise<IbGibAppAny | undefined> {\n const lc = `[${createNewApp.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!ibgibs) { throw new Error(`ibgibs all powerful service required. (E: b24e78de0d204dc78909022bee296b30)`); }\n\n space = space ?? await ibgibs.getLocalUserSpace({ lock: true });\n\n // prompt user to create the ibgib, passing in null because we're\n // creating not editing.\n let resApp = await fnPromptApp(space, /*ibGib*/ null);\n\n if (!resApp) { throw new Error(`resApp falsy after prompt for app. (E: 2225a567abcd680a5e957e81fbb64123)`); }\n\n /** this should be the witness class itself at this point. */\n const newApp = (resApp.newIbGib as IbGibAppAny);\n\n let allIbGibs: IbGib_V1[] = [];\n allIbGibs.push(newApp);\n resApp.intermediateIbGibs?.forEach((x: IbGib_V1) => allIbGibs.push(x));\n resApp.dnas?.forEach((x: IbGib_V1) => allIbGibs.push(x));\n for (let i = 0; i < allIbGibs.length; i++) {\n const ibGib = allIbGibs[i];\n const validationErrors = await validateIbGibIntrinsically({ ibGib });\n if ((validationErrors ?? []).length > 0) { throw new Error(`(UNEXPECTED) invalid app ibgib created. validationErrors: ${validationErrors}. app: ${pretty(newApp.toIbGibDto())} (E: 54cfc2f6bc284ed79be91d2da5e4bd2f)`); }\n }\n\n await persistTransformResult({ resTransform: resApp, space });\n const { zeroSpace, fnBroadcast, fnUpdateBootstrap } = ibgibs;\n await registerNewIbGib({\n ibGib: newApp,\n space,\n fnBroadcast: (x: IbGibTimelineUpdateInfo) => fnBroadcast(x),\n });\n\n await rel8ToSpecialIbGib({\n type: \"apps\",\n rel8nName: APP_REL8N_NAME,\n ibGibsToRel8: [newApp],\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n });\n return newApp;\n } catch (error) {\n debugger; // before error\n console.error(`${lc} ${error.message}`);\n return;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport class AppFormBuilder extends WitnessFormBuilder {\n protected lc: string = `[${AppFormBuilder.name}]`;\n\n constructor() {\n super();\n this.what = 'app';\n }\n\n icon({\n of,\n required,\n defaultValue,\n iconsList,\n }: {\n of: string,\n required?: boolean,\n defaultValue?: string,\n iconsList: string[],\n }): AppFormBuilder {\n // const exampleIonicons = IONICONS.slice(0, 4).map(x => `\"${x}\"`).join(', ');\n const exampleIonicons = iconsList.slice(0, 4).map(x => `\"${x}\"`).join(', ');\n this.addItem({\n // witness.data.outputPrefix\n name: \"icon\",\n description: `Icon name for the app's icon in the app bar. (NOTE: Only ionicons right now, e.g. ${exampleIonicons}). See https://ionic.io/ionicons for a full list.`,\n label: \"Icon\",\n fnValid: (x: string | number) => { return typeof x === 'string' && iconsList.includes(x); },\n defaultErrorMsg: `Must be a valid icon from the icons list.`,\n dataType: 'select',\n value: of,\n defaultValue: defaultValue || 'beer',\n selectOptions: [\n ...iconsList,\n ],\n required,\n });\n return this;\n }\n\n}\n\n// export function documentLocationIsAtWelcomePage(): boolean {\n// return ['welcome', '/welcome', '/welcome/'].includes(document.location.pathname);\n// }\n", "import { AppData_V1, AppRel8ns_V1 } from '../app-types.mjs';\n\nexport const DEFAULT_UUID_CHAT_APP = '0';\nexport const DEFAULT_NAME_CHAT_APP = 'chat_gib';\nexport const DEFAULT_DESCRIPTION_CHAT_APP =\n `A chat app done ibgib style, enabling infinitely nesting comments, pics and links. It's ibgibs all the way down...`;\n\n\nexport interface ChatAppData_V1 extends AppData_V1 {\n\n}\n\n\nexport interface ChatAppRel8ns_V1 extends AppRel8ns_V1 {\n\n}\n\n/**\n * Default data values for a random app.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_CHAT_APP_DATA_V1: ChatAppData_V1 = {\n version: '1',\n uuid: DEFAULT_UUID_CHAT_APP,\n name: DEFAULT_NAME_CHAT_APP,\n description: DEFAULT_DESCRIPTION_CHAT_APP,\n // classname: ChatApp_V1.name,\n classname: `ChatApp_V1`,\n\n icon: 'chatbubbles',\n\n persistOptsAndResultIbGibs: false,\n allowPrimitiveArgs: true,\n catchAllErrors: true,\n trace: false,\n}\nexport const DEFAULT_CHAT_APP_REL8NS_V1: ChatAppRel8ns_V1 | undefined = undefined;\n", "import { AppData_V1, AppRel8ns_V1 } from '../app-types.mjs';\n\nexport const DEFAULT_UUID_RAW_APP = '0';\nexport const DEFAULT_NAME_RAW_APP = 'raw_gib';\nexport const DEFAULT_DESCRIPTION_RAW_APP =\n `Explorer app for navigating raw ibgib data.`;\n\n\nexport interface RawAppData_V1 extends AppData_V1 {\n\n}\n\nexport interface RawAppRel8ns_V1 extends AppRel8ns_V1 {\n\n}\n\n/**\n * Default data values for a random app.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_RAW_APP_DATA_V1: RawAppData_V1 = {\n version: '1',\n uuid: DEFAULT_UUID_RAW_APP,\n name: DEFAULT_NAME_RAW_APP,\n description: DEFAULT_DESCRIPTION_RAW_APP,\n // classname: RawApp_V1.name,\n classname: `RawApp_V1`,\n\n icon: 'paper-plane',\n\n persistOptsAndResultIbGibs: false,\n allowPrimitiveArgs: true,\n catchAllErrors: true,\n trace: false,\n}\n\nexport const DEFAULT_RAW_APP_REL8NS_V1: RawAppRel8ns_V1 | undefined = undefined;\n", "import { Gib } from '@ibgib/ts-gib/dist/types.mjs';\nimport { IbGibData_V1, IbGibRel8ns_V1, IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\nimport { AppData_V1, AppRel8ns_V1 } from '../app-types.mjs';\n\nexport const DEFAULT_UUID_TODO_APP = '0';\nexport const DEFAULT_NAME_TODO_APP = 'todo_gib';\nexport const DEFAULT_DESCRIPTION_TODO_APP =\n `Todo app for viewing and interacting with ibgibs like they're checklists.`;\n\n\nexport interface TodoAppData_V1 extends AppData_V1 {\n\n}\n\nexport interface TodoAppRel8ns_V1 extends AppRel8ns_V1 {\n\n}\n\n/**\n * Default data values for a random app.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_TODO_APP_DATA_V1: TodoAppData_V1 = {\n version: '1',\n uuid: DEFAULT_UUID_TODO_APP,\n name: DEFAULT_NAME_TODO_APP,\n description: DEFAULT_DESCRIPTION_TODO_APP,\n // classname: TodoApp_V1.name,\n classname: `TodoApp_V1`,\n\n icon: 'checkbox',\n\n persistOptsAndResultIbGibs: false,\n allowPrimitiveArgs: true,\n catchAllErrors: true,\n trace: false,\n}\nexport const DEFAULT_TODO_APP_REL8NS_V1: TodoAppRel8ns_V1 | undefined = undefined;\n\n/**\n * when an ibgib has children that are checked/unchecked using\n * the (a?) todo app, this is the rel8n name to the info.\n */\nexport const TODO_INFO_REL8N_NAME = 'todo';\nexport const TODO_INFO_IB = 'todo_info';\n\n\nexport interface TodoInfoData_V1 extends IbGibData_V1 {\n tjpGibsDone: Gib[];\n}\n\nexport interface TodoInfoRel8ns_V1 extends IbGibRel8ns_V1 {\n}\n\nexport interface TodoInfoIbGib_V1 extends IbGib_V1<TodoInfoData_V1, TodoInfoRel8ns_V1> { }\n", "import { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/index.mjs\";\nimport { getIbGibAddr } from \"@ibgib/ts-gib/dist/helper.mjs\";\nimport { validateIbGibIntrinsically } from \"@ibgib/ts-gib/dist/V1/validate-helper.mjs\";\n\nimport { BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY, BOOTSTRAP_IBGIB_ADDR } from \"./bootstrap-constants.mjs\";\nimport { BootstrapData, BootstrapRel8ns } from \"./bootstrap-types.mjs\";\n\nexport async function validateBootstrapIbGib(bootstrapSpace: IbGib_V1): Promise<boolean> {\n const lc = `[${validateBootstrapIbGib.name}]`;\n const errors: string[] = [];\n try {\n const addr = getIbGibAddr({ ibGib: bootstrapSpace });\n if (addr !== BOOTSTRAP_IBGIB_ADDR) {\n errors.push(`invalid bootstrapSpace addr. Should equal \"${BOOTSTRAP_IBGIB_ADDR}\" (E: ecfdbed719284db7a1aa3f867f706fe9)`);\n }\n let intrinsicErrors = await validateIbGibIntrinsically({ ibGib: bootstrapSpace });\n if (intrinsicErrors?.length ?? -1 > 0) { intrinsicErrors!.forEach(e => errors.push(e)); }\n\n const data = (bootstrapSpace.data as BootstrapData);\n const rel8ns = (bootstrapSpace.rel8ns as BootstrapRel8ns);\n\n if (Object.keys(data || {}).length === 0) {\n errors.push(`invalid bootstrapSpace data. data required (E: 5a9bd15dd0644f9b93cafbbba660cfdf)`);\n }\n if ((data.spaceIds ?? []).length === 0) {\n errors.push(`invalid bootstrapSpace, data.spaceIds required. (E: 6b91ddc12cfd41e59ded7d7502c1909f)`);\n }\n if (Object.keys(bootstrapSpace.rel8ns || {}).length === 0) {\n errors.push(`invalid bootstrapSpace rel8ns (empty). Should have at least one rel8n, with rel8nName corresponding to the spaceId (E: b188ce4ae25e49f794f35e141bc2ecde)`);\n }\n data.spaceIds.forEach((spaceId: string) => {\n if ((rel8ns[spaceId] ?? []).length === 0) {\n errors.push(`invalid bootstrap. Each spaceId listed in data should have a corresponding address in rel8ns. spaceId (${spaceId}) missing. (E: 62dd0d76e29a415a98b4b27deb8db17e)`);\n }\n });\n if (!data[BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY]) {\n errors.push(`invalid bootstrap. data.${BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY} required. (E: f763af2e275f445cbf1db5801bacafad)`);\n } else if ((rel8ns[data[BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY]] ?? []).length === 0) {\n errors.push(`invalid bootstrap. data.${BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY} (${data[BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY]}) not found in rel8ns. (E: 44d0799d232f4a51a0b0019ebebe019f)`);\n }\n if (errors.length === 0) {\n return true;\n } else {\n console.error(`${lc} errors: ${errors.join('|')}`);\n return false;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return false;\n }\n}\n", "/**\n * @module meta-stone constants\n *\n * constants are in this file!\n */\n\n// /**\n// * example enum-like type+const that I use in ibgib. sometimes i put\n// * these in the types.mts and sometimes in the const.mts, depending\n// * on context.\n// */\n// export type SomeEnum =\n// 'ib' | 'gib';\n// export const SomeEnum = {\n// ib: 'ib' as SomeEnum,\n// gib: 'gib' as SomeEnum,\n// } satisfies { [key: string]: SomeEnum };\n// export const SOME_TYPE_VALUES: SomeEnum[] = Object.values(SomeEnum);\n\n/**\n * atom used in ibs\n *\n * atow (11/2023) this should also be (as with most atoms) the ib of the parent\n * primitive ibgib used when creating a new ibgib (forking a primitive ibgib\n * with this ib).\n */\nexport const META_STONE_ATOM = 'meta_stone';\n\n/**\n * default regexp for a simple name string.\n */\nexport const META_STONE_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,255}$/;\n\n/**\n * for use when creating a metastone targeting an ibgib without a tjp (i.e. a\n * stone ibgib itself).\n */\nexport const DEFAULT_META_STONE_TJPGIB = 'undefined';\n/**\n * for use when targetIbGib.data.n is falsy or NaN\n */\nexport const DEFAULT_META_STONE_N = -1;\n/**\n * for use when targetIbGib.data.timestamp is falsy\n */\nexport const DEFAULT_META_STONE_TIMESTAMP = 'undefined';\n\n/**\n * rel8n name pointing from the metastone to its target ibgib.\n */\nexport const META_STONE_TARGET_REL8N_NAME = 'target';\n/**\n * rel8n name pointing from the metastone to the target's temporal junction\n * point.\n */\nexport const META_STONE_TARGET_TJP_REL8N_NAME = 'targetTjp';\n", "/**\n * @module meta-stone helper/util/etc. functions\n *\n * this is where you will find helper functions like those that generate\n * and parse ibs for meta-stone.\n */\n\n// import * as pathUtils from 'path';\n// import { statSync } from 'node:fs';\n// import { readFile, } from 'node:fs/promises';\n// import * as readline from 'node:readline/promises';\n// import { stdin, stdout } from 'node:process'; // decide if use this or not\n\nimport {\n extractErrorMsg, getTimestamp, getTimestampInTicks,\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { Ib, IbGibAddr, } from '@ibgib/ts-gib/dist/types.mjs';\nimport {\n validateGib, validateIbGibAddr, validateIbGibIntrinsically,\n validateRel8nsIntrinsically\n} from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { getIbAndGib, getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\nimport { GIB } from '@ibgib/ts-gib/dist/V1/constants.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\nimport {\n MetaStoneData_V1, MetaStoneRel8ns_V1, MetaStoneIbGib_V1, MetaStoneIbInfo,\n} from './meta-stone-types.mjs';\nimport {\n DEFAULT_META_STONE_N, DEFAULT_META_STONE_TIMESTAMP,\n DEFAULT_META_STONE_TJPGIB, META_STONE_ATOM, META_STONE_TARGET_REL8N_NAME,\n META_STONE_TARGET_TJP_REL8N_NAME,\n} from './meta-stone-constants.mjs';\nimport { constantIbGib, getTimestampInfo, getTjpAddr, isBinary } from '../other/ibgib-helper.mjs';\n\n/**\n * for verbose logging\n */\nconst logalot = GLOBAL_LOG_A_LOT;\n\nexport function validateCommonMetaStoneIb({\n ib,\n}: {\n ib: Ib,\n}): string[] {\n const lc = `[${validateCommonMetaStoneIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const errors: string[] = [];\n\n const pieces = ib.split(' ');\n\n // atom\n const atom = pieces[0];\n if (atom !== META_STONE_ATOM) {\n errors.push(`${lc} invalid ib. atom is expected to be META_STONE_ATOM: ${META_STONE_ATOM} (E: a9812bffc18f44418aa091fb0ed260bd)`)\n }\n\n // validate tjpGib\n const tjpGib = pieces[1];\n const tjpGibValidationErrors = validateGib({ gib: tjpGib }) ?? [];\n if (tjpGibValidationErrors.length > 0) {\n errors.push(`invalid ib. pieces[1] should be a valid tjpGib. validation errors: ${tjpGibValidationErrors} (E: 233db2babfbe4d28a80f98261f1c0e01)`);\n }\n\n // n\n const nAsString = pieces[2];\n const parsedN = Number.parseInt(nAsString);\n if (isNaN(parsedN)) { errors.push(`invalid ib. space-delimited pieces[2] should be valid integer (E: 71df0d6abd7b4cf4b11621e6bfb556cd)`); }\n\n // timestampInTicks\n const timestampInTicks = pieces[3];\n if (timestampInTicks === 'undefined') {\n // this happens when it's a binary ibgib or just doesn't have a timestamp in the data map\n } else {\n const timestampInfo = getTimestampInfo({ timestamp: timestampInTicks });\n if (!timestampInfo.valid) {\n errors.push(`invalid ib. pieces[3] should be valid timestampInTicks. emsg: (${timestampInfo.emsg}) (E: 06dae01d66f54f54b71d9c920c730840)`);\n }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function validateCommonMetaStoneData({\n data,\n}: {\n data?: MetaStoneData_V1,\n}): string[] {\n const lc = `[${validateCommonMetaStoneData.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!data) { throw new Error(`data required (E: c50ac422af4501b72af12481fbd4961e)`); }\n const errors: string[] = [];\n\n // we need to be careful here. we have two different \"data\" objects: 1)\n // the metastone's data, and 2) the metastone's targetData.\n\n // first validate 1) the metastone's data itself (barring the\n // targetData)\n const { targetData, timestamp } = data;\n\n // timestamp is required\n const timestampInfo = getTimestampInfo({ timestamp });\n if (!timestampInfo.valid) {\n errors.push(`invalid timestampInTicks. should be valid ticks number. (E: 7e381ed5b0c8486b90cfd37676da3626)`);\n }\n\n const {\n tjpGib: targetTjpGib,\n n: targetN,\n timestamp: targetTimestamp,\n } =\n targetData;\n\n // target tjpGib\n if (targetTjpGib) {\n if (targetTjpGib === 'undefined') {\n // target had no tjpgib\n } else {\n const tjpGibValidationErrors = validateGib({ gib: targetTjpGib }) ?? [];\n if (tjpGibValidationErrors.length > 0) {\n errors.push(`invalid data (targetTjpGib). validation errors: ${tjpGibValidationErrors} (E: d216b12eb75544ef8c5ffb27cd132e2e)`);\n }\n }\n }\n\n // target n\n if (typeof targetN !== 'number') {\n errors.push(`invalid n. should be valid integer. if target.data.n is falsy, targetN should be -1 (E: 8f234967b388ad80776c8054d71fbc23)`);\n }\n\n // target timestamp (optional)\n if (targetTimestamp) {\n if (targetTimestamp === 'undefined') {\n // target had no timestamp\n } else {\n const targetTimestampInfo = getTimestampInfo({ timestamp: targetTimestamp });\n if (!targetTimestampInfo.valid) {\n errors.push(`invalid targetTimestamp. emsg: ${targetTimestampInfo.emsg} (E: c15d4fd2a2b74a0fab3223e83d954379)`);\n }\n }\n\n }\n const timestampDate = new Date(timestamp);\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function validateCommonMetaStoneRel8ns({\n rel8ns,\n}: {\n rel8ns?: MetaStoneRel8ns_V1,\n}): string[] {\n const lc = `[${validateCommonMetaStoneRel8ns.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!rel8ns) { throw new Error(`rel8ns required (E: 7737ae550e2347e68c67b715c1221393)`); }\n const errors: string[] = [];\n\n // basic rel8ns validation\n const intrinsicErrors = validateRel8nsIntrinsically({ rel8ns: rel8ns ?? {} }) ?? [];\n if (intrinsicErrors.length > 0) {\n errors.push(`invalid rel8ns intrinsically. errors: ${intrinsicErrors.join('|')}. (E: abc91753f0f946afa0a3ea2c1917960f)`);\n }\n\n // [META_STONE_TARGET_REL8N_NAME]: IbGibAddr[];\n // all metastones should have exactly 1 targetAddr\n const targetAddrs = rel8ns[META_STONE_TARGET_REL8N_NAME] ?? [];\n if (targetAddrs.length === 0) {\n errors.push(`invalid metastone rel8ns. should have exactly 1 rel8nName ${META_STONE_TARGET_REL8N_NAME}. has 0. (E: 8181652da9e89613e204d245db12d723)`);\n } else if (targetAddrs.length > 1) {\n errors.push(`invalid metastone rel8ns. should have exactly 1 rel8nName ${META_STONE_TARGET_REL8N_NAME}. has ${targetAddrs.length}. (E: 2318047c6fea482d9f53febe02cf8912)`);\n }\n\n // [META_STONE_TARGET_TJP_REL8N_NAME]?: IbGibAddr[];\n // optional rel8n, should have 0 or 1\n // if we want to get picky, we could check to make sure it is a tjpAddr\n let targetTjpAddrs = rel8ns[META_STONE_TARGET_TJP_REL8N_NAME] ?? [];\n if (targetTjpAddrs.length > 1) {\n errors.push(`invalid metastone rel8ns. should have 0 or 1 rel8nName ${META_STONE_TARGET_TJP_REL8N_NAME}. has ${targetTjpAddrs.length}. (E: 34a8ae53825f46caa7ad024a64400db2)`)\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * performs validation on the ib, data and rel8ns, as well as validates the\n * ibgib intrinsically (i.e. ensures the gib hash is correct)\n * @returns errors array if any found, otherwise undefined (if no errors)\n */\nexport async function validateCommonMetaStoneIbGib({\n ibGib,\n}: {\n ibGib: MetaStoneIbGib_V1,\n}): Promise<string[] | undefined> {\n const lc = `[${validateCommonMetaStoneIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f32249d08105b997871a06cdee006311)`); }\n const intrinsicErrors: string[] = await validateIbGibIntrinsically({ ibGib: ibGib }) ?? [];\n\n if (!ibGib.data) { throw new Error(`MetaStoneIbGib.data required (E: 96432cf4f919d339277d9a1c61ea4264)`); }\n\n // validate ib happens in parse...if only i had a memory...\n const ibErrors: string[] = [];\n try {\n const { atom, tjpGib, n, timestampInTicks } =\n parseMetaStoneIb({ ib: ibGib.ib });\n } catch (error) {\n ibErrors.push(extractErrorMsg(error));\n }\n\n const dataErrors = validateCommonMetaStoneData({ data: ibGib.data });\n const rel8nsErrors = validateCommonMetaStoneRel8ns({ rel8ns: ibGib.rel8ns });\n\n const result = [\n ...(intrinsicErrors ?? []),\n ...(ibErrors ?? []),\n ...(dataErrors ?? []),\n ...(rel8nsErrors ?? []),\n ];\n if (result.length > 0) {\n return result;\n } else {\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * validates the given `data` and builds the ib based on that data.\n *\n * _NOTE: This is **NOT** the function to use to build a metastone based a target ibgib._\n *\n * @returns ib shaped for metastone (atow 11/2023 has tjpGib,n,timestampInTicks)\n */\nexport function getMetaStoneIb({\n data,\n classname,\n}: {\n data: MetaStoneData_V1,\n classname?: string,\n}): Ib {\n const lc = `[${getMetaStoneIb.name}]`;\n try {\n const validationErrors = validateCommonMetaStoneData({ data });\n if (validationErrors.length > 0) { throw new Error(`invalid MetaStone data: ${validationErrors} (E: ac642cc5915f0fc0508cb2fb728c86fa)`); }\n if (classname) {\n if (logalot) { console.log(`${lc} classname not required. no big deal that it is provided here. (I: db4d41471cb976795afd3fa89f8cb823)`); }\n }\n\n // we need to be careful here. we have two different \"data\" objects: 1)\n // the metastone's data, and 2) the metastone's targetData.\n\n // these are validated in common data\n const targetTimestamp = data.targetData.timestamp;\n const targetTimestampInTicks = !!targetTimestamp && targetTimestamp !== 'undefined' ?\n getTimestampInTicks(targetTimestamp) :\n DEFAULT_META_STONE_TIMESTAMP;\n\n return `${META_STONE_ATOM} ${data.targetData.tjpGib} ${data.targetData.n} ${targetTimestampInTicks}`;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Current schema is `${META_STONE_ATOM} ${data.targetData.tjpGib} ${data.targetData.n} ${targetTimestampInTicks}`;\n *\n * NOTE this ib is space-delimited\n */\nexport function parseMetaStoneIb({\n ib,\n}: {\n ib: Ib,\n}): MetaStoneIbInfo {\n const lc = `[${parseMetaStoneIb.name}]`;\n try {\n if (!ib) { throw new Error(`MetaStone ib required (E: 8e74e098d7aeef52d3952e35150d83ed)`); }\n\n const validationErrors = validateCommonMetaStoneIb({ ib });\n if (validationErrors.length > 0) { throw new Error(`invalid ib. validationErrors: ${validationErrors} (E: a6107f62200eb943e523f70f51300623)`); }\n\n const pieces = ib.split(' ');\n\n return {\n atom: pieces[0],\n tjpGib: pieces[1],\n n: Number.parseInt(pieces[2]),\n timestampInTicks: pieces[3],\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * metastone ibgibs are for things like helping to keep track of the latest\n * ibgib in a timeline (similar to the HEAD pointer in e.g. git).\n *\n * @returns true if `addr` is for a metastone ibgib, else false\n */\nexport function isMetaStone({\n addr,\n ibGib,\n}: {\n addr?: IbGibAddr,\n ibGib?: IbGib_V1,\n}): boolean {\n // ignore edge case of checking if both are provided that they both should\n // be equal.\n\n addr ||= getIbGibAddr({ ibGib });\n if (!addr) { throw new Error(`either addr or ibGib required. (E: 372b2574d5a9fac298119beed9f6e223)`); }\n return addr.startsWith(`${META_STONE_ATOM} `);\n}\n\n/**\n * factory function that generates a metastone (constant) ibgib based on the\n * given `ibGib`.\n */\nexport async function newUpMetaStone({\n targetIbGib,\n}: {\n targetIbGib: IbGib_V1,\n}): Promise<MetaStoneIbGib_V1> {\n const lc = `[${newUpMetaStone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: d846313065c89c89e4b5afa2df2b7123)`); }\n\n const targetAddr = getIbGibAddr({ ibGib: targetIbGib });\n const targetTjpAddr = getTjpAddr({ ibGib: targetIbGib, defaultIfNone: \"incomingAddr\" })!;\n\n let metaStoneData: MetaStoneData_V1;\n const metaStoneRel8ns: MetaStoneRel8ns_V1 = {\n [META_STONE_TARGET_REL8N_NAME]: [targetAddr],\n [META_STONE_TARGET_TJP_REL8N_NAME]: [targetTjpAddr],\n };\n\n // const targetGibInfo = getGibInfo({ ibGibAddr: targetAddr });\n if (!targetIbGib.gib) { throw new Error(`(UNEXPECTED) targetIbGib.gib falsy? (E: 28eaa8a799021dadd87b043711aee826)`); }\n /**\n * * if the targetIbGib is the tjp, then its gib is the tjpGib.\n * * if the targetIbGib has a tjp, then gibInfo.tjpGib is what we want.\n * * if the targetIbGib is a stone, then we pretend that it is the\n * tjpGib (any stone might one day be raised up & come to life)\n */\n const targetTjpGib = targetIbGib.data?.isTjp ?\n targetIbGib.gib :\n getGibInfo({ ibGibAddr: targetAddr }).tjpGib ?? targetIbGib.gib;\n\n if (targetTjpGib === GIB) { throw new Error(`cannot create metastone for primitive ibgib (E: 2887e8ef83381a0698256b7bc7531826)`); }\n\n const metaStoneTimestampDate = new Date();\n /**\n * timestamp for the metastone itself (not the target.data.timestamp)\n */\n const metaStoneTimestamp = getTimestamp(metaStoneTimestampDate);\n const metaStoneTimestampMs = metaStoneTimestampDate.getMilliseconds();\n\n if (targetIbGib.data) {\n if (isBinary({ ibGib: targetIbGib })) {\n // binary data is just a uint8array\n metaStoneData = {\n targetData: {\n n: -1,\n tjpGib: targetTjpGib,\n },\n timestamp: metaStoneTimestamp,\n timestampMs: metaStoneTimestampMs,\n };\n } else {\n metaStoneData = {\n targetData: {\n n: targetIbGib.data.n ?? DEFAULT_META_STONE_N,\n tjpGib: targetTjpGib,\n timestamp: targetIbGib.data.timestamp ?? DEFAULT_META_STONE_TIMESTAMP,\n },\n timestamp: metaStoneTimestamp,\n timestampMs: metaStoneTimestampMs,\n }\n if (targetIbGib.data?.isTjp) { metaStoneData.targetData.isTjp = true; }\n }\n } else {\n // no target data\n metaStoneData = {\n targetData: {\n n: DEFAULT_META_STONE_N,\n tjpGib: targetTjpGib,\n },\n timestamp: metaStoneTimestamp,\n timestampMs: metaStoneTimestampMs,\n }\n }\n\n // now that we have the data, we can build the ib\n const metaStoneIb = getMetaStoneIb({ data: metaStoneData });\n\n // now that we have the data, rel8ns, and the ib, we can create the\n // stone (which is a constant ibgib).\n const metaStoneIbGib = await constantIbGib<MetaStoneData_V1, MetaStoneRel8ns_V1>({\n parentPrimitiveIb: META_STONE_ATOM,\n ib: metaStoneIb,\n data: metaStoneData,\n rel8ns: metaStoneRel8ns,\n }) as MetaStoneIbGib_V1;\n\n if (logalot) {\n console.log(`${lc} metaStoneIbGib... (I: 2b16197478488b329246d22d2dc41423)`);\n console.dir(metaStoneIbGib);\n }\n\n return metaStoneIbGib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "export const WITNESS_ATOM = 'witness';\nexport const WITNESS_ARG_METADATA_STRING = 'witness_arg';\nexport const WITNESS_RESULT_METADATA_STRING = 'witness_result';\n\nexport const WITNESS_CONTEXT_REL8N_NAME = 'context';\n", "import {\n clone, delay, getExpirationUTCString, getTimestampInTicks,\n getUUID, isExpired, pretty, extractErrorMsg,\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { TransformResult, Ib, IbGibAddr, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbAndGib, getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { GIB, IBGIB_DELIMITER } from '@ibgib/ts-gib/dist/V1/constants.mjs'\nimport { IbGib_V1, Rel8n } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { Factory_V1 as factory } from '@ibgib/ts-gib/dist/V1/factory.mjs';\nimport { rel8 } from '@ibgib/ts-gib/dist/V1/transforms/rel8.mjs';\nimport { fork } from '@ibgib/ts-gib/dist/V1/transforms/fork.mjs';\nimport { getGib, getGibInfo, } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\nimport { APP_REL8N_NAME } from '../app/app-constants.mjs';\nimport {\n GetIbGibOpts, GetIbGibResult, PutIbGibOpts, PutIbGibResult, DeleteIbGibOpts,\n DeleteIbGibResult, SpecialIbGibType, IbGibTimelineUpdateInfo,\n} from '../../common/other/other-types.mjs';\nimport {\n getRootIb, getSpecialConfigKey, getSpecialIbGibIb,\n getSpecialTypeFromIb, getTjpAddr, isSpecial, isTjp_Naive, tagTextToIb\n} from '../../common/other/ibgib-helper.mjs';\nimport { TagData_V1, TagIbGib_V1 } from '../../common/tag/tag-types.mjs';\nimport { BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY, BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY, BOOTSTRAP_IBGIB_ADDR } from './bootstrap/bootstrap-constants.mjs';\nimport {\n SpaceLockScope, IbGibSpaceLockIbGib, SpaceId, IbGibSpaceLockOptions, TxId,\n IbGibSpaceResultIbGib, IbGibSpaceResultData, IbGibSpaceResultRel8ns, SpaceType, SpaceSubtype, VALID_SPACE_TYPES, VALID_SPACE_SUBTYPES, IbGibSpaceData,\n IbGibSpaceOptionsCmd, IbGibSpaceOptionsCmdModifier,\n} from './space-types.mjs';\nimport { getAppIb, } from '../app/app-helper.mjs';\nimport { AppData_V1, AppIbGib_V1 } from '../app/app-types.mjs';\nimport { DEFAULT_CHAT_APP_DATA_V1, DEFAULT_CHAT_APP_REL8NS_V1 } from '../app/chat-app/chat-app-types.mjs';\nimport { DEFAULT_RAW_APP_DATA_V1, DEFAULT_RAW_APP_REL8NS_V1 } from '../app/raw-app/raw-app-types.mjs';\nimport { DEFAULT_TODO_APP_DATA_V1, DEFAULT_TODO_APP_REL8NS_V1, DEFAULT_UUID_TODO_APP } from '../app/todo-app/todo-app-types.mjs';\nimport { IbGibSpaceAny } from './space-base-v1.mjs';\nimport { RootData } from '../../common/root/root-types.mjs';\nimport { IbGibCacheService } from '../../common/cache/cache-types.mjs';\nimport {\n DEFAULT_MAX_DELAY_MS_RETRY_LOCK_ACQUIRE,\n DEFAULT_MAX_DELAY_RETRY_LOCK_ACQUIRE_ATTEMPTS, DEFAULT_SECONDS_VALID_LOCAL,\n DEFAULT_TX_ID_LENGTH, IBGIB_SPACE_NAME_DEFAULT, SPACE_ATOM,\n SPACE_LOCK_IB_TERM, SYNC_SPACE_REL8N_NAME,\n} from './space-constants.mjs';\nimport { DEFAULT_TAG_DESCRIPTION, DEFAULT_TAG_ICON, TAG_REL8N_NAME } from '../../common/tag/tag-constants.mjs';\nimport {\n DEFAULT_ROOT_DESCRIPTION, DEFAULT_ROOT_ICON, DEFAULT_ROOT_REL8N_NAME,\n DEFAULT_ROOT_TEXT, ROOT_REL8N_NAME\n} from '../../common/root/root-constants.mjs';\nimport { ARCHIVE_REL8N_NAME, TRASH_REL8N_NAME } from '../../common/other/other-constants.mjs';\nimport { validateBootstrapIbGib } from './bootstrap/bootstrap-helper.mjs';\nimport { BootstrapData, BootstrapIbGib, BootstrapRel8ns } from './bootstrap/bootstrap-types.mjs';\nimport { newUpMetaStone } from '../../common/meta-stone/meta-stone-helper.mjs';\nimport { WITNESS_ATOM } from '../witness-constants.mjs';\n\nlet logalot = GLOBAL_LOG_A_LOT;\n\n\n/**\n * Two spaces can be equivalent if they point to the same area.\n *\n * @returns true if the \"same\" space\n */\nexport function isSameSpace({\n a,\n b,\n mustHaveSameData,\n}: {\n a: IbGibSpaceAny,\n b: IbGibSpaceAny,\n /**\n * If true, then only same exact internal data will do.\n * Be careful if they have last modified timestamps.\n */\n mustHaveSameData?: boolean,\n}): boolean {\n const lc = `[${isSameSpace.name}]`;\n\n if (!a) { throw new Error(`${lc} a is falsy`) };\n if (!b) { throw new Error(`${lc} b is falsy`) };\n\n // try by data\n if (a.data && JSON.stringify(a.data) === JSON.stringify(b.data)) {\n return true;\n } else if (mustHaveSameData) {\n return false;\n }\n\n // try by uuid\n if (a.data?.uuid && b.data?.uuid) { return a.data!.uuid === b.data!.uuid; }\n\n // try by tjp\n if (a.rel8ns?.tjp?.length === 1 && b.rel8ns?.tjp?.length === 1) {\n return a.rel8ns.tjp[0] === b.rel8ns.tjp[0];\n }\n\n // try by gib (last resort), can't both be falsy or primitive (maybe overkill)\n if (!a.gib && !b.gib) {\n throw new Error(`${lc} Invalid spaces. both a.gib and b.gib are falsy, neither has uuid and neither has tjp.`);\n }\n if (a.gib === GIB && b.gib === GIB) { throw new Error(`${lc} both a and b are primitives`); }\n return a.gib === b.gib;\n}\n\n/**\n * wrapper for dealing with a space.\n *\n * @returns legacy `GetIbGibResult`\n */\nexport async function getFromSpace({\n addr,\n addrs,\n isDna,\n space,\n force,\n}: GetIbGibOpts): Promise<GetIbGibResult> {\n let lc = `[${getFromSpace.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!space) { throw new Error(`space required. (E: 4d188d6c863246f28aa575753a052304)`); }\n if (!addr && (addrs ?? []).length === 0) { throw new Error(`addr or addrs required. (E: 1a0b92564ba942f1ba91a089ac1a2125)`); }\n\n if (addr && (addrs?.length ?? 0) > 0) {\n console.warn(`${lc} both addr and addrs provided, but supposed to be used one or the other. (W: 87226c2ac50e4ea28211334a7b58782f)`);\n if (!addrs!.includes(addr)) { addrs!.push(addr); }\n }\n addrs = (addrs ?? []).length > 0 ? addrs : [addr!];\n\n const argGet = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'get',\n ibGibAddrs: addrs,\n isDna,\n },\n });\n const result = await space.witness(argGet);\n if (result?.data?.success) {\n if (logalot) { console.log(`${lc} got.`) }\n return {\n success: true,\n ibGibs: result.ibGibs,\n rawResultIbGib: result,\n }\n } else {\n if (logalot) { console.log(`${lc} didn't get.`) }\n return {\n success: false,\n errorMsg: result.data?.errors?.join('|') || `${lc} something went wrong. addrs: ${addrs!.join('\\n')} (E: b9e9d5ce0cde4122bfb74f7688db85e0)`,\n rawResultIbGib: result,\n }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return { errorMsg: error.message, }\n }\n}\n\n/**\n * Wrapper for saving ibgib in a given space.\n *\n * ## warnings\n *\n * The given space doesn't have to work this way.\n * This is a convenience for me ATOW.\n */\nexport async function putInSpace({\n ibGib,\n ibGibs,\n isDna,\n force,\n space,\n}: PutIbGibOpts): Promise<PutIbGibResult> {\n const lc = `[${putInSpace.name}]`;\n try {\n if (!ibGib && (ibGibs ?? []).length === 0) { throw new Error(`ibGib or ibGibs required. (E: e59c4de3695f4dd28c8fe82dbb9c4e90)`); }\n if (!space) { throw new Error(`space required. (E: dd0b7189c67c43c586b905a8ed6f51c9)`); }\n\n if (ibGib && (ibGibs ?? []).length > 0) {\n console.warn(`${lc} Both ibGib and ibGibs is assigned, whereas this is intended to be exclusive one or the other. (W: 4c797835b620445f88e4cba6b5aa3460)`)\n if (!ibGibs!.some(x => x.gib === ibGib.gib)) {\n ibGibs = ibGibs!.concat([ibGib]);\n }\n }\n ibGibs = ibGibs ?? [ibGib!];\n\n if (logalot) { console.log(`${lc} ibGibs.length: ${ibGibs.length}`) }\n const argPutIbGibs = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'put', force, isDna,\n ibGibAddrs: ibGibs.map(x => getIbGibAddr({ ibGib: x })),\n },\n ibGibs: ibGibs.concat(),\n });\n const resPutIbGibs = await space.witness(argPutIbGibs);\n if (resPutIbGibs.data?.success) {\n if ((resPutIbGibs.data!.warnings ?? []).length > 0) {\n resPutIbGibs.data!.warnings!.forEach((warning: string) => console.warn(`${lc} ${warning}`));\n }\n return { success: true }\n } else {\n const errorMsg = resPutIbGibs?.data?.errors?.length > 0 ?\n `Error(s) putting in local space:\\n${resPutIbGibs.data.errors.join('\\n')}` :\n '(UNEXPECTED) unknown error putting ibGibs (E: 3d7426d4527243b79c5e55eb25f3fa73)';\n throw new Error(errorMsg);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return { errorMsg: error.message, }\n }\n}\n\n/**\n * Wrapper for removing ibgib from the a given space, else the current space.\n */\nexport async function deleteFromSpace({\n addr,\n isDna,\n space,\n}: DeleteIbGibOpts): Promise<DeleteIbGibResult> {\n let lc = `[${deleteFromSpace.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: 40ab3b51e91c4b5eb4f215baeefbcef0)`); }\n if (!space.data) { throw new Error(`space.data required. (E: 0d02c8e85ee143b8bd6a1a1db0d9af1b)`); }\n lc = `${lc}[${space.data.name || 'noname?'}][${space.data.uuid || 'nouuid?'}]`;\n\n const argDel = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'delete',\n ibGibAddrs: [addr],\n isDna,\n },\n });\n const result = await space.witness(argDel);\n if (result.data?.success) {\n return { success: true, }\n } else {\n if (result.data?.warnings?.length > 0) {\n console.warn(`${lc} warnings with delete (${addr}): ${result.data!.warnings!.join('|')}`);\n }\n if (result.data?.addrs?.length > 0) {\n console.warn(`${lc} partial addrs deleted: ${result.data!.addrs!.join('|')}`);\n }\n const errorMsg: string = result.data?.errors?.join('|') || `${lc} something went wrong (E: e397fd09b4a746a3ba3305d6ea0893cb)`;\n if (errorMsg.includes('File does not exist')) {\n if (logalot) { console.log(`${lc} tried to delete file that does not exist. (I: cb5d1348ccbc58bf0bfc95f3006f1e22)`); }\n }\n return { errorMsg }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return { errorMsg: error.message };\n }\n}\n\n/**\n * Convenience function for persisting a transform result, which has\n * a newIbGib and optionally intermediate ibGibs and/or dnas.\n *\n * it persists these ibgibs into the given space, else the current space.\n */\nexport async function persistTransformResult({\n resTransform,\n space,\n force,\n}: {\n resTransform: TransformResult<IbGib_V1>,\n space: IbGibSpaceAny,\n force?: boolean,\n}): Promise<void> {\n const lc = `[${persistTransformResult.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: dc6835614ff1a1b82b179225023ae823)`); }\n if (!space) { throw new Error(`space required. (E: cf94f1d74f1c4561bb88025a2095965b)`); }\n\n const { newIbGib, intermediateIbGibs, dnas } = resTransform;\n const ibGibs = [newIbGib, ...(intermediateIbGibs || [])];\n const argPutIbGibs = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'put', force,\n ibGibAddrs: ibGibs.map(x => getIbGibAddr({ ibGib: x })),\n },\n ibGibs: ibGibs.concat(),\n });\n const resPutIbGibs = await space.witness(argPutIbGibs);\n if (resPutIbGibs.data?.success) {\n if (resPutIbGibs.data!.warnings?.length > 0) {\n resPutIbGibs.data!.warnings!.forEach((warning: string) => console.warn(`${lc} ${warning}`));\n }\n } else {\n const errorMsg = resPutIbGibs?.data?.errors?.length > 0 ?\n resPutIbGibs.data.errors.join('\\n') :\n 'unknown error putting ibGibs';\n throw new Error(errorMsg);\n }\n\n if (dnas?.length ?? 0 > 0) {\n const argPutDnas = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'put', isDna: true, force,\n ibGibAddrs: dnas!.map(x => getIbGibAddr({ ibGib: x })),\n },\n ibGibs: dnas!.concat(),\n });\n const resPutDnas = await space.witness(argPutDnas);\n if (resPutDnas.data?.success) {\n if (resPutDnas.data!.warnings?.length > 0) {\n resPutDnas.data!.warnings!.forEach((warning: string) => console.warn(`${lc} ${warning}`));\n }\n } else {\n const errorMsg = resPutDnas?.data?.errors?.length > 0 ?\n resPutDnas.data.errors.join('\\n') :\n 'unknown error putting dna ibGibs';\n throw new Error(errorMsg);\n }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete. (I: dc6835614ff1a1b82b179225023ae823)`); }\n }\n}\n\nexport async function getSpecialRel8dIbGibs<TIbGib extends IbGib_V1 = IbGib_V1>({\n type,\n rel8nName,\n space,\n}: {\n type: SpecialIbGibType,\n rel8nName: string,\n space: IbGibSpaceAny,\n}): Promise<TIbGib[]> {\n const lc = `[${getSpecialRel8dIbGibs.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: f73868a952ac4181a4f90ee6d86cacf3)`); }\n\n let special = await getSpecialIbGib({ type, space });\n if (!special) { throw new Error(`couldn't get special (${type}) (E: a65bef190416479697605be486846731)`) };\n const rel8dAddrs = special.rel8ns ? special.rel8ns[rel8nName] || [] : [];\n const rel8dIbgibs: TIbGib[] = [];\n for (let i = 0; i < rel8dAddrs.length; i++) {\n const addr = rel8dAddrs[i];\n let resGet = await getFromSpace({ addr, space });\n if (resGet.success && resGet.ibGibs?.length === 1) {\n rel8dIbgibs.push(resGet.ibGibs[0] as TIbGib);\n } else {\n throw new Error(`couldn't get addr: ${addr} (E: 76ef256ee80149ab860c5786484b0e89)`);\n }\n }\n return rel8dIbgibs;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Gets one of the app's special ibGibs, e.g., TagsIbGib.\n *\n * When initializing tags, this will generate some boilerplate tags.\n * I'm going to be doing roots here also, and who knows what else, but each\n * one will have its own initialize specifics.\n *\n * @param initialize initialize (i.e. create) ONLY IF IbGib not found. Used for initializing app (first run).\n *\n * @see {@link createSpecial}\n * @see {@link createSpecial_Tags}\n */\nexport async function getSpecialIbGib({\n type,\n initialize,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n fnGetInitializing,\n fnSetInitializing,\n dontWarnIfNotExist,\n}: {\n type: SpecialIbGibType,\n initialize?: boolean,\n space: IbGibSpaceAny,\n /**\n * Only required if `initialize` is true.\n */\n zeroSpace?: IbGibSpaceAny,\n /**\n * Only required if `initialize` is true.\n */\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n /**\n * Only required if `initialize` is true.\n */\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n /**\n * Initialization lock getter function.\n */\n fnGetInitializing?: () => boolean,\n /**\n * Initialization lock setter function.\n *\n * Because we don't want to initialize while we're initializing.\n */\n fnSetInitializing?: (x: boolean) => void,\n /**\n * if true, won't warn about non-existent/non-initialized things.\n * useful if you are just checking to see if a special ibgib exists.\n */\n dontWarnIfNotExist?: boolean,\n}): Promise<IbGib_V1 | null> {\n const lc = `[${getSpecialIbGib.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: d454b31d58764a9bb9c4e47fb5ef38b5)`); }\n\n let key = getSpecialConfigKey({ type });\n let addr = await getConfigAddr({\n key, space,\n dontWarn: dontWarnIfNotExist || !!initialize // dont warn if we're initializing\n });\n\n if (!addr) {\n if (initialize && (!fnGetInitializing || !fnSetInitializing)) { throw new Error(`if initialize, you must provide fnGetInitializeLock & fnSetInitializeLock. (E: 8eb322625d0c4538be089800882487de)`); }\n if (initialize && !fnGetInitializing!()) {\n fnSetInitializing!(true);\n try {\n if (!zeroSpace) { throw new Error(`zeroSpace required when 'initialize' truthy (E: 8582c92c637f90c9b2dbe0ec8355b523)`); }\n addr = await createSpecial({ type, space, zeroSpace: zeroSpace!, fnBroadcast, fnUpdateBootstrap }) ?? undefined;\n } catch (error) {\n console.error(`${lc} error initializing: ${error.message}`);\n } finally {\n fnSetInitializing!(false);\n }\n }\n if (!addr) {\n if (fnGetInitializing && fnGetInitializing()) {\n console.warn(`${lc} couldn't get addr, but we're still initializing...`);\n return null;\n } else {\n throw new Error(`Special address not in config and couldn't initialize it either. (E: d8ebdc9eaaa640b99cd206f132962c93)`);\n }\n }\n }\n\n if (logalot) { console.log(`${lc} getting addr: ${addr}`); }\n\n let resSpecial = await getFromSpace({ addr, space });\n\n // I'm putting in this check in case we're getting a meta that wasn't\n // saved into the meta folder.\n if (!resSpecial.success) {\n resSpecial = await getFromSpace({ addr, space });\n if (resSpecial.success) {\n console.warn(`${lc} special ibgib was not stored in meta folder...putting in meta folder now for the future (W: e6f5571fd98c449bb2809359be5057cc)`);\n const resPutInMeta = await putInSpace({ ibGib: resSpecial!.ibGibs![0], space });\n if (!resPutInMeta.success) {\n console.warn(`${lc} (UNEXPECTED) tried to put special in meta but success was false? (W: b934b53571c24057af172c790e6a7240)`)\n }\n }\n }\n if (!resSpecial.success) { throw new Error(resSpecial.errorMsg); }\n if (resSpecial.ibGibs?.length !== 1) { throw new Error(`no ibGib in result (E: 3a42abdddc3648e292d63dc45c560064)`); }\n const specialIbGib = resSpecial.ibGibs[0];\n\n // I'm putting this check in here because it's bad not to have the\n // latest special associated with a space. eventually this shouldn't be\n // necessary.\n let resLatest = await getLatestAddrs({ ibGibs: [specialIbGib], space });\n if (resLatest?.data?.success && resLatest.data.addrs?.length === 1) {\n let specialAddr = getIbGibAddr({ ibGib: specialIbGib });\n let latestAddr = resLatest.data.addrs[0];\n if (latestAddr !== specialAddr) {\n console.warn(`${lc} latest addr is not the one associated with the local space.\\nspecialAddr: ${specialAddr}\\nlatestAddr: ${latestAddr} (W: 141b69dc3c414efc9645bb76fcf12df9)`)\n }\n }\n\n return specialIbGib;\n } catch (error) {\n const emsg = `${lc} ${error.message}`;\n /**\n * error code found in preceding try block (just do a find on it).\n */\n const notFoundErrorCode = 'd8ebdc9eaaa640b99cd206f132962c93';\n if (emsg.includes(notFoundErrorCode) && dontWarnIfNotExist) {\n // don't log error, it's expected\n } else {\n console.error(emsg);\n }\n return null;\n }\n}\n\n/**\n * Gets a config addr from the current space via the given key\n * as the space's rel8n name.\n *\n * For example, for `key = tags`, a space may look like:\n *\n * ```json\n * {\n * ib: space xyz,\n * gib: e89ff8a1c4954db28432007615a78952,\n * rel8ns: {\n * past: [space xyz^21cb29cc353f45a491d2b49ff2f130db],\n * ancestor: [space^gib],\n * tags: [tags^99b388355f8f4a979ca30ba284d3a686], // <<< rel8n with name specified by key\n * }\n * }\n * ```\n *\n * @param key config key\n * @returns addr in config if exists, else undefined\n */\nexport async function getConfigAddr({\n key,\n space,\n dontWarn,\n}: {\n key: string,\n space: IbGibSpaceAny,\n /**\n * if true, won't warn about non-existent/non-initialized things.\n * useful if you are just checking to see if a special ibgib exists.\n */\n dontWarn?: boolean,\n}): Promise<string | undefined> {\n const lc = `[${getConfigAddr.name}](${key})`;\n try {\n if (logalot) { console.log(`${lc} getting... (I: 43e7bfc2515d45e5af8767b9a85b248e)`) }\n\n if (!space) { throw new Error(`space required. (E: 4f135d4276e64054ba21aeb9c304ecec)`); }\n\n if (!space.rel8ns) {\n if (logalot || !dontWarn) { console.warn(`${lc} space.rel8ns falsy. (W: 7c642259fbf547dbaa1b2fdf0115f6ef)`); }\n return undefined;\n }\n if (!space.rel8ns[key]) {\n if (logalot || !dontWarn) { console.warn(`${lc} space.rel8ns[${key}] falsy. (W: 3c1c49b9987b45cc96dd78b808f98e91)`); }\n return undefined;\n }\n if (space.rel8ns[key]!.length === 1) {\n if (logalot) { console.log(`${lc} got (I: f13e71b693d5404c9535bda8ff0cc6a9)`); }\n return space.rel8ns![key]![0];\n } else if (space.rel8ns[key]!.length > 1) {\n if (logalot || !dontWarn) { console.warn(`${lc} more than one config addr with ${key} rel8n. (W: 102f63eb74904bcfaac2eaf778043205)`) }\n return space.rel8ns![key]![0];\n } else {\n if (logalot) { console.log(`${lc} didn't find (I: 1163e6ac60194d25b3f24881650edfad)`); }\n // key not found or?\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return undefined;\n }\n}\n\nexport async function setConfigAddr({\n key,\n addr,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n}: {\n key: string,\n addr: string,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n}): Promise<IbGibSpaceAny> {\n const lc = `[${setConfigAddr.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: c28b663c991d44419aef1026cc689636)`); }\n if (!zeroSpace) { throw new Error(`zeroSpace required. (E: d3707ae5265d464891ad216f64be6184)`); }\n\n // rel8 the `addr` to the current space via rel8n named `key`\n // note that since we are replacing the pointer, we include the key\n // in `linkedRel8ns` which will keep only the most recent\n const rel8nsToAddByAddr = { [key]: [addr] };\n const resNewSpace = await rel8({\n src: space.toIbGibDto(),\n dna: false,\n linkedRel8ns: [\"past\", \"ancestor\", key], // we only want the most recent key address\n rel8nsToAddByAddr,\n nCounter: true,\n });\n\n if (!resNewSpace.newIbGib) { throw new Error(`create new space failed.`); }\n\n // persist the new space in both default space and its own space\n // (will actually have the space witness its future self interestingly\n // enough...perhaps should have the new space witness itself instead\n\n // witness in the default zero space\n // in refactoring, may have to make this optional...hmm\n await persistTransformResult({ resTransform: resNewSpace, space: zeroSpace });\n\n // witness in the given space\n await persistTransformResult({ resTransform: resNewSpace, space });\n\n // going to update the bootstrap^gib with the new space address, but first...\n const newSpace = (resNewSpace.newIbGib as IbGibSpaceAny);\n\n // ...must update the original space reference any time we change it.\n // messy atm...\n await space.loadIbGibDto(newSpace);\n\n // ...now update so the proper space (config) loads on next app start\n if (fnUpdateBootstrap) {\n await fnUpdateBootstrap(newSpace);\n } else {\n console.warn(`${lc} fnUpdateBootstrap is falsy. (W: 9fb874de2b19454dac18645e61ac463f)`);\n }\n\n return newSpace;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport async function getCurrentRoot({\n space,\n}: {\n space: IbGibSpaceAny,\n}): Promise<IbGib_V1<RootData> | undefined> {\n const lc = `[${getCurrentRoot.name}]`;\n\n try {\n if (!space) { throw new Error(`space required. (E: f0d546101fba4c169256158114ab3c56)`); }\n\n const roots = await getSpecialIbGib({ type: \"roots\", space });\n if (!roots) { throw new Error(`Roots not initialized. (E: 89b1ba12ed12416aac41cef9fdaf1fc2)`); }\n if (!roots.rel8ns) { throw new Error(`Roots not initialized properly. No rel8ns. (E: 8513a07cf530484db9521a2a3a27b7f6)`); }\n if (!roots.rel8ns.current) { throw new Error(`Roots not initialized properly. No current root. (E: 459c3a007a30486d96fb8d83f696e239)`); }\n if (roots.rel8ns.current.length === 0) { throw new Error(`Invalid Roots: empty current root rel8n. (E: bede5864090440bca01ea7ab7fd107d6)`); }\n if (roots.rel8ns.current.length > 1) { throw new Error(`Invalid Roots: multiple current roots selected. (E: 97561acbf63a48ecaa037697bd26555a)`); }\n\n const currentRootAddr = roots.rel8ns.current[0]!;\n const resCurrentRoot =\n await getFromSpace({ addr: currentRootAddr, space });\n if (resCurrentRoot.ibGibs?.length === 1) {\n return resCurrentRoot.ibGibs![0] as IbGib_V1<RootData>;\n } else {\n throw new Error(`could not get current root. addr: ${currentRootAddr}`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return undefined;\n }\n}\n\nexport async function setCurrentRoot({\n root,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n root: IbGib_V1<RootData>,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<void> {\n const lc = `[${setCurrentRoot.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 7f16e845a80fe95d28923e4170f0c825)`); }\n if (!root) { throw new Error(`root required.`); }\n\n if (!space) { throw new Error(`space required. (E: 186af2731c5342a78b063a0a4346f3db)`); }\n\n const rootAddr = getIbGibAddr({ ibGib: root });\n\n // get the roots and update its \"current\" rel8n\n const roots = await getSpecialIbGib({ type: \"roots\", space });\n if (!roots) { throw new Error(`Roots not initialized. (E: a8232b9afac89d0d189534480b7a9825)`); }\n\n // we'll rel8 current with a linkedRel8n, thus ensuring a maximum of only\n // one rel8d addr (the one we're adding here)\n const rel8nsToAddByAddr = { current: [rootAddr] };\n const resNewRoots = await rel8({\n src: roots,\n dna: false,\n linkedRel8ns: [\"past\", \"ancestor\", \"current\"], // current here ensures only 1 rel8n\n rel8nsToAddByAddr,\n nCounter: true,\n });\n await persistTransformResult({ resTransform: resNewRoots, space });\n\n const configKey = getSpecialConfigKey({ type: \"roots\" });\n const newRoots = resNewRoots.newIbGib;\n const newRootsAddr = getIbGibAddr({ ibGib: newRoots });\n await setConfigAddr({ key: configKey, addr: newRootsAddr, space, zeroSpace, fnUpdateBootstrap });\n await registerNewIbGib({ ibGib: newRoots, space, fnBroadcast, });\n\n // how to let others know roots has changed?\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete. (I: 7f16e845a80fe95d28923e4170f0c825)`); }\n }\n}\n\n/**\n * Every tjp should be related to one of the roots in a space.\n *\n * You should NOT relate every ibgib frame of a given ibGib.\n */\nexport async function rel8ToCurrentRoot({\n ibGib,\n linked,\n rel8nName,\n space,\n fnBroadcast,\n zeroSpace,\n fnUpdateBootstrap,\n}: {\n ibGib: IbGib_V1,\n linked?: boolean,\n rel8nName?: string,\n space: IbGibSpaceAny,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n}): Promise<void> {\n const lc = `[${rel8ToCurrentRoot.name}]`;\n\n try {\n if (!space) { throw new Error(`space required. (E: f2758eab3bb844d2b749515672d9e392)`); }\n if (!ibGib) { throw new Error(`ibGib required (E: f1bfd67754a7271553f4af544d30bc22)`); }\n\n let currentRoot = await getCurrentRoot({ space });\n if (!currentRoot) { throw new Error('currentRoot undefined (E: 5c2d84dafc664808866008f6eb535750'); }\n\n // only relate the tjp to roots and use the latest index ibgib to have\n // the reference to the latest ibgib in the space.\n const tjpAddr = getTjpAddr({ ibGib, defaultIfNone: \"incomingAddr\" });\n const ibGibAddr = getIbGibAddr({ ibGib });\n\n // check to see if it's already rel8d. If so, we're done.\n if (rel8nName && tjpAddr &&\n currentRoot.rel8ns &&\n currentRoot.rel8ns[rel8nName] &&\n currentRoot.rel8ns[rel8nName]!.includes(tjpAddr)) {\n // already rel8d\n return;\n }\n\n rel8nName = rel8nName || DEFAULT_ROOT_REL8N_NAME;\n\n // we only need to add the ibgib itself to the root, not the tjp\n // and not any dependent ibgibs. ...wakka doodle.\n const resNewRoot = await rel8({\n src: currentRoot,\n dna: false,\n linkedRel8ns: linked ? [\"past\", \"ancestor\", rel8nName] : [\"past\", \"ancestor\"],\n rel8nsToAddByAddr: { [rel8nName]: [ibGibAddr] },\n nCounter: true,\n });\n await persistTransformResult({ resTransform: resNewRoot, space });\n const newRoot = resNewRoot.newIbGib as IbGib_V1<RootData>;\n const newRootAddr = getIbGibAddr({ ibGib: newRoot });\n if (logalot) { console.log(`${lc} updating _currentRoot root. newRootAddr: ${newRootAddr}`); }\n await registerNewIbGib({ ibGib: newRoot, space, fnBroadcast, });\n await setCurrentRoot({ root: newRoot, space, zeroSpace, fnUpdateBootstrap, fnBroadcast });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return;\n }\n}\n\n/**\n * used atow (11/2023) for latest ibgib indexing.\n * i dont know any use cases right now to use this explicitly.\n * used in {@link registerNewIbGib}\n */\nexport async function createAndSaveNewMetaStone({\n targetIbGib,\n space,\n}: {\n targetIbGib: IbGib_V1,\n space: IbGibSpaceAny,\n}): Promise<void> {\n const lc = `[${createAndSaveNewMetaStone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 291638372117dbc983b4b7cbd8f52123)`); }\n const metaStone = await newUpMetaStone({ targetIbGib });\n const resPutMetaStone = await putInSpace({ ibGib: metaStone, space });\n if (!resPutMetaStone.success) { throw new Error(`error putting metaStone in space. error: ${resPutMetaStone.errorMsg ?? '[unknown error (E: 45f700f4f1ff463ca8f5353c8e796ac7)]'} (E: 4c25379e66365055e3e423561a7d6123)`); }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Used for tracking tjpAddr -> latest ibGibAddr.\n *\n *\n * Call this when you create a new ibGib.\n *\n * Need to put this in another service at some point, but crunch crunch\n * like pacman's lunch.\n *\n * ## notes\n *\n * * atow (11/2023)the new implementation of this creates a metastone for\n * the incoming ibgib and broadcasts if a timeline is involved.\n * * double-checks if previous latest addr is actually older.\n */\nexport async function registerNewIbGib({\n ibGib,\n space,\n fnBroadcast,\n}: {\n ibGib: IbGib_V1,\n space: IbGibSpaceAny,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<void> {\n let lc = `[${registerNewIbGib.name}]`;\n let initialLogalot = logalot;\n // logalot = true;\n try {\n const ibGibAddr: IbGibAddr = getIbGibAddr({ ibGib });\n lc = `${lc}[${ibGibAddr}]`;\n\n if (!space) { throw new Error(`space required. (E: ea0c03256f8a4062b460aa4de11f1e3e)`); }\n\n if (logalot) { console.log(`${lc} starting...`); }\n\n // we only need to register as latest if there is a timeline involved.\n let gibInfo = getGibInfo({ ibGibAddr });\n if (!gibInfo.tjpGib && !ibGib.data?.isTjp) {\n if (logalot) { console.log(`${lc} incoming ibGib has no timeline, so no broadcast. still going to create a metastone for it and return early. (I: 649752e3b1be0e0ceb078e0ec2a84f23)`); }\n await createAndSaveNewMetaStone({ targetIbGib: ibGib, space });\n return; /* <<<< returns early */\n }\n\n let tjpAddr = getTjpAddr({ ibGib, defaultIfNone: 'undefined' });\n if (!tjpAddr) {\n // get tjp information. used in multiple places in the rest of this fn\n let tjp = ibGib.data?.isTjp ? ibGib : await getTjpIbGib({ ibGib, space });\n if (!tjp) {\n console.warn(`${lc} tjp not found for ${ibGibAddr}? Should at least just be the ibGib's address itself. (W: d9b570e5bf6d4312bc7d9249ed3bbaad)`);\n tjp = ibGib;\n }\n tjpAddr = getIbGibAddr({ ibGib: tjp });\n }\n if (!tjpAddr) { throw new Error(`(UNEXPECTED) tjpAddr falsy? should be guaranteed at this point. (E: 39aafb70bc3c6d70b6d2cf8882311223)`); }\n\n /**\n * either we're adding the given ibGib, replacing the existing with the\n * ibGib, or doing nothing. We can do this with our current vars in a\n * closure at this point.\n */\n const replaceLatest: () => Promise<void> = async () => {\n if (logalot) { console.log(`${lc} adding/replacing latest. tjp: ${tjpAddr} (I: 7f848da003a2436089fd6f044d96bb42)`); }\n\n await createAndSaveNewMetaStone({ targetIbGib: ibGib, space });\n\n // broadcast if available\n if (fnBroadcast) {\n if (logalot) { console.log(`${lc} fnBroadcast is true...(I: 0e3b561fb5474a0598b5c6d698df5e1f)`) }\n // queue it up in event loop, as this spins off\n setTimeout(() => {\n if (logalot) { console.log(`${lc} broadcasting... (I: 61785937be0346f0959d476d7267ab24)`) }\n fnBroadcast({\n ib: 'IbGibTimelineUpdateInfo',\n tjpAddr,\n latestAddr: ibGibAddr,\n latestIbGib: ibGib\n });\n });\n }\n }\n\n if (ibGib.data?.isTjp) {\n // this is the temporal junction point, so we know it's new...but\n // perhaps it has already been registered? regardless, shouldn't be\n // a big deal if multiple metastones are made for the same tjp, and\n // there is a tradeoff here. either we spend extra processing time\n // each time to check to be sure there isn't already one there\n // (rare) or we just live with the possibility of some having\n // multiple metastones created (also rare).\n if (logalot) { console.log(`${lc} ibGib.data?.isTjp true. replacingLatest and returning early. (I: 02c626e006668291550e278b461bcb23)`); }\n await replaceLatest();\n return; /* <<<< returns early */\n }\n\n // there is a tjp/timeline involved. check to see if the new ibgib is\n // actually new.\n if (logalot) { console.log(`${lc} ibGib.data?.isTjp is falsy. (I: 84940e3a9eff869c9474b7b92b864b23)`); }\n const resLatest = await getLatestAddrs({ ibGibs: [ibGib], space, });\n if (!resLatest.data) { throw new Error(`(UNEXPECTED) resLatest.data falsy? (E: af3d3914d96adcc5525e4db83cc5d223)`); }\n let { success, latestAddrsMap } = resLatest.data;\n if (!success) {\n let { errors } = resLatest.data;\n errors ??= ['[unknown error (E: 344857f1853641aa842cea3931f90428)]'];\n throw new Error(`resLatest.success falsy. errors: ${pretty(errors)}. addr: ${ibGibAddr} (E: b66721da6e1ef9ac4f4089e86c059323)`);\n }\n\n // #region validate expectations of resulting latestAddrsMap\n if (!latestAddrsMap) { throw new Error(`(UNEXPECTED) latestAddrsMap falsy but success truthy? (E: c34caff7a256503575ff3ff491dec823)`); }\n let keysLatestAddrsMap = Object.keys(latestAddrsMap);\n if (keysLatestAddrsMap.length !== 1) { throw new Error(`(UNEXPECTED) latestAddrsMap size isn't 1? (E: e11ffc2c18d473745b5bbfc3fe5e3a23)`); }\n if (keysLatestAddrsMap[0] !== ibGibAddr) { throw new Error(`(UNEXPECTED) latestAddrsMap has 1 key (correct) but the key isn't the incoming ibGibAddr? (incorrect). incoming ibGibAddr: ${ibGibAddr}. key found: ${keysLatestAddrsMap[0]} (E: 82d79a95d2d7de90eae9db571a360f23)`); }\n // #endregion validate expectations of resulting latestAddrsMap\n\n\n if (logalot) {\n console.log(`${lc} valid latestAddrsMap. console.dir(latestAddrsMap)... (I: e24de41622cabbef375172c3017cfd23)`);\n console.dir(latestAddrsMap);\n }\n const existingLatestAddr = latestAddrsMap[ibGibAddr];\n if (existingLatestAddr) {\n if (existingLatestAddr === ibGibAddr) {\n // latest addr is the same as the incoming addr may indicate:\n // 1. NOT NEW if it's already registered.\n // 2. NEW but not necessarily registered (with new impl as of 11/2023).\n\n // at the very least we can replace the latest (which saves a\n // new metastone) and the broadcast subscribers can do\n // additional checking if the address is actually new to them or\n // not. (I think it's different logic so other things may break)\n if (logalot) { console.log(`${lc} no other found. possible idempotent replacement. addr: ${ibGibAddr} (I: 7f5bd5d3391be95919240f0e97976e22)`); }\n await replaceLatest();\n return; /* <<<< returns early */\n } else {\n // different addr found, then YES the incoming ibGibAddr is expected\n // to be NEW (note that the incoming ibgib may indeed be older but\n // somehow the register new has gotten out of whack and this should be\n // defensively checked elsewhere as needed). So broadcast that there is\n // a new ibGib if there is a tjp involved.\n\n if (logalot) { console.log(`${lc} different addr found. incoming ibgib addr is newer. existingLatestAddr: ${existingLatestAddr}. incoming addr: ${ibGibAddr} (I: 6cadf13f82aabeb71d76babf1813e623)`); }\n\n // double check that the existing ibGib actually is older. once that is\n // determined, then we'll execute the replaceLatest\n\n // not the latest or not registered, so get the full existing latest\n // ibgib and analyze to see if the incoming ibgib is indeed newer\n let resExistingLatest = await getFromSpace({ addr: existingLatestAddr, space });\n if (!resExistingLatest.success || resExistingLatest.ibGibs?.length !== 1) {\n console.error(`Didn't find existing latest ibGib (${existingLatestAddr}). I haven't implemented more robust multi-node/distributed strategies for this scenario yet. so we are going ahead with setting the incoming ibgib as the latest in the timeline. (E: 10f6cca6e5ef45bfacbfe48f652e2102)`);\n await replaceLatest();\n return; /* <<<< returns early */\n }\n const existingLatestIbGib = resExistingLatest.ibGibs![0];\n\n // if there is an nCounter, then we can go by that. Otherwise, we'll\n // try to brute force \"latest\" comparison\n const ibGibHasNCounter =\n typeof ibGib.data?.n === 'number' &&\n ibGib.data!.n! >= 0;\n if (ibGibHasNCounter) {\n // #region ibGib.data.n counter method\n if (logalot) { console.log(`found ibGib.data.n (version counter), using this to determine latest ibGib: ${ibGib.data!.n!}`); }\n const n_ibGib = (ibGib.data!.n! as number);\n\n const existingLatestHasNCounter =\n typeof existingLatestIbGib.data?.n === 'number' &&\n existingLatestIbGib.data!.n! >= 0;\n\n if (existingLatestHasNCounter) {\n // both have counters, so compare by those.\n const n_existingLatest = (existingLatestIbGib.data!.n! as number);\n if (n_ibGib > n_existingLatest) {\n // is newer\n if (logalot) { console.log(`${lc} is newer (I: 040d05ac2032f08c7fd0c4d8b2887323)`); }\n await replaceLatest();\n } else {\n // not newer\n if (logalot) { console.log(`is not newer, so we don't need to do anything else. (I: 14c25dc3314748dc909d61b77eb64354)`) }\n console.warn(`${lc} incoming ibGib (${ibGibAddr}) is NOT NEWER than existing latest (${existingLatestAddr}). multiple branches for the same timeline? ignoring incoming ibGibAddr. n_ibGib: ${n_ibGib}. n_existingLatest: ${n_existingLatest}. space.ib: ${space.ib} (W: 057baadca494473dabb26fb4fb879774)`)\n return; /* <<<< returns early */\n }\n } else {\n // only the new one has the counter, so that wins by\n // default. this is common when existingLatestIbGib is a\n // tjp and the ibGib we're registering is n === 0\n if (existingLatestIbGib.data?.isTjp && ibGib.data!.n === 0) {\n // normal situation\n await replaceLatest();\n } else {\n console.warn(`${lc} (UNEXPECTED) only existingLatestIbGib (isTjp: ${existingLatestIbGib.data?.isTjp}) has a data.n counter? ibGib.data.n: ${ibGib.data!.n}. usually this only happens when existing latest is a tjp and the new ibGib we are registering is n === 0. This is falsy in this instance though. We will go ahead and replace the latest with the new one, but this is an anomalous state. (W: 73d08aea17ad4e1481a5f97e2556a878)`)\n console.log(`${lc} console.dir(existingLatestIbGib)... (I: 9ef7962d9cc74f1eb0409e5caf98e915)`);\n console.dir(existingLatestIbGib);\n console.log(`${lc} console.dir(ibGib)... (I: 9ef7962d9cc74f1eb0409e5caf98e915)`);\n console.dir(ibGib);\n await replaceLatest();\n }\n }\n // #endregion\n\n } else {\n if (logalot) { console.log(`${lc} no nCounter found. Trying brute force method.`); }\n // #region brute force latest\n let latestAddr = await getLatestAddr_Brute({\n ibGib, ibGibAddr,\n existingLatest: existingLatestIbGib, existingLatestAddr,\n tjpAddr,\n space,\n });\n if (latestAddr === ibGibAddr) {\n await replaceLatest();\n } else {\n return; /* <<<< returns early */\n }\n // #endregion\n }\n }\n } else {\n // if latestAddr is null (no address is found), the incoming ibGib\n // timeline (or ibGib itself if it's a stone) has not been found at all\n // yet so YES the incoming ibGib is NEW\n if (existingLatestAddr === null) {\n if (logalot) { console.log(`${lc} no existing tjp mapping so incoming ibgib is considered new to this space. ibGib addr: ${ibGibAddr} (I: 4f2bbc32b31e4fa982d95b3a785db82f)`); }\n await replaceLatest();\n return; /* <<<< returns early */\n } else {\n // should we just warn?\n throw new Error(`(UNEXPECTED) latestAddr is falsy but not null? the getLatestAddrs impl in the space should be guaranteed to provide either the incoming ibgib addr, the latest addr (if exists), or null if not found. (E: 3159dd531c0bc0efc1ece116adf28923)`);\n }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n logalot = initialLogalot;\n }\n}\n\n/**\n * Performs a rel8 transform on the special ibgib corresponding to the incoming\n * `type`.\n *\n * ## special ibgibs\n *\n * much metadata configuration is stored via \"special\" ibgibs. Most of these are\n * tracked in a space's ibgib directly, and the space itself is tracked in the\n * bootstrap. So when storing configuration data, I usually create a new special\n * ibgib. this function performs the plumbing for the rel8 transform related to\n * that special ibgib.\n *\n * ## notes\n *\n * * special ibgib must exist in the space, i.e. previously initialized\n * * i'm using this atm for mainly the local ionic space, but sometimes\n * might be good in sync space, i dunno at this point.\n * * I've migrated a lot of local space behavior into this space-agnostic file.\n *\n * @returns new special ibgib addr\n */\nexport async function rel8ToSpecialIbGib({\n type,\n rel8nName,\n ibGibsToRel8,\n ibGibsToUnRel8,\n addrsToUnRel8,\n linked,\n severPast,\n deletePreviousSpecialIbGib,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n /**\n * the \"name\" of the special ibgib.\n *\n * This will drive deterministically what the special ibgib's `ib` will be,\n * among other things.\n */\n type: SpecialIbGibType,\n /**\n * The rel8nName by which to rel8 the target incoming `ibGibsToRel8`.\n */\n rel8nName: string,\n /**\n * multiple ibgibs to rel8\n */\n ibGibsToRel8?: IbGib_V1[],\n /**\n * multiple ibgibs to UNrel8.\n * YOU CANNOT SET BOTH {@link ibGibsToUnRel8} AND {@link addrsToUnRel8}\n * There is no technical reason for this, I'm just too tired to implement\n * yagni overhead.\n * @see {@link addrsToUnRel8}\n */\n ibGibsToUnRel8?: IbGib_V1[],\n /**\n * alternatively just specify addrs to unrel8.\n * YOU CANNOT SET BOTH {@link ibGibsToUnRel8} AND {@link addrsToUnRel8}\n * There is no technical reason for this, I'm just too tired to implement\n * yagni overhead.\n * @see {@link ibGibsToUnRel8}\n */\n addrsToUnRel8?: IbGibAddr[],\n /**\n * If linked, then the rel8nName will only contain one address, i.e. the\n * last rel8d ibgib's address.\n *\n * This depends on your use case.\n */\n linked?: boolean,\n /**\n * Clears out the special.rel8ns.past array to an empty array.\n *\n * {@see deletePreviousSpecialIbGib} for driving use case.\n */\n severPast?: boolean,\n /**\n * Deletes the previous special ibGib.\n *\n * ## driving use case\n *\n * the latest ibGib is one that is completely ephemeral. It doesn't get attached\n * to the current root, and it only has the current instance. So we don't want to\n * keep around past incarnations.\n */\n deletePreviousSpecialIbGib?: boolean,\n /**\n * The space in which the special ibgib resides.\n */\n space: IbGibSpaceAny,\n /**\n * The default zero space that contains metaspace information, i.e.\n * bootstrap ibgib, space ibgibs, etc.\n */\n zeroSpace: IbGibSpaceAny,\n /**\n * The function by which to update the bootstrap ibgib.\n *\n * This is necessary, because when you update a special ibgib,\n * the address of that special ibgib must be updated in the given\n * `space`. This will require an update to the space's address, which\n * itself is tracked in the bootstrap ibgib.\n */\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n /**\n * Use this if you want to broadcast the new space's address after this\n * function performs the rel8 transform.\n */\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr> {\n const lc = `[${rel8ToSpecialIbGib.name}](type:${type},rel8nName:${rel8nName})`;\n try {\n if (!space) { throw new Error(`space required. (E: 956192eea28047eba6dad81620bb96fb)`); }\n if ((ibGibsToRel8 ?? []).length === 0 &&\n (ibGibsToUnRel8 ?? []).length === 0 &&\n (addrsToUnRel8 ?? []).length === 0\n ) {\n throw new Error(`either ibGibsToRel8 or ibGibsToUnRel8 required. (E: 5add49c8e46a54e2c6b057c22646a822)`);\n }\n if ((ibGibsToUnRel8 ?? []).length > 0 && (addrsToUnRel8 ?? []).length > 0) {\n throw new Error(`can't provide both ibGibsToUnRel8 and addrsToUnRel8. There isn't a technical reason but I'm too tired right now to implement the overhead to enable this atow (05/2025). (E: 31ef66be26349cfe1b1f352389b99425)`);\n }\n\n const addrsToRel8 = ibGibsToRel8?.map(ibGib => getIbGibAddr({ ibGib }));\n addrsToUnRel8 ??= ibGibsToUnRel8?.map(ibGib => getIbGibAddr({ ibGib }));\n\n // get the special ibgib\n const configKey = getSpecialConfigKey({ type });\n let specialAddr =\n // type === SpecialIbGibType.latest ? // latest special ibgib addr is constant\n // getSpecialIbGibAddr({ type }) :\n await getConfigAddr({ key: configKey, space });\n if (!specialAddr) { throw new Error(`specialAddr not found (E: 680dfd1caa3e4d7cb0f593b893a10f0d)`) };\n let resGetSpecial = await getFromSpace({ addr: specialAddr, space });\n if (!resGetSpecial.success) { throw new Error(`couldn't get special (E: 897f7671d2184515866c5a675d33b3dc)`) }\n if (!resGetSpecial.ibGibs) { throw new Error(`resGetSpecial.ibGibs falsy (E: 2405dd295b2444d88503f7731796a5a0)`) }\n if (resGetSpecial.ibGibs!.length !== 1) { throw new Error(`resGetSpecial.ibGibs count is not 1 (${resGetSpecial.ibGibs!.length}) (E: b4547789016a4729af30cd972a4ca4ab)`) }\n\n const oldSpecialIbGib = resGetSpecial.ibGibs![0];\n\n // execute the rel8 transform on the special ibgib.\n const resNewSpecial = await rel8({\n src: oldSpecialIbGib,\n rel8nsToAddByAddr: addrsToRel8 ? { [rel8nName]: addrsToRel8 } : undefined,\n rel8nsToRemoveByAddr: addrsToUnRel8 ? { [rel8nName]: addrsToUnRel8 } : undefined,\n dna: false,\n linkedRel8ns: linked ? [Rel8n.past, rel8nName] : [Rel8n.past],\n nCounter: true,\n });\n const newSpecialIbGib = resNewSpecial.newIbGib;\n\n // sever\n if (severPast) {\n if (resNewSpecial.intermediateIbGibs) { throw new Error('new special creates intermediate ibgibs. so severing past is harder. (E: b580c0c56253494192e9c62212ee187d)'); }\n newSpecialIbGib.rel8ns!.past = [];\n newSpecialIbGib.gib = await getGib({ ibGib: newSpecialIbGib });\n }\n\n // // special ibgib latest index is always the same address\n // if (type === SpecialIbGibType.latest) {\n // newSpecialIbGib.gib = GIB;\n // }\n\n // persist\n await persistTransformResult({ resTransform: resNewSpecial, space });\n\n // return the new special address (not the incoming new ibGib)\n const newSpecialAddr = getIbGibAddr({ ibGib: newSpecialIbGib });\n const specialTjpAddr = getTjpAddr({ ibGib: newSpecialIbGib });\n\n // update the space ibgib which contains the special/config information\n // if (type !== SpecialIbGibType.latest) {\n await setConfigAddr({ key: configKey, addr: newSpecialAddr, space, zeroSpace, fnUpdateBootstrap });\n // }\n\n // delete if required, only after updating config with the new special addr.\n // if (deletePreviousSpecialIbGib && type !== SpecialIbGibType.latest) {\n if (deletePreviousSpecialIbGib) {\n await deleteFromSpace({ addr: specialAddr, space });\n }\n\n await registerNewIbGib({ ibGib: newSpecialIbGib, fnBroadcast, space, });\n\n // is this necessary? no i don't think so, as the above registerNewIbGib\n // already has this dispatch\n // if (fnBroadcast && specialTjpAddr && getIbAndGib({ ibGibAddr: specialTjpAddr }).gib !== GIB) {\n // fnBroadcast({\n // ib: 'IbGibTimelineUpdateInfo',\n // tjpAddr: specialTjpAddr,\n // latestIbGib: newSpecialIbGib,\n // latestAddr: newSpecialAddr,\n // });\n // }\n\n return newSpecialAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport async function getTjpIbGib({\n ibGib,\n naive = true,\n space,\n}: {\n ibGib: IbGib_V1<any>,\n naive?: boolean,\n space: IbGibSpaceAny,\n}): Promise<IbGib_V1<any> | undefined> {\n const lc = `[${getTjpIbGib.name}]`;\n\n try {\n if (!space) { throw new Error(`space required. (E: 941f973d50e84415b58724af173f52c2)`); }\n if (!ibGib) { throw new Error('ibGib required.'); }\n\n let ibGibAddr = getIbGibAddr({ ibGib });\n const { gib } = getIbAndGib({ ibGibAddr });\n if (gib === GIB) { return ibGib; }\n let isTjp = await isTjp_Naive({ ibGib, naive });\n if (isTjp) { return ibGib; }\n\n // the given ibGib arg isn't itself the tjp\n\n // if no rel8ns, then there is no tjp ibgib, since this is not\n // intrinsically the tjp and there is no 'tjp' or 'past' rel8n to check\n if (!ibGib.rel8ns) {\n if (logalot) { console.log(`${lc} ibgib not tjp in data, and rel8ns is falsy. so tjp is undefined (I: acdadb76a7568807db7a68f6f866de22)`); }\n return undefined; // <<<< returns early\n }\n\n // check explicitly listed tjp in rel8ns\n if (ibGib.rel8ns!.tjp && ibGib.rel8ns!.tjp.length > 0) {\n let firstTjpAddr = ibGib.rel8ns!.tjp[0];\n let resGetTjpIbGib = await getFromSpace({ addr: firstTjpAddr, space });\n if (resGetTjpIbGib.success && resGetTjpIbGib.ibGibs?.length === 1) {\n return resGetTjpIbGib.ibGibs[0]\n } else {\n const resErrorMsg = resGetTjpIbGib.errorMsg ?? '[unspecified error in get result]';\n throw new Error(`ibGib references tjp but could not retrieve from space. res error: ${resErrorMsg} (E: 94f0340706ad48c794c6a62c1b235a22)`);\n }\n }\n\n // couldn't get the tjp from the rel8ns.tjp, so look for manually in past.\n // but we can't just get the earliest in the 'past', because the tjp\n // may be one of the intermediates!\n // So, check the immediate past ibGib recursively.\n\n const past = ibGib.rel8ns!.past || [];\n if (past.length === 0) {\n console.warn(`${lc} past.length === 0, so there is no tjp.`)\n if (logalot) { console.log(`${lc} ibgib is not tjp in data, not in tjp rel8n, and past is empty. so tjp is undefined (I: bf06f664917dcf4492fb9c4c106a6222)`); }\n return undefined; // <<<< returns early\n }\n const pastIbGibAddr = past[past.length - 1];\n const resGetPastIbGib = await getFromSpace({ addr: pastIbGibAddr, space });\n if (!resGetPastIbGib.success || resGetPastIbGib.ibGibs?.length !== 1) { throw new Error(`get past failed. addr: ${pastIbGibAddr}`); }\n const pastIbGib = resGetPastIbGib.ibGibs![0];\n\n // call this method recursively!\n return await getTjpIbGib({ ibGib: pastIbGib, naive, space });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n// #region creates\n\n/**\n * Routing function to various `create_____` functions.\n *\n * @returns address of newly created special.\n */\nexport async function createSpecial({\n type,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n type: SpecialIbGibType,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial.name}]`;\n try {\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized. (E: 66e7d3ff098248f0a5ddda51853c92e6)`); }\n\n switch (type) {\n case \"roots\": return createSpecial_Roots({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"tags\": return createSpecial_Tags({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n // case \"latest\": return createSpecial_Latest({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"secrets\": return createSpecial_Secrets({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"encryptions\": return createSpecial_Encryptions({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"outerspaces\": return createSpecial_OuterSpaces({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"autosyncs\": return createSpecial_Autosyncs({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"robbots\": return createSpecial_Robbots({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"apps\": return createSpecial_Apps({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n default: return createSpecial_Default({ type, space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Creates a new special ibgib, persists it and if not skipped, relates\n * it to the current root.\n *\n * @returns newly created ibgib (not just address)\n */\nexport async function createSpecialIbGib({\n type,\n skipRel8ToRoot,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n type: SpecialIbGibType,\n skipRel8ToRoot?: boolean,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGib_V1> {\n const lc = `[${createSpecialIbGib.name}][${type || 'falsy type?'}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n const specialIb = getSpecialIbGibIb({ type });\n const src = factory.primitive({ ib: specialIb });\n const resNewSpecial = await fork({\n src,\n destIb: specialIb,\n linkedRel8ns: [Rel8n.past, Rel8n.ancestor],\n tjp: { uuid: true, timestamp: true },\n dna: true,\n nCounter: true,\n });\n await persistTransformResult({ resTransform: resNewSpecial, space });\n // we don't relate the special roots index to itself and we don't relate\n // the latest index as it is a super (woohoo!) special ephemeral ibgib.\n if (type !== 'roots' && type !== 'latest' && !skipRel8ToRoot) {\n await rel8ToCurrentRoot({\n ibGib: resNewSpecial.newIbGib,\n linked: true,\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n }\n if (logalot) { console.log(`${lc} complete.`); }\n return resNewSpecial.newIbGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Creates a new tags^gib instance (unique to current space), as well as\n * default initial tags, e.g. \"home\", \"favorites\", etc., and relates these\n * individual tags to the tags ibGib itself.\n *\n * Stores the tags ibGib's addr in config.\n */\nexport async function createSpecial_Tags({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Tags.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: 9c05b9bd355943a39ca47afef67a50eb)`); }\n\n const configKey = getSpecialConfigKey({ type: \"tags\" });\n const special = await createSpecialIbGib({\n type: \"tags\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n let addr = getIbGibAddr({ ibGib: special });\n await setConfigAddr({ key: configKey, addr: addr, space, zeroSpace, fnUpdateBootstrap });\n\n // at this point, our tags ibGib has no associated tag ibGibs.\n // add home, favorite tags\n const initialTagDatas: TagData_V1[] = [\n { text: 'home', icon: 'home-outline' },\n { text: 'favorite', icon: 'heart-outline' },\n ];\n for (const data of initialTagDatas) {\n const resCreate = await createTagIbGibAndSundry({ ...data, space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n addr = resCreate.newTagsAddr;\n await setConfigAddr({ key: configKey, addr: addr, space, zeroSpace, fnUpdateBootstrap });\n }\n\n return addr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\n/**\n * 1. Creates a new tag ibgib with the given properties.\n * 2. Persists graph in given {@link space}\n * 3. Registers the new tag ibgib in that space, using the given\n * {@link fnUpdateBootstrap} and {@link fnBroadcast} functions.\n * 4. Relates the new tag to the special tags ibgib.\n *\n * @returns the new tag ibgib and new tags address.\n */\nexport async function createTagIbGibAndSundry({\n text,\n icon,\n description,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n text: string,\n icon?: string,\n description?: string,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<{ newTagIbGib: TagIbGib_V1, newTagsAddr: string }> {\n const lc = `[${createTagIbGibAndSundry.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!space) { throw new Error(`space required. (E: 5def0b1afab74b0c9286e3ac5060cb8f)`); }\n\n if (!text) { throw new Error(`${lc} text required`); }\n icon = icon || DEFAULT_TAG_ICON;\n description = description || DEFAULT_TAG_DESCRIPTION;\n const tagIb = tagTextToIb(text);\n const tagPrimitive = factory.primitive({ ib: \"tag\" });\n const resNewTag = await factory.firstGen({\n parentIbGib: tagPrimitive,\n ib: tagIb,\n data: { text, icon, description },\n tjp: { uuid: true, timestamp: true },\n dna: true,\n nCounter: true,\n });\n const newTag = resNewTag.newIbGib as TagIbGib_V1;\n await persistTransformResult({ resTransform: resNewTag, space });\n await registerNewIbGib({ ibGib: newTag, space, fnBroadcast, });\n const newTagsAddr = await rel8TagToTagsIbGib({\n tagIbGib: newTag, space, zeroSpace, fnUpdateBootstrap, fnBroadcast,\n });\n return { newTagIbGib: newTag, newTagsAddr };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function createSpecial_Roots({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Roots.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: d12a8ea31163429fb6e53ff8e7579c57)`); }\n\n const configKey = getSpecialConfigKey({ type: \"roots\" });\n // const rootsIbGib = await createSpecialIbGib({type: \"roots\", space});\n const rootsIbGib = await createSpecialIbGib({\n type: \"roots\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n let rootsAddr: IbGibAddr | undefined = getIbGibAddr({ ibGib: rootsIbGib });\n await setConfigAddr({ key: configKey, addr: rootsAddr, space, zeroSpace, fnUpdateBootstrap });\n\n // at this point, our ibGib has no associated ibGibs.\n // so we add initial roots\n const rootNames = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];\n\n const initialDatas: RootData[] = rootNames.map(n => {\n return {\n text: `${n}root`,\n icon: DEFAULT_ROOT_ICON,\n description: DEFAULT_ROOT_DESCRIPTION\n };\n });\n let firstRoot: IbGib_V1<RootData> | undefined = undefined;\n for (let i = 0; i < initialDatas.length; i++) {\n const data = initialDatas[i];\n const resCreate = await createRootIbGib({\n ...data,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n });\n if (!firstRoot) { firstRoot = resCreate.newRootIbGib; }\n if (!resCreate.newRootIbGib) { throw new Error(`(UNEXPECTED) resCreate.newRootIbGib falsy? (E: c9fb2c94a9c1d762c1699b41a4d5ad23)`); }\n rootsAddr = resCreate.newRootsAddr;\n // update the config for the updated **roots** ibgib.\n // that roots ibgib is what points to the just created new root.\n await setConfigAddr({ key: configKey, addr: rootsAddr, space, zeroSpace, fnUpdateBootstrap });\n }\n if (!firstRoot) { throw new Error(`(UNEXPECTED) firstRoot still falsy? (E: b2e2c926d242966e7ed7159e4b129e23)`); }\n\n // initialize current root\n await setCurrentRoot({ root: firstRoot, space, zeroSpace, fnUpdateBootstrap, fnBroadcast });\n // hack: the above line updates the roots in config. so get **that** addr.\n\n rootsAddr = await getConfigAddr({ key: configKey, space });\n if (!rootsAddr) { throw new Error('(UNEXPECTED) no roots address in config? (E: 76345340699a4738a195e48803ef0d31)'); }\n return rootsAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nasync function createRootIbGib({\n text,\n icon,\n description,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n text: string,\n icon?: string,\n description?: string,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<{ newRootIbGib: IbGib_V1<RootData>, newRootsAddr: string }> {\n const lc = `[${createRootIbGib.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: cfa876e5c8c64a53a463ca7a645571c8)`); }\n\n text = text || DEFAULT_ROOT_TEXT;\n icon = icon || DEFAULT_ROOT_ICON;\n description = description || DEFAULT_ROOT_DESCRIPTION;\n const ib = getRootIb(text);\n const parentIbGib = factory.primitive({ ib: \"root\" });\n const resNewIbGib = await factory.firstGen({\n parentIbGib,\n ib,\n data: { text, icon, description },\n linkedRel8ns: [Rel8n.past, Rel8n.ancestor],\n tjp: { uuid: true, timestamp: true },\n dna: true,\n nCounter: true,\n });\n const { newIbGib } = resNewIbGib;\n await persistTransformResult({\n resTransform: resNewIbGib,\n space,\n });\n const newRootsAddr = await rel8ToSpecialIbGib({\n type: \"roots\",\n rel8nName: ROOT_REL8N_NAME,\n ibGibsToRel8: [newIbGib],\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n });\n return { newRootIbGib: newIbGib as IbGib_V1<RootData>, newRootsAddr };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n// async function createSpecial_Latest({\n// space,\n// zeroSpace,\n// fnUpdateBootstrap,\n// fnBroadcast,\n// }: {\n// space: IbGibSpaceAny,\n// zeroSpace: IbGibSpaceAny,\n// fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n// fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n// }): Promise<IbGibAddr | null> {\n// const lc = `[${createSpecial_Latest.name}]`;\n// try {\n// if (!space) { throw new Error(`space required. (E: 173b08d7eb114238b32280c3efce9d1a)`); }\n\n// const configKey = getSpecialConfigKey({ type: \"latest\" });\n// // const special =\n// // await createSpecialIbGib({type: \"latest\", skipRel8ToRoot: true, space});\n// const special = await createSpecialIbGib({\n// type: \"latest\",\n// space,\n// skipRel8ToRoot: true,\n// zeroSpace,\n// fnBroadcast,\n// fnUpdateBootstrap,\n// });\n// special.gib = GIB;\n// let specialAddr = getIbGibAddr({ ibGib: special });\n// await setConfigAddr({ key: configKey, addr: specialAddr, space, zeroSpace, fnUpdateBootstrap });\n\n// // right now, the latest ibgib doesn't have any more initialization,\n// // since it is supposed to be as ephemeral and non-tracked as possible.\n\n// return specialAddr;\n// } catch (error) {\n// console.error(`${lc} ${error.message}`);\n// return null;\n// }\n// }\n\nasync function createSpecial_Secrets({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Secrets.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: 340960cd5ad24addb300b23d9722e30a)`); }\n\n let secretsAddr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type: \"secrets\" });\n\n // special ibgib doesn't exist, so create it (empty)\n // const secretsIbgib = await createSpecialIbGib({type: \"secrets\", space});\n const secretsIbgib = await createSpecialIbGib({\n type: \"secrets\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n secretsAddr = getIbGibAddr({ ibGib: secretsIbgib });\n await setConfigAddr({ key: configKey, addr: secretsAddr, space, zeroSpace, fnUpdateBootstrap });\n\n return secretsAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nasync function createSpecial_Encryptions({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Encryptions.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: 5084e698b6924e7090697ca50075ca59)`); }\n\n let addr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type: \"encryptions\" });\n\n // special ibgib doesn't exist, so create it (empty)\n // const encryptionsIbgib = await createSpecialIbGib({type: \"encryptions\", space});\n const encryptionsIbgib = await createSpecialIbGib({\n type: \"encryptions\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n addr = getIbGibAddr({ ibGib: encryptionsIbgib });\n await setConfigAddr({ key: configKey, addr: addr, space, zeroSpace, fnUpdateBootstrap });\n\n return addr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nasync function createSpecial_OuterSpaces({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_OuterSpaces.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: 99dd9e92535c470482eb9f6625a33831)`); }\n\n let outerSpacesAddr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type: \"outerspaces\" });\n\n // special outerspaces ibgib doesn't exist, so create it (empty)\n // const outerSpacesIbGib = await createSpecialIbGib({type: \"outerspaces\", space});\n const outerSpacesIbGib = await createSpecialIbGib({\n type: \"outerspaces\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n outerSpacesAddr = getIbGibAddr({ ibGib: outerSpacesIbGib });\n await setConfigAddr({ key: configKey, addr: outerSpacesAddr, space, zeroSpace, fnUpdateBootstrap });\n\n return outerSpacesAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nasync function createSpecial_Autosyncs({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Autosyncs.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: f01cf6a4a460486796e16d505d629522)`); }\n\n let autosyncsAddr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type: \"autosyncs\" });\n\n const autosyncsIbGib = await createSpecialIbGib({\n type: \"autosyncs\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n autosyncsAddr = getIbGibAddr({ ibGib: autosyncsIbGib });\n await setConfigAddr({ key: configKey, addr: autosyncsAddr, space, zeroSpace, fnUpdateBootstrap });\n\n return autosyncsAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nexport async function createSpecial_Robbots({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Robbots.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: f01cf6a4a460486796e16d505d629522)`); }\n\n let robbotsAddr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type: \"robbots\" });\n\n const robbotsIbGib = await createSpecialIbGib({\n type: \"robbots\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n robbotsAddr = getIbGibAddr({ ibGib: robbotsIbGib });\n await setConfigAddr({ key: configKey, addr: robbotsAddr, space, zeroSpace, fnUpdateBootstrap });\n\n return robbotsAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nexport async function createSpecial_Apps({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Apps.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: f01cf6a4a460486796e16d505d629522)`); }\n\n let appsAddr: IbGibAddr | undefined | null;\n const configKey = getSpecialConfigKey({ type: \"apps\" });\n\n const appsIbGib = await createSpecialIbGib({\n type: \"apps\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n appsAddr = getIbGibAddr({ ibGib: appsIbGib });\n await setConfigAddr({ key: configKey, addr: appsAddr, space, zeroSpace, fnUpdateBootstrap });\n\n // at this point, our apps ibGib has no associated app ibGibs.\n // so create our initial apps.\n // appsAddr = await createApps_Chat({ space, zeroSpace, fnUpdateBootstrap, fnBroadcast });\n appsAddr = await createApp({\n defaultAppData: DEFAULT_CHAT_APP_DATA_V1,\n defaultAppRel8ns: DEFAULT_CHAT_APP_REL8NS_V1,\n space, zeroSpace, fnUpdateBootstrap, fnBroadcast,\n });\n // appsAddr = await createApps_Raw({ space, zeroSpace, fnUpdateBootstrap, fnBroadcast });\n appsAddr = await createApp({\n defaultAppData: DEFAULT_RAW_APP_DATA_V1,\n defaultAppRel8ns: DEFAULT_RAW_APP_REL8NS_V1,\n space, zeroSpace, fnUpdateBootstrap, fnBroadcast,\n });\n // appsAddr = await createApps_Todo({ space, zeroSpace, fnUpdateBootstrap, fnBroadcast });\n appsAddr = await createApp({\n defaultAppData: DEFAULT_TODO_APP_DATA_V1,\n defaultAppRel8ns: DEFAULT_TODO_APP_REL8NS_V1,\n space, zeroSpace, fnUpdateBootstrap, fnBroadcast,\n });\n\n return appsAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nexport async function createApp({\n defaultAppData,\n defaultAppRel8ns,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n /**\n * object that contains all of the default \"data\" for the app. Data here\n * does not mean an app's data like other apps. In ibgib, data is\n * everywhere. This means particularly the defalut app ibGib's data, i.e.\n * `ibGib.data`.\n */\n defaultAppData: any,\n defaultAppRel8ns: any,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createApp.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 677f68789abdc7316887e8f38c764e22)`); }\n\n // #region torn from chat-app-v1.ts because of circular dependency...eesh\n\n if (logalot) { console.log(`${lc} starting...`); }\n let data = clone(defaultAppData) as AppData_V1;\n let rel8ns = defaultAppRel8ns ? clone(defaultAppRel8ns) : undefined;\n data.uuid = (!data.uuid || data.uuid === DEFAULT_UUID_TODO_APP) ?\n await getUUID() :\n data.uuid;\n let { classname } = data;\n\n const ib = getAppIb({ appData: data, classname });\n\n const resNewApp = await factory.firstGen({\n ib,\n parentIbGib: factory.primitive({ ib: `app ${classname}` }),\n data: data,\n rel8ns,\n dna: true,\n linkedRel8ns: [Rel8n.ancestor, Rel8n.past],\n nCounter: true,\n tjp: { timestamp: true },\n }) as TransformResult<AppIbGib_V1>;\n\n // #endregion torn from chat-app-v1.ts because of circular dependency...eesh\n\n await persistTransformResult({ resTransform: resNewApp, space });\n await registerNewIbGib({ ibGib: resNewApp.newIbGib, fnBroadcast, space, });\n let appsAddr = await rel8ToSpecialIbGib({\n type: \"apps\",\n rel8nName: APP_REL8N_NAME,\n ibGibsToRel8: [resNewApp.newIbGib],\n fnBroadcast,\n fnUpdateBootstrap,\n space, zeroSpace,\n });\n\n return appsAddr;\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nasync function createSpecial_Default({\n type,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n type: SpecialIbGibType,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Default.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: c7bbafcbe901418db4c6048f17f53091)`); }\n\n if (logalot) { console.log(`${lc} creating special of type: ${type} (I: 283c8bb30ed6f9698b74b886c6078622)`); }\n\n let specialAddr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type });\n\n const specialIbGib = await createSpecialIbGib({\n type,\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n specialAddr = getIbGibAddr({ ibGib: specialIbGib });\n await setConfigAddr({ key: configKey, addr: specialAddr, space, zeroSpace, fnUpdateBootstrap });\n\n return specialAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\n/**\n * 1. Creates a new robbot ibgib with the given properties.\n * 2. Persists graph in given {@link space}\n * 3. Registers the new robbot ibgib in that space, using the given\n * {@link fnUpdateBootstrap} and {@link fnBroadcast} functions.\n * 4. Relates the new robbot to the special robbots ibgib.\n *\n * @returns the new robbot ibgib and new robbots address.\n */\n// export async function createRobbotIbGib({\n// robbotData,\n// space,\n// zeroSpace,\n// fnUpdateBootstrap,\n// fnBroadcast,\n// }: {\n// robbotData: RobbotData_V1,\n// space: IbGibSpaceAny,\n// zeroSpace: IbGibSpaceAny,\n// fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n// fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n// }): Promise<{ newRobbotIbGib: RobbotIbGib_V1, newRobbotsAddr: string }> {\n// const lc = `[${createRobbotIbGib.name}]`;\n// try {\n// if (logalot) { console.log(`${lc} starting...`); }\n// if (!space) { throw new Error(`space required. (E: 5def0b1afab74b0c9286e3ac5060cb8f)`); }\n// if (!robbotData) { throw new Error(`robbotData required (E: cd0304401a2f5a63d86dd71f76f31222)`); }\n\n// const ib = getRobbotIb({ robbotData });\n// const resNewRobbot = await factory.firstGen({\n// parentIbGib: factory.primitive({ ib: \"robbot\" }),\n// ib,\n// data: robbotData,\n// linkedRel8ns: [Rel8n.past, Rel8n.ancestor],\n// tjp: { uuid: true, timestamp: true },\n// dna: true,\n// nCounter: true,\n// });\n// const newRobbot = (resNewRobbot.newIbGib as RobbotIbGib_V1);\n// await persistTransformResult({ resTransform: resNewRobbot, space });\n// await registerNewIbGib({ ibGib: newRobbot, space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n// const newRobbotsAddr = await rel8ToSpecialIbGib({\n// type: \"robbots\",\n// rel8nName: ROBBOT_REL8N_NAME,\n// ibGibsToRel8: [newRobbot],\n// space,\n// zeroSpace,\n// fnUpdateBootstrap,\n// fnBroadcast,\n// });\n// return { newRobbotIbGib: newRobbot, newRobbotsAddr };\n// } catch (error) {\n// console.error(`${lc} ${error.message}`);\n// throw error;\n// } finally {\n// if (logalot) { console.log(`${lc} complete.`); }\n// }\n// }\n\n\n/**\n * We are NOT searching through all of our data looking for a needle in a haystack.\n * What we ARE doing is we are looking through the past of the existing latest and\n * the prospective latest (the given ibGib param) and comparing between the two.\n *\n * Since `past` rel8n is usually a linked rel8n now, we may have to traverse it all\n * the way to its beginning for each possibility.\n *\n * @returns either {@param ibGibAddr} or {@param existingLatestAddr}\n */\nasync function getLatestAddr_Brute({\n ibGib, ibGibAddr,\n existingLatest, existingLatestAddr,\n tjpAddr,\n space,\n}: {\n ibGib: IbGib_V1<any>, ibGibAddr: string,\n existingLatest: IbGib_V1<any>, existingLatestAddr: string,\n tjpAddr: string,\n space: IbGibSpaceAny,\n}): Promise<string> {\n const lc = `[${getLatestAddr_Brute.name}][${ibGibAddr}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 64eb9a271f5d43deadec30b9638746c8)`); }\n\n // no nCounter, so we need to brute force.\n // The easiest way is to check each's past, as the most common\n // scenario would be registering a newer one, or less likely, a timing issue\n // with registering a previous ibGib frame.\n\n let ibGibPast = ibGib.rel8ns?.past || [];\n let existingLatestPast = existingLatest.rel8ns?.past || [];\n\n // going to check a bunch of specific, easy cases to narrow things down.\n\n if (ibGibPast.length === 1 && existingLatestPast.length === 0) {\n if (logalot) { console.log(`prospective has a past, so it \"must\" be newer. (won't quote \"must\" anymore)`); }\n return ibGibAddr;\n } else if (existingLatestPast.length === 1 && ibGibPast.length === 0) {\n if (logalot) { console.log(`existing has a past, so it must be newer.`); }\n return existingLatestAddr;\n } else if (existingLatestPast.length === 0 && ibGibPast.length === 0) {\n console.warn(`${lc} neither existing latest nor prospective new ibGib has a past, so keeping existing.`);\n return existingLatestAddr;\n } else if (existingLatestPast.includes(ibGibAddr)) {\n if (logalot) { console.log(`existing by definition is newer`); }\n return existingLatestAddr;\n } else if (ibGibPast.includes(existingLatestAddr)) {\n if (logalot) { console.log(`ibGib by definition is newer`); }\n return ibGibAddr;\n } else if (existingLatestAddr === ibGibAddr) {\n if (logalot) { console.log(`they're the same!`); }\n return existingLatestAddr;\n } else if (existingLatestAddr === tjpAddr && existingLatest.rel8ns?.tjp?.length === 1) {\n if (logalot) { console.log(`ibGib must be newer because the existingLatestAddr is the tjp, which is by definition first in unique past.`); }\n return ibGibAddr;\n } else if (ibGibAddr === tjpAddr && ibGib.rel8ns?.tjp?.length === 1) {\n if (logalot) { console.log(`existing must be newer because the ibGibAddr is the tjp, which is by definition first in unique past.`); }\n return existingLatestAddr;\n }\n\n // well, neither one really gives us any indicator alone\n // so load each one in the past\n if (logalot) { console.log(`${lc} brute forcing through iterating the pasts.`); }\n let newerAddr: string | undefined;\n let firstIterationCount = -1; // klugy hack, but is an ugly method anyway (brute after all!)\n\n let getPastCount: (x: IbGib_V1<any>, n: number, otherAddr: string) => Promise<number> =\n async (x, n, otherAddr) => {\n let xPast = x.rel8ns?.past || [];\n if (xPast.includes(otherAddr)) {\n // no need to proceed further, since the other is found in the past of x, so x is newer\n newerAddr = getIbGibAddr({ ibGib: x });\n return -1;\n }\n if (xPast.length === 0) { return n; } // no more past to increment\n let newCount = n + xPast.length;\n if (firstIterationCount !== -1 && newCount > firstIterationCount) {\n // we've determined that the second iteration has a longer past,\n // so we don't need to look further\n newerAddr = getIbGibAddr({ ibGib: x });\n return -1;\n }\n // load up the earliest one and call recursively\n let resNextX = await getFromSpace({ addr: xPast[0], space });\n if (!resNextX.success || resNextX.ibGibs?.length !== 1) { throw new Error(`Couldn't load past addr (xPast[0]): ${xPast[0]}`); }\n return getPastCount(resNextX.ibGibs![0], n + xPast.length, otherAddr);\n }\n\n if (logalot) { console.log(`${lc} doing ibGibPastCount`); }\n let ibGibPastCount = await getPastCount(ibGib, 0, existingLatestAddr);\n if (newerAddr) { return newerAddr; }\n\n // we didn't hit upon it, so set the firstIterationCount so we don't spend unnecessary cycles\n if (logalot) { console.log(`${lc} Doing existingPastCount`); }\n firstIterationCount = ibGibPastCount;\n let existingPastCount = await getPastCount(existingLatest, 0, ibGibAddr);\n if (newerAddr) { return newerAddr; }\n\n // we didn't yet determine it, so whichever has the longer past is newer\n if (ibGibPastCount > existingPastCount) {\n if (logalot) { console.log(`${lc} ibGibPastCount (${ibGibPastCount}) is longer than existingPastCount (${existingPastCount}), so ibGib is newer.`); }\n newerAddr = ibGibAddr;\n } else {\n if (logalot) { console.log(`${lc} existingPastCount (${existingPastCount}) is longer than ibGibPastCount (${ibGibPastCount}), so ibGib is newer.`); }\n newerAddr = existingLatestAddr;\n }\n return newerAddr;\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n// #endregion\n\n\n/**\n * Relates the given tag to the TagsIbGib, saves the generated\n * TagsIbGib and updates the settings to point to the new TagsIbGib.\n *\n * @param tagIbGib to add to Tags\n */\nexport function rel8TagToTagsIbGib({\n tagIbGib,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n tagIbGib: IbGib_V1,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr> {\n return rel8ToSpecialIbGib({\n type: \"tags\",\n rel8nName: TAG_REL8N_NAME,\n ibGibsToRel8: [tagIbGib],\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n });\n}\n\n\n/**\n * Throws an error if any duplicates found in either array.\n *\n * ## notes\n *\n * Only pass in ibGib or ibGibAddrs, not both. Warns if both are passed in though.\n *\n * @throws if both params are falsy or if addrs || mapped addrs contains duplicates.\n */\nexport function throwIfDuplicates({\n ibGibs,\n ibGibAddrs,\n}: {\n ibGibs?: IbGib_V1[],\n ibGibAddrs?: IbGibAddr[],\n}): void {\n const lc = `[${throwIfDuplicates.name}]`;\n try {\n if (!ibGibs && !ibGibAddrs) { throw new Error(`either ibGibs or ibGibAddrs required. (E: 37776788620f4966b0964945ce181fc6)`); }\n if (ibGibs && ibGibAddrs) { console.warn(`${lc} both ibGibs and ibGibAddrs provided. You should only provide one. Only ibGibAddrs will be checked. (W: dc13f9e197834e2daaba3bcfd08418db)`); }\n\n const addrs = ibGibAddrs ? ibGibAddrs.concat() : ibGibs!.map(x => getIbGibAddr({ ibGib: x }));\n for (let i = 0; i < addrs.length; i++) {\n const addr = addrs[i];\n if (addrs.filter(x => x === addr).length > 1) { throw new Error(`duplicate addr found: ${addr} (E: 70fbef040dd449c38c667d53b8092053)`); }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport function getSpaceLockAddr({\n space,\n scope,\n}: {\n space: IbGibSpaceAny,\n scope: SpaceLockScope,\n}): IbGibAddr {\n const lc = `[${getSpaceLockAddr.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 3ba16e6c3e5e47948b0e63448da11752)`); }\n if (!space.data?.uuid) { throw new Error(`invalid space (space.data.uuid falsy) (E: 273262b32f2ef27b2e690bc699f33822)`); }\n if (!scope) { throw new Error(`scope required. (E: f47801d6c45e2247b42a53d9b604b522)`); }\n while (scope.includes(IBGIB_DELIMITER)) {\n if (logalot) { console.log(`${lc} scope contains ibgib delimiter...replacing... (I: 0f456fd7cc6552a799673a0c5b4a7d22)`); }\n scope = scope.replace(IBGIB_DELIMITER, '_');\n }\n\n const spaceId = space.data!.uuid;\n const ib = `${SPACE_LOCK_IB_TERM} ${spaceId} ${scope}`;\n const gib = GIB;\n return getIbGibAddr({ ib, gib });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Executes some function `fn` against/in a given `space` while\n * performing lock plumbing in that space.\n *\n * By this, I mean that this function takes care of acquiring the lock,\n * attempting retries according to the parameters, and then unlocking\n * the space regardless of result/error.\n *\n * @returns result of inner `fn` with `TResult`\n */\nexport async function execInSpaceWithLocking<TResult>({\n space,\n scope,\n secondsValid,\n maxDelayMs,\n fn,\n callerInstanceId,\n maxLockAttempts,\n}: {\n space: IbGibSpaceAny,\n scope: string,\n secondsValid: number,\n /**\n * If resource locked, will delay at max this ms.\n */\n maxDelayMs?: number,\n fn: () => Promise<TResult>,\n /**\n * for use differentiating among tabs.\n *\n * ## intent\n * the idea is the ibgibs service has an instance id and passes it in here.\n */\n callerInstanceId?: string,\n /**\n * if given, will try to acquire lock at most this many times, else\n * will default to {@link DEFAULT_MAX_DELAY_RETRY_LOCK_ACQUIRE_ATTEMPTS}.\n */\n maxLockAttempts?: number,\n}): Promise<TResult> {\n const lc = `[${execInSpaceWithLocking.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n // #region validation\n\n if (!space) { throw new Error(`space required. (E: 66fd8f21a5b2b572d18cdeb9472a7722)`); }\n if (!secondsValid) { throw new Error(`secondsValid required. (E: 92c5610e57ceede5ce83cff86d5c2a22)`); }\n if (secondsValid < 0) { throw new Error(`secondsValid must be positive. (E: 970a7510c517235d7a355a843d18d222)`); }\n // if (secondsValid > MAX_LOCK_SECONDS_VALID) { throw new Error(`secondsValid arg (${secondsValid}) exceeds max secondsValid (${MAX_LOCK_SECONDS_VALID}) (E: 4cffe49a23c8f1698bf7c78eaccbb722)`); }\n if (!fn) { throw new Error(`fn required (E: 7022e280252ec2faf756b6db05c56e22)`); }\n\n // #endregion validation\n\n let resultFn: TResult;\n\n if (logalot) { console.log(`${lc} attempting to acquire lock with scope ${scope} (I: fed36d42a975b1c52897a4df804ac722)`); }\n let lockIbGib: IbGibSpaceLockIbGib;\n maxDelayMs =\n (maxDelayMs ?? 0) > 0 ? maxDelayMs : DEFAULT_MAX_DELAY_MS_RETRY_LOCK_ACQUIRE\n let attempts = 0;\n maxLockAttempts =\n maxLockAttempts ?? -1 > 0 ?\n maxLockAttempts :\n DEFAULT_MAX_DELAY_RETRY_LOCK_ACQUIRE_ATTEMPTS;\n do {\n lockIbGib = await lockSpace({\n space,\n scope,\n secondsValid,\n instanceId: callerInstanceId,\n });\n if (lockIbGib?.data?.success) { break; }\n /** Delay a small random amount of time before trying again. */\n let delayMs = Math.ceil(Math.random() * maxDelayMs!);\n await delay(delayMs);\n attempts++;\n } while (attempts < maxLockAttempts!);\n if (lockIbGib?.data?.success) {\n if (logalot) { console.log(`${lc} lock acquired. (I: d847fa953ee131a57e1a89c537342722)`); }\n } else {\n throw new Error(`could not acquire lock after ${attempts} attempts with intermittent delays of ${maxDelayMs} ms (E: 898c559dbd0c9bf20c14cf87a8f1e222)`);\n }\n\n // execute the actual get inside an additional try..catch..finally\n // to ensure (attempted) unlockSpace call.\n const lc2 = `${lc}[fn]`;\n try {\n if (logalot) { console.log(`${lc2} starting... (I: c2f7bedf95d3f1dd1f76de34a68d3f22)`); }\n resultFn = await fn();\n } catch (error) {\n console.error(`${lc2} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc2} unlocking space with scope: ${scope} (I: 21034d9c3395499756e9000e40417d22)`); }\n await unlockSpace({ space: space, scope: scope, instanceId: callerInstanceId });\n if (logalot) { console.log(`${lc2} complete. (I: 79d8ac03714a4d429c7e6c2ac6e18d22)`); }\n }\n\n return resultFn;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Gets the bootstrap ibgib in the given `zeroSpace`.\n *\n * @example\n *\n * ```json\n * {\n * \"ib\":\"bootstrap\",\n * \"gib\":\"gib\",\n * \"data\":{\n * \"defaultSpaceId\":\"d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33\",\n * \"spaceIds\":[\"d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33\"]\n * },\n * \"rel8ns\":{\n * \"d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33\":[\n * \"witness space IonicSpace_V1 oij d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33^B336251655E8C56B38E9E86F20E0E42E6C153785F1A0A798ADE6916E71CF055B\"\n * ]\n * }\n * }\n * ```\n *\n * @returns bootstrapIbGib if found, else null\n */\nexport async function getValidatedBootstrapIbGib({\n zeroSpace,\n}: {\n zeroSpace: IbGibSpaceAny,\n}): Promise<BootstrapIbGib | null> {\n const lc = `[${getValidatedBootstrapIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!zeroSpace) { throw new Error(`zeroSpace required. (E: 66fd8f21a5b2b572d18cdeb9472a7722)`); }\n\n const bootstrapAddr = BOOTSTRAP_IBGIB_ADDR;\n\n if (logalot) { console.log(`${lc} getting from zeroSpace...`); }\n const argGet = await zeroSpace.argy({\n ibMetadata: getSpaceArgMetadata({ space: zeroSpace }),\n argData: {\n cmd: 'get',\n ibGibAddrs: [bootstrapAddr],\n },\n });\n const resGetBootstrapIbGib = await zeroSpace.witness(argGet);\n\n if (resGetBootstrapIbGib?.data?.success && resGetBootstrapIbGib.ibGibs?.length === 1) {\n // bootstrap found\n const bootstrapIbGib = resGetBootstrapIbGib!.ibGibs![0]!;\n if (logalot) { console.log(`${lc} bootstrapibGib found: ${pretty(bootstrapIbGib)}`); }\n if (await validateBootstrapIbGib(bootstrapIbGib)) {\n return (bootstrapIbGib as BootstrapIbGib);\n } else {\n if (logalot) { console.log(`${lc} bootstrapIbGib was invalid. (I: cce66b26805404fc85525d565e1f8b22)`); }\n return null;\n }\n } else {\n // bootstrap NOT found\n if (logalot) { console.log(`${lc} bootstrapIbGib NOT found. (I: 421562993bf3464eb507d2967d311e22)`); }\n return null;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * So when loading the local user space, even if the class changes or default\n * constructors change, the internal `data` is loaded from file.\n */\nexport async function getLocalSpace<TSpace extends IbGibSpaceAny>({\n zeroSpace,\n bootstrapIbGib,\n localSpaceId,\n lock,\n callerInstanceId,\n fnDtoToSpace,\n localSpaceCacheSvc,\n}: {\n /**\n * A zero space is a space that is built with default settings that\n * is not specific to a user.\n *\n * This is the foundational space that all spaces share, out of which\n * a bootstrap ibgib can be found that will itself have rel8ns to other\n * spaces.\n *\n * ## notes\n *\n * This is what I was calling a zeroSpace, but that will in the future\n * mean a default space among a group of spaces.\n */\n zeroSpace: IbGibSpaceAny,\n /**\n * bootstrap ibGib, if provided, which was found in the zero space.\n * The bootstrap ibgib should have a rel8n entry to the local space.\n *\n * ## future\n *\n * We will have multiple local spaces to choose from, with a default\n * being the one that we're referring to atow.\n */\n bootstrapIbGib?: BootstrapIbGib,\n /**\n * If provided, will look for the space via this id in the bootstrap ibgib.\n * If not provided, will use the bootstrap ibgib's default spaceId.\n */\n localSpaceId?: SpaceId,\n /**\n * If true, we will lock on getting the bootstrap ibgib (if needed), as\n * well as getting the user space.\n */\n lock?: boolean,\n /**\n * for use differentiating among tabs.\n *\n * ## intent\n * the idea is the ibgibs service has an instance id and passes it in here.\n */\n callerInstanceId: string,\n /**\n * function that turns the space dto into the space witness.\n *\n * ## intent\n *\n * When loading a space, the only part stored is the ibgib data. You still\n * need a function that hydrates a witness class with that data.\n */\n fnDtoToSpace: (spaceDto: IbGib_V1) => Promise<TSpace>,\n /**\n * Optional caching service\n */\n localSpaceCacheSvc?: IbGibCacheService,\n}): Promise<TSpace> {\n const lc = `[${getLocalSpace.name}]`;\n try {\n if (!zeroSpace) { throw new Error(`zeroSpace required. (E: 0793781a98c456a666cfa9eb960bcd22)`); }\n\n if (!bootstrapIbGib) {\n if (logalot) { console.log(`${lc} bootstrap falsy, so loading it... (I: f2366e38283495a38b5501297aa34422)`); }\n if (lock) {\n const bootstrapAddr = BOOTSTRAP_IBGIB_ADDR;\n if (logalot) { console.log(`${lc} using locked version of loading bootstrap... (I: 52b9b11999674e586d051c2b23f59b22)`); }\n bootstrapIbGib = await execInSpaceWithLocking<BootstrapIbGib>({\n space: zeroSpace,\n scope: bootstrapAddr,\n fn: async () => {\n let validatedBootstrapIbGib = await getValidatedBootstrapIbGib({ zeroSpace });\n if (validatedBootstrapIbGib) {\n return validatedBootstrapIbGib;\n } else {\n throw new Error(`(UNEXPECTED) unable to get bootstrap ibgib? (E: c111dc7627acbfb992134ddf4064ea23)`);\n }\n },\n callerInstanceId,\n secondsValid: DEFAULT_SECONDS_VALID_LOCAL,\n });\n } else {\n if (logalot) { console.log(`${lc} lock is false, so just getting the bootstrap ibgib (I: 49d55e5a824510bb3ee0ccd9f5ec3322)`); }\n bootstrapIbGib = await getValidatedBootstrapIbGib({ zeroSpace }) ?? undefined;\n }\n }\n\n if (!bootstrapIbGib) { throw new Error(`bootstrapIbGib falsy. not initialized? (E: 91f5c82b5e124178d958701ebcb09822)`); }\n\n if (!bootstrapIbGib.data) { throw new Error(`(UNEXPECTED) bootstrapIbGib.data required. invalid bootstrap? (E: 568c6b837c1a39f7a25d188a90167423)`); }\n\n localSpaceId = localSpaceId ?? bootstrapIbGib!.data[BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY];\n const localSpaceAddr = bootstrapIbGib.rel8ns![localSpaceId]![0]; // guaranteed b/c bootstrap was validated\n\n const fnGet: () => Promise<TSpace> = async () => {\n\n const argGet = await zeroSpace.argy({\n ibMetadata: getSpaceArgMetadata({ space: zeroSpace }),\n argData: {\n cmd: 'get',\n ibGibAddrs: [localSpaceAddr],\n },\n });\n const resLocalSpace = await zeroSpace.witness(argGet);\n if (resLocalSpace?.data?.success && resLocalSpace.ibGibs?.length === 1) {\n const localSpaceDto = resLocalSpace.ibGibs[0] as TSpace;\n const localSpace = await fnDtoToSpace(localSpaceDto);\n if (localSpaceCacheSvc) { localSpace.cacheSvc = localSpaceCacheSvc; }\n return localSpace;\n } else {\n throw new Error(`Could not get local space addr (${localSpaceAddr}) specified in bootstrap space (${getIbGibAddr({ ibGib: bootstrapIbGib })}). (E: 6d6b45e7eae4472697ddc971438e4922)`);\n }\n }\n\n if (lock) {\n if (logalot) { console.log(`${lc} getting localSpaceId (${localSpaceId}) WITH locking (I: c48a0e4ac5971cdbc57273dd35f8a522)`); }\n return await execInSpaceWithLocking({\n space: zeroSpace,\n scope: localSpaceId,\n fn: () => { return fnGet(); },\n callerInstanceId,\n secondsValid: DEFAULT_SECONDS_VALID_LOCAL,\n });\n } else {\n if (logalot) { console.log(`${lc} getting localSpaceId (${localSpaceId}) WITHOUT locking (I: 48e504835dee4006839df8820d860b22)`); }\n return fnGet();\n }\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport async function lockSpace({\n space,\n scope,\n secondsValid,\n instanceId,\n}: IbGibSpaceLockOptions): Promise<IbGibSpaceLockIbGib> {\n const lc = `[${lockSpace.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 5c0a7197a75f483a82d74e5eea60df37)`); }\n if (!scope) { throw new Error(`scope required. (E: c7f1dde9570f4df3b450faa2c2f85122)`); }\n if (!secondsValid) { throw new Error(`secondsValid required and positive (E: b42b6733638b46c06c9aff59a6c49822)`); }\n if (secondsValid < 0) { throw new Error(`secondsValid must be positive (E: bbe3b6d567583bfb35a1c0825eb29622)`); }\n\n /** what we will return */\n let resLockIbGib: IbGibSpaceLockIbGib;\n\n /** space lock address is deterministic ibgib primitive (gib === 'gib') */\n const spaceLockAddr = getSpaceLockAddr({ space, scope });\n\n // check for existing lock...\n let existingLock: IbGibSpaceLockIbGib | undefined;\n\n // ...in space's backing store (file, IndexedDB entry, DB, etc.)\n\n let getLock = await getFromSpace({\n addr: spaceLockAddr, space, force: true\n });\n if (getLock.success && getLock.ibGibs?.length === 1) {\n existingLock = getLock.ibGibs[0] as IbGibSpaceLockIbGib;\n if (existingLock?.data?.expirationUTC) {\n if (isExpired({ expirationTimestampUTC: existingLock.data.expirationUTC })) {\n // lock expired, so log only. skipping delete atow because should be overwritten\n // when the new lock is in place.\n console.warn(`${lc} ignoring expired existing lock in space at ${spaceLockAddr}. Should be overwritten (W: 7421c5b051724b189f88cecbbd449b22)`);\n existingLock = undefined;\n }\n } else {\n console.error(`${lc} (UNEXPECTED) exisingLock.data.expirationUTC falsy? (E: 218dc0e935534a149d0be153c532cf25)`);\n existingLock = undefined;\n }\n } else {\n if (logalot) { console.log(`${lc} existing lock not found for ${spaceLockAddr} (I: 191af56ec4e2db3d19084e46bf949222)`); }\n }\n\n // populate resLockIbGib if/else existingLock\n if (existingLock) {\n if (!existingLock.data) { throw new Error(`(UNEXPECTED) existingLock.data falsy? (E: 00069b4662e5566d971760d15e293723)`); }\n // valid lock already exists, so return informing caller. this\n // includes the existing lock's info, i.e. its expiration\n resLockIbGib = clone(existingLock) as IbGibSpaceLockIbGib;\n resLockIbGib.data!.alreadyLocked = true;\n resLockIbGib.data!.success = false;\n } else {\n // not yet locked so immediately lock in memory for space, then via\n // `space.put(lock)`\n const { ib, gib } = getIbAndGib({ ibGibAddr: spaceLockAddr });\n resLockIbGib = {\n ib, gib,\n data: {\n scope,\n secondsValid,\n instanceId,\n expirationUTC: getExpirationUTCString({ seconds: secondsValid }),\n }\n } as IbGibSpaceLockIbGib;\n\n // We must use space.witness (via argy) directly here instead of\n // `putInSpace` helper, because we need to check\n // `addrsAlreadyHave`. If the space already has the addr, then\n // we have lost a race condition and the space is ALREADY locked.\n const argPut = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'put',\n force: true,\n ibGibAddrs: [spaceLockAddr],\n },\n ibGibs: [resLockIbGib],\n });\n const resPut = await space.witness(argPut);\n\n if (resPut.data?.success) {\n if ((resPut.data.addrsAlreadyHave ?? []).includes(spaceLockAddr)) {\n // Race condition lost! The lock was put by someone else in the interim.\n if (logalot) { console.log(`${lc} racelost! addrsAlreadyHave includes spaceLockAddr (${spaceLockAddr}) (I: 2e8a1562947c40698110b64251141753)`); }\n\n // get the existing lock that beat us\n const getLockRace = await getFromSpace({\n addr: spaceLockAddr, space, force: true\n });\n if (getLockRace.success && getLockRace.ibGibs?.length === 1) {\n const existingLockRace = getLockRace.ibGibs[0] as IbGibSpaceLockIbGib;\n resLockIbGib = clone(existingLockRace) as IbGibSpaceLockIbGib;\n resLockIbGib.data!.alreadyLocked = true;\n resLockIbGib.data!.success = false;\n } else {\n // Should be unreachable if addrsAlreadyHave is true, but handle gracefully\n const emsg = `${lc} (UNEXPECTED) addrsAlreadyHave true, but couldn't get lock? (E: 8374a2b6628b49369363bc5843105763)`;\n console.error(emsg);\n resLockIbGib.data!.success = false;\n resLockIbGib.data!.errorMsg = emsg;\n }\n } else {\n // Success! We put the lock and it was new.\n resLockIbGib.data!.success = true;\n }\n } else {\n const emsg = `${lc} there was an error putting the lock in the space: ${resPut.data?.errors?.join('|')}`;\n resLockIbGib.data!.success = false;\n resLockIbGib.data!.errorMsg = emsg;\n console.error(emsg);\n }\n }\n\n return resLockIbGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function unlockSpace({\n space,\n scope,\n instanceId,\n}: IbGibSpaceLockOptions): Promise<IbGibSpaceLockIbGib | undefined> {\n const lc = `[${unlockSpace.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 5c0a7197a75f483a82d74e5eea60df37)`); }\n if (!scope) { throw new Error(`scope required. (E: c7f1dde9570f4df3b450faa2c2f85122)`); }\n\n /** space lock address is deterministic ibgib primitive (gib === 'gib') */\n const spaceLockAddr = getSpaceLockAddr({ space, scope });\n\n // delete in file if it exists\n let resDelete = await deleteFromSpace({ addr: spaceLockAddr, space, force: true });\n if (resDelete.success) {\n const { ib, gib } = getIbAndGib({ ibGibAddr: spaceLockAddr });\n return {\n ib, gib,\n data: {\n // action: 'unlock',\n success: true,\n instanceId,\n scope,\n }\n } as IbGibSpaceLockIbGib;\n } else {\n /** May NOT be an error, just setting this here is convenient to code. */\n const emsg = `Delete lock in space failed. delete errorMsg: ${resDelete.errorMsg}`;\n if (emsg.includes('not implemented')) {\n // rethrow error if space has not implemented a delete command handler\n throw new Error(emsg);\n } else if (\n emsg.toLowerCase().includes(`does not exist`) ||\n emsg.toLowerCase().includes(`doesn't exist`) ||\n emsg.toLowerCase().includes(`not found`)\n ) {\n // don't want to warn if just file didn't exist\n if (logalot) { console.log(`${lc} ${emsg} (I: b647916fd0f3e5366e9387131be21c22)`); }\n const { ib, gib } = getIbAndGib({ ibGibAddr: spaceLockAddr });\n return {\n ib, gib,\n data: {\n action: 'unlock',\n success: true,\n instanceId,\n scope,\n }\n } as IbGibSpaceLockIbGib;\n } else {\n console.warn(`${lc} ${emsg} (W: 14c84fcac15944bd9a417099964d5d9d)`);\n }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Updates the bootstrap^gib record in the default space data store\n * with the 'space' rel8n set to the `newSpaceAddr`.\n *\n * This way, if the app closes at this point, it will know to look at this\n * space when it loads.\n *\n * ## notes\n *\n * I'm probably typing this all over, but the bootstrap^gib is the\n * first record that the app looks at to know what space to load.\n * The space itself has configuration and has a proper gib hash\n * so it's verifiable. But the initial bootstrap^gib record is\n * NOT, since it only has 'gib' as its address (and thus its not hashed).\n *\n * In the future, this could be alleviated by asking other witnesses\n * \"Hey what was my last bootstrap^gib hash\", but there's no way to\n * do it beyond this without using some kind of authentication/secret(s)\n * that generate the record, i.e. encrypting bootstrap^gib cleverly.\n */\nexport async function updateBootstrapIbGib({\n space,\n zeroSpace,\n setSpaceAsDefault,\n createIfNotFound,\n}: {\n /**\n * space to add/replace in the bootstrap^gib ibgib.\n */\n space: IbGibSpaceAny,\n /**\n * default \"zero\" space which contains a bootstrap^gib ibgib.\n */\n zeroSpace?: IbGibSpaceAny,\n /**\n * set the space as the default local space in the bootstrap^gib ibgib.\n */\n setSpaceAsDefault?: boolean,\n /**\n * If bootstrap not found, create a new one\n */\n createIfNotFound?: boolean,\n}): Promise<void> {\n const lc = `[${updateBootstrapIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 6fc19548fa7d1d5219e19871f280a322)`); }\n if (!space.data?.uuid) { throw new Error(`space.data.uuid required (E: 6483188ca6f2ed2085fd355595f3ab22)`); }\n if (!zeroSpace) { throw new Error(`zeroSpace required. (E: abbf156e18b1018d96273e22a260f122)`); }\n\n const spaceId = space.data.uuid;\n const newSpaceAddr = getIbGibAddr({ ibGib: space });\n\n /** validated bootstrap ibgib or null */\n let bootstrapIbGib = await getValidatedBootstrapIbGib({ zeroSpace });\n if (!bootstrapIbGib) {\n if (!createIfNotFound) {\n if (logalot) { console.log(`${lc} bootstrapIbGib not found but createIfNotFound falsy, so returning early. (I: 5c67d85a8599a5ba4a6780f26a66ea22)`); }\n return; /* <<<< returns early */\n }\n\n // create the bootstrap^gib space that points to user space\n if (logalot) { console.log(`${lc} creating new bootstrap ibgib for spaceId (${spaceId}) with address of (${newSpaceAddr}) (I: 651959c27bf2ebc5be1f7f44e2b9e422)`); }\n const { ib: bootstrapIb, gib } = getIbAndGib({ ibGibAddr: BOOTSTRAP_IBGIB_ADDR });\n bootstrapIbGib = (factory.primitive as any)({ ib: bootstrapIb });\n bootstrapIbGib!.gib = gib;\n bootstrapIbGib!.data = {\n /**\n * first space is automatically set as default, regardless of\n * `setSpaceAsDefault` value\n */\n [BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY]: spaceId,\n [BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY]: [spaceId],\n } as BootstrapData;\n bootstrapIbGib!.rel8ns = {\n /**\n * individual spaces indexed by spaceId, should be length === 1\n * with the value being the most recent.\n */\n [spaceId]: [newSpaceAddr],\n } as BootstrapRel8ns;\n } else {\n // at this point, we have a validated bootstrap.\n // update existing bootstrap with newSpaceAddr for given spaceId\n if (logalot) { console.log(`${lc} updating existing bootstrap (I: 977d4aa7ed47bef73b35743c05ce0722)`); }\n if (bootstrapIbGib.data!.spaceIds.includes(spaceId)) {\n if (logalot) { console.log(`${lc} space already rel8d to bootstrap, possibly updating its addr (I: b5e2c515ef732d4bbcf02625a9e7c722)`); }\n const existingSpaceAddr = bootstrapIbGib.rel8ns![spaceId]![0];\n if (existingSpaceAddr === newSpaceAddr) {\n if (logalot) { console.log(`${lc} bootstrap already rel8d to space (I: c1be027b23e7350c64790a631cae2822)`); }\n } else {\n if (logalot) { console.log(`${lc} updating rel8ns[${spaceId}] with newSpaceAddr (${newSpaceAddr}). (Old address: ${existingSpaceAddr})(I: 297a9b0061fd471b8d28a06e04a6ad22)`); }\n bootstrapIbGib.rel8ns![spaceId] = [newSpaceAddr];\n }\n } else {\n // new space being rel8d to bootstrap\n if (logalot) { console.log(`${lc} new space being rel8d. adding spaceId to data.spaceIds and amending rel8ns (I: 40903d71719aa1d56e498299f5699a22)`); }\n bootstrapIbGib.data!.spaceIds.push(spaceId);\n bootstrapIbGib.rel8ns![spaceId] = [newSpaceAddr];\n }\n if (setSpaceAsDefault) {\n if (logalot) { console.log(`${lc} setting spaceId (${spaceId}) as default space (I: f85eda6c6ad2b0bec9750ce3c7795b22)`); }\n bootstrapIbGib.data![BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY] = spaceId;\n }\n }\n\n if (!bootstrapIbGib) { throw new Error(`(UNEXPECTED) bootstrapIbGib still falsy? (E: cf21d7f1756710a66aa0e6a28d762723)`); }\n\n if (logalot) { console.log(`${lc} saving bootstrapIbGib: ${pretty(bootstrapIbGib)} (I: 3cceca0b98dde90e4a58a734be252322)`); }\n\n // save the bootstrap^gib in the zero space for future space loadings,\n // especially when the app first starts up\n const argPutBootstrap = await zeroSpace.argy({\n ibMetadata: bootstrapIbGib!.ib,\n argData: {\n cmd: 'put', force: true,\n ibGibAddrs: [getIbGibAddr({ ibGib: bootstrapIbGib })],\n },\n ibGibs: [bootstrapIbGib],\n });\n if (logalot) { console.log(`${lc} zeroSpace will witness/put... (I: 1be9aca22ffc4951b6690965a7aeae5b)`); }\n const resPutBootstrap = await zeroSpace.witness(argPutBootstrap);\n if (resPutBootstrap?.data?.success) {\n if (logalot) { console.log(`${lc} zero space put complete. (I: ac3056d655e841f1a3c442bcc64942f9)`); }\n } else {\n throw new Error(`${resPutBootstrap?.data?.errors?.join('|') || \"There was a problem with zeroSpace witnessing the bootstrap^gib primitive pointing to the new user space\"}`);\n }\n if (logalot) { console.log(`${lc} complete.`); }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n\n}\n\nexport function getSpaceArgMetadata({ space }: { space: IbGibSpaceAny }): string {\n return `${space.ib} ${getTimestampInTicks()}`;\n}\n\nexport function getSpaceResultMetadata({ space }: { space: IbGibSpaceAny }): string {\n return `${space.ib} ${getTimestampInTicks()}`;\n}\n\n/**\n * builds the space's ib based on either spaceData or space.data, depending on\n * what is passed in. if for some reason both are passed in, this does some\n * basic checking to be sure that they are the same data.\n * @returns generated spaceIb\n */\nexport function getSpaceIb({\n space,\n spaceData,\n classname,\n}: {\n space?: IbGibSpaceAny,\n spaceData?: IbGibSpaceData,\n classname?: string,\n}): Ib {\n const lc = `[${getSpaceIb.name}]`;\n try {\n if (!space && !spaceData) { throw new Error(`either space or spaceData required (E: 4dabec34ee77d67c9cc30ee3c3049622)`); }\n if (space && !space.data) { throw new Error(`(UNEXPECTED) given space has falsy space.data? (E: 058d298876ebbeada7bbddb9e3da2f23)`); }\n if (space && spaceData) {\n if (space.data!.uuid !== spaceData.uuid) { throw new Error(`(UNEXPECTED) both space and spaceData given, but uuid don't match? (E: efdd4603cba93a17340a76811fe56b24)`); }\n if (space.data!.n !== spaceData.n) { throw new Error(`(UNEXPECTED) both space and spaceData given, but n don't match? (E: e51278a707c9bccc57a08a4b86524524)`); }\n }\n spaceData ??= space!.data!;\n if (!spaceData) { throw new Error(`(UNEXPECTED) spaceData falsy? (thought this was a compiler problem that this was even possible.) (E: b3c7ffedcae4b1f45b263b3825930b24)`); }\n\n\n if (classname && spaceData.classname && classname !== spaceData.classname) {\n throw new Error(`both classname arg (${classname}) and spaceData.classname (${spaceData.classname}) are different truthy values. (E: f98f012ee876eb8fbe7403f7b53e4624)`);\n } else {\n classname ||= spaceData.classname;\n }\n if (!classname) { throw new Error(`classname required (E: fa3af4613ad56742dab51d1b0d839322)`); }\n if (classname.includes(' ')) { throw new Error(`invalid classname (${classname}). cannot contain spaces (E: 243adbf720dcce7904e2665933208b22)`); }\n\n const name = spaceData?.name || IBGIB_SPACE_NAME_DEFAULT;\n if (name.includes(' ')) { throw new Error(`invalid space name. cannot contain spaces (E: a8450e1651081412c8ac018520182422)`); }\n\n const id = spaceData?.uuid || undefined;\n if (!id) { throw new Error(`invalid space, spaceData.uuid falsy (E: 50ae723a9ab24f4fc7132613e65faf23)`); }\n if (id.includes(' ')) { throw new Error(`invalid space id. cannot contain spaces (E: 8696830fe7f54bfa85e670a063f3e089)`); }\n\n const spaceType = spaceData.type ?? undefined;\n const spaceSubtype = spaceData.subtype ?? undefined;\n if (spaceType && !spaceSubtype) {\n throw new Error(`spaceType (${spaceType}) is set but spaceSubtype is falsy. (E: 878ab960d7987ae2331103b4a00d0d24)`);\n }\n\n return `${WITNESS_ATOM} ${SPACE_ATOM} ${classname} ${name} ${id} ${spaceType} ${spaceSubtype}`;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * determines if the given ib belongs to a space ibgib.\n *\n * atow (03/2024) checks to see if the ib starts with\n *\n * `${WITNESS_ATOM} ${SPACE_ATOM} `\n */\nexport function isSpaceIb({\n ib\n}: {\n ib: Ib\n}): boolean {\n const lc = `[${isSpaceIb.name}]`;\n if (!ib) {\n const emsg = `${lc} ib required (E: dd5244f62f964359a86e59bb08ee47e6)`;\n console.error(emsg);\n throw new Error(emsg);\n }\n return ib.startsWith(`${WITNESS_ATOM} ${SPACE_ATOM} `);\n // return ib.startsWith('witness space ') || ib.startsWith('outerspace sync ');\n}\n\n/**\n * atow (03/2024), (space-delimited) schema is...\n *\n * `${WITNESS_ATOM} ${SPACE_ATOM} ${classname} ${name} ${id} ${spaceType} ${spaceSubtype}`\n */\nexport function parseSpaceIb({\n spaceIb,\n}: {\n spaceIb: Ib,\n}): {\n /**\n * currently this can be the classname OR undefined of the space.\n */\n spaceClassname: string | undefined,\n /**\n * non-unique spaceName of the given space (i.e. most likely space.data.name)\n */\n spaceName: string,\n /**\n * currently this returns EITHER SpaceId OR undefined.\n *\n * This is because of my using different schemas for local/outer spaces...\n *\n * (for better or worse)\n */\n spaceId: SpaceId | undefined,\n /**\n * if undefined, by convention, this is a user space\n */\n spaceType: SpaceType | undefined,\n /**\n * subtype, if applicable\n */\n spaceSubtype: SpaceSubtype | undefined,\n} {\n const lc = `[${parseSpaceIb.name}]`;\n try {\n if (!spaceIb) { throw new Error(`spaceIb required (E: fa5424cfb7e846e2851562f2f417944f)`); }\n\n // `${WITNESS_ATOM} ${SPACE_ATOM} ${classname} ${name} ${id} ${spaceType} ${spaceSubtype}`\n const [witnessAtom, spaceAtom, spaceClassname, spaceName, spaceId, spaceType_string, spaceSubtype_string] =\n spaceIb.split(' ');\n\n if (witnessAtom !== WITNESS_ATOM) { throw new Error(`invalid spaceIb (${spaceIb}). witnessAtom !== WITNESS_ATOM (E: 5ae1ca12cf8f30ae341f3e582b025224)`); }\n if (spaceAtom !== SPACE_ATOM) { throw new Error(`invalid spaceIb (${spaceIb}). spaceAtom !== SPACE_ATOM (E: 9cc6b6f30e13455eb29748148a94fa0f)`); }\n if (!spaceClassname) { throw new Error(`invalid spaceIb (${spaceIb}). spaceClassname falsy (E: 00d3392da007ca8b2840b16b199d9a24)`); }\n if (!spaceName) { throw new Error(`invalid spaceIb (${spaceIb}). spaceName falsy (E: b957d8e74ef34d889fa64c60c7a5ea0b)`); }\n if (!spaceId) { throw new Error(`invalid spaceIb (${spaceIb}). spaceId falsy (E: 7a1773722d8e46a0866d683130b65b89)`); }\n\n let spaceType: SpaceType | undefined = undefined;\n if (spaceType_string && spaceType_string !== 'undefined') {\n if (VALID_SPACE_TYPES.includes(spaceType_string as SpaceType)) {\n spaceType = spaceType_string as SpaceType;\n } else {\n throw new Error(`invalid spaceIb (${spaceIb}). spaceType (${spaceType_string}) is set but not a valid type. valid types: ${VALID_SPACE_TYPES.join(', ')} (E: 838f4638a88cfbf3545a3a3a38b6dd24)`);\n }\n }\n\n let spaceSubtype: SpaceSubtype | undefined = undefined;\n if (spaceSubtype_string && spaceSubtype_string !== 'undefined') {\n if (VALID_SPACE_SUBTYPES.includes(spaceSubtype_string as SpaceSubtype)) {\n spaceSubtype = spaceSubtype_string as SpaceSubtype;\n } else {\n throw new Error(`invalid spaceIb (${spaceIb}). spaceSubtype (${spaceSubtype_string}) is set but not a valid subtype. valid subtypes: ${VALID_SPACE_SUBTYPES.join(', ')} (E: 5bdcf23027f94e73860e4340313b04ab)`);\n }\n }\n\n return {\n spaceClassname,\n spaceName,\n spaceId,\n spaceType,\n spaceSubtype,\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * @deprecated\n * use `parseSpaceIb`\n */\nexport function getInfoFromSpaceIb({\n spaceIb,\n}: {\n spaceIb: Ib,\n}): {\n /**\n * currently this can be SpaceId OR undefined.\n */\n spaceClassname: string | undefined,\n /**\n * non-unique spaceName of the given space (i.e. most likely space.data.name)\n */\n spaceName: string,\n /**\n * currently this returns EITHER SpaceId OR undefined.\n *\n * This is because of my using different schemas for local/outer spaces...\n *\n * (for better or worse)\n */\n spaceId: SpaceId | undefined,\n} {\n return parseSpaceIb({ spaceIb });\n}\n\n/**\n * Helper function that generates a unique-ish id.\n *\n * atow this is just `return (await getUUID()).slice(0, DEFAULT_TX_ID_LENGTH);`\n *\n * ## notes\n *\n * The thinking is that it only has to be a couple characters in length\n * because this is supposed to only be a unique id within the scope of\n * a tx which has its own tjp (gib) used as the id for the entire communication\n * saga.\n *\n * @returns txId\n */\nexport async function getNewTxId({\n length,\n}: {\n /**\n * length of txId\n *\n * @default DEFAULT_TX_ID_LENGTH\n */\n length?: number,\n} = { length: DEFAULT_TX_ID_LENGTH }): Promise<TxId> {\n const lc = `[${getNewTxId.name}]`;\n try {\n length = length || DEFAULT_TX_ID_LENGTH;\n return (await getUUID()).slice(0, length) as TxId;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * wrapper for dealing with a space.\n *\n * convenience function for creating an arg ibgib to send to the given space\n * using Cmd/CmdModifiers for getting latest addrs.\n *\n * @returns space result ibgib from the given `space.witness` call.\n */\nexport async function getLatestAddrs({\n ibGibs,\n addrs,\n tjps,\n tjpAddrs,\n space,\n}: {\n ibGibs?: IbGib_V1[],\n addrs?: IbGibAddr[],\n tjps?: IbGib_V1[],\n tjpAddrs?: IbGibAddr[],\n space: IbGibSpaceAny,\n}): Promise<IbGibSpaceResultIbGib<IbGib_V1, IbGibSpaceResultData, IbGibSpaceResultRel8ns>> {\n let lc = `[${getLatestAddrs.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 4d188d6c863246f28aa575753a052304)`); }\n\n // so we don't have to do a bunch of conditional checks all over\n ibGibs = ibGibs ?? []; addrs = addrs ?? [];\n tjps = tjps ?? []; tjpAddrs = tjpAddrs ?? [];\n\n if (\n addrs.length === 0 && ibGibs.length === 0 &&\n tjps.length === 0 && tjpAddrs.length === 0\n ) {\n throw new Error(`Either addrs, ibGibs, tjps, or tjpAddrs required. (E: 7c6ebfbab98d4d21a431b144457fd991)`);\n }\n\n /**\n * Addrs that we'll ultimately send to the space. They start off as\n * tjpAddrs (and derived from `tjps` if any), and then add the incoming\n * ibgibs/addrs if we don't already have their corresponding tjpAddrs\n * being queried.\n * */\n const addrsToQuery = new Set<IbGibAddr>(\n tjpAddrs.concat(tjps.map(ibGib => getIbGibAddr({ ibGib })))\n );\n\n // add ibgibs/addrs only if they do not already have their corresponding\n // tjpAddr in the query addrs. We can do this by checking if the tjpGib\n // is located in the ibGibAddr.gib, which has the form\n // [punctiliarHash].[tjpGib]\n const tjpGibs = Array.from(addrsToQuery).map(x => getIbAndGib({ ibGibAddr: x }).gib);\n ibGibs.map(ibGib => getIbGibAddr({ ibGib }))\n .concat(addrs)\n .forEach(ibGibAddr => {\n const { gib } = getIbAndGib({ ibGibAddr });\n const addrHasExistingTjpGib =\n tjpGibs.some(tjpGib => gib.includes(tjpGib));\n if (!addrHasExistingTjpGib) { addrsToQuery.add(ibGibAddr); }\n });\n\n if (logalot) { console.log(`${lc}[testing] ${space.data?.name || space.ib} (${space.data?.uuid || '[space.data.uuid falsy]'}) addrsToQuery: ${Array.from(addrsToQuery)} (I: 8a2202912c364238b6d6eb09577bc246)`); }\n\n // construct the arg and execute\n const argGet = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'get',\n cmdModifiers: ['latest', 'addrs'],\n ibGibAddrs: Array.from(addrsToQuery),\n },\n });\n return await space.witness(argGet);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * I'm making this because i want to archive on a special tags index ibgib.\n * But we can't allow archiving on any old special ibgib, like the 'roots' index.\n * so this checks to see if it's on the forbidden list (winging that atm), and if it\n * is then this throws.\n *\n * use this function inside of commands that act on ibgibs that are special.\n */\nexport function throwIfContextIsSpecial({\n ibGib_Context,\n}: {\n ibGib_Context: IbGib_V1,\n}): void {\n const lc = `[${throwIfContextIsSpecial.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5f583fd94d27731a65d514e731b8aa22)`); }\n\n if (!isSpecial({ ibGib: ibGib_Context })) { return; /* <<<< returns early */; }\n\n const FORBIDDEN_MANUAL_SPECIAL_TYPES: SpecialIbGibType[] = [\n 'roots', 'autosyncs'\n ];\n if (FORBIDDEN_MANUAL_SPECIAL_TYPES.some(x => ibGib_Context.ib.includes(x))) {\n throw new Error(`cannot perform a modification of this type on this special ibgib (E: b8fb718a7323fc54454464b973412722)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function trash({\n ibGib_Context,\n rel8nName_Context,\n addr,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n ibGib_Context: IbGib_V1,\n rel8nName_Context: string,\n addr: IbGibAddr,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<void> {\n const lc = `[${trash.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 2dc486bb2d516e4534f437aaf5ec7f22)`); }\n if (!ibGib_Context) { throw new Error(`ibGib_Context required (E: 75f7bfa93145d6dffe85d488443ca722)`); }\n if (!rel8nName_Context) { throw new Error(`rel8nName_Context required (E: 12aaa43de9e34b68b25dc9a2a68ad6b9)`); }\n if (!addr) { throw new Error(`addr required (E: e27df3bdc5a2554697cc9597afc4e422)`); }\n if (!space) { throw new Error(`space required (E: 2e3562486ed2956a770ed9e8d77a3f22)`); }\n\n const contextIsSpecialIbGib = isSpecial({ ibGib: ibGib_Context });\n if (contextIsSpecialIbGib) { throwIfContextIsSpecial({ ibGib_Context }); }\n\n const resNewContext = await rel8({\n src: ibGib_Context,\n rel8nsToAddByAddr: { [TRASH_REL8N_NAME]: [addr] },\n rel8nsToRemoveByAddr: { [rel8nName_Context]: [addr] },\n dna: true,\n nCounter: true,\n });\n\n await persistTransformResult({ resTransform: resNewContext, space });\n\n if (contextIsSpecialIbGib) {\n const newSpecialAddr = getIbGibAddr({ ibGib: resNewContext.newIbGib });\n const specialType = getSpecialTypeFromIb({ ib: ibGib_Context.ib });\n const configKey = getSpecialConfigKey({ type: specialType });\n await setConfigAddr({ key: configKey, addr: newSpecialAddr, space, zeroSpace, fnUpdateBootstrap });\n }\n\n await registerNewIbGib({ ibGib: resNewContext.newIbGib, fnBroadcast, space, });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function archive({\n ibGib_Context,\n rel8nName_Context,\n addr,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n ibGib_Context: IbGib_V1,\n rel8nName_Context: string,\n addr: IbGibAddr,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<void> {\n const lc = `[${archive.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 38098552b830495187299bb24fcddff0)`); }\n if (!ibGib_Context) { throw new Error(`ibGib_Context required (E: d819e8c4db5b4c0bb721300ba434cd40)`); }\n if (!rel8nName_Context) { throw new Error(`rel8nName_Context required (E: de061adff8c04429a211aa09116a532d)`); }\n if (!addr) { throw new Error(`addr required (E: 7059ebb8ef6149ea94e22f961d6b5c81)`); }\n if (!space) { throw new Error(`space required (E: e19566f2d42347798621447edcae312e)`); }\n\n const contextIsSpecialIbGib = isSpecial({ ibGib: ibGib_Context });\n if (contextIsSpecialIbGib) { throwIfContextIsSpecial({ ibGib_Context }); }\n\n const resNewContext = await rel8({\n src: ibGib_Context,\n rel8nsToAddByAddr: { [ARCHIVE_REL8N_NAME]: [addr] },\n rel8nsToRemoveByAddr: { [rel8nName_Context]: [addr] },\n dna: true,\n nCounter: true,\n });\n\n await persistTransformResult({ resTransform: resNewContext, space });\n\n if (contextIsSpecialIbGib) {\n const newSpecialAddr = getIbGibAddr({ ibGib: resNewContext.newIbGib });\n const specialType = getSpecialTypeFromIb({ ib: ibGib_Context.ib });\n const configKey = getSpecialConfigKey({ type: specialType });\n await setConfigAddr({ key: configKey, addr: newSpecialAddr, space, zeroSpace, fnUpdateBootstrap });\n }\n\n await registerNewIbGib({ ibGib: resNewContext.newIbGib, fnBroadcast, space, });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function spaceNameIsValid(name: string): boolean {\n const lc = `[${spaceNameIsValid.name}]`;\n try {\n // non-falsy\n if (!name) {\n console.error(`${lc} name is falsy`)\n return false;\n }\n\n // valid characters are alphanumerics, numbers, underscores, hyphens\n const regexOnlyIncluded = /[\\w-]+/;\n const matchOnlyIncluded = name.match(regexOnlyIncluded);\n if (matchOnlyIncluded?.length !== 1 || matchOnlyIncluded[0].length !== name.length) {\n console.error(`${lc} name can only contain letters, numbers, underscores, hyphens`);\n return false;\n }\n\n // start with alphanumeric\n const regexStart = /[a-zA-Z\\d]/;\n const matchStart = name[0].match(regexStart);\n if (!matchStart) {\n console.error(`${lc} name must start with a letter or number`);\n return false;\n }\n\n return true;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return false;\n }\n}\n\n/**\n * wrapper for getting dependency graph from a space.\n *\n * NOTE: This calls the witness space with the command. This is NOT the\n * same as the logic helper in graph-helper.mts which performs the graph\n * traversal logic potentially in-memory or naively.\n */\nexport async function getDependencyGraph({\n space,\n ibGibAddrs,\n live,\n}: {\n space: IbGibSpaceAny,\n ibGibAddrs: IbGibAddr[],\n live?: boolean,\n}): Promise<{ [addr: string]: IbGib_V1 } | null> {\n const lc = `[${getDependencyGraph.name}]`;\n try {\n if (!space) { throw new Error(`space required (E: 8f2441c099084898953153549725f778)`); }\n if ((ibGibAddrs ?? []).length === 0) { throw new Error(`ibGibAddrs required (E: 9c3b8853609841808093153927649526)`); }\n\n const argData: any = {\n cmd: IbGibSpaceOptionsCmd.get,\n cmdModifiers: [IbGibSpaceOptionsCmdModifier.dependencyGraph],\n ibGibAddrs,\n live,\n };\n const arg = await space.argy({ argData });\n\n const result = await space.witness(arg);\n if (result?.data?.success) {\n const graph: { [addr: string]: IbGib_V1 } = {};\n if (result.ibGibs) {\n for (const ibGib of result.ibGibs) {\n const addr = getIbGibAddr({ ibGib });\n graph[addr] = ibGib;\n }\n }\n return graph;\n } else {\n return null;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import {\n HashAlgorithm, clone, extractErrorMsg, groupBy, hash, pretty\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs'\nimport { UUID_REGEXP } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { Ib, IbGibAddr, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbAndGib, getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { Factory_V1 } from '@ibgib/ts-gib/dist/V1/factory.mjs';\nimport { GIB, FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES, GIB_DELIMITER, ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';\nimport { validateIb } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport { getGib, getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT, IB_REGEXP_DEFAULT } from '../../core-constants.mjs';\nimport { SpecialIbGibType } from './other-types.mjs';\nimport { INVALID_DATE_STRING, SPECIAL_IBGIB_TYPE_REGEXP } from './other-constants.mjs';\nimport { CONFIG_KEY_ATOM } from './ibgib-constants.mjs';\nimport { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';\nimport { getFromSpace } from '../../witness/space/space-helper.mjs';\nimport { FlatIbGibGraph } from './graph-types.mjs';\nimport { IbGibSpaceResultData } from '../../witness/space/space-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n/**\n * Gets ibgibs that are directly related to the given `ibGib` via `rel8nNames`.\n *\n * @returns map of rel8nName -> ibgibs that are related.\n */\nexport async function getRel8dIbGibs({\n ibGib,\n rel8nNames,\n space,\n}: {\n ibGib: IbGib_V1,\n rel8nNames?: string[],\n space: IbGibSpaceAny,\n}): Promise<{ [rel8nName: string]: IbGib_V1[] }> {\n const lc = `[${getRel8dIbGibs.name}]`;\n try {\n if (!ibGib) { throw new Error(`ibGib required (E: a3c1b2d4e5f6a7b8c9d0e1f2a3b4c5d6)`); }\n if (!space) { throw new Error(`space required (E: b4d2c3e4f5a6b7c8d9e0f1a2b3c4d5e6)`); }\n\n // Default to all rel8n names if none provided\n if (!rel8nNames) {\n rel8nNames = Object.keys(ibGib.rel8ns || {});\n }\n\n const rel8dIbGibs: { [rel8nName: string]: IbGib_V1[] } = {};\n\n for (const rel8nName of rel8nNames) {\n const rel8dAddrs = ibGib.rel8ns?.[rel8nName] || [];\n\n if (rel8dAddrs.length > 0) {\n const resGet = await getFromSpace({ addrs: rel8dAddrs, space });\n if (resGet.success && resGet.ibGibs?.length === rel8dAddrs.length) {\n rel8dIbGibs[rel8nName] = resGet.ibGibs.concat();\n } else {\n // Start logging warnings instead of throwing immediately?\n // For now, consistent with user request to adapt legacy code\n throw new Error(`Problem getting rel8d ibgibs for rel8nName: ${rel8nName}. ${resGet.errorMsg || 'Unknown error'} (E: c5e3d4f5a6b7c8d9e0f1a2b3c4d5e6)`);\n }\n } else {\n rel8dIbGibs[rel8nName] = [];\n }\n }\n\n return rel8dIbGibs;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Utility function to generate hard-coded ibgibs to use at runtime \"on-chain\" but\n * written at compile-time in (for now) \"off-chain\" source code.\n *\n * Because this is supposed to create and re-create deterministically the equivalent\n * of a non-primitive ibgib \"constant\", this function creates a single ibgib with...\n * * one ancestor\n * * no past, dna, or tjp rel8ns\n * * no tjp timestamp or uuid\n * * no nCounter\n *\n * ## validation\n *\n * * validates the given `ib` against `ibRegExpPattern` or default regexp.\n * * validates that rel8ns doesn't include default forbidden rel8n names or\n * atow `'tjp'`.\n *\n * ## intent\n *\n * I want to be able to create deterministic ibGibs that I can reference at\n * runtime, similar to an ibgib primitive (e.g. \"root^gib\"), but with the\n * integrity of the `gib` hash. This way, I can reference a deterministic ibgib\n * from code at compile time, and at runtime this will have a corresponding\n * ibgib datum with gib-hashed integrity.\n *\n * ## example\n *\n * I want to create a \"hard-coded\" schema ibgib that I rel8 to some protocol\n * ibgib. So I'll create the data here, which lives in source control in a text file,\n * and then I'll render that as an ibgib that verifies integrity. If I as a coder change\n * it at all, then the `gib` of course will be different.\n */\nexport async function constantIbGib<\n TData extends IbGibData_V1 = any,\n TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1\n>({\n parentPrimitiveIb,\n ib,\n ibRegExpPattern,\n data,\n rel8ns,\n}: {\n parentPrimitiveIb: Ib,\n ib: Ib,\n /**\n * for checking the constant's generated ib\n */\n ibRegExpPattern?: string,\n data?: TData,\n rel8ns?: TRel8ns,\n}): Promise<IbGib_V1<TData, TRel8ns>> {\n const lc = `[${constantIbGib.name}]`;\n try {\n // validation\n // parentPrimitiveIb\n if (!parentPrimitiveIb) { throw new Error(`parentPrimitiveIb required. (E: 88ddf188cc5a4340b597abefba1481e2)`); }\n if (validateIb({ ib: parentPrimitiveIb }) !== null) { throw new Error(`Invalid parentPrimitiveIb: ${parentPrimitiveIb}. (E:5aec0320956d492ebeeaca41eb1fe1c6)`); }\n\n // ib\n if (!ib) { throw new Error(`ib required. (E: 7bbc88f4f2e842d6b00126e55b1783e4)`); }\n const regExp = ibRegExpPattern ? new RegExp(ibRegExpPattern) : IB_REGEXP_DEFAULT;\n if (!ib.match(regExp)) { throw new Error(`invalid ib. does not match regexp (${regExp})`); }\n\n // rel8ns\n const incomingRel8nNames = Object.keys(rel8ns ?? {});\n const forbiddenRel8nNames = [...FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES, 'tjp'];\n const rel8nsIsInvalid = incomingRel8nNames.some(x => {\n // we don't want constants trying to look like they have/are descendants/tjps/etc.\n return forbiddenRel8nNames.includes(x);\n });\n if (rel8nsIsInvalid) { throw new Error(`Invalid rel8ns. forbiddenRel8nNames: ${forbiddenRel8nNames}. rel8ns keys: ${Object.keys(rel8ns ?? {})}. (E: 837a993c265c4362b6aa0b1a234ea5f8)`); }\n\n\n // create the constant\n const resFirstGen = await Factory_V1.firstGen({\n ib,\n parentIbGib: Factory_V1.primitive({ ib: parentPrimitiveIb }),\n data,\n rel8ns,\n dna: false,\n noTimestamp: true,\n nCounter: false,\n });\n const constantIbGib = resFirstGen.newIbGib as IbGib_V1<TData, TRel8ns>;\n\n // remove any extraneous stuff\n if (constantIbGib?.rel8ns?.past) { delete constantIbGib.rel8ns.past; }\n if (constantIbGib?.rel8ns?.tjp) { delete constantIbGib.rel8ns.tjp; }\n if (constantIbGib?.rel8ns?.identity) { delete constantIbGib.rel8ns.identity; }\n\n // recalculate the gib hash\n // constantIbGib.gib = await sha256v1({\n constantIbGib.gib = await getGib({\n ibGib: {\n ib: constantIbGib.ib,\n data: constantIbGib.data,\n rel8ns: constantIbGib.rel8ns,\n },\n hasTjp: false,\n });\n\n return constantIbGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Binaries require special handling, since they do not conform to the\n * \"normal\" IbGib_V1 data structure per se. This stems from wanting to\n * be able to have binaries (jpgs, gifs, etc. especially) able to\n * sit on a server and be served as regular files.\n *\n * @returns string in expected template for binaries in this app.\n */\nexport function getBinIb({ binHash, binExt, binEncoding }: { binHash: string, binExt?: string, binEncoding?: string }): IbGibAddr {\n if (binEncoding) {\n // adding this part after the fact here. not sure how this is going to\n // go down. just noting because of the strange shape of the logic here.\n return binExt ? `bin ${binHash} ${binExt} enc=${binEncoding}` : `bin ${binHash} enc=${binEncoding}`;\n } else {\n return binExt ? `bin ${binHash} ${binExt}` : `bin ${binHash}`;\n }\n}\n\n/**\n * @deprecated\n *\n * use {@link parseBinIb}\n */\nexport function getBinHashAndExt({ addr }: { addr: IbGibAddr }): { binHash: string, binExt: string, binEncoding?: string } {\n return parseBinIb({ addr });\n}\n\n/**\n * parses a given addr that is expected to be for a {@link BinIbGib_V1}.\n *\n * @throws an error if addr is not for a {@link BinIbGib_V1} (via {@link isBinary})\n *\n * @returns parsed bin ib information\n */\nexport function parseBinIb({ addr }: { addr: IbGibAddr }): { binHash: string, binExt: string, binEncoding?: string } {\n const lc = `[${parseBinIb.name}]`;\n try {\n if (!isBinary({ addr })) { throw new Error(`not a bin address (E: df0804d129bc4888bd6939cb76c5e0f6)`); }\n const { ib } = getIbAndGib({ ibGibAddr: addr });\n const ibPieces = ib.split(' ');\n if (ibPieces.length === 2) {\n // bin ${binHash}\n return {\n binHash: ibPieces[1],\n binExt: '',\n // binEncoding: undefined,\n };\n } else if (ibPieces.length === 3) {\n // could be\n // bin ${binHash} enc=${binEncoding}\n // or...\n // bin ${binHash} ${binExt}\n return ibPieces[2].startsWith(\"enc=\") ?\n {\n binHash: ibPieces[1],\n binExt: '',\n binEncoding: ibPieces[2].substring(\"enc=\".length),\n } :\n {\n binHash: ibPieces[1],\n binExt: ibPieces[2],\n // binEncoding: undefined,\n };\n } else if (ibPieces.length === 4) {\n if (!ibPieces[3].startsWith(\"enc=\")) {\n throw new Error(`bin ib (${ib}) has 4 space-delimited pieces. we expect therefore the form to be bin \\${binHash} \\${binExt} enc=\\${binEncoding}. but ibPieces[3] doesn't start with \"enc=\". (E: 87196d7cdd7c12d982cc8204a1163524)`);\n }\n return {\n binHash: ibPieces[1],\n binExt: ibPieces[2],\n binEncoding: ibPieces[3].substring(\"enc=\".length),\n };\n } else {\n throw new Error(`(UNEXPECTED) ibPieces.length not 2, 3, or 4? atow (01/2024) the only components of a bin ib are: atom, binHash, binExt, binEncoding. binExt and binEncoding are optional, with binEncoding being prefixed with \"enc=\". (E: b05df3c1b3949f76464a83c9fd1c4f24)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * atow (01/2024) this looks to see...\n *\n * * that data is truthy (if ibGib is truthy)\n * * gib is a UUID\n *\n * ## dev note\n *\n * this is tightly coupled with {@link getBinIb} and {@link parseBinIb}\n *\n * @returns true if analysis of ibgib indicates it is a {@link BinIbGib_V1}, else false\n */\nexport function isBinary({\n ibGib,\n addr,\n}: {\n ibGib?: IbGib_V1,\n addr?: IbGibAddr,\n}): boolean {\n const lc = `[${isBinary.name}]`;\n try {\n // probably overkill here, but...\n if (!ibGib && !addr) { throw new Error(`either ibGib or addr required. (E: c935b51e773f41a2a547c556e9dc16c6)`); }\n if (ibGib && !ibGib.data) { return false; }\n addr = addr || getIbGibAddr({ ibGib });\n const { ib, gib } = getIbAndGib({ ibGibAddr: addr });\n if (!ib) { return false; }\n if (!gib) { return false; }\n if (!ib.startsWith('bin ')) { return false; }\n\n // at this point any weirdness throws an error, because the ib plainly\n // indicates this is a bin ibgib.\n\n if (gib.length !== 64) {\n throw new Error(`ib starts with \"bin \" but gib length is not 64, so return false. Two things: 1) bin ibgibs are expected to be stones, i.e., have no temporal junction point and only a single punctiliar hash for the gib. the default hash used atow (01/2024) is sha-256, so the length should be 64. But this may not be true if using another hash algorithm. need to change this function when this becomes the case. (W: 60725d65d13c4b4fbb7b96d7feb19d67)`);\n }\n\n // tightly coupled here with parsing algorithm\n\n const ibPieces = ib.split(' ');\n if (ibPieces.length === 2) {\n // bin ${binHash}\n if (!ibPieces[1].match(UUID_REGEXP)) {\n throw new Error(`(UNEXPECTED) ib starts with \"bin \" but space-delimited !ibPieces[1].match(UUID_REGEXP)? (E: f6baca2ff155f1017b278a5d7597a224)`);\n }\n } else if (ibPieces.length === 3) {\n // could be\n // bin ${binHash} enc=${binEncoding}\n // or...\n // bin ${binHash} ${binExt}\n if (!ibPieces[1].match(UUID_REGEXP)) {\n throw new Error(`(UNEXPECTED) ib starts with \"bin \" but space-delimited !ibPieces[1].match(UUID_REGEXP)? (E: 8d0443d6cada4b50be79a8390a7a426c)`);\n }\n } else if (ibPieces.length === 4) {\n if (!ibPieces[1].match(UUID_REGEXP)) {\n throw new Error(`(UNEXPECTED) ib starts with \"bin \" but space-delimited !ibPieces[1].match(UUID_REGEXP)? (E: 3209eacc0a3848a59593d4c3ee956191)`);\n }\n // bin ${binHash} ${binExt} enc=${binEncoding}\n if (!ibPieces[3].startsWith(\"enc=\")) {\n throw new Error(`(UNEXPECTED) ib starts with \"bin \" but space-delimited !ibPieces[3].startsWith(\"enc=\")? (E: 4c8a0c3b07a90d30e3d1a4373d57d824)`);\n }\n } else {\n throw new Error(`(UNEXPECTED) ib starts with \"bin \" but space-delimited ibPieces length is not 2, 3 or 4? (E: c7eccf88518304997c7e42b32e08d224)`);\n }\n\n // passed gauntlet\n return true;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Recursively hashes some string {@link recursionCount} number of times.\n */\nexport async function hash16816({\n s,\n algorithm,\n recursionCount,\n saltPrependedPerHash,\n}: {\n /**\n * string to hash\n */\n s: string,\n /**\n * algorithm to use. defaults to 'SHA-256'\n */\n algorithm: HashAlgorithm,\n /**\n * number of recursions to do. Defaults to 16816.\n */\n recursionCount: number,\n saltPrependedPerHash: string,\n}): Promise<string> {\n const lc = `[${hash16816.name}]`;\n try {\n saltPrependedPerHash ??= '';\n recursionCount ??= 16816;\n algorithm ??= 'SHA-256';\n let hashed: string = '';\n if (saltPrependedPerHash) {\n for (let i = 0; i < recursionCount; i++) {\n hashed = await hash({ s: saltPrependedPerHash + s, algorithm });\n }\n } else {\n for (let i = 0; i < recursionCount; i++) {\n hashed = await hash({ s, algorithm });\n }\n }\n return hashed;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * creates atow (10/2023) space-delimited ib in the form of `meta special ${type}`.\n *\n * @returns ib for given `type`\n * @throws error if `type` doesn't match {@link SPECIAL_IBGIB_TYPE_REGEXP}\n *\n * @see {@link getSpecialTypeFromIb}\n * @see {@link SPECIAL_IBGIB_TYPE_REGEXP}\n */\nexport function getSpecialIbGibIb({ type }: { type: SpecialIbGibType }): Ib {\n if (!type.match(SPECIAL_IBGIB_TYPE_REGEXP)) {\n throw new Error(`special ibgib type must not have spaces and just be alphanumerics. regexp: ${SPECIAL_IBGIB_TYPE_REGEXP.source} (E: 6c1c92521b7f076cc4666e4915593723)`);\n }\n return `meta special ${type}`;\n}\n\n/**\n * extracts the {@link SpecialIbGibType} from the given `ib`.\n *\n * @returns type {@link SpecialIbGibType}\n *\n * @see {@link getSpecialIbGibIb}\n * @see {@link SPECIAL_IBGIB_TYPE_REGEXP}\n */\nexport function getSpecialTypeFromIb({ ib }: { ib: Ib }): SpecialIbGibType {\n const lc = `[${getSpecialTypeFromIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: c82ba222bd345ee6b695df4d63a23322)`); }\n if (!ib) { throw new Error(`ib required (E: 08897145f7138e644fe01c4a59353322)`); }\n if (!isSpecial({ ib })) { throw new Error(`ib is not special (E: 174aff63b992adff3ac2394643735922)`); }\n const pieces = ib.split(' ');\n if (pieces.length < 3) { throw new Error(`invalid ib. should be space-delimited in form of \"meta special [type]\" (E: ffd89e2cbe63427f98634ab897aab222)`); }\n const specialType = pieces[2];\n if (!Object.values(SpecialIbGibType).some(x => x === specialType)) {\n console.warn(`unknown special type (${specialType}). This may be expected, but atow I am adding special types to the SpecialIbGibType enum-like. (W: f4e26c3ebb57fe49d69014a4ba32a922)`);\n }\n return (specialType as SpecialIbGibType);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * gets a special ib and tacks on ^gib for a constant address.\n *\n * used in primitives (ancestors for special ibgibs), as well as as of atow\n * (11/2023) the \"latest\" special ibgib.\n *\n * @returns special IbGibAddr\n */\nexport function getSpecialIbGibAddr({ type }: { type: SpecialIbGibType }): string {\n const ib = getSpecialIbGibIb({ type });\n return `${ib}^${GIB}`;\n}\n\nexport function getSpecialConfigKey({ type }: { type: SpecialIbGibType }): string {\n return `${CONFIG_KEY_ATOM} ${getSpecialIbGibAddr({ type })}`;\n}\n\nexport function isSpecial({ ib, ibGib }: { ib?: Ib, ibGib?: IbGib_V1 }): boolean {\n if (!ib && !ibGib?.ib) { throw new Error(`either ib or ibGib.ib required (E: b4cf539638d7966c2e351987f55e1a23)`); }\n return (ib ?? ibGib?.ib)?.startsWith('meta special')!;\n}\n\n/**\n * returns ib for a given root. ATOW this is simply \"root {text}\"\n *\n * @returns ib for the given rootText\n */\nexport function getRootIb(rootText: string): string {\n const lc = `[${getRootIb.name}]`;\n if (!rootText) { throw new Error(`${lc} text required.`) }\n return `root ${rootText}`;\n}\n\n/**\n * Tags for this app have the form: tag [tagText]\n *\n * @param tagText e.g. \"Favorites\"\n *\n * @example\n * For the Favorites tag, the ib would be \"tag Favorites\"\n */\nexport function tagTextToIb(tagText: string): string {\n const lc = `[${tagTextToIb.name}]`;\n if (!tagText) { throw new Error(`${lc} tag required.`) }\n return `tag ${tagText}`;\n}\n\n/**\n * Living: has tjp and dna.\n * Stones: does not have Dna, maybe has tjp.\n *\n * Splits the given `ibGibs` into two maps, one that includes the ibgibs that\n * have a tjp (temporal junction point) AND dna (\"living\") and those that do not\n * have both tjp AND dna (\"stones\").\n *\n * ## notes\n *\n * Having dna implies having a tjp, but the reverse is not necessarily true.\n * Sometimes you want an ibgib that has a tjp so you can, e.g., reference the\n * entire timeline easily. But at the same time you don't want to keep track of\n * the transforms, perhaps this is because you don't want to be able to merge\n * timelines.\n */\nexport function splitPerTjpAndOrDna({\n ibGibs,\n filterPrimitives,\n}: {\n ibGibs: IbGib_V1[],\n filterPrimitives?: boolean,\n}): {\n /** ibgibs have both tjp and dna */\n mapWithTjp_YesDna: { [gib: string]: IbGib_V1 },\n /** ibgibs have tjp but NO dna */\n mapWithTjp_NoDna: { [gib: string]: IbGib_V1 },\n /** ibgibs that have no tjp (and implicitly no dna) */\n mapWithoutTjps: { [gib: string]: IbGib_V1 }\n} {\n const lc = `[${splitPerTjpAndOrDna.name}]`;\n try {\n const mapWithTjp_YesDna: { [gib: string]: IbGib_V1 } = {};\n const mapWithTjp_NoDna: { [gib: string]: IbGib_V1 } = {};\n const mapWithoutTjps: { [gib: string]: IbGib_V1 } = {};\n // const mapLivingIbGibs: { [gib: string]: IbGib_V1 } = {};\n // const mapStoneIbGibs: { [gib: string]: IbGib_V1 } = {};\n const ibGibsTodo = filterPrimitives ?\n ibGibs.filter(ibGib => ibGib.gib ?? ibGib.gib !== GIB) :\n ibGibs;\n ibGibsTodo.forEach(ibGib => {\n if (hasTjp({ ibGib })) {\n if ((ibGib.rel8ns?.dna ?? []).length > 0) {\n mapWithTjp_YesDna[ibGib.gib!] = ibGib;\n } else {\n mapWithTjp_NoDna[ibGib.gib!] = ibGib;\n }\n } else {\n mapWithoutTjps[ibGib.gib!] = ibGib;\n }\n });\n return { mapWithTjp_YesDna, mapWithTjp_NoDna, mapWithoutTjps };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Takes incoming `ibGibs`, filters out those that do\n * not have tjps( i.e. non-timelines), and groups\n * the timeline ibgibs by tjp in ascending order.\n *\n * This means that each map entry will be in the form:\n * `[tjpAddr] => [ibgib0 (tjp), ibgib1, ibgib2, ..., ibgibN (latest)]`\n *\n * ## notes\n *\n * * sorts by `ibgib.data.n`. If this is undefined, will not sort in ascending\n * order properly.\n *\n * @returns filtered, sorted map of incoming `ibGibs` [tjpAddr] => timeline [ibgib0 (tjp), ibgib1, ibgib2, ..., ibgibN (latest)]\n */\nexport function getTimelinesGroupedByTjp({\n ibGibs,\n}: {\n /**\n * group of source ibGibs to filter/group/sort by tjp.\n */\n ibGibs: IbGib_V1[],\n}): { [tjpAddr: string]: IbGib_V1[] } {\n const lc = `[${getTimelinesGroupedByTjp.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n // pull out only the ibgibs in timelines (either is tjp or has tjp)\n let { mapWithTjp_YesDna, mapWithTjp_NoDna } =\n splitPerTjpAndOrDna({ ibGibs, filterPrimitives: true });\n const mapIbGibsWithTjp = { ...mapWithTjp_YesDna, ...mapWithTjp_NoDna };\n const ibGibsWithTjp = Object.values(mapIbGibsWithTjp);\n\n const mapTjpTimelines_Ascending = groupBy({\n items: ibGibsWithTjp,\n keyFn: x => {\n // x.data?.isTjp ? getIbGibAddr({ ibGib: x }) : (x.rel8ns?.tjp[0] ?? '') // converting this untested...hmm\n if (x.data?.isTjp) {\n return getIbGibAddr({ ibGib: x });\n } else if (x.rel8ns?.tjp) {\n return x.rel8ns?.tjp[0] ?? '';\n } else {\n if (logalot) { console.log(`${lc} neither isTjp nor x.rel8ns.tjp truthy (I: ec9a5597bf53dec1bd3d83350abbf823)`); }\n return '';\n }\n\n }\n });\n\n if (logalot) { console.log(`${lc} sorting (ascending) ibGibsWithTjpGroupedByTjpAddr: ${pretty(mapTjpTimelines_Ascending)} (I: 9b9fff5ce61444a6cb06d62db9a99422)`); }\n Object.entries(mapTjpTimelines_Ascending).forEach(([_tjpAddr, timeline]) => {\n if (timeline.some(ibGib => ibGib.data?.n === undefined)) {\n console.warn(`${lc} timeline includes ibgibs with ibGib.data?.n === undefined (W: cab9a6b64a38c4279fe82c3569bbab22)`);\n }\n // sort mutates array in place\n timeline.sort((a, b) => (a.data?.n ?? -1) > (b.data?.n ?? -1) ? 1 : -1); // sorts ascending, e.g., 0,1,2...[Highest]\n });\n if (logalot) { console.log(`${lc} after sort ibGibsWithTjpGroupedByTjpAddr: ${pretty(mapTjpTimelines_Ascending)} (I: 9b9fff5ce61444a6cb06d62db9a99422)`); }\n\n return mapTjpTimelines_Ascending; // ascending\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Helper function that checks the given `ibGib` to see if it\n * either has a tjp or is a tjp itself.\n *\n * ## notes\n *\n * Only unique ibGibs are meant to have tjps, or rather, if an\n * ibGib timeline is expected to be unique over \"time\", then the\n * tjp is an extremely convenient mechanism that provides a\n * \"name\" for that timeline.\n *\n * Otherwise, if they are not unique, then successive \"different\"\n * timelines cannot be easily referenced by their first unique\n * frame in time, making it much harder to pub/sub updates among\n * other things. (If there are no unique frames, then they are\n * the same ibGib.)\n *\n * ## tjp = temporal junction point\n *\n * I've written elsewhere on this as well. Refer to B2tF2.\n *\n * @returns true if the ibGib has/is a tjp, else false\n */\nexport function hasTjp({ ibGib }: { ibGib: IbGib_V1 }): boolean {\n const lc = `[${hasTjp.name}]`;\n\n if (!ibGib) { throw new Error(`(UNEXPECTED) ibGib falsy? (E: ce3a59f9db14e6158bb2c438ca1a3823)`); }\n\n // most likely is that rel8ns.tjp has an entry or the internal data.isTjp\n if ((ibGib.rel8ns?.tjp?.length ?? 0) > 0 || ibGib.data?.isTjp) {\n return true; /* <<<< returns early */\n }\n\n // dna transforms do not have tjp\n const dnaPrimitives = ['fork^gib', 'mut8^gib', 'rel8^gib'];\n if ((ibGib.rel8ns?.ancestor ?? []).some(x => dnaPrimitives.includes(x))) {\n return false; /* <<<< returns early */\n }\n\n if (!ibGib.gib) {\n console.warn(`${lc} ibGib.gib falsy. (W: 6400d780822b44d992846f1196509be3)`);\n return false; /* <<<< returns early */\n }\n if (ibGib.gib.includes(GIB_DELIMITER)) {\n return true; /* <<<< returns early */\n }\n\n if (ibGib.gib === GIB) {\n // primitive\n return false; /* <<<< returns early */\n }\n\n // at this point, we've already determined most likely what the result is.\n // definitively, we'll pass the buck to getGibInfo in case implementation\n // details change in the future. it is a more expensive call. could\n // possibly just return false at this point, but since gib info would change\n // if we change our standards for gib, this is nicer.\n const gibInfo = getGibInfo({ ibGibAddr: getIbGibAddr({ ibGib }) });\n return !!gibInfo.tjpGib;\n}\n\nexport function hasDna({ ibGib }: { ibGib: IbGib_V1 }): boolean {\n const lc = `[${hasDna.name}]`;\n\n if (!ibGib) {\n console.warn(`${lc} ibGib falsy. (W: 5fd19751f5c84da59d83dd33487ed859)`);\n return false;\n }\n\n return (ibGib.rel8ns?.dna ?? []).length > 0;\n}\n\n/**\n * Extracts the tjp addr from the ibgib record. If there is no tjp addr found,\n * then refers to `defaultIfNone` arg to determine if it returns undefined or\n * the incoming ibgib's addr.\n * @returns extracted tjp addr or undefined, depending on if found and defaultIfNone value\n */\nexport function getTjpAddr({\n ibGib,\n defaultIfNone = 'undefined',\n}: {\n ibGib: IbGib_V1,\n defaultIfNone?: 'incomingAddr' | 'undefined',\n}): IbGibAddr | undefined {\n const lc = `[${getTjpAddr.name}]`;\n try {\n const tjpMap = getTjpAddrs({ ibGibs: [ibGib], defaultIfNone });\n return tjpMap && Object.keys(tjpMap).length === 1 ? Object.values(tjpMap)[0] : undefined;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * builds a map of the given ibgib's addrs to each's corresponding tjp addr.\n *\n * @returns a map of ibgib addr -> tjp addr\n */\nexport function getTjpAddrs({\n ibGibs,\n defaultIfNone = 'undefined',\n}: {\n ibGibs: IbGib_V1[],\n defaultIfNone?: 'incomingAddr' | 'undefined',\n}): { [ibGibAddr: IbGibAddr]: IbGibAddr | undefined } {\n const lc = `[${getTjpAddrs.name}]`;\n try {\n const resultMap: { [ibGibAddr: IbGibAddr]: IbGibAddr | undefined } = {};\n\n ibGibs.forEach(ibGib => {\n let ibGibAddr = getIbGibAddr({ ibGib });\n let tjpAddr: IbGibAddr | undefined;\n if (ibGib.rel8ns?.tjp?.length ?? 0 > 0) {\n // get the last tjp addr atow\n tjpAddr = ibGib.rel8ns!.tjp![ibGib.rel8ns!.tjp!.length - 1];\n } else if (ibGib.data?.isTjp || defaultIfNone === 'incomingAddr') {\n // either the incoming addr is the tjp or we're defaulting to it per defaultIfNone arg\n tjpAddr = ibGibAddr;\n } else {\n // explicitly set to undefined per defaultIfNone arg\n tjpAddr = undefined;\n }\n resultMap[ibGibAddr] = tjpAddr;\n });\n\n return resultMap;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Returns true if the given {@param ibGib} is the temporal junction\n * point for a given ibGib timeline.\n */\nexport async function isTjp_Naive({\n ibGib,\n naive = true,\n}: {\n ibGib: IbGib_V1<any>,\n naive?: boolean,\n}): Promise<boolean> {\n const lc = `[${isTjp_Naive.name}]`;\n try {\n if (!ibGib) { throw new Error('ibGib required.'); }\n if (naive) {\n if (ibGib.data) {\n if (ibGib.data.isTjp) { return true; }\n if (!ibGib.rel8ns) {\n if (logalot) { console.log(`${lc} ibGib.rel8ns falsy (I: c69c9e78b34845311ce7c674d7195622)`); }\n return false;\n }\n if (ibGib.rel8ns.past && ibGib.rel8ns.past.length > 0) { return false; }\n if (ibGib.rel8ns.past && ibGib.rel8ns.past.length === 0) { return true; }\n return false;\n } else {\n throw new Error('loaded ibGib required (data).');\n }\n } else {\n throw new Error('only naive implemented right now.');\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport function toDto<TData = IbGibData_V1, TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1>({\n ibGib,\n}: {\n ibGib: IbGib_V1,\n}): IbGib_V1<TData, TRel8ns> {\n const lc = `[${toDto.name}]`;\n if (!ibGib.ib) { console.warn(`${lc} ibGib.ib is falsy. (W: e60e41c2a1fc48268379d88ce13cb77b)`); }\n if (!ibGib.gib) { console.warn(`${lc} ibGib.gib is falsy. (W: fb3889cbf0684ae4ac51e48f28570377)`); }\n\n\n let dtoIbGib: IbGib_V1<TData, TRel8ns> = { ib: (ibGib.ib || '').slice() };\n if (ibGib.gib) { dtoIbGib.gib = ibGib.gib.slice(); };\n if (ibGib.data) {\n if (isBinary({ ibGib })) {\n // binary has data of Uint8Array atow (02/2024)\n dtoIbGib.data = (ibGib.data as Uint8Array).slice() as any;\n } else {\n dtoIbGib.data = clone(ibGib.data);\n }\n }\n if (ibGib.rel8ns) { dtoIbGib.rel8ns = clone(ibGib.rel8ns); }\n\n return dtoIbGib;\n}\n\n/**\n * helpful for differentiating discriminated unions.\n *\n * technically, atow, anything with an ib meets the minimum requirements for an\n * ibgib. this is because you can think of any value as being a metadata\n * \"header\" with other derivative & metadatas as being absent.\n *\n * For example, a string value \"my string yo\" is all you have to go on if you\n * don't have a hash which would be metadata about that value. its address would\n * be \"my string yo^gib\" as it's a primitive, and its intrinisic data would just\n * be a duplicate of the ib, so it's left undefined, and there are no extrinsic\n * rel8ns so rel8ns would be undefined.\n *\n * ## driving use case\n *\n * In doing rxjs replacement, I'm needing to tell if an error coming down the\n * pipe is ErrorIbGib_V1 | Error | string.\n *\n * @param obj any object. note: if falsy, returns false\n * @returns true if the obj is an ibgib, else false\n */\nexport function isIbGib(obj: any): boolean {\n const lc = `[${isIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 57aef93fc6cc2309523b5c72a6b11823)`); }\n // technically\n return !!obj && typeof obj.ib === 'string';\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * extracts timestamp info from the given `ibGib`.\n *\n * ## about\n *\n * not all ibGibs have timestamps (data.timestamp) and they may be in the form\n * of a timestamp string. this may actually be a timestamp string for a Date\n * object or it could be a string of ticks from date.getTime(). or maybe\n * downstream someone just does a number instead of a string.\n *\n * so this function is supposed to be good at figuring this out given an\n * `ibGib`.\n *\n * ## todo\n *\n * 1. we could add an optional path parameter that allows us to specify the\n * path(s) of things that should be timestamps.\n *\n * 2. we could have a simple extractTimestamp(value: any) that does the same\n * thing and then call that from this function.\n *\n * @returns info object that has the timestamp in various formats (if valid) or an error msg (if invalid)\n */\nexport function getTimestampInfo({\n ibGib,\n data,\n timestamp,\n}: {\n // /**\n // * ibGib from which we are extracting timestamp info.\n // */\n ibGib?: IbGib_V1;\n data?: IbGibData_V1;\n timestamp?: string;\n}): {\n valid: true;\n date: Date,\n utc: string,\n ticks: string,\n ms: number | undefined;\n} | {\n valid: false;\n emsg: string;\n} {\n const lc = `[${getTimestampInfo.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 35cb68744bcf6139d78e37de644fad23)`); }\n\n timestamp = timestamp || data?.timestamp || ibGib?.data?.timestamp;\n const ms = ibGib?.data?.timestampMs || data?.timestampMs;\n\n // ensure timestamp truthy\n if (!timestamp) {\n const emsg = `${lc} timestamp is falsy. (W: 5f1f1182c8804807b886a3d922ac3dcf)`;\n console.warn(emsg);\n return { valid: false, emsg }; /* <<<< returns early */\n }\n\n // we have a timestamp, but no idea what it actually is. supposed to be\n // a string with either a utc timestamp or a number, but check for other\n // cases as well\n\n // try it as a timestamp string\n if (typeof timestamp === 'string') {\n if (Number.isInteger(Number.parseInt(timestamp))) {\n\n // #region maybe ticks string\n const parsedTimestamp = Number.parseInt(timestamp);\n let date = new Date();\n date.setTime(parsedTimestamp);\n if (date.toString() !== INVALID_DATE_STRING) {\n // valid timestampInTicks string\n if (logalot) { console.log(`${lc} valid timestampInTicks string (I: 7069a1c3047f3bbc92b78674b20f5b23)`); }\n return {\n valid: true,\n date,\n utc: date.toUTCString(),\n ticks: date.getTime().toString(),\n ms,\n }; /* <<<< returns early */\n } else {\n const emsg = `${lc} data.timestamp (${timestamp}) is an integer string but not a valid timestampInTicks string. (produces invalid date) (E: f49fbb600fe1426c8805dfc8afbe5cf3)`;\n console.error(emsg);\n return { valid: false, emsg }; /* <<<< returns early */\n }\n // #endregion maybe ticks string\n } else {\n // #region maybe timestamp string\n let date = new Date(timestamp);\n if (date.toString() !== INVALID_DATE_STRING) {\n // valid timestamp string (may or may not be UTC)\n return {\n valid: true,\n date,\n utc: date.toUTCString(),\n ticks: date.getTime().toString(),\n ms,\n }; /* <<<< returns early */\n } else {\n const emsg = `${lc} data.timestamp is a non-integer string but not a valid date timestamp string (new date instantiated produces invalid date). (W: c6c90f7f3bfb49838d2081ba84fdb5fb)`;\n console.warn(emsg)\n return { valid: false, emsg }; /* <<<< returns early */\n }\n // #endregion maybe timestamp string\n }\n } else if (typeof (timestamp as any) === 'number') {\n if (Number.isInteger(timestamp)) {\n console.warn(`${lc} expected data.timestamp to be a string but is a number (W: 9d786f4d4e8d4279b5af7bee19bf721b)`);\n let date = new Date();\n date.setTime(timestamp as number);\n if (date.toString() !== INVALID_DATE_STRING) {\n // valid timestamp string\n return {\n valid: true,\n date,\n utc: date.toUTCString(),\n ticks: date.getTime().toString(),\n ms,\n }; /* <<<< returns early */\n } else {\n const emsg = `${lc} timestamp (${timestamp}) is an integer number but not a valid timestampInTicks (new date setTime produces invalid date). (W: c6c90f7f3bfb49838d2081ba84fdb5fb)`;\n console.warn(emsg)\n return { valid: false, emsg }; /* <<<< returns early */\n }\n } else {\n // number but not integer? hmm\n const emsg = `${lc} timestamp (${timestamp}) is a non-integer number (supposed to be a string either timestamp string or ticks). (E: 2963d95f8d3b464c992b0bff948b4479)`;\n console.error(emsg)\n return { valid: false, emsg }; /* <<<< returns early */\n }\n } else {\n const emsg = `${lc} unknown typeof timestamp (${typeof timestamp}). (E: 12458a9c16c84e4f859b5771a30dd2ef)`;\n console.error(emsg);\n return { valid: false, emsg }; /* <<<< returns early */\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * First we combine {@link readCache_graph} and {@link readCache_array} into\n * one unified cache. This can even be empty (if both empty/falsy).\n *\n * Then looks in {@link space} for all other addrs (throws if *any* not found).\n *\n * Then creates the result array, which will be in the same order as incoming\n * {@link addrs} (so this acts like a fancy .map() call).\n *\n * @throws if any addr is not found\n *\n * ## notes\n *\n * Since you can pass in empty cache(s), you can actually use this as a generic\n * getIbGibs function that throws if you don't want to use `getFromSpace` and\n * parse the results. (which is what I find I want more and more the lazier I\n * get).\n */\nexport async function getIbGibsFromCache_fallbackToSpaces({\n addrs,\n readCache_graph,\n readCache_array,\n space,\n}: {\n addrs: IbGibAddr[],\n readCache_graph?: FlatIbGibGraph,\n readCache_array?: IbGib_V1[],\n space: IbGibSpaceAny,\n}): Promise<IbGib_V1[]> {\n const lc = `[${getIbGibsFromCache_fallbackToSpaces.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5db66871239dfa05182277f886a20926)`); }\n readCache_graph ??= {};\n readCache_array ??= [];\n\n /**\n * we're going to put all ibgibs into this graph. IOW, we'll start with\n * incoming caches, then get all other addrs not found here from the\n * space in a single call. At that point, we'll be able to create the\n * result array.\n */\n const allIbGibs_graph = { ...readCache_graph };\n readCache_array.forEach(x => allIbGibs_graph![getIbGibAddr({ ibGib: x })] = x);\n\n const allCachedAddrs = Object.keys(readCache_graph);\n const addrsNotFoundInCache = addrs.filter(x => !allCachedAddrs.includes(x));\n\n\n if (addrsNotFoundInCache.length > 0) {\n if (logalot) { console.log(`${lc} ${addrsNotFoundInCache.length} addrsNotFoundInCache: ${addrsNotFoundInCache} (I: fccbd18116ffb849f813aaebfc6c0826)`); }\n\n /**\n * I changed this to spaces for a workaround but I am putting back\n * the signature to the single space. But I kind of like the idea of\n * this being able to pull from multiple spaces, so I'm leaving the\n * logic here for future.\n */\n const spaces = [space];\n let addrsStillNotFound = addrsNotFoundInCache.concat();\n for (const space of spaces) {\n const resGet = await getFromSpace({ addrs: addrsStillNotFound, space });\n if (resGet.success && resGet.ibGibs && resGet.ibGibs.length === addrsStillNotFound.length) {\n resGet.ibGibs.forEach(x => allIbGibs_graph![getIbGibAddr({ ibGib: x })] = x);\n addrsStillNotFound = [];\n } else {\n // might have gotten some ibgibs\n if (resGet.ibGibs && resGet.ibGibs.length > 0) {\n addrsStillNotFound =\n addrsStillNotFound.filter(addr =>\n !resGet.ibGibs!.some(gottenIbGib => getIbGibAddr({ ibGib: gottenIbGib }) === addr)\n );\n if (addrsStillNotFound.length === 0) {\n break;\n }\n } else {\n if (logalot) { console.log(`${lc} no addrs found in space (${space.ib}). trying next space. (I: 4f99d8bacbb10ab3f8737a752564b326)`); }\n }\n }\n }\n\n if (addrsStillNotFound.length > 0) {\n throw new Error(`could not get all addrs from cache or spaces. addrsStillNotFound: ${addrsStillNotFound}. spaces: ${spaces.map(x => x.ib).join('|')} (E: 0c6418f83dd85bda886e56f5b98f3126)`);\n }\n }\n\n // at this point, we're guaranteed to have all addrs in allIbGibs_graph,\n // but we will still check\n\n const resIbGibs: IbGib_V1[] = [];\n for (const addr of addrs) {\n // refactor this later to be less defensive if this stands the test\n // of time. (ATOW 01/28/2026)\n const ibGib = allIbGibs_graph[addr];\n if (!ibGib) { throw new Error(`(UNEXPECTED) allIbGibs_graph doesn't have addr? We're expecting logic to preclude this at this point. addr: ${addr} (E: f68e1d236ae5e3eb08da9933c8230626)`); }\n resIbGibs.push(ibGib);\n }\n\n return resIbGibs;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * naive general purpose helper guard function based off of a given ibgib's\n * `ib` property.\n *\n * uses conventional V1 `ib` schema, expecting space-delimited `ib` with the\n * first piece being the atom.\n *\n * @param x - any object, usually known to be an ibgib\n * @param atom - the expected atom that determines the type of ibgib\n * @returns true if `x.ib` contains `atom` and thus is `TIbGib`, else false\n */\nexport function isIbGibWithAtom<TIbGib extends IbGib_V1>(x: any, atom: string): x is TIbGib {\n const lc = `[${isIbGibWithAtom.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: e946f8ca70b65e6968bd8e78aa473826)`); }\n\n if (!x.ib) {\n return false; /* <<<< returns early */\n }\n\n if (typeof x.ib !== 'string') {\n return false; /* <<<< returns early */\n }\n\n const [pieceAtom, ...otherPieces] = x.ib.split(' ');\n\n if (atom !== pieceAtom) {\n return false; /* <<<< returns early */\n }\n\n return true;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "import { tagTextToIb } from \"@ibgib/core-gib/dist/common/other/ibgib-helper.mjs\";\nimport { ZERO_SPACE_ID } from \"@ibgib/core-gib/dist/witness/space/space-constants.mjs\";\nimport { IbGibAmbientContextConfig } from \"@ibgib/web-gib/dist/app-bootstrap/types.mjs\";\n\n// ---------------------------------------------------------------------------\n// Logging / debug\n// ---------------------------------------------------------------------------\n\nexport const GLOBAL_LOG_A_LOT = false;\n\n// ---------------------------------------------------------------------------\n// Storage \u2014 unique per app instance\n// ---------------------------------------------------------------------------\n\nexport const SPACE_GIB_DB_NAME = 'space_gib_db';\nexport const SPACE_GIB_STORE_NAME = 'space_gib_store';\nexport const SPACE_GIB_API_KEY_NAME = 'space_gib_api_key';\n\nexport const SPACE_GIB_INDEXEDDB_KEY_LOCAL_SPACE_NAME = 'local_space_name';\n/**\n * Prefix for the automatically generated local space name on first visit.\n * A random suffix is appended at runtime.\n */\nexport const SPACE_GIB_INDEXEDDB_LOCAL_SPACE_NAME_PREFIX = 'space_gib_';\n\n// ---------------------------------------------------------------------------\n// App identity discriminator\n// ---------------------------------------------------------------------------\n\nexport const HTML_META_APP_ID_NAME = \"ibgib-app-id\";\nexport const HTML_META_APP_ID_CONTENT = \"0c45ac92e668410190b115512d5e2d51\";\n\n// ---------------------------------------------------------------------------\n// Agent / AI (optional)\n// ---------------------------------------------------------------------------\n\nexport const GEMINI_API_KEY_REGEXP = /^[a-zA-Z0-9\\-_]{32,64}$/;\nexport const CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP = `Gemini API Key config option (\u2699\uFE0F icon)`;\n\n// ---------------------------------------------------------------------------\n// Tags\n// ---------------------------------------------------------------------------\n\nexport const TAG_AGENT_TEXT = \"agent\";\nexport const TAG_AGENT_ICON = \"body-outline\";\nexport const TAG_AGENT_DESCRIPTION =\n \"This tag tracks the active agents for the current local user space.\";\nexport const TAG_AGENT_IB = tagTextToIb(TAG_AGENT_TEXT);\n\n// ---------------------------------------------------------------------------\n// Colors\n// ---------------------------------------------------------------------------\n\nexport const DEFAULT_IBGIB_COLOR = '#78f87e88';\nexport const DEFAULT_IBGIB_TRANSLUCENT = '#78f87e10';\nexport const DEFAULT_IBGIB_COLOR_CONTRAST = '#ffffff';\nexport const DEFAULT_TJP_COLOR = '#78f87e88';\nexport const DEFAULT_TJP_COLOR_TRANSLUCENT = '#78f87e10';\nexport const DEFAULT_TJP_COLOR_CONTRAST = '#ffffff';\n\n// ---------------------------------------------------------------------------\n// Server API base URL (relative \u2014 same origin serves both API and SPA)\n// ---------------------------------------------------------------------------\n\nexport const API_BASE_URL = '/api';\n\n// ---------------------------------------------------------------------------\n// Ambient context config\n// ---------------------------------------------------------------------------\n\nexport const APP_CONFIG: IbGibAmbientContextConfig = {\n dbName: SPACE_GIB_DB_NAME,\n storeName: SPACE_GIB_STORE_NAME,\n additionalStoreNames: [ZERO_SPACE_ID],\n apiKeyName: SPACE_GIB_API_KEY_NAME,\n};\n", "/**\n * @module auto-generated-version\n *\n * CHANGES TO THIS FILE WILL NOT BE SAVED.\n * This is automatically updated during the build process.\n */\n\n/**\n * Version of space-gib, auto-updated by the build process.\n */\nexport const AUTO_GENERATED_VERSION = '0.0.1';\n", "import { tagTextToIb } from \"@ibgib/core-gib/dist/common/other/ibgib-helper.mjs\";\n\n/**\n * @internal\n * Library-internal toggle for verbose logging.\n *\n * ## Usage note\n *\n * This is an ibgib-pattern meant to be redefined per project. Downstream apps\n * should NOT import this from web-gib, but instead define their own\n * `GLOBAL_LOG_A_LOT` constant for their own logging needs.\n */\nexport const GLOBAL_LOG_A_LOT = false;\nexport const GLOBAL_TIMER_NAME = '[web^gib timer]';\n/**\n * `globalThis[GLOBAL_THIS_IBGIB_KEY]`\n *\n * So the pattern for other apps/libs is:\n *\n * `globalThis[GLOBAL_THIS_IBGIB_KEY][APP_SPECIFIC_GLOBAL_KEY]`\n *\n * and given the value of this continues to be `\"ibgib\"`:\n * `globalThis.ibgib.[APP_SPECIFIC_GLOBAL_KEY]`\n *\n * @example globalThis.ibgib.myApp\n * @example globalThis.ibgib.blankGib\n */\nexport const GLOBAL_THIS_IBGIB_KEY = 'ibgib';\n\n/**\n * regex for what we think of as a gemini api key.\n */\nexport const GEMINI_API_KEY_REGEXP = /^[a-zA-Z0-9\\-_]{32,64}$/;\nexport const CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP = `Gemini API Key Config option (\u2699\uFE0F icon in the top right)`;\n\n/**\n * used for the agent tag, in ibgib.data.text\n */\nexport const TAG_AGENT_TEXT = \"agent\";\n/**\n * used for the agent tag, in ibgib.data.icon\n */\nexport const TAG_AGENT_ICON = \"body-outline\";\n/**\n * used for the agent tag, in ibgib.data.description\n */\nexport const TAG_AGENT_DESCRIPTION = \"This tag tracks the active agents for the current local user space.\";\n/**\n * the ib value of the tag ibgib for the agents.\n */\nexport const TAG_AGENT_IB = tagTextToIb(TAG_AGENT_TEXT);\n\nexport const DEFAULT_IBGIB_COLOR = '#78f87e88';\nexport const DEFAULT_IBGIB_TRANSLUCENT = '#78f87e10';\nexport const DEFAULT_IBGIB_COLOR_CONTRAST = '#ffffff';\nexport const DEFAULT_TJP_COLOR = '#78f87e88';\nexport const DEFAULT_TJP_COLOR_TRANSLUCENT = '#78f87e10';\nexport const DEFAULT_TJP_COLOR_CONTRAST = '#ffffff';\n\n/**\n * I am toying with tagging hardcoded prompts at the moment (atow 05/2025)\n */\nexport const HARDCODED_PROMPT_TAG_TEXT = 'AUTOMATED_TEXT';\n", "import { extractErrorMsg } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\n\nimport { GLOBAL_LOG_A_LOT } from \"../../core-constants.mjs\";\nimport { FlatIbGibGraph } from \"./graph-types.mjs\";\nimport { SerializedUint8Array } from \"./other-types.mjs\";\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * @internal Helper to convert a Uint8Array to a Base64 string\n * @param uint8Array @\n * @returns Base64 string\n */\nfunction uint8ArrayToBase64(uint8Array: Uint8Array): Promise<string> {\n return new Promise((resolve, reject) => {\n const blob = new Blob([uint8Array as any], { type: 'application/octet-stream' });\n const reader = new FileReader();\n reader.onload = () => {\n const dataUrl = reader.result as string;\n // The result is a data URL: \"data:application/octet-stream;base64,...\"\n // We only want the Base64 part.\n const base64String = dataUrl.split(',')[1];\n resolve(base64String);\n };\n reader.onerror = (error) => reject(error);\n reader.readAsDataURL(blob);\n });\n}\n\n/**\n * @internal Helper to convert a Base64 string back to a Uint8Array\n * @param base64String to convert back to Uint8Array\n * @returns Uint8Array\n */\nasync function base64ToUint8Array(base64String: string): Promise<Uint8Array> {\n // Use the fetch API to decode the Base64 string.\n // This is a modern and robust way to handle Base64 in the browser.\n const dataUrl = `data:application/octet-stream;base64,${base64String}`;\n const response = await fetch(dataUrl);\n const blob = await response.blob();\n const buffer = await blob.arrayBuffer();\n return new Uint8Array(buffer);\n}\n\nexport async function serializeGraphToString({ graph }: { graph: FlatIbGibGraph }): Promise<string> {\n const lc = `[${serializeGraphToString.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 4ddb8803cf68e1d3d35f60680cb69825)`); }\n\n // 1. Serialize: Create a JSON-safe representation of the graph\n // We use a custom replacer to handle Uint8Array\n // const replacer = (key: string, value: any) => {\n // if (value instanceof Uint8Array) {\n // // This part is async, so we can't use it directly in JSON.stringify.\n // // We must pre-process the object first.\n // throw new Error(\"Cannot use async replacer. Pre-process the object first.\");\n // }\n // return value;\n // };\n\n // Pre-process the graph to handle async Base64 conversion\n const serializableGraph = JSON.parse(JSON.stringify(graph)); // Deep clone to avoid mutation\n for (const key in serializableGraph) {\n if (graph[key].data instanceof Uint8Array) {\n serializableGraph[key].data = {\n _dataType: 'Uint8Array_Base64',\n value: await uint8ArrayToBase64(graph[key].data as Uint8Array)\n } as SerializedUint8Array;\n }\n }\n\n // 2. Stringify: Convert the serializable object to a JSON string\n const jsonString = JSON.stringify(serializableGraph);\n\n if (logalot) { console.log(`${lc} jsonString.length: ${jsonString.length} (I: 56dec8ad0931ab8ba9b5ca3d4e66be25)`); }\n\n return jsonString;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Takes an incoming jsonString created via {@link serializeGraphToString}\n * and returns the original FlatIbGibGraph dto.\n *\n * @param jsonString\n * @returns graph that was originally serialized\n *\n * ## notes\n *\n * This serialize/deserialize is used in the compress/decompress fns:\n *\n * @see {@link compressIbGibToBlob}\n * @see {@link decompressIbGibFromBlob}\n * @see {@link compressIbGibGraphToString}\n * @see {@link decompressIbGibGraphFromString}\n */\nexport async function deserializeStringToGraph({ jsonString }: { jsonString: string }): Promise<FlatIbGibGraph> {\n const lc = `[${deserializeStringToGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 52e1a1fb1adcc75168fbc6d819868825)`); }\n\n const reviver = (key: string, value: any) => {\n if (value && value._dataType === 'Uint8Array_Base64') {\n // Converting base64 to Uint8Array is async, so we can't use it\n // in JSON.parse. We will post-process the object.\n return value; // Return the placeholder for now\n }\n return value;\n };\n\n const parsedGraph = JSON.parse(jsonString, reviver);\n\n // Post-process to convert Base64 back to Uint8Array\n for (const key in parsedGraph) {\n const data = parsedGraph[key].data;\n if (data && data._dataType === 'Uint8Array_Base64') {\n parsedGraph[key].data = await base64ToUint8Array(data.value);\n }\n }\n\n return parsedGraph as FlatIbGibGraph;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Compresses an FlatIbGibGraph object into a Blob.\n * @param graph The FlatIbGibGraph object to compress.\n * @returns A Promise that resolves with the compressed Blob.\n */\nexport async function compressIbGibToBlob(graph: FlatIbGibGraph): Promise<Blob> {\n const lc = `[${compressIbGibToBlob.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 8d306868b718596fe8f562bd5118d825)`); }\n\n // 1. Serialize: Create a JSON-safe representation of the graph and stringify\n const jsonString = await serializeGraphToString({graph});\n\n // 2. Encode: Convert the string to a Uint8Array (UTF-8)\n const dataToCompress = new TextEncoder().encode(jsonString);\n\n // 3. Compress: Use the Compression Streams API\n const stream = new Response(dataToCompress).body!;\n const compressedStream = stream.pipeThrough(new CompressionStream('gzip'));\n\n // Return the compressed data as a Blob\n return await new Response(compressedStream).blob();\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Decompresses a Blob back into an FlatIbGibGraph object.\n * @param compressedBlob The Blob containing the compressed graph data.\n * @returns A Promise that resolves with the original FlatIbGibGraph object.\n */\nexport async function decompressIbGibFromBlob(compressedBlob: Blob): Promise<FlatIbGibGraph> {\n // 1. Decompress: Use the Decompression Streams API\n const decompressedStream = compressedBlob.stream().pipeThrough(\n new DecompressionStream('gzip')\n );\n\n // 2. Decode: Convert the decompressed stream back to a string\n const jsonString = await new Response(decompressedStream).text();\n\n // 3. Deserialize: Parse the JSON with a reviver to restore Uint8Arrays\n const parsedGraph = await deserializeStringToGraph({jsonString});\n return parsedGraph;\n}\n\n/**\n * Compresses an FlatIbGibGraph object and returns a Base64 string representation.\n * @param graph The FlatIbGibGraph object to compress.\n * @returns A Promise that resolves with the compressed data as a Base64 string.\n */\nexport async function compressIbGibGraphToString({\n graph\n}: {\n graph: FlatIbGibGraph\n}): Promise<string> {\n const lc = `[${compressIbGibGraphToString.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 1352f8540c08f0b725952df8f18c4825)`); }\n\n // 1. Get the compressed data as a Blob first.\n const compressedBlob = await compressIbGibToBlob(graph);\n\n // 2. Convert the Blob's binary data to a Uint8Array.\n const buffer = await compressedBlob.arrayBuffer();\n const uint8Array = new Uint8Array(buffer);\n\n // 3. Convert that Uint8Array to a Base64 string.\n return await uint8ArrayToBase64(uint8Array);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Decompresses a Base64 string back into an FlatIbGibGraph object.\n * @param compressedBase64 The Base64 string containing the compressed graph data.\n * @returns A Promise that resolves with the original FlatIbGibGraph object.\n */\nexport async function decompressIbGibGraphFromString({\n compressedBase64,\n}: {\n compressedBase64: string,\n}): Promise<FlatIbGibGraph> {\n const lc = `[${decompressIbGibGraphFromString.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5f3fa940a2c8f8d7b877978ae7f87825)`); }\n\n // 1. Convert the Base64 string back to a Uint8Array.\n const compressedUint8Array = await base64ToUint8Array(compressedBase64);\n\n // 2. Create a Blob from the Uint8Array.\n // The MIME type isn't strictly necessary for DecompressionStream but is good practice.\n const compressedBlob = new Blob([compressedUint8Array as any], { type: 'application/gzip' });\n\n // 3. Use our existing function to decompress the Blob.\n return await decompressIbGibFromBlob(compressedBlob);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "export const RAW_EXPORT_ATOM = 'export';\n", "import { extractErrorMsg, getSaferSubstring, getTimestamp, getTimestampInTicks } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { Ib, IbGibAddr } from \"@ibgib/ts-gib/dist/types.mjs\";\nimport { getIbAndGib, getIbGibAddr } from \"@ibgib/ts-gib/dist/helper.mjs\";\nimport { getGib, getGibInfo } from \"@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs\";\nimport { validateIbGibIntrinsically } from \"@ibgib/ts-gib/dist/V1/validate-helper.mjs\";\n\nimport { GLOBAL_LOG_A_LOT } from \"../../core-constants.mjs\";\nimport { RawExportData_V1, RawExportIbGib_V1, RawExportIbInfo } from \"./import-export-types.mjs\";\nimport { RAW_EXPORT_ATOM } from \"./import-export-constants.mjs\";\nimport { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\nimport { MetaspaceService } from \"../../witness/space/metaspace/metaspace-types.mjs\";\nimport { IbGibSpaceAny } from \"../../witness/space/space-base-v1.mjs\";\nimport { compressIbGibGraphToString, serializeGraphToString } from \"../other/other-helper.web.mjs\";\nimport { getTjpAddr } from \"../other/ibgib-helper.mjs\";\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * builds the ib for a {@link RawExportIbGib_V1}\n */\nexport function getRawExportIb({\n data,\n}: {\n data: RawExportData_V1,\n}): Ib {\n const lc = `[${getRawExportIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 158dfaeb9613a1531be71a9735184624)`); }\n const { graphSize, dependencyGraphAsString, timestamp } = data;\n const graphStringLength = dependencyGraphAsString.length;\n const timestampInTicks = getTimestampInTicks(timestamp);\n const compressDescription = data.compression === 'gzip' ? 'gzip' : 'raw';\n\n if (!data.timestamp) { throw new Error(`(UNEXPECTED) data.timestamp falsy? (E: 2f5bc88488cbf260634239a8a8396825)`); }\n const date = new Date(data.timestamp);\n\n const { ib, gib } = getIbAndGib({ ibGibAddr: data.contextIbGibAddr });\n const gibInfo = getGibInfo({ gib });\n const tjpGib = gibInfo.tjpGib ?? gib;\n\n /**\n * make it easiest to sort in a file explorer but still be readable.\n *\n * timestampInTicks is not easily human-readable\n */\n const dateString =\n date.toISOString().slice(0, 19)\n .replace('T', '_').replace(/:/g, '').replace(/ /g, '_');\n // it's just too much to include the entire ib as well I think\n // let safeSubtextOfThisIb = getSaferSubstring({\n // text: ib.replace(' ', '___'),\n // length: 20, // wth\n // });\n\n return `${RAW_EXPORT_ATOM} ${dateString} ${compressDescription} ${graphSize} ${graphStringLength} ${tjpGib}`;\n\n // let exportIb = `ibgib_export ${nowString} ${compress ? 'gzip' : 'raw'} ${safeSubtextOfThisIb} ${gib}`;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * space-delimited info contained in ib.\n *\n * atow (06/2025)\n * `${RAW_EXPORT_ATOM} ${dateString} ${compressDescription} ${graphSize} ${graphStringLength} ${tjpGib}`;\n * OLD (02/2024)\n * `${RAW_EXPORT_ATOM} ${timestampInTicks} ${graphSize} ${graphStringLength}`\n */\nexport function parseRawExportIb({\n ib,\n}: {\n ib: Ib,\n}): RawExportIbInfo {\n const lc = `[${parseRawExportIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 3297e51184f87a45d343d8654b165324)`); }\n const [atom, dateString, compressDescription, graphSizeStr, graphStringLengthStr, tjpGib] = ib.split(' ');\n if (atom !== RAW_EXPORT_ATOM) { throw new Error(`atom (${atom}) !== ${RAW_EXPORT_ATOM} (E: ad7545da5b8c4baeb15d86e92d657524)`); }\n const graphSize = Number.parseInt(graphSizeStr);\n if (Number.isNaN(graphSize) || graphSize < 0) { throw new Error(`graphSize (${graphSizeStr}) is not a positive integer. (E: 2b43d9d3462f6e16547b121bccef9b24)`); }\n\n const graphStringLength = Number.parseInt(graphStringLengthStr);\n if (Number.isNaN(graphStringLength) || graphStringLength < 0) { throw new Error(`graphStringLength (${graphStringLengthStr}) is not a positive integer. (E: 112ceccee1a54b19ab4f4662b6694ba0)`); }\n\n const compression = compressDescription === 'gzip' ? 'gzip' : undefined;\n\n return { atom, dateString, graphSize, graphStringLength, compression, tjpGib, };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport interface GetRawExportIbGibOpts {\n ibGib: IbGib_V1,\n metaspace: MetaspaceService,\n space: IbGibSpaceAny,\n live: boolean;\n compress?: boolean;\n /**\n * if true, will ignore as much errors as possible to try to get as much data exported as possible.\n */\n ignoreErrors?: boolean;\n // /**\n // * If true, then the export should disassociate from its past and ancestor rel8ns.\n // */\n // detach?: boolean;\n // detachRel8nNames?: string[];\n}\nexport interface ExportErrorInfo {\n errorMsg: string;\n ibGibAddr?: IbGibAddr;\n rawError?: any;\n}\n/**\n * this should be an ibgib right?\n */\nexport interface GetRawExportIbGibResult {\n rawExportIbGib: RawExportIbGib_V1;\n /**\n * all addrs included in the export.\n */\n manifest: IbGibAddr[];\n errors?: ExportErrorInfo[];\n}\nexport async function getRawExportIbGib({\n ibGib,\n metaspace,\n space,\n compress,\n live,\n ignoreErrors,\n // detach,\n // detachRel8nNames,\n}: GetRawExportIbGibOpts): Promise<GetRawExportIbGibResult> {\n const lc = `[${getRawExportIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0b6ba8608ba8bde0682a0936b9a01825)`); }\n if (!ibGib) { throw new Error(`(UNEXPECTED) ibGib falsy? (E: d2898eea744360865f0da5fb91baae22)`); }\n const ibGibAddr = getIbGibAddr({ ibGib });\n // if (preparingExport) {\n // console.warn(`${lc} already preparing export. (W: cb31b23a313247f0ad128dd984645db4)`);\n // return; /* <<<< returns early */\n // }\n const errorInfos: ExportErrorInfo[] = [];\n\n // preparingExport = true;\n\n // build an ibgib that contains the entire dependency graph of this.ibGib and save it\n\n const validationErrors = await validateIbGibIntrinsically({ ibGib }) ?? [];\n if (validationErrors.length > 0) {\n const errorMsg = `ibGib had validation errors: ${validationErrors} (E: 84890bbc0598192498178a98ae299825)`;\n if (ignoreErrors) {\n errorInfos.push({ errorMsg, ibGibAddr });\n } else {\n throw new Error(errorMsg);\n }\n }\n\n // build the data\n const resGraph = await metaspace.getDependencyGraph({\n ibGib,\n live,\n space,\n });\n const dependencyGraphAsString = compress ?\n await compressIbGibGraphToString({ graph: resGraph }) :\n await serializeGraphToString({ graph: resGraph });\n const tjpAddr = getTjpAddr({ ibGib, defaultIfNone: 'incomingAddr' }) ?? ibGibAddr;\n const now = new Date();\n let exportData: RawExportData_V1 = {\n contextIbGibAddr: ibGibAddr,\n tjpAddr,\n dependencyGraphAsString,\n graphSize: Object.keys(resGraph).length,\n timestamp: getTimestamp(now),\n timestampMs: now.getMilliseconds(),\n };\n if (compress) { exportData.compression = 'gzip'; }\n\n // [no rel8ns because this is a self-contained export ibgib]\n\n // gib\n const exportIbGib: RawExportIbGib_V1 = {\n ib: getRawExportIb({ data: exportData }),\n data: exportData,\n };\n let exportGib = await getGib({ ibGib: exportIbGib, hasTjp: false });\n exportIbGib.gib = exportGib;\n\n if (logalot || true) { console.log(`${lc} JSON.stringify(exportIbGib).length: ${JSON.stringify(exportIbGib).length} (I: db3a8d913a91d8fc5d6e45981e034822)`); }\n\n return {\n rawExportIbGib: exportIbGib,\n manifest: Object.keys(resGraph),\n errors: errorInfos.length > 0 ? errorInfos : undefined,\n };\n\n\n // // at this point, we have a possibly quite large ibGib whose data includes\n // // every single ibgib that this.ibGib relates to (its dependency graph).\n // // so now we can save this file and later import from it.\n\n // // thank you SO, OP and volzotan at https://stackoverflow.com/questions/19721439/download-json-object-as-a-file-from-browser\n // // set the anchor's href to a data stream\n // var dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(exportIbGib));\n\n // // get the filename for the anchor to suggest for the \"download\"\n // let exportAddr = getIbGibAddr({ ibGib: exportIbGib });\n // const filename = `${exportAddr}.json`;\n\n // // if (this.web) {\n // // trigger the click\n // const dlAnchorElemId ='export-ibgib-anchor';\n // const dlAnchorElem = document.getElementById(dlAnchorElemId);\n // if (!dlAnchorElem) { throw new Error(`(UNEXPECTED) dlAnchorElem falsy? should be an element with id ${dlAnchorElemId}? (E: 51dfe2d823eedeefb8b9c9580090e625)`); }\n // dlAnchorElem.setAttribute(\"href\", dataStr);\n // dlAnchorElem.setAttribute(\"download\", filename);\n // dlAnchorElem.click();\n // } else {\n // // let res = await Filesystem.requestPermissions();\n // await Filesystem.writeFile({\n // data: dataStr,\n // directory: Directory.ExternalStorage,\n // path: `/Download/${filename}`,\n // encoding: Encoding.UTF8,\n // recursive: true,\n // });\n // }\n // await Dialog.alert({ title: 'export succeeded', message: 'way to go, the export succeeded' });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "import { delay, extractErrorMsg, } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\n\nimport { GLOBAL_LOG_A_LOT } from \"../constants.mjs\";\nimport { UIThemeInfo } from \"./ui-types.mjs\";\nimport { storageGet, storagePut } from \"../storage/storage-helpers.web.mjs\";\nimport { UI_THEME_INFO_KEY } from \"./ui-constants.mjs\";\nimport type { getGlobalDbName, getGlobalStoreName } from \"../helpers.web.mjs\";\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Shows the fullscreen dialog with the given title, message, and optional prompt.\n *\n * @param {object} details - Options for showing the dialog.\n * @param {string} details.title - Title of the dialog.\n * @param {string} details.message - Message to display in the dialog body.\n * @param {boolean} [details.prompt] - If true, shows a text input for prompting the user.\n * @returns {Promise<string | null>} - A promise that resolves with the text entered by the user (if prompt is true) or null if canceled/dismissed.\n */\nexport async function showFullscreenDialog(opts: {\n title: string,\n msg: string,\n /**\n * determines if to show the cancel button. does NOT control whether or not\n * we show the input control.\n *\n * so if you want to prompt just for a boolean, just set this to true. If\n * you need actual string input from the user, set {@link showInput} to\n * true.\n *\n * @see {@link showInput}\n */\n prompt?: boolean,\n /**\n * this flag determines if the user input field is shown. If this is truthy,\n * then {@link prompt} will be ignored and always set to `true`.\n *\n * @see {@link prompt}\n */\n showInput?: boolean,\n defaultValue?: string,\n okButtonTitle?: string,\n cancelButtonTitle?: string,\n isPassword?: boolean,\n}): Promise<string | undefined> {\n const lc = `[${showFullscreenDialog.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 037b228a2568181cd3eb25dba4e03225)`); }\n\n // const dialog = document.getElementById(ID_FULLSCREEN_DIALOG) as HTMLDialogElement;\n // const dialogBody = document.getElementById(ID_FULLSCREEN_DIALOG_BODY) as HTMLDialogElement;\n // const titleElement = document.getElementById(ID_FULLSCREEN_DIALOG_TITLE) as HTMLElement;\n // const messageElement = document.getElementById(ID_FULLSCREEN_DIALOG_MESSAGE) as HTMLElement;\n // const promptInput = document.getElementById(ID_FULLSCREEN_DIALOG_PROMPT_INPUT) as HTMLInputElement;\n // const okButton = document.getElementById(ID_FULLSCREEN_DIALOG_OK_BUTTON) as HTMLButtonElement;\n // const cancelButton = document.getElementById(ID_FULLSCREEN_DIALOG_CANCEL_BUTTON) as HTMLButtonElement;\n\n const dialog = document.getElementById('fullscreen-dialog') as HTMLDialogElement;\n const dialogBody = document.getElementById('fullscreen-dialog-body') as HTMLDialogElement;\n const titleElement = document.getElementById('fullscreen-dialog-title') as HTMLElement;\n const messageElement = document.getElementById('fullscreen-dialog-message') as HTMLElement;\n const promptInput = document.getElementById('fullscreen-dialog-prompt-input') as HTMLInputElement;\n const okButton = document.getElementById('fullscreen-dialog-ok-button') as HTMLButtonElement;\n const cancelButton = document.getElementById('fullscreen-dialog-cancel-button') as HTMLButtonElement;\n\n if (!dialog || !dialogBody || !titleElement || !messageElement || !promptInput || !okButton || !cancelButton) {\n throw new Error(`(UNEXPECTED) One or more dialog elements not found in DOM (E: 578e37c0271cc57a99e95e780ad18a25)`);\n }\n\n titleElement.textContent = opts.title || '';\n [...messageElement.childNodes as any].forEach(child => messageElement.removeChild(child));\n // messageElement.innerHTML = '';\n let msgLines = (opts.msg || '').split('\\n');\n msgLines.forEach(line => {\n const pLine = document.createElement('p');\n pLine.textContent = line;\n messageElement.appendChild(pLine);\n });\n // messageElement.textContent = opts.msg || '';\n\n // reset the input classList\n promptInput.classList.remove('collapsed');\n cancelButton.classList.remove('collapsed');\n cancelButton.style.display = 'inline-block';\n okButton.textContent = opts.okButtonTitle || 'OK';\n\n // Prompt-specific setup\n const onKeypress = (ev: KeyboardEvent) => {\n /**\n * apparently an input has ev.key of 'Enter' but textarea is '\\n'\n */\n const isEnter = ev.key === 'Enter' || ev.key === '\\n';\n if (isEnter && ev.ctrlKey) { okButton.click(); }\n };\n\n if (opts.prompt || opts.showInput) {\n promptInput.addEventListener('keypress', onKeypress);\n if (opts.showInput) {\n promptInput.autofocus = true;\n promptInput.value = opts.defaultValue ?? '';\n promptInput.addEventListener('keypress', (ev) => {\n if (ev.key === 'Enter') { okButton.click(); }\n });\n if (opts.isPassword) {\n promptInput.type = 'password';\n promptInput.autocomplete = 'off';\n promptInput.required = true;\n } else {\n promptInput.type = 'text';\n promptInput.autocomplete = 'on';\n promptInput.required = false;\n promptInput.attributes['auto-complete'] = 'on';\n }\n } else {\n promptInput.autofocus = false;\n promptInput.classList.add('collapsed');\n }\n cancelButton.textContent = opts.cancelButtonTitle || 'Cancel';\n } else {\n promptInput.classList.add('collapsed'); // Hide prompt input\n cancelButton.style.display = 'none'; // Hide cancel button for alerts\n }\n\n return new Promise<string | undefined>((resolve) => {\n // handlers\n\n /** helper used in other handlers */\n const removeEventListeners = () => {\n if (opts.prompt || opts.showInput) {\n promptInput.removeEventListener('keypress', onKeypress);\n }\n okButton.removeEventListener('click', onOK);\n cancelButton.removeEventListener('click', onCancel);\n dialog.removeEventListener('close', onClose); // Remove dialog-level listener too\n };\n /** user clicks OK or hits \"ENTER\" in input */\n const onOK = () => {\n removeEventListeners();\n let result = opts.showInput ?\n promptInput.value ?? '' :\n true.toString();\n if (promptInput) { promptInput.value = ''; } // Clear input for next time\n dialog.close(result);\n resolve(result);\n };\n\n /** user actively clicks Cancel */\n const onCancel = () => {\n removeEventListeners();\n if (promptInput) { promptInput.value = ''; } // Clear input for next time\n dialog.close(undefined); // Pass back null for cancel\n resolve(undefined);\n };\n /**\n * Handle dialog.close() without button click (e.g., Esc key)\n *\n * NOTE: this does not trigger when dialog.close() is executed. This\n * is only firing when esc is pressed.\n */\n const onClose = () => {\n removeEventListeners();\n if (promptInput) { promptInput.value = ''; } // Clear input for next time\n dialog.close(undefined);\n resolve(undefined);\n };\n\n // wire up\n okButton.addEventListener('click', onOK);\n cancelButton.addEventListener('click', onCancel);\n dialog.addEventListener('close', onClose); // e.g. escape key\n\n // show it\n dialog.showModal();\n delay(1000).then(() => {\n dialogBody.scrollTo({ top: 0, behavior: 'smooth' });\n });\n });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Gets {@link UIThemeInfo} if it exists in the db ({@link dbName}) and store\n * ({@link storeName}) at the given {@link key}.\n *\n * Used with libs\\web-gib\\src\\api\\commands\\ui\\update-css-variables.mts\n *\n * @see {@link putUIInfoInStore}\n * @see {@link UI_THEME_INFO_KEY}\n * @see {@link putUIInfoInStore}\n * @see {@link getGlobalDbName}\n * @see {@link getGlobalStoreName}\n */\nexport async function getExistingUIInfo({\n dbName,\n storeName,\n key = UI_THEME_INFO_KEY,\n}: {\n dbName: string,\n storeName: string,\n key?: string,\n}): Promise<UIThemeInfo | undefined> {\n const lc = `[${getExistingUIInfo.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 4c9d7c7f1e8bfcc917d405b842438825)`); }\n\n key ??= UI_THEME_INFO_KEY;\n\n let existingUIInfo: UIThemeInfo | undefined = undefined;\n const existingUIInfoAsString = await storageGet({\n dbName,\n storeName,\n key,\n });\n if (existingUIInfoAsString) {\n try {\n existingUIInfo = JSON.parse(existingUIInfoAsString) as UIThemeInfo;\n if (!existingUIInfo.cssVariableOverrides) { throw new Error(`invalid existing UI info (E: 2fb408362178ce79a57da313d6680d25)`); }\n } catch (error) {\n existingUIInfo = undefined;\n }\n }\n\n return existingUIInfo;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Complementing {@link getExistingUIInfo}, this puts {@link newUIInfo} in the\n * db ({@link dbName}) and into the store ({@link storeName}) at the given\n * {@link key}.\n *\n * Used with libs\\web-gib\\src\\api\\commands\\ui\\update-css-variables.mts\n *\n * @see {@link getExistingUIInfo}\n * @see {@link UI_THEME_INFO_KEY}\n * @see {@link putUIInfoInStore}\n * @see {@link getGlobalDbName}\n * @see {@link getGlobalStoreName}\n */\nexport async function putUIInfoInStore({\n dbName,\n storeName,\n key = UI_THEME_INFO_KEY,\n newUIInfo,\n}: {\n dbName: string,\n storeName: string,\n key?: string,\n newUIInfo: UIThemeInfo,\n}): Promise<void> {\n const lc = `[${putUIInfoInStore.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 79c9ee707e426fd8c861c4ff4cf16826)`); }\n\n await storagePut({\n dbName,\n storeName,\n key,\n value: JSON.stringify(newUIInfo),\n });\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n};", "import { clone, delay, extractErrorMsg, getTimestampInTicks } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { IbGib_V1, Rel8n } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\nimport { getIbAndGib, getIbGibAddr } from \"@ibgib/ts-gib/dist/helper.mjs\";\nimport { GIB } from \"@ibgib/ts-gib/dist/V1/constants.mjs\";\nimport { Gib, IbGibAddr } from \"@ibgib/ts-gib/dist/types.mjs\";\nimport { getGibInfo, isPrimitive } from \"@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs\";\nimport { mut8 } from \"@ibgib/ts-gib/dist/V1/transforms/mut8.mjs\";\nimport { getSpecialConfigKey, getTjpAddr } from \"@ibgib/core-gib/dist/common/other/ibgib-helper.mjs\";\nimport { execInSpaceWithLocking, persistTransformResult } from \"@ibgib/core-gib/dist/witness/space/space-helper.mjs\";\nimport { MetaspaceService } from \"@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs\";\nimport { IbGibSpaceAny } from \"@ibgib/core-gib/dist/witness/space/space-base-v1.mjs\";\nimport { SpecialIbGibType } from \"@ibgib/core-gib/dist/common/other/other-types.mjs\";\n\nimport { DEFAULT_IBGIB_COLOR, DEFAULT_IBGIB_COLOR_CONTRAST, DEFAULT_IBGIB_TRANSLUCENT, GLOBAL_LOG_A_LOT, GLOBAL_THIS_IBGIB_KEY, } from \"./constants.mjs\";\nimport { GibColorInfo, IbGibGlobalThisInfo } from \"./types.mjs\";\n\nconst logalot = GLOBAL_LOG_A_LOT; // change this when you want to turn off verbose logging\n\nexport async function getTagsIbGib({\n metaspace,\n space,\n}: {\n metaspace: MetaspaceService,\n space: IbGibSpaceAny | undefined,\n}): Promise<IbGib_V1> {\n const lc = `[${getTagsIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 2ccb79537a75e7896bace84e6c710d25)`); }\n\n const tagsIbGib = await metaspace.getSpecialIbGib({ type: SpecialIbGibType.tags, space });\n if (!tagsIbGib) { throw new Error(`tagsIbGib not found in metaspace. space: ${!!space ? space.ib : 'default local user space'} (E: 4734c510a411274315c0add8f70e1925)`); }\n\n return tagsIbGib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * NOTE: This was originally written only for agents and I'm generalizing it to\n * any \"coupled\" ibgib. The idea is that for local-space-specific ibgibs that\n * are related to domain ibgibs, but where we don't want to modify the domain\n * ibgib directly, we create this \"coupled\" ibgib. We then index it in a local\n * space special (index) ibgib and associate it by tjpAddr.\n *\n * Generates a consistent special name for the agent index ibGib based on the\n * domain ibGib's primitive ancestor's ib or the ibGibAddr's ib atom.\n *\n * RIGHT NOW I\"M PRIORITIZING THE ATOM. I THINK IT ALWAYS RETURNS THE ATOM, I.E., THE FIRST SPACE-DELIMITED PIECE OF THE `ib`.\n *\n * I am doing this because the project ibgib actually forks from a comment\n * ibgib, so its primitive ancestor is \"comment^gib\".\n *\n * ## notes\n *\n * We are trying to get a special ibgib index that maps from ibgibs (the domain)\n * to what local agent is registered to handle that ibgib's timeline.\n *\n * Concretely, we're working on the project ibgibs and we need a way to get at\n * the agent that is assigned to that project. But we can't just mut8 the\n * project itself because this would cause issues once the project is spread out\n * among multiple execution contexts (similar to \"remotes\" in git).\n *\n * So we will have a special ibgib registered with the local space which will\n * act as this index that maps ibgib -> handling agent. This function helps get\n * the *name* of that special indexing ibgib.\n *\n * This can be driven either by the ibgib itself, via the last primitive ancestor\n * ibgib's address, or via the ib's atom (the first space-delimited term in the\n * `ib` metadata).\n *\n * So if an ancestor is [comment^gib, specialComment^gib, specialComment\n * abc123^ABC123.DEF456] (where the abc123 things are representative of the full\n * hashes 64 characters long atow since we're using sha256), then the *last*\n * primitive address is specialComment^gib.\n */\nexport function getIndexNameFromIbGib({\n scope,\n ibGib,\n ibGibAddr,\n defaultNameIfError,\n}: {\n /**\n * what kind of index are we talking in general?\n */\n scope: string,\n ibGib?: IbGib_V1,\n ibGibAddr?: IbGibAddr,\n /**\n * if truthy and an error is produced, then this will be returned.\n */\n defaultNameIfError?: string,\n}): string {\n const lc = `[${getIndexNameFromIbGib.name}]`;\n try {\n if (!ibGib && !ibGibAddr) { throw new Error(`${lc} Must provide either ibGib or ibGibAddr. (E: genuuid)`); }\n if (scope.includes(' ')) {\n console.warn(`${lc} scope includes one or more spaces. These will be converted to double underscores. (W: 1554a81454e8ae0a6858ea5dd17f8925)`);\n scope = scope.replace(/ /g, '__');\n }\n /**\n * note: non-alphanumerics are replaced with underscores\n */\n let primitiveAncestorIb: IbGibAddr | undefined = undefined;\n let atom: string | undefined = undefined;\n /**\n * This is what we're trying to extract. once we have this, then we can\n * simply append our index name, e.g. `${ancestorIbOrAtom}-agent-index`\n */\n let ancestorIbOrAtom: string | undefined = undefined;\n if (ibGib) {\n // go by the ibgib's full data\n if (!ibGib.data) { throw new Error(`(UNEXPECTED) ibGib.data falsy? (E: genuuid)`); }\n if (!ibGib.rel8ns) { throw new Error(`(UNEXPECTED) ibGib.rel8ns falsy? (E: genuuid)`); }\n if (!ibGib.rel8ns.ancestor) { throw new Error(`(UNEXPECTED) ibGib.rel8ns.ancestor falsy? (E: genuuid)`); }\n if (ibGib.rel8ns.ancestor.length === 0) {\n throw new Error(`(UNEXPECTED) ibGib.rel8ns.ancestor.length === 0? there should be at least one ancestor (E: genuuid)`);\n // this may turn into a warning later on down the road and return based on the ibGib's addr\n }\n if (ibGib && ibGibAddr) {\n if (getIbGibAddr({ ibGib }) !== ibGibAddr) {\n throw new Error(`(UNEXPECTED) both ibGib and ibGibAddr provided, but addr of ibGib doesn't equal ibGibAddr? (E: genuuid)`);\n }\n }\n\n // const primitiveAncestor = getPrimitiveAncestor({ ibGib });\n const primitiveAncestorAddrs =\n ibGib.rel8ns.ancestor!.filter(x => isPrimitive({ gib: getIbAndGib({ ibGibAddr: x }).gib }));\n if (primitiveAncestorAddrs.length === 0) {\n debugger; // error no primitive ancestor addrs?\n console.error(`${lc} ibGib has no primitive ancestor addrs? Still going to work off of the ib then, which should have the atom as the first space-delimited term. (E: genuuid)`)\n }\n const primitiveAncestorAddr = primitiveAncestorAddrs.at(-1)!;\n primitiveAncestorIb =\n getIbAndGib({ ibGibAddr: primitiveAncestorAddr }).ib;\n // replace ALL spaces with underscores\n ancestorIbOrAtom = primitiveAncestorIb;\n }\n\n // get the atom from the address\n ibGibAddr ??= getIbGibAddr({ ibGib });\n\n // try to get at it from the ibGibAddr\n const { ib } = getIbAndGib({ ibGibAddr });\n atom = (ib.split(' ').at(0) ?? '');\n\n // at this point we have a raw atom and possibly a raw primitive\n // ancestor ib. we want to compare the two, which usually should be the\n // same (i think?). if different, warn and return\n atom = atom.replace(/\\W/g, '_');\n\n primitiveAncestorIb ??= atom;\n primitiveAncestorIb = primitiveAncestorIb.replace(/\\W/g, '_');\n\n if (!primitiveAncestorIb && !atom) {\n throw new Error(`(UNEXPECTED) both primitiveAncestorIb and atom falsy? one should be truthy at this point. (E: genuuid)`);\n }\n\n // if (primitiveAncestorIb !== atom) {\n // // warn and do per arg\n // console.warn(`${lc} ibGib primitive ancestor ib (${primitiveAncestorIb}) doesn't match atom (${atom}). going with ancestorIbOrAtom: ${ancestorIbOrAtom} (W: genuuid)`);\n // }\n ancestorIbOrAtom = atom.toLowerCase();\n if (logalot) { console.log(`${lc} ancestorIbOrAtom: ${ancestorIbOrAtom} (I: genuuid)`); }\n\n /**\n * I forgot, this cannot be kebab-cased because we only allow \\w regexp\n * on the special ibgib name. I don't remember the reasoning for this,\n * may be arbitrary. But for now, going to change this to underscore,\n * even though the atom or ancestor ib may have underscores in it. Ah\n * well.\n */\n const indexName = `${ancestorIbOrAtom}_${scope}index`;\n if (logalot) { console.log(`${lc} indexName: ${indexName} (I: genuuid)`); }\n return indexName;\n } catch (error) {\n if (!!defaultNameIfError) {\n console.warn(`${lc} error happened but defaultNameIfError (${defaultNameIfError}) provided. So will return this value. error that was thrown: ${extractErrorMsg(error)}`);\n return defaultNameIfError;\n } else {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n }\n}\n\n/**\n * NOTE: This was originally written only for agents and I'm generalizing it to\n * any \"coupled\" ibgib. The idea is that for local-space-specific ibgibs that\n * are related to domain ibgibs, but where we don't want to modify the domain\n * ibgib directly, we create this \"coupled\" ibgib. We then index it in a local\n * space special (index) ibgib and associate it by tjpAddr.\n * Retrieves the agent ibGib associated with a domain ibGib from the special agent index ibGib.\n *\n * may have to change this to require the ibgib, not give an optional\n * domainIbGibAddr\n */\nexport async function getLocalCoupledIbGibForDomainIbGib<TIbGib extends IbGib_V1>({\n scope,\n ibGib,\n metaspace,\n space,\n skipGetLatest,\n}: {\n scope: string,\n ibGib: IbGib_V1,\n metaspace: MetaspaceService,\n space: IbGibSpaceAny,\n /**\n * if true, will not call getLatest on the coupled ibgib if found.\n */\n skipGetLatest?: boolean,\n}): Promise<TIbGib | undefined> {\n const lc = `[${getLocalCoupledIbGibForDomainIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f19dc86aab380fe809aef27ccc7a7425)`); }\n\n if (!scope) { throw new Error(`scope required to be a non-empty string (E: 73e702495c38c7d8747d1cf8850af825)`); }\n if (!ibGib) { throw new Error(`ibGib required (E: genuuid)`); }\n\n // Get the index name and domain TJP address\n const indexSpecialIbGibType: SpecialIbGibType =\n getIndexNameFromIbGib({ scope, ibGib, }) as SpecialIbGibType;\n\n const domainTjpAddr = getTjpAddr({ ibGib, defaultIfNone: 'incomingAddr' })!;\n\n // Get the index ibGib\n const fn: () => Promise<TIbGib | undefined> = async () => {\n const specialIndex = await metaspace.getSpecialIbGib({\n type: indexSpecialIbGibType,\n space,\n initialize: false, // Do not create if it doesn't exist when retrieving\n dontWarnIfNotExist: true, // Don't warn if the index doesn't exist\n lock: true,\n });\n\n // If the index ibGib doesn't exist, nothing is registered for this domain ibgib\n if (!specialIndex || !specialIndex.data) {\n if (logalot) { console.log(`${lc} special ${scope} index ibGib not found for indexSpecialIbGibType (${indexSpecialIbGibType}). No coupled ibgib registered, returning undefined. (I: genuuid)`); }\n return undefined; /* <<<< returns early */\n }\n\n // Get the address from the map\n const coupleMap: { [tjpAddr: string]: IbGibAddr } =\n specialIndex.data.coupleMap ??\n specialIndex.data.agentMap ??\n {};\n const coupledAddr = coupleMap[domainTjpAddr];\n\n if (!coupledAddr) {\n if (logalot) { console.log(`${lc} No coupled ${scope} ibgib address found for domain ${domainTjpAddr} in the coupled index map. indexSpecialIbGibType: ${indexSpecialIbGibType}. returning undefined. (I: genuuid)`); }\n return undefined; /* <<<< returns early */\n }\n\n let addrToGet = skipGetLatest ?\n coupledAddr :\n await metaspace.getLatestAddr({ addr: coupledAddr, space }) ?? coupledAddr;\n\n let resGet = await metaspace.get({\n addrs: [addrToGet],\n space,\n });\n\n if (resGet.errorMsg || (resGet.ibGibs ?? []).length !== 1) {\n throw new Error(`couldn't get latest coupled ibgib (${addrToGet}) for domain ${domainTjpAddr}. (E: 8aa7b25f5cd4ebadd8bf2f8807dfe825)`);\n }\n\n return resGet.ibGibs![0] as TIbGib;\n }\n\n const result = await execInSpaceWithLocking({\n scope: indexSpecialIbGibType,\n secondsValid: 180, // Example timeout\n maxDelayMs: 100, // Example delay\n maxLockAttempts: 1800, // Example attempts\n space,\n callerInstanceId: lc + getTimestampInTicks(),\n fn,\n });\n\n return result;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Registers a domain ibGib with its associated agent ibGib in the special agent\n * index ibGib. This creates or updates a mapping from the domain ibGib's TJP\n * address to the agent's address.\n *\n * ## intent\n *\n * we want to rel8 ibgibs but not directly change the domain ibgib. Like if we\n * have an ibgib that we want to collaborate on, we want a mechanism for the\n * local space (later local user via keystone) to have settings, agents, etc.,\n * for that domain ibgib. But each space has its own version, like a local/user\n * settings vs. a workspace settings.\n *\n * So this gets/creates an index on the local space and associates the domain\n * with the local.\n *\n * @example\n * use this to couple a local agent to a domain ibgib or a local settings ibgib\n * to a domain ibgib, that you do not want to share with others who will have\n * their own versions.\n */\nexport async function coupleDomainIbGibWithLocalIbGibViaIndex({\n scope,\n domainIbGib,\n localIbGib,\n metaspace,\n space,\n}: {\n scope: string,\n domainIbGib: IbGib_V1,\n localIbGib: IbGib_V1,\n metaspace: MetaspaceService,\n space: IbGibSpaceAny,\n}): Promise<void> {\n const lc = `[${coupleDomainIbGibWithLocalIbGibViaIndex.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 217ae68e0c820e48f4c00409f7f14325)`); }\n\n const indexSpecialIbGibType: SpecialIbGibType =\n getIndexNameFromIbGib({ scope, ibGib: domainIbGib, });\n\n const domainTjpAddr = getTjpAddr({ ibGib: domainIbGib });\n const localAddr = getIbGibAddr({ ibGib: localIbGib });\n\n if (!domainTjpAddr) { throw new Error(`${lc} Could not get TJP address for domain ibGib. (E: 35a4e8ac291b0b85cb958e28dd812f25)`); }\n if (!localAddr) { throw new Error(`${lc} Could not get address for agent ibGib. (E: 2fce1187630b45934c4155a23204d125)`); }\n\n const fn = async () => {\n\n // Get or create the agent index ibGib\n const agentSpecialIndex = await metaspace.getSpecialIbGib({\n type: indexSpecialIbGibType,\n space,\n initialize: true, // Create if it doesn't exist\n dontWarnIfNotExist: true,\n lock: false,\n });\n\n if (!agentSpecialIndex) { throw new Error(`${lc} Could not get or create agent index ibGib.`); }\n\n // Initialize data if it doesn't exist\n if (!agentSpecialIndex.data) {\n throw new Error(`(UNEXPECTED) agentSpecialIndex.data falsy? (E: 74299eed147debf6398ca37e7b8d5c25)`);\n }\n\n // Get the current mapping or initialize an empty one\n const map = agentSpecialIndex.data.coupleMap ?? agentSpecialIndex.data.agentMap;\n const coupleMap: { [tjpAddr: string]: IbGibAddr } =\n !!map ? clone(map) : {};\n\n // Update the mapping\n const existingMappedAgentAddr = coupleMap[domainTjpAddr];\n if (existingMappedAgentAddr) {\n if (existingMappedAgentAddr === localAddr) {\n if (logalot) { console.log(`${lc} domain ibGib (${domainTjpAddr}) already mapped to agent (${localAddr}). returning early (I: cb5d4dcef8cf14de7336120fb8ffef25)`); }\n return; /* <<<< returns early */\n } else {\n console.warn(`${lc} domainTjpAddr (${domainTjpAddr}) already assigned to existingMappedAgentAddr (${existingMappedAgentAddr}). We will be changing to new localAddr (${localAddr}). (W: eb993e33f7731e570fa76f24a2d80625)`)\n }\n }\n coupleMap[domainTjpAddr] = localAddr;\n\n // Assign the updated map back to data Save the updated index ibGib.\n // there is extra plumbing involved with special index ibgibs. see\n // `rel8ToSpecialIbGib` for an example in\n // libs/core-gib/src/witness/space/space-helper.mts\n // await updateSpecialIndex({\n // metaspace,\n // type: indexSpecialIbGibType,\n // dataToAddOrPatch: { coupleMap },\n // space,\n // });\n const resNewSpecial = await mut8({\n src: agentSpecialIndex,\n dataToAddOrPatch: { coupleMap },\n dna: false,\n linkedRel8ns: [Rel8n.past],\n nCounter: true,\n });\n\n const newSpecialIbGib = resNewSpecial.newIbGib;\n\n // persist\n await persistTransformResult({ resTransform: resNewSpecial, space });\n\n // update the space ibgib which contains the special/config information\n const configKey = getSpecialConfigKey({ type: indexSpecialIbGibType });\n await metaspace.setConfigAddr({\n key: configKey,\n addr: getIbGibAddr({ ibGib: newSpecialIbGib }),\n space,\n });\n\n await metaspace.registerNewIbGib({ ibGib: newSpecialIbGib, space, });\n }\n\n await execInSpaceWithLocking({\n scope: indexSpecialIbGibType, // Use the special index type as the lock scope.\n secondsValid: 60, // Example timeout\n maxDelayMs: 100, // Example delay\n maxLockAttempts: 600, // Example attempts\n space,\n // callerInstanceId: // You might need a way to generate a unique ID for the caller\n fn,\n });\n\n if (logalot) { console.log(`${lc} Registered domain ${domainTjpAddr} with agent ${localAddr}`); }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Returns a function, that, as long as it continues to be invoked, will not\n * be triggered. The function will be called after it stops being called for\n * N milliseconds. If `immediate` is passed, trigger the function on the\n * leading edge, instead of the trailing.\n *\n * @param func The function to debounce.\n * @param wait The number of milliseconds to wait after the last call.\n * @param immediate If true, trigger the function on the leading edge.\n * @returns A debounced version of the function.\n */\nexport function debounce<T extends (...args: any[]) => void>(\n func: T,\n wait: number,\n immediate?: boolean\n): (...args: Parameters<T>) => void {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: any, ...args: Parameters<T>): void {\n const context = this;\n\n const later = function (): void {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n };\n\n const callNow = immediate && !timeout;\n\n if (timeout) {\n clearTimeout(timeout);\n }\n\n timeout = setTimeout(later, wait);\n\n if (callNow) {\n func.apply(context, args);\n }\n };\n}\n\nexport function getMaskedSecret({ secret, countToShow }: { secret: string, countToShow: number }): string {\n const lc = `[${getMaskedSecret.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 4d479c342b77f12568501c085b4b0425)`); }\n if (secret) {\n if (countToShow > secret.length) {\n if (secret.length === 1) {\n console.warn(`${lc} secret is one character? (W: genuuid)`);\n return secret; // whatever\n } else {\n console.warn(`${lc} countToShow is longer than the entire secret! just showing the last two (W: genuuid)`);\n return `****${secret.substring(secret.length - 2)}`;\n }\n } else {\n // show the last countToShow\n const secretMasked = `****${secret.substring(secret.length - countToShow)}`;\n return secretMasked;\n }\n } else {\n console.error(`${lc} secret falsy? empty? returning empty string. (E: genuuid)`);\n return '';\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function insertAt<T>({\n newItems,\n index,\n targetArray,\n}: {\n newItems: T[],\n index: number,\n targetArray: T[],\n}): T[] {\n const lc = `[${insertAt.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5fc3c84d9e08f4ee88978be8bd117a25)`); }\n\n if (index < 0 || index >= targetArray.length) {\n throw new Error(`index (${index}) is out of bounds for targetArray (length ${targetArray.length}) (E: genuuid)`);\n }\n\n const arrayCopy = [...targetArray];\n arrayCopy.splice(index, 0, ...newItems);\n return arrayCopy;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function deleteAt<T>({\n targetArray,\n index,\n}: {\n targetArray: T[],\n index: number,\n}): T[] {\n const lc = `[${deleteAt.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 6f2df80039f897a0883714686af97925)`); }\n\n if (index < 0 || index >= targetArray.length) {\n throw new Error(`index (${index}) is out of bounds for targetArray (length ${targetArray.length}) (E: genuuid)`);\n }\n\n const arrayCopy = [...targetArray];\n arrayCopy.splice(index, 1);\n return arrayCopy;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getShortenedStringWithEllipsis({\n str,\n maxChars,\n}: {\n str: string,\n maxChars: number,\n}): string {\n const lc = `[${getShortenedStringWithEllipsis.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 228729c84d2805bc186e96c8cbc56825)`); }\n\n if (str.length <= maxChars) {\n return str;\n } else {\n return str.substring(0, maxChars - 1) + '\u2026';\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * location for globals to be used across ALL ibgib apps/libs, present and future.\n *\n * NOTE: Very little should be in here, since it pertains to such a broad scope.\n *\n * ## how to use this class\n *\n * ibgib apps are expected to have a metaspace singleton, and this is expected to be\n */\nexport class IbGibGlobalThis_IbGib {\n private lc: string = `[${IbGibGlobalThis_IbGib.name}]`;\n\n private _metaspacesByAppId: { [appId: string]: MetaspaceService } = {};\n private _globalThisObjectsByAppId: { [appId: string]: any } = {};\n\n constructor() {\n\n }\n\n /**\n * The metaspace should already be initialized.\n *\n * @throws if metaspace.initialized is falsy\n *\n * @see {@link IbGibGlobalThis_IbGib} for general instructions on how to use\n * this class.\n */\n public async registerInitializedMetaspace({\n appId,\n metaspace,\n }: {\n appId: string,\n metaspace: MetaspaceService,\n }): Promise<void> {\n const lc = `${this.lc}[${this.registerInitializedMetaspace.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: d65058fb49953ac8bff6823cbc464825)`); }\n if (this._metaspacesByAppId[appId]) { throw new Error(`appId (${appId}) already has a metaspace registered. (E: 1601f88722b849bdd85b6b98075e8225)`); }\n\n if (metaspace.initialized) {\n this._metaspacesByAppId[appId] = metaspace;\n } else {\n throw new Error(`metaspace.initialized is false. (E: 00e361cff998dd54e4f7b8a10106ed25)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n /**\n * sync call to a metaspace that was registered by the appId.\n *\n * @throws If no metaspace was registered with the {@link appId}\n *\n * @see {@link IbGibGlobalThis_IbGib} for general instructions on how to use\n * this class.\n */\n getMetaspace({ appId }: { appId: string }): MetaspaceService {\n const lc = `${this.lc}[${this.getMetaspace.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b918969698bf80cf18a03a3b91385525)`); }\n const metaspace = this._metaspacesByAppId[appId];\n if (metaspace) {\n return metaspace;\n } else {\n throw new Error(`NOT FOUND: appId (${appId}) does not have a metaspace registered. (E: 0ebcf95fb208d2d3f27edb06260d9d25)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n /**\n * Registers an app-specific global object for global state with ibgib apps,\n * on the ibgib global object (atow 12/2025 this is `globalThis.ibgib`).\n * @see {@link IbGibGlobalThis_IbGib.getGlobalThis}\n *\n * @see {@link IbGibGlobalThis_IbGib} for general instructions on how to use\n * this class.\n */\n registerGlobalThis<TGlobalInfo>({ appId, appGlobal }: { appId: string, appGlobal: TGlobalInfo }): void {\n const lc = `${this.lc}[${this.registerGlobalThis.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0680ec122948fe23cd0f4c3a61451825)`); }\n if (this._globalThisObjectsByAppId[appId]) { throw new Error(`appId (${appId}) already has a globalThis object registered. (E: 1e71e8859a8b94c9a85af595818cd825)`); }\n\n this._globalThisObjectsByAppId[appId] = appGlobal;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Get the app-specific global object on globalThis.ibgib that was\n * (or should have been) registered by the {@link appId}\n *\n * @throws if no globalThis obj was registered with `appId`\n * @see {@link IbGibGlobalThis_IbGib.registerGlobalThis}\n *\n * @see {@link IbGibGlobalThis_IbGib} for general instructions on how to use\n * this class.\n */\n getGlobalThis<TGlobalInfo>({ appId }: { appId: string }): TGlobalInfo {\n const lc = `${this.lc}[${this.getGlobalThis.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f59f58a8344664092877a0f8b43c1125)`); }\n\n const globalThisObj = this._globalThisObjectsByAppId[appId] as (TGlobalInfo | undefined);\n if (globalThisObj) {\n return globalThisObj;\n } else {\n throw new Error(`NOT FOUND: appId (${appId}) does not have a globalThis object registered. (E: 8e3b08d05c475399781871d2a12ba825)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n\n/**\n *\n */\nexport function getIbGibGlobalThis_IbGib(): IbGibGlobalThisInfo {\n const lc = `[${getIbGibGlobalThis_IbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 890f53e984d69461d9f4ded8741fcc25)`); }\n\n let result = globalThis[GLOBAL_THIS_IBGIB_KEY];\n if (!result) {\n console.log(`${lc} initializing globalThis.${GLOBAL_THIS_IBGIB_KEY}... (I: 9d9ff1813448d9a1b82b0e5790a74825)`);\n result = {};\n }\n\n return result;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * helper that waits until the global metaspace is initialized and then returns\n * that metaspace.\n *\n * NOTE: This does not have a max count breakout or cancellation. The metaspace\n * is simply integral to the website and this is not expected to fail (otherwise\n * the entire website is foo anyway).\n *\n * ## driving use case\n *\n * when the router tries to load a route that is based on an ibgib, the\n * metaspace is required.\n */\nexport async function getGlobalMetaspace_waitIfNeeded({\n delayIntervalMs = 50\n}: {\n delayIntervalMs: number\n} = { delayIntervalMs: 50 }): Promise<MetaspaceService> {\n const lc = `[${getGlobalMetaspace_waitIfNeeded.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 4acc22d08dd1100503f9b0423f302925)`); }\n let metaspace: MetaspaceService | undefined;\n while (!metaspace) {\n if (getIbGibGlobalThis_IbGib().metaspace) {\n metaspace = getIbGibGlobalThis_IbGib().metaspace!;\n }\n if (!metaspace) {\n // global metaspace is loading. we have loaded html immediately\n // out of the gate and the metaspace hasn't initialized yet.\n console.log(`${lc} metaspace still not initialized. delayIntervalMs: ${delayIntervalMs} until next retry... (I: 490f77ac4ded1d7d3c0340e460404125)`);\n await delay(delayIntervalMs);\n }\n }\n return metaspace;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * builds a color schema based on the gib.\n *\n * note that the alpha drives the translucent property, but the solid color is\n * always built\n */\nexport function getDeterministicColorInfo({\n ibGibAddr,\n gib,\n ibGib,\n translucentAlpha = 10,\n}: {\n ibGibAddr?: IbGibAddr,\n gib?: Gib,\n ibGib?: IbGib_V1,\n /**\n * drives the translucent color.\n *\n * @default 10\n */\n translucentAlpha?: number\n}): GibColorInfo {\n const lc = `[${getDeterministicColorInfo.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 3b70af42d1c4f6ae91870f3a15c6c625)`); }\n if (!ibGibAddr && !gib && !ibGib) { gib = GIB; }\n gib ??= ibGib?.gib ?? getIbAndGib({ ibGibAddr }).gib;\n const gibInfo = getGibInfo({ gib });\n translucentAlpha ??= 10;\n /**\n * we want to color coordinate according to timeline if possible, i.e.,\n * by tjpGib.\n */\n let drivingHash = '';\n if (gibInfo.isPrimitive) {\n return {\n gib,\n gibInfo,\n punctiliarColor: DEFAULT_IBGIB_COLOR,\n punctiliarColorTranslucent: DEFAULT_IBGIB_TRANSLUCENT,\n punctiliarColorContrast: DEFAULT_IBGIB_COLOR_CONTRAST,\n }; /* <<<< returns early */\n } else {\n drivingHash = gibInfo.tjpGib ?? gibInfo.punctiliarHash ?? gib; // hmm, gib should be punctiliar but meh\n }\n\n\n\n /**\n * gets the color string\n */\n // const fnGetColorStr = (drivingHash: string) => {\n // function getContrastColor(hexcolor: string) {\n // const c = hexcolor.concat().replace(\"#\", \"\");\n // var r = parseInt(c.substr(0, 2), 16);\n // var g = parseInt(c.substr(2, 2), 16);\n // var b = parseInt(c.substr(4, 2), 16);\n // var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;\n // return (yiq >= 128) ? '#000000' : '#FFFFFF';\n // }\n // let alphaStr = '';\n // if (translucentAlpha || translucentAlpha === 0) {\n // if (translucentAlpha < 0 || translucentAlpha > 100) {\n // throw new Error(`alpha must be between 0 and 100 (E: c78faeb1477482c739b03dd32d2e1825)`);\n // }\n // if (translucentAlpha === 100) {\n // alphaStr = '';\n // } else if (translucentAlpha >= 0 && translucentAlpha < 10) {\n // // single digit\n // alphaStr = `0${translucentAlpha}`;\n // } else {\n // alphaStr = translucentAlpha.toString();\n // }\n // }\n // const color = `#${drivingHash.substring(0, 6)}`;\n // const colorTranslucent = `#${drivingHash.substring(0, 6)}${alphaStr}`;\n // const colorContrast = getContrastColor(color);\n // return [color, colorTranslucent, colorContrast];\n // };\n\n const [punctiliarColor, punctiliarColorTranslucent, punctiliarColorContrast] = getColorStrings(translucentAlpha, gibInfo.punctiliarHash ?? gib);\n const [tjpColor, tjpColorTranslucent, tjpColorContrast] = !!gibInfo.tjpGib ?\n getColorStrings(translucentAlpha, gibInfo.tjpGib) :\n [undefined, undefined, undefined];\n\n return {\n gib,\n gibInfo,\n punctiliarColor, punctiliarColorTranslucent, punctiliarColorContrast,\n tjpColor, tjpColorTranslucent, tjpColorContrast,\n };\n } catch (error) {\n const errorMsg = `${lc} ${extractErrorMsg(error)}`;\n console.error(errorMsg);\n return {\n gib: gib ?? GIB,\n gibInfo: { isPrimitive: true },\n punctiliarColor: '#ff0000', // red\n punctiliarColorTranslucent: '#ff000010', // translucent red\n punctiliarColorContrast: '#ffffff', // black\n errorMsg,\n };\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * gets the color, colorTranslucent and colorContrast\n */\nexport function getColorStrings(translucentAlpha: number, drivingHash: string): [string, string, string] {\n function getContrastColor(hexcolor: string) {\n const c = hexcolor.concat().replace(\"#\", \"\");\n var r = parseInt(c.substr(0, 2), 16);\n var g = parseInt(c.substr(2, 2), 16);\n var b = parseInt(c.substr(4, 2), 16);\n var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;\n return (yiq >= 128) ? '#000000' : '#FFFFFF';\n }\n let alphaStr = '';\n if (translucentAlpha || translucentAlpha === 0) {\n if (translucentAlpha < 0 || translucentAlpha > 100) {\n throw new Error(`alpha must be between 0 and 100 (E: c78faeb1477482c739b03dd32d2e1825)`);\n }\n if (translucentAlpha === 100) {\n alphaStr = '';\n } else if (translucentAlpha >= 0 && translucentAlpha < 10) {\n // single digit\n alphaStr = `0${translucentAlpha}`;\n } else {\n alphaStr = translucentAlpha.toString();\n }\n }\n const color = `#${drivingHash.substring(0, 6)}`;\n const colorTranslucent = `#${drivingHash.substring(0, 6)}${alphaStr}`;\n const colorContrast = getContrastColor(color);\n return [color, colorTranslucent, colorContrast];\n};\n\n\n", "/**\n * @module helpers.web\n *\n * helper functions specific to the web version.\n */\n\nimport { delay, extractErrorMsg, pretty, } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\nimport { getIbGibAddr } from \"@ibgib/ts-gib/dist/helper.mjs\";\nimport { isPrimitive } from \"@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs\";\nimport { validateIbGibIntrinsically } from \"@ibgib/ts-gib/dist/V1/validate-helper.mjs\";\nimport { MetaspaceService } from \"@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs\";\nimport { RawExportIbGib_V1 } from \"@ibgib/core-gib/dist/common/import-export/import-export-types.mjs\";\nimport { FlatIbGibGraph } from \"@ibgib/core-gib/dist/common/other/graph-types.mjs\";\nimport { decompressIbGibGraphFromString, deserializeStringToGraph } from \"@ibgib/core-gib/dist/common/other/other-helper.web.mjs\";\nimport { getRawExportIbGib } from \"@ibgib/core-gib/dist/common/import-export/import-export-helper.web.mjs\";\nimport { IbGibSpaceAny } from \"@ibgib/core-gib/dist/witness/space/space-base-v1.mjs\";\n\nimport {\n GLOBAL_LOG_A_LOT, GEMINI_API_KEY_REGEXP,\n CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP\n} from \"./constants.mjs\";\nimport { showFullscreenDialog } from \"./ui/ui-helpers.mjs\";\nimport {\n initializeStorage, storageCreateStoreIfNotExist, storageDBExists, storagePut\n} from \"./storage/storage-helpers.web.mjs\";\nimport { getIbGibGlobalThis_IbGib } from \"./helpers.mjs\";\n\n\n/**\n * used in verbose logging\n */\nconst logalot = GLOBAL_LOG_A_LOT;\n\n\n/**\n * converts string to Uint8Array.\n * @param str to convert\n * @returns array\n */\nexport function stringToUint8Array(str: string): Uint8Array {\n const encoder = new TextEncoder();\n return encoder.encode(str);\n}\n\n/**\n * converts Uint8Array to string.\n * @param array to convert\n * @returns string\n */\nexport function uint8ArrayToString(array: Uint8Array) {\n const decoder = new TextDecoder();\n return decoder.decode(array);\n}\n\n/**\n * I'm pulling out node from @ibgib/ibgib rcli code. This interface is just to\n * aid in that transition.\n */\nexport interface PathUtilsHelper {\n isAbsolute(path: string): boolean;\n isRelative(path: string): boolean;\n\n // for now I'm taking out resolve since it requires being stateful and isn't\n // used AFAICT in the code I'm porting over\n // resolve(path: string): string;\n\n join(...paths: string[]): string;\n dirname(path: string): string;\n basename(path: string, ext?: string): string;\n}\n\n/**\n * Helper class that exposes pathUtils functions. Note that this is relative to\n * an individual space.\n */\nexport class PathUtilsHelper implements PathUtilsHelper {\n /** class-level log context */\n lc: string = `[${PathUtilsHelper.name}]`;\n\n // /**\n // * this path utils helper is per space, so this is the id of that space.\n // */\n // spaceId: SpaceId;\n /**\n *\n */\n // constructor({ spaceId, initialCwd, }: { spaceId: SpaceId, initialCwd: string }) {\n // const lc = `${this.lc}[ctor]`;\n // this.spaceId = spaceId;\n // let ibGibGlobalThis = getIbGibGlobalThis();\n // if (!ibGibGlobalThis.spaceShim[spaceId]) {\n // console.log(`${lc} initializing IbGibGlobalThis data`);\n // // initialize\n // ibGibGlobalThis.spaceShim[spaceId] = {\n // cwd: initialCwd,\n // initialCwd,\n // };\n // } else {\n // if (logalot) { console.log(`${lc} ibgib global this already initialized (I: e48b0cb4075e536d150919e87ddc1f24)`); }\n // }\n // }\n /**\n *\n */\n constructor() { }\n\n isAbsolute(path: string): boolean {\n if (!path) { throw new Error(`(UNEXPECTED) path falsy? (E: dcb92e11770ba06205c0afe3e6560b24)`); }\n return path.startsWith('/');\n }\n\n isRelative(path: string): boolean {\n return !this.isAbsolute(path);\n }\n\n // resolve(path: string): string {\n // const lc = `${this.lc}[${this.resolve.name}]`;\n // if (!path) { throw new Error(`(UNEXPECTED) path falsy? (E: 76161b12dbd446a0c2a9e18f4847fc24)`); }\n\n // // for our implementation, we will throw if there is a relative path\n // // specifier (. or ..) in the middle of the path. the proper\n // // implementation probably resolves these concretely.\n\n // if (this.isAbsolute(path)) {\n // if (path.includes('/../') || path.endsWith('/..')) { throw new Error(`path is absolute but contains \"/../\" in it or ends with \"../\"? (E: 16145bf37d874abc886111c32c035124)`); }\n // return path;\n // }\n\n // // we have a relative path. get the cwd from global for this particular space. If this space has no\n // let ibGibGlobalThis = getIbGibGlobalThis();\n // let info = ibGibGlobalThis.spaceShim[this.spaceId];\n // if (!info) { throw new Error(`(UNEXPECTED) no info for spaceId in ibgibglobalthis? (E: c063f34ed784e70ccd19a6b2026eb924)`); }\n\n // const { cwd } = info;\n // if (!cwd) { throw new Error(`(UNEXPECTED) cwd falsy? (E: 91cbd7418a51d9d152ae53d4f87b3a24)`); }\n // if (path.startsWith(cwd)) {\n // console.log(`${lc} path already resolved (starts with cwd). path: ${path} (I: 1d99a4bad47398174fe127b85088fb24)`);\n // }\n // if (cwd.endsWith('/')) {\n // // cwd does end with slash, so slice off initial if needed\n // return cwd + (path.startsWith('/') ? path.slice(1) : path);\n // } else {\n // // cwd does NOT end with slash, so add if needed\n // return cwd + (path.startsWith('/') ? path : `/${path}`);\n // }\n // }\n\n join(...paths: string[]): string {\n const lc = `${this.lc}[${this.join.name}]`;\n\n if (paths.length === 0) {\n console.log(`${lc} paths.length === 0. returning '.' per node convention. (I: 153da80765ff6160675fae895ebac225)`);\n return '.'; /* <<<< returns early */\n }\n if (paths.length === 1 && paths[0] === '..') {\n console.log(`${lc} paths.length === 1 && paths[0] === '..'. returning '..' per node convention. (I: 9af242b7615430a8c6899b1a332e9925)`);\n return '..'; /* <<<< returns early */\n }\n\n let joined = '';\n for (let i = 0; i < paths.length; i++) {\n let path = paths[i];\n if (path === '..') {\n joined = joined.split('/').slice(0, -1).join('/');\n } else {\n if (path.startsWith('/')) { path = path.slice(1); }\n if (path.endsWith('/')) {\n path = path.slice(0, -1);\n }\n joined += (i > 0 ? '/' : '') + path;\n }\n }\n\n return joined;\n }\n\n dirname(path: string): string {\n return path.split('/').slice(0, -1).join('/');\n }\n\n basename(path: string, ext?: string): string {\n return path.split('/').pop() ?? '';\n }\n}\n\n\nexport async function copyToClipboard({\n data,\n logalot,\n}: {\n data: { title?: string, text?: string, url?: string },\n logalot?: boolean,\n}): Promise<void> {\n const lc = `[${copyToClipboard.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 37d6a4e3c3ee9fa46a0b1cd5c8a5cf24)`); }\n let { title, text, url } = data;\n const textToCopy = [\n `${data.title || ''}`,\n `${data.text || ''}`,\n `${data.url || ''}`,\n ].join('\\n').trim();\n await navigator.clipboard.writeText(textToCopy);\n console.log('Content copied to clipboard!');\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * helper to trigger browser's share functionality (or fallback).\n */\nexport async function shareContent({\n data,\n logalot,\n}: {\n data: { title?: string, text?: string, url?: string },\n logalot?: boolean,\n}): Promise<void> {\n const lc = `[${shareContent.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: bfc7e484eba91f9126c3f5fc381e6424)`); }\n\n if (navigator.share) {\n await navigator.share(data);\n console.log('Content shared successfully!');\n } else {\n console.warn('Web Share API not supported. Copying to clipboard instead.');\n alert(`Share info copied to clipboard!`);\n await copyToClipboard({ data, logalot });\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * useful for knowing if we are executing in our website or within an iframe.\n *\n * ## driving use case\n *\n * When we are loading an embedded iframe for link-gib, it is trying to trigger\n * the router which is no bueno.\n *\n * This is causing a problem though when testing inside an iframe in Project\n * IDX...I guess I'll have to whitelist embedded sites like link-gib\n *\n * ## usage\n *\n * Put something like this in the html in <head>:\n * ```html\n * <meta name=\"ibgib-app-id-yo\" content=\"0f73bca49d2856a446044768fbab8d25\" />\n * ```\n * Then create constants like this (I put them in a constants file):\n *\n * ```typescript\n * export const HTML_META_APP_ID_NAME = \"ibgib-app-id-yo\";\n * export const HTML_META_APP_ID_CONTENT = \"0f73bca49d2856a446044768fbab8d25\";\n * ```\n *\n * Then you can call this like this:\n *\n * ```typescript\n * const isInWebAppProper = isExecutingInBlankGibWebAppProper({\n * metaName_appId: HTML_META_APP_ID_NAME,\n * metaContent_appId: HTML_META_APP_ID_CONTENT\n * });\n * ```\n *\n * @returns true if we are executing in an iframe, false otherwise.\n */\nexport function isExecutingInBlankGibWebAppProper({\n metaName_appId,\n metaContent_appId\n}: {\n /**\n * this runs code:\n *\n * `const metaElement = document.querySelector(`meta[name=${metaName_appId}]`) as (HTMLMetaElement | null);`\n *\n * in the index, you should tag the meta tag with attribute of this.\n */\n metaName_appId: string,\n /**\n * this is an appId on the `metaElement.content`\n */\n metaContent_appId: string,\n}): boolean {\n const metaElement =\n document.querySelector(`meta[name=${metaName_appId}]`) as (HTMLMetaElement | null);\n return !!metaElement && metaElement.content === metaContent_appId;\n}\n\n/**\n * Low-level plumbing for prompting the user for some text.\n *\n * ## notes\n *\n * * if an empty string is entered, confirm is automatic/always happens.\n * * if confirm is true, will confirm on any entry\n * * can just hit ENTER to confirm anything\n * * this should be parameterized\n *\n * @returns the text the user entered.\n */\nexport async function promptForText({\n msg,\n title,\n confirm,\n noNewLine,\n rl,\n defaultValue,\n dontCloseRl,\n cancelable,\n}: {\n msg: string,\n title?: string,\n confirm?: boolean,\n noNewLine?: boolean,\n /**\n * ignored in web version. used in node version. this is after all, a hack\n * port\n */\n rl?: any,\n defaultValue?: string,\n /**\n * ignored in web version. used in node version. this is after all, a hack\n * port\n */\n dontCloseRl?: boolean,\n /**\n * if true, cancel will show and an empty string will be returned\n */\n cancelable?: boolean,\n}): Promise<string> {\n const lc = `[${promptForText.name}]`;\n try {\n if (!msg) { throw new Error(`msg required (E: 7f4d67bca4cf98ea95fa110aabc98924)`); }\n\n let result: string | undefined;\n\n let attempts = 0;\n let maxAttempts = 5;\n do {\n attempts++;\n if (attempts >= maxAttempts) {\n throw new Error(`max attempts reached (E: 1ef20ae955622d4b39479f3da91a1d25)`);\n }\n await delay(50);\n result = await showFullscreenDialog({\n title: title || 'Prompt for Info',\n msg,\n prompt: true,\n showInput: true,\n isPassword: false,\n defaultValue,\n });\n\n } while (result === undefined && !cancelable);\n\n return result ?? '';\n\n // let userText: string | undefined = undefined;\n // try {\n // do {\n // title = title ? `[${title}] ` : '';\n // let promptMessage = `${title}${msg}${noNewLine ? ' ' : '\\n'}`;\n // let prompt = window.prompt;\n\n // // Handle default value (Note: `prompt` can't pre-fill like readline.write)\n // if (defaultValue) {\n // if (defaultValue.includes('\\n')) {\n // if (logalot) { console.log(`defaultValue includes newline. (I: 147d4ea942995d0f92a19c3534c18a24)`); }\n // // We can't pre-fill with newline in prompt, so we'll just inform if needed\n // }\n // promptMessage += ` (Default: ${defaultValue})`;\n // }\n\n // let userText1 = prompt(promptMessage);\n\n // // Check for cancellation (prompt returns null on cancel)\n // if (userText1 === null) {\n // // return null; // User cancelled\n // throw new Error(`user cancelled (E: bf3a221626f8cd14b2a945bfe661cb24)`);\n // }\n\n // if (userText1 === \"\") {\n // let userText2 = prompt(`empty string entered. confirm:${noNewLine ? ' ' : '\\n'}`);\n // if (userText2 === userText1) {\n // userText = userText1;\n // break;\n // } else {\n // console.log(`confirm failed. please try again.`);\n // }\n // } else if (confirm) {\n // let userText2 = prompt(`confirm by either hitting ENTER (empty string) or retype input:${noNewLine ? ' ' : '\\n'}`);\n // if (userText2 === '' || userText2 === userText1) {\n // userText = userText1;\n // } else {\n // console.log(`confirm failed. please try again.`);\n // }\n // } else {\n // userText = userText1;\n // }\n\n // } while (userText === undefined);\n\n // return userText;\n\n // } catch (error) {\n // throw error;\n // }\n } catch (error) {\n debugger; // in error block promptForText\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * not implemented atow (12/2024). I think we'll have perhaps a modal dialog\n * with a known name and get at it that way.\n */\nexport async function promptForSecret({\n msg,\n confirm,\n}: {\n msg?: string,\n confirm: boolean,\n}): Promise<string> {\n const lc = `[${promptForSecret.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 795a4ce348ddb9a5119770f4c572ac24)`); }\n\n let result: string | undefined = undefined;\n\n let firstTry = true;\n let attempts = 0;\n let maxAttempts = 5;\n\n do {\n attempts++;\n if (attempts >= maxAttempts) {\n throw new Error(`max attempts reached (E: d4166b4bf37aff0c6d44567792e9ad25)`);\n }\n await delay(50);\n result = await showFullscreenDialog({\n title: firstTry ? 'Shh...' : 'Secrets didn\\'t match, try again...',\n msg: msg || 'Enter Your Secret...',\n prompt: true,\n showInput: true,\n isPassword: true,\n defaultValue: undefined,\n });\n if (result === undefined) { throw new Error(`user cancelled (E: 91519d04378e84106f3df8eb36d99725)`); }\n\n if (confirm) {\n await delay(250);\n let result2 = await showFullscreenDialog({\n title: 'Shh...',\n msg: 'Confirm...',\n prompt: true,\n showInput: true,\n isPassword: true,\n defaultValue: undefined,\n });\n if (result2 === undefined) { result = undefined; }\n if (result !== result2) {\n result = undefined;\n firstTry = false;\n await delay(250);\n }\n }\n\n\n } while (result === undefined);\n\n return result;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * prompt specifically looking to confirm something. if \"cancelled\", returns\n * false.\n */\nexport async function promptForConfirm({\n msg,\n yesLabel,\n noLabel,\n}: {\n /**\n * if provided, this is the message displayed when confirming.\n */\n msg?: string,\n yesLabel?: string,\n noLabel?: string,\n}): Promise<boolean> {\n const lc = `[${promptForConfirm.name}]`;\n try {\n await delay(50);\n let result = await showFullscreenDialog({\n title: 'Confirm?',\n msg: msg ?? 'Confirm?',\n okButtonTitle: yesLabel || undefined,\n cancelButtonTitle: noLabel || undefined,\n prompt: true,\n });\n return !!result;\n // msg ||= 'confirm?';\n // yesLabel ||= '(y)es';\n // noLabel ||= '(n)o';\n // try {\n // const fnAnswerMatchesLabel = (answer: string, label: string) => {\n // if (answer === label.replace(/[\\(\\)]/g, '').toLowerCase()) {\n // // matched full label\n // return true; /* <<<< returns early */\n // } else {\n // // check for short answers\n // const regexCaptureCharsInsideParens = /\\((\\w+)\\)/;\n // const shortLabel = label.match(regexCaptureCharsInsideParens);\n // if ((shortLabel ?? []).length >= 2) {\n // if (answer === shortLabel![1].toLowerCase()) {\n // // matched short label\n // return true; /* <<<< returns early */\n // }\n // }\n // }\n // // if got this far, nothing positive matched\n // return false;\n // };\n\n // const prompt = window.prompt;\n\n // // try up to three times. if match found, either way, return early.\n // const maxTries = 3;\n // for (let i = 0; i < maxTries; i++) {\n // let answer = prompt(`${msg} [${yesLabel}, ${noLabel}]\\n`);\n // if (answer) {\n // answer = answer.toLowerCase();\n // const matchesYesLabel = fnAnswerMatchesLabel(answer, yesLabel);\n // if (matchesYesLabel) { return true; /* <<<< returns early */ }\n // const matchesNoLabel = fnAnswerMatchesLabel(answer, noLabel);\n // if (matchesNoLabel) { return false; /* <<<< returns early */ }\n // } else {\n // `no answer provided. defaulting to no...`;\n // console.log('huh?');\n // }\n // }\n\n // // max tries reached\n // throw new Error(`could not confirm (E: ebbd2f642bde103c41d0102cf7e38d24)`);\n // } catch (error) {\n // throw error;\n // }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function alertUser({\n msg,\n title,\n skipHitEnterToContinue,\n}: {\n msg: string,\n title?: string,\n /**\n * ignored in web version atow (12/2024)\n */\n skipHitEnterToContinue?: boolean,\n}): Promise<void> {\n const lc = `[${alertUser.name}]`;\n try {\n\n if (!msg) { throw new Error(`msg required (E: ffcf7dd00324df7cea2792223d229524)`); }\n try {\n title ??= '';\n await delay(50);\n await showFullscreenDialog({\n title,\n msg,\n });\n } catch (error) {\n throw error;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nexport function getUserPreferredColorScheme(): 'light' | 'dark' {\n const lc = `[${getUserPreferredColorScheme.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 196286d17b656bce5ce16f358f386525)`); }\n const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n return prefersDark ? 'dark' : 'light';\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * helper function to get a query param in the current url.\n *\n * # ONLY IN BROWSER\n *\n * not for use in node.js\n *\n * @returns raw\n */\nexport function getQueryParam<TValue>({ paramName, parseJSON, logalot, }: {\n paramName: string, parseJSON?: boolean, logalot?: boolean,\n}): TValue | undefined {\n const lc = `[${getQueryParam.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f1a61ecdbb52cff1b958d1ceaea85f24)`); }\n\n const url = new URL(window.location.href);\n const rawValue = url.searchParams.get(paramName);\n if (rawValue) {\n const decodedValue = decodeURIComponent(rawValue);\n if (parseJSON) {\n try {\n return JSON.parse(decodedValue) as TValue;\n } catch (parseError) {\n console.error(`${lc} Error parsing JSON from query parameter ${paramName}: ${parseError} (E: fa8128dbe8ed41fc9fdf57a8146d88de)`);\n throw parseError;\n }\n } else {\n return decodedValue as TValue;\n }\n } else {\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * helper function to set a query param in the current url.\n *\n * # ONLY IN BROWSER\n *\n * not for use in node.js\n */\nexport function setQueryParam<TValue>({\n paramName, paramValue, rmParam, logalot,\n}: {\n paramName: string,\n paramValue?: TValue,\n /**\n * if true, we will remove the param from the URL.\n */\n rmParam?: boolean,\n logalot?: boolean,\n}): void {\n const lc = `[${setQueryParam.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f3c557d19f5b3a723611c59aa4a20324)`); }\n const url = new URL(window.location.href);\n\n if (rmParam) {\n url.searchParams.delete(paramName);\n } else {\n const actualValue = typeof paramValue === 'string' ?\n paramValue :\n JSON.stringify(paramValue);\n url.searchParams.set(paramName, actualValue);\n }\n\n // Update the URL without reloading the page\n window.history.replaceState({}, '', url.toString());\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * helper to highlight an element with border/background.\n *\n * ## requires\n *\n * .highlight and .unhighlight classes\n *\n * The unhighlight is for correctly showing the transition/animation.\n *\n * ## intent\n *\n * Just making this to make highlighting things (drawing the user's eye)\n * easier and more consistent.\n *\n * @see {@link unhighlightElement}\n */\nexport async function highlightElement({\n el,\n magicHighlightTimingMs,\n scrollIntoView,\n}: {\n el: HTMLElement,\n /**\n * if provided, will unhighlight the element after this delay in ms\n */\n magicHighlightTimingMs?: number,\n scrollIntoView?: boolean,\n}): Promise<void> {\n const lc = `[${highlightElement.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 1820329f88bb937b21ff98e624c03e25)`); }\n\n if (scrollIntoView) { el.scrollIntoView({ behavior: 'smooth' }); }\n\n el.classList.add('highlight');\n if (magicHighlightTimingMs) {\n await delay(magicHighlightTimingMs);\n el.classList.add('unhighlight');\n el.classList.remove('highlight');\n await delay(magicHighlightTimingMs);\n el.classList.remove('unhighlight');\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * @see {@link highlightElement}\n */\nexport async function unhighlightElement({\n el,\n}: {\n el: HTMLElement,\n}): Promise<void> {\n const lc = `[${unhighlightElement.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: ee5894b05ec31085883098cc512e1c25)`); }\n\n el.classList.add('unhighlight');\n el.classList.remove('highlight');\n await delay(500);\n el.classList.remove('unhighlight');\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Takes an incoming string. Assumes it's invalid. Does best effort at validating this.\n * Gets the raw export ibgib if it can. If so, and if it is compressed, decompresses the\n * compressed graph contained in the export ibgib.\n *\n * @returns RawExportIbGib_V1 and its decompressed graph\n */\nexport async function getRawExportIbGibAndGraphFromJsonString({\n exportIbGibJsonString,\n metaspace,\n}: {\n exportIbGibJsonString: string,\n metaspace: MetaspaceService,\n}): Promise<[RawExportIbGib_V1, FlatIbGibGraph]> {\n const lc = `[${getRawExportIbGibAndGraphFromJsonString.name}]`;\n try {\n debugger; // walk thru getRawExportIbGibAndGraphFromJsonString\n if (logalot) { console.log(`${lc} starting... (I: genuuid)`); }\n if (!metaspace) { throw new Error(`(UNEXPECTED) metaspace falsy? (E: genuuid)`); }\n\n const space = await metaspace.getLocalUserSpace({ lock: false });\n if (!space) { throw new Error(`(UNEXPECTED) couldn't get default local user space? (E: genuuid)`); }\n\n let parsedIbGib_notYetValidated: IbGib_V1;\n let parsedExportIbGib_dependenciesNotValidated: RawExportIbGib_V1;\n try {\n parsedIbGib_notYetValidated = JSON.parse(exportIbGibJsonString) as IbGib_V1;\n } catch (error) {\n const emsg = `Error during parse JSON. error: ${extractErrorMsg(error)} (E: genuuid)`;\n const errorHack = new Error(emsg);\n (errorHack as any).cause = error;\n throw errorHack;\n }\n try {\n const validationErrors = await validateIbGibIntrinsically({ ibGib: parsedIbGib_notYetValidated }) ?? [];\n if (validationErrors.length > 0) {\n throw new Error(`validation errors when validating the parsed ibgib that should be a RawExportIbGib_V1: ${validationErrors} (E: 8ba178d3b26e8eca28a67c182fe16825)`);\n }\n // todo: other validation raw export ibgib, maybe to see if it's a full dependency graph, etc.\n\n parsedExportIbGib_dependenciesNotValidated = parsedIbGib_notYetValidated as RawExportIbGib_V1;\n if (!parsedExportIbGib_dependenciesNotValidated.data) { throw new Error(`(UNEXPECTED) rawExportIbGib.data falsy? (E: ef1824d1cca5584ab8e34288346e9825)`); }\n } catch (error) {\n const emsg = `Error during parse JSON. error: ${extractErrorMsg(error)} (E: genuuid)`;\n const errorHack = new Error(emsg);\n (errorHack as any).cause = error;\n throw errorHack;\n }\n\n\n\n // at this point, we have a possibly quite large ibGib whose data\n // includes a dependencyGraphAsString. this could possibly be\n // compressed.\n let payloadGraph: FlatIbGibGraph;\n if (!!parsedExportIbGib_dependenciesNotValidated.data.compression) {\n switch (parsedExportIbGib_dependenciesNotValidated.data.compression) {\n case 'gzip':\n payloadGraph = await decompressIbGibGraphFromString({\n compressedBase64: parsedExportIbGib_dependenciesNotValidated.data.dependencyGraphAsString,\n });\n break;\n default:\n throw new Error(`unknown value of rawExportIbGib.data.compression: ${parsedExportIbGib_dependenciesNotValidated.data.compression} (E: 784672fae568312d887ddbb841199925)`);\n }\n } else {\n payloadGraph = await deserializeStringToGraph({\n jsonString: parsedExportIbGib_dependenciesNotValidated.data.dependencyGraphAsString\n });\n }\n\n const validationErrorMap: { [addr: string]: string[] } = {};\n for (const [addr, payloadIbGib] of Object.entries(payloadGraph)) {\n const validationErrors = await validateIbGibIntrinsically({ ibGib: payloadIbGib }) ?? [];\n if (validationErrors.length > 0) { validationErrorMap[addr] = validationErrors; }\n }\n if (Object.keys(validationErrorMap).length > 0) {\n throw new Error(`there were validation errors for the RawExportIbGib_V1.data payload (contained in data.dependencyGraphAsString). Here is the validationErrorMap:\\n${pretty({ validationErrorMap })} (E: e63f38b182a84122d83a55befb369825)`);\n }\n const exportIbGib_validated = parsedExportIbGib_dependenciesNotValidated;\n\n return [exportIbGib_validated, payloadGraph];\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * exports a given ibgib to the default local userspace in the metaspace.\n */\nexport async function exportIbGib({\n ibGib,\n compress,\n // downloadAnchorEl,\n metaspace,\n space,\n}: {\n ibGib: IbGib_V1,\n compress: boolean,\n // downloadAnchorEl: HTMLAnchorElement,\n metaspace: MetaspaceService,\n space: IbGibSpaceAny,\n}): Promise<void> {\n const lc = `[${exportIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 623d9463d919683be81f749821a95825)`); }\n if (isPrimitive({ ibGib })) { throw new Error(`ibGib is primitive. Can't export primitive. (E: dd42c42e9fda0707e81c692af1a2a225)`); }\n\n const resGetExport = await getRawExportIbGib({\n ibGib,\n live: true,\n compress,\n metaspace: metaspace,\n space,\n });\n\n const { rawExportIbGib: exportIbGib, errors: exportErrors } = resGetExport;\n if ((exportErrors ?? []).length > 0) { throw new Error(`Export had errors: ${exportErrors!} (E: 05faf83f25d3449ab809dfd24eeaf825)`); }\n\n // at this point, we have a possibly quite large ibGib whose data includes\n // every single other ibgib that ibGib relates to (its dependency graph). This\n // so now we can save this file and later import from it.\n\n /**\n * exportIbGib is guaranteed to have a serializable structure, i.e.,\n * the data has only primitives. (there are no Uint8Array)\n */\n const exportIbGibAsString = JSON.stringify(exportIbGib);\n\n // thank you SO, OP and volzotan at https://stackoverflow.com/questions/19721439/download-json-object-as-a-file-from-browser\n // set the anchor's href to a data stream\n const dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(exportIbGibAsString);\n\n // get the filename for the anchor to suggest for the \"download\"\n const exportAddr = getIbGibAddr({ ibGib: exportIbGib });\n const filename = `${exportAddr}.json`;\n\n // trigger the click\n const downloadAnchorEl = document.createElement('a');\n downloadAnchorEl.setAttribute(\"style\", \"none\");\n downloadAnchorEl.setAttribute(\"href\", dataStr);\n downloadAnchorEl.setAttribute(\"download\", filename);\n const div = document.getElementsByTagName('div')[0]; // just append to the first div then remove it\n div.appendChild(downloadAnchorEl);\n downloadAnchorEl.click();\n div.removeChild(downloadAnchorEl);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function promptForAPIKey({\n msg,\n}: {\n /**\n * msg to tell the user when prompting for the API key (secret)\n *\n * originally in blankgib, this is CHAT_WITH_AGENT_NEED_API_KEY\n */\n msg: string,\n}): Promise<string | undefined> {\n const lc = `[${promptForAPIKey.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: genuuid)`); }\n let resAPIKey = '';\n let tryAgain = false;\n let attempts = 0;\n let maxAttempts = 5;\n do {\n attempts++;\n if (attempts >= maxAttempts) { throw new Error(`too many attempts (E: genuuid)`); }\n resAPIKey = await promptForSecret({\n msg,\n confirm: false,\n });\n if (resAPIKey) {\n if (resAPIKey.match(GEMINI_API_KEY_REGEXP)) {\n tryAgain = false;\n // return resAPIKey; /* <<<< returns early */\n } else {\n await alertUser({\n title: `That's an API Key?`,\n msg: `That doesn't look like a valid API key, please try again, or hit cancel if you don't want to at this time.`,\n });\n tryAgain = true;\n }\n } else {\n console.log(`${lc} user cancelled entering API key. (I: genuuid)`);\n tryAgain = false;\n }\n } while (tryAgain);\n\n return resAPIKey;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * updates the given {@link apiKey}. if {@link force} is true and `apiKey` is\n * empty, then this will set an empty string for the apiKey, effectively\n * deleting it.\n */\nexport async function updateAPIKeyInStorage({\n dbName,\n storeName,\n key,\n apiKey,\n force,\n}: {\n dbName: string,\n storeName: string,\n key: string,\n apiKey: string,\n force: boolean,\n}): Promise<void> {\n const lc = `[${updateAPIKeyInStorage.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 64951b38da35ec5ff847004d53b2d425)`); }\n\n const matches = apiKey.match(GEMINI_API_KEY_REGEXP);\n if (matches || force) {\n await storagePut({\n dbName, storeName,\n key,\n value: apiKey,\n });\n if (apiKey) {\n // set a new truthy key\n await alertUser({ title: `need to reload...`, msg: `Cool! We successfully SAVED your Gemini API key in your browser's IndexedDB.\\n\\nIf you'd like to remove it later, you can clear it out by using the ${CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP}.\\n\\nWe must now reload the page to use the new API key... (investment would be a good thing to improve this UX workflow!)` });\n } else {\n // cleared out the key\n await alertUser({ title: `need to reload...`, msg: `Cool! We successfully CLEARED your Gemini API key from your browser's IndexedDB.\\n\\nIf you'd like to set a new key, use the ${CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP}.\\n\\nThe API key is already removed, but we must now reload the page for this to propagate throughout the web page... (investment would be a good thing to improve this UX workflow!)` });\n }\n window.location.reload();\n } else {\n throw new Error(`apiKey does not match apiKeyRegex (${GEMINI_API_KEY_REGEXP.source}) and force is false. (E: 2d6c798803e6b71bf6aa70bd60170825)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n\n}\n\n/**\n * wrapper for simplifying/asserting an element that is expected to exist.\n *\n * ## intent\n *\n * This avoids using TypeScript truthy assertions (!) or excessive\n * falsy/exception checks.\n */\nexport function getElementById_throwsIfFalsy<TElement extends Element>({\n id,\n shadowRoot,\n}: {\n id: string;\n /**\n * If set, will get element here, else will use document\n */\n shadowRoot?: ShadowRoot;\n}): TElement {\n const lc = `[${getElementById_throwsIfFalsy.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 18a338c6dab8690c72b8759b8d952925)`); }\n let resElement = !!shadowRoot ?\n shadowRoot.getElementById(id) as TElement | null :\n document.getElementById(id) as TElement | null;\n\n if (resElement) {\n return resElement;\n } else {\n throw new Error(`${!!shadowRoot ? 'shadowRoot' : 'document'}.getElementById(${id}) returned null. So...Element was not found. (E: 5e501f6835cc74cd4c2faf0d9e387825)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * wrapper that throws if element not found.\n * @param id of Element\n * @returns Element of type TElement or throws.\n * @see {@link shadowRoot_getElementById}\n *\n * ## intent\n *\n * This avoids using TypeScript truthy assertions (!) or excessive\n * falsy/exception checks.\n */\nexport function document_getElementById<TElement extends Element = HTMLElement>(id: string): TElement {\n return getElementById_throwsIfFalsy<TElement>({ id });\n}\n\n/**\n * wrapper that throws if element not found.\n * @param shadowRoot in which the element MUST be truthy or throws\n * @param id of Element\n * @returns Element of type TElement or throws.\n * @see {@link document_getElementById}\n *\n * ## intent\n *\n * This avoids using TypeScript truthy assertions (!) or excessive\n * falsy/exception checks.\n */\nexport function shadowRoot_getElementById<TElement extends Element = HTMLElement>(shadowRoot: ShadowRoot, id: string): TElement {\n return getElementById_throwsIfFalsy<TElement>({ id, shadowRoot });\n}\n\nexport function getGlobalStoreName(): string {\n const lc = `[${getGlobalStoreName.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 62a29f9982b4b5ecd91ff58ca4dd6825)`); }\n // ARMY_STORE in blankgib\n const hackGlobal = getIbGibGlobalThis_IbGib();\n if (!hackGlobal.storeName_hack) { throw new Error(`(UNEXPECTED) global store name falsy? (E: 3b9b680f6a980debbb877c9a13fb2625)`); }\n return hackGlobal.storeName_hack;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getGlobalDbName(): string {\n const lc = `[${getGlobalDbName.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 8c8f08728fc7384f87697377358cc825)`); }\n // BLANK_GIB_DB_NAME in blankgib\n const hackGlobal = getIbGibGlobalThis_IbGib();\n if (!hackGlobal.dbName_hack) { throw new Error(`(UNEXPECTED) global db name falsy? (E: 3aa028d5e4088f3f3841aae94ac02825)`); }\n return hackGlobal.dbName_hack;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getGlobalIndexedDbKey_APIKey(): string {\n const lc = `[${getGlobalIndexedDbKey_APIKey.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 59a2510a85051f97ed15fbc8825b6825)`); }\n // BEE_KEY in blankgib\n const hackGlobal = getIbGibGlobalThis_IbGib();\n if (!hackGlobal.apiKeyName_hack) { throw new Error(`(UNEXPECTED) global api key name falsy? (E: 1782e812f0c87f54b8059468a5b60125)`); }\n return hackGlobal.apiKeyName_hack;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * helper info for {@link initAppStorage}\n */\ninterface AppStorageInfo {\n dbName: string;\n storeNames: string[];\n}\n/**\n * ensures db and stores are created and can be used.\n */\nexport async function initAppStorage({\n infos,\n}: {\n infos: AppStorageInfo[],\n}): Promise<void> {\n const lc = `[${initAppStorage.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 4d41880fb748ee2302a624a255665825)`); }\n\n for (const info of infos) {\n const { dbName, storeNames } = info;\n const dbExists = await storageDBExists({\n dbName,\n // dbName: BLANK_GIB_DB_NAME,\n });\n if (!dbExists) {\n await initializeStorage({\n dbName,\n // dbName: BLANK_GIB_DB_NAME,\n });\n }\n for (const storeName of storeNames) {\n await storageCreateStoreIfNotExist({\n dbName,\n storeName,\n // dbName: BLANK_GIB_DB_NAME,\n // storeName: ARMY_STORE,\n });\n }\n // await storageCreateStoreIfNotExist({\n // dbName: BLANK_GIB_DB_NAME,\n // storeName: ARMY_STORE,\n // });\n\n // await storageCreateStoreIfNotExist({\n // dbName: BLANK_GIB_DB_NAME,\n // storeName: ZERO_SPACE_ID,\n // logalot,\n // });\n }\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "/**\n * @module storage-helpers.web.mts\n *\n * This is the storage abstraction that wraps indexed db.\n *\n * NOTE:\n *\n * I just want to say that callbacks are not very cool and that much of the\n * ridiculousness of this code is due to this fact.\n *\n * That said, these functions try to ensure db is closed per function via global\n * finally block. With nested promises and callbacks, this is a big f*n mess.\n * But more importantly, this is why there aren't db.close() calls sprinkled\n * throughout each function. But ths assumes that I am wiring up resolve/reject\n * calls correctly through all the paths and this is far from certain.\n */\n\nimport { extractErrorMsg } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\n\nimport { GLOBAL_LOG_A_LOT, } from \"../constants.mjs\";\nimport { uint8ArrayToString } from \"../helpers.web.mjs\";\nimport { Dirent } from \"./storage-types.web.mjs\";\n\n\nlet logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * key/value pair interface for working with indexeddb\n */\nexport interface IndexedDBStorageDatum {\n key: string;\n /**\n * may have to change this to work with binary array buffers.\n */\n value: string | Uint8Array;\n}\n\nlet initRequestCount: number = 0;\n\nexport async function askForPersistStorage(): Promise<void> {\n const lc = `[${askForPersistStorage.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 94b9aca3633e3d4cd3d420329a9c7425)`); }\n const _unusedtesting = await navigator.storage.persist();\n if (navigator.storage?.persist) {\n const alreadyPersisted = await navigator.storage.persisted();\n if (alreadyPersisted) {\n if (logalot) { console.log(`${lc} navigator.storage is already persisted (I: 2e55a7106e6d07715356b5feb5300b25)`); }\n } else {\n if (logalot) { console.log(`${lc} navigator.storage not already persisted. asking navigator.storage for persist... (I: 78086d15e2e94c14a0028c584099d715)`); }\n const persisted = await navigator.storage.persist();\n if (logalot) { console.log(`${lc} navigator.storage persist: ${persisted} (I: 923eb26c2c3240c9b5659c3266388071)`); }\n }\n } else {\n if (logalot) { console.warn(`${lc} navigator.storage.persist not supported. (W: f5a9c3a8f7614d30b9f205f3f6c61b34)`); }\n }\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * initializes db ALWAYS but initializes store given by {@link storeName} ONLY\n * WHEN VERSION IS HIGHER THAN EXISTING VERSION.\n *\n * @see {@link storageCreateStoreIfNotExist}\n */\nexport async function initializeStorage({\n dbName,\n storeName,\n version,\n logalot = false,\n}: {\n dbName: string,\n storeName?: string,\n version?: number,\n logalot?: boolean,\n}): Promise<void> {\n const lc = `[${initializeStorage.name}][${dbName}][${storeName ?? 'no store name'}]`;\n const uuid = crypto.randomUUID();\n if (logalot) { console.time(lc + uuid); }\n /** db variable outside try block for finally access in order to close it. */\n let db: IDBDatabase | undefined = undefined;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f35d4e1ba37252f14c8532fb861b1125)`); }\n\n const prom = new Promise<void>((resolve, reject) => {\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0aeddd9376daa0a044677ce4cf8a4c24)`); }\n\n // Open a database connection\n if (logalot) { console.timeLog(lc + uuid, 'opening... (I: e748b4ddb445d77cb10a7ba158b49125)') }\n // so when we get here via storageCreateStoreIfNotExist function,\n // the version is going to be a bumped number. so is this what is\n // necessarily triggering the onblocked?\n const openDBRequest = indexedDB.open(dbName, /*version*/version);\n initRequestCount++;\n console.log(`${lc} initRequestCount: ${initRequestCount} (I: 294d5f0b12ffe5512bacebe891824d25)`);\n let storeAlreadyExisted: boolean | undefined = undefined;\n openDBRequest.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n try {\n db = (event.target as any).result as IDBDatabase;\n if (logalot) { console.timeLog(lc + uuid, 'onupgradeneeded... (I: e748b4ddb445d77cb10a7ba158b49125)') }\n\n // Create a store if it doesn't exist. note that\n // db.createObjectStore can only be called within this\n // onupgradeneeded handler.\n if (storeName) {\n if (!db.objectStoreNames.contains(storeName)) {\n storeAlreadyExisted = false;\n db.createObjectStore(storeName, { keyPath: 'key' });\n } else {\n storeAlreadyExisted = true;\n }\n }\n } catch (error) {\n console.error(`${lc}[openDBRequest.onupgradeneeded] ${extractErrorMsg(error)} (E: 4a5fa1b0850be47e28bee653da287325)`);\n reject(error);\n }\n };\n\n openDBRequest.onblocked = (event: IDBVersionChangeEvent) => {\n console.log(`${lc}[openDBRequest.onblocked] openDBRequest blocked...time wasted a bit here. version change event (old -> new): ${event.oldVersion} -> ${event.newVersion} (I: 9074ebf4afdba54d6f9d41b360b96a25)`);\n console.dir(event);\n };\n\n /**\n * this handler fires independently of upgradeneeded\n */\n openDBRequest.onsuccess = (ev) => {\n try {\n if (logalot) { console.log('init success (I: 297a5a71e405a0b56413af813f248d24)'); }\n if (logalot) { console.timeLog(lc + uuid, 'onupgradeneeded... (I: e748b4ddb445d77cb10a7ba158b49125)') }\n db = (ev.target as any).result as IDBDatabase;\n if (storeName) {\n storeAlreadyExisted ??= db.objectStoreNames.contains(storeName);\n if (logalot) { console.log(`${lc} ${dbName} store \"${storeName}\" ${storeAlreadyExisted ? 'already exists' : 'does not exist'}. (I: db64712bc69c5287b1cf77af1fc13d24)`); }\n }\n resolve();\n } catch (error) {\n console.error(`${lc}[openDBRequest.onsuccess] ${extractErrorMsg(error)}`);\n reject(error);\n }\n };\n\n openDBRequest.onerror = (event: any) => { // IDBRequestEvent but doesn't compile\n debugger; // error initializeStorage openDBRequest.onerror\n console.error(`${lc}[initRequest.onerror] ${extractErrorMsg(openDBRequest.error)} (E: 74cf09e9fba2dd9e41225e943c331124)`);\n reject(openDBRequest.error); // same as below?\n // reject(event.target.error);\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n debugger; // error\n reject(error);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n });\n await prom;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (db) {\n if (logalot) { console.log(`${lc} closing db ${dbName}... (I: 3f1c18eec567ea63f3927eef0f038925)`); }\n (db as any).close();\n if (logalot) {\n console.log(`${lc} closing db ${dbName} complete. (I: bc3b2f504245d6203dbba6bd65d30325)`);\n console.timeLog(lc + uuid, 'db closed. (I: e748b4ddb445d77cb10a7ba158b49125)')\n }\n }\n if (logalot) {\n console.log(`${lc} complete.`);\n console.timeEnd(lc + uuid);\n }\n }\n\n}\n\n/**\n * wrapper for filtered indexedDB.databases() call basically\n *\n * @returns db info for given dbName\n */\nexport async function storageGetDBInfo({\n dbName,\n logalot = false,\n}: {\n dbName: string,\n logalot?: boolean,\n}): Promise<IDBDatabaseInfo | undefined> {\n const lc = `[${storageGetDBInfo.name}]`;\n\n const uuid = crypto.randomUUID();\n if (logalot) { console.time(lc + uuid); }\n try {\n if (logalot) { console.log(`${lc} starting... (I: 8516795b20529d19eb6923defd7a0f24)`); }\n const dbInfo = (await indexedDB.databases()).filter(x => x.name === dbName).at(0);\n return dbInfo;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n } finally {\n if (logalot) { console.timeEnd(lc + uuid); }\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n\n/**\n * wrapper that ensures indexeddb store exists\n */\nexport async function storageCreateStoreIfNotExist({\n dbName,\n storeName,\n logalot = false,\n}: {\n dbName: string,\n storeName: string,\n logalot?: boolean,\n}): Promise<void> {\n const lc = `[${storageCreateStoreIfNotExist.name}]`;\n const uuid = crypto.randomUUID();\n if (logalot) { console.time(lc + uuid); }\n /** db variable outside try block for finally access in order to close it. */\n let db: IDBDatabase | undefined = undefined;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 029f7caa8ea5ea08a865f3924c82b624)`); }\n\n const dbInfo_viaIndexedDBDatabasesFn = (await indexedDB.databases()).filter(x => x.name === dbName).at(0);\n if (!dbInfo_viaIndexedDBDatabasesFn) { throw new Error(`db (${dbName}) does not exist. can't create store (${storeName}) (E: 5b15f7aed6f7068d077b2c7ebcbe8524)`); }\n\n let storeExists = false;\n\n if (logalot) { console.timeLog(lc + uuid); }\n\n await new Promise<void>((resolve, reject) => {\n const openDBRequest = indexedDB.open(dbName);\n openDBRequest.onsuccess = (ev: Event) => {\n db = (ev.target as any).result as IDBDatabase;\n storeExists = db.objectStoreNames?.contains(storeName);\n if (logalot) { console.timeLog(lc + uuid, 'open db request'); }\n resolve();\n };\n openDBRequest.onerror = (event: any) => { // IDBRequestEvent but doesn't compile\n debugger; // error storageCreateStoreIfNotExist openDBRequest.onerror\n console.error(`${lc}[openDBRequest.onerror] ${extractErrorMsg(openDBRequest.error)} (E: 63695744e9e59ff8019e04ceeb8e2524)`);\n // reject(event.target.error); // same as openDBRequest.error?\n reject(openDBRequest.error);\n };\n });\n\n if (logalot) { console.timeLog(lc + uuid); }\n\n if (storeExists) {\n if (logalot) { console.log(`${lc} store ${storeName} already existed. (I: a2263b510c18240fc59fca54e3892324)`); }\n return; /* <<<< returns early */\n }\n\n // store does not exist, so get the version number, bump it, and in the upgradeneeded handler, create the store\n const dbInfo = await storageGetDBInfo({ dbName, logalot }); // does not need db closed yet\n if (logalot) { console.timeLog(lc + uuid, 'storageGetDBInfo complete'); }\n if (!dbInfo) { throw new Error(`db (${dbName}) does not exist. can't create store (${storeName}) (E: c771db13fa28f67079aad45e1ab7e624)`); }\n const version = dbInfo.version;\n if (!version) { throw new Error(`db (${dbName}) has no version. can't create store (${storeName}) (E: 3d2ec52853ad99f92b19ac5aa7fbfe24)`); }\n const newVersion = version + 1;\n if (logalot) { console.log(`${lc} creating store ${storeName} with version ${newVersion} (I: 312b79f28243c650cf38935114f21e24)`); }\n // we need to manually close db here before calling the inititalizeStorage\n if (db) {\n (db as any).close();\n db = undefined;\n } else {\n throw new Error(`(UNEXPECTED) how did we get here with db falsy? (E: b561784879e19bac54b1c4936aff0c25)`);\n }\n await initializeStorage({ dbName, storeName, version: newVersion, logalot });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error; // why wasn't I rethrowing??\n } finally {\n if (db) {\n if (logalot) { console.log(`${lc} closing db ${dbName}... (I: 3f1c18eec567ea63f3927eef0f038925)`); }\n (db as any).close();\n if (logalot) { console.log(`${lc} closing db ${dbName} complete. (I: bc3b2f504245d6203dbba6bd65d30325)`); }\n }\n if (logalot) { console.timeLog(lc + uuid); }\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * set key/value item\n * helper for indexeddb storage.\n */\nexport async function storagePut({\n dbName,\n version,\n storeName,\n key,\n value,\n logalot = false,\n}: {\n dbName: string,\n version?: number,\n storeName: string,\n key: string,\n value: string | Uint8Array,\n logalot?: boolean,\n}): Promise<void> {\n const lc = `[${storagePut.name}]`;\n /** db variable outside try block for finally access in order to close it. */\n let db: IDBDatabase | undefined = undefined;\n try {\n if (logalot) { console.log(`${lc} starting... (I: bf7316c244888cb8ead2d3aac1d9f625)`); }\n\n const prom = new Promise<void>((resolve, reject) => {\n try {\n if (logalot) { console.log(`${lc} starting... (I: 81df59e3961d711ce5d8f2ae3e2f3824)`); }\n\n const openDBRequest = indexedDB.open(dbName, /*version*/version);\n openDBRequest.onsuccess = (event: any) => { // IDBOpenDBRequestEvent?\n db = event.target.result as IDBDatabase;\n try {\n const store = db.transaction(storeName, 'readwrite').objectStore(storeName);\n const data: IndexedDBStorageDatum = { key, value };\n store.put(data);\n resolve();\n } catch (error) {\n console.error(`${lc}[putRequest.onsuccess] ${extractErrorMsg(error)}`);\n reject(error);\n }\n };\n\n openDBRequest.onerror = (event: any) => { // IDBRequestEvent?\n debugger; // storagePut openDBRequest error\n // is openDBRequest.error same as event.target.error?\n console.error(`${lc}[putRequest.onerror] ${extractErrorMsg(openDBRequest.error)} (E: 7a946d99ede2b248df4dcfea4ac99724)`);\n reject(openDBRequest.error);\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n reject(error);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n });\n\n await prom;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (db) {\n if (logalot) { console.log(`${lc} closing db ${dbName}... (I: 438c6edced94b83a3478c71b08c6c325)`); }\n (db as any).close();\n if (logalot) { console.log(`${lc} closing db ${dbName} complete. (I: 0d081553b1eb53c65ade2cedb802cf25)`); }\n }\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * get item via key\n * helper for indexeddb storage.\n */\nexport async function storageGet({\n dbName,\n version,\n storeName,\n key,\n logalot = false,\n}: {\n dbName: string,\n version?: number,\n storeName: string,\n key: string,\n logalot?: boolean,\n}): Promise<string | undefined> {\n const lc = `[${storageGet.name}]`;\n /** db variable outside try block for finally access in order to close it. */\n let db: IDBDatabase | undefined = undefined;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f8ba7cd5801918a8580e91b7c90aa525)`); }\n const prom = new Promise<string | undefined>((resolve, reject) => {\n try {\n if (logalot) { console.log(`${lc} starting... (I: 24163c4a11c8712097db45febaf9c724)`); }\n\n // Retrieve the value later\n const openDBRequest = indexedDB.open(dbName, version);\n openDBRequest.onsuccess = (event: any) => { // IDBOpenDBRequestEvent?\n db = event.target.result as IDBDatabase;\n\n let store: IDBObjectStore;\n try {\n store = db.transaction(storeName).objectStore(storeName);\n } catch (error) {\n debugger; // error getting objectStore\n console.error(`${lc}[openDBRequest.onsuccess][objectStore] ${extractErrorMsg(error)}`);\n reject(error);\n return; /* <<<< returns early */\n }\n\n // Get the value using the key\n const getRequest = store.get(key);\n getRequest.onsuccess = (event: any) => { // IDBRequestEvent?\n try {\n let value = (event.target?.result as IndexedDBStorageDatum)?.value ?? undefined;\n if (!value) {\n resolve(value);\n return; /* <<<< returns early */\n }\n\n if (logalot) { console.log('Retrieved value:', value); }\n if (value instanceof Uint8Array) {\n resolve(uint8ArrayToString(value as Uint8Array));\n } else {\n if (typeof value !== 'string') { throw new Error(`(UNEXPECTED) truthy, non-Uint8Array value is not a string? (E: 6a4ec24e2e5d9848f8b542bc2661dc24)`); }\n resolve(value);\n }\n } catch (error) {\n reject(error);\n }\n };\n\n getRequest.onerror = (event: any) => {\n debugger; // storageGet getRequest.onerror\n const error = getRequest.error;\n console.error(`${lc}[openDBRequest.onsuccess][getRequest.onerror] ${extractErrorMsg(error)}`);\n reject(error);\n };\n };\n\n openDBRequest.onerror = (event: any) => { // IDBRequestEvent but doesn't compile\n debugger; // error indexeddb storageGet openDBRequest.onerror\n // are openDBRequest.error and event.target.error the same?\n console.error(`${lc}[openDBRequest.onerror] ${extractErrorMsg(openDBRequest.error)} (E: 074963a908fa9a075f01c73cae829224)`);\n reject(openDBRequest.error);\n };\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n reject(error);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n });\n\n const result = await prom;\n return result;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (db) {\n if (logalot) { console.log(`${lc} closing db ${dbName}... (I: a938fc22dfdc76b15f6926bc4d458225)`); }\n (db as any).close();\n if (logalot) { console.log(`${lc} closing db ${dbName} complete. (I: 18f2ec1557bc83ec4e2c5d5e72264525)`); }\n }\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * checks if db exists. if store is provided, checks to see if that specific\n * store exists in the db's schema.\n *\n * helper for indexeddb storage.\n */\nexport async function storageDBExists({\n dbName,\n store,\n}: {\n dbName: string,\n store?: string,\n}): Promise<boolean> {\n const lc = `[${storageDBExists.name}]`;\n /** db variable outside try block for finally access in order to close it. */\n let db: IDBDatabase | undefined = undefined;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 2b4373affa3841220f0b7ca690406624)`); }\n\n const dbs = await window.indexedDB.databases();\n const dbExists = dbs.some(db => db.name === dbName);\n if (dbExists) {\n if (store) {\n return await new Promise((resolve, reject) => {\n const openDBRequest = indexedDB.open(dbName);\n openDBRequest.onsuccess = (event: any) => { // IDBOpenDBRequestEvent?\n db = event.target.result as IDBDatabase;\n const storeExists = db.objectStoreNames.contains(store);\n resolve(storeExists);\n };\n openDBRequest.onerror = (event: any) => { // IDBRequestEvent but doesn't compile\n debugger; // onerror\n db = openDBRequest.result;\n const { error } = event.target;\n console.error(`${lc}[openDBRequest.onerror] ${extractErrorMsg(openDBRequest.error)} (E: c783fe607451e46c1feae3a81e0f7924)`);\n reject(error);\n };\n });\n } else {\n return true;\n }\n } else {\n return false;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (db) {\n if (logalot) { console.log(`${lc} closing db ${dbName}... (I: 8782d9eea285cf9eb638d493a421a625)`); }\n // for some reason, typescript incorrectly thinks db is type\n // \"never\", so this any cast is necessary\n (db as any).close();\n if (logalot) { console.log(`${lc} closing db ${dbName} complete. (I: 76a0c5dea2643e2bb84c82c8446a8125)`); }\n }\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * helper function equivalent to rm -rf in our filesystem space\n */\nexport async function storageRmRF({\n dbName,\n storeName,\n pathToRm,\n}: {\n dbName: string;\n storeName: string;\n pathToRm: string;\n}): Promise<void> {\n const lc = `[${storageRmRF.name}]`;\n /**\n * turning it off for this function...note that this does not call any other\n * functions in this file that would be affected.\n */\n const logalotInitDebug = logalot;\n // logalot = false;\n if (logalot) { console.log(`${lc} starting... (I: c7e4cb759789ece0a8189d7dfb4d2a24)`); }\n /** db variable outside try block for finally access in order to close it. */\n let db: IDBDatabase | undefined = undefined;\n return new Promise<void>((resolve, reject) => {\n try {\n if (!dbName) { throw new Error(`(UNEXPECTED) dbName falsy? (E: ed336d88c9c4e8d4916b29356dc58324)`); }\n if (!storeName) { throw new Error(`(UNEXPECTED) storeName falsy? (E: ad493bb79b63a192524b14c59a706524)`); }\n if (!pathToRm) { throw new Error(`(UNEXPECTED) pathToRm falsy? (E: 88c9631d93467e17996946882254af24)`); }\n const openDBRequest = indexedDB.open(dbName);\n\n openDBRequest.onerror = () => {\n debugger; // error\n if (openDBRequest.result) { // Only close if a DB object was obtained\n (openDBRequest.result as IDBDatabase).close();\n }\n console.error(`${lc}[openDBRequest.onerror] ${extractErrorMsg(openDBRequest.error)} (E: 4c5ab71a765e61b4292008fd4fafe324)`);\n reject(openDBRequest.error);\n };\n\n openDBRequest.onsuccess = () => {\n db = openDBRequest.result;\n const transaction = db.transaction(storeName, \"readwrite\");\n const objectStore = transaction.objectStore(storeName);\n\n // Use IDBKeyRange.lowerBound() for efficiency\n const range = IDBKeyRange.lowerBound(pathToRm);\n const openCursorRequest = objectStore.openCursor(range);\n\n openCursorRequest.onerror = () => {\n debugger; // error\n console.error(`${lc}[openCursorRequest.onerror] ${extractErrorMsg(openCursorRequest.error)} (E: caefdda2bb95f92e9fb8d89ee412b524)`);\n reject(openCursorRequest.error);\n };\n\n openCursorRequest.onsuccess = () => {\n try {\n let rmCount = 0;\n // does it matter if the path is a dir vs. a file?\n const cursor = openCursorRequest.result;\n if (cursor) {\n if (cursor.key.toString().startsWith(pathToRm)) {\n const deleteRequest = cursor.delete();\n rmCount++;\n\n deleteRequest.onerror = () => {\n debugger; // error\n console.error(`${lc}[deleteRequest.onerror] ${extractErrorMsg(deleteRequest.error)} (E: abc031c53e5387322cd8909b3ada9b24)`);\n reject(deleteRequest.error);\n };\n cursor.continue();\n } else {\n // No more keys starting with dirPath, we can stop\n if (logalot) { console.log(`${lc} rmCount: ${rmCount} (I: e4bc613a5514c0942484b79267e16724)`); }\n resolve();\n }\n } else {\n if (logalot) { console.log(`${lc} cursor is falsy, so either we have no more records or had no records to begin with. (I: 9ff3aec6274416501a7baf6dcc5f2624)`); }\n resolve();\n }\n } catch (error) {\n console.error(`${lc}[openCursorRequest.onsuccess] ${extractErrorMsg(error)}`);\n reject(error);\n }\n };\n };\n } catch (error) {\n debugger; // error storageRmDir\n console.error(`${lc} ${extractErrorMsg(error)}`);\n reject(error);\n }\n }).finally(() => {\n if (db) {\n if (logalot) { console.log(`${lc} closing db ${dbName}... (I: 39b4ba83de4bdfd541e3384ebab27425)`); }\n db.close();\n if (logalot) { console.log(`${lc} closing db ${dbName} complete. (I: e4015b9436c4b2bc0ccf0e11e2037925)`); }\n }\n if (logalot) { console.log(`${lc} complete.`); }\n logalot = logalotInitDebug;\n });\n}\n\n/**\n * helper function equivalent to readdir in our filesystem space\n */\nexport async function storageReaddir({\n dbName,\n storeName,\n dirPath,\n withFileTypes = false,\n}: {\n dbName: string;\n storeName: string;\n dirPath: string;\n withFileTypes?: boolean;\n}): Promise<string[] | Dirent[]> {\n const lc = `[${storageReaddir.name}]`;\n /** db variable outside try block for finally access in order to close it. */\n let db: IDBDatabase | undefined = undefined;\n try {\n const prom = new Promise<string[] | Dirent[]>((resolve, reject) => {\n const openDBRequest = indexedDB.open(dbName);\n\n openDBRequest.onerror = () => {\n debugger; // error\n // if (openDBRequest.result) { // Only close if a DB object was obtained\n // (openDBRequest.result as IDBDatabase).close();\n // }\n reject(openDBRequest.error);\n };\n\n openDBRequest.onsuccess = () => {\n db = openDBRequest.result;\n const transaction = db.transaction(storeName, \"readonly\");\n const objectStore = transaction.objectStore(storeName);\n\n const normalizedDirPath = dirPath.endsWith(\"/\") ? dirPath : dirPath + \"/\";\n const range = IDBKeyRange.lowerBound(normalizedDirPath);\n const openCursorRequest = objectStore.openCursor(range);\n const entries: Set<string> = new Set();\n const dirents: Dirent[] = [];\n\n openCursorRequest.onerror = () => {\n debugger; // error\n console.error(`${lc}[openCursorRequest.onerror] ${extractErrorMsg(openCursorRequest.error)}`);\n reject(openCursorRequest.error);\n };\n\n // cursor.continue() repeatedly calls this handler ick\n openCursorRequest.onsuccess = () => {\n try {\n const cursor = openCursorRequest.result;\n if (cursor) {\n const key = cursor.key.toString();\n if (key.startsWith(normalizedDirPath) && key !== normalizedDirPath) {\n const relativePath = key.substring(normalizedDirPath.length);\n const childSegment = relativePath.split(\"/\")[0];\n if (withFileTypes) {\n // Determine if it's a file or directory\n const isDirectory = relativePath.substring(childSegment.length).startsWith(\"/\");\n dirents.push({\n name: childSegment,\n isDirectory: () => isDirectory,\n isFile: () => !isDirectory,\n isBlockDevice: () => false,\n isCharacterDevice: () => false,\n isSymbolicLink: () => false,\n isFIFO: () => false,\n isSocket: () => false,\n });\n } else {\n entries.add(childSegment);\n }\n cursor.continue();\n } else if (!key.startsWith(normalizedDirPath)) {\n resolve(withFileTypes ? dirents : Array.from(entries));\n } else {\n cursor.continue();\n }\n } else {\n resolve(withFileTypes ? dirents : Array.from(entries));\n }\n } catch (error) {\n console.error(`${lc}[openCursorRequest.onsuccess] ${extractErrorMsg(error)}`);\n reject(error);\n }\n };\n };\n });\n\n const result = await prom;\n\n return result;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (db) {\n if (logalot) { console.log(`${lc} closing db ${dbName}... (I: 39b4ba83de4bdfd541e3384ebab27425)`); }\n // for some reason, typescript incorrectly thinks db is type\n // \"never\", so this any cast is necessary\n (db as any).close();\n if (logalot) { console.log(`${lc} closing db ${dbName} complete. (I: e4015b9436c4b2bc0ccf0e11e2037925)`); }\n }\n }\n}\n", "/**\n * @module helpers.web\n *\n * Web-specific helper functions for space-gib.\n */\n\nimport { extractErrorMsg } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { storageGet } from \"@ibgib/web-gib/dist/storage/storage-helpers.web.mjs\";\nimport { initAppStorage } from \"@ibgib/web-gib/dist/helpers.web.mjs\";\nimport { getGlobalMetaspace_waitIfNeeded } from \"@ibgib/web-gib/dist/helpers.mjs\";\nimport { IbGibDynamicComponentMetaCtorOpts } from \"@ibgib/web-gib/dist/ui/component/component-types.mjs\";\nimport { IbGibGlobalThisInfo } from \"@ibgib/web-gib/dist/types.mjs\";\nimport { delay } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\n\nimport { GLOBAL_LOG_A_LOT } from \"./constants.mjs\";\nimport { AUTO_GENERATED_VERSION } from \"./AUTO-GENERATED-version.mjs\";\nimport {\n IbGibAmbientContextConfig,\n IbGibGlobalThis_SpaceGib,\n IbGibGlobalThis_Common,\n} from \"./types.mjs\";\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n// ---------------------------------------------------------------------------\n// Storage initialization\n// ---------------------------------------------------------------------------\n\nexport async function initIbGibStorage(config: IbGibAmbientContextConfig): Promise<void> {\n const lc = `[${initIbGibStorage.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 1905af1827a34ca8a5507fe0c5085b01)`); }\n await initAppStorage({\n infos: [\n {\n dbName: config.dbName,\n storeNames: [config.storeName, ...(config.additionalStoreNames ?? [])],\n },\n ],\n });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n// ---------------------------------------------------------------------------\n// globalThis initialization\n// ---------------------------------------------------------------------------\n\nexport function initIbGibGlobalThis(config: IbGibAmbientContextConfig): void {\n const lc = `[${initIbGibGlobalThis.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 7be20d161bb14a498c44a42d3193bec1)`); }\n\n if (!(globalThis as any).ibgib) {\n (globalThis as any).ibgib = {\n dbName_hack: config.dbName,\n apiKeyName_hack: config.apiKeyName,\n storeName_hack: config.storeName,\n } satisfies IbGibGlobalThisInfo;\n }\n\n if (!(globalThis as any).ibgib.spaceGib) {\n (globalThis as any).ibgib.spaceGib = {\n version: AUTO_GENERATED_VERSION,\n spaceShim: {},\n fnDefaultGetAPIKey: async () => {\n const apiKey = await storageGet({\n dbName: config.dbName,\n storeName: config.storeName,\n key: config.apiKeyName,\n });\n return apiKey ?? '';\n },\n dbName_hack: config.dbName,\n apiKeyName_hack: config.apiKeyName,\n storeName_hack: config.storeName,\n } satisfies IbGibGlobalThis_SpaceGib;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n// ---------------------------------------------------------------------------\n// GlobalThis accessors\n// ---------------------------------------------------------------------------\n\nexport function getIbGibGlobalThis_SpaceGib(\n config?: IbGibAmbientContextConfig\n): IbGibGlobalThis_SpaceGib {\n if (!(globalThis as any).ibgib?.spaceGib) {\n if (!config) {\n throw new Error(`Global context not initialized and config not provided.`);\n }\n initIbGibGlobalThis(config);\n }\n return (globalThis as any).ibgib.spaceGib as IbGibGlobalThis_SpaceGib;\n}\n\nexport function getIbGibGlobalThis_Common(): IbGibGlobalThis_Common {\n const g = (globalThis as any).ibgib?.spaceGib;\n if (!g) {\n throw new Error(`(UNEXPECTED) globalThis.ibgib.spaceGib not initialized.`);\n }\n return g as IbGibGlobalThis_Common;\n}\n\n// ---------------------------------------------------------------------------\n// API key helper\n// ---------------------------------------------------------------------------\n\nexport function getDefaultFnGetAPIKey(): () => Promise<string> {\n return async () => {\n const gb = getIbGibGlobalThis_SpaceGib();\n return (await storageGet({\n dbName: gb.dbName_hack,\n storeName: gb.storeName_hack,\n key: gb.apiKeyName_hack,\n })) ?? '';\n };\n}\n\n// ---------------------------------------------------------------------------\n// Dynamic bootstrap loading\n// ---------------------------------------------------------------------------\n\nexport async function dynamicallyLoadBootstrapScript(path: string): Promise<void> {\n const lc = `[${dynamicallyLoadBootstrapScript.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 3123b18eb29b480bad056a9a029b9ad4)`); }\n const module = await import(path);\n await module.bootstrapSpaceGibApp();\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component constructor args helper\n// ---------------------------------------------------------------------------\n\nexport function getComponentCtorArg(): IbGibDynamicComponentMetaCtorOpts {\n const fnGetMetaspace = async () => getGlobalMetaspace_waitIfNeeded();\n\n const bootstrapPromiseWrapper = new Promise<void>(async (resolve, reject) => {\n try {\n let maxTries = 100_000;\n let counter = 0;\n let bootstrapPromise: Promise<void> | undefined;\n do {\n bootstrapPromise =\n getIbGibGlobalThis_SpaceGib()?.bootstrapPromise;\n counter++;\n if (counter > maxTries) { break; }\n await delay(10);\n } while (bootstrapPromise === undefined);\n if (!bootstrapPromise) {\n throw new Error(`Timed out waiting for bootstrapPromise. (E: ceb3ba5261994476900e4a623c0e9d10)`);\n }\n await bootstrapPromise;\n resolve();\n } catch (error) {\n reject(error);\n }\n });\n\n return { fnGetMetaspace, bootstrapPromise: bootstrapPromiseWrapper };\n}\n", "import { HashAlgorithm } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { IbGibAddr } from \"@ibgib/ts-gib/dist/types.mjs\";\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\n\nimport { KEYSTONE_ATOM } from \"./keystone-constants.mjs\";\nimport type { KeystoneVerb } from \"./keystone-constants.mjs\";\n\n// #region KeystoneChallengeType\nexport const KEYSTONE_CHALLENGE_TYPE_HASH_REVEAL_V1 = 'hash-reveal-v1';\n/**\n * The discriminator for the mechanism.\n * 'hash-reveal-v1': Standard Hash chain (Sigma-like).\n */\nexport type KeystoneChallengeType =\n | typeof KEYSTONE_CHALLENGE_TYPE_HASH_REVEAL_V1\n // | 'decrypt-v1' // Future\n // | 'pow-v1'; // Future\n ;\nexport const KeystoneChallengeType = {\n hash_reveal_v1: KEYSTONE_CHALLENGE_TYPE_HASH_REVEAL_V1,\n} satisfies { [key: string]: KeystoneChallengeType };\nexport const KEYSTONE_CHALLENGE_TYPE_VALID_VALUES = Object.values(KeystoneChallengeType);\nexport function isValidKeystoneChallengeType(x: any): x is KeystoneChallengeType {\n return typeof x === 'string' && KEYSTONE_CHALLENGE_TYPE_VALID_VALUES.includes(x as any);\n}\n// #endregion KeystoneChallengeType\n\n// ===========================================================================\n// CONFIGURATION\n// ===========================================================================\n\n// #region KeystoneReplenishStrategy\n/**\n * @see {@link KeystoneReplenishStrategy.topUp}\n */\nexport const KEYSTONE_REPLENISH_STRATEGY_TOP_UP = 'top-up';\n/**\n * @see {@link KeystoneReplenishStrategy.replaceAll}\n */\nexport const KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL = 'replace-all';\n/**\n * @see {@link KeystoneReplenishStrategy.consume}\n */\nexport const KEYSTONE_REPLENISH_STRATEGY_CONSUME = 'consume';\n/**\n * @see {@link KeystoneReplenishStrategy.deleteAll}\n */\nexport const KEYSTONE_REPLENISH_STRATEGY_DELETE_ALL = 'delete-all';\nexport type KeystoneReplenishStrategy =\n | typeof KEYSTONE_REPLENISH_STRATEGY_TOP_UP\n | typeof KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL\n | typeof KEYSTONE_REPLENISH_STRATEGY_CONSUME\n | typeof KEYSTONE_REPLENISH_STRATEGY_DELETE_ALL\n ;\n/**\n * @see {@link KeystonePoolBehavior.replenish}\n */\nexport const KeystoneReplenishStrategy = {\n /**\n * replaces each used challenge, \"topping up\" the pool to the pool's size\n */\n topUp: KEYSTONE_REPLENISH_STRATEGY_TOP_UP,\n /**\n * replaces the entire pool with the new challenges\n */\n replaceAll: KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL,\n /**\n * do not replenish, only consume\n *\n * ## intent\n * adding this for revocation, though we have added deleteAll for this now.\n * Leaving it in.\n */\n consume: KEYSTONE_REPLENISH_STRATEGY_CONSUME,\n /**\n * Deletes ALL challenges in the pool, regardless of how many were used.\n * The \"Nuclear Option\" for revocation.\n */\n deleteAll: KEYSTONE_REPLENISH_STRATEGY_DELETE_ALL,\n} satisfies { [key: string]: KeystoneReplenishStrategy };\nexport const KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES = Object.values(KeystoneReplenishStrategy);\nexport function isKeystoneReplenishStrategy(x: any): x is KeystoneReplenishStrategy {\n return typeof x === 'string' && KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES.includes(x as any);\n}\n// #endregion KeystoneReplenishStrategy\n\nexport interface KeystonePoolBehavior {\n /**\n * Target number of challenges to maintain in the pool.\n */\n size: number;\n\n /**\n * How do we fill the void left by consumed challenges?\n *\n * @see {@link KeystoneReplenishStrategy} individual members for information\n * on each one.\n */\n replenish: KeystoneReplenishStrategy;\n\n /**\n * Minimum number of challenges to consume from the \"front\" (oldest) of the pool.\n * Mitigates sequence prediction attacks if high, allows strictly ordered audit if used alone.\n */\n selectSequentially: number;\n\n /**\n * Minimum number of challenges to consume randomly from the remainder.\n * Mitigates pre-computation attacks on the sequence.\n */\n selectRandomly: number;\n\n /**\n * Number of hex characters from the Target's Gib to match.\n * @default 0\n */\n targetBindingChars: number;\n}\n\nexport interface KeystonePoolConfigBase {\n /**\n * The ID of the pool this config belongs to.\n */\n id: string;\n\n type: KeystoneChallengeType;\n /**\n * Unique salt for this pool's derivation path from the Master Secret.\n */\n salt: string;\n behavior: KeystonePoolBehavior;\n /**\n * The list of Verbs (primitive ibGib addresses) this pool is authorized to sign.\n * e.g. [\"revoke^gib\", \"admin^gib\"]\n *\n * If undefined or empty, this pool is considered a \"General/Default\" pool\n * and can sign any verb NOT explicitly claimed by another pool (implementation detail of selection)\n * or simply any verb at all (permissive).\n *\n * For V1 Security: If this is set, Validation MUST enforce it.\n */\n allowedVerbs: string[];\n}\n\nexport interface KeystonePoolConfig_HashV1 extends KeystonePoolConfigBase {\n type: typeof KeystoneChallengeType.hash_reveal_v1;\n algo: HashAlgorithm;\n rounds: number;\n}\n\nexport type KeystonePoolConfig = KeystonePoolConfig_HashV1;\n\n// ===========================================================================\n// CHALLENGES (Public Puzzles)\n// ===========================================================================\n\nexport interface KeystoneChallengeBase {\n type: KeystoneChallengeType;\n}\n\nexport interface KeystoneChallenge_HashV1 extends KeystoneChallengeBase {\n id: string;\n type: typeof KeystoneChallengeType.hash_reveal_v1;\n /**\n * The hash that must be matched by the solution.\n */\n hash: string;\n}\n\nexport type KeystoneChallenge = KeystoneChallenge_HashV1;\n\n// ===========================================================================\n// SOLUTIONS (Private Answers revealed in Proofs)\n// ===========================================================================\n\nexport interface KeystoneSolutionBase {\n type: KeystoneChallengeType;\n /**\n * The ID of the pool this solution comes from.\n */\n poolId: string;\n /**\n * The ID of the specific challenge being solved.\n */\n challengeId: string;\n}\n\nexport interface KeystoneSolution_HashV1 extends KeystoneSolutionBase {\n type: 'hash-reveal-v1';\n /**\n * The Pre-image value.\n */\n value: string;\n}\n\nexport type KeystoneSolution = KeystoneSolution_HashV1;\n\n// ===========================================================================\n// HIGH-LEVEL STRUCTURES\n// ===========================================================================\n\n/**\n * A container for a set of challenges.\n */\nexport interface KeystoneChallengePool {\n /**\n * Unique ID (e.g. \"default\", \"admin\").\n */\n id: string;\n\n /**\n * Parameterization of this pool.\n *\n * Signing and validating this pool must observe this config.\n */\n config: KeystonePoolConfig;\n\n /**\n * Default claim values for this pool.\n * Useful for \"verb-stones\".\n */\n defaultClaim?: Partial<KeystoneClaim>;\n\n /**\n * The currently active challenges.\n * Key: The unique Challenge ID (e.g. \"poolSalt_0\").\n */\n challenges: { [challengeId: string]: KeystoneChallenge };\n\n /**\n * Explicit Buckets for Target Binding.\n * Key: Hex Character ('0'-'f').\n * Value: Array of Challenge IDs that satisfy this bucket.\n * Note: A single ID may appear in multiple buckets (Coverage Strategy).\n */\n bindingMap: { [hexChar: string]: string[] };\n\n /**\n * If true, this pool's secrets are NOT derived from the Keystone's\n * primary Master Secret. They are held by an external entity.\n *\n * ## intent\n *\n * The driving use case for this is signing in with a server \"super node\"\n * and giving that node the ability to sign on behalf of the user. This is a\n * common pattern in SSO-type workflows.\n */\n isForeign?: boolean;\n\n /**\n * Arbitrary metadata for the wallet/user to identify the pool.\n * e.g. { delegate: \"PrimaryServer\", purpose: \"SSO\" }\n *\n * ## intent\n *\n * The driving use case for this is signing in with a server \"super node\"\n * and giving that node the ability to sign on behalf of the user. This is a\n * common pattern in SSO-type workflows.\n */\n metadata?: any;\n}\n\n/**\n * Describes the specific privilege that the evolution of the keystone\n * authorizes.\n */\nexport interface KeystoneClaim {\n /**\n * what action/ability does the claim make?\n *\n * @see {@link KeystoneVerb} and all of its members for just a list of some\n * common verbs. But really, this can be any string.\n */\n verb: string;\n /**\n * What specific ibgib does this claim relate to?\n *\n * For example, if we are signing a keystone to witness some specific ibgib\n * itself, similar to the most conventional use of digital signatures, then\n * this will be the address of that ibgib.\n */\n target: IbGibAddr;\n /**\n * What limitations are narrowed down to beyond just target + verb?\n */\n scope?: string;\n}\n\n/**\n * Authorization Proof.\n */\nexport interface KeystoneProof {\n id?: string;\n\n /**\n * The claim being made.\n */\n claim: Partial<KeystoneClaim>;\n\n /**\n * The solutions required to validate this claim.\n */\n solutions: KeystoneSolution[];\n\n /**\n * The list of specific Challenge IDs that were mandatorily requested\n * by the verifier/context during the signing process.\n * Essential for deterministic validation.\n */\n requiredChallengeIds?: string[];\n}\n\n/**\n * Revocation Context.\n */\nexport interface KeystoneRevocationInfo {\n reason: string;\n proof: KeystoneProof;\n}\n\n// ===========================================================================\n// TOP LEVEL IBGIB DATA\n// ===========================================================================\n\nexport interface KeystoneIb_V1 {\n atom: typeof KEYSTONE_ATOM;\n}\n\nexport interface KeystoneData_V1 extends IbGibData_V1 {\n /**\n * The pools containing the FUTURE challenges.\n * (Always topped up in V1 implementation).\n */\n challengePools: KeystoneChallengePool[];\n\n /**\n * The proofs authorizing THIS frame's evolution.\n */\n proofs: KeystoneProof[];\n\n /**\n * If present, this Keystone is dead.\n */\n revocationInfo?: KeystoneRevocationInfo;\n\n /**\n * Ephemeral details specific to this frame's creation context.\n * Meant to be observed on this frame, but NOT automatically carried forward\n * to the next frame's data during evolution.\n */\n frameDetails?: any;\n\n /**\n * Aggregated state of the Keystone identity up to this frame.\n * Acts as a snapshot to avoid walking the entire timeline.\n */\n checkpointDetails?: any;\n}\n\nexport interface KeystoneRel8ns_V1 extends IbGibRel8ns_V1 {\n // Standard ibGib relations (ancestor, past, etc.)\n // Specific hard-links for composite keystones go here later.\n}\n\nexport interface KeystoneIbGib_V1 extends IbGib_V1<KeystoneData_V1, KeystoneRel8ns_V1> {\n data: KeystoneData_V1;\n rel8ns: KeystoneRel8ns_V1;\n}\n\nexport interface DeterministicResult {\n /**\n * The Set of IDs that MUST be present in the solution.\n * Includes Alice's Demands + Target Binding Matches + FIFO.\n */\n mandatoryIds: Set<string>;\n\n /**\n * The IDs remaining in the pool that are valid candidates for\n * the Random/Stochastic step.\n */\n availableIds: string[];\n}\n", "import {\n KeystonePoolConfigBase,\n KeystoneChallengeBase,\n KeystoneSolutionBase\n} from '../keystone-types.mjs';\n\n/**\n * Abstract base class for all Keystone Challenge Strategies.\n *\n * @template TConfig The specific configuration interface (e.g. HashV1).\n * @template TChallenge The specific public challenge interface.\n * @template TSolution The specific private solution interface.\n */\nexport abstract class KeystoneStrategy<\n TConfig extends KeystonePoolConfigBase,\n TChallenge extends KeystoneChallengeBase,\n TSolution extends KeystoneSolutionBase\n> {\n constructor(protected config: TConfig) {}\n\n /**\n * Derives the secret specific to this pool from the master keystone secret.\n * This isolates the pool so the master secret is never used directly\n * in challenge generation.\n */\n abstract derivePoolSecret({\n masterSecret\n }: {\n masterSecret: string\n }): Promise<string>;\n\n /**\n * Generates the private solution (Pre-image) for a specific challenge ID.\n *\n * @returns The concrete solution object (not just the value string).\n */\n abstract generateSolution({\n poolSecret,\n poolId,\n challengeId,\n }: {\n poolSecret: string;\n poolId: string;\n challengeId: string;\n }): Promise<TSolution>;\n\n /**\n * Generates the public challenge from a given solution.\n * Used when creating the pool (Top Up) or verifying a solution.\n */\n abstract generateChallenge({\n solution,\n }: {\n solution: TSolution;\n }): Promise<TChallenge>;\n\n /**\n * Validates that a given solution mathematically solves the given challenge.\n *\n * @returns true if valid, false otherwise.\n */\n abstract validateSolution({\n solution,\n challenge,\n }: {\n solution: TSolution;\n challenge: TChallenge;\n }): Promise<boolean>;\n}\n\nexport type KeystoneStrategyAny = KeystoneStrategy<any,any,any>;\n", "/**\r\n * KDF Strategy Constants\r\n *\r\n * Defines available key derivation function strategies.\r\n */\r\n\r\n// #region KdfStrategy\r\nexport const KDF_STRATEGY_RECURSIVE_SALT_WRAP = 'recursive-salt-wrap';\r\nexport type KdfStrategy =\r\n | typeof KDF_STRATEGY_RECURSIVE_SALT_WRAP\r\n ;\r\n\r\n/**\r\n * Available KDF strategies for deriving keys from master secrets.\r\n *\r\n * - `recursive-salt-wrap`: Hash(salt + current + salt) ^ rounds\r\n * Used by KeystoneStrategy_HashRevealV1 for pool secret derivation\r\n */\r\nexport const KdfStrategy = {\r\n /**\r\n * Recursive salt wrap strategy: Hash(salt + current + salt) ^ rounds\r\n *\r\n * This is the primary strategy used by keystones for deriving pool secrets\r\n * from master secrets with configurable rounds for key stretching.\r\n */\r\n recursive_salt_wrap: KDF_STRATEGY_RECURSIVE_SALT_WRAP,\r\n} satisfies { [key: string]: KdfStrategy };\r\n\r\nexport const KDF_STRATEGY_VALID_VALUES = Object.values(KdfStrategy);\r\n\r\nexport function isValidKdfStrategy(strategy: string): strategy is KdfStrategy {\r\n return KDF_STRATEGY_VALID_VALUES.includes(strategy as KdfStrategy);\r\n}\r\n// #endregion KdfStrategy\r\n", "import { extractErrorMsg, hash, HashAlgorithm } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\r\n\r\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\r\nimport { KDF_STRATEGY_RECURSIVE_SALT_WRAP, KDF_STRATEGY_VALID_VALUES, KdfStrategy } from './kdf-constants.mjs';\r\nimport { DeriveKeyParams, KdfOptions_RecursiveSaltWrap } from './kdf-types.mjs';\r\n\r\nconst logalot = GLOBAL_LOG_A_LOT;\r\n\r\n/**\r\n * Derive a key from a master secret using the specified KDF strategy\r\n *\r\n * This is the main dispatch function for all KDF operations. It routes to the\r\n * appropriate strategy implementation based on `kdfOpts.strategy`.\r\n *\r\n * @param params - Derivation parameters including master secret and KDF options\r\n * @returns Derived key\r\n *\r\n * @example\r\n * ```typescript\r\n * const derivedKey = await deriveKey({\r\n * masterSecret: 'my-strong-password',\r\n * kdfOpts: {\r\n * strategy: KdfStrategy.recursiveSaltWrap,\r\n * salt: 'pool-identifier',\r\n * rounds: 10000,\r\n * algorithm: 'SHA-256'\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport async function deriveKey({\r\n masterSecret,\r\n kdfOpts\r\n}: DeriveKeyParams): Promise<string> {\r\n const lc = `[${deriveKey.name}]`;\r\n try {\r\n if (logalot) { console.log(`${lc} starting... (I: 268e87ec311874ee6822bf459c5a5426)`); }\r\n\r\n const strategy = kdfOpts.strategy;\r\n\r\n switch (strategy) {\r\n case KdfStrategy.recursive_salt_wrap:\r\n return await kdf_recursiveSaltWrap({\r\n masterSecret,\r\n salt: kdfOpts.salt,\r\n rounds: kdfOpts.rounds,\r\n algorithm: kdfOpts.algorithm\r\n });\r\n default:\r\n throw new Error(`Unknown KDF strategy: ${strategy}. valid values: ${KDF_STRATEGY_VALID_VALUES.join(', ')} (E: c81258e9d9481eb0f88385a825193226)`);\r\n }\r\n\r\n } catch (error) {\r\n console.error(`${lc} ${extractErrorMsg(error)}`);\r\n throw error;\r\n } finally {\r\n if (logalot) { console.log(`${lc} complete.`); }\r\n }\r\n}\r\n\r\n/**\r\n * Recursive Salt Wrap KDF Strategy\r\n *\r\n * Derives a key by recursively applying: Hash(salt + current + salt) for N rounds\r\n *\r\n * This is the strategy used by KeystoneStrategy_HashRevealV1 for deriving pool secrets.\r\n *\r\n * @param masterSecret - The initial secret/password to derive from\r\n * @param salt - Salt value to wrap around the secret\r\n * @param rounds - Number of hash iterations (key stretching)\r\n * @param algorithm - Hash algorithm to use (default: SHA-256)\r\n * @returns Derived key\r\n */\r\nexport async function kdf_recursiveSaltWrap({\r\n masterSecret,\r\n salt,\r\n rounds,\r\n algorithm = HashAlgorithm.sha_256,\r\n}: {\r\n masterSecret: string;\r\n salt: string;\r\n rounds: number;\r\n algorithm?: HashAlgorithm;\r\n}): Promise<string> {\r\n const lc = `[${kdf_recursiveSaltWrap.name}]`;\r\n try {\r\n if (logalot) { console.log(`${lc} starting... (I: 850868e50aba82ff28c77da8169e4c26)`); }\r\n\r\n let current = masterSecret;\r\n\r\n for (let i = 0; i < rounds; i++) {\r\n current = await hash({\r\n s: `${salt}${current}${salt}`,\r\n algorithm\r\n });\r\n }\r\n\r\n return current;\r\n } catch (error) {\r\n console.error(`${lc} ${extractErrorMsg(error)}`);\r\n throw error;\r\n } finally {\r\n if (logalot) { console.log(`${lc} complete.`); }\r\n }\r\n}\r\n", "import { hash } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { KeystoneStrategy } from '../keystone-strategy.mjs';\nimport {\n KeystonePoolConfig_HashV1, KeystoneChallenge_HashV1, KeystoneSolution_HashV1\n} from '../../keystone-types.mjs';\nimport { kdf_recursiveSaltWrap } from '../../kdf/kdf-helpers.mjs';\n\n/**\n * The concrete implementation of the \"Salted Wrap\" Hash Reveal strategy.\n */\nexport class KeystoneStrategy_HashRevealV1 extends KeystoneStrategy<\n KeystonePoolConfig_HashV1,\n KeystoneChallenge_HashV1,\n KeystoneSolution_HashV1\n> {\n\n /**\n * Derives Pool Secret = Hash(PoolSalt + MasterSecret + PoolSalt) ^ Rounds\n */\n override async derivePoolSecret({\n masterSecret\n }: {\n masterSecret: string\n }): Promise<string> {\n const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.derivePoolSecret.name}]`;\n try {\n const { salt, rounds, algo } = this.config;\n\n return await kdf_recursiveSaltWrap({\n masterSecret,\n salt,\n rounds,\n algorithm: algo\n });\n } catch (error) {\n console.error(`${lc} Error deriving pool secret: ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Solution Value = Hash(IndexSalt + PoolSecret + IndexSalt) ^ Rounds\n */\n override async generateSolution({\n poolSecret,\n poolId,\n challengeId,\n }: {\n poolSecret: string;\n poolId: string;\n challengeId: string;\n }): Promise<KeystoneSolution_HashV1> {\n const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.generateSolution.name}]`;\n try {\n const { rounds, algo } = this.config;\n\n // The Index Salt is the unique identifier for this slot\n const indexSalt = challengeId;\n\n let current = poolSecret;\n for (let i = 0; i < rounds; i++) {\n current = await hash({\n s: `${indexSalt}${current}${indexSalt}`,\n algorithm: algo\n });\n }\n\n return {\n type: 'hash-reveal-v1',\n poolId,\n challengeId,\n value: current\n };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Challenge Hash = Hash(IndexSalt + SolutionValue + IndexSalt) ^ Rounds\n */\n override async generateChallenge({\n solution,\n }: {\n solution: KeystoneSolution_HashV1;\n }): Promise<KeystoneChallenge_HashV1> {\n const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.generateChallenge.name}]`;\n try {\n const { rounds, algo } = this.config;\n const { challengeId, value } = solution;\n const indexSalt = challengeId;\n\n let current = value;\n for (let i = 0; i < rounds; i++) {\n current = await hash({\n s: `${indexSalt}${current}${indexSalt}`,\n algorithm: algo\n });\n }\n\n return {\n id: challengeId,\n type: 'hash-reveal-v1',\n hash: current\n };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Re-generates the challenge from the candidate solution and compares.\n */\n override async validateSolution({\n solution,\n challenge,\n }: {\n solution: KeystoneSolution_HashV1;\n challenge: KeystoneChallenge_HashV1;\n }): Promise<boolean> {\n const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.validateSolution.name}]`;\n try {\n // 1. Check Type Compatibility\n if (solution.type !== 'hash-reveal-v1' || challenge.type !== 'hash-reveal-v1') {\n console.warn(`${lc} Mismatched types provided.`);\n return false;\n }\n\n // 2. Generate the expected challenge hash from the solution provided\n const calculatedChallenge = await this.generateChallenge({ solution });\n\n // 3. Compare\n return calculatedChallenge.hash === challenge.hash;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return false; // Fail closed\n }\n }\n}\n", "import {\n KeystonePoolConfig\n} from '../keystone-types.mjs';\nimport { KeystoneStrategyAny } from './keystone-strategy.mjs';\nimport { KeystoneStrategy_HashRevealV1 } from './hash-reveal-v1/hash-reveal-v1.mjs';\n\nexport class KeystoneStrategyFactory {\n\n /**\n * Instantiates the appropriate concrete KeystoneStrategy based on the\n * provided configuration type.\n *\n * @param config The configuration object for the pool (contains 'type').\n * @returns An instance of the specific strategy class.\n */\n static create({\n config,\n }: {\n config: KeystonePoolConfig,\n }): KeystoneStrategyAny {\n const lc = `[${KeystoneStrategyFactory.name}.create]`;\n try {\n switch (config.type) {\n case 'hash-reveal-v1':\n return new KeystoneStrategy_HashRevealV1(config);\n\n default:\n throw new Error(`Unknown strategy type: ${(config as any).type} (E: 4e3c2f7129a241c1b687555e678c1065)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n}\n", "import { HashAlgorithm } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { KeystoneReplenishStrategy } from \"./keystone-types.mjs\";\n\nexport const KEYSTONE_ATOM = \"keystone\";\nexport const KEYSTONE_POOL_ID_REGEXP = /^\\w[\\w\\-.]*$/;\n/**\n * arbitrary 64 limit? only letters characters good\n */\nexport const KEYSTONE_SALT_REGEXP = /^[a-zA-Z0-9]{1,64}$/;\n/**\n * arbitrary right now. don't want an easy DoS. this may still be too high.\n */\nexport const KEYSTONE_HASH_MAX_ROUNDS = 1_000;\n\n// #region KeystoneVerb enum\n/**\n * @see {@link KeystoneVerb.REVOKE}\n */\nexport const KEYSTONE_VERB_REVOKE = \"revoke\";\n/**\n * @see {@link KeystoneVerb.MANAGE}\n */\nexport const KEYSTONE_VERB_MANAGE = \"manage\";\n/**\n * @see {@link KeystoneVerb.SIGN}\n */\nexport const KEYSTONE_VERB_SIGN = \"sign\";\nexport type KeystoneVerb =\n | typeof KEYSTONE_VERB_REVOKE\n | typeof KEYSTONE_VERB_MANAGE\n | typeof KEYSTONE_VERB_SIGN;\n\n/**\n * Verbs that describe actions that can be authorized by a Keystone.\n */\nexport const KeystoneVerb = {\n /**\n * The specific ibGib address for the 'revoke' verb.\n * Used in Claims to indicate the Keystone should be considered dead.\n */\n REVOKE: KEYSTONE_VERB_REVOKE,\n /**\n * The meta-verb used to authorize structural changes to the Keystone,\n * specifically adding or removing challenge pools.\n *\n * \"Root access\" to the identity.\n *\n * Basically, this is the verb for the \"admin\" pool.\n *\n * todo: add a separate \"add pool\" verb\n * todo: add a one-time mechanism that limits pool use per verb.\n */\n MANAGE: KEYSTONE_VERB_MANAGE,\n /**\n * This is the least of all privileges that can actually evolve a keystone.\n */\n SIGN: KEYSTONE_VERB_SIGN,\n} satisfies { [key: string]: KeystoneVerb };\nexport const KEYSTONE_VERB_VALID_VALUES = Object.values(KeystoneVerb);\nexport function isKeystoneVerb(value: string): value is KeystoneVerb {\n return KEYSTONE_VERB_VALID_VALUES.includes(value as KeystoneVerb);\n}\n// #endregion KeystoneVerb enum\n\n/**\n * Some standard pool IDs can be conventionally named after their primary verb,\n * but this is not a requirement.\n */\nexport const POOL_ID_REVOKE = KEYSTONE_VERB_REVOKE;\nexport const POOL_ID_MANAGE = KEYSTONE_VERB_MANAGE;\nexport const POOL_ID_DEFAULT = \"default\";\nexport const POOL_ID_DELEGATE = \"delegate\";\n/**\n * **THESE SHOULD ONLY BE USED IN TEMPORARY/SESSION KEYSTONES.**\n * _this is because a receiver could intercept the stone, DoS participants and\n * then take over a stone._\n *\n * transition pools are used as a temporary mechanism to create one-time management pools for delegates to create their own pools.\n */\nexport const POOL_ID_TRANSITION = \"transition\";\n\nexport const KEYSTONE_CONFIG_DEFAULT_SIZE = 200;\nexport const KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL = 2;\nexport const KEYSTONE_CONFIG_DEFAULT_RANDOM = 2;\nexport const KEYSTONE_CONFIG_DEFAULT_BINDING = 5;\nexport const KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY = KeystoneReplenishStrategy.topUp;\nexport const KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM = HashAlgorithm.sha_256;\nexport const KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS = 1;\n\nexport const KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY = 2000;\nexport const KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL_HIGHSECURITY = 5;\nexport const KEYSTONE_CONFIG_DEFAULT_RANDOM_HIGHSECURITY = 5;\nexport const KEYSTONE_CONFIG_DEFAULT_BINDING_HIGHSECURITY = 16;\nexport const KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY_HIGHSECURITY = KeystoneReplenishStrategy.replaceAll;\nexport const KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM_HIGHSECURITY = HashAlgorithm.sha_512;\nexport const KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS_HIGHSECURITY = 10;\n/**\n * the checkpointing mechanism will do a checkpoint every [this number] of\n * keystone frame evolutions.\n */\nexport const KEYSTONE_CHECKPOINT_FREQUENCY = 50;\n", "import { delay, extractErrorMsg, pretty, unique } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGibAddr, TjpIbGibAddr, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbAndGib, getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { validateIbGibAddr } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport {\n GIB, IbGib_V1,\n isPrimitive,\n IBGIB_DELIMITER,\n} from '@ibgib/ts-gib/dist/V1/index.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\nimport { getFromSpace, getLatestAddrs } from '../../witness/space/space-helper.mjs';\nimport { getTimelinesGroupedByTjp, toDto } from './ibgib-helper.mjs';\nimport { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';\nimport { FlatIbGibGraph } from './graph-types.mjs';\n\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Options when getting dependency graph for ibGib(s).\n *\n * Note that this is used both in local and outer space contexts.\n * When you want to default to the local user space in the local context,\n * i.e. in `IbgibsService` atow, pass in `null` for {@link space}.\n */\nexport interface GetGraphOptions {\n /**\n * source ibGib to grab dependencies of.\n *\n * caller can pass in `ibGib` or `ibGibs` or `ibGibAddr` or `ibGibAddrs`.\n */\n ibGib?: IbGib_V1,\n /**\n * source ibGibs to grab dependencies of.\n *\n * caller can pass in `ibGib` or `ibGibs` or `ibGibAddr` or `ibGibAddrs`.\n */\n ibGibs?: IbGib_V1[],\n /**\n * source ibGib address to grab dependencies of.\n *\n * caller can pass in `ibGib` or `ibGibs` or `ibGibAddr` or `ibGibAddrs`.\n */\n ibGibAddr?: IbGibAddr,\n /**\n * source ibGib addresses to grab dependencies of.\n *\n * caller can pass in `ibGib` or `ibGibs` or `ibGibAddr` or `ibGibAddrs`.\n */\n ibGibAddrs?: IbGibAddr[],\n /**\n * If true, for each timeline in each \"frozen\" ibgib graph we will get the\n * latest address in the timeline and recheck rel8d ibgibs for newly\n * added timeline branches.\n *\n * If false, this will only look in the past for each rel8d ibgib.\n *\n * ## notes\n *\n * Say you have a source ibgib with a comment \"child\" (relative to our\n * source ibgib). Now say you add an ibgib to that child comment. The rel8d\n * addr in the source ibgib will still point to the child comment's initial\n * addr - before it was changed by adding its own \"child\" (\"grandchild\" to\n * the source). So if you get a live dependency graph on the parent, it will\n * come across the child's timeline and get the latest for that timeline\n * (and associated ibgibs like the child's dna transforms that add the\n * grandchild). This will include the grandchild. If it's not a live graph,\n * then the parent will only have the child and will exclude the grandchild.\n */\n live?: boolean,\n /**\n * object that will be populated through recursive calls to this function.\n *\n * First caller of this function should not provide this and I'm not atow\n * coding a separate implementation function to ensure this.\n *\n * @see {@link skipAddrs}\n */\n gotten?: { [addr: string]: IbGib_V1 },\n /**\n * used when doing {@link live} dependency graph gets. Same use as\n * {@link gotten}, but with regards to timelines.\n */\n tjpAddrsAlreadyAnalyzed?: TjpIbGibAddr[],\n /**\n * List of ibgib addresses to skip not retrive in the dependency graph.\n *\n * This will also skip any ibgib addresses that would have occurred in the\n * past of these ibgibs, as when skipping an ibgib, you are also skipping\n * its dependencies implicitly as well (unless those others are related via\n * another ibgib that is not skipped of course).\n *\n * ## driving use case\n *\n * We don't want to get ibgibs that we already have, and this is cleaner\n * than pre-populating the `gotten` parameter for double-duty. That property\n * should be strictly used within this call recursively.\n *\n * @see {@link gotten}\n */\n skipAddrs?: IbGibAddr[],\n /**\n * Skip these particular rel8n names.\n *\n * ## driving intent\n *\n * I'm adding this to be able to skip getting dna ibgibs.\n *\n * ## see also\n *\n * @see {@link onlyRel8nNames} for whitelist of rel8n names for traversal\n */\n skipRel8nNames?: string[],\n /**\n * whitelist of rel8nNames to traverse.\n *\n * ## see also\n *\n * @see {@link skipRel8nNames} for a blacklist of rel8n names for traversal\n */\n onlyRel8nNames?: string[],\n /**\n * If not found when getting dependency graph, do we retry? This is the\n * max number of retries.\n */\n maxRetries?: number,\n /**\n * If provided and {@link maxRetries} is non-zero, the next retry will be\n * delayed this amount of time if one or more addrs are not found.\n */\n msBetweenRetries?: number,\n /**\n * Space within which we should be looking for ibGibs.\n *\n * ## NOTE on providing space vs local user space\n *\n * I'm reusing this interface for both generic space function and ibgib service\n * function, which has an implicit default space of the local user space if this\n * is falsy. So just pass in `null` if you are using this with ibgibs service and\n * want it to default to the local user space.\n */\n space: IbGibSpaceAny | null,\n /**\n * If supplied, will make intermittent calls to console.timeLog using this name.\n */\n timeLogName?: string,\n /**\n * When getting the live dependency graph, this is used so we don't\n * duplicate work in recursive calls.\n *\n * IOW, in the first run of{@link getGraphProjection_Live}, we call\n * getLatestAddrs which maps some addrs to the latest addrs in the space. So\n * we now have a reference to the latest and if we need to call the function\n * {@link getGraphProjection_Live} recursively, then we can provide this\n * info to reduce unnecessary computation.\n */\n mapTjpAddrToLatestAddrsInSpace?: { [tjpAddr: string]: IbGibAddr }\n}\n\nexport type GetGraphResult = FlatIbGibGraph;\n\nexport interface GetGraphProjectionOptions extends GetGraphOptions {\n // /**\n // * max depth away from source ibgibs to traverse\n // */\n // depth?: number;\n}\n\nexport interface GetDependencyGraphOptions extends GetGraphProjectionOptions {\n // depth?: undefined;\n}\n\n/**\n *\n * @returns dependency graph, live or non-live depending on {@link GetDependencyGraphOptions}\n *\n * Getting a `live` dependency graph means that we will be looking in the given\n * @see {@link GetDependencyGraphOptions.space} for updates to ibGibs' timelines\n * (those ibGibs that have timelines/tjps). This is more costly computationally\n * in the short-term, but often cheaper in the long-term.\n */\nexport async function getDependencyGraph({\n ibGib, ibGibs, ibGibAddr, ibGibAddrs,\n live,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n}: GetGraphProjectionOptions): Promise<GetGraphResult> {\n const lc = `[${getDependencyGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: c2a4426c22e849611ca0cedabe683a22)`); }\n\n const graph = await getGraphProjection({\n ibGib, ibGibs, ibGibAddr, ibGibAddrs,\n live,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n });\n\n Object.values(graph).filter(ibGib => ibGib.ib.startsWith('comment ')).forEach(ibGib => { console.table(ibGib); });\n if (logalot) {\n console.log(`${lc} graph size: ${Object.keys(graph).length} (I: c6cb5e7e1e2611d35b9006fac6503d22)`);\n const ibs =\n Object.values(graph).filter(ibGib => ibGib.ib.startsWith('comment ') || ibGib.ib.startsWith('pic '))\n .map(ibGib => ibGib.ib);\n unique(ibs).forEach(ib => console.log(ib));\n }\n return graph;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nasync function getGraphProjection_initializeOpts({\n ibGib, ibGibs, ibGibAddr, ibGibAddrs,\n live,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n}: GetDependencyGraphOptions): Promise<GetDependencyGraphOptions> {\n const lc = `[${getGraphProjection_initializeOpts.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: bd6807477f679345df9dddefe0b4e922)`); }\n\n if (!space) { throw new Error(`space required. (E: 9f38166ab70340cb919174f8d26af909)`); }\n if (!ibGib && !ibGibAddr && (ibGibs ?? []).length === 0 && (ibGibAddrs ?? []).length === 0) {\n throw new Error(`either ibGib/s or ibGibAddr/s required. (E: b6d08699651f455697f0d05a41edb039)`);\n }\n\n skipRel8nNames = skipRel8nNames || [];\n // do NOT initialize onlyRel8nNames because we do logic based on falsy value\n skipAddrs = skipAddrs || [];\n gotten = gotten || {};\n tjpAddrsAlreadyAnalyzed = tjpAddrsAlreadyAnalyzed || [];\n\n // convert single args (ibGib, ibGibAddr) into the array args, filtering\n // out primitives that we don't want. The `filter` function creates the\n // copy here, so we won't mutate the incoming arrays. (The ibgibs and\n // addrs themselves are immutable).\n ibGibAddrs = (ibGibAddrs ?? [])\n .filter(x => !isPrimitive({ gib: getIbAndGib({ ibGibAddr: x }).gib })) // no primitives\n .filter(x => !skipAddrs!.includes(x));\n ibGibs =\n (ibGibs ?? [])\n .filter(x => !isPrimitive({ ibGib: x })) // no primitives\n .filter(x => !skipAddrs!.includes(getIbGibAddr({ ibGib: x })));\n // if we're passed in a single ibGib, add it to the ibGibs array because\n // we're going to work off of that.\n if (ibGib &&\n !isPrimitive({ ibGib }) &&\n !ibGibs.some(x => x.gib === ibGib.gib) &&\n !skipAddrs.includes(getIbGibAddr({ ibGib }))\n ) {\n ibGibs.push(ibGib);\n }\n // if we're passed in a single ibGibAddr, add it to the ibGibAddrs array because\n // we're going to work off of that.\n if (ibGibAddr &&\n !isPrimitive({ gib: getIbAndGib({ ibGibAddr }).gib }) &&\n !ibGibAddrs.includes(ibGibAddr) &&\n !skipAddrs.includes(ibGibAddr)\n ) {\n ibGibAddrs.push(ibGibAddr);\n }\n return {\n ibGib, ibGibs, ibGibAddr, ibGibAddrs,\n live,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n };\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nasync function getGraphProjection_getIbGibsInIbGibAddrs({\n ibGibs,\n ibGibAddrs,\n gotten,\n skipAddrs,\n maxRetries, msBetweenRetries,\n timeLogName,\n space,\n}: GetGraphProjectionOptions): Promise<IbGib_V1[]> {\n const lc = `[${getGraphProjection_getIbGibsInIbGibAddrs.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 67b2be37ff24393fff56e229304da122)`); }\n\n /**\n * ibgibs that we'll return\n */\n const resIbGibs: IbGib_V1[] = [];\n ibGibs ??= [];\n ibGibAddrs ??= [];\n skipAddrs ??= [];\n gotten ??= {};\n\n const addrsToGetFromSpace: IbGibAddr[] = [];\n const gottenAddrs: IbGibAddr[] = Object.keys(gotten ?? {}); // compute once in this closure\n const incomingIbGibAddrs = ibGibs.map(x => getIbGibAddr({ ibGib: x }));\n // const noNeedAddrs = [...gottenAddrs, ...incomingIbGibAddrs, ...skipAddrs,];\n for (let i = 0; i < ibGibAddrs.length; i++) {\n const addr = ibGibAddrs[i];\n if (skipAddrs.includes(addr) || incomingIbGibAddrs.includes(addr)) {\n continue;\n } else if (gottenAddrs.includes(addr)) {\n // we've already gotten this addr previously and put it into the\n // gotten object, so we don't need to retrieve it from space\n resIbGibs.push(gotten[addr]);\n } else {\n // if (!noNeedAddrs.includes(ibGibAddrs[i])) {\n addrsToGetFromSpace.push(ibGibAddrs[i]);\n }\n }\n\n if (logalot) { console.log(`${lc}[analyze debugging] addrsToGetFromSpace (${addrsToGetFromSpace.length}):\\n${addrsToGetFromSpace.join('\\n')} (I: b45a2614184b48b694becfd377c789f5)`); }\n\n if (addrsToGetFromSpace.length > 0) {\n // get from space, with retries if applicable\n let addrsToGet = addrsToGetFromSpace.concat();\n let retryCount = 0;\n maxRetries = maxRetries ?? 0;\n while (retryCount <= maxRetries && addrsToGet.length > 0) {\n if (timeLogName && retryCount === 0) { console.timeLog(timeLogName, `${lc} FIRST try starting...`) }\n if (timeLogName && retryCount > 0) { console.timeLog(timeLogName, `${lc} RETRY starting...`) }\n // delay if applicable\n if (retryCount > 0 && msBetweenRetries) {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} delaying ${msBetweenRetries}ms for retry`); }\n if (logalot) { console.log(`${lc} retrying. addrsToGet (${addrsToGet.length}): ${addrsToGet} (I: 8460694cdd5518472680784c3b96a822)`); }\n await delay(msBetweenRetries);\n }\n\n // do the get\n if (timeLogName) { console.timeLog(timeLogName, `${lc} getFromSpace (${addrsToGet?.length}) starting...`); }\n if (!space) { throw new Error(`(UNEXPECTED) space falsy? (E: aa9f657695717034b3581066932d7d23)`); }\n let resGetThese = await getFromSpace({ addrs: addrsToGet, space });\n if (timeLogName) { console.timeLog(timeLogName, `${lc} getFromSpace complete.`); }\n if (resGetThese.success && (resGetThese.ibGibs?.length ?? 0) > 0) {\n resGetThese.ibGibs!.forEach(x => resIbGibs.push(x));\n // resGetThese.ibGibs.forEach(x => ibGibs.push(x));\n const gottenAddrs = resGetThese.ibGibs!.map(x => getIbGibAddr({ ibGib: x }));\n if (gottenAddrs.length === addrsToGet.length) {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} got all.`) }\n // got them all, so we're done\n addrsToGet = [];\n break;\n } else {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} got some.`) }\n // got only some, prune addrsToGet for next retry (if any)\n addrsToGet = addrsToGet.filter(x => !gottenAddrs.includes(x));\n }\n } else {\n // failed, maybe partial maybe completely\n const gottenIbGibs: IbGib_V1[] = (resGetThese.rawResultIbGib as any).ibGibs ?? [];\n if (gottenIbGibs.length > 0) {\n // failed partial\n gottenIbGibs.forEach(x => resIbGibs.push(x));\n // resGetThese.ibGibs.forEach(x => ibGibs.push(x));\n const gottenAddrs = gottenIbGibs.map(x => getIbGibAddr({ ibGib: x }));\n if (timeLogName) { console.timeLog(timeLogName, `${lc} got some.`) }\n // got only some, prune addrsToGet for next retry (if any)\n addrsToGet = addrsToGet.filter(x => !gottenAddrs.includes(x));\n } else {\n // failed completely, addrsToGet stays the same\n if (timeLogName) { console.timeLog(timeLogName, `${lc} failed. addrs: ${addrsToGet?.join(',')}`) }\n }\n }\n retryCount++;\n }\n if (addrsToGet?.length > 0) {\n // console.dir(primaryKeysDebug);\n throw new Error(`unable to retrieve dependency ibgibs from space (ib: ${space?.ib}). addrsToGet: ${addrsToGet.join('\\n')} (E: 8413594b6c1b447988781cf3f3e1729d)`);\n // throw new Error(`unable to retrieve dependency ibgibs from space (ib: ${space?.ib}).\\n\\nThis is often because downloading failed due to the sync space's server getting temporarily overloaded, OR...it sometimes happens when an ibgib doesn't get fully published to the sync space in the first place.\\n\\nYou could retry immediately or later, but if the problem persists, then retry from the publishers end (have the publisher sync again). (E: 8413594b6c1b447988781cf3f3e1729d)`);\n }\n }\n\n return resIbGibs;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function getGraphProjection(opts: GetDependencyGraphOptions): Promise<GetGraphResult> {\n const lc = `[${getGraphProjection.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 70508d7a5c63eae1f22ae851b32b3d22)`); }\n\n if (!opts.ibGib && !opts.ibGibAddr && (opts.ibGibs ?? []).length === 0 && (opts.ibGibAddrs ?? []).length === 0) {\n // no ibgibs/addrs, return empty - don't throw\n return {} as GetGraphResult; /* <<<< returns early */\n }\n\n // ibGib and ibGibAddr get condensed into ibGibs and ibGibAddrs\n let {\n /*ibGib,*/ ibGibs, /*ibGibAddr,*/ ibGibAddrs,\n live,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n } = await getGraphProjection_initializeOpts(opts);\n\n if (timeLogName) { console.timeLog(timeLogName, `${lc} starting...`) }\n\n // retrieve ibgibs listed in incoming ibGibAddrs (if any) and put them\n // in our incoming ibGibs array\n if (ibGibAddrs?.length ?? 0 > 0) {\n const supplementalIbGibs = await getGraphProjection_getIbGibsInIbGibAddrs({\n ibGibs, ibGibAddrs,\n gotten,\n skipAddrs,\n maxRetries, msBetweenRetries,\n timeLogName,\n space,\n });\n ibGibs = ibGibs ?\n [...ibGibs, ...supplementalIbGibs] :\n [...supplementalIbGibs]\n }\n ibGibAddrs = ibGibs!.map(x => getIbGibAddr({ ibGib: x }));\n\n\n // at this point, there are two different strategies for diving deeper,\n // depending on if we are building a `live` graph or not.\n\n let commentIbs = unique(ibGibs!.map(x => x.ib).filter(x => x.startsWith('comment ')));\n if (logalot) { console.log(`${lc}[analyze debugging] ibGibs commentIbs: ${commentIbs.join('\\n')} (I: c89dc951315f746954f9bddbe8941122)`); }\n\n if (live) {\n return getGraphProjection_Live({\n ibGibs, ibGibAddrs,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space, timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n });\n } else {\n return getGraphProjection_NonLive({\n ibGibs, ibGibAddrs,\n gotten, /* tjpAddrsAlreadyAnalyzed not used */\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space, timeLogName,\n });\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n\n/**\n * Get the dependency graph for {@link ibGibAddr} since {@link latestCommonFrameAddr}.\n *\n * if ibGibAddr is A^5 and latestCommonFrameAddr is A^3, then this should\n * get all dependencies in A^5 dependency graph NOT ALREADY IN the A^3\n * graph.\n *\n * NOTE: The {@link live} param is for the delta graph itself. The graph\n * corresponding to {@link latestCommonFrameAddr} is always calculated live ===\n * false.\n */\nexport async function getDeltaDependencyGraph({\n ibGibAddr,\n latestCommonFrameAddr,\n live,\n space,\n}: {\n ibGibAddr: string;\n latestCommonFrameAddr: string;\n live: boolean,\n space: IbGibSpaceAny;\n}): Promise<FlatIbGibGraph> {\n const lc = `[${getDeltaDependencyGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5d225e56dc11e62cd83c5366ea288826)`); }\n\n if (ibGibAddr === latestCommonFrameAddr) {\n console.warn(`${lc} ibGibAddr === latestCommonFrameAddr. So the delta graph is empty. what are we doing here? (W: e0c8287ae6de8152bf36b6c73ca59a26)`);\n return {};\n }\n\n const dependencyGraph_lcf = await getDependencyGraph({\n ibGibAddr: latestCommonFrameAddr,\n live: false, // always get the smaller graph live === false!\n space,\n });\n const dependencyGraph_delta = await getDependencyGraph({\n ibGibAddr,\n live,\n skipAddrs: Object.keys(dependencyGraph_lcf),\n space,\n });\n\n return dependencyGraph_delta;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n *\n * live dependency graph searching requires a timeline-centric approach.\n * for each incoming ibGib, we must first determine if it has a\n * timeline. if it does, then we get the latest in that timeline and\n * get all ibgibs in that lineage only. we do NOT YET go through any\n * rel8d ibgibs that also have timelines\n *\n * what we can do is compile our list of ibGib addrs according to each\n * timeline and then call the nonlive version of the dependency graph.\n * but we must get the latest in the timeline, then get all associated\n * timelines and get the latest of those. Then we can call get\n * dependency graph on the non-live version, passing in all of those\n * latest ibgibs in the timelines (and everything we've gotten in the\n * interim so we don't waste time getting more).\n *\n * @see {@link getGraphProjection}\n * @see {@link getDependencyGraph}\n */\nasync function getGraphProjection_Live({\n ibGibs, ibGibAddrs,\n gotten, tjpAddrsAlreadyAnalyzed,\n mapTjpAddrToLatestAddrsInSpace,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n}: GetGraphProjectionOptions): Promise<GetGraphResult> {\n const lc = `[${getGraphProjection_Live.name}]`;\n try {\n mapTjpAddrToLatestAddrsInSpace = mapTjpAddrToLatestAddrsInSpace ?? {};\n tjpAddrsAlreadyAnalyzed = tjpAddrsAlreadyAnalyzed ?? [];\n\n // ibGibs contains the ones we explicitly are still working on getting\n // projections within, gotten are the ones we have completed. so we want\n // to get all of them together so we have a complete (up to this point)\n // picture of timelines, because we're looking for timelines that we\n // haven't yet analyzed\n let allIbGibsSoFar = { ...gotten };\n (ibGibs ?? []).forEach(x => allIbGibsSoFar[getIbGibAddr({ ibGib: x })] = x);\n const allKnownTimelinesAtThisPoint = getTimelinesGroupedByTjp({\n ibGibs: Object.values(allIbGibsSoFar),\n });\n if (logalot) { console.log(`${lc}[analyze debugging] timeline tjps(${Object.keys(allKnownTimelinesAtThisPoint).length}): ${Object.keys(allKnownTimelinesAtThisPoint)} (I: 509f04ac15ca08c5a3f0777b48934622)`); }\n\n const timelinesNotAnalyzed: { [addr: string]: IbGib_V1[] } = {};\n Object.keys(allKnownTimelinesAtThisPoint).forEach(tjpAddr => {\n if (!tjpAddrsAlreadyAnalyzed!.includes(tjpAddr)) {\n timelinesNotAnalyzed[tjpAddr] = allKnownTimelinesAtThisPoint[tjpAddr];\n }\n });\n if (logalot) { console.log(`${lc}[analyze debugging] timelinesNotAnalyzed: ${pretty(timelinesNotAnalyzed)} (I: a4b67d95fdd6b98d3241c0a7d0a93c22)`); }\n\n const mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed: { [tjpAddr: IbGibAddr]: IbGib_V1 } = {};\n /**\n * Convience mapping back from latest addr already gotten back to the tjp addr.\n * Convenience = not strictly necessary, but makes it easier later.\n */\n const mapLatestAddrAlreadyGottenToTjpAddr: { [latestAddrAlreadyGotten: IbGibAddr]: IbGibAddr } = {};\n\n Object.keys(allKnownTimelinesAtThisPoint)\n .filter(tjpAddr => !tjpAddrsAlreadyAnalyzed!.includes(tjpAddr))\n .forEach(tjpAddr => {\n const timeline = allKnownTimelinesAtThisPoint[tjpAddr];\n // add to the array we'll send below\n const latestIbGibAlreadyGotten = timeline[timeline.length - 1];\n mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed[tjpAddr] = latestIbGibAlreadyGotten;\n // add to mapping back from addr to tjpaddr for convenience below\n const latestAddrAlreadyGotten = getIbGibAddr({ ibGib: latestIbGibAlreadyGotten });\n mapLatestAddrAlreadyGottenToTjpAddr[latestAddrAlreadyGotten] = tjpAddr;\n });\n let countOfTimelinesNotYetGotten =\n Object.keys(mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed).length;\n\n if (countOfTimelinesNotYetGotten > 0) {\n // we have more timelines still to do. get the latest ibGib in each timeline,\n // add it, check for more timelines. But we may have already gotten a latestAddrsMap\n // in a previous call, so account for this.\n\n // query only latest ibgibs that we haven't already gotten AND whose\n // timelines we've not already analyzed, per\n // mapTjpAddrToLatestAddrsInSpace.\n /**\n * build this map of latest addr given -> latest addr in space (per timeline/tjp).\n */\n let latestAddrsMap: { [addr: string]: IbGibAddr | null } = {};\n Object.keys(mapTjpAddrToLatestAddrsInSpace)\n .filter(tjpAddr => !tjpAddrsAlreadyAnalyzed!.includes(tjpAddr))\n .forEach(tjpAddr => {\n const latestIbGibCorrespondingToTjpAddr =\n mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed[tjpAddr];\n if (latestIbGibCorrespondingToTjpAddr) {\n const latestAddrCorrespondingToTjpAddr =\n getIbGibAddr({ ibGib: latestIbGibCorrespondingToTjpAddr });\n latestAddrsMap[latestAddrCorrespondingToTjpAddr] = mapTjpAddrToLatestAddrsInSpace![tjpAddr];\n } else {\n console.error(`${lc} latestIbGibCorrespondingToTjpAddr is falsy`)\n }\n });\n if (logalot) { console.log(`${lc} latestAddrsMap *before* getLatestAddrs: ${pretty(latestAddrsMap)} (I: 427b4bb78595e9e521ecf2c5e5c80722)`); }\n /**\n * these are the ibgibs whose timelines we are aware of but haven't\n * explicitly queried for the latest in the space.\n */\n const ibGibsToQueryLatestAddrs =\n Object.values(mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed);\n\n /**\n * this is the result map of ibgibs whose timelines we are aware of\n * but hadn't explicitly queried for.\n */\n let queriedLatestAddrsMap: { [addr: string]: IbGibAddr | null } = {};\n if (ibGibsToQueryLatestAddrs.length > 0) {\n if (!space) { throw new Error(`(UNEXPECTED) space falsy? (E: 8e878975e3561df9a8dc4c628b0abc23)`); }\n /** This is result with the map of the latest addrs in the space */\n const resLatestAddrsMapInEntireSpace = await getLatestAddrs({\n ibGibs: ibGibsToQueryLatestAddrs,\n space,\n });\n if (!resLatestAddrsMapInEntireSpace?.data?.latestAddrsMap) { throw new Error(`(UNEXPECTED) getLatestAddrs result latestAddrsMap falsy (E: 088caa1fc95fd3b079108ab63ef33422)`); }\n queriedLatestAddrsMap = resLatestAddrsMapInEntireSpace?.data?.latestAddrsMap;\n if (Object.keys(queriedLatestAddrsMap).length !== countOfTimelinesNotYetGotten) {\n // this happens when the space does not have the address, sometimes because of\n // not pushing the most recent changes to the sync space...hmmm\n throw new Error(`(UNEXPECTED) latestAddrsMap is not the same size as the incoming map (E: 666af512bbd44534983bb28ee8d43fed)`);\n }\n if (logalot) { console.log(`${lc} queriedLatestAddrsMap: ${pretty(queriedLatestAddrsMap)} (I: 7b39a5f7ce9e9d9fabae4be98ed44522)`); }\n latestAddrsMap = {\n ...queriedLatestAddrsMap,\n ...latestAddrsMap\n };\n }\n if (logalot) { console.log(`${lc} combined latestAddrsMap: ${pretty(latestAddrsMap)} (I: e3aedea63f29c5b06a79632f691aa522)`); }\n\n /**\n * these addrs are those whose timelines we did not yet have the latest.\n * this means that we will have to work off of these ibgibs.\n */\n const newerAddrsFound: IbGibAddr[] = [];\n const newerAddrFoundToTjpAddrMap: { [newerAddrFound: string]: IbGibAddr } = {}\n Object.values(mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed)\n .forEach(latestIbGibAlreadyGotten => {\n const latestAddrAlreadyGotten = getIbGibAddr({ ibGib: latestIbGibAlreadyGotten });\n const tjpAddr = mapLatestAddrAlreadyGottenToTjpAddr[latestAddrAlreadyGotten];\n const latestAddrInSpace = latestAddrsMap[latestAddrAlreadyGotten];\n if (!latestAddrInSpace) { throw new Error(`(UNEXPECTED) latestAddrInSpace not found in latestAddrsMap (E: 095d2b3f88e3e8a2c3e7d3de4c6d5622)`); }\n if (latestAddrInSpace === latestAddrAlreadyGotten) {\n // we've already got the latest for this timeline. This\n // means that we must have already at least queued all\n // timelines possible, so nothing else to do.\n if (logalot) { console.log(`${lc} analyzed ${tjpAddr}(I: afb7960900f04b8a87538f4c7bd903b7)`); }\n tjpAddrsAlreadyAnalyzed!.push(tjpAddr);\n } else {\n // there is a newer \"latest\" in this timeline that we\n // haven't gotten yet, so add that addr to the\n newerAddrsFound.push(latestAddrInSpace);\n newerAddrFoundToTjpAddrMap[latestAddrInSpace] = tjpAddr;\n }\n });\n\n let rel8dAddrsNotYetGotten: IbGibAddr[] = [];\n for (let i = 0; i < (ibGibs ?? []).length; i++) {\n const ibGib = ibGibs![i];\n const rel8ns = ibGib.rel8ns ?? {};\n const rel8nNames = Object.keys(rel8ns)\n .filter(x => !(skipRel8nNames ?? []).includes(x))\n .filter(x => onlyRel8nNames ? onlyRel8nNames.includes(x) : true);\n rel8nNames.forEach(rel8nName => {\n const rel8dAddrs = rel8ns[rel8nName] ?? [];\n rel8dAddrs.forEach(rel8dAddr => {\n // only add todo if we don't already have the ibgib\n\n if (!rel8dAddrsNotYetGotten.includes(rel8dAddr) &&\n !ibGibs!.some(x => getIbGibAddr({ ibGib: x }) === rel8dAddr)\n ) {\n rel8dAddrsNotYetGotten.push(rel8dAddr);\n }\n });\n });\n }\n ibGibAddrs = unique([...(ibGibAddrs ?? []), ...rel8dAddrsNotYetGotten, ...newerAddrsFound]);\n\n // if (newerAddrsFound.length === 0) {\n // there were no newer addrs found, necessitating that we have\n // no additional ibgibs that we don't know about.\n\n return await getGraphProjection({\n ibGibs, ibGibAddrs,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n live: true,\n mapTjpAddrToLatestAddrsInSpace,\n });\n // } else {\n // // #region old notes\n\n // // i don't know if i'll need these or if this algorithm is\n // // working correctly. atow (02/2024) it looks like it is\n // // working from initial testing in b2tfs ibgib testing.\n\n // // there are still newer ibgibs that must be included in the analysis., without yet\n // // going into the direct rel8ns of\n // // need to call recursively this _Live function, passing in\n // // the already computated latest map in mapTjpAddrToLatestAddrsInSpace\n // // I need to also adjust preceding code to use this map.\n // // Object.keys(queriedLatestAddrsMap).forEach(latestAddrNotGotten => {\n // // Object.keys(queriedLatestAddrsMap).forEach(tjpAddr => {\n // // const latestAddrNotGotten = queriedLatestAddrsMap[tjpAddr];\n // // // const tjpAddr = mapLatestAddrAlreadyGottenToTjpAddr[latestAddrNotGotten];\n // // mapTjpAddrToLatestAddrsInSpace![tjpAddr] = latestAddrNotGotten;\n // // if (queriedLatestAddrsMap[latestAddrNotGotten]) { ibGibAddrs!.push(); }\n // // });\n // // ibGibAddrs = unique(ibGibAddrs);\n // // // ibGibAddrs = unique([...ibGibAddrs, ...rel8dAddrsNotYetGotten]);\n // // #endregion old notes\n\n // return await getGraphProjection({\n // ibGibs, ibGibAddrs,\n // gotten, tjpAddrsAlreadyAnalyzed,\n // skipAddrs, skipRel8nNames, onlyRel8nNames,\n // maxRetries, msBetweenRetries,\n // space,\n // timeLogName,\n // live: true,\n // mapTjpAddrToLatestAddrsInSpace,\n // });\n // }\n } else {\n // we have no more timelines that we haven't already gotten, so we\n // can pass off to the non-live version\n if (!ibGibs) { ibGibs = []; }\n Object.values(gotten ?? {}).forEach(x => {\n const addr = getIbGibAddr({ ibGib: x });\n if (!ibGibs!.some(y => getIbGibAddr({ ibGib: x }) === addr)) {\n ibGibs!.push(x);\n }\n });\n return await getGraphProjection({ /* <<<< returns early */\n ibGibs, ibGibAddrs,\n gotten, /* tjpAddrsAlreadyAnalyzed not used */\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n live: false,\n });\n }\n } catch (error) {\n const emsg = `${lc} ${error.message}`;\n console.error(emsg);\n if (timeLogName) { console.timeLog(timeLogName, `${lc} error: ${emsg}`); }\n throw error;\n } finally {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} complete.`) }\n }\n}\n\n/**\n * NOT EXPORTED\n *\n * @see {@link getGraphProjection}\n * @see {@link getDependencyGraph}\n */\nasync function getGraphProjection_NonLive({\n ibGibs, ibGibAddrs,\n gotten, /* tjpAddrsAlreadyAnalyzed not used */\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n}: GetGraphProjectionOptions): Promise<GetGraphResult> {\n const lc = `[${getGraphProjection_NonLive.name}]`;\n try {\n // next, compile what could be a rather large list of rel8d ibgibAddrs\n // which must necessarily be in the past of the futuremost incoming\n // ibGib/ibGibAddr/s as rel8ns only work backwards (whereas tjp's can\n // refer to future timelines, the DAG substrate only looks backwards)\n const addrsWeDontHaveAlready_Rel8dAddrs: IbGibAddr[] = [];\n ibGibs ??= [];\n gotten ??= {};\n skipAddrs ??= [];\n skipRel8nNames ??= [];\n\n // so, we will iterate through all of our given and loaded ibGibs (not\n // the ones in gotten map though), look through all of their rel8ns, and\n // add any that haven't already been gotten\n if (timeLogName) { console.timeLog(timeLogName, `${lc} analyzing next step starting...`); }\n for (let i = 0; i < ibGibs.length; i++) {\n const ibGib = ibGibs[i];\n const ibGibAddr = getIbGibAddr({ ibGib });\n\n // do i need this?\n const { gib } = getIbAndGib({ ibGib });\n if (gib === GIB) { throw new Error(`cannot get dependency graph of primitive.`); }\n\n // ?\n // I believe I have this so we don't try to do this ibgib again on recursive call.\n // but should I be adding it at this point? hmm...\n if (!Object.keys(gotten).includes(ibGibAddr)) { gotten[ibGibAddr] = ibGib; }\n\n // iterate through rel8ns and compile list of ibgib addrs not yet gotten\n /** map of addr to validation errors array */\n const invalidAddrs: { [addr: string]: string[] } = {};\n const rel8ns = ibGib.rel8ns || {};\n let rel8nNames = (Object.keys(rel8ns) || []).filter(x => !skipRel8nNames!.includes(x));\n if (onlyRel8nNames) {\n rel8nNames = rel8nNames.filter(x => onlyRel8nNames.includes(x));\n }\n const gottenKeys = Object.keys(gotten);\n for (let i = 0; i < rel8nNames.length; i++) {\n const rel8nName = rel8nNames[i];\n const rel8dAddrs = rel8ns[rel8nName] ?? [];\n const falsyAddrs = rel8dAddrs.filter(addr =>\n addr === '' ||\n addr === undefined ||\n addr === null ||\n !addr.includes(IBGIB_DELIMITER)\n );\n if (falsyAddrs.length > 0) { console.warn(`${lc} (UNEXPECTED) has falsyAddrs: ${falsyAddrs} (W: da9505cb0a4db68a4aff7f279ad2d322)`); }\n const rel8dAddrsNotGottenYetThisRel8n =\n rel8dAddrs\n .filter(addr => !!addr)\n .filter(addr => !gottenKeys.includes(addr))\n .filter(addr => !skipAddrs!.includes(addr))\n .filter(addr => getIbAndGib({ ibGibAddr: addr }).gib !== GIB)\n .filter(addr => !addrsWeDontHaveAlready_Rel8dAddrs.includes(addr));\n rel8dAddrsNotGottenYetThisRel8n.forEach(rel8dAddr => {\n const validationErrors = validateIbGibAddr({ addr: rel8dAddr });\n if ((validationErrors || []).length === 0) {\n // valid addr. add it if we haven't gotten/queued it yet\n addrsWeDontHaveAlready_Rel8dAddrs.push(rel8dAddr);\n } else {\n // invalid address\n invalidAddrs[rel8dAddr] = validationErrors!;\n }\n });\n }\n\n if (Object.keys(invalidAddrs).length > 0) {\n throw new Error(`invalid addresses found in dependency graph. Errors (clipped to 1kB): ${JSON.stringify(invalidAddrs).substring(0, 1024)}`);\n }\n }\n if (timeLogName) { console.timeLog(timeLogName, `${lc} analyzing next step complete.`); }\n\n if (addrsWeDontHaveAlready_Rel8dAddrs.length > 0) {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} get addrsWeDontHaveAlready_Rel8dAddrs starting...`); }\n // execute the get on those addrs\n if (!space) { throw new Error(`(UNEXPECTED) space falsy? (E: 0ce327cf5d521bd798340333460f3423)`); }\n const resGet = await getFromSpace({ addrs: addrsWeDontHaveAlready_Rel8dAddrs, space });\n if (timeLogName) { console.timeLog(timeLogName, `${lc} get addrsWeDontHaveAlready_Rel8dAddrs complete.`); }\n if (resGet.success) {\n if (resGet.ibGibs?.length === addrsWeDontHaveAlready_Rel8dAddrs.length) {\n if (logalot) { console.log(`${lc} got ALL of them (happy path)`); }\n resGet.ibGibs.forEach(x => gotten![getIbGibAddr({ ibGib: x })] = x);\n // return a recursive call for the newly-gotten ibgibs'\n // dependencies, passing in the now-larger accumulating\n // `gotten` map of ibgibs already processed.\n if (timeLogName) { console.timeLog(timeLogName, `${lc} call getGraphProjection recursively starting...`); }\n const result = await getGraphProjection({\n ibGibs: resGet.ibGibs,\n live: false,\n gotten, /* tjpAddrsAlreadyAnalyzed not used */\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n });\n if (timeLogName) { console.timeLog(timeLogName, `${lc} call getGraphProjection recursively complete.`); }\n return result; // <<<< returns early\n } else if ((resGet.ibGibs?.length ?? 0) > 0 && resGet.ibGibs!.length < addrsWeDontHaveAlready_Rel8dAddrs.length) {\n if (logalot) { console.warn(`${lc} got SOME of them (happy-ish path?). not sure what to do here... (W: e3458f61a1ae4979af9e6b18ac935c14)`); }\n throw new Error(`trouble getting dependency ibgibs (E: 8156bf65fd084ae4a4e8a0669db28b07)`);\n } else if ((resGet.ibGibs?.length ?? 0 > 0) && resGet.ibGibs!.length > addrsWeDontHaveAlready_Rel8dAddrs.length) {\n // got more than our original list? not a good space behavior...\n throw new Error(`(UNEXPECTED) got more ibGibs than addrs that we asked for. space not working properly. (E: 352219b3d18543bcbda957f2d60b78f3)`);\n } else {\n // didn't get any...hmm...\n throw new Error(`couldn't get dependency ibgibs from space. (E: 225f26b7d7f84911bb033753a062209b)`);\n }\n } else {\n // resGet.success falsy indicates an error in the space. If it wasn't found\n // then resGet.success would (should) still be truthy.\n throw new Error(`failure getting addrs in space ${space?.data?.name || '[no name?]'} (id: ${space?.data?.uuid || '[no uuid?]'}). (E: 60404e6e389249d9bbecf0039cd51878) addrs:\\n${addrsWeDontHaveAlready_Rel8dAddrs.join('\\n')} `);\n }\n } else {\n // no other rel8d addrs to get, so our job is done and the `gotten`\n // map of dependency ibgibs is complete (no need for another\n // recursive call).\n return gotten;\n }\n\n } catch (error) {\n const emsg = `${lc} ${error.message}`;\n console.error(emsg);\n if (timeLogName) { console.timeLog(timeLogName, `${lc} error: ${emsg}`); }\n throw error;\n } finally {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} complete.`) }\n }\n}\n\n/**\n * Helper function to convert an array of {@link ibGibs} (or undefined) to a\n * {@link FlatIbGibGraph} ([addr] -> ibGib map).\n * @returns if ibGibs undefined returns undefined, else flat graph map\n */\nexport function toFlatGraph({ ibGibs }: { ibGibs: IbGib_V1[] | undefined }): FlatIbGibGraph | undefined {\n const lc = `[${toFlatGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 6019a812cff8597f79c12088e45cc226)`); }\n\n if (ibGibs) {\n const resGraph: FlatIbGibGraph = {};\n ibGibs.forEach(x => { resGraph[getIbGibAddr({ ibGib: x })] = x; })\n return resGraph;\n } else {\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * compare two graphs for \"equivalency\".\n *\n * The default just checks that sizes and addrs are the same.\n *\n * The more thorough check does the json strings of the values (as dtos).\n */\nexport function graphsAreEquivalent({\n graphA,\n graphB,\n slowButThorough,\n}: {\n graphA: FlatIbGibGraph,\n graphB: FlatIbGibGraph,\n /**\n * if true, will actually compare the dto strings of each ibgib in the graph\n */\n slowButThorough?: boolean,\n}): boolean {\n const lc = `[${graphsAreEquivalent.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: e50a98b659189dece8b4ef581e4ad826)`); }\n\n const sameSize = Object.keys(graphA).length === Object.keys(graphB).length;\n if (!sameSize) {\n if (logalot) { console.log(`${lc} not the same size. false. (I: e1044e52421dbf7e067e0fe850ac6826)`); }\n return false; /* <<<< returns early */\n }\n\n for (const addr of Object.keys(graphA)) {\n if (!graphB[addr]) {\n if (logalot) { console.log(`${lc} addr (${addr}) in graphA not found in graphB (I: 264c68408378ce30b8f6a978f8b86926)`); }\n return false; /* <<<< returns early */\n }\n }\n\n if (slowButThorough) {\n // go back through and check for dto string equality (deep equality)\n for (const addr of Object.keys(graphA)) {\n const ibGibA = toDto({ ibGib: graphA[addr] });\n const jsonA = JSON.stringify(ibGibA);\n const ibGibB = toDto({ ibGib: graphB[addr] });\n const jsonB = JSON.stringify(ibGibB);\n if (jsonA !== jsonB) {\n if (logalot) { console.log(`${lc} jsonA !== jsonB for addr (${addr}) (I: 98ed9f58ac88dabba83f96582f725926)`); }\n return false; /* <<<< returns early */\n }\n }\n }\n\n return true;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}", "import { extractErrorMsg, hash, HashAlgorithm, pretty } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { GIB } from \"@ibgib/ts-gib/dist/V1/constants.mjs\";\nimport { Ib, TransformResult } from \"@ibgib/ts-gib/dist/types.mjs\";\nimport { getIbAndGib, getIbGibAddr } from \"@ibgib/ts-gib/dist/helper.mjs\";\nimport { validateIbGibIntrinsically } from \"@ibgib/ts-gib/dist/V1/validate-helper.mjs\";\nimport { mut8 } from \"@ibgib/ts-gib/dist/V1/transforms/mut8.mjs\";\nimport { Factory_V1 } from \"@ibgib/ts-gib/dist/V1/factory.mjs\";\nimport { getGib } from \"@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs\";\n\nimport { GLOBAL_LOG_A_LOT } from \"../core-constants.mjs\";\nimport { KEYSTONE_ATOM, KEYSTONE_HASH_MAX_ROUNDS, KEYSTONE_POOL_ID_REGEXP, KEYSTONE_SALT_REGEXP } from \"./keystone-constants.mjs\";\nimport {\n KeystoneData_V1, KeystoneIbGib_V1, KeystoneIb_V1, KeystoneChallengePool,\n DeterministicResult, KeystoneProof, KeystonePoolConfig,\n KeystoneReplenishStrategy, KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES,\n KeystoneClaim, KeystoneSolution,\n KeystoneChallengeType,\n KEYSTONE_CHALLENGE_TYPE_VALID_VALUES,\n KeystonePoolConfig_HashV1,\n} from \"./keystone-types.mjs\";\nimport { MetaspaceService } from \"../witness/space/metaspace/metaspace-types.mjs\";\nimport { IbGibSpaceAny } from \"../witness/space/space-base-v1.mjs\";\nimport { KeystoneStrategyFactory } from \"./strategy/keystone-strategy-factory.mjs\";\nimport { getDependencyGraph } from \"../common/other/graph-helper.mjs\";\nimport { getIbGibsFromCache_fallbackToSpaces, getTimelinesGroupedByTjp, splitPerTjpAndOrDna } from \"../common/other/ibgib-helper.mjs\";\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\nimport { getLatestAddrs } from \"../witness/space/space-helper.mjs\";\nimport { FlatIbGibGraph } from \"../common/other/graph-types.mjs\";\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * space-delimited keystone ib containing select keystone metadata.\n *\n * NOTE: This must match {@link parseKeystoneIb}\n * @see {@link KeystoneIb_V1}\n */\nexport async function getKeystoneIb({\n keystoneData,\n}: {\n keystoneData: KeystoneData_V1,\n}): Promise<Ib> {\n const lc = `[${getKeystoneIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: c3022a146faac9730154f34d1439a225)`); }\n\n const atom = KEYSTONE_ATOM;\n\n const ib = [\n atom,\n ].join(' ');\n\n return ib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * NOTE: This must match {@link getKeystoneIb}\n * @see {@link KeystoneIb_V1}\n */\nexport async function parseKeystoneIb({\n ib,\n}: {\n ib: Ib,\n}): Promise<KeystoneIb_V1> {\n const lc = `[${parseKeystoneIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 73cb6832984255ed48b2f44db6a21e25)`); }\n const [\n atom\n ] = ib.split(' ');\n\n if (atom !== KEYSTONE_ATOM) {\n throw new Error(`invalid keystone ib. atom found in ib (${atom}) does not match keystone atom (${KEYSTONE_ATOM}) (E: 79b3d587824c4271b6e60acc76e0c825)`);\n }\n\n return {\n atom,\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * The Policy Engine.\n * Calculates exactly which challenges MUST be consumed based on config and demands.\n * Enforces STRICT DISTINCTNESS (No double-dipping).\n */\nexport function getDeterministicRequirements({\n pool,\n requiredChallengeIds,\n targetAddr\n}: {\n pool: KeystoneChallengePool;\n requiredChallengeIds?: string[];\n targetAddr?: string;\n}): DeterministicResult {\n const behavior = pool.config.behavior;\n const mandatory = new Set<string>();\n\n // Start with all available IDs.\n // We assume Object.keys respects insertion order (ES2015+), crucial for FIFO.\n let available = Object.keys(pool.challenges);\n\n // ---------------------------------------------------------\n // 1. Alice's Demands (Explicit Requirements)\n // ---------------------------------------------------------\n if (requiredChallengeIds && requiredChallengeIds.length > 0) {\n for (const id of requiredChallengeIds) {\n if (!pool.challenges[id]) {\n throw new Error(`(UNEXPECTED) Required challenge ID not found in pool: ${id} (E: 10c5619d80d8cf6cc84ffbf8be0dbc25)`);\n }\n // Strict: Consume it.\n if (!available.includes(id)) {\n // Should be caught by check above, but handles duplicates in 'demands'\n continue;\n }\n mandatory.add(id);\n }\n // Remove from available pool\n available = available.filter(id => !mandatory.has(id));\n }\n\n // ---------------------------------------------------------\n // 2. Target Binding (Explicit Buckets)\n // ---------------------------------------------------------\n if (behavior.targetBindingChars > 0 && targetAddr) {\n const { gib } = getIbAndGib({ ibGibAddr: targetAddr });\n if (gib) {\n // Get required hex prefixes (e.g. 'a', 'b', 'c', '1')\n const prefixes = gib !== GIB ?\n gib.substring(0, behavior.targetBindingChars).toLowerCase() :\n 'abc'; // arbitrary for primitive binding target ibgib\n\n for (const char of prefixes) {\n // Look in the Explicit Bucket\n const bucket = pool.bindingMap[char] || [];\n\n // Find the first ID in this bucket that is still in 'available'\n const match = bucket.find(id => available.includes(id));\n\n if (!match) {\n throw new Error(`Entropy Exhaustion. Cannot satisfy binding for char '${char}'. (E: 341b95dc3a58be3e083d1d9c4a0c4925)`);\n }\n\n // Strict: Consume it.\n mandatory.add(match);\n available = available.filter(id => id !== match);\n }\n }\n }\n\n // ---------------------------------------------------------\n // 3. FIFO (Sequential)\n // ---------------------------------------------------------\n if (behavior.selectSequentially > 0) {\n // Take the first N from the remaining available list\n if (available.length < behavior.selectSequentially) {\n console.error(`[getDeterministicRequirements] Entropy Exhaustion! AvailableCount: ${available.length}, Required Seq: ${behavior.selectSequentially}. Available IDs: ${available.join(',')}`);\n throw new Error(`Entropy Exhaustion. Insufficient challenges for FIFO requirement. (E: 9efa88003e1d5eccb837c85154ee5625)`);\n }\n\n const fifoIds = available.slice(0, behavior.selectSequentially);\n fifoIds.forEach(id => mandatory.add(id));\n\n // Remove from available\n available = available.slice(behavior.selectSequentially);\n }\n\n return { mandatoryIds: mandatory, availableIds: available };\n}\n\n/**\n * Helper to update the Binding Map when adding new Challenge IDs.\n * Uses \"Implicit Bucketing\" (ID start char) but can be extended for full coverage.\n */\nexport function addToBindingMap(\n map: { [char: string]: string[] },\n challengeId: string\n): void {\n const firstChar = challengeId.charAt(0).toLowerCase();\n // Validate it is hex\n if (/[0-9a-f]/.test(firstChar)) {\n if (!map[firstChar]) { map[firstChar] = []; }\n map[firstChar].push(challengeId);\n\n // OPTIONAL: Implement Full Coverage Strategy here?\n // e.g. map[challengeId[1]].push(challengeId) ...\n // For V1, we stick to Native/Implicit bucket (Index 0).\n } else {\n throw new Error(`invalid challengeId (${challengeId}). Must start with a hex character. (E: c96ed8460de89e28c801370a0f07f826)`);\n }\n}\n\n/**\n * Helper to clean up Binding Map when removing IDs.\n */\nexport function removeFromBindingMap(\n map: { [char: string]: string[] },\n challengeId: string\n): void {\n // Since we don't know exactly which buckets an ID is in (if we did multi-bucket),\n // we strictly should scan all. For V1 Native, we check first char.\n // SAFE IMPLEMENTATION: Scan all buckets.\n for (const key of Object.keys(map)) {\n map[key] = map[key].filter(id => id !== challengeId);\n }\n}\n\n/**\n * Selects the specific pool to use for an operation based on ID, filter criteria, or verb authorization.\n *\n * @returns The matching KeystoneChallengePool\n * @throws If no pool matches or if multiple pools match but one was expected.\n */\nexport function resolveTargetPool({\n pools,\n poolId,\n poolFilter,\n verb,\n}: {\n pools: KeystoneChallengePool[];\n /**\n * Explicit ID of the pool to use.\n */\n poolId?: string;\n /**\n * Optional predicate to find a pool.\n * Useful for finding delegates via metadata.\n */\n poolFilter?: (pool: KeystoneChallengePool) => boolean;\n /**\n * The verb being performed (e.g. 'revoke', 'manage', 'post').\n * Used for authorization checks and auto-resolution.\n */\n verb?: string;\n}): KeystoneChallengePool {\n const lc = `[resolveTargetPool]`;\n try {\n let pool: KeystoneChallengePool | undefined;\n\n if (poolId) {\n // 1. Explicit ID Strategy\n pool = pools.find(p => p.id === poolId);\n if (!pool) { throw new Error(`Pool not found with ID: ${poolId} (E: 4a2b17428515c1e82813158581898125)`); }\n } else if (poolFilter) {\n // 2. Filter Strategy\n const matches = pools.filter(poolFilter);\n if (matches.length === 0) { throw new Error(`No pool matched the provided filter. (E: 5b3c27428515c1e82813158581898125)`); }\n // For now, we take the first match. In future, might want to be strict about uniqueness.\n pool = matches[0];\n } else {\n // 3. Auto-Resolution by Verb Strategy\n if (!verb) { throw new Error(`Cannot auto-resolve pool without a verb. (E: 6c4d37428515c1e82813158581898125)`); }\n\n // Priority A: Look for Specific Match (Pool explicitly lists this verb)\n pool = pools.find(p =>\n p.config.allowedVerbs && p.config.allowedVerbs.includes(verb)\n );\n\n // Priority B: Look for General/Default (No restrictions / Wildcard)\n if (!pool) {\n pool = pools.find(p =>\n !p.config.allowedVerbs || p.config.allowedVerbs.length === 0\n );\n }\n\n if (!pool) { throw new Error(`No suitable pool found for verb: ${verb} (E: 7d5e47428515c1e82813158581898125)`); }\n }\n\n // 4. Authorization Check (Applies to all strategies if verb is present)\n if (verb && pool.config.allowedVerbs && pool.config.allowedVerbs.length > 0) {\n if (!pool.config.allowedVerbs.includes(verb)) {\n throw new Error(`Pool ${pool.id} is not authorized for verb: ${verb} (E: 8e6f57428515c1e82813158581898125)`);\n }\n }\n\n return pool;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Calculates the complete list of Challenge IDs to solve for a given operation.\n * Combines Deterministic requirements (Mandatory/Binding/FIFO) with Stochastic requirements.\n *\n * @returns Array of unique challenge IDs.\n */\nexport function selectChallengeIds({\n pool,\n targetAddr,\n requiredChallengeIds,\n}: {\n pool: KeystoneChallengePool;\n /**\n * The address of the target ibgib (used for binding entropy).\n */\n targetAddr?: string;\n /**\n * Explicit demands from a verifier.\n */\n requiredChallengeIds?: string[];\n}): string[] {\n const lc = `[selectChallengeIds]`;\n try {\n // 1. Get Deterministic Requirements\n const { mandatoryIds, availableIds } = getDeterministicRequirements({\n pool,\n requiredChallengeIds,\n targetAddr\n });\n\n // 2. Stochastic Selection\n const randomCount = pool.config.behavior.selectRandomly;\n const randomIds: string[] = [];\n\n if (randomCount > 0) {\n if (availableIds.length < randomCount) {\n throw new Error(`Insufficient challenges for random requirement. Need ${randomCount}, have ${availableIds.length} (E: 9f7a67428515c1e82813158581898125)`);\n }\n // Shuffle & Pick\n // Note: simple Math.random sort is sufficient for V1 stochastic selection\n // as we are just picking from valid available options.\n const shuffled = [...availableIds].sort(() => 0.5 - Math.random());\n randomIds.push(...shuffled.slice(0, randomCount));\n }\n\n // 3. Combine\n return [...mandatoryIds, ...randomIds];\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Generates an opaque, collision-resistant ID for a challenge.\n * atow (2025/12/22) - Hash(Salt + Timestamp + Index)\n */\nexport async function generateOpaqueChallengeId({\n salt,\n timestamp,\n index\n}: {\n salt: string,\n timestamp: string,\n index: number\n}): Promise<string> {\n // Use first 16 chars of hex (64 bits) for brevity + safety.\n const raw = await hash({ s: `${salt}${timestamp}${index}` });\n return raw.substring(0, 16);\n}\n\n/**\n * Calculates the NEXT state of the Challenge Pools given a specific consumption event.\n * Handles TopUp, ReplaceAll, Consume, and ScorchedEarth strategies.\n *\n * @returns The new array of KeystoneChallengePools (including the modified one).\n */\nexport async function applyReplenishmentStrategy({\n prevPools,\n targetPoolId,\n consumedIds,\n masterSecret,\n strategy,\n config,\n}: {\n prevPools: KeystoneChallengePool[],\n targetPoolId: string,\n consumedIds: string[],\n masterSecret: string,\n /**\n * The instantiated KeystoneStrategy (e.g. HashRevealV1) used to generate new challenges.\n */\n strategy: any, // Typed as 'any' or 'KeystoneStrategyAny' to avoid circular dep if possible\n config: KeystonePoolConfig,\n}): Promise<KeystoneChallengePool[]> {\n const lc = `[applyReplenishmentStrategy]`;\n try {\n const newPools = JSON.parse(JSON.stringify(prevPools));\n const targetIdx = newPools.findIndex((p: any) => p.id === targetPoolId);\n if (targetIdx === -1) { throw new Error(`Target pool ${targetPoolId} not found in keystone data. (E: 75200388d22744838634524233772545)`); }\n const pool = newPools[targetIdx];\n\n const poolSecret = await strategy.derivePoolSecret({ masterSecret });\n const timestamp = Date.now().toString();\n\n const strategyType = config.behavior.replenish;\n\n // Clean up Binding Map for consumed IDs\n consumedIds.forEach(id => {\n if (pool.bindingMap) { removeFromBindingMap(pool.bindingMap, id); }\n });\n\n if (strategyType === KeystoneReplenishStrategy.topUp) {\n // Remove consumed\n consumedIds.forEach(id => delete pool.challenges[id]);\n\n // Add New\n for (let i = 0; i < consumedIds.length; i++) {\n const newId = await generateOpaqueChallengeId({\n salt: config.salt, timestamp, index: i\n });\n\n const solution = await strategy.generateSolution({\n poolSecret, poolId: pool.id, challengeId: newId\n });\n pool.challenges[newId] = await strategy.generateChallenge({ solution });\n\n // Update Binding Map\n if (!pool.bindingMap) { pool.bindingMap = {}; }\n addToBindingMap(pool.bindingMap, newId);\n }\n } else if (strategyType === KeystoneReplenishStrategy.replaceAll) {\n pool.challenges = {};\n pool.bindingMap = {};\n\n for (let i = 0; i < config.behavior.size; i++) {\n const newId = await generateOpaqueChallengeId({\n salt: config.salt, timestamp, index: i\n });\n const solution = await strategy.generateSolution({\n poolSecret, poolId: pool.id, challengeId: newId\n });\n pool.challenges[newId] = await strategy.generateChallenge({ solution });\n addToBindingMap(pool.bindingMap, newId);\n }\n } else if (strategyType === KeystoneReplenishStrategy.consume) {\n consumedIds.forEach(id => delete pool.challenges[id]);\n } else if (strategyType === KeystoneReplenishStrategy.deleteAll) {\n pool.challenges = {};\n pool.bindingMap = {};\n } else {\n throw new Error(`Unknown replenish strategy: ${strategyType}. Valid list: ${pretty(KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES)} (E: 0acf56f1e1486240080e11e8046d0825)`);\n }\n\n return newPools;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * High-level orchestration helper.\n * 1. Instantiates Strategy.\n * 2. Derives Secret.\n * 3. Solves Challenges (Generates Solutions).\n * 4. Replenishes Pool (Calculates the next state of ALL pools).\n * 5. Constructs Proof.\n *\n * @returns The resulting Proof and the full list of Next Pools.\n */\nexport async function solveAndReplenish({\n targetPoolId,\n prevPools,\n masterSecret,\n challengeIds,\n claim,\n requiredChallengeIds,\n}: {\n /**\n * The ID of the pool to use for signing.\n */\n targetPoolId: string;\n /**\n * The full list of pools from the previous Keystone frame.\n * Required to reconstruct the full state for the next frame.\n */\n prevPools: KeystoneChallengePool[];\n masterSecret: string;\n challengeIds: string[];\n claim: Partial<KeystoneClaim>;\n requiredChallengeIds?: string[];\n}): Promise<{ proof: KeystoneProof, nextPools: KeystoneChallengePool[] }> {\n const lc = `[solveAndReplenish]`;\n try {\n if (logalot) { console.log(`${lc} starting... poolId: ${targetPoolId}, ids: ${challengeIds.length}`); }\n\n const pool = prevPools.find(p => p.id === targetPoolId);\n if (!pool) { throw new Error(`Target pool not found: ${targetPoolId} (E: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6)`); }\n\n const strategy = KeystoneStrategyFactory.create({ config: pool.config });\n const poolSecret = await strategy.derivePoolSecret({ masterSecret });\n const solutions: KeystoneSolution[] = [];\n\n // 1. Solve\n for (const id of challengeIds) {\n const solution = await strategy.generateSolution({\n poolSecret, poolId: pool.id, challengeId: id,\n });\n solutions.push(solution);\n }\n\n // 2. Construct Proof\n const proof: KeystoneProof = {\n claim,\n solutions,\n requiredChallengeIds: (requiredChallengeIds && requiredChallengeIds.length > 0) ? requiredChallengeIds : undefined\n };\n\n // 3. Replenish\n const nextPools = await applyReplenishmentStrategy({\n prevPools,\n targetPoolId: pool.id,\n consumedIds: challengeIds,\n masterSecret,\n strategy,\n config: pool.config\n });\n\n return { proof, nextPools };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nexport async function validateChallengePool_typeHashRevealV1({ pool }: {\n pool: KeystoneChallengePool;\n}): Promise<string[]> {\n const lc = `[${validateChallengePool_typeHashRevealV1.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: e2ffd568b698cc12d8c5e838d73ae726)`); }\n\n if (!pool.config) { throw new Error(`(UNEXPECTED) pool.configy falsy? (E: fcde88fe20e8004a58d7e445436bf526)`); }\n if (pool.config.type !== KeystoneChallengeType.hash_reveal_v1) {\n throw new Error(`(UNEXPECTED) pool.config.type !== KeystoneChallengeType.hash_reveal_v1? (E: e205f8872909c37168a624a9df778c26)`);\n }\n\n const errors: string[] = [];\n\n const { algo, rounds, salt, } = pool.config as KeystonePoolConfig_HashV1;\n\n const validAlgos: HashAlgorithm[] = [HashAlgorithm.sha_256];\n if (algo) {\n if (!validAlgos.includes(algo)) {\n errors.push(`${lc} invalid hash algorithm (${algo}). Must be one of ${validAlgos}. (E: a22399ca3a68e63ffcc7507699be5826)`);\n }\n } else {\n errors.push(`${lc} algorithm required. (E: 8cd6bfb0590862b9bae24d98d2cf3826)`)\n }\n\n if (rounds && typeof rounds === 'number' && Number.isInteger(rounds)) {\n if (rounds > KEYSTONE_HASH_MAX_ROUNDS) {\n errors.push(`${lc} rounds too high. max rounds: ${KEYSTONE_HASH_MAX_ROUNDS} (E: 31ce082f7fd88d6b58ef08a816458826)`);\n }\n } else {\n errors.push(`${lc} invalid rounds (${rounds}). must be positive integer. (E: 73c643ccda78afaf28d52a6871a9e826)`);\n }\n\n if (salt && typeof salt === 'string') {\n // no limits on this? sanity check?\n if (!KEYSTONE_SALT_REGEXP.test(salt)) {\n errors.push(`${lc} invalid salt (${salt.substring(0, 99)}). Must match regexp ${KEYSTONE_SALT_REGEXP}`);\n }\n } else {\n errors.push(`${lc} invalid salt (${salt}). must be truthy string value. (E: 564a4844ec88fc1988197ce89c381426)`);\n }\n\n return errors;\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function validateChallengePool({ pool }: {\n pool: KeystoneChallengePool;\n}): Promise<string[]> {\n const lc = `[${validateChallengePool.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 1a0eafc158a83d1ba8fc019d5c979a26)`); }\n const errors: string[] = [];\n\n if (pool.config) {\n // first validate common to all pools, regardless of type...\n if (pool.config.id) {\n if (!KEYSTONE_POOL_ID_REGEXP.test(pool.config.id)) {\n // not 100% that this is needed but hey\n errors.push(`${lc} pool.config.id is not formatted correctly. must pass regexp: ${KEYSTONE_POOL_ID_REGEXP.source}`);\n }\n } else {\n errors.push(`${lc} pool.config.id falsy (E: 31d7943d95f877326d5f4ea14463d626)`);\n }\n\n if (pool.config.behavior) {\n const { size } = pool.config.behavior;\n if (!size || size === 0) {\n errors.push(`${lc} invalid pool.config.behavior.size (${size}). Must be positive integer. (E: b221e36ec102bdc944552248ce8fe626)`)\n }\n // todo: more behavior checks\n } else {\n errors.push(`${lc} pool.config.behavior falsy (E: bede081c066c39732eefe2f92e296326)`)\n }\n\n // ...then do type-specific validation\n const poolType = pool.config.type;\n switch (poolType) {\n case KeystoneChallengeType.hash_reveal_v1:\n const errorsHashRevealV1 = await validateChallengePool_typeHashRevealV1({ pool });\n errorsHashRevealV1.forEach(x => errors.push(x));\n break;\n default:\n throw new Error(`(UNEXPECTED) unknown pool.config.type (${poolType})? We only implement the following at this time: ${KEYSTONE_CHALLENGE_TYPE_VALID_VALUES} (E: cce5285cf7580b8bc82172488eba2826)`);\n }\n } else {\n errors.push(`${lc} pool.config falsy. (E: 8d05c875a1d2c58018a5eaf803977d26)`);\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n\nexport async function validateGenesisKeystone({\n keystoneIbGib\n}: {\n keystoneIbGib: KeystoneIbGib_V1;\n}): Promise<string[]> {\n const lc = `[${validateGenesisKeystone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: ec6ba82ec848b5ac3d8953e89d8d9826)`); }\n\n const errors: string[] = [];\n\n const { data, rel8ns } = keystoneIbGib;\n\n // no proofs/solutions yet\n if (data.proofs && data.proofs.length > 0) {\n errors.push(`${lc} proofs already exist on genesis keystone. (E: 7a5e15f20918f1bbd8ffb62857dcd526)`);\n }\n\n for (const pool of data.challengePools) {\n // validate each pool intrinsically (config, sanity)\n const poolErrors = await validateChallengePool({ pool });\n poolErrors.forEach(x => errors.push(x));\n\n // additionally ensure each pool has challenges. This is only on\n // this genesis keystone, as it is valid to have pool without\n // challenges after revocation\n if (!pool.challenges || Object.keys(pool.challenges).length === 0) {\n errors.push(`${lc} invalid pool (${pool.id}). pool.challenges is falsy/empty. (E: 8cd16a5416ae62a058342828be465b26)`);\n }\n }\n\n // not stated as revoked already\n if (!!data.revocationInfo) {\n errors.push(`${lc} genesis keystone already has revocationInfo. (E: e11408d0c558d0fa948efbce611ec826)`);\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Validates the transition from Prev -> Curr.\n * Enforces Cryptography AND Behavioral Policy.\n *\n * @returns Array of validation error strings. Empty array means Valid.\n */\nexport async function validateKeystoneTransition({\n currentIbGib,\n prevIbGib,\n}: {\n currentIbGib: KeystoneIbGib_V1;\n prevIbGib: KeystoneIbGib_V1;\n}): Promise<string[]> {\n const lc = `[${validateKeystoneTransition.name}]`;\n const errors: string[] = [];\n try {\n if (!currentIbGib) {\n throw new Error(`(UNEXPECTED) currentIbGib falsy? (E: 3c0f02655fa8279e386a079ebb604b25)`);\n }\n if (!prevIbGib) { throw new Error(`(UNEXPECTED) prevIbGib falsy? (E: 0d07c812634d839c784f31b8848ba825)`); }\n\n // intrinsic validation\n const validationErrors = await validateIbGibIntrinsically({ ibGib: currentIbGib });\n if (validationErrors && validationErrors.length > 0) {\n errors.push(...validationErrors);\n }\n\n const currData = currentIbGib.data!;\n const prevData = prevIbGib.data!;\n\n // must be sequential data.n values\n // note: \"-2\" because we don't want a \"valid\" sequential data.n if we\n // have an invalid prev and a valid currDataN of 0\n const currDataN = currData.n ?? -2;\n const prevDataN = prevData.n ?? -2;\n if (currDataN < 0) {\n errors.push('invalid keystone.currData.n is undefined or null.');\n }\n if (prevDataN < 0) {\n errors.push('invalid keystone.prevData.n is undefined or null.');\n };\n if (currDataN !== (prevDataN + 1)) {\n errors.push(`keystone data.n values are not sequential. prevData.n: ${prevDataN}, currData.n: ${currDataN}. `);\n }\n\n for (const proof of currData.proofs) {\n if (proof.solutions.length === 0) {\n errors.push(`Proof ${proof.id || 'unknown'} has no solutions.`);\n continue;\n }\n\n const poolId = proof.solutions[0].poolId;\n\n // Standard Verification (Internal Pools Only)\n // The pool MUST be present in the previous frame.\n const pool = prevData.challengePools.find(p => p.id === poolId);\n if (!pool) {\n errors.push(`Proof references unknown pool: ${poolId}`);\n continue;\n }\n\n await verifyProofAgainstPool({ proof, pool, errors });\n\n } // End proof loop\n\n // Revocation Logic checks\n if (currData.revocationInfo) {\n const target = currData.revocationInfo.proof.claim.target;\n const expectedTarget = getIbGibAddr({ ibGib: prevIbGib });\n if (target !== expectedTarget) {\n errors.push(`Revocation target mismatch. Expected ${expectedTarget}, got ${target}`);\n }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error; // System errors still throw\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Helper to verify a single proof against a specific pool.\n */\nexport async function verifyProofAgainstPool({\n proof,\n pool,\n errors,\n}: {\n proof: KeystoneProof;\n pool: KeystoneChallengePool;\n errors: string[];\n}): Promise<void> {\n const lc = `[${verifyProofAgainstPool.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b8f9b6085888eea2258bf579ecd5e825)`); }\n\n // 0. VERB AUTH\n if (pool.config.allowedVerbs && pool.config.allowedVerbs.length > 0) {\n if (!proof.claim.verb || !pool.config.allowedVerbs.includes(proof.claim.verb)) {\n errors.push(`Policy Violation: Pool ${pool.id} used for unauthorized verb ${proof.claim.verb}`);\n }\n }\n\n // 1. Reconstruct Deterministic Requirements\n const { mandatoryIds, availableIds } = getDeterministicRequirements({\n pool,\n requiredChallengeIds: proof.requiredChallengeIds,\n targetAddr: proof.claim.target // Not used extensively in V1 logic yet, mainly for logging/context\n });\n\n // 2. Check Mandatory\n const proofIds = new Set(proof.solutions.map(s => s.challengeId));\n for (const id of mandatoryIds) {\n if (!proofIds.has(id)) {\n errors.push(`Policy Violation: Missing mandatory challenge ${id}`);\n }\n }\n\n // 3. Stochastic\n const randomCandidates = [...proofIds].filter(id => !mandatoryIds.has(id));\n const requiredRandomCount = pool.config.behavior.selectRandomly;\n if (randomCandidates.length < requiredRandomCount) {\n errors.push(`Policy Violation: Insufficient random count. Need ${requiredRandomCount}, got ${randomCandidates.length}`);\n }\n\n // 4. Validity (Double Dip / Existence)\n for (const id of randomCandidates) {\n if (!availableIds.includes(id)) {\n errors.push(`Policy Violation: ID ${id} is invalid or double-dipped.`);\n }\n }\n\n // 5. Crypto\n const strategy = KeystoneStrategyFactory.create({ config: pool.config });\n for (const solution of proof.solutions) {\n const challenge = pool.challenges[solution.challengeId];\n if (!challenge) {\n errors.push(`Crypto Violation: Challenge ${solution.challengeId} not found in pool.`);\n } else {\n const isValid = await strategy.validateSolution({ solution, challenge });\n if (!isValid) {\n errors.push(`Crypto Violation: Solution for ${solution.challengeId} is invalid.`);\n }\n }\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function evolvePersistAndRegisterKeystone({\n prevIbGib,\n newData,\n metaspace,\n space,\n}: {\n prevIbGib: KeystoneIbGib_V1,\n newData: KeystoneData_V1\n metaspace: MetaspaceService,\n space: IbGibSpaceAny,\n}): Promise<KeystoneIbGib_V1> {\n const lc = `[${evolvePersistAndRegisterKeystone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 8b10e8920f08b7842803665834cf8925)`); }\n\n if (!prevIbGib.data) { throw new Error(`(UNEXPECTED) prevIbGib.data falsy? (E: 5e84875bf992c585b979e6c8ed5bf225)`); }\n if (prevIbGib.data.revocationInfo) { throw new Error(`Keystone has already been revoked (prevIbGib.data.revocationInfo truthy), so we cannot evolve the keystone. Keystone addr: ${getIbGibAddr({ ibGib: prevIbGib })} (E: 45d7f846556829de6b2a701838c3f825)`); }\n\n const prevData = prevIbGib.data;\n /**\n * we want to completely replace these keys, so we will remove them\n * from the data. This occurs first in the underlying mut8\n * transform.\n * @see {@link mut8}\n */\n let dataToRemove: Partial<KeystoneData_V1> | undefined = {}\n if (prevData.proofs) { dataToRemove.proofs = []; }\n if (prevData.challengePools) { dataToRemove.challengePools = []; }\n if (prevData.frameDetails) { dataToRemove.frameDetails = {}; }\n if (prevData.checkpointDetails) { dataToRemove.checkpointDetails = {}; }\n if (Object.keys(dataToRemove).length === 0) { dataToRemove = undefined; }\n\n const resMut8 = await mut8({\n src: prevIbGib,\n dataToRemove,\n dataToAddOrPatch: newData,\n // dna: false, // explicitly set to false just to show\n nCounter: true,\n });\n\n if (!!resMut8.intermediateIbGibs) { throw new Error(`(UNEXPECTED) resMut8.intermediateIbGibs truthy? I'm not sure if we expect there to be intermediateIbGibs, but I feel like we shouldn't. Pretty sure we shouldn't, definitely don't *want* them. (E: ba40d55d7c2d36d438c413886f148625)`); }\n if (!!resMut8.dnas) { throw new Error(`(UNEXPECTED) resMut8.dnas truthy? We do not want dnas with keystones. (E: 49470513d018f97d28024f4e82da3b25)`); }\n\n\n const newKeystoneIbGib = resMut8.newIbGib as KeystoneIbGib_V1;\n\n // run validation here\n const errors = await validateKeystoneTransition({\n currentIbGib: newKeystoneIbGib,\n prevIbGib,\n });\n if (errors.length > 0) {\n console.error(`${lc} Validation Failed:\\n${errors.join('\\n')}`);\n throw new Error(`(UNEXPECTED) invalid keystone after we just evolved it? Errors: ${errors.join('; ')} (E: ae2c58406c1db7687879dfb89fc1f825)`);\n }\n\n // save and register\n await metaspace.put({ ibGib: newKeystoneIbGib, space, });\n await metaspace.registerNewIbGib({ ibGib: newKeystoneIbGib, space, });\n\n return newKeystoneIbGib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Creates a new keystone ibgib that has no dna and no past.\n */\nexport async function createKeystoneIbGibImpl({\n data,\n metaspace,\n space,\n}: {\n data: KeystoneData_V1,\n metaspace: MetaspaceService,\n space?: IbGibSpaceAny,\n}): Promise<KeystoneIbGib_V1> {\n const lc = `[${createKeystoneIbGibImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5e32389700e9899e788cbefacef7c825)`); }\n\n space ??= await metaspace.getLocalUserSpace({ lock: false });\n if (!space) { throw new Error(`(UNEXPECTED) space was falsy and we couldn't get default local user space from metaspace? (E: 9a6498cf16a8801f19ec376749742225)`); }\n\n // create the actual keystoneIbGib\n const resFirstGen = await Factory_V1.firstGen({\n parentIbGib: Factory_V1.primitive({ ib: KEYSTONE_ATOM }),\n ib: await getKeystoneIb({ keystoneData: data }),\n data,\n dna: false,\n nCounter: true,\n tjp: {\n timestamp: true,\n uuid: true,\n },\n }) as TransformResult<KeystoneIbGib_V1>;\n const keystoneIbGib = resFirstGen.newIbGib;\n\n if (!keystoneIbGib.data) { throw new Error(`(UNEXPECTED) keystoneIbGib.data falsy? We expect the data to be populated with real keystone data. (E: 38a358facdb89d16d81d48c8520d3d25)`); }\n if (!keystoneIbGib.rel8ns) { throw new Error(`(UNEXPECTED) keystoneIbGib.rel8ns falsy? we expect the rel8ns to have ancestor and past. (E: 20cb7723dc33ae1ef808fe76d1bf4b25)`); }\n if (!keystoneIbGib.rel8ns.past || keystoneIbGib.rel8ns.past.length === 0) {\n throw new Error(`(UNEXPECTED) keystoneIbGib.rel8ns.past falsy or empty? we expect the firstGen call to generate an interstitial ibgib that we will splice out. (E: 0fd8388d045ab9f37834c27d67e78825)`);\n }\n\n // reset n\n keystoneIbGib.data.n = 0;\n // reset tjp\n keystoneIbGib.data.isTjp = true;\n delete keystoneIbGib.rel8ns.tjp;\n // reset past\n delete keystoneIbGib.rel8ns.past;\n\n // recalculate gib\n keystoneIbGib.gib = await getGib({ ibGib: keystoneIbGib });\n\n // save and register\n await metaspace.put({ ibGib: keystoneIbGib, space, });\n await metaspace.registerNewIbGib({ ibGib: keystoneIbGib, space, });\n\n return keystoneIbGib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function validateKeystoneGraph({\n keystoneIbGib,\n dependencyGraph,\n getLatest,\n invalidIfMoreRecentKeystoneFoundInSpace,\n space,\n}: {\n keystoneIbGib: KeystoneIbGib_V1,\n /**\n * set this if you already have a reference to the graph. It is the caller's\n * responsibility to enforce {@link getLatest}.\n */\n dependencyGraph?: FlatIbGibGraph,\n /**\n * if true, then this will get the latest keystone known in the incoming\n * {@link keystoneIbGib} timeline, as found in {@link space}.\n */\n getLatest: boolean,\n invalidIfMoreRecentKeystoneFoundInSpace: boolean,\n space: IbGibSpaceAny,\n}): Promise<string[]> {\n const lc = `[${validateKeystoneGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 22e1ca1d5a08a3f90b7fe9da95df7b26)`); }\n\n // maybe too defensive but...\n if (!keystoneIbGib) { throw new Error(`(UNEXPECTED) keystoneIbGib falsy? (E: 26482871d529fff6e8899c5d8a6c3826)`); }\n\n const errors: string[] = [];\n\n // first, get the latest if that is the case...\n if (getLatest) {\n const keystoneAddr = getIbGibAddr({ ibGib: keystoneIbGib });\n const resGetLatestAddrs = await getLatestAddrs({\n ibGibs: [keystoneIbGib],\n space,\n });\n if (!resGetLatestAddrs.data) { throw new Error(`(UNEXPECTED) resGetLatestAddrs.data falsy? (E: 3a23b3b420a8da1928219ca8d47b2126)`); }\n if (!resGetLatestAddrs.data.latestAddrsMap) { throw new Error(`(UNEXPECTED) resGetLatestAddrs.data.latestAddrsMap falsy? (E: 93f1180598fb65a4b8d36e08d6c50426)`); }\n\n const { latestAddrsMap } = resGetLatestAddrs.data;\n if (Object.keys(latestAddrsMap).length === 0) {\n throw new Error(`(UNEXPECTED) latestAddrsMap truthy but empty? (E: 7142f8f7625b9186281d08251e407826)`);\n }\n\n const latestAddr = latestAddrsMap[keystoneAddr];\n if (latestAddr) {\n if (latestAddr !== keystoneAddr) {\n if (invalidIfMoreRecentKeystoneFoundInSpace) {\n errors.push(`${lc} more recent keystone (${latestAddr}) found than the one passed in (${keystoneAddr}) in space (${space.ib}). (E: 64bf48de9448ee5c7528bf03bed2a826)`);\n } else {\n // get the latest ibgib and point the incoming ref to that\n const [latestKeystoneIbGib] = await getIbGibsFromCache_fallbackToSpaces({\n addrs: [latestAddr],\n space,\n });\n keystoneIbGib = latestKeystoneIbGib as KeystoneIbGib_V1;\n }\n } else {\n // the incoming ibgib **is** the latest keystone, so nothing more to be done.\n if (logalot) { console.log(`${lc} incoming keystone (${keystoneAddr}) is the latest in the space (${space.ib}) (I: 8ffbd8d6cbc8a461e5e7f1084bd22a26)`); }\n }\n } else {\n // keystone not found in space?\n console.warn(`${lc} keystoneIbGib (${keystoneAddr}) not found in space (${space.ib}). I don't know what the implications of this are. (W: 258c88742448db34a585669484771826)`)\n }\n }\n\n dependencyGraph ??= await getDependencyGraph({\n ibGib: keystoneIbGib,\n space,\n });\n\n const depIbGibs = Object.values(dependencyGraph);\n const { mapWithTjp_NoDna, mapWithTjp_YesDna, mapWithoutTjps, } =\n splitPerTjpAndOrDna({ ibGibs: depIbGibs });\n\n\n // there should be no DNA\n if (Object.keys(mapWithTjp_YesDna).length > 0) {\n errors.push(`${lc} DNA found. Keystones should NOT have DNA. (E: a3ec7827c4284cdea61c2372c0615826)`);\n }\n\n // is there a tjp? I think there is, so mapWithoutTjps should also be\n // empty\n if (Object.keys(mapWithoutTjps).length > 0) {\n errors.push(`${lc} Non-tjp ibgibs found? Keystones are expected to have tjps. (E: a3ec7827c4284cdea61c2372c0615826)`);\n }\n\n if (Object.keys(mapWithTjp_NoDna).length > 0) {\n // happy path here. These should be the keystone ibgibs. we will put\n // them in order, then do validation on the transitions. We will\n // also check other graph-scoped integrity of keystones (like do\n // certain properties match among ALL keystones, etc.)\n\n const keystoneIbGibs_unordered = Object.values(mapWithTjp_NoDna);\n\n const orderedKeystonesMap = getTimelinesGroupedByTjp({ ibGibs: keystoneIbGibs_unordered });\n const keys = Object.keys(orderedKeystonesMap);\n if (keys.length === 0) {\n throw new Error(`(UNEXPECTED) orderedKeystonesMap empty? (E: d437b80bef58e83a034b28af46278726)`);\n } else if (keys.length > 1) {\n // keys.length > 1\n throw new Error(`(UNEXPECTED) more than one timeline in keystone graph? ATOW (02/19/2026) we are expecting only a single timeline. (E: 66085b14e3887a59c872afd240511f26)`);\n }\n // happy path: exactly one timeline\n const keystoneTjpAddr = keys[0];\n const keystoneIbGibs_ordered = orderedKeystonesMap[keystoneTjpAddr] as KeystoneIbGib_V1[];\n\n if (keystoneIbGibs_ordered.length === 0) { throw new Error(`(UNEXPECTED) empty keystoneIbGibs_ordered? (E: 4a6b085aa8a76828a8d65367e7e56526)`); }\n\n const genesisErrors = await validateGenesisKeystone({\n keystoneIbGib: keystoneIbGibs_ordered[0]\n });\n genesisErrors.forEach(x => errors.push(x));\n\n if (keystoneIbGibs_ordered.length === 1) {\n // only the genesis keystone, which has already been done.\n } else {\n // more than 1 keystone, so validate the transitions\n for (let i = 0; i < keystoneIbGibs_ordered.length - 1; i++) {\n const prevIbGib = keystoneIbGibs_ordered[i];\n const currentIbGib = keystoneIbGibs_ordered[i + 1];\n const transitionErrors = await validateKeystoneTransition({\n prevIbGib, currentIbGib\n });\n if (transitionErrors.length > 0) {\n errors.push(`${lc} keystone has ${transitionErrors.length} transition errors. i: ${i}. prevIbGib addr: ${getIbGibAddr({ ibGib: prevIbGib })}. currentIbGib addr: ${getIbGibAddr({ ibGib: currentIbGib })}. (E: 3ac17be916141d0c286ca5a87bb1b426)`);\n transitionErrors.forEach(x => errors.push(x));\n }\n\n break; // stop after the first found transition error\n }\n }\n } else {\n // one of the other errors regarding mapWithTjp_YesDna or\n // mapWithoutTjps will exist at this point, so we don't need to add\n // any more errors.\n if (errors.length === 0) { throw new Error(`(UNEXPECTED) mapWithTjp_NoDna empty (which is an error) but errors.length === 0? If we get here, we expect one of the other errors to have been populated. (E: 7bca2866b6f8fca318923de8c88e8826)`); }\n }\n\n return errors;\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n", "import { extractErrorMsg, mergeMapsOrArrays_Naive } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';\nimport {\n KeystoneData_V1, KeystoneIbGib_V1, KeystonePoolConfig, KeystoneClaim,\n KeystoneChallengePool, KeystoneReplenishStrategy, KeystoneRevocationInfo,\n} from './keystone-types.mjs';\nimport { KeystoneStrategyFactory } from './strategy/keystone-strategy-factory.mjs';\nimport { POOL_ID_REVOKE, KEYSTONE_VERB_REVOKE, KEYSTONE_VERB_MANAGE, KEYSTONE_CHECKPOINT_FREQUENCY } from './keystone-constants.mjs';\nimport {\n addToBindingMap, createKeystoneIbGibImpl, evolvePersistAndRegisterKeystone,\n generateOpaqueChallengeId, resolveTargetPool, selectChallengeIds,\n solveAndReplenish, validateKeystoneTransition,\n validateGenesisKeystone, validateKeystoneGraph\n} from './keystone-helpers.mjs';\nimport { IbGibSpaceAny } from '../witness/space/space-base-v1.mjs';\nimport { MetaspaceService } from '../witness/space/metaspace/metaspace-types.mjs';\nimport { FlatIbGibGraph } from '../common/other/graph-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Facade for managing Keystone Identities.\n *\n * Handles Genesis, Authorized Evolution (Signing), and Validation.\n */\nexport class KeystoneService_V1 {\n protected lc: string = `[${KeystoneService_V1.name}]`;\n\n /**\n * Creates a brand new Keystone Identity Timeline.\n */\n async genesis({\n masterSecret,\n frameDetails,\n configs,\n metaspace,\n space,\n }: {\n masterSecret: string;\n frameDetails?: any;\n configs: KeystonePoolConfig[];\n metaspace: MetaspaceService;\n space: IbGibSpaceAny;\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.genesis.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: c98ae8adbc5888dbf84c5aced7610b25)`); }\n\n const challengePools: KeystoneChallengePool[] = [];\n\n for (const config of configs) {\n const strategy = KeystoneStrategyFactory.create({ config });\n const poolSecret = await strategy.derivePoolSecret({ masterSecret });\n const challenges: { [id: string]: any } = {};\n const bindingMap: { [char: string]: string[] } = {};\n\n const targetSize = config.behavior.size;\n const timestamp = Date.now().toString();\n\n for (let i = 0; i < targetSize; i++) {\n const challengeId = await generateOpaqueChallengeId({\n salt: config.salt, timestamp, index: i\n });\n\n const solution = await strategy.generateSolution({\n poolSecret, poolId: config.id, challengeId,\n });\n const challenge = await strategy.generateChallenge({ solution });\n challenges[challengeId] = challenge;\n\n // Populate Binding Map\n addToBindingMap(bindingMap, challengeId);\n }\n\n challengePools.push({\n id: config.id,\n config,\n challenges,\n bindingMap\n });\n }\n\n if (challengePools.length === 0) { throw new Error(`No challenge pools created. (E: 38e538530996940e1f16a8b199995825)`); }\n\n const data: KeystoneData_V1 = { challengePools, proofs: [] };\n if (frameDetails) { data.frameDetails = frameDetails; }\n const keystoneIbGib = await createKeystoneIbGibImpl({ data, metaspace, space });\n return keystoneIbGib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Signs a claim by solving challenges from a specific pool and evolving the Keystone timeline.\n *\n * Uses a hybrid selection strategy: Mandatory IDs (Alice) + Sequential (FIFO) + Random (Stochastic).\n *\n * Supports Delegation via `poolFilter` to find specific foreign pools.\n *\n * todo: wrap this and other entire keystone sign/method implementations in locks on the keystone's tjpGib.\n */\n async sign({\n latestKeystone,\n masterSecret,\n claim,\n poolId,\n poolFilter,\n requiredChallengeIds = [],\n frameDetails,\n metaspace,\n space,\n }: {\n latestKeystone: KeystoneIbGib_V1;\n /**\n * The secret used to solve the challenges.\n * If signing with a native pool, this is the User's Master Secret.\n * If signing with a foreign/delegated pool, this is the Delegate's Secret.\n */\n masterSecret: string;\n claim: Partial<KeystoneClaim>;\n /**\n * Explicit ID of the pool to use.\n */\n poolId?: string;\n /**\n * Optional predicate to find a pool.\n * Useful for finding delegates via metadata without knowing the exact ID.\n * e.g. (p) => p.metadata?.delegate === 'Bob'\n */\n poolFilter?: (pool: KeystoneChallengePool) => boolean;\n requiredChallengeIds?: string[];\n frameDetails?: any;\n metaspace: MetaspaceService;\n space: IbGibSpaceAny;\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.sign.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const prevData = latestKeystone.data!;\n\n if (prevData.revocationInfo) { throw new Error(`Keystone has been revoked. Cannot sign. (E: 4f2198c39116d15c48ba191940316825)`); }\n\n // 1. Identify Authority (Resolve Pool)\n const pool = resolveTargetPool({\n pools: prevData.challengePools,\n poolId,\n poolFilter,\n verb: claim.verb\n });\n\n if (logalot) { console.log(`${lc} Selected pool: ${pool.id} (size: ${Object.keys(pool.challenges).length}) (I: 6b26d6f4aad18380f2b3a0989b592826)`); }\n\n // 2. Calculate Costs (Select IDs)\n const idsToSolve = selectChallengeIds({\n pool,\n targetAddr: claim.target,\n requiredChallengeIds\n });\n\n // 3. Pay the Cost (Solve & Replenish)\n // This helper handles the Strategy creation, Secret derivation, Solving,\n // and the calculation of the Next state for ALL pools.\n const { proof, nextPools } = await solveAndReplenish({\n targetPoolId: pool.id,\n prevPools: prevData.challengePools,\n masterSecret,\n challengeIds: idsToSolve,\n claim,\n requiredChallengeIds\n });\n\n // 4. Construct New Data\n const n = (prevData.n ?? 0) + 1;\n let checkpointDetails: any | undefined;\n if (n % KEYSTONE_CHECKPOINT_FREQUENCY === 0) {\n // Generate a temporary view of the keystone as it would be in this frame\n // to calculate the aggregated state.\n const currentFrameView: KeystoneIbGib_V1 = {\n ...latestKeystone,\n data: { ...prevData, frameDetails }\n };\n checkpointDetails = await this.getAggregateDetails({\n latestKeystone: currentFrameView,\n metaspace,\n space\n });\n }\n\n const newData: KeystoneData_V1 = {\n challengePools: nextPools,\n proofs: [proof],\n frameDetails,\n checkpointDetails,\n };\n\n // 5. Commit (Evolve, Persist, Register)\n const resKeystone = await evolvePersistAndRegisterKeystone({\n prevIbGib: latestKeystone,\n newData,\n metaspace,\n space\n });\n\n return resKeystone;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Validates a keystone.\n *\n * ## NOTES\n *\n * Atow (12/22/2025) this only validates the transition from Prev -> Curr.\n *\n * @returns Array of validation error strings. Empty array means Valid.\n *\n * @see {@link validateKeystoneTransition}\n */\n async validate({\n currentIbGib,\n prevIbGib,\n }: {\n currentIbGib: KeystoneIbGib_V1;\n prevIbGib: KeystoneIbGib_V1;\n }): Promise<string[]> {\n // todo: change this to validate the entire keystone graph. the next\n // step is to walk the history and validate each transition.\n const errors = await validateKeystoneTransition({ currentIbGib, prevIbGib });\n return errors;\n }\n\n /**\n * Validates a genesis keystone.\n *\n * @returns Array of validation error strings. Empty array means Valid.\n */\n async validateGenesisKeystone({\n keystoneIbGib,\n }: {\n keystoneIbGib: KeystoneIbGib_V1;\n }): Promise<string[]> {\n return await validateGenesisKeystone({ keystoneIbGib });\n }\n\n /**\n * Retrieves the latest keystone frame for the given address.\n * \n * Uses `metaspace.getLatestAddr` to find the actual tip instead of trusting\n * an incoming payload's `past` rel8n.\n * \n * @see `ibgib-get-pattern` SKILL.md\n */\n async getLatestKeystone({\n addr,\n metaspace,\n space,\n }: {\n addr: string;\n metaspace: MetaspaceService;\n space: IbGibSpaceAny;\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.getLatestKeystone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n \n const latestAddr = await metaspace.getLatestAddr({ tjpAddr: addr, space });\n if (!latestAddr) {\n throw new Error(`could not find latest addr for ${addr}`);\n }\n\n const resGet = await metaspace.get({ addr: latestAddr, space });\n if (resGet.success && resGet.ibGibs && resGet.ibGibs.length > 0) {\n return resGet.ibGibs[0] as KeystoneIbGib_V1;\n } else {\n const resIbGib = resGet.rawResultIbGib as any;\n const addrsNotFound = resIbGib?.data?.addrsNotFound ?? 'unknown';\n throw new Error(`couldn't find latest keystone at ${latestAddr}. addrsNotFound: ${addrsNotFound}? resGet.errorMsg: ${resGet.errorMsg}`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Validates an entire keystone graph from tip to genesis.\n *\n * @returns Array of validation error strings. Empty array means Valid.\n */\n async validateKeystoneGraph({\n keystoneIbGib,\n dependencyGraph,\n getLatest,\n invalidIfMoreRecentKeystoneFoundInSpace,\n space,\n }: {\n keystoneIbGib: KeystoneIbGib_V1,\n /**\n * set this if you already have a reference to the graph. It is the caller's\n * responsibility to enforce {@link getLatest}.\n */\n dependencyGraph?: FlatIbGibGraph,\n /**\n * if true, then this will get the latest keystone known in the incoming\n * {@link keystoneIbGib} timeline, as found in {@link space}.\n */\n getLatest: boolean,\n invalidIfMoreRecentKeystoneFoundInSpace: boolean,\n space: IbGibSpaceAny,\n }): Promise<string[]> {\n const lc = `${this.lc}[${this.validateKeystoneGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 01c5cd455038c270cbf1effc1704af26)`); }\n\n return await validateKeystoneGraph({\n keystoneIbGib,\n dependencyGraph,\n getLatest,\n invalidIfMoreRecentKeystoneFoundInSpace,\n space\n });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Permanently revokes the Identity.\n *\n * Logic:\n * 1. Locates the 'revoke' pool.\n * 2. Solves required challenges to prove ownership.\n * 3. Wipes the pool (via the delete all strategy in solveAndReplenish).\n * 4. Sets the revocationInfo on the new frame.\n */\n async revoke({\n latestKeystone,\n masterSecret,\n reason = \"User initiated revocation\",\n frameDetails,\n metaspace,\n space,\n }: {\n latestKeystone: KeystoneIbGib_V1;\n masterSecret: string;\n reason?: string;\n frameDetails?: any;\n metaspace: MetaspaceService;\n space: IbGibSpaceAny;\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.revoke.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const prevData = latestKeystone.data!;\n\n // 1. Identify Authority (Resolve Revoke Pool)\n const pool = resolveTargetPool({\n pools: prevData.challengePools,\n poolId: POOL_ID_REVOKE // Explicitly require the special revoke pool\n });\n\n // 2. Construct Claim\n const claim: Partial<KeystoneClaim> = {\n verb: KEYSTONE_VERB_REVOKE,\n target: getIbGibAddr({ ibGib: latestKeystone })\n };\n\n // 3. Calculate Costs\n const idsToSolve = selectChallengeIds({\n pool,\n targetAddr: claim.target,\n requiredChallengeIds: []\n });\n\n if (idsToSolve.length === 0) { throw new Error(`Revocation policy selected 0 challenges? Check config for pool ${pool.id}. Revocation requires proof. (E: 97e5a8356d241ae7b882db791cb1f825)`); }\n\n // 4. Pay the Cost & Scorched Earth\n // The revoke pool config should have 'replenishStrategy:\n // KeystoneReplenishStrategy.deleteAll', causing solveAndReplenish\n // to return an empty pool in nextPools.\n const { proof, nextPools } = await solveAndReplenish({\n targetPoolId: pool.id,\n prevPools: prevData.challengePools,\n masterSecret,\n challengeIds: idsToSolve,\n claim,\n requiredChallengeIds: []\n });\n // warn if nextPools contains pool.id that isn't empty (we were\n // supposed to do \"scorched earth\" which empties the pool)\n if (nextPools.find(p => p.id === pool.id && Object.keys(p.challenges).length > 0)) {\n console.warn(`${lc} revocation pool ${pool.id} is not empty after revocation. Is the revocation pool replenish strategy set to ${KeystoneReplenishStrategy.deleteAll}? (W: 300c28bc8b98fc3e3c0b0d988344f825)`);\n }\n\n // 5. Construct Revocation Info\n const revocationInfo: KeystoneRevocationInfo = { reason, proof };\n\n // 6. Construct New Data\n const n = (prevData.n ?? 0) + 1;\n let checkpointDetails: any | undefined;\n if (n % KEYSTONE_CHECKPOINT_FREQUENCY === 0) {\n const currentFrameView: KeystoneIbGib_V1 = {\n ...latestKeystone,\n data: { ...prevData, frameDetails, revocationInfo }\n };\n checkpointDetails = await this.getAggregateDetails({\n latestKeystone: currentFrameView,\n metaspace,\n space\n });\n }\n\n const newData: KeystoneData_V1 = {\n challengePools: nextPools,\n proofs: [proof],\n revocationInfo,\n frameDetails,\n checkpointDetails,\n };\n\n // 7. Commit\n const newKeystone = await evolvePersistAndRegisterKeystone({\n prevIbGib: latestKeystone,\n newData,\n metaspace,\n space\n });\n\n return newKeystone;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Structural evolution: Adds new challenge pools to the keystone.\n *\n * Use Case: Adding a delegate (Server) for SSO, adding a recovery key,\n * or rotating to a new set of pools.\n *\n * Requires the Master Secret to authorize the change via a pool containing\n * the 'manage' verb.\n */\n async addPools({\n latestKeystone,\n masterSecret,\n newPools,\n metaspace,\n space,\n }: {\n latestKeystone: KeystoneIbGib_V1;\n /**\n * Alice's Master Secret.\n * Required to solve challenges from the Admin/Manage pool to authorize this change.\n */\n masterSecret: string;\n /**\n * The pools to add.\n * NOTE: These are fully constructed Pool objects.\n * If they are foreign (Bob's), Alice must have constructed them\n * using Bob's challenges + Her config restrictions + isForeign=true.\n */\n newPools: KeystoneChallengePool[];\n metaspace: MetaspaceService;\n space: IbGibSpaceAny;\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.addPools.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!latestKeystone.data) { throw new Error(`(UNEXPECTED) latestKeystone.data falsy? (E: 7334c8faed128166a999d428c7805b25)`); }\n const prevData = latestKeystone.data;\n\n if (prevData.revocationInfo) { throw new Error(`Keystone has been revoked. Cannot add pools. (E: 8599f8f51c78d722252ddb2894fdbe25)`); }\n\n if (newPools.length === 0) { throw new Error(`No new pools provided to add. (E: 6599f8f51c78d722252ddb2894fdbe25)`); }\n\n // 1. Identify Authority (Resolve Admin Pool)\n // We need a pool that allows the 'manage' verb.\n const adminPool = resolveTargetPool({\n pools: prevData.challengePools,\n verb: KEYSTONE_VERB_MANAGE,\n });\n\n if (logalot) { console.log(`${lc} Authorized via pool: ${adminPool.id}`); }\n\n // 2. Construct the Management Claim\n const target = getIbGibAddr({ ibGib: latestKeystone });\n const claim: Partial<KeystoneClaim> = {\n verb: KEYSTONE_VERB_MANAGE,\n target, // I am managing myself\n // Scope creates a cryptographic commitment to WHICH pools are being added\n scope: JSON.stringify({ add: newPools.map(p => p.id) })\n };\n\n // 3. Calculate Costs\n const idsToSolve = selectChallengeIds({\n pool: adminPool,\n targetAddr: target\n });\n\n // 4. Pay the Cost (Solve & Replenish)\n // This authorizes the change by evolving the admin pool.\n const { proof, nextPools: replenishedExistingPools } = await solveAndReplenish({\n targetPoolId: adminPool.id,\n prevPools: prevData.challengePools,\n masterSecret,\n challengeIds: idsToSolve,\n claim,\n });\n\n // 5. Mutate Structure (Add the new pools)\n // We verify ID uniqueness cheaply here to prevent blatant errors\n const existingIds = new Set(replenishedExistingPools.map(p => p.id));\n for (const newPool of newPools) {\n if (existingIds.has(newPool.id)) {\n throw new Error(`Cannot add pool. ID collision: ${newPool.id} (E: 8a4c2b1d3e5f6a7b8c9d0e1f2a3b4c5d)`);\n }\n }\n\n const finalPools = [...replenishedExistingPools, ...newPools];\n\n // 6. Construct New Data\n const n = (prevData.n ?? 0) + 1;\n let checkpointDetails: any | undefined;\n if (n % KEYSTONE_CHECKPOINT_FREQUENCY === 0) {\n const currentFrameView: KeystoneIbGib_V1 = {\n ...latestKeystone,\n data: { ...prevData, challengePools: finalPools }\n };\n checkpointDetails = await this.getAggregateDetails({\n latestKeystone: currentFrameView,\n metaspace,\n space\n });\n }\n\n const newData: KeystoneData_V1 = {\n challengePools: finalPools,\n proofs: [proof], // The proof authorizes the structure change\n checkpointDetails,\n };\n\n // 7. Commit\n const newKeystone = await evolvePersistAndRegisterKeystone({\n prevIbGib: latestKeystone,\n newData,\n metaspace,\n space\n });\n\n return newKeystone;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Consolidates the state of a Keystone identity across its history.\n * Walks back until it hits a checkpoint or genesis.\n */\n async getAggregateDetails({\n latestKeystone,\n metaspace,\n space,\n }: {\n latestKeystone: KeystoneIbGib_V1;\n metaspace: MetaspaceService;\n space?: IbGibSpaceAny;\n }): Promise<any> {\n const lc = `${this.lc}[${this.getAggregateDetails.name}]`;\n try {\n let aggregated: any = {};\n let current = latestKeystone;\n\n while (current) {\n const data = current.data!;\n\n // 1. If we hit a checkpoint, merge it and STOP.\n if (data.checkpointDetails) {\n aggregated = mergeMapsOrArrays_Naive({\n dominant: aggregated,\n recessive: data.checkpointDetails\n });\n break;\n }\n\n // 2. Merge this frame's details\n if (data.frameDetails) {\n aggregated = mergeMapsOrArrays_Naive({\n dominant: aggregated,\n recessive: data.frameDetails\n });\n }\n\n // 3. Genesis check (n=0)\n if (data.n === 0) { break; }\n\n // 4. Walk back\n const past = current.rel8ns?.past;\n const prevAddr = (past && past.length > 0) ? past[past.length - 1] : undefined;\n if (!prevAddr) { break; }\n\n const res = await metaspace.get({ addr: prevAddr, space });\n if (!res.success || !res.ibGibs || res.ibGibs.length === 0) {\n throw new Error(`Could not find previous keystone frame at ${prevAddr} (E: e3d069b22e11e550e58844889ddb5325)`);\n }\n current = res.ibGibs[0] as KeystoneIbGib_V1;\n }\n\n return aggregated;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n }\n}\n", "import { extractErrorMsg, HashAlgorithm } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';\nimport {\n KeystonePoolConfig, KeystonePoolConfig_HashV1, KeystonePoolBehavior,\n KeystoneReplenishStrategy, KeystonePoolConfigBase, KeystoneChallengeType,\n} from './keystone-types.mjs';\nimport { POOL_ID_REVOKE, KEYSTONE_VERB_REVOKE, KEYSTONE_CONFIG_DEFAULT_SIZE, KEYSTONE_CONFIG_DEFAULT_BINDING, KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY, KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL, KEYSTONE_CONFIG_DEFAULT_RANDOM, KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY, KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL_HIGHSECURITY, KEYSTONE_CONFIG_DEFAULT_RANDOM_HIGHSECURITY, KEYSTONE_CONFIG_DEFAULT_BINDING_HIGHSECURITY, KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY_HIGHSECURITY, KeystoneVerb, KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM, KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS, KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM_HIGHSECURITY, KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS_HIGHSECURITY } from './keystone-constants.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Abstract Base Builder.\n * Handles configuration common to ALL strategies (Salt, Size, Replenishment, Selection).\n *\n * @template TConfig The concrete config type being built.\n */\nexport abstract class KeystoneConfigBuilderBase<TConfig extends KeystonePoolConfigBase> {\n protected _id: string | undefined;\n protected _salt: string | undefined;\n protected _size: number | undefined;\n protected _replenish: KeystoneReplenishStrategy | undefined;\n protected _seq: number | undefined;\n protected _rand: number | undefined;\n protected _verbs: string[] = [];\n protected _targetBinding: number | undefined;\n\n /**\n * Sets the unique id for this pool.\n */\n withId(id: string): this {\n this._id = id;\n return this;\n }\n\n /**\n * Sets the unique salt for this pool.\n */\n withSalt(salt: string): this {\n this._salt = salt;\n return this;\n }\n\n /**\n * Sets the total number of challenges to maintain in the pool.\n */\n withSize(size: number): this {\n this._size = size;\n return this;\n }\n\n /**\n * Binds challenge selection to the content address of the target.\n * @param chars Number of hex characters to match (e.g. 4).\n */\n withTargetBinding(chars: number): this {\n this._targetBinding = chars;\n return this;\n }\n\n /**\n * Configures the pool to use strictly Sequential (FIFO) selection.\n * @param count Number of challenges to consume per sign.\n */\n withFIFO(count: number): this {\n this._seq = count;\n this._rand = 0;\n return this;\n }\n\n /**\n * Configures the pool to use strictly Random selection.\n * @param count Number of challenges to consume per sign.\n */\n withRandom(count: number): this {\n this._seq = 0;\n this._rand = count;\n return this;\n }\n\n /**\n * Configures the pool to use Hybrid (Both FIFO and Random) selection.\n */\n withHybrid({ seqCount, randCount }: { seqCount: number, randCount: number }): this {\n this._seq = seqCount;\n this._rand = randCount;\n return this;\n }\n\n /**\n * Sets the replenishment strategy.\n */\n withReplenishStrategy(strategy: KeystoneReplenishStrategy): this {\n this._replenish = strategy;\n return this;\n }\n\n /**\n * Constructs the behavioral config object.\n * Helper for subclasses.\n */\n protected buildBehavior(): KeystonePoolBehavior {\n if (this._size === undefined) { throw new Error(`size required (E: 68320865d9adb8477836485b20b08826)`); }\n if (this._replenish === undefined) { throw new Error(`replenish strategy required (E: 9f8798d1a568763a282e53c89185b826)`); }\n if (this._seq === undefined) { throw new Error(`sequential required (E: e0da08a24e9790d0a8c1a9322f8eb826)`); }\n if (this._rand === undefined) { throw new Error(`selectRandomly required (E: 7721d84d1a8b7d020d0ab33c3f811426)`); }\n if (this._targetBinding === undefined) { throw new Error(`targetBinding required (E: 9add64d7e8e8cba01d901727a8e9b826)`); }\n return {\n size: this._size,\n replenish: this._replenish,\n selectSequentially: this._seq,\n selectRandomly: this._rand,\n targetBindingChars: this._targetBinding,\n };\n }\n\n /**\n * Restricts this pool to specific verbs.\n * @param verbs List of verb addresses (e.g. 'revoke^gib')\n */\n forVerbs(verbs: string[]): this {\n this._verbs = verbs;\n return this;\n }\n\n // protected buildBase(): KeystonePoolConfigBase {\n // // Helper to keep the concrete build() clean\n // return {\n // type: KeystoneChallengeType.hash_reveal_v1, // This is overridden by concrete/interface usually, but needed for base shape\n // salt: this._salt,\n // allowedVerbs: this._verbs\n // } as any;\n // }\n\n abstract build(): TConfig;\n}\n\n/**\n * Concrete Builder for Hash-Reveal V1 Strategy.\n */\nexport class KeystoneConfigBuilder_HashV1 extends KeystoneConfigBuilderBase<KeystonePoolConfig_HashV1> {\n protected lc: string = `[${KeystoneConfigBuilder_HashV1}]`;\n private _algo: HashAlgorithm | undefined;\n private _rounds: number | undefined;\n\n /**\n * Sets the hashing strength.\n */\n withHash({ algo, rounds }: { algo: HashAlgorithm, rounds: number }): this {\n const lc = `${this.lc}[${this.withHash.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 15d1b3bd2e98bba33fc6c78228755826)`); }\n\n this._algo = algo;\n this._rounds = rounds;\n return this;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n build(): KeystonePoolConfig_HashV1 {\n const lc = `${this.lc}[${this.build.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5df568c63c4993bb98df0a319ee16826)`); }\n\n if (!this._id) { throw new Error(`id required (E: b50d082adf38bcbf463552f80d2c3226)`); }\n if (!this._salt) { throw new Error(`salt required (E: b0f1926657b8d7d3a88fb9385ead5826)`); }\n if (!this._algo) { throw new Error(`algorithm required (E: cff228f9898fd6383ef752088dae6826)`); }\n if (this._rounds === undefined) { throw new Error(`rounds required (E: eb72580f3b014cda18cba3e399683c26)`); }\n\n const result: KeystonePoolConfig_HashV1 = {\n id: this._id,\n type: KeystoneChallengeType.hash_reveal_v1,\n salt: this._salt,\n allowedVerbs: this._verbs,\n behavior: this.buildBehavior(),\n algo: this._algo,\n rounds: this._rounds,\n };\n\n return result;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n\n// ===========================================================================\n// STATIC ENTRY POINT (Optional Convenience)\n// ===========================================================================\n\nexport class KeystoneConfig {\n static hash(): KeystoneConfigBuilder_HashV1 {\n return new KeystoneConfigBuilder_HashV1();\n }\n\n // Future:\n // static pow(): KeystoneConfigBuilder_PoW { ... }\n}\n\n// ===========================================================================\n// FACTORY FUNCTIONS (Presets)\n// ===========================================================================\n\ninterface KeystoneConfigFactoryOptions_Standard {\n /**\n * id for pool that this config pertains to\n */\n id: string;\n /**\n * should be a unique string\n */\n salt: string;\n /**\n * number of challenges in the pool\n * @see {@link KeystonePoolConfig}\n */\n size?: number;\n /**\n * number of sequential challenges required for solution per action\n */\n sequential?: number;\n /**\n * number of random challenges required for solution per action\n */\n random?: number;\n /**\n * number of target binding characters required for solution per action\n * @see {@link KeystonePoolBehavior.targetBindingChars}\n */\n targetBinding?: number;\n /**\n * @see {@link KeystonePoolBehavior.replenish}\n */\n replenishStrategy?: KeystoneReplenishStrategy;\n /**\n * verbs for the pool\n */\n verbs?: string[];\n\n // only hash challenge type currently implemented\n type?: KeystoneChallengeType,\n hashAlgorithm?: HashAlgorithm;\n hashRounds?: number;\n}\n\nexport function createStandardPoolConfig(opts: KeystoneConfigFactoryOptions_Standard): KeystonePoolConfig {\n if (opts.type && opts.type !== KeystoneChallengeType.hash_reveal_v1) {\n throw new Error(`invalid type (${opts.type}). Only ${KeystoneChallengeType.hash_reveal_v1} currently implemented. (E: c38616cd7a459149f670418f88766526)`);\n }\n\n const {\n salt, id, size, sequential, random, targetBinding, replenishStrategy,\n verbs, hashAlgorithm, hashRounds,\n } = opts;\n\n return KeystoneConfig.hash()\n .withId(id)\n .withSalt(salt)\n .withSize(size ?? KEYSTONE_CONFIG_DEFAULT_SIZE)\n .withHybrid({\n seqCount: sequential ?? KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL,\n randCount: random ?? KEYSTONE_CONFIG_DEFAULT_RANDOM,\n })\n .withTargetBinding(targetBinding ?? KEYSTONE_CONFIG_DEFAULT_BINDING)\n .withReplenishStrategy(replenishStrategy ?? KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY)\n .withHash({\n algo: hashAlgorithm ?? KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM,\n rounds: hashRounds ?? KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS\n })\n .forVerbs(verbs ?? [])\n .build();\n}\n\nexport function createHighSecurityPoolConfig(opts: KeystoneConfigFactoryOptions_Standard): KeystonePoolConfig {\n if (opts.type && opts.type !== KeystoneChallengeType.hash_reveal_v1) {\n throw new Error(`invalid type (${opts.type}). Only ${KeystoneChallengeType.hash_reveal_v1} currently implemented. (E: 09c1f7772bd2a7910f5562b4934d3826)`);\n }\n const {\n salt, id, size, sequential, random, targetBinding, replenishStrategy,\n verbs, hashAlgorithm, hashRounds,\n } = opts;\n return KeystoneConfig.hash()\n .withId(id)\n .withSalt(salt)\n .withSize(size ?? KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY)\n .withHybrid({\n seqCount: sequential ?? KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL_HIGHSECURITY,\n randCount: random ?? KEYSTONE_CONFIG_DEFAULT_RANDOM_HIGHSECURITY,\n })\n .withTargetBinding(targetBinding ?? KEYSTONE_CONFIG_DEFAULT_BINDING_HIGHSECURITY)\n .withReplenishStrategy(replenishStrategy ?? KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY_HIGHSECURITY)\n .withHash({\n algo: hashAlgorithm ?? KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM_HIGHSECURITY,\n rounds: hashRounds ?? KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS_HIGHSECURITY\n })\n .forVerbs(verbs ?? [])\n .build();\n}\n\nexport function createManagePoolConfig(opts: KeystoneConfigFactoryOptions_Standard): KeystonePoolConfig {\n return createHighSecurityPoolConfig({\n ...opts,\n verbs: [KeystoneVerb.MANAGE],\n });\n}\n\nexport function createRevocationPoolConfig(opts: KeystoneConfigFactoryOptions_Standard): KeystonePoolConfig {\n return createHighSecurityPoolConfig({\n ...opts,\n verbs: [KeystoneVerb.REVOKE],\n replenishStrategy: KeystoneReplenishStrategy.deleteAll,\n });\n}\n", "/**\n * @module common/keystone-policies\n *\n * Centralized identity and security policies for the space-gib application.\n * Defines standard configurations for both persistent (Domain) and ephemeral (Session) keystones.\n *\n * ## important\n *\n * This file is part of the `src/common` layer. It MUST NEVER import from\n * `src/client` or `src/server`.\n */\n\nimport { HashAlgorithm } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport {\n KeystoneReplenishStrategy,\n KeystoneChallengeType,\n KeystoneIbGib_V1,\n KeystoneSolution\n} from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';\nimport { KeystoneStrategyFactory } from '@ibgib/core-gib/dist/keystone/strategy/keystone-strategy-factory.mjs';\n\n// ---------------------------------------------------------------------------\n// 1. Session Keystone (S) Policies\n// ---------------------------------------------------------------------------\n\n/**\n * Default configurations for short-lived session keystones (S^Stjp).\n * These values match the real-world usage in the space-gib client.\n */\nexport const SESSION_KEYSTONE_POLICY = {\n /**\n * Shared parameters across all session pools\n */\n COMMON: {\n ALGO: HashAlgorithm.sha_256,\n TYPE: KeystoneChallengeType.hash_reveal_v1,\n ROUNDS: 2,\n REPLENISH: KeystoneReplenishStrategy.topUp,\n },\n\n /**\n * The primary authorization pool for sync actions (e.g. putting/getting ibgibs).\n */\n DEFAULT_POOL: {\n ID: 'default',\n SIZE: 20,\n SELECT_SEQUENTIALLY: 2,\n SELECT_RANDOMLY: 2,\n /**\n * We want more for this, with future implementations we will not have\n * resource exhaustion.\n */\n TARGET_BINDING_CHARS: 3,\n },\n\n /**\n * Dedicated pool for the WebSocket sync protocol handshake.\n */\n HANDSHAKE_POOL: {\n ID: 'handshake',\n VERB: 'handshake',\n SIZE: 10,\n SELECT_SEQUENTIALLY: 2,\n SELECT_RANDOMLY: 2,\n TARGET_BINDING_CHARS: 0,\n /** Number of IDs the server should demand during the handshake. */\n SERVER_DEMAND_COUNT: 3,\n }\n} as const;\n\n\n// ---------------------------------------------------------------------------\n// 2. Domain/Identity Keystone (I) Policies\n// ---------------------------------------------------------------------------\n\n/**\n * Server-side minimum requirements for long-lived primary identity keystones.\n *\n * [Nag] These are initial placeholder standards and should be reviewed for\n * production hardening.\n */\nexport const DOMAIN_KEYSTONE_SECURITY_STANDARDS = {\n MIN_DEFAULT_POOL_SIZE: 50,\n ALLOWED_ALGORITHMS: [\n HashAlgorithm.sha_256,\n HashAlgorithm.sha_512\n ],\n} as const;\n\n\n// ---------------------------------------------------------------------------\n// 3. Upfront Picket-Fence Handshake Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the lexicographically first challenge from the session keystone's\n * 'handshake' pool to be used as a deterministic, dynamic upfront pre-filter challenge.\n */\nexport function getHandshakeChallenge(keystone: KeystoneIbGib_V1): { challengeId: string; challenge: any } {\n const handshakePool = (keystone.data?.challengePools ?? []).find(\n (p) => p.id === SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID\n );\n if (!handshakePool) {\n throw new Error(`Keystone missing \"${SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID}\" pool`);\n }\n\n const challengeIds = Object.keys(handshakePool.challenges).sort();\n if (challengeIds.length === 0) {\n throw new Error(`Handshake pool has no challenges`);\n }\n\n const challengeId = challengeIds[0];\n const challenge = handshakePool.challenges[challengeId];\n return { challengeId, challenge };\n}\n\n/**\n * Cryptographically validates the upfront picket-fence solution against the session keystone.\n * Verifies that the client solved the lexicographically first challenge from the 'handshake' pool.\n */\nexport async function checkHandshakeSolution(\n keystone: KeystoneIbGib_V1,\n solutionValue: string\n): Promise<boolean> {\n const handshakePool = (keystone.data?.challengePools ?? []).find(\n (p) => p.id === SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID\n );\n if (!handshakePool) {\n return false;\n }\n\n const { challengeId, challenge } = getHandshakeChallenge(keystone);\n const strategy = KeystoneStrategyFactory.create({ config: handshakePool.config });\n const solution: KeystoneSolution = {\n type: 'hash-reveal-v1',\n challengeId,\n poolId: SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID,\n value: solutionValue\n };\n\n return await strategy.validateSolution({ solution, challenge });\n}\n\n// this is what we had by default inside the sync saga coordinator\n// const primaryPoolConfig: KeystonePoolConfig_HashV1 = {\n// allowedVerbs: [KEYSTONE_VERB_MANAGE],\n// id: SESSION_IDENTITY_KEYSTONE_PRIMARY_POOL_ID,\n// salt: sagaId,\n// behavior: {\n// size: SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE, // Large pool for many signatures\n// replenish: SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY,\n// selectSequentially: SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL,\n// selectRandomly: SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM,\n// targetBindingChars: SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING,\n// },\n// type: KeystoneChallengeType.hash_reveal_v1,\n// algo: SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO,\n// rounds: SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS,\n// };", "import { extractErrorMsg } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\n\n/**\n * Handles communication with the SpaceGib REST API.\n */\nexport class SpaceGibApiBridge {\n private lc: string = `[SpaceGibApiBridge]`;\n\n /**\n * Posts a single genesis keystone ibgib to the server to create a new domain.\n * \n * @param keystoneIbGib The genesis keystone ibgib.\n * @returns Promise resolving to the server response containing the addr.\n */\n public async postGenesisKeystone(keystoneIbGib: IbGib_V1): Promise<{ success: boolean; message?: string; addr?: string }> {\n const lc = `${this.lc}[${this.postGenesisKeystone.name}]`;\n try {\n console.log(`${lc} [NAG][ibgib-paradigm] posting genesis keystone...`);\n \n const response = await fetch('/api/keystone/genesis', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ keystoneIbGib }),\n });\n\n const data = await response.json();\n \n if (!response.ok) {\n const errorMsg = data.message || data.error || 'Unknown error';\n console.error(`${lc} [NAG][ibgib-paradigm] server rejected genesis keystone: ${errorMsg}`);\n return { success: false, message: errorMsg, addr: data.addr };\n }\n\n console.log(`${lc} [NAG][ibgib-paradigm] genesis keystone posted successfully.`);\n return { success: true, addr: data.addr };\n\n } catch (error) {\n const errorMsg = extractErrorMsg(error);\n console.error(`${lc} [NAG][ibgib-paradigm] fetch error: ${errorMsg}`);\n return { success: false, message: errorMsg };\n }\n }\n\n /**\n * PUTs an evolved domain keystone and any related ibgibs (e.g. S^Stjp) to the server.\n */\n public async putEvolveKeystone(domainAddr: string, keystoneIbGib: IbGib_V1, relatedIbGibs: IbGib_V1[] = []): Promise<{ success: boolean; message?: string }> {\n const lc = `${this.lc}[${this.putEvolveKeystone.name}]`;\n try {\n console.log(`${lc} posting evolved keystone...`);\n \n // Note: encodeURIComponent safely encodes the `^` if needed, though our regex handles both\n const url = `/api/keystone/evolve/${encodeURIComponent(domainAddr)}`;\n const response = await fetch(url, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ keystoneIbGib, relatedIbGibs }),\n });\n\n const data = await response.json();\n \n if (!response.ok) {\n const errorMsg = data.message || data.error || 'Unknown error';\n console.error(`${lc} server rejected keystone evolution: ${errorMsg}`);\n return { success: false, message: errorMsg };\n }\n\n console.log(`${lc} keystone evolution accepted by server.`);\n return { success: true };\n\n } catch (error) {\n const errorMsg = extractErrorMsg(error);\n console.error(`${lc} fetch error: ${errorMsg}`);\n return { success: false, message: errorMsg };\n }\n }\n}\n\n/** Singleton instance for the bridge. */\nexport const spaceGibApiBridge = new SpaceGibApiBridge();\n", "/**\n * @module client/dev-tools\n *\n * Wires up the Dev Tools panel button handlers for manual testing during\n * development. Import this from index.mts inside the DOMContentLoaded handler.\n *\n * ## intent\n *\n * Remove or gate this module once the real sync WebSocket endpoint is confirmed\n * working end-to-end.\n */\n\nimport { extractErrorMsg, getTimestamp, getUUID, HashAlgorithm } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { Factory_V1 as factory } from '@ibgib/ts-gib/dist/V1/factory.mjs';\nimport { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';\nimport { getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';\nimport { KeystoneChallengeType, KeystoneIbGib_V1, KeystoneReplenishStrategy } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';\nimport { createManagePoolConfig } from '@ibgib/core-gib/dist/keystone/keystone-config-builder.mjs';\nimport { getGlobalMetaspace_waitIfNeeded } from \"@ibgib/web-gib/dist/helpers.mjs\";\n\nimport { GLOBAL_LOG_A_LOT } from './constants.mjs';\nimport { SESSION_KEYSTONE_POLICY, getHandshakeChallenge } from \"../common/keystone-policies.mjs\";\nimport { KeystoneStrategyFactory } from '@ibgib/core-gib/dist/keystone/strategy/keystone-strategy-factory.mjs';\nimport { SpaceGibApiBridge } from './api/space-gib-api-bridge.mjs';\nimport { KeystoneVerb } from '@ibgib/core-gib/dist/keystone/keystone-constants.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT\nconst lc = '[dev-tools]';\n\ninterface DebugState {\n domainI?: KeystoneIbGib_V1;\n domainIMasterSecret?: string;\n targetX?: IbGib_V1;\n sessionS?: KeystoneIbGib_V1;\n sessionSecret?: string;\n}\n\nexport const debugState: DebugState = {};\n(window as any).ibgibDebugState = debugState;\n\n// ---------------------------------------------------------------------------\n// Dev panel log helper\n// ---------------------------------------------------------------------------\n\nexport function devLog(msg: string): void {\n const logEl = document.getElementById('dev-panel-log') as HTMLPreElement | null;\n if (!logEl) { return; }\n const timestamp = new Date().toISOString().slice(11, 23); // HH:MM:SS.mmm\n logEl.textContent = `[${timestamp}] ${msg}\\n` + logEl.textContent;\n}\n\n// ---------------------------------------------------------------------------\n// Test WebSocket button\n// ---------------------------------------------------------------------------\n\nlet _ws: WebSocket | null = null;\n\nfunction initWsTestButton(): void {\n const lc_fn = `${lc}[initWsTestButton]`;\n const btn = document.getElementById('btn-test-ws') as HTMLButtonElement | null;\n if (!btn) {\n console.warn(`${lc_fn} btn-test-ws not found \u2014 skipping`);\n return;\n }\n\n btn.addEventListener('click', () => {\n try {\n if (_ws && _ws.readyState === WebSocket.OPEN) {\n // Already connected \u2014 send a test ping instead\n _ws.send(JSON.stringify({ ping: 'hello from client', ts: Date.now() }));\n devLog('\u2192 sent ping on existing connection');\n return;\n }\n\n // Build the WebSocket URL from the current origin (wss:// if https://)\n const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';\n const wsUrl = `${protocol}//${location.host}/api/debug/ws-echo`;\n devLog(`\u2192 connecting to ${wsUrl}`);\n\n _ws = new WebSocket(wsUrl);\n\n _ws.addEventListener('open', () => {\n devLog('\u2713 WebSocket connected');\n btn.textContent = 'Send WS Ping';\n });\n\n _ws.addEventListener('message', (ev) => {\n devLog(`\u2190 ${ev.data}`);\n });\n\n _ws.addEventListener('close', (ev) => {\n devLog(`\u2717 WebSocket closed (code ${ev.code})`);\n btn.textContent = 'Test WebSocket';\n _ws = null;\n });\n\n _ws.addEventListener('error', (ev) => {\n devLog(`\u2717 WebSocket error \u2014 check console`);\n console.error(`${lc_fn} WebSocket error`, ev);\n });\n\n } catch (error) {\n devLog(`\u2717 ${extractErrorMsg(error)}`);\n console.error(`${lc_fn} ${extractErrorMsg(error)}`);\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Print Dev State button\n// ---------------------------------------------------------------------------\n\nfunction initPrintStateButton(): void {\n const btn = document.getElementById('btn-print-dev-state') as HTMLButtonElement | null;\n if (!btn) return;\n btn.addEventListener('click', () => {\n devLog(`Printing debug state to console...`);\n console.dir(debugState);\n });\n}\n\n// ---------------------------------------------------------------------------\n// Create Domain Keystone (I) button\n// ---------------------------------------------------------------------------\n\nfunction initCreateDomainKeystoneButton(): void {\n const lc_fn = `${lc}[initCreateDomainKeystoneButton]`;\n const btn = document.getElementById('btn-create-domain-keystone') as HTMLButtonElement | null;\n if (!btn) return;\n\n btn.addEventListener('click', async () => {\n try {\n btn.disabled = true;\n devLog('Generating dummy Domain Keystone (I)...');\n\n const metaspace = await getGlobalMetaspace_waitIfNeeded();\n const space = await metaspace.getLocalUserSpace({});\n if (!space) { throw new Error(\"No default space found in metaspace.\"); }\n\n const masterSecret = 'password'; // Hardcoded for debug as requested\n const keystoneService = new KeystoneService_V1();\n\n const domainI = await keystoneService.genesis({\n masterSecret,\n configs: [\n createManagePoolConfig({\n id: 'default',\n salt: await getUUID(),\n replenishStrategy: KeystoneReplenishStrategy.topUp,\n }),\n ],\n metaspace,\n space,\n frameDetails: { client: 'space-gib-web-dev', timestamp: getTimestamp() }\n });\n\n const iAddr = getIbGibAddr({ ibGib: domainI });\n devLog(`\u2713 Local genesis complete: ${iAddr}`);\n\n debugState.domainI = domainI;\n debugState.domainIMasterSecret = masterSecret;\n\n // Post to server\n devLog(`Posting genesis keystone to server...`);\n const apiBridge = new SpaceGibApiBridge();\n const resSync = await apiBridge.postGenesisKeystone(domainI);\n if (!resSync.success) {\n devLog(`\u2717 Server rejected genesis keystone: ${resSync.message}`);\n btn.disabled = false;\n return;\n }\n\n devLog(`\u2713 Server accepted Domain Keystone (I)`);\n btn.textContent = '\u2713 Domain Keystone Created';\n\n // Enable next step\n const nextBtn = document.getElementById('btn-create-test-ibgib') as HTMLButtonElement;\n if (nextBtn) nextBtn.disabled = false;\n\n } catch (error) {\n devLog(`\u2717 ${extractErrorMsg(error)}`);\n console.error(`${lc_fn} ${extractErrorMsg(error)}`);\n btn.disabled = false;\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Create Test IbGib button\n// ---------------------------------------------------------------------------\n\nfunction initCreateTestIbGibButton(): void {\n const lc_fn = `${lc}[initCreateTestIbGibButton]`;\n const btn = document.getElementById('btn-create-test-ibgib') as HTMLButtonElement | null;\n if (!btn) {\n console.warn(`${lc_fn} btn-create-test-ibgib not found \u2014 skipping`);\n return;\n }\n\n btn.addEventListener('click', async () => {\n try {\n devLog('Generating dummy X^Xtjp ibgib...');\n const resX = await factory.firstGen({\n parentIbGib: ROOT,\n ib: 'test data',\n data: { hello: 'world', random: Math.random() },\n dna: true,\n nCounter: true,\n tjp: { uuid: true, timestamp: true }\n });\n const xIbGib = resX.newIbGib;\n const xAddr = getIbGibAddr({ ibGib: xIbGib });\n\n debugState.targetX = xIbGib;\n devLog(`\u2713 Created X: ${xAddr}`);\n btn.textContent = '\u2713 Test IbGib (X) Created';\n\n // Enable next step\n const nextBtn = document.getElementById('btn-create-session-keystone') as HTMLButtonElement;\n if (nextBtn) nextBtn.disabled = false;\n } catch (error) {\n devLog(`\u2717 ${extractErrorMsg(error)}`);\n console.error(`${lc_fn} ${extractErrorMsg(error)}`);\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Create Session Keystone (S^Stjp) button\n// ---------------------------------------------------------------------------\n\nfunction initCreateSessionKeystoneButton(): void {\n const lc_fn = `${lc}[initCreateSessionKeystoneButton]`;\n const btn = document.getElementById('btn-create-session-keystone') as HTMLButtonElement | null;\n if (!btn) {\n console.warn(`${lc_fn} btn-create-session-keystone not found \u2014 skipping`);\n return;\n }\n\n btn.addEventListener('click', async () => {\n try {\n devLog('Generating Session Keystone (S^Stjp)...');\n\n const domainI = debugState.domainI;\n const targetX = debugState.targetX;\n\n if (!domainI) { devLog('\u26A0 No domain keystone (I) found in state. Please Create Domain Keystone first.'); return; }\n if (!targetX) { devLog('\u26A0 No target ibgib (X) found in state. Please Create Test IbGib first.'); return; }\n\n const metaspace = await getGlobalMetaspace_waitIfNeeded();\n const space = await metaspace.getLocalUserSpace({});\n if (!space) { throw new Error(\"No default space found in metaspace.\"); }\n\n const sessionSecret = 'ephemeral-' + Math.random().toString();\n const keystoneService = new KeystoneService_V1();\n\n console.warn(`${lc}[NAG] placeholder genesis keystone config right now (W: 69b108687cf8bec0f9a8e148bcca8d26)`);\n const sIbGib = await keystoneService.genesis({\n masterSecret: sessionSecret,\n configs: [\n {\n id: SESSION_KEYSTONE_POLICY.DEFAULT_POOL.ID,\n salt: await getUUID(),\n type: SESSION_KEYSTONE_POLICY.COMMON.TYPE,\n algo: SESSION_KEYSTONE_POLICY.COMMON.ALGO,\n rounds: SESSION_KEYSTONE_POLICY.COMMON.ROUNDS,\n behavior: {\n size: SESSION_KEYSTONE_POLICY.DEFAULT_POOL.SIZE,\n replenish: SESSION_KEYSTONE_POLICY.COMMON.REPLENISH,\n selectSequentially: SESSION_KEYSTONE_POLICY.DEFAULT_POOL.SELECT_SEQUENTIALLY,\n selectRandomly: SESSION_KEYSTONE_POLICY.DEFAULT_POOL.SELECT_RANDOMLY,\n targetBindingChars: SESSION_KEYSTONE_POLICY.DEFAULT_POOL.TARGET_BINDING_CHARS,\n },\n allowedVerbs: [],\n },\n {\n id: SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID,\n salt: await getUUID(),\n type: SESSION_KEYSTONE_POLICY.COMMON.TYPE,\n algo: SESSION_KEYSTONE_POLICY.COMMON.ALGO,\n rounds: SESSION_KEYSTONE_POLICY.COMMON.ROUNDS,\n behavior: {\n size: SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.SIZE,\n replenish: SESSION_KEYSTONE_POLICY.COMMON.REPLENISH,\n selectSequentially: SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.SELECT_SEQUENTIALLY,\n selectRandomly: SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.SELECT_RANDOMLY,\n targetBindingChars: SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.TARGET_BINDING_CHARS,\n },\n allowedVerbs: [SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.VERB],\n }\n ],\n metaspace,\n space,\n frameDetails: {\n client: 'space-gib-web-session',\n target_I: domainI ? getIbGibAddr({ ibGib: domainI }) : undefined,\n target_X: targetX ? getIbGibAddr({ ibGib: targetX }) : undefined,\n }\n });\n\n const sAddr = getIbGibAddr({ ibGib: sIbGib });\n debugState.sessionS = sIbGib;\n debugState.sessionSecret = sessionSecret;\n\n devLog(`\u2713 Created Session Keystone: ${sAddr}`);\n btn.textContent = '\u2713 Session Keystone Created';\n\n // Enable next step\n const nextBtn = document.getElementById('btn-evolve-domain-keystone') as HTMLButtonElement;\n if (nextBtn) nextBtn.disabled = false;\n } catch (error) {\n devLog(`\u2717 ${extractErrorMsg(error)}`);\n console.error(`${lc_fn} ${extractErrorMsg(error)}`);\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Evolve Domain Keystone (I^I1) button\n// ---------------------------------------------------------------------------\n\nfunction initEvolveDomainKeystoneButton(): void {\n const lc_fn = `${lc}[initEvolveDomainKeystoneButton]`;\n const btn = document.getElementById('btn-evolve-domain-keystone') as HTMLButtonElement | null;\n if (!btn) {\n console.warn(`${lc_fn} btn-evolve-domain-keystone not found \u2014 skipping`);\n return;\n }\n\n btn.addEventListener('click', async () => {\n try {\n btn.disabled = true;\n devLog('Evolving Domain Keystone (I^I1) with sync claim...');\n\n const domainI = debugState.domainI;\n const masterSecret = debugState.domainIMasterSecret;\n const sessionS = debugState.sessionS;\n\n if (!domainI || !masterSecret) { devLog('\u26A0 No domain keystone (I) found. Please Create Domain Keystone first.'); return; }\n if (!sessionS) { devLog('\u26A0 No session keystone (S) found. Please Create Session Keystone first.'); return; }\n\n const metaspace = await getGlobalMetaspace_waitIfNeeded();\n const space = await metaspace.getLocalUserSpace({});\n if (!space) { throw new Error(\"No default space found in metaspace.\"); }\n\n const keystoneService = new KeystoneService_V1();\n const sAddr = getIbGibAddr({ ibGib: sessionS });\n\n devLog('Solving challenges to authorize sync...');\n const evolvedI = await keystoneService.sign({\n latestKeystone: domainI,\n masterSecret,\n claim: {\n target: sAddr,\n verb: 'sync'\n },\n metaspace,\n space\n });\n\n const evolvedAddr = getIbGibAddr({ ibGib: evolvedI });\n devLog(`\u2713 Local evolution complete: ${evolvedAddr}`);\n\n // Update state with new tip\n debugState.domainI = evolvedI;\n\n devLog('Posting evolution to server...');\n const apiBridge = new SpaceGibApiBridge();\n // We pass the domain address (from the original TJP) and the session keystone\n const domainAddr = getIbGibAddr({ ibGib: domainI });\n const resSync = await apiBridge.putEvolveKeystone(domainAddr, evolvedI, [sessionS]);\n\n if (!resSync.success) {\n devLog(`\u2717 Server rejected evolution: ${resSync.message}`);\n btn.disabled = false;\n return;\n }\n\n devLog('\u2713 Server accepted Domain Keystone evolution!');\n btn.textContent = '\u2713 Domain Keystone Evolved';\n\n // Enable next step\n const nextBtn = document.getElementById('btn-perform-sync') as HTMLButtonElement;\n if (nextBtn) nextBtn.disabled = false;\n\n } catch (error) {\n devLog(`\u2717 ${extractErrorMsg(error)}`);\n console.error(`${lc_fn} ${extractErrorMsg(error)}`);\n btn.disabled = false;\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Perform Sync Handshake (S) button\n// ---------------------------------------------------------------------------\n\nfunction initPerformSyncButton(): void {\n const lc_fn = `${lc}[initPerformSyncButton]`;\n const btn = document.getElementById('btn-perform-sync') as HTMLButtonElement | null;\n if (!btn) return;\n\n btn.addEventListener('click', async () => {\n try {\n debugger; // walk through sync\n btn.disabled = true;\n devLog('Initiating Sync Handshake via WebSocket...');\n\n const sessionS = debugState.sessionS;\n const sessionSecret = debugState.sessionSecret;\n const domainI = debugState.domainI;\n\n if (!sessionS || !sessionSecret || !domainI) {\n devLog('\u26A0 Incomplete state. Please complete steps 1-4.');\n btn.disabled = false;\n return;\n }\n\n const metaspace = await getGlobalMetaspace_waitIfNeeded();\n const space = await metaspace.getLocalUserSpace({});\n if (!space) { throw new Error(\"No space.\"); }\n\n devLog('Pre-solving upfront picket-fence challenge...');\n const handshakePool = (sessionS.data?.challengePools ?? []).find(p => p.id === SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID);\n if (!handshakePool) {\n throw new Error(`Session keystone missing \"${SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID}\" pool`);\n }\n\n const { challengeId } = getHandshakeChallenge(sessionS);\n const strategy = KeystoneStrategyFactory.create({ config: handshakePool.config });\n const poolSecret = await strategy.derivePoolSecret({ masterSecret: sessionSecret });\n const solution = await strategy.generateSolution({\n poolSecret,\n poolId: SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID,\n challengeId\n });\n\n const sAddr = getIbGibAddr({ ibGib: sessionS });\n const domainAddr = getIbGibAddr({ ibGib: domainI });\n const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';\n const wsUrl = `${protocol}//${location.host}/api/sync/ws/${encodeURIComponent(domainAddr)}` +\n `?sAddr=${encodeURIComponent(sAddr)}` +\n `&solution=${solution.value}`;\n\n devLog(`\u2192 connecting to ${wsUrl}`);\n const ws = new WebSocket(wsUrl);\n\n ws.addEventListener('open', () => {\n devLog('\u2713 WebSocket connected. Waiting for server challenge...');\n });\n\n ws.addEventListener('message', async (ev) => {\n try {\n const msg = JSON.parse(ev.data);\n devLog(`\u2190 received: ${msg.type ?? 'message'}`);\n\n if (msg.type === 'auth-challenge-init') {\n devLog('\u2192 sending auth-init with sAddr...');\n ws.send(JSON.stringify({\n type: 'auth-init',\n sAddr: getIbGibAddr({ ibGib: sessionS })\n }));\n } else if (msg.type === 'auth-challenge') {\n const { challengeUuid, demandedIds } = msg;\n devLog(`\u2192 server demanded ${demandedIds.length} ids. Signing handshake proof...`);\n\n const keystoneService = new KeystoneService_V1();\n const proofFrame = await keystoneService.sign({\n latestKeystone: sessionS,\n masterSecret: sessionSecret,\n poolId: 'handshake',\n requiredChallengeIds: demandedIds,\n claim: {\n verb: 'handshake',\n target: challengeUuid\n },\n metaspace,\n space\n });\n\n devLog('\u2192 sending auth-proof...');\n ws.send(JSON.stringify({\n type: 'auth-proof',\n proofFrame\n }));\n } else if (msg.type === 'auth-ok') {\n devLog('\u2713 Handshake SUCCESS! Sync session authorized.');\n btn.textContent = '\u2713 Sync Authorized';\n } else if (msg.type === 'auth-fail') {\n devLog(`\u2717 Handshake FAILED: ${msg.message}`);\n btn.disabled = false;\n }\n } catch (error) {\n devLog(`\u2717 Message handler error: ${extractErrorMsg(error)}`);\n console.error(`${lc_fn} Message handler error:`, error);\n btn.disabled = false;\n }\n });\n\n ws.addEventListener('close', (ev) => {\n devLog(`\u2717 WebSocket closed (code ${ev.code})`);\n btn.disabled = false;\n });\n\n ws.addEventListener('error', () => {\n devLog(`\u2717 WebSocket error \u2014 check server`);\n btn.disabled = false;\n });\n\n } catch (error) {\n devLog(`\u2717 ${extractErrorMsg(error)}`);\n console.error(`${lc_fn} ${extractErrorMsg(error)}`);\n btn.disabled = false;\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Dev Tools UI Init\n// ---------------------------------------------------------------------------\n\n/**\n * Call once inside DOMContentLoaded to wire up all dev-tool buttons.\n */\nexport function initDevTools(): void {\n const lc_fn = `${lc}[initDevTools]`;\n try {\n initPrintStateButton();\n initCreateDomainKeystoneButton();\n initWsTestButton();\n initCreateTestIbGibButton();\n initCreateSessionKeystoneButton();\n initEvolveDomainKeystoneButton();\n initPerformSyncButton();\n } catch (error) {\n console.error(`${lc_fn} ${extractErrorMsg(error)}`);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["UUID_REGEXP", "CLASSNAME_REGEXP", "ERROR_MSG_WITH_ID_CAPTURE_GROUPS_REGEXP", "ERROR_MSG_LOCATION_ONLY_REGEXP", "HEXADECIMAL_HASH_STRING_REGEXP_32", "HEXADECIMAL_HASH_STRING_REGEXP_64", "DEFAULT_DATA_PATH_DELIMITER", "ONLY_HAS_NON_ALPHANUMERICS", "logalot", "crypto", "subtle", "HashAlgorithm", "clone", "obj", "__name", "getTimestamp", "date", "hash", "s", "algorithm", "validAlgorithms", "msgUint8", "buffer", "b", "error", "extractErrorMsg", "getUUID", "seedSize", "uuid", "values", "pretty", "delay", "ms", "resolve", "groupBy", "items", "keyFn", "lc", "result", "i", "item", "key", "getRegExp", "min", "max", "chars", "noSpaces", "getTimestampInTicks", "timestamp", "getExpirationUTCString", "startDate", "years", "months", "days", "hours", "seconds", "addTimeToDate", "intervalToAdd", "newDateTicks", "isExpired", "expirationTimestampUTC", "expirationDate", "unique", "arr", "patchObject", "value", "path", "pathDelimiter", "DEFAULT_DATA_PATH_DELIMITER", "targetObj", "pathPieces", "x", "piece", "currentValue", "getIdPool", "n", "id", "getSaferSubstring", "text", "length", "keepLiterals", "replaceMap", "saferText", "tokenToKeepMap", "keep", "tmpToken", "pickRandom_Letters", "toReplace", "replaceWith", "tokens", "token", "ONLY_HAS_NON_ALPHANUMERICS", "pickRandom", "randomIndex", "count", "mergeMapsOrArrays_Naive", "dominant", "recessive", "lc", "output", "clone", "warned", "recessiveItem", "xString", "o", "dominantKeys", "recessiveKeys", "key", "error", "__name", "getIbGibAddr", "ib", "gib", "ibGib", "delimiter", "__name", "getIbAndGib", "ibGibAddr", "lc", "pieces", "crypto", "subtle", "sha256v1", "ibGib", "salt", "hashToHex", "__name", "message", "msgUint8", "buffer", "subtle", "b", "hashToHex_Uint8Array", "tohashUint8Array", "msgUint8_salt", "hashAsBuffer", "toNormalizedForHashing", "value", "element", "normalizedObject", "sortedKeys", "key", "propertyValue", "hashFields", "ib", "data", "rel8ns", "hasRel8ns", "k", "hasData", "ibHash", "rel8nsHash", "dataHash", "Rel8n", "IB", "GIB", "ROOT", "IBGIB_DELIMITER", "GIB_DELIMITER", "ROOT_ADDR", "FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES", "IB_MAX_LENGTH_DEFAULT", "IB_REGEXP_DEFAULT", "buildDna", "opts", "transformData", "clone", "lc", "result", "IBGIB_DELIMITER", "GIB", "sha256v1", "__name", "isDna", "ibGib", "knownTransformPrimitiveAddrs", "x", "error", "extractErrorMsg", "isPrimitive", "gib", "getGib", "hasTjp", "tjpAddr", "gibDelimiter", "hashAlgorithm", "ibGibHash", "rel8ns", "data", "GIB_DELIMITER", "tjpAddrGib", "getIbGibAddr", "getIbAndGib", "getGibInfo", "ibGibAddr", "pieces", "p", "piecesCount", "fork", "opts", "noTimestamp", "dna", "linkedRel8ns", "destIb", "uuid", "tjp", "cloneRel8ns", "cloneData", "type", "src", "lc", "IBGIB_DELIMITER", "dto", "srcAddr", "getIbGibAddr", "rel8ns", "clone", "data", "ancestor", "Rel8n", "newIbGib", "date", "getTimestamp", "getUUID", "ROOT_ADDR", "transformDna", "buildDna", "dnaAddr", "sha256v1", "result", "__name", "mut8", "opts", "noTimestamp", "dna", "linkedRel8ns", "dataToRename", "dataToRemove", "dataToAddOrPatch", "mut8Ib", "type", "src", "lc", "IBGIB_DELIMITER", "srcAddr", "getIbGibAddr", "isPrimitive", "dto", "newIbGib", "clone", "srcRel8ns", "rel8ns", "Rel8n", "data", "renameOrRemove", "patch", "date", "getTimestamp", "tjpRel8n", "transformDna", "buildDna", "dnaAddr", "hasTjp", "getGib", "result", "__name", "obj", "info", "which", "FORBIDDEN_RENAME_REMOVE_KEYS", "key", "infoVal", "patchInfo", "patchKey", "patchVal", "objVal", "rel8", "opts", "noTimestamp", "dna", "linkedRel8ns", "rel8nsToAddByAddr", "rel8nsToRemoveByAddr", "type", "src", "lc", "IBGIB_DELIMITER", "isPrimitive", "isAdding", "isRemoving", "srcAddr", "getIbGibAddr", "fnValidIbGibAddr", "__name", "s", "x", "rel8ds", "rel8d", "dto", "newIbGib", "clone", "data", "date", "getTimestamp", "rel8ns", "rel8nName", "FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES", "existingRel8d", "newRel8d", "toRemoveRel8d", "prunedRel8d", "linkedRel8nName", "initialLength", "tjpRel8n", "hasTjp", "transformDna", "buildDna", "dnaAddr", "Rel8n", "getGib", "result", "hasTjp", "ibGib", "lc", "dnaPrimitives", "x", "GIB_DELIMITER", "GIB", "getGibInfo", "getIbGibAddr", "__name", "toDto", "dtoIbGib", "clone", "logalot", "validateIbGibIntrinsically", "ibGib", "lc", "errors", "addr", "getIbGibAddr", "validateIbGibAddr", "isPrimitive", "gottenGib", "getGib", "toDto", "hasTjp", "error", "extractErrorMsg", "__name", "delimiter", "version", "IBGIB_DELIMITER", "ib", "gib", "getIbAndGib", "resValidateIb", "validateIb", "resValidateGib", "validateGib", "ibGibAddrDelimiter", "IB", "gibDelimiter", "INVALID_GIB_CHARS", "invalidCharsFound", "invalidChar", "punctiliarHash", "tjpGib", "getGibInfo", "GIB_DELIMITER", "punctiliarHashIs_32", "HEXADECIMAL_HASH_STRING_REGEXP_32", "punctiliarHashIs_64", "HEXADECIMAL_HASH_STRING_REGEXP_64", "tjpGibValidationErrors", "validateRel8nsIntrinsically", "rel8ns", "rel8nNames", "i", "rel8nName", "addrs", "j", "addrErrors", "logalot", "Factory_V1", "_Factory_V1", "__name", "IB", "ib", "GIB", "ibs", "parentIbGib", "data", "rel8ns", "dna", "tjp", "linkedRel8ns", "noTimestamp", "nCounter", "squash", "lc", "interimResults", "src", "ROOT", "resFork", "fork", "resMut8", "mut8", "resRel8", "rel8", "newIbGib", "resultWithIntermediates", "x", "dnas", "res", "getGib", "error", "extractErrorMsg", "parentPrimitiveIb", "ibRegExpPattern", "uuid", "validateIb", "regExp", "IB_REGEXP_DEFAULT", "incomingRel8nNames", "forbiddenRel8nNames", "FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES", "stoneIbGib", "getUUID", "GLOBAL_TIMER_NAME", "SAFE_SPECIAL_CHARS", "IB_REGEXP_DEFAULT", "ROBBOT_NAME_REGEXP", "ROBBOT_PREFIX_SUFFIX_REGEXP", "SpecialIbGibType", "ROBBOT_REL8N_NAME", "ZERO_SPACE_ID", "IBGIB_SPACE_NAME_DEFAULT", "PERSIST_OPTS_AND_RESULTS_IBGIBS_DEFAULT", "DEFAULT_LOCAL_SPACE_DESCRIPTION", "SPACE_NAME_REGEXP", "SYNC_SPACE_REL8N_NAME", "DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS", "SPACE_ATOM", "SPACE_LOCK_IB_TERM", "DEFAULT_MAX_DELAY_MS_RETRY_LOCK_ACQUIRE", "DEFAULT_MAX_DELAY_RETRY_LOCK_ACQUIRE_ATTEMPTS", "MAX_LOCK_SECONDS_VALID", "DEFAULT_SECONDS_VALID_LOCAL", "ROOT_REL8N_NAME", "DEFAULT_ROOT_REL8N_NAME", "DEFAULT_ROOT_TEXT", "DEFAULT_ROOT_ICON", "DEFAULT_ROOT_DESCRIPTION", "TAG_REL8N_NAME", "TAG_TARGET_REL8N_NAME", "DEFAULT_TAG_ICON", "DEFAULT_TAG_DESCRIPTION", "AUTOSYNC_ALWAYS_REL8N_NAME", "ARCHIVE_REL8N_NAME", "TRASH_REL8N_NAME", "SPECIAL_IBGIB_TYPE_REGEXP", "INVALID_DATE_STRING", "TRUE_GIB", "GIB", "FALSE_GIB", "GIB", "CONFIG_KEY_ATOM", "APP_NAME_REGEXP", "APP_REL8N_NAME", "BOOTSTRAP_IBGIB_ADDR", "GIB", "BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY", "BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY", "SaltStrategy", "SALT_STRATEGIES", "HashAlgorithm", "HASH_ALGORITHMS", "AlphabetIndexingMode", "ALPHABET_INDEXING_MODES", "encodeStringToHexString", "s", "lc", "resolve", "reject", "bytes", "stringToUTF8Bytes", "hexString", "bytesToHexString", "error", "extractErrorMsg", "__name", "byte", "decodeHexStringToString", "hexStringToBytes", "utf8BytesToString", "numBytes", "i", "DEFAULT_SALT_STRATEGY", "SaltStrategy", "DEFAULT_HASH_ALGORITHM", "DEFAULT_GETUUID_SEEDSIZE", "DEFAULT_INITIAL_RECURSIONS", "DEFAULT_RECURSIONS_PER_HASH", "DEFAULT_ALPHABET_INDEXING_MODE_LEGACY", "DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE", "DEFAULT_MAX_BLOCK_SIZE", "DEFAULT_NUM_OF_PASSES", "DEFAULT_ENCRYPTED_DATA_DELIMITER", "getPreHash", "secret", "prevHash", "salt", "saltStrategy", "SaltStrategy", "__name", "execRound_getNextHash", "count", "hashAlgorithm", "lc", "hash", "i", "preHash", "error", "extractErrorMsg", "doInitialRecursions_keystretch", "initialRecursions", "encryptFromHex_stream", "hexEncodedData", "initialRecursions", "recursionsPerHash", "salt", "saltStrategy", "secret", "hashAlgorithm", "encryptedDataDelimiter", "indexingMode", "lc", "prevHash", "doInitialRecursions_keystretch", "getIndex", "alphabet", "hexChar", "encryptedDataIndexes", "i", "hexCharFromData", "hash", "execRound_getNextHash", "charIndex", "error", "extractErrorMsg", "__name", "decryptToHex_stream", "encryptedData", "initialRecursions", "recursionsPerHash", "salt", "saltStrategy", "secret", "hashAlgorithm", "encryptedDataDelimiter", "lc", "prevHash", "doInitialRecursions_keystretch", "encryptedDataIndexes", "nString", "decryptedDataArray", "i", "charIndex", "alphabet", "hash", "execRound_getNextHash", "hexChar", "error", "extractErrorMsg", "__name", "decryptImpl_stream", "encryptedData", "initialRecursions", "recursionsPerHash", "salt", "saltStrategy", "secret", "hashAlgorithm", "encryptedDataDelimiter", "lc", "errors", "warnings", "DEFAULT_INITIAL_RECURSIONS", "DEFAULT_RECURSIONS_PER_HASH", "DEFAULT_SALT_STRATEGY", "DEFAULT_HASH_ALGORITHM", "getUUID", "DEFAULT_GETUUID_SEEDSIZE", "DEFAULT_ENCRYPTED_DATA_DELIMITER", "lcv", "e", "HashAlgorithm", "SALT_STRATEGIES", "hexEncodedData", "decryptToHex_stream", "decodeHexStringToString", "__name", "encryptImpl_stream", "dataToEncrypt", "initialRecursions", "recursionsPerHash", "salt", "saltStrategy", "secret", "hashAlgorithm", "encryptedDataDelimiter", "confirm", "indexingMode", "lc", "errors", "warnings", "DEFAULT_INITIAL_RECURSIONS", "DEFAULT_RECURSIONS_PER_HASH", "DEFAULT_SALT_STRATEGY", "DEFAULT_HASH_ALGORITHM", "getUUID", "DEFAULT_GETUUID_SEEDSIZE", "DEFAULT_ENCRYPTED_DATA_DELIMITER", "DEFAULT_ALPHABET_INDEXING_MODE_LEGACY", "lcv", "e", "ALPHABET_INDEXING_MODES", "HashAlgorithm", "SALT_STRATEGIES", "hexEncodedData", "encodeStringToHexString", "decodeHexStringToString", "encryptedData", "encryptFromHex_stream", "resDecrypt", "decryptImpl_stream", "__name", "encryptFromHex_blockMode", "hexEncodedData", "initialRecursions", "recursionsPerHash", "salt", "saltStrategy", "secret", "hashAlgorithm", "encryptedDataDelimiter", "indexingMode", "maxBlockSize", "numOfPasses", "lc", "prevHash", "doInitialRecursions_keystretch", "getIndexOfCharInAlphabet", "alphabet", "hexChar", "encryptedDataIndexes", "totalLength", "blockSize", "blockSections", "finalBlockSize", "indexHexEncodedDataAtStartOfPass", "indexOfBlock", "resGetAlphabets", "getAlphabetsThisBlock", "alphabetsThisBlock", "encryptedIndexesThisBlock", "getEncryptedIndexesThisBlock", "error", "extractErrorMsg", "__name", "indexHexEncodedData", "hash", "passNum", "indexIntoBlock", "execRound_getNextHash", "hexCharFromData", "resIndexes", "encryptedIndexIntoAlphabet", "decryptToHex_blockMode", "encryptedData", "initialRecursions", "recursionsPerHash", "salt", "saltStrategy", "secret", "hashAlgorithm", "encryptedDataDelimiter", "maxBlockSize", "numOfPasses", "lc", "prevHash", "doInitialRecursions_keystretch", "encryptedDataIndexes", "nString", "decryptedDataArray", "totalLength", "blockSize", "blockSections", "finalBlockSize", "indexEncryptedDataIndexesAtStartOfPass", "indexOfBlock", "resGetAlphabets", "getAlphabetsThisBlock", "alphabetsThisBlock", "decryptedDataArrayThisBlock", "getDecryptedDataArrayThisBlock", "error", "extractErrorMsg", "__name", "indexEncryptedDataIndexes", "hash", "passNum", "indexIntoBlock", "alphabet", "execRound_getNextHash", "encryptedIndex", "resDataArray", "decryptedCharString", "decryptImpl_blockMode", "args", "lc", "encryptedData", "initialRecursions", "recursionsPerHash", "salt", "saltStrategy", "secret", "hashAlgorithm", "encryptedDataDelimiter", "indexingMode", "blockMode", "multipass", "errors", "warnings", "DEFAULT_INITIAL_RECURSIONS", "DEFAULT_RECURSIONS_PER_HASH", "DEFAULT_SALT_STRATEGY", "DEFAULT_HASH_ALGORITHM", "getUUID", "DEFAULT_GETUUID_SEEDSIZE", "DEFAULT_ENCRYPTED_DATA_DELIMITER", "DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE", "maxBlockSize", "maxPassSectionLength", "numOfPasses", "DEFAULT_MAX_BLOCK_SIZE", "DEFAULT_NUM_OF_PASSES", "lcv", "e", "ALPHABET_INDEXING_MODES", "HashAlgorithm", "SALT_STRATEGIES", "result", "hexEncodedData", "decryptToHex_blockMode", "decryptedData", "decodeHexStringToString", "__name", "encryptImpl_blockMode", "args", "lc", "dataToEncrypt", "initialRecursions", "recursionsPerHash", "salt", "saltStrategy", "secret", "hashAlgorithm", "encryptedDataDelimiter", "confirm", "indexingMode", "blockMode", "multipass", "errors", "warnings", "DEFAULT_INITIAL_RECURSIONS", "DEFAULT_ENCRYPTED_DATA_DELIMITER", "DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE", "maxBlockSize", "maxPassSectionLength", "numOfPasses", "DEFAULT_MAX_BLOCK_SIZE", "DEFAULT_NUM_OF_PASSES", "lcv", "e", "ALPHABET_INDEXING_MODES", "HashAlgorithm", "SALT_STRATEGIES", "result", "hexEncodedData", "encodeStringToHexString", "decodeHexStringToString", "encryptedData", "encryptFromHex_blockMode", "resDecrypt", "decryptImpl_blockMode", "error", "extractErrorMsg", "__name", "encrypt", "args", "lc", "getUUID", "DEFAULT_GETUUID_SEEDSIZE", "DEFAULT_SALT_STRATEGY", "DEFAULT_HASH_ALGORITHM", "DEFAULT_RECURSIONS_PER_HASH", "result", "encryptImpl_blockMode", "encryptImpl_stream", "e", "w", "error", "__name", "decrypt", "decryptImpl_blockMode", "decryptImpl_stream", "DEFAULT_ENCRYPTION_INITIAL_RECURSIONS", "DEFAULT_ENCRYPTION_SALT_STRATEGY", "SaltStrategy", "DEFAULT_ENCRYPTION_RECURSIONS_PER_HASH", "DEFAULT_ENCRYPTION_HASH_ALGORITHM", "ENCRYPTION_REL8N_NAME", "CIPHERTEXT_ATOM", "SpaceLocation", "VALID_SPACE_LOCATIONS", "SpaceType", "VALID_SPACE_TYPES", "UserSpaceSubtype", "SyncSpaceSubtype", "SpaceSubtype", "VALID_SPACE_SUBTYPES", "IbGibSpaceOptionsCmd", "IbGibSpaceOptionsCmdModifier", "logalot", "DynamicFormBuilder", "_DynamicFormBuilder", "__name", "lc", "resultArray", "chars", "charLength", "i", "charIndex", "id", "what", "item", "idPool", "value", "required", "defaultValue", "getRegExp", "SAFE_SPECIAL_CHARS", "of", "label", "UUID_REGEXP", "formName", "WitnessFormBuilder", "_WitnessFormBuilder", "DynamicFormBuilder", "__name", "of", "required", "data", "allowPrimitiveArgs", "catchAllErrors", "persistOptsAndResultIbGibs", "trace", "version", "logalot", "validateCommonAppData", "appData", "lc", "logalot", "errors", "name", "uuid", "classname", "APP_NAME_REGEXP", "UUID_REGEXP", "error", "__name", "getAppIb", "validationErrors", "getInfoFromAppIb", "appIb", "pieces", "createNewApp", "fnPromptApp", "ibgibs", "space", "lc", "logalot", "resApp", "newApp", "allIbGibs", "x", "i", "ibGib", "validationErrors", "validateIbGibIntrinsically", "pretty", "persistTransformResult", "zeroSpace", "fnBroadcast", "fnUpdateBootstrap", "registerNewIbGib", "__name", "rel8ToSpecialIbGib", "APP_REL8N_NAME", "error", "DEFAULT_UUID_CHAT_APP", "DEFAULT_NAME_CHAT_APP", "DEFAULT_DESCRIPTION_CHAT_APP", "DEFAULT_CHAT_APP_DATA_V1", "DEFAULT_CHAT_APP_REL8NS_V1", "DEFAULT_UUID_RAW_APP", "DEFAULT_NAME_RAW_APP", "DEFAULT_DESCRIPTION_RAW_APP", "DEFAULT_RAW_APP_DATA_V1", "DEFAULT_RAW_APP_REL8NS_V1", "DEFAULT_UUID_TODO_APP", "DEFAULT_NAME_TODO_APP", "DEFAULT_DESCRIPTION_TODO_APP", "DEFAULT_TODO_APP_DATA_V1", "DEFAULT_TODO_APP_REL8NS_V1", "validateBootstrapIbGib", "bootstrapSpace", "lc", "errors", "getIbGibAddr", "BOOTSTRAP_IBGIB_ADDR", "intrinsicErrors", "validateIbGibIntrinsically", "e", "data", "rel8ns", "spaceId", "BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY", "error", "__name", "META_STONE_ATOM", "DEFAULT_META_STONE_TIMESTAMP", "META_STONE_TARGET_REL8N_NAME", "META_STONE_TARGET_TJP_REL8N_NAME", "logalot", "validateCommonMetaStoneIb", "ib", "lc", "errors", "pieces", "META_STONE_ATOM", "tjpGib", "tjpGibValidationErrors", "validateGib", "nAsString", "parsedN", "timestampInTicks", "timestampInfo", "getTimestampInfo", "error", "extractErrorMsg", "__name", "validateCommonMetaStoneData", "data", "targetData", "timestamp", "targetTjpGib", "targetN", "targetTimestamp", "targetTimestampInfo", "timestampDate", "validateCommonMetaStoneRel8ns", "rel8ns", "intrinsicErrors", "validateRel8nsIntrinsically", "targetAddrs", "META_STONE_TARGET_REL8N_NAME", "targetTjpAddrs", "META_STONE_TARGET_TJP_REL8N_NAME", "validateCommonMetaStoneIbGib", "ibGib", "validateIbGibIntrinsically", "ibErrors", "atom", "n", "parseMetaStoneIb", "dataErrors", "rel8nsErrors", "result", "getMetaStoneIb", "classname", "validationErrors", "targetTimestampInTicks", "getTimestampInTicks", "DEFAULT_META_STONE_TIMESTAMP", "isMetaStone", "addr", "getIbGibAddr", "newUpMetaStone", "targetIbGib", "targetAddr", "targetTjpAddr", "getTjpAddr", "metaStoneData", "metaStoneRel8ns", "getGibInfo", "GIB", "metaStoneTimestampDate", "metaStoneTimestamp", "getTimestamp", "metaStoneTimestampMs", "isBinary", "metaStoneIb", "metaStoneIbGib", "constantIbGib", "WITNESS_ATOM", "WITNESS_ARG_METADATA_STRING", "WITNESS_RESULT_METADATA_STRING", "WITNESS_CONTEXT_REL8N_NAME", "logalot", "getFromSpace", "addr", "addrs", "isDna", "space", "force", "lc", "logalot", "argGet", "getSpaceArgMetadata", "result", "error", "__name", "putInSpace", "ibGib", "ibGibs", "x", "argPutIbGibs", "getIbGibAddr", "resPutIbGibs", "warning", "errorMsg", "deleteFromSpace", "argDel", "persistTransformResult", "resTransform", "newIbGib", "intermediateIbGibs", "dnas", "argPutDnas", "resPutDnas", "getSpecialRel8dIbGibs", "type", "rel8nName", "special", "getSpecialIbGib", "rel8dAddrs", "rel8dIbgibs", "resGet", "initialize", "zeroSpace", "fnUpdateBootstrap", "fnBroadcast", "fnGetInitializing", "fnSetInitializing", "dontWarnIfNotExist", "key", "getSpecialConfigKey", "getConfigAddr", "createSpecial", "resSpecial", "specialIbGib", "resLatest", "getLatestAddrs", "specialAddr", "latestAddr", "emsg", "dontWarn", "setConfigAddr", "rel8nsToAddByAddr", "resNewSpace", "rel8", "newSpace", "getCurrentRoot", "roots", "currentRootAddr", "resCurrentRoot", "setCurrentRoot", "root", "rootAddr", "resNewRoots", "configKey", "newRoots", "newRootsAddr", "registerNewIbGib", "rel8ToCurrentRoot", "linked", "currentRoot", "tjpAddr", "getTjpAddr", "ibGibAddr", "DEFAULT_ROOT_REL8N_NAME", "resNewRoot", "newRoot", "newRootAddr", "createAndSaveNewMetaStone", "targetIbGib", "metaStone", "newUpMetaStone", "resPutMetaStone", "extractErrorMsg", "initialLogalot", "getGibInfo", "tjp", "getTjpIbGib", "replaceLatest", "success", "latestAddrsMap", "errors", "pretty", "keysLatestAddrsMap", "existingLatestAddr", "resExistingLatest", "existingLatestIbGib", "n_ibGib", "n_existingLatest", "getLatestAddr_Brute", "rel8ToSpecialIbGib", "ibGibsToRel8", "ibGibsToUnRel8", "addrsToUnRel8", "severPast", "deletePreviousSpecialIbGib", "addrsToRel8", "resGetSpecial", "oldSpecialIbGib", "resNewSpecial", "Rel8n", "newSpecialIbGib", "getGib", "newSpecialAddr", "specialTjpAddr", "naive", "gib", "getIbAndGib", "GIB", "isTjp_Naive", "firstTjpAddr", "resGetTjpIbGib", "resErrorMsg", "past", "pastIbGibAddr", "resGetPastIbGib", "pastIbGib", "createSpecial_Roots", "createSpecial_Tags", "createSpecial_Secrets", "createSpecial_Encryptions", "createSpecial_OuterSpaces", "createSpecial_Autosyncs", "createSpecial_Robbots", "createSpecial_Apps", "createSpecial_Default", "createSpecialIbGib", "skipRel8ToRoot", "specialIb", "getSpecialIbGibIb", "src", "Factory_V1", "fork", "initialTagDatas", "data", "createTagIbGibAndSundry", "text", "icon", "description", "DEFAULT_TAG_ICON", "DEFAULT_TAG_DESCRIPTION", "tagIb", "tagTextToIb", "tagPrimitive", "resNewTag", "newTag", "newTagsAddr", "rel8TagToTagsIbGib", "rootsIbGib", "rootsAddr", "initialDatas", "n", "DEFAULT_ROOT_ICON", "DEFAULT_ROOT_DESCRIPTION", "firstRoot", "i", "resCreate", "createRootIbGib", "DEFAULT_ROOT_TEXT", "ib", "getRootIb", "parentIbGib", "resNewIbGib", "ROOT_REL8N_NAME", "secretsAddr", "secretsIbgib", "encryptionsIbgib", "outerSpacesAddr", "outerSpacesIbGib", "autosyncsAddr", "autosyncsIbGib", "robbotsAddr", "robbotsIbGib", "appsAddr", "appsIbGib", "createApp", "DEFAULT_CHAT_APP_DATA_V1", "DEFAULT_CHAT_APP_REL8NS_V1", "DEFAULT_RAW_APP_DATA_V1", "DEFAULT_RAW_APP_REL8NS_V1", "DEFAULT_TODO_APP_DATA_V1", "DEFAULT_TODO_APP_REL8NS_V1", "defaultAppData", "defaultAppRel8ns", "clone", "rel8ns", "DEFAULT_UUID_TODO_APP", "getUUID", "classname", "getAppIb", "resNewApp", "APP_REL8N_NAME", "existingLatest", "ibGibPast", "existingLatestPast", "newerAddr", "firstIterationCount", "getPastCount", "otherAddr", "xPast", "newCount", "resNextX", "ibGibPastCount", "existingPastCount", "tagIbGib", "TAG_REL8N_NAME", "getSpaceLockAddr", "space", "scope", "lc", "logalot", "IBGIB_DELIMITER", "spaceId", "ib", "SPACE_LOCK_IB_TERM", "getIbGibAddr", "GIB", "error", "__name", "execInSpaceWithLocking", "secondsValid", "maxDelayMs", "fn", "callerInstanceId", "maxLockAttempts", "resultFn", "lockIbGib", "DEFAULT_MAX_DELAY_MS_RETRY_LOCK_ACQUIRE", "attempts", "DEFAULT_MAX_DELAY_RETRY_LOCK_ACQUIRE_ATTEMPTS", "lockSpace", "delayMs", "delay", "lc2", "unlockSpace", "getValidatedBootstrapIbGib", "zeroSpace", "bootstrapAddr", "BOOTSTRAP_IBGIB_ADDR", "argGet", "getSpaceArgMetadata", "resGetBootstrapIbGib", "bootstrapIbGib", "pretty", "validateBootstrapIbGib", "getLocalSpace", "localSpaceId", "lock", "fnDtoToSpace", "localSpaceCacheSvc", "validatedBootstrapIbGib", "DEFAULT_SECONDS_VALID_LOCAL", "BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY", "localSpaceAddr", "fnGet", "resLocalSpace", "localSpaceDto", "localSpace", "instanceId", "resLockIbGib", "spaceLockAddr", "existingLock", "getLock", "getFromSpace", "isExpired", "clone", "gib", "getIbAndGib", "getExpirationUTCString", "argPut", "resPut", "getLockRace", "existingLockRace", "emsg", "resDelete", "deleteFromSpace", "updateBootstrapIbGib", "setSpaceAsDefault", "createIfNotFound", "newSpaceAddr", "existingSpaceAddr", "bootstrapIb", "Factory_V1", "BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY", "argPutBootstrap", "resPutBootstrap", "getTimestampInTicks", "getSpaceResultMetadata", "getSpaceIb", "spaceData", "classname", "name", "IBGIB_SPACE_NAME_DEFAULT", "id", "spaceType", "spaceSubtype", "WITNESS_ATOM", "SPACE_ATOM", "isSpaceIb", "parseSpaceIb", "spaceIb", "witnessAtom", "spaceAtom", "spaceClassname", "spaceName", "spaceType_string", "spaceSubtype_string", "VALID_SPACE_TYPES", "VALID_SPACE_SUBTYPES", "getLatestAddrs", "ibGibs", "addrs", "tjps", "tjpAddrs", "space", "lc", "logalot", "addrsToQuery", "ibGib", "getIbGibAddr", "tjpGibs", "x", "getIbAndGib", "ibGibAddr", "gib", "tjpGib", "argGet", "getSpaceArgMetadata", "error", "__name", "throwIfContextIsSpecial", "ibGib_Context", "isSpecial", "trash", "rel8nName_Context", "addr", "zeroSpace", "fnUpdateBootstrap", "fnBroadcast", "contextIsSpecialIbGib", "resNewContext", "rel8", "TRASH_REL8N_NAME", "persistTransformResult", "newSpecialAddr", "specialType", "getSpecialTypeFromIb", "configKey", "getSpecialConfigKey", "setConfigAddr", "registerNewIbGib", "archive", "ARCHIVE_REL8N_NAME", "spaceNameIsValid", "name", "regexOnlyIncluded", "matchOnlyIncluded", "regexStart", "logalot", "constantIbGib", "parentPrimitiveIb", "ib", "ibRegExpPattern", "data", "rel8ns", "lc", "validateIb", "regExp", "IB_REGEXP_DEFAULT", "incomingRel8nNames", "forbiddenRel8nNames", "FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES", "x", "Factory_V1", "getGib", "error", "__name", "getBinHashAndExt", "addr", "parseBinIb", "__name", "lc", "isBinary", "ib", "getIbAndGib", "ibPieces", "error", "ibGib", "getIbGibAddr", "gib", "UUID_REGEXP", "getSpecialIbGibIb", "type", "SPECIAL_IBGIB_TYPE_REGEXP", "__name", "getSpecialTypeFromIb", "ib", "lc", "logalot", "isSpecial", "pieces", "specialType", "SpecialIbGibType", "x", "error", "getSpecialIbGibAddr", "GIB", "getSpecialConfigKey", "CONFIG_KEY_ATOM", "ibGib", "getRootIb", "rootText", "tagTextToIb", "tagText", "splitPerTjpAndOrDna", "ibGibs", "filterPrimitives", "mapWithTjp_YesDna", "mapWithTjp_NoDna", "mapWithoutTjps", "hasTjp", "getTimelinesGroupedByTjp", "mapIbGibsWithTjp", "ibGibsWithTjp", "mapTjpTimelines_Ascending", "groupBy", "getIbGibAddr", "pretty", "_tjpAddr", "timeline", "a", "b", "dnaPrimitives", "GIB_DELIMITER", "getGibInfo", "getTjpAddr", "ibGib", "defaultIfNone", "lc", "tjpMap", "getTjpAddrs", "error", "__name", "ibGibs", "resultMap", "ibGibAddr", "getIbGibAddr", "tjpAddr", "isTjp_Naive", "naive", "logalot", "toDto", "dtoIbGib", "isBinary", "clone", "isIbGib", "obj", "getTimestampInfo", "data", "timestamp", "ms", "emsg", "parsedTimestamp", "date", "INVALID_DATE_STRING", "extractErrorMsg", "getIbGibsFromCache_fallbackToSpaces", "addrs", "readCache_graph", "readCache_array", "space", "allIbGibs_graph", "x", "allCachedAddrs", "addrsNotFoundInCache", "spaces", "addrsStillNotFound", "resGet", "getFromSpace", "addr", "gottenIbGib", "resIbGibs", "GLOBAL_LOG_A_LOT", "SPACE_GIB_DB_NAME", "SPACE_GIB_STORE_NAME", "SPACE_GIB_API_KEY_NAME", "TAG_AGENT_TEXT", "TAG_AGENT_IB", "tagTextToIb", "TAG_AGENT_TEXT", "APP_CONFIG", "SPACE_GIB_DB_NAME", "SPACE_GIB_STORE_NAME", "ZERO_SPACE_ID", "SPACE_GIB_API_KEY_NAME", "AUTO_GENERATED_VERSION", "GLOBAL_LOG_A_LOT", "GLOBAL_TIMER_NAME", "GLOBAL_THIS_IBGIB_KEY", "TAG_AGENT_TEXT", "TAG_AGENT_ICON", "TAG_AGENT_DESCRIPTION", "TAG_AGENT_IB", "tagTextToIb", "DEFAULT_IBGIB_COLOR", "DEFAULT_IBGIB_TRANSLUCENT", "DEFAULT_IBGIB_COLOR_CONTRAST", "HARDCODED_PROMPT_TAG_TEXT", "logalot", "uint8ArrayToBase64", "uint8Array", "resolve", "reject", "blob", "reader", "base64String", "error", "__name", "base64ToUint8Array", "dataUrl", "buffer", "serializeGraphToString", "graph", "lc", "serializableGraph", "key", "jsonString", "extractErrorMsg", "deserializeStringToGraph", "parsedGraph", "value", "data", "compressIbGibToBlob", "dataToCompress", "compressedStream", "decompressIbGibFromBlob", "compressedBlob", "decompressedStream", "compressIbGibGraphToString", "decompressIbGibGraphFromString", "compressedBase64", "compressedUint8Array", "RAW_EXPORT_ATOM", "logalot", "getRawExportIb", "data", "lc", "graphSize", "dependencyGraphAsString", "timestamp", "graphStringLength", "timestampInTicks", "getTimestampInTicks", "compressDescription", "date", "ib", "gib", "getIbAndGib", "tjpGib", "getGibInfo", "dateString", "RAW_EXPORT_ATOM", "error", "extractErrorMsg", "__name", "getRawExportIbGib", "ibGib", "metaspace", "space", "compress", "live", "ignoreErrors", "lc", "logalot", "ibGibAddr", "getIbGibAddr", "errorInfos", "validationErrors", "validateIbGibIntrinsically", "errorMsg", "resGraph", "dependencyGraphAsString", "compressIbGibGraphToString", "serializeGraphToString", "tjpAddr", "getTjpAddr", "now", "exportData", "getTimestamp", "exportIbGib", "getRawExportIb", "exportGib", "getGib", "error", "extractErrorMsg", "__name", "logalot", "GLOBAL_LOG_A_LOT", "showFullscreenDialog", "opts", "lc", "dialog", "dialogBody", "titleElement", "messageElement", "promptInput", "okButton", "cancelButton", "child", "line", "pLine", "onKeypress", "__name", "ev", "resolve", "removeEventListeners", "onOK", "onCancel", "onClose", "result", "delay", "error", "extractErrorMsg", "logalot", "GLOBAL_LOG_A_LOT", "getTagsIbGib", "metaspace", "space", "lc", "tagsIbGib", "SpecialIbGibType", "error", "extractErrorMsg", "__name", "getIndexNameFromIbGib", "scope", "ibGib", "ibGibAddr", "defaultNameIfError", "primitiveAncestorIb", "atom", "ancestorIbOrAtom", "getIbGibAddr", "primitiveAncestorAddrs", "x", "isPrimitive", "getIbAndGib", "primitiveAncestorAddr", "ib", "indexName", "getLocalCoupledIbGibForDomainIbGib", "skipGetLatest", "indexSpecialIbGibType", "domainTjpAddr", "getTjpAddr", "fn", "specialIndex", "coupledAddr", "addrToGet", "resGet", "execInSpaceWithLocking", "getTimestampInTicks", "coupleDomainIbGibWithLocalIbGibViaIndex", "domainIbGib", "localIbGib", "localAddr", "agentSpecialIndex", "map", "coupleMap", "clone", "existingMappedAgentAddr", "resNewSpecial", "mut8", "Rel8n", "newSpecialIbGib", "persistTransformResult", "configKey", "getSpecialConfigKey", "getIbGibGlobalThis_IbGib", "lc", "logalot", "result", "GLOBAL_THIS_IBGIB_KEY", "error", "extractErrorMsg", "__name", "getGlobalMetaspace_waitIfNeeded", "delayIntervalMs", "metaspace", "delay", "getDeterministicColorInfo", "ibGibAddr", "gib", "ibGib", "translucentAlpha", "GIB", "getIbAndGib", "gibInfo", "getGibInfo", "drivingHash", "DEFAULT_IBGIB_COLOR", "DEFAULT_IBGIB_TRANSLUCENT", "DEFAULT_IBGIB_COLOR_CONTRAST", "punctiliarColor", "punctiliarColorTranslucent", "punctiliarColorContrast", "getColorStrings", "tjpColor", "tjpColorTranslucent", "tjpColorContrast", "errorMsg", "getContrastColor", "hexcolor", "r", "g", "b", "yiq", "alphaStr", "color", "colorTranslucent", "colorContrast", "logalot", "GLOBAL_LOG_A_LOT", "uint8ArrayToString", "array", "__name", "PathUtilsHelper", "_PathUtilsHelper", "path", "paths", "lc", "joined", "i", "ext", "promptForText", "msg", "title", "confirm", "noNewLine", "rl", "defaultValue", "dontCloseRl", "cancelable", "lc", "result", "attempts", "maxAttempts", "delay", "showFullscreenDialog", "error", "extractErrorMsg", "__name", "promptForSecret", "logalot", "firstTry", "result2", "alertUser", "msg", "title", "skipHitEnterToContinue", "lc", "delay", "showFullscreenDialog", "error", "extractErrorMsg", "__name", "getRawExportIbGibAndGraphFromJsonString", "exportIbGibJsonString", "metaspace", "lc", "logalot", "parsedIbGib_notYetValidated", "parsedExportIbGib_dependenciesNotValidated", "error", "emsg", "extractErrorMsg", "errorHack", "validationErrors", "validateIbGibIntrinsically", "payloadGraph", "decompressIbGibGraphFromString", "deserializeStringToGraph", "validationErrorMap", "addr", "payloadIbGib", "pretty", "__name", "exportIbGib", "ibGib", "compress", "space", "isPrimitive", "resGetExport", "getRawExportIbGib", "exportErrors", "exportIbGibAsString", "dataStr", "filename", "getIbGibAddr", "downloadAnchorEl", "div", "getGlobalStoreName", "lc", "logalot", "hackGlobal", "getIbGibGlobalThis_IbGib", "error", "extractErrorMsg", "__name", "getGlobalDbName", "getGlobalIndexedDbKey_APIKey", "initAppStorage", "infos", "info", "dbName", "storeNames", "storageDBExists", "initializeStorage", "storeName", "storageCreateStoreIfNotExist", "logalot", "GLOBAL_LOG_A_LOT", "initRequestCount", "initializeStorage", "dbName", "storeName", "version", "logalot", "lc", "uuid", "db", "resolve", "reject", "openDBRequest", "initRequestCount", "storeAlreadyExisted", "event", "error", "extractErrorMsg", "ev", "__name", "storageGetDBInfo", "x", "storageCreateStoreIfNotExist", "storeExists", "dbInfo", "newVersion", "storagePut", "key", "value", "store", "data", "storageGet", "getRequest", "uint8ArrayToString", "storageDBExists", "storageRmRF", "pathToRm", "logalotInitDebug", "objectStore", "range", "openCursorRequest", "rmCount", "cursor", "deleteRequest", "storageReaddir", "dirPath", "withFileTypes", "normalizedDirPath", "entries", "dirents", "relativePath", "childSegment", "isDirectory", "logalot", "GLOBAL_LOG_A_LOT", "initIbGibStorage", "config", "lc", "initAppStorage", "error", "extractErrorMsg", "__name", "initIbGibGlobalThis", "AUTO_GENERATED_VERSION", "storageGet", "getIbGibGlobalThis_SpaceGib", "dynamicallyLoadBootstrapScript", "path", "lc", "logalot", "error", "extractErrorMsg", "__name", "getComponentCtorArg", "fnGetMetaspace", "getGlobalMetaspace_waitIfNeeded", "bootstrapPromiseWrapper", "resolve", "reject", "maxTries", "counter", "bootstrapPromise", "getIbGibGlobalThis_SpaceGib", "delay", "KEYSTONE_CHALLENGE_TYPE_HASH_REVEAL_V1", "KeystoneChallengeType", "KEYSTONE_CHALLENGE_TYPE_VALID_VALUES", "KEYSTONE_REPLENISH_STRATEGY_TOP_UP", "KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL", "KEYSTONE_REPLENISH_STRATEGY_CONSUME", "KEYSTONE_REPLENISH_STRATEGY_DELETE_ALL", "KeystoneReplenishStrategy", "KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES", "KeystoneStrategy", "__name", "config", "KDF_STRATEGY_RECURSIVE_SALT_WRAP", "KdfStrategy", "KDF_STRATEGY_VALID_VALUES", "logalot", "kdf_recursiveSaltWrap", "masterSecret", "salt", "rounds", "algorithm", "HashAlgorithm", "lc", "logalot", "current", "i", "hash", "error", "extractErrorMsg", "__name", "KeystoneStrategy_HashRevealV1", "_KeystoneStrategy_HashRevealV1", "KeystoneStrategy", "__name", "masterSecret", "lc", "salt", "rounds", "algo", "kdf_recursiveSaltWrap", "error", "poolSecret", "poolId", "challengeId", "indexSalt", "current", "i", "hash", "solution", "value", "challenge", "KeystoneStrategyFactory", "_KeystoneStrategyFactory", "__name", "config", "lc", "KeystoneStrategy_HashRevealV1", "error", "KEYSTONE_ATOM", "KEYSTONE_POOL_ID_REGEXP", "KEYSTONE_SALT_REGEXP", "KEYSTONE_HASH_MAX_ROUNDS", "KEYSTONE_VERB_REVOKE", "KEYSTONE_VERB_MANAGE", "KEYSTONE_VERB_SIGN", "KeystoneVerb", "KEYSTONE_VERB_VALID_VALUES", "POOL_ID_REVOKE", "KEYSTONE_VERB_REVOKE", "KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY", "KeystoneReplenishStrategy", "KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM", "HashAlgorithm", "KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY", "KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL_HIGHSECURITY", "KEYSTONE_CONFIG_DEFAULT_RANDOM_HIGHSECURITY", "KEYSTONE_CONFIG_DEFAULT_BINDING_HIGHSECURITY", "KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY_HIGHSECURITY", "KeystoneReplenishStrategy", "KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM_HIGHSECURITY", "HashAlgorithm", "KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS_HIGHSECURITY", "KEYSTONE_CHECKPOINT_FREQUENCY", "logalot", "getDependencyGraph", "ibGib", "ibGibs", "ibGibAddr", "ibGibAddrs", "live", "gotten", "tjpAddrsAlreadyAnalyzed", "skipAddrs", "skipRel8nNames", "onlyRel8nNames", "maxRetries", "msBetweenRetries", "space", "timeLogName", "mapTjpAddrToLatestAddrsInSpace", "lc", "graph", "getGraphProjection", "ibs", "unique", "ib", "error", "__name", "getGraphProjection_initializeOpts", "x", "isPrimitive", "getIbAndGib", "getIbGibAddr", "getGraphProjection_getIbGibsInIbGibAddrs", "resIbGibs", "addrsToGetFromSpace", "gottenAddrs", "incomingIbGibAddrs", "i", "addr", "addrsToGet", "retryCount", "delay", "resGetThese", "getFromSpace", "gottenIbGibs", "opts", "supplementalIbGibs", "commentIbs", "getGraphProjection_Live", "getGraphProjection_NonLive", "getGraphProjection_Live", "ibGibs", "ibGibAddrs", "gotten", "tjpAddrsAlreadyAnalyzed", "mapTjpAddrToLatestAddrsInSpace", "skipAddrs", "skipRel8nNames", "onlyRel8nNames", "maxRetries", "msBetweenRetries", "space", "timeLogName", "lc", "allIbGibsSoFar", "x", "getIbGibAddr", "allKnownTimelinesAtThisPoint", "getTimelinesGroupedByTjp", "logalot", "timelinesNotAnalyzed", "tjpAddr", "pretty", "mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed", "mapLatestAddrAlreadyGottenToTjpAddr", "timeline", "latestIbGibAlreadyGotten", "latestAddrAlreadyGotten", "countOfTimelinesNotYetGotten", "latestAddrsMap", "latestIbGibCorrespondingToTjpAddr", "latestAddrCorrespondingToTjpAddr", "ibGibsToQueryLatestAddrs", "queriedLatestAddrsMap", "resLatestAddrsMapInEntireSpace", "getLatestAddrs", "newerAddrsFound", "newerAddrFoundToTjpAddrMap", "latestAddrInSpace", "rel8dAddrsNotYetGotten", "i", "rel8ns", "rel8nName", "rel8dAddr", "unique", "getGraphProjection", "addr", "y", "error", "emsg", "__name", "getGraphProjection_NonLive", "addrsWeDontHaveAlready_Rel8dAddrs", "ibGib", "ibGibAddr", "gib", "getIbAndGib", "GIB", "invalidAddrs", "rel8nNames", "gottenKeys", "rel8dAddrs", "falsyAddrs", "IBGIB_DELIMITER", "validationErrors", "validateIbGibAddr", "resGet", "getFromSpace", "result", "logalot", "getKeystoneIb", "keystoneData", "lc", "KEYSTONE_ATOM", "error", "extractErrorMsg", "__name", "getDeterministicRequirements", "pool", "requiredChallengeIds", "targetAddr", "behavior", "mandatory", "available", "id", "gib", "getIbAndGib", "prefixes", "GIB", "char", "match", "__name", "addToBindingMap", "map", "challengeId", "firstChar", "removeFromBindingMap", "key", "resolveTargetPool", "pools", "poolId", "poolFilter", "verb", "lc", "p", "matches", "error", "extractErrorMsg", "selectChallengeIds", "mandatoryIds", "availableIds", "randomCount", "randomIds", "shuffled", "generateOpaqueChallengeId", "salt", "timestamp", "index", "hash", "applyReplenishmentStrategy", "prevPools", "targetPoolId", "consumedIds", "masterSecret", "strategy", "config", "newPools", "targetIdx", "poolSecret", "strategyType", "KeystoneReplenishStrategy", "i", "newId", "solution", "pretty", "KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES", "solveAndReplenish", "challengeIds", "claim", "logalot", "KeystoneStrategyFactory", "solutions", "proof", "nextPools", "validateChallengePool_typeHashRevealV1", "KeystoneChallengeType", "errors", "algo", "rounds", "validAlgos", "HashAlgorithm", "KEYSTONE_HASH_MAX_ROUNDS", "KEYSTONE_SALT_REGEXP", "validateChallengePool", "KEYSTONE_POOL_ID_REGEXP", "size", "poolType", "x", "KEYSTONE_CHALLENGE_TYPE_VALID_VALUES", "validateGenesisKeystone", "keystoneIbGib", "data", "rel8ns", "validateKeystoneTransition", "currentIbGib", "prevIbGib", "validationErrors", "validateIbGibIntrinsically", "currData", "prevData", "currDataN", "prevDataN", "verifyProofAgainstPool", "target", "expectedTarget", "getIbGibAddr", "proofIds", "s", "randomCandidates", "requiredRandomCount", "challenge", "evolvePersistAndRegisterKeystone", "newData", "metaspace", "space", "dataToRemove", "resMut8", "mut8", "newKeystoneIbGib", "createKeystoneIbGibImpl", "Factory_V1", "KEYSTONE_ATOM", "getKeystoneIb", "getGib", "validateKeystoneGraph", "dependencyGraph", "getLatest", "invalidIfMoreRecentKeystoneFoundInSpace", "keystoneAddr", "resGetLatestAddrs", "getLatestAddrs", "latestAddrsMap", "latestAddr", "latestKeystoneIbGib", "getIbGibsFromCache_fallbackToSpaces", "getDependencyGraph", "depIbGibs", "mapWithTjp_NoDna", "mapWithTjp_YesDna", "mapWithoutTjps", "splitPerTjpAndOrDna", "keystoneIbGibs_unordered", "orderedKeystonesMap", "getTimelinesGroupedByTjp", "keys", "keystoneTjpAddr", "keystoneIbGibs_ordered", "transitionErrors", "logalot", "KeystoneService_V1", "_KeystoneService_V1", "__name", "masterSecret", "frameDetails", "configs", "metaspace", "space", "lc", "challengePools", "config", "strategy", "KeystoneStrategyFactory", "poolSecret", "challenges", "bindingMap", "targetSize", "timestamp", "i", "challengeId", "generateOpaqueChallengeId", "solution", "challenge", "addToBindingMap", "data", "createKeystoneIbGibImpl", "error", "extractErrorMsg", "latestKeystone", "claim", "poolId", "poolFilter", "requiredChallengeIds", "prevData", "pool", "resolveTargetPool", "idsToSolve", "selectChallengeIds", "proof", "nextPools", "solveAndReplenish", "n", "checkpointDetails", "KEYSTONE_CHECKPOINT_FREQUENCY", "currentFrameView", "evolvePersistAndRegisterKeystone", "currentIbGib", "prevIbGib", "validateKeystoneTransition", "keystoneIbGib", "validateGenesisKeystone", "addr", "latestAddr", "resGet", "addrsNotFound", "dependencyGraph", "getLatest", "invalidIfMoreRecentKeystoneFoundInSpace", "validateKeystoneGraph", "reason", "POOL_ID_REVOKE", "KEYSTONE_VERB_REVOKE", "getIbGibAddr", "p", "KeystoneReplenishStrategy", "revocationInfo", "newPools", "adminPool", "KEYSTONE_VERB_MANAGE", "target", "replenishedExistingPools", "existingIds", "newPool", "finalPools", "aggregated", "current", "mergeMapsOrArrays_Naive", "past", "prevAddr", "res", "logalot", "KeystoneConfigBuilderBase", "__name", "id", "salt", "size", "chars", "count", "seqCount", "randCount", "strategy", "verbs", "KeystoneConfigBuilder_HashV1", "_KeystoneConfigBuilder_HashV1", "algo", "rounds", "lc", "error", "extractErrorMsg", "KeystoneChallengeType", "KeystoneConfig", "createHighSecurityPoolConfig", "opts", "KeystoneChallengeType", "salt", "id", "size", "sequential", "random", "targetBinding", "replenishStrategy", "verbs", "hashAlgorithm", "hashRounds", "KeystoneConfig", "KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY", "KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL_HIGHSECURITY", "KEYSTONE_CONFIG_DEFAULT_RANDOM_HIGHSECURITY", "KEYSTONE_CONFIG_DEFAULT_BINDING_HIGHSECURITY", "KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY_HIGHSECURITY", "KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM_HIGHSECURITY", "KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS_HIGHSECURITY", "__name", "createManagePoolConfig", "KeystoneVerb", "SESSION_KEYSTONE_POLICY", "HashAlgorithm", "KeystoneChallengeType", "KeystoneReplenishStrategy", "DOMAIN_KEYSTONE_SECURITY_STANDARDS", "getHandshakeChallenge", "keystone", "handshakePool", "p", "challengeIds", "challengeId", "challenge", "__name", "SpaceGibApiBridge", "__name", "keystoneIbGib", "lc", "response", "data", "errorMsg", "error", "extractErrorMsg", "domainAddr", "relatedIbGibs", "url", "spaceGibApiBridge", "lc", "debugState", "devLog", "msg", "logEl", "timestamp", "__name", "_ws", "initWsTestButton", "lc_fn", "btn", "wsUrl", "ev", "error", "extractErrorMsg", "initPrintStateButton", "initCreateDomainKeystoneButton", "metaspace", "getGlobalMetaspace_waitIfNeeded", "space", "masterSecret", "domainI", "KeystoneService_V1", "createManagePoolConfig", "getUUID", "KeystoneReplenishStrategy", "getTimestamp", "iAddr", "getIbGibAddr", "resSync", "SpaceGibApiBridge", "nextBtn", "initCreateTestIbGibButton", "xIbGib", "Factory_V1", "ROOT", "xAddr", "initCreateSessionKeystoneButton", "targetX", "sessionSecret", "keystoneService", "sIbGib", "SESSION_KEYSTONE_POLICY", "sAddr", "initEvolveDomainKeystoneButton", "sessionS", "evolvedI", "evolvedAddr", "apiBridge", "domainAddr", "initPerformSyncButton", "handshakePool", "p", "challengeId", "getHandshakeChallenge", "strategy", "KeystoneStrategyFactory", "poolSecret", "solution", "ws", "challengeUuid", "demandedIds", "proofFrame", "initDevTools"]
|
|
7
|
+
}
|