@overmap-ai/core 1.0.25 → 1.0.26
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/dist/overmap-core.js +478 -257
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +478 -257
- package/dist/overmap-core.umd.cjs.map +1 -1
- package/dist/sdk/sdk.d.ts +3 -1
- package/dist/sdk/services/AuthService.d.ts +2 -2
- package/dist/sdk/services/EmailDomainsService.d.ts +8 -0
- package/dist/sdk/services/MainService.d.ts +2 -1
- package/dist/sdk/services/OrganizationAccessService.d.ts +3 -0
- package/dist/sdk/services/OrganizationService.d.ts +7 -0
- package/dist/sdk/services/ProjectAccessService.d.ts +3 -4
- package/dist/sdk/services/index.d.ts +2 -0
- package/dist/store/slices/categorySlice.d.ts +1 -0
- package/dist/store/slices/emailDomainsSlice.d.ts +20 -0
- package/dist/store/slices/index.d.ts +1 -0
- package/dist/store/slices/issueSlice.d.ts +1 -0
- package/dist/store/slices/organizationSlice.d.ts +8 -2
- package/dist/store/slices/projectFileSlice.d.ts +1 -0
- package/dist/store/slices/projectSlice.d.ts +4 -1
- package/dist/store/slices/userSlice.d.ts +5 -3
- package/dist/store/slices/workspaceSlice.d.ts +1 -0
- package/dist/store/store.d.ts +3 -0
- package/dist/typings/models/access.d.ts +1 -1
- package/dist/typings/models/emailDomain.d.ts +5 -0
- package/dist/typings/models/index.d.ts +1 -0
- package/dist/typings/models/organizations.d.ts +1 -0
- package/dist/typings/models/users.d.ts +3 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overmap-core.umd.cjs","sources":["../src/sdk/classes/OutboxCoordinator.ts","../src/sdk/errors.ts","../src/utils/async/DeferredPromise.ts","../node_modules/redux/node_modules/@babel/runtime/helpers/esm/typeof.js","../node_modules/redux/node_modules/@babel/runtime/helpers/esm/toPrimitive.js","../node_modules/redux/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js","../node_modules/redux/node_modules/@babel/runtime/helpers/esm/defineProperty.js","../node_modules/redux/node_modules/@babel/runtime/helpers/esm/objectSpread2.js","../node_modules/redux/es/redux.js","../src/enums/api.ts","../src/enums/issue.ts","../src/enums/map.ts","../src/store/migrations.ts","../src/store/slices/authSlice.ts","../src/utils/coordinates.ts","../src/utils/css.ts","../src/utils/file.ts","../src/utils/logging.ts","../src/utils/offline.ts","../src/utils/search.ts","../src/utils/string.ts","../src/utils/utils.ts","../src/utils/optimization.ts","../node_modules/@radix-ui/colors/index.mjs","../src/utils/colors.ts","../src/utils/date.ts","../src/store/slices/categorySlice.ts","../src/store/slices/componentSlice.ts","../src/store/slices/ComponentStageCompletionSlice.ts","../src/store/slices/componentStageSlice.ts","../src/store/slices/componentTypeSlice.ts","../src/store/slices/workspaceSlice.ts","../src/store/slices/issueSlice.ts","../src/store/slices/fileSlice.ts","../src/store/slices/mapSlice.ts","../src/store/slices/organizationSlice.ts","../src/store/slices/outboxSlice.ts","../src/store/slices/projectAccessSlice.ts","../src/typings/models/access.ts","../src/typings/models/projects.ts","../src/typings/models/emailVerification.ts","../src/store/slices/projectSlice.ts","../src/store/slices/projectFileSlice.ts","../src/store/slices/rehydratedSlice.ts","../src/store/slices/settingsSlice.ts","../src/store/slices/userFormSlice.ts","../src/store/slices/userSlice.ts","../src/store/slices/organizationAccessSlice.ts","../src/store/slices/versioningSlice.ts","../src/constants/ui.ts","../src/constants/defaults.ts","../src/constants/offline.ts","../src/store/store.ts","../src/store/hooks.ts","../src/sdk/services/BaseApiService.ts","../src/sdk/services/AttachmentService.ts","../src/sdk/services/AuthService.ts","../src/sdk/services/CategoryService.ts","../src/sdk/services/ComponentService.ts","../src/sdk/services/ComponentStageCompletionService.ts","../src/sdk/services/ComponentStageService.ts","../src/sdk/services/ComponentTypeService.ts","../src/sdk/services/IssueCommentService.ts","../src/sdk/services/IssueService.ts","../src/sdk/services/MainService.ts","../src/sdk/services/ProjectAccessService.ts","../src/sdk/services/ProjectFileService.ts","../src/sdk/services/ProjectService.ts","../src/sdk/services/UserFormService.ts","../src/sdk/services/UserFormSubmissionService.ts","../src/sdk/services/WorkspaceService.ts","../src/sdk/services/OrganizationAccessService.ts","../src/sdk/services/FileService.ts","../src/sdk/services/EmailVerificationService.ts","../src/sdk/sdk.ts","../src/contexts/sdk/sdk.tsx","../src/contexts/sdk/hooks.ts","../src/contexts/overmap.tsx"],"sourcesContent":["import { DepGraph } from \"dependency-graph\"\r\nimport type { FullOfflineAction } from \"../../store\"\r\nimport { Outbox } from \"@redux-offline/redux-offline/lib/types\"\r\n\r\n// TODO: Tests:\r\n// - Bulk-create components, then delete one of those components. Ensure the dependency to the bulk-create is found.\r\n\r\nexport class OutboxCoordinator {\r\n\tgraph: DepGraph<FullOfflineAction>\r\n\trequestAttemptCounter: Record<string, number>\r\n\r\n\tconstructor() {\r\n\t\tthis.graph = new DepGraph()\r\n\t\tthis.requestAttemptCounter = {}\r\n\t}\r\n\r\n\t/**\r\n\t * Used when the app is loaded. Reconstructs the dependency graph based on an outbox from the redux-offline store.\r\n\t */\r\n\tstatic fromOutbox(outbox: Outbox) {\r\n\t\tconst ret = new OutboxCoordinator()\r\n\r\n\t\tfor (let i = 0; i < outbox.length; i++) {\r\n\t\t\tconst outboxItem = outbox[i] as FullOfflineAction | undefined\r\n\t\t\tif (!outboxItem) {\r\n\t\t\t\tconsole.error(\"Outbox item was undefined\")\r\n\t\t\t\tcontinue\r\n\t\t\t}\r\n\t\t\tret.sneakRequest(outboxItem)\r\n\t\t\t// Add any dependencies to requests that were added before this one\r\n\t\t\tfor (let j = 0; j < i; j++) {\r\n\t\t\t\tconst previousOutboxItem = outbox[j] as FullOfflineAction | undefined\r\n\t\t\t\tif (!previousOutboxItem) {\r\n\t\t\t\t\tconsole.error(\"Previous outbox item was undefined\")\r\n\t\t\t\t\tcontinue\r\n\t\t\t\t}\r\n\t\t\t\tif (previousOutboxItem.payload.uuid === outboxItem.payload.uuid) {\r\n\t\t\t\t\tcontinue // Skip self\r\n\t\t\t\t}\r\n\t\t\t\tif (previousOutboxItem.payload.blocks.some((block) => outboxItem.payload.blockers.includes(block))) {\r\n\t\t\t\t\tOutboxCoordinator._addDependency(\r\n\t\t\t\t\t\toutboxItem.payload.uuid,\r\n\t\t\t\t\t\tpreviousOutboxItem.payload.uuid,\r\n\t\t\t\t\t\tret.graph,\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn ret\r\n\t}\r\n\r\n\t_addDependency(from: string, to: string) {\r\n\t\tOutboxCoordinator._addDependency(from, to, this.graph)\r\n\t}\r\n\r\n\tstatic _addDependency(from: string, to: string, graph: DepGraph<FullOfflineAction>) {\r\n\t\tif (from === to) {\r\n\t\t\tthrow new Error(`Tried to add dependency from node to itself: ${from}`)\r\n\t\t}\r\n\t\tconst fromExists = graph.hasNode(from)\r\n\t\tif (!fromExists) {\r\n\t\t\tthrow new Error(`Tried to add dependency from non-existent node: ${from} (to node: ${to})`)\r\n\t\t}\r\n\t\tconst toExists = graph.hasNode(to)\r\n\t\tif (!toExists) {\r\n\t\t\tthrow new Error(`Tried to add dependency to non-existent node: ${to} (from node: ${from})`)\r\n\t\t}\r\n\t\tgraph.addDependency(from, to)\r\n\t}\r\n\r\n\t/**\r\n\t * If there are one or more nodes in the graph, we find all nodes that match a dependency of the request and add a\r\n\t * dependency from the new request node to that node.\r\n\t */\r\n\taddRequest(request: FullOfflineAction) {\r\n\t\tthis.graph.addNode(request.payload.uuid, request)\r\n\r\n\t\tif (request.payload.blockers.length === 0 || this.graph.size() === 1) {\r\n\t\t\t// The request has no dependencies, or there are no other nodes in the graph, so there are no dependencies\r\n\t\t\t// to create.\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Create dependencies according to the request's blockers\r\n\t\tfor (const node of this.graph.overallOrder()) {\r\n\t\t\tif (node === request.payload.uuid) continue // Skip the node we just added\r\n\t\t\tconst details = this.graph.getNodeData(node)\r\n\t\t\t// 1. Any node matching this request's offline_id\r\n\t\t\tif (request.payload.blockers.some((blocker) => details.payload.blocks.includes(blocker))) {\r\n\t\t\t\tthis._addDependency(request.payload.uuid, node)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Inserts a request at the beginning of the queue. This could be used for requests that were popped, then failed,\r\n\t * and need to be re-enqueued at the front of the queue. Any requests that were previously blocked by this request\r\n\t * will be blocked by this request again. No blockers will be added to this request because it is assumed that the\r\n\t * request was already unblocked when it was popped.\r\n\t * @param request The request to insert at the beginning of the queue.\r\n\t */\r\n\tinsertRequest(request: FullOfflineAction) {\r\n\t\tthis.graph.addNode(request.payload.uuid, request)\r\n\r\n\t\t// Create dependencies according to the request's blockers\r\n\t\tfor (const node of this.graph.overallOrder()) {\r\n\t\t\tif (node === request.payload.uuid) continue // Skip the request we just inserted\r\n\t\t\tconst details = this.graph.getNodeData(node)\r\n\t\t\t// 1. Any node matching this request's offline_id\r\n\t\t\tif (details.payload.blockers.some((blocker) => request.payload.blocks.includes(blocker))) {\r\n\t\t\t\tthis._addDependency(node, request.payload.uuid)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Sneaks a request into the dependency graph without creating any blockers. Useful for reconstructing the graph\r\n\t * (from the offline store's outbox state) when the app is loaded.\r\n\t */\r\n\tsneakRequest(request: FullOfflineAction) {\r\n\t\tthis.graph.addNode(request.payload.uuid, request)\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the next node in line to be sent. This is the unblocked node with the fewest number of attempts. If there\r\n\t * are multiple nodes with the same number of attempts, the first one (by insertion order) will be returned.\r\n\t */\r\n\t_getNextNode(): string | undefined {\r\n\t\tconst leafNodes = this.graph.overallOrder(true)\r\n\t\tlet minAttempts = Infinity\r\n\t\tlet minAttemptsNode: string | undefined\r\n\t\tfor (const node of leafNodes) {\r\n\t\t\tconst attempts = this.requestAttemptCounter[node] || 0\r\n\t\t\tif (attempts < minAttempts) {\r\n\t\t\t\tminAttempts = attempts\r\n\t\t\t\tminAttemptsNode = node\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn minAttemptsNode\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the next request in line to be sent without removing it.\r\n\t */\r\n\tpeek(): FullOfflineAction | undefined {\r\n\t\tconst nextNode = this._getNextNode()\r\n\t\tif (!nextNode) return undefined\r\n\t\treturn this.graph.getNodeData(nextNode)\r\n\t}\r\n\r\n\t/**\r\n\t * Removes a request from the graph. This should be called when a request is successfully sent.\r\n\t * @param uuid The UUID of the request to remove.\r\n\t */\r\n\tremove(uuid: string): void {\r\n\t\tthis.graph.removeNode(uuid)\r\n\t\tdelete this.requestAttemptCounter[uuid]\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the next request in line to be sent and removes it from the graph.\r\n\t */\r\n\tpop(): FullOfflineAction | undefined {\r\n\t\tconst nextRequestDetails = this.peek()\r\n\t\tif (nextRequestDetails) {\r\n\t\t\tthis.graph.removeNode(nextRequestDetails.payload.uuid)\r\n\t\t}\r\n\t\treturn nextRequestDetails\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current queue for the outbox. Should be called to get a new value for the outbox slice every time a\r\n\t * request is enqueued. It will be used to render the outbox items in a single lane.\r\n\t */\r\n\tgetQueue(): FullOfflineAction[] {\r\n\t\tconst ret = this.graph.overallOrder().map((nodeName) => this.graph.getNodeData(nodeName))\r\n\r\n\t\t// We will return the normal overall order, except we put the request with the fewest number of attempts at the\r\n\t\t// front of the queue, assuming it is not blocked.\r\n\t\tconst nextNode = this._getNextNode()\r\n\t\tif (nextNode) {\r\n\t\t\tconst nextRequestDetails = this.graph.getNodeData(nextNode)\r\n\t\t\tconst nextRequestIndex = ret.findIndex(\r\n\t\t\t\t(request) => request.payload.uuid === nextRequestDetails.payload.uuid,\r\n\t\t\t)\r\n\t\t\tif (nextRequestIndex !== -1) {\r\n\t\t\t\tret.splice(nextRequestIndex, 1)\r\n\t\t\t\tret.unshift(nextRequestDetails)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn ret\r\n\t}\r\n\r\n\t/**\r\n\t * Gets a list of requests that can currently be sent (requests with no unresolved dependencies). Used to process\r\n\t * the next ready request in case the request at the front of the queue is failing.\r\n\t */\r\n\tgetReady(): FullOfflineAction[] {\r\n\t\tlet ret = this.graph.overallOrder(true).map((nodeName) => this.graph.getNodeData(nodeName))\r\n\t\t// First, order by insertion order\r\n\t\tret = ret.sort((a, b) => {\r\n\t\t\treturn a.meta.offline.effect.timestamp.localeCompare(b.meta.offline.effect.timestamp)\r\n\t\t})\r\n\t\t// Then, order by number of attempts\r\n\t\tret = ret.sort((a, b) => {\r\n\t\t\tconst aAttempts = this.requestAttemptCounter[a.payload.uuid] || 0\r\n\t\t\tconst bAttempts = this.requestAttemptCounter[b.payload.uuid] || 0\r\n\t\t\t// If these are equal, we want to keep the insertion order, which should be maintained from the previous\r\n\t\t\t// sort if we return 0.\r\n\t\t\treturn aAttempts - bAttempts\r\n\t\t})\r\n\t\treturn ret\r\n\t}\r\n\r\n\tregisterRetry(uuid: string): void {\r\n\t\tthis.requestAttemptCounter[uuid] = (this.requestAttemptCounter[uuid] || 0) + 1\r\n\t}\r\n}\r\n\r\n// TODO: Consider auto-discovering UUIDs instead of (or in addition to) explicitly passing them to `enqueueRequest`\r\n/**\r\n * Given a request, returns an array of discovered UUIDs referenced in the request.\r\n * Discovers UUIDs in the URL, body, and query string.\r\n * @param request\r\n */\r\n/*\r\nfunction _discoverUuids(request: RequestDetails): Set<string> {\r\n\t// We need to consider:\r\n\t// 1. Any UUID in the URL\r\n\t// 2. Any UUID in the body\r\n\t// 3. Any UUID in the query parameters\r\n\r\n\tconst ret = new Set<string>()\r\n\r\n\tfunction discoverUuidsInArray(values: unknown[]): void {\r\n\t\tfor (const value of values) {\r\n\t\t\tif (typeof value === \"string\" && value.length === 36 && UUID_REGEX.test(value)) {\r\n\t\t\t\tret.add(value)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tconst urlParts = request.url.split(\"/\")\r\n\r\n\tdiscoverUuidsInArray(urlParts)\r\n\r\n\tif (request.payload) {\r\n\t\tdiscoverUuidsInArray(Object.values(request.payload))\r\n\t}\r\n\r\n\tif (request.queryParams) {\r\n\t\tdiscoverUuidsInArray(Object.values(request.queryParams))\r\n\t}\r\n\r\n\treturn ret\r\n}\r\n */\r\n","// Contains custom error classes used by the SDK\r\n\r\nimport request from \"superagent\"\r\n\r\nexport interface APIErrorOptions {\r\n\tdiscard: boolean\r\n}\r\n\r\nexport class APIError extends Error {\r\n\t// NOTE: Needs to conform to NetworkError in @redux-offline/redux-offline, which has `status` and `response`.\r\n\tstatus: number\r\n\tmessage: string\r\n\tresponse: request.Response | undefined\r\n\toptions: APIErrorOptions\r\n\r\n\tconstructor(message: string, response?: request.Response, options?: APIErrorOptions) {\r\n\t\tsuper(response?.text)\r\n\t\tthis.message = message\r\n\t\tthis.status = response?.status ?? 0\r\n\t\tthis.response = response\r\n\t\tthis.options = options ?? { discard: false }\r\n\t}\r\n}\r\n","// https://gist.github.com/GFoley83/5877f6c09fbcfd62569c51dc91444cf0\r\n\r\n/**\r\n * A new instance of deferred is constructed by calling `new DeferredPromise<T>()`.\r\n * The purpose of the deferred object is to expose the associated Promise\r\n * instance APIs that can be used for signaling the successful\r\n * or unsuccessful completion, as well as the state of the task.\r\n * @export\r\n * @class DeferredPromise\r\n * @implements {Promise<T>}\r\n * @template T\r\n * @example\r\n * const deferred = new DeferredPromise<string>()\r\n * console.log(deferred.state) // \"pending\"\r\n *\r\n * deferred\r\n * .then(str => console.log(str))\r\n * .catch(err => console.error(err))\r\n *\r\n * deferred.resolve(\"Foo\")\r\n * console.log(deferred.state) // \"fulfilled\"\r\n * // deferred.reject(\"Bar\")\r\n */\r\nexport class DeferredPromise<T> implements Promise<T> {\r\n\t[Symbol.toStringTag] = \"Promise\"\r\n\r\n\tprivate _promise: Promise<T>\r\n\tprivate _resolve: null | ((value?: T | PromiseLike<T>) => void)\r\n\tprivate _reject: null | ((reason?: unknown) => void)\r\n\tprivate _state: \"pending\" | \"fulfilled\" | \"rejected\" = \"pending\"\r\n\r\n\tpublic get state(): \"pending\" | \"fulfilled\" | \"rejected\" {\r\n\t\treturn this._state\r\n\t}\r\n\r\n\tconstructor() {\r\n\t\tthis._resolve = null\r\n\t\tthis._reject = null\r\n\r\n\t\tthis._promise = new Promise<T>((resolve, reject) => {\r\n\t\t\tthis._resolve = resolve as (value?: T | PromiseLike<T>) => void\r\n\t\t\tthis._reject = reject\r\n\t\t})\r\n\t}\r\n\r\n\tpublic then<TResult1, TResult2>(\r\n\t\tonFulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>,\r\n\t\tonRejected?: (reason: unknown) => TResult2 | PromiseLike<TResult2>,\r\n\t): Promise<TResult1 | TResult2> {\r\n\t\treturn this._promise.then(onFulfilled, onRejected)\r\n\t}\r\n\r\n\tpublic catch<TResult>(onRejected?: (reason: unknown) => TResult | PromiseLike<TResult>): Promise<T | TResult> {\r\n\t\treturn this._promise.catch(onRejected)\r\n\t}\r\n\r\n\tpublic resolve(value?: T | PromiseLike<T>): void {\r\n\t\tif (!this._resolve) throw new Error(\"No resolve callback\")\r\n\t\tthis._resolve(value)\r\n\t\tthis._state = \"fulfilled\"\r\n\t}\r\n\r\n\tpublic reject(reason?: unknown): void {\r\n\t\tif (!this._reject) throw reason\r\n\t\tthis._reject(reason)\r\n\t\tthis._state = \"rejected\"\r\n\t}\r\n\r\n\tpublic finally(_onFinally?: (() => void) | undefined | null): Promise<T> {\r\n\t\tthrow new Error(\"`finally` not implemented\")\r\n\t}\r\n}\r\n","export default function _typeof(o) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) {\n return typeof o;\n } : function (o) {\n return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o;\n }, _typeof(o);\n}","import _typeof from \"./typeof.js\";\nexport default function _toPrimitive(input, hint) {\n if (_typeof(input) !== \"object\" || input === null) return input;\n var prim = input[Symbol.toPrimitive];\n if (prim !== undefined) {\n var res = prim.call(input, hint || \"default\");\n if (_typeof(res) !== \"object\") return res;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (hint === \"string\" ? String : Number)(input);\n}","import _typeof from \"./typeof.js\";\nimport toPrimitive from \"./toPrimitive.js\";\nexport default function _toPropertyKey(arg) {\n var key = toPrimitive(arg, \"string\");\n return _typeof(key) === \"symbol\" ? key : String(key);\n}","import toPropertyKey from \"./toPropertyKey.js\";\nexport default function _defineProperty(obj, key, value) {\n key = toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}","import defineProperty from \"./defineProperty.js\";\nfunction ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n}\nexport default function _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n}","import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';\n\n/**\n * Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js\n *\n * Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes\n * during build.\n * @param {number} code\n */\nfunction formatProdErrorMessage(code) {\n return \"Minified Redux error #\" + code + \"; visit https://redux.js.org/Errors?code=\" + code + \" for the full message or \" + 'use the non-minified dev environment for full errors. ';\n}\n\n// Inlined version of the `symbol-observable` polyfill\nvar $$observable = (function () {\n return typeof Symbol === 'function' && Symbol.observable || '@@observable';\n})();\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nvar randomString = function randomString() {\n return Math.random().toString(36).substring(7).split('').join('.');\n};\n\nvar ActionTypes = {\n INIT: \"@@redux/INIT\" + randomString(),\n REPLACE: \"@@redux/REPLACE\" + randomString(),\n PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {\n return \"@@redux/PROBE_UNKNOWN_ACTION\" + randomString();\n }\n};\n\n/**\n * @param {any} obj The object to inspect.\n * @returns {boolean} True if the argument appears to be a plain object.\n */\nfunction isPlainObject(obj) {\n if (typeof obj !== 'object' || obj === null) return false;\n var proto = obj;\n\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n\n return Object.getPrototypeOf(obj) === proto;\n}\n\n// Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of\nfunction miniKindOf(val) {\n if (val === void 0) return 'undefined';\n if (val === null) return 'null';\n var type = typeof val;\n\n switch (type) {\n case 'boolean':\n case 'string':\n case 'number':\n case 'symbol':\n case 'function':\n {\n return type;\n }\n }\n\n if (Array.isArray(val)) return 'array';\n if (isDate(val)) return 'date';\n if (isError(val)) return 'error';\n var constructorName = ctorName(val);\n\n switch (constructorName) {\n case 'Symbol':\n case 'Promise':\n case 'WeakMap':\n case 'WeakSet':\n case 'Map':\n case 'Set':\n return constructorName;\n } // other\n\n\n return type.slice(8, -1).toLowerCase().replace(/\\s/g, '');\n}\n\nfunction ctorName(val) {\n return typeof val.constructor === 'function' ? val.constructor.name : null;\n}\n\nfunction isError(val) {\n return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number';\n}\n\nfunction isDate(val) {\n if (val instanceof Date) return true;\n return typeof val.toDateString === 'function' && typeof val.getDate === 'function' && typeof val.setDate === 'function';\n}\n\nfunction kindOf(val) {\n var typeOfVal = typeof val;\n\n if (process.env.NODE_ENV !== 'production') {\n typeOfVal = miniKindOf(val);\n }\n\n return typeOfVal;\n}\n\n/**\n * @deprecated\n *\n * **We recommend using the `configureStore` method\n * of the `@reduxjs/toolkit` package**, which replaces `createStore`.\n *\n * Redux Toolkit is our recommended approach for writing Redux logic today,\n * including store setup, reducers, data fetching, and more.\n *\n * **For more details, please read this Redux docs page:**\n * **https://redux.js.org/introduction/why-rtk-is-redux-today**\n *\n * `configureStore` from Redux Toolkit is an improved version of `createStore` that\n * simplifies setup and helps avoid common bugs.\n *\n * You should not be using the `redux` core package by itself today, except for learning purposes.\n * The `createStore` method from the core `redux` package will not be removed, but we encourage\n * all users to migrate to using Redux Toolkit for all Redux code.\n *\n * If you want to use `createStore` without this visual deprecation warning, use\n * the `legacy_createStore` import instead:\n *\n * `import { legacy_createStore as createStore} from 'redux'`\n *\n */\n\nfunction createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(0) : 'It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.');\n }\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(1) : \"Expected the enhancer to be a function. Instead, received: '\" + kindOf(enhancer) + \"'\");\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(2) : \"Expected the root reducer to be a function. Instead, received: '\" + kindOf(reducer) + \"'\");\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n /**\n * This makes a shallow copy of currentListeners so we can use\n * nextListeners as a temporary list while dispatching.\n *\n * This prevents any bugs around consumers calling\n * subscribe/unsubscribe in the middle of a dispatch.\n */\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n\n\n function getState() {\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(3) : 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.');\n }\n\n return currentState;\n }\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n\n\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(4) : \"Expected the listener to be a function. Instead, received: '\" + kindOf(listener) + \"'\");\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(5) : 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');\n }\n\n var isSubscribed = true;\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(6) : 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');\n }\n\n isSubscribed = false;\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n currentListeners = null;\n };\n }\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n\n\n function dispatch(action) {\n if (!isPlainObject(action)) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(7) : \"Actions must be plain objects. Instead, the actual type was: '\" + kindOf(action) + \"'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.\");\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(8) : 'Actions may not have an undefined \"type\" property. You may have misspelled an action type string constant.');\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(9) : 'Reducers may not dispatch actions.');\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n\n for (var i = 0; i < listeners.length; i++) {\n var listener = listeners[i];\n listener();\n }\n\n return action;\n }\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n\n\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(10) : \"Expected the nextReducer to be a function. Instead, received: '\" + kindOf(nextReducer));\n }\n\n currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT.\n // Any reducers that existed in both the new and old rootReducer\n // will receive the previous state. This effectively populates\n // the new state tree with any relevant data from the old one.\n\n dispatch({\n type: ActionTypes.REPLACE\n });\n }\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/tc39/proposal-observable\n */\n\n\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object' || observer === null) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(11) : \"Expected the observer to be an object. Instead, received: '\" + kindOf(observer) + \"'\");\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return {\n unsubscribe: unsubscribe\n };\n }\n }, _ref[$$observable] = function () {\n return this;\n }, _ref;\n } // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n\n\n dispatch({\n type: ActionTypes.INIT\n });\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[$$observable] = observable, _ref2;\n}\n/**\n * Creates a Redux store that holds the state tree.\n *\n * **We recommend using `configureStore` from the\n * `@reduxjs/toolkit` package**, which replaces `createStore`:\n * **https://redux.js.org/introduction/why-rtk-is-redux-today**\n *\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} [enhancer] The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\n\nvar legacy_createStore = createStore;\n\n/**\n * Prints a warning in the console if it exists.\n *\n * @param {String} message The warning message.\n * @returns {void}\n */\nfunction warning(message) {\n /* eslint-disable no-console */\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error(message);\n }\n /* eslint-enable no-console */\n\n\n try {\n // This error was thrown as a convenience so that if you enable\n // \"break on all exceptions\" in your console,\n // it would pause the execution at this line.\n throw new Error(message);\n } catch (e) {} // eslint-disable-line no-empty\n\n}\n\nfunction getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {\n var reducerKeys = Object.keys(reducers);\n var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';\n\n if (reducerKeys.length === 0) {\n return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';\n }\n\n if (!isPlainObject(inputState)) {\n return \"The \" + argumentName + \" has unexpected type of \\\"\" + kindOf(inputState) + \"\\\". Expected argument to be an object with the following \" + (\"keys: \\\"\" + reducerKeys.join('\", \"') + \"\\\"\");\n }\n\n var unexpectedKeys = Object.keys(inputState).filter(function (key) {\n return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];\n });\n unexpectedKeys.forEach(function (key) {\n unexpectedKeyCache[key] = true;\n });\n if (action && action.type === ActionTypes.REPLACE) return;\n\n if (unexpectedKeys.length > 0) {\n return \"Unexpected \" + (unexpectedKeys.length > 1 ? 'keys' : 'key') + \" \" + (\"\\\"\" + unexpectedKeys.join('\", \"') + \"\\\" found in \" + argumentName + \". \") + \"Expected to find one of the known reducer keys instead: \" + (\"\\\"\" + reducerKeys.join('\", \"') + \"\\\". Unexpected keys will be ignored.\");\n }\n}\n\nfunction assertReducerShape(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, {\n type: ActionTypes.INIT\n });\n\n if (typeof initialState === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(12) : \"The slice reducer for key \\\"\" + key + \"\\\" returned undefined during initialization. \" + \"If the state passed to the reducer is undefined, you must \" + \"explicitly return the initial state. The initial state may \" + \"not be undefined. If you don't want to set a value for this reducer, \" + \"you can use null instead of undefined.\");\n }\n\n if (typeof reducer(undefined, {\n type: ActionTypes.PROBE_UNKNOWN_ACTION()\n }) === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(13) : \"The slice reducer for key \\\"\" + key + \"\\\" returned undefined when probed with a random type. \" + (\"Don't try to handle '\" + ActionTypes.INIT + \"' or other actions in \\\"redux/*\\\" \") + \"namespace. They are considered private. Instead, you must return the \" + \"current state for any unknown actions, unless it is undefined, \" + \"in which case you must return the initial state, regardless of the \" + \"action type. The initial state may not be undefined, but can be null.\");\n }\n });\n}\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\n\n\nfunction combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (process.env.NODE_ENV !== 'production') {\n if (typeof reducers[key] === 'undefined') {\n warning(\"No reducer provided for key \\\"\" + key + \"\\\"\");\n }\n }\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n\n var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same\n // keys multiple times.\n\n var unexpectedKeyCache;\n\n if (process.env.NODE_ENV !== 'production') {\n unexpectedKeyCache = {};\n }\n\n var shapeAssertionError;\n\n try {\n assertReducerShape(finalReducers);\n } catch (e) {\n shapeAssertionError = e;\n }\n\n return function combination(state, action) {\n if (state === void 0) {\n state = {};\n }\n\n if (shapeAssertionError) {\n throw shapeAssertionError;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);\n\n if (warningMessage) {\n warning(warningMessage);\n }\n }\n\n var hasChanged = false;\n var nextState = {};\n\n for (var _i = 0; _i < finalReducerKeys.length; _i++) {\n var _key = finalReducerKeys[_i];\n var reducer = finalReducers[_key];\n var previousStateForKey = state[_key];\n var nextStateForKey = reducer(previousStateForKey, action);\n\n if (typeof nextStateForKey === 'undefined') {\n var actionType = action && action.type;\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(14) : \"When called with an action of type \" + (actionType ? \"\\\"\" + String(actionType) + \"\\\"\" : '(unknown type)') + \", the slice reducer for key \\\"\" + _key + \"\\\" returned undefined. \" + \"To ignore an action, you must explicitly return the previous state. \" + \"If you want this reducer to hold no value, you can return null instead of undefined.\");\n }\n\n nextState[_key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n\n hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length;\n return hasChanged ? nextState : state;\n };\n}\n\nfunction bindActionCreator(actionCreator, dispatch) {\n return function () {\n return dispatch(actionCreator.apply(this, arguments));\n };\n}\n/**\n * Turns an object whose values are action creators, into an object with the\n * same keys, but with every function wrapped into a `dispatch` call so they\n * may be invoked directly. This is just a convenience method, as you can call\n * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.\n *\n * For convenience, you can also pass an action creator as the first argument,\n * and get a dispatch wrapped function in return.\n *\n * @param {Function|Object} actionCreators An object whose values are action\n * creator functions. One handy way to obtain it is to use ES6 `import * as`\n * syntax. You may also pass a single function.\n *\n * @param {Function} dispatch The `dispatch` function available on your Redux\n * store.\n *\n * @returns {Function|Object} The object mimicking the original object, but with\n * every action creator wrapped into the `dispatch` call. If you passed a\n * function as `actionCreators`, the return value will also be a single\n * function.\n */\n\n\nfunction bindActionCreators(actionCreators, dispatch) {\n if (typeof actionCreators === 'function') {\n return bindActionCreator(actionCreators, dispatch);\n }\n\n if (typeof actionCreators !== 'object' || actionCreators === null) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(16) : \"bindActionCreators expected an object or a function, but instead received: '\" + kindOf(actionCreators) + \"'. \" + \"Did you write \\\"import ActionCreators from\\\" instead of \\\"import * as ActionCreators from\\\"?\");\n }\n\n var boundActionCreators = {};\n\n for (var key in actionCreators) {\n var actionCreator = actionCreators[key];\n\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);\n }\n }\n\n return boundActionCreators;\n}\n\n/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\nfunction compose() {\n for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n return funcs.reduce(function (a, b) {\n return function () {\n return a(b.apply(void 0, arguments));\n };\n });\n}\n\n/**\n * Creates a store enhancer that applies middleware to the dispatch method\n * of the Redux store. This is handy for a variety of tasks, such as expressing\n * asynchronous actions in a concise manner, or logging every action payload.\n *\n * See `redux-thunk` package as an example of the Redux middleware.\n *\n * Because middleware is potentially asynchronous, this should be the first\n * store enhancer in the composition chain.\n *\n * Note that each middleware will be given the `dispatch` and `getState` functions\n * as named arguments.\n *\n * @param {...Function} middlewares The middleware chain to be applied.\n * @returns {Function} A store enhancer applying the middleware.\n */\n\nfunction applyMiddleware() {\n for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {\n middlewares[_key] = arguments[_key];\n }\n\n return function (createStore) {\n return function () {\n var store = createStore.apply(void 0, arguments);\n\n var _dispatch = function dispatch() {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(15) : 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.');\n };\n\n var middlewareAPI = {\n getState: store.getState,\n dispatch: function dispatch() {\n return _dispatch.apply(void 0, arguments);\n }\n };\n var chain = middlewares.map(function (middleware) {\n return middleware(middlewareAPI);\n });\n _dispatch = compose.apply(void 0, chain)(store.dispatch);\n return _objectSpread(_objectSpread({}, store), {}, {\n dispatch: _dispatch\n });\n };\n };\n}\n\nexport { ActionTypes as __DO_NOT_USE__ActionTypes, applyMiddleware, bindActionCreators, combineReducers, compose, createStore, legacy_createStore };\n","export const enum HttpMethod {\r\n\tGET = \"GET\",\r\n\tPOST = \"POST\",\r\n\tPATCH = \"PATCH\",\r\n\tPUT = \"PUT\",\r\n\tDELETE = \"DELETE\",\r\n\t// TODO: Add support\r\n\t// OPTIONS = \"OPTIONS\",\r\n}\r\n","export enum IssuePriority {\r\n\tLOWEST = 0,\r\n\tLOW = 2,\r\n\tMEDIUM = 4,\r\n\tHIGH = 6,\r\n\tHIGHEST = 8,\r\n}\r\n\r\nexport enum IssueStatus {\r\n\tBACKLOG = 0,\r\n\tSELECTED = 2,\r\n\tDONE = 4,\r\n}\r\n","// We can call the first three \"Sun, Moon, Earth\" in the UI, but more descriptive names are used in development\r\nexport enum MapStyle {\r\n\tLIGHT = \"LIGHT\",\r\n\tDARK = \"DARK\",\r\n\tSATELLITE = \"SATELLITE\",\r\n\tNONE = \"NONE\",\r\n}\r\n","// TODO: This is deprecated and moved into redux-persist. See: https://github.com/wildlifela/redux-persist-migrate\r\n// It also doesn't seem to be doing much.\r\n\r\nimport type { Manifest, Migrator } from \"../typings\"\r\n\r\n// NOTE: If changing, also change it in store.ts (avoid circular imports)\r\nconst VERSION_REDUCER_KEY = \"versioning\"\r\n\r\ntype WrapMigrator = (migrator: Migrator) => Migrator\r\n\r\n// gets the most recent (largest) version number\r\nconst latestVersion = () => migrations.length - 1\r\n\r\n// if unset, set the app version to the latest\r\n// this is the case when someone opens the app for the first time\r\nconst initialVersioning: Migrator = (state) => {\r\n\t// @ts-expect-error This is the only time it's OK to set the version.\r\n\tstate[VERSION_REDUCER_KEY] = { version: latestVersion() }\r\n\treturn state\r\n}\r\n\r\n// migration that signs the user out due to the redux store being changed in a breaking way\r\nconst signOut: Migrator = () => {\r\n\t// set the app version to the latest so that this migration is not run again\r\n\treturn initialVersioning({})\r\n}\r\n\r\n// Added a new state to the outbox slice\r\nconst createOutboxState: Migrator = (state) => {\r\n\tif (state.outboxReducer) {\r\n\t\tstate.outboxReducer.deletedRequests = []\r\n\t}\r\n\treturn state\r\n}\r\n\r\n// wraps migrations with the skipAfterInitialVersioning check for convenience\r\nconst wrapMigration: WrapMigrator = (migrator) => (state) => {\r\n\t// REASON: This happened to GCS\r\n\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\r\n\tif (state === undefined) {\r\n\t\tstate = {}\r\n\t}\r\n\r\n\tif (state[VERSION_REDUCER_KEY]?.version === latestVersion()) return state\r\n\r\n\treturn migrator(state)\r\n}\r\n\r\n// migrations take in a RootState, modify it, and then return the updated root state\r\n// add new migrations to the **end** of this array\r\n// ensure initialVersioning() is always the first migration\r\nconst migrations: Migrator[] = [initialVersioning, signOut, signOut, createOutboxState]\r\n\r\n// used by redux-persist-migrate to run the migrations when rehydrating the app\r\nexport const manifest: Manifest = Object.fromEntries(migrations.map((migration, i) => [i, wrapMigration(migration)]))\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { TokenPair } from \"sdk/typings\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport interface AuthState {\r\n\taccessToken: string\r\n\trefreshToken: string\r\n\tisLoggedIn: boolean\r\n}\r\n\r\nconst initialState: AuthState = {\r\n\taccessToken: \"\",\r\n\trefreshToken: \"\",\r\n\tisLoggedIn: false,\r\n}\r\n\r\n/**\r\n * Stores the auth state of the app (tokens, and whether user is logged in or not)\r\n */\r\nexport const authSlice = createSlice({\r\n\tname: \"auth\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetTokens: (state, action: PayloadAction<TokenPair>) => {\r\n\t\t\tstate.accessToken = action.payload.accessToken\r\n\t\t\tstate.refreshToken = action.payload.refreshToken\r\n\t\t},\r\n\t\tclearTokens: (state) => {\r\n\t\t\tstate.accessToken = \"\"\r\n\t\t\tstate.refreshToken = \"\"\r\n\t\t},\r\n\t\tsetLoggedIn: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tif (!action.payload) {\r\n\t\t\t\tauthSlice.caseReducers.clearTokens(state)\r\n\t\t\t}\r\n\t\t\tstate.isLoggedIn = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setTokens, clearTokens, setLoggedIn } = authSlice.actions\r\nexport const selectAccessToken = (state: RootState) => state.authReducer.accessToken\r\nexport const selectIsLoggedIn = (state: RootState) => state.authReducer.isLoggedIn\r\n\r\nexport const authReducer: Reducer<AuthState> = authSlice.reducer\r\n","import L from \"leaflet\"\r\nimport { Coordinates, Geometry, Marker } from \"../typings\"\r\n\r\n// Convert our Coordinates type into a Leaflet LatLngLiteral\r\nexport const coordinatesToLiteral = (coordinates: Coordinates): L.LatLngLiteral => {\r\n\treturn { lng: coordinates[0], lat: coordinates[1] }\r\n}\r\n\r\n// Convert a Leaflet LatLngLiteral into our Coordinates type\r\nexport const literalToCoordinates = (literal: L.LatLngLiteral): Coordinates => {\r\n\treturn [literal.lng, literal.lat]\r\n}\r\n\r\n/**\r\n * Flip coordinates from [lng, lat] to [lat, lng]\r\n */\r\nexport const flipCoordinates = (coordinates: L.LatLngTuple): Coordinates => {\r\n\treturn [coordinates[1], coordinates[0]]\r\n}\r\n\r\nexport const markerToCoordinates: (marker: Marker) => Coordinates = (marker) => {\r\n\treturn flipCoordinates(marker.geometry.coordinates)\r\n}\r\n\r\nexport function offsetPositionByMeters(\r\n\toriginalPosition: L.LatLng,\r\n\tlatMeters: number,\r\n\tlngMeters: number,\r\n): L.LatLngLiteral {\r\n\tconst { lat, lng } = originalPosition\r\n\tconst earthRadius = 6378137 // Earth's radius in meters.\r\n\tconst metersPerDegree = (2 * Math.PI * earthRadius) / 360\r\n\t// The significance of one degree decreases the closer you get to a pole. This accounts for that.\r\n\tconst newLng = lng + lngMeters / metersPerDegree / Math.cos((lat * Math.PI) / 180)\r\n\tconst newLat = lat - latMeters / metersPerDegree\r\n\treturn { lat: newLat, lng: newLng }\r\n}\r\n\r\nexport const coordinatesToPointGeometry = (coordinates: Coordinates): Geometry => {\r\n\treturn {\r\n\t\ttype: \"Point\",\r\n\t\tcoordinates,\r\n\t}\r\n}\r\n\r\nexport const createPointMarker = (coordinates: Coordinates): Marker => {\r\n\treturn {\r\n\t\ttype: \"Feature\",\r\n\t\tgeometry: coordinatesToPointGeometry(coordinates),\r\n\t\tproperties: {},\r\n\t}\r\n}\r\n\r\nexport const coordinatesAreEqual = (a: Coordinates, b: Coordinates): boolean => {\r\n\treturn a[0] === b[0] && a[1] === b[1]\r\n}\r\n\r\n// export const coordinatesAreNearlyEqual = (a: Coordinates, b: Coordinates, thresholdMeters: number): boolean => {\r\n// return a === b\r\n// TODO: Fix\r\n// const diffLat = Math.abs(a[1] - b[1])\r\n// Length in km of 1° of latitude = always 111.32 km\r\n// const diffLatMeters = diffLat * 111320\r\n// if (diffLatMeters < thresholdMeters) return true\r\n// Length in km of 1° of longitude = 40075 km * cos(latitude) / 360'\r\n// const aVal = a[0] // Optimization\r\n// const diffLong = Math.abs(aVal - b[0])\r\n// const diffLongMeters = diffLong * ((40075000 * Math.cos(aVal)) / 360)\r\n// return diffLongMeters < thresholdMeters\r\n// }\r\n\r\n// This converts a Coordinate [lng, lat] to \"lat, lng\" string format with an option to round the numbers\r\nexport const coordinatesToText = (coordinates: Coordinates | null | undefined, decimalPlaces?: number) => {\r\n\tif (!coordinates) return \"(No Location)\"\r\n\tconst { lat, lng } = coordinatesToLiteral(coordinates)\r\n\tif (decimalPlaces) return `${lat.toFixed(decimalPlaces)}, ${lng.toFixed(decimalPlaces)}`\r\n\treturn `${lat}, ${lng}`\r\n}\r\n\r\nexport const coordinatesToUrlText = (coordinates: Coordinates) => {\r\n\tconst { lat, lng } = coordinatesToLiteral(coordinates)\r\n\treturn `${lat}%2C${lng}`\r\n}\r\n\r\nexport const getMarkerCoordinates = (marker: Marker | null): Coordinates | undefined => {\r\n\treturn marker?.geometry.coordinates\r\n}\r\n\r\nexport const markerCoordinatesToText = (marker: Marker | null, decimalPlaces?: number): string => {\r\n\tconst coordinates: Coordinates | undefined = getMarkerCoordinates(marker)\r\n\tif (coordinates) return coordinatesToText(coordinates, decimalPlaces)\r\n\treturn \"(No location)\"\r\n}\r\n\r\n// Opens coordinates in Google maps\r\nexport const openCoordsInGoogleMaps = (coordinates: Coordinates) => {\r\n\tconst url = `https://www.google.com/maps/search/?api=1&query=${coordinatesToUrlText(coordinates)}`\r\n\twindow.open(url)\r\n}\r\n\r\nexport const openDirectionsInGoogleMaps = (startingPoint: Coordinates, destination: Coordinates) => {\r\n\tconst startingPointUrl = coordinatesToUrlText(startingPoint)\r\n\tconst destinationUrl = coordinatesToUrlText(destination)\r\n\tconst url = `https://www.google.com/maps/dir/?api=1&origin=${startingPointUrl}&destination=${destinationUrl}`\r\n\twindow.open(url)\r\n}\r\n\r\nexport const worldBounds: [L.LatLngTuple, L.LatLngTuple] = [\r\n\t[90, -180],\r\n\t[-90, 180],\r\n]\r\n","/**\r\n * Combines multiple class names into a single string. Keys are class names and values are booleans.\r\n * If the value is true, the key is added to the string.\r\n */\r\nexport function classNames(...args: (object | string | undefined | null | number)[]): string {\r\n\tconst classes: string[] = []\r\n\tfor (const arg of args) {\r\n\t\tif (!arg) {\r\n\t\t\tcontinue\r\n\t\t}\r\n\t\tif (typeof arg === \"string\") {\r\n\t\t\tclasses.push(arg)\r\n\t\t} else if (typeof arg === \"object\") {\r\n\t\t\tfor (const [key, value] of Object.entries(arg)) {\r\n\t\t\t\tif (value) {\r\n\t\t\t\t\tclasses.push(key)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn classes.join(\" \")\r\n}\r\n","import { useSDK } from \"contexts/sdk\"\r\nimport { useEffect, useState } from \"react\"\r\n\r\n// See: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string\r\nfunction hex(buffer: ArrayBufferLike): string {\r\n\tconst hashArray = new Uint8Array(buffer)\r\n\r\n\treturn hashArray.reduce((data, byte) => data + byte.toString(16).padStart(2, \"0\"), \"\")\r\n}\r\n\r\nexport const getFileS3Key = async (file: File, hash?: string) => {\r\n\tif (!hash) {\r\n\t\thash = await hashFile(file)\r\n\t}\r\n\tlet fileType = file.type\r\n\tif (fileType.includes(\"/\")) {\r\n\t\tfileType = fileType.split(\"/\")[1]!\r\n\t}\r\n\tif (!fileType) {\r\n\t\tthrow new Error(`Could not extract file type from ${file.type}`)\r\n\t}\r\n\treturn `${hash}.${fileType}`\r\n}\r\n\r\nexport function hashFile(file: Blob): Promise<string> {\r\n\treturn new Promise((resolve, reject) => {\r\n\t\tconst reader = new FileReader()\r\n\t\t// Provide an onload callback for this instance of FileReader\r\n\t\t// This is called once reader.readAsArrayBuffer() is done\r\n\t\treader.onload = () => {\r\n\t\t\tconst fileResult = reader.result as ArrayBuffer | null\r\n\t\t\tif (!fileResult) {\r\n\t\t\t\treject()\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\r\n\t\t\tvoid crypto.subtle.digest(\"SHA-1\", fileResult).then((hash) => {\r\n\t\t\t\tconst sha1result = hex(hash)\r\n\t\t\t\tresolve(sha1result)\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\t// calling reader.readAsArrayBuffer and providing a file should trigger the callback above\r\n\t\t// as soon as readAsArrayBuffer is complete\r\n\t\treader.readAsArrayBuffer(file)\r\n\t})\r\n}\r\n\r\nexport function getFileIdentifier(file: File): string {\r\n\tif (!file.name || !file.type || !file.size) {\r\n\t\tconst message = \"File has no name, type, and/or size\"\r\n\t\tconsole.error(`${message}`, file)\r\n\t\tthrow new Error(`${message}.`)\r\n\t}\r\n\treturn `${file.name}&${file.type}${file.size}`\r\n}\r\n\r\nexport function getRenamedFile(file: File, newName: string): File & { name: string } {\r\n\treturn new File([file], newName, { type: file.type })\r\n}\r\n\r\nexport function downloadInMemoryFile(filename: string, text: string) {\r\n\tconst element = document.createElement(\"a\")\r\n\telement.setAttribute(\"href\", \"data:text/plain;charset=utf-8,\" + encodeURIComponent(text))\r\n\telement.setAttribute(\"download\", filename)\r\n\r\n\telement.style.display = \"none\"\r\n\tdocument.body.appendChild(element)\r\n\r\n\telement.click()\r\n\r\n\tdocument.body.removeChild(element)\r\n}\r\n\r\nexport const fileToBlob = async (dataUrl: string): Promise<Blob> => {\r\n\t// TODO: Is this as reliable and supported as this?\r\n\t// https://www.nixtu.info/2013/06/how-to-upload-canvas-data-to-server.html\r\n\treturn (await fetch(dataUrl)).blob()\r\n}\r\n\r\nexport const blobToBase64 = (blob: Blob): Promise<string> => {\r\n\treturn new Promise((resolve, _) => {\r\n\t\tconst reader = new FileReader()\r\n\t\treader.onloadend = () => {\r\n\t\t\tresolve(reader.result?.toString() || \"\")\r\n\t\t}\r\n\t\treader.readAsDataURL(blob)\r\n\t})\r\n}\r\n\r\nexport interface useFileSrcProps {\r\n\tfile: string | null\r\n\tfileSha1: string | null\r\n\tplaceholder?: string\r\n}\r\n\r\n// TODO:\r\n/** Converts a profile `file` and `fileSha1` into an img src that can be rendered. This relies on an API request. */\r\nexport const useFileSrc = (props: useFileSrcProps) => {\r\n\tconst { file, fileSha1, placeholder } = props\r\n\tconst [src, setSrc] = useState(placeholder)\r\n\tconst { sdk } = useSDK()\r\n\r\n\t// Fetch the photo file, return false\r\n\tuseEffect(() => {\r\n\t\t// use the default placeholder if no file or fileSha1\r\n\t\tif (!fileSha1 || !file) return\r\n\r\n\t\tsdk.files\r\n\t\t\t.fetchFileFromUrl(file, fileSha1)\r\n\t\t\t.then((file) => {\r\n\t\t\t\tsetSrc(URL.createObjectURL(file))\r\n\t\t\t})\r\n\t\t\t.catch((reason) => {\r\n\t\t\t\tconsole.error(`Failed to fetch file ${file} (${fileSha1}):\\n`, reason)\r\n\t\t\t})\r\n\t}, [file, fileSha1, sdk.files])\r\n\r\n\treturn src\r\n}\r\n","const logCache: Record<string, Record<string, boolean> | undefined> = {}\r\n\r\n/**\r\n * Logging the same message over and over again in a loop takes a lot of resources and makes the app laggy. This utility\r\n * function accepts a log ID (e.g. \"issue-has-no-index-workspace\") and an object ID (e.g. the offline_id of an issue),\r\n * and only logs the message on the first call with the same combination of logId and objId.\r\n * @param logId An arbitrary but unique identifier for this \"type of message\".\r\n * @param objId A unique identifier for the object the message regards. Can be an arbitrary string, e.g. \"current-user\"\r\n * or an actual object ID, e.g. the offline_id of an issue.\r\n * @param level The log level to use. For example, \"debug\" means `console.debug` will be called.\r\n * @param args The arguments to pass to the console log method.\r\n */\r\nexport function logOnlyOnce(\r\n\tlogId: string,\r\n\tobjId: string,\r\n\tlevel: \"debug\" | \"info\" | \"warn\" | \"error\",\r\n\t...args: unknown[]\r\n) {\r\n\tconst thisLogIdCache = logCache[logId]\r\n\tlet shouldLog = false\r\n\tif (!thisLogIdCache) {\r\n\t\tlogCache[logId] = { [objId]: true }\r\n\t\tshouldLog = true\r\n\t} else {\r\n\t\tconst hasLoggedForThisObject = thisLogIdCache[objId]\r\n\t\tif (!hasLoggedForThisObject) {\r\n\t\t\tthisLogIdCache[objId] = true\r\n\t\t\tshouldLog = true\r\n\t\t}\r\n\t}\r\n\tif (shouldLog) {\r\n\t\tconsole[level](...args)\r\n\t}\r\n}\r\n","import { Offline, OfflineModel } from \"../typings\"\r\nimport { v4 as uuidv4 } from \"uuid\"\r\n\r\n/**\r\n * Adds a generated UUID to the \"offline_id\" key of the object.\r\n * @param draft The model data to add the offline_id to\r\n */\r\nexport function offline<T>(draft: T): Offline<T> {\r\n\treturn { ...draft, offline_id: uuidv4() } as Offline<T>\r\n}\r\n\r\n/**\r\n * Converts an array of OfflineModel objects to a Record<string, TModel>, mapping an offline ID to the object with that\r\n * offline ID.\r\n * @param array An array of offline model instances\r\n */\r\nexport function toOfflineIdRecord<TModel extends OfflineModel>(array: TModel[]): Record<string, TModel> {\r\n\tconst asMapping: Record<string, TModel> = {}\r\n\tfor (const item of array) {\r\n\t\tasMapping[item.offline_id] = item\r\n\t}\r\n\treturn asMapping\r\n}\r\n","import { SearchResult, Stored } from \"../typings\"\r\nimport { Issue } from \"../typings\"\r\n\r\nexport const issueToSearchResult = (issue: Stored<Issue>, tag: string | null): SearchResult<Stored<Issue>> => {\r\n\treturn {\r\n\t\tlabel: issue.title || \"\",\r\n\t\ttypeLabel: \"issue\",\r\n\t\ttag: tag,\r\n\t\titem: issue,\r\n\t}\r\n}\r\n","/**\r\n * Returns a file-safe string from arbitrary text. Will return maximum 255 characters, which is the longest safe\r\n * Long File Name (LFN).\r\n * WARNING! May give poor performance in big loops.\r\n * @param str The string to make safe for file names.\r\n * @param extension An extension (not including a period) to be added after a period at the end of the string. The\r\n * character limit of the returned string includes the extension, meaning characters from str will be removed to\r\n * accommodate it if necessary.\r\n * @param maxLength The maximum length of the resulting file name. Defaults to 255.\r\n */\r\nexport function toFileNameSafeString(str: string, extension: string | undefined = undefined, maxLength = 255): string {\r\n\tlet ret = str.replace(/[^a-z0-9_\\-.]/gi, \"_\").replace(/_{2,}/g, \"_\")\r\n\tif (!extension) {\r\n\t\tconst parts = str.split(\".\")\r\n\t\tif (parts.length > 1) {\r\n\t\t\textension = parts[parts.length - 1]\r\n\t\t}\r\n\t}\r\n\tif (extension && !extension.startsWith(\".\")) {\r\n\t\textension = \".\" + extension\r\n\t}\r\n\tconst extensionLengthWithPeriod = extension ? extension.length : 0\r\n\r\n\tif (ret.length + extensionLengthWithPeriod > maxLength) {\r\n\t\tret = ret.slice(0, maxLength - extensionLengthWithPeriod) + (extension || \"\")\r\n\t}\r\n\treturn ret\r\n}\r\n\r\nexport function spacesToDashesLower(value: string): string {\r\n\treturn value.toLowerCase().replace(\" \", \"-\")\r\n}\r\n\r\nexport function slugify(str: string, underscore = false) {\r\n\treturn str\r\n\t\t.normalize(\"NFKD\")\r\n\t\t.toLowerCase()\r\n\t\t.replace(/[^\\w\\s-]/g, \"\")\r\n\t\t.trim()\r\n\t\t.replace(/[-\\s]+/g, underscore ? \"_\" : \"-\")\r\n}\r\n\r\n/**\r\n * Given a string, returns a truncated version of it with an ellipsis character at the end if it is longer than\r\n * maxLength. The resulting string will be no longer than maxLength. Note that the ellipsis is only one character long.\r\n * @param str The string to truncate.\r\n * @param maxLength The maximum length of the resulting string, including the ellipsis.\r\n */\r\nexport function truncate(str: string, maxLength: number) {\r\n\tif (str.length <= maxLength) {\r\n\t\treturn str\r\n\t}\r\n\t// -1 to account for the ellipsis character\r\n\tconst subString = str.slice(0, maxLength - 1)\r\n\treturn subString.slice(0, subString.lastIndexOf(\" \")) + \"…\"\r\n}\r\n","import { Coordinates, IssueAttachment, OfflineModel, RootState } from \"../typings\"\r\n\r\ntype MemoizedSelectorWithArgs<TArgs, TRet> = (state: RootState, args: TArgs) => TRet\r\n\r\n// makes the createSelector function fit the current pattern for selectors with arguments\r\nexport const restructureCreateSelectorWithArgs =\r\n\t<TArgs, TRet>(selector: MemoizedSelectorWithArgs<TArgs, TRet>) =>\r\n\t(args: TArgs) =>\r\n\t(state: RootState) =>\r\n\t\tselector(state, args)\r\n\r\nexport function onlyUniqueOfflineIds(value: OfflineModel, index: number, self: OfflineModel[]) {\r\n\treturn self.findIndex((v) => v.offline_id === value.offline_id) === index\r\n}\r\n\r\nexport function onlyUniqueHashes(value: IssueAttachment, index: number, self: IssueAttachment[]) {\r\n\treturn (\r\n\t\tself.findIndex((v: IssueAttachment) => {\r\n\t\t\treturn v.file_sha1 === value.file_sha1\r\n\t\t}) === index\r\n\t)\r\n}\r\n\r\n/**\r\n *\r\n * @param bounds order: [northEast, southWest]\r\n * @param coordinates\r\n */\r\nexport function boundsContainPoint(bounds: [Coordinates, Coordinates], coordinates: Coordinates): boolean {\r\n\t// TODO: this is flipped for Marker (Geometry)\r\n\treturn (\r\n\t\tbounds[0][0] > coordinates[0] &&\r\n\t\tbounds[1][0] < coordinates[0] &&\r\n\t\tbounds[0][1] > coordinates[1] &&\r\n\t\tbounds[1][1] < coordinates[1]\r\n\t)\r\n}\r\n\r\nexport const emailRegex = /^.+@.+\\..+$/\r\n","import React, { useEffect, useRef } from \"react\"\r\n\r\nlet debug = false\r\n\r\nconst REACT_APP_DEBUG_MEMOIZATION = (import.meta.env.REACT_APP_DEBUG_MEMOIZATION as string | undefined) || \"\"\r\n\r\nif ([\"true\", \"1\"].includes(REACT_APP_DEBUG_MEMOIZATION.toLowerCase())) {\r\n\tdebug = true\r\n}\r\n\r\nexport function shallowEqual(objA: object, objB: object) {\r\n\t// Check if they're the same object (objA is objB) -- just a quick reference check\r\n\tif (objA === objB) return true\r\n\r\n\tif (typeof objA !== typeof objB) {\r\n\t\treturn false\r\n\t}\r\n\r\n\tconst keysA = Object.keys(objA)\r\n\tconst keysB = Object.keys(objB)\r\n\r\n\t// Only calculate this once\r\n\tconst keysALength = keysA.length\r\n\tif (keysALength !== keysB.length) return false\r\n\r\n\tfor (let i = 0; i < keysALength; i++) {\r\n\t\tif (!Object.prototype.hasOwnProperty.call(objB, keysA[i]!) || objA[keysA[i]!] !== objB[keysA[i]!]) {\r\n\t\t\treturn false\r\n\t\t}\r\n\t}\r\n\r\n\treturn true\r\n}\r\n\r\nexport function memoize<T extends (...args) => unknown>(func: T): T {\r\n\t// Taken from https://www.sitepoint.com/implementing-memoization-in-javascript/\r\n\tconst memo = {}\r\n\r\n\treturn function () {\r\n\t\t// eslint-disable-next-line prefer-rest-params\r\n\t\tconst args = Array.prototype.slice.call(arguments)\r\n\r\n\t\t// SEE: https://stackoverflow.com/questions/10173956/how-to-use-array-as-key-in-javascript\r\n\r\n\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n\t\t// @ts-expect-error\r\n\t\tif (args in memo) {\r\n\t\t\tif (debug) {\r\n\t\t\t\tconsole.debug(`Memoization debug: Using memorized return value for ${func.toString()}(`, args, \")\")\r\n\t\t\t}\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n\t\t\t// @ts-expect-error\r\n\t\t\treturn memo[args] as T\r\n\t\t} else {\r\n\t\t\tif (debug) {\r\n\t\t\t\tconsole.debug(`Memoization debug: Cache miss! Memoizing ${func.toString()}(`, args, \")\")\r\n\t\t\t}\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n\t\t\t// @ts-expect-error\r\n\t\t\treturn (memo[args] = func.apply(this, args))\r\n\t\t}\r\n\t} as T\r\n}\r\n\r\nexport type EqualityChecker<TArgs> = (current: TArgs, previous: TArgs) => boolean\r\n\r\nexport function useMemoCompare<TValue>(\r\n\tnext: TValue | undefined,\r\n\tcompare: (prev: TValue | undefined, next: TValue | undefined) => boolean,\r\n): TValue | undefined {\r\n\t// Ref for storing previous value\r\n\tconst previousRef = useRef<TValue>()\r\n\tconst previous: TValue | undefined = previousRef.current\r\n\r\n\t// Pass previous and next value to compare function\r\n\t// to determine whether to consider them equal.\r\n\tconst isEqual = compare(previous, next)\r\n\r\n\t// If not equal update previousRef to next value.\r\n\t// We only update if not equal so that this hook continues to return\r\n\t// the same old value if compare keeps returning true.\r\n\tuseEffect(() => {\r\n\t\tif (!isEqual) {\r\n\t\t\tpreviousRef.current = next\r\n\t\t}\r\n\t})\r\n\r\n\t// Finally, if equal then return the previous value\r\n\treturn isEqual ? previous : next\r\n}\r\n\r\n/**\r\n * Performs an equality check by contents in order.\r\n * Reference types like objects and arrays are compared by reference.\r\n */\r\nexport function areArraysEqual(first: unknown[], second: unknown[]) {\r\n\tif (first.length !== second.length) return false\r\n\tfor (let i = 0; i < first.length; i++) {\r\n\t\tif (first[i] !== second[i]) return false\r\n\t}\r\n\treturn true\r\n}\r\n\r\nexport const genericMemo: <T>(component: T) => T = React.memo\r\n","const grayDark = {\n gray1: \"#111111\",\n gray2: \"#191919\",\n gray3: \"#222222\",\n gray4: \"#2a2a2a\",\n gray5: \"#313131\",\n gray6: \"#3a3a3a\",\n gray7: \"#484848\",\n gray8: \"#606060\",\n gray9: \"#6e6e6e\",\n gray10: \"#7b7b7b\",\n gray11: \"#b4b4b4\",\n gray12: \"#eeeeee\",\n};\nconst grayDarkA = {\n grayA1: \"#00000000\",\n grayA2: \"#ffffff09\",\n grayA3: \"#ffffff12\",\n grayA4: \"#ffffff1b\",\n grayA5: \"#ffffff22\",\n grayA6: \"#ffffff2c\",\n grayA7: \"#ffffff3b\",\n grayA8: \"#ffffff55\",\n grayA9: \"#ffffff64\",\n grayA10: \"#ffffff72\",\n grayA11: \"#ffffffaf\",\n grayA12: \"#ffffffed\",\n};\nconst grayDarkP3 = {\n gray1: \"color(display-p3 0.067 0.067 0.067)\",\n gray2: \"color(display-p3 0.098 0.098 0.098)\",\n gray3: \"color(display-p3 0.135 0.135 0.135)\",\n gray4: \"color(display-p3 0.163 0.163 0.163)\",\n gray5: \"color(display-p3 0.192 0.192 0.192)\",\n gray6: \"color(display-p3 0.228 0.228 0.228)\",\n gray7: \"color(display-p3 0.283 0.283 0.283)\",\n gray8: \"color(display-p3 0.375 0.375 0.375)\",\n gray9: \"color(display-p3 0.431 0.431 0.431)\",\n gray10: \"color(display-p3 0.484 0.484 0.484)\",\n gray11: \"color(display-p3 0.706 0.706 0.706)\",\n gray12: \"color(display-p3 0.933 0.933 0.933)\",\n};\nconst grayDarkP3A = {\n grayA1: \"color(display-p3 0 0 0 / 0)\",\n grayA2: \"color(display-p3 1 1 1 / 0.034)\",\n grayA3: \"color(display-p3 1 1 1 / 0.071)\",\n grayA4: \"color(display-p3 1 1 1 / 0.105)\",\n grayA5: \"color(display-p3 1 1 1 / 0.134)\",\n grayA6: \"color(display-p3 1 1 1 / 0.172)\",\n grayA7: \"color(display-p3 1 1 1 / 0.231)\",\n grayA8: \"color(display-p3 1 1 1 / 0.332)\",\n grayA9: \"color(display-p3 1 1 1 / 0.391)\",\n grayA10: \"color(display-p3 1 1 1 / 0.445)\",\n grayA11: \"color(display-p3 1 1 1 / 0.685)\",\n grayA12: \"color(display-p3 1 1 1 / 0.929)\",\n};\nconst mauveDark = {\n mauve1: \"#121113\",\n mauve2: \"#1a191b\",\n mauve3: \"#232225\",\n mauve4: \"#2b292d\",\n mauve5: \"#323035\",\n mauve6: \"#3c393f\",\n mauve7: \"#49474e\",\n mauve8: \"#625f69\",\n mauve9: \"#6f6d78\",\n mauve10: \"#7c7a85\",\n mauve11: \"#b5b2bc\",\n mauve12: \"#eeeef0\",\n};\nconst mauveDarkA = {\n mauveA1: \"#00000000\",\n mauveA2: \"#f5f4f609\",\n mauveA3: \"#ebeaf814\",\n mauveA4: \"#eee5f81d\",\n mauveA5: \"#efe6fe25\",\n mauveA6: \"#f1e6fd30\",\n mauveA7: \"#eee9ff40\",\n mauveA8: \"#eee7ff5d\",\n mauveA9: \"#eae6fd6e\",\n mauveA10: \"#ece9fd7c\",\n mauveA11: \"#f5f1ffb7\",\n mauveA12: \"#fdfdffef\",\n};\nconst mauveDarkP3 = {\n mauve1: \"color(display-p3 0.07 0.067 0.074)\",\n mauve2: \"color(display-p3 0.101 0.098 0.105)\",\n mauve3: \"color(display-p3 0.138 0.134 0.144)\",\n mauve4: \"color(display-p3 0.167 0.161 0.175)\",\n mauve5: \"color(display-p3 0.196 0.189 0.206)\",\n mauve6: \"color(display-p3 0.232 0.225 0.245)\",\n mauve7: \"color(display-p3 0.286 0.277 0.302)\",\n mauve8: \"color(display-p3 0.383 0.373 0.408)\",\n mauve9: \"color(display-p3 0.434 0.428 0.467)\",\n mauve10: \"color(display-p3 0.487 0.48 0.519)\",\n mauve11: \"color(display-p3 0.707 0.7 0.735)\",\n mauve12: \"color(display-p3 0.933 0.933 0.94)\",\n};\nconst mauveDarkP3A = {\n mauveA1: \"color(display-p3 0 0 0 / 0)\",\n mauveA2: \"color(display-p3 0.996 0.992 1 / 0.034)\",\n mauveA3: \"color(display-p3 0.937 0.933 0.992 / 0.077)\",\n mauveA4: \"color(display-p3 0.957 0.918 0.996 / 0.111)\",\n mauveA5: \"color(display-p3 0.937 0.906 0.996 / 0.145)\",\n mauveA6: \"color(display-p3 0.953 0.925 0.996 / 0.183)\",\n mauveA7: \"color(display-p3 0.945 0.929 1 / 0.246)\",\n mauveA8: \"color(display-p3 0.937 0.918 1 / 0.361)\",\n mauveA9: \"color(display-p3 0.933 0.918 1 / 0.424)\",\n mauveA10: \"color(display-p3 0.941 0.925 1 / 0.479)\",\n mauveA11: \"color(display-p3 0.965 0.961 1 / 0.712)\",\n mauveA12: \"color(display-p3 0.992 0.992 1 / 0.937)\",\n};\nconst slateDark = {\n slate1: \"#111113\",\n slate2: \"#18191b\",\n slate3: \"#212225\",\n slate4: \"#272a2d\",\n slate5: \"#2e3135\",\n slate6: \"#363a3f\",\n slate7: \"#43484e\",\n slate8: \"#5a6169\",\n slate9: \"#696e77\",\n slate10: \"#777b84\",\n slate11: \"#b0b4ba\",\n slate12: \"#edeef0\",\n};\nconst slateDarkA = {\n slateA1: \"#00000000\",\n slateA2: \"#d8f4f609\",\n slateA3: \"#ddeaf814\",\n slateA4: \"#d3edf81d\",\n slateA5: \"#d9edfe25\",\n slateA6: \"#d6ebfd30\",\n slateA7: \"#d9edff40\",\n slateA8: \"#d9edff5d\",\n slateA9: \"#dfebfd6d\",\n slateA10: \"#e5edfd7b\",\n slateA11: \"#f1f7feb5\",\n slateA12: \"#fcfdffef\",\n};\nconst slateDarkP3 = {\n slate1: \"color(display-p3 0.067 0.067 0.074)\",\n slate2: \"color(display-p3 0.095 0.098 0.105)\",\n slate3: \"color(display-p3 0.13 0.135 0.145)\",\n slate4: \"color(display-p3 0.156 0.163 0.176)\",\n slate5: \"color(display-p3 0.183 0.191 0.206)\",\n slate6: \"color(display-p3 0.215 0.226 0.244)\",\n slate7: \"color(display-p3 0.265 0.28 0.302)\",\n slate8: \"color(display-p3 0.357 0.381 0.409)\",\n slate9: \"color(display-p3 0.415 0.431 0.463)\",\n slate10: \"color(display-p3 0.469 0.483 0.514)\",\n slate11: \"color(display-p3 0.692 0.704 0.728)\",\n slate12: \"color(display-p3 0.93 0.933 0.94)\",\n};\nconst slateDarkP3A = {\n slateA1: \"color(display-p3 0 0 0 / 0)\",\n slateA2: \"color(display-p3 0.875 0.992 1 / 0.034)\",\n slateA3: \"color(display-p3 0.882 0.933 0.992 / 0.077)\",\n slateA4: \"color(display-p3 0.882 0.953 0.996 / 0.111)\",\n slateA5: \"color(display-p3 0.878 0.929 0.996 / 0.145)\",\n slateA6: \"color(display-p3 0.882 0.949 0.996 / 0.183)\",\n slateA7: \"color(display-p3 0.882 0.929 1 / 0.246)\",\n slateA8: \"color(display-p3 0.871 0.937 1 / 0.361)\",\n slateA9: \"color(display-p3 0.898 0.937 1 / 0.42)\",\n slateA10: \"color(display-p3 0.918 0.945 1 / 0.475)\",\n slateA11: \"color(display-p3 0.949 0.969 0.996 / 0.708)\",\n slateA12: \"color(display-p3 0.988 0.992 1 / 0.937)\",\n};\nconst sageDark = {\n sage1: \"#101211\",\n sage2: \"#171918\",\n sage3: \"#202221\",\n sage4: \"#272a29\",\n sage5: \"#2e3130\",\n sage6: \"#373b39\",\n sage7: \"#444947\",\n sage8: \"#5b625f\",\n sage9: \"#63706b\",\n sage10: \"#717d79\",\n sage11: \"#adb5b2\",\n sage12: \"#eceeed\",\n};\nconst sageDarkA = {\n sageA1: \"#00000000\",\n sageA2: \"#f0f2f108\",\n sageA3: \"#f3f5f412\",\n sageA4: \"#f2fefd1a\",\n sageA5: \"#f1fbfa22\",\n sageA6: \"#edfbf42d\",\n sageA7: \"#edfcf73c\",\n sageA8: \"#ebfdf657\",\n sageA9: \"#dffdf266\",\n sageA10: \"#e5fdf674\",\n sageA11: \"#f4fefbb0\",\n sageA12: \"#fdfffeed\",\n};\nconst sageDarkP3 = {\n sage1: \"color(display-p3 0.064 0.07 0.067)\",\n sage2: \"color(display-p3 0.092 0.098 0.094)\",\n sage3: \"color(display-p3 0.128 0.135 0.131)\",\n sage4: \"color(display-p3 0.155 0.164 0.159)\",\n sage5: \"color(display-p3 0.183 0.193 0.188)\",\n sage6: \"color(display-p3 0.218 0.23 0.224)\",\n sage7: \"color(display-p3 0.269 0.285 0.277)\",\n sage8: \"color(display-p3 0.362 0.382 0.373)\",\n sage9: \"color(display-p3 0.398 0.438 0.421)\",\n sage10: \"color(display-p3 0.453 0.49 0.474)\",\n sage11: \"color(display-p3 0.685 0.709 0.697)\",\n sage12: \"color(display-p3 0.927 0.933 0.93)\",\n};\nconst sageDarkP3A = {\n sageA1: \"color(display-p3 0 0 0 / 0)\",\n sageA2: \"color(display-p3 0.976 0.988 0.984 / 0.03)\",\n sageA3: \"color(display-p3 0.992 0.945 0.941 / 0.072)\",\n sageA4: \"color(display-p3 0.988 0.996 0.992 / 0.102)\",\n sageA5: \"color(display-p3 0.992 1 0.996 / 0.131)\",\n sageA6: \"color(display-p3 0.973 1 0.976 / 0.173)\",\n sageA7: \"color(display-p3 0.957 1 0.976 / 0.233)\",\n sageA8: \"color(display-p3 0.957 1 0.984 / 0.334)\",\n sageA9: \"color(display-p3 0.902 1 0.957 / 0.397)\",\n sageA10: \"color(display-p3 0.929 1 0.973 / 0.452)\",\n sageA11: \"color(display-p3 0.969 1 0.988 / 0.688)\",\n sageA12: \"color(display-p3 0.992 1 0.996 / 0.929)\",\n};\nconst oliveDark = {\n olive1: \"#111210\",\n olive2: \"#181917\",\n olive3: \"#212220\",\n olive4: \"#282a27\",\n olive5: \"#2f312e\",\n olive6: \"#383a36\",\n olive7: \"#454843\",\n olive8: \"#5c625b\",\n olive9: \"#687066\",\n olive10: \"#767d74\",\n olive11: \"#afb5ad\",\n olive12: \"#eceeec\",\n};\nconst oliveDarkA = {\n oliveA1: \"#00000000\",\n oliveA2: \"#f1f2f008\",\n oliveA3: \"#f4f5f312\",\n oliveA4: \"#f3fef21a\",\n oliveA5: \"#f2fbf122\",\n oliveA6: \"#f4faed2c\",\n oliveA7: \"#f2fced3b\",\n oliveA8: \"#edfdeb57\",\n oliveA9: \"#ebfde766\",\n oliveA10: \"#f0fdec74\",\n oliveA11: \"#f6fef4b0\",\n oliveA12: \"#fdfffded\",\n};\nconst oliveDarkP3 = {\n olive1: \"color(display-p3 0.067 0.07 0.063)\",\n olive2: \"color(display-p3 0.095 0.098 0.091)\",\n olive3: \"color(display-p3 0.131 0.135 0.126)\",\n olive4: \"color(display-p3 0.158 0.163 0.153)\",\n olive5: \"color(display-p3 0.186 0.192 0.18)\",\n olive6: \"color(display-p3 0.221 0.229 0.215)\",\n olive7: \"color(display-p3 0.273 0.284 0.266)\",\n olive8: \"color(display-p3 0.365 0.382 0.359)\",\n olive9: \"color(display-p3 0.414 0.438 0.404)\",\n olive10: \"color(display-p3 0.467 0.49 0.458)\",\n olive11: \"color(display-p3 0.69 0.709 0.682)\",\n olive12: \"color(display-p3 0.927 0.933 0.926)\",\n};\nconst oliveDarkP3A = {\n oliveA1: \"color(display-p3 0 0 0 / 0)\",\n oliveA2: \"color(display-p3 0.984 0.988 0.976 / 0.03)\",\n oliveA3: \"color(display-p3 0.992 0.996 0.988 / 0.068)\",\n oliveA4: \"color(display-p3 0.953 0.996 0.949 / 0.102)\",\n oliveA5: \"color(display-p3 0.969 1 0.965 / 0.131)\",\n oliveA6: \"color(display-p3 0.973 1 0.969 / 0.169)\",\n oliveA7: \"color(display-p3 0.98 1 0.961 / 0.228)\",\n oliveA8: \"color(display-p3 0.961 1 0.957 / 0.334)\",\n oliveA9: \"color(display-p3 0.949 1 0.922 / 0.397)\",\n oliveA10: \"color(display-p3 0.953 1 0.941 / 0.452)\",\n oliveA11: \"color(display-p3 0.976 1 0.965 / 0.688)\",\n oliveA12: \"color(display-p3 0.992 1 0.992 / 0.929)\",\n};\nconst sandDark = {\n sand1: \"#111110\",\n sand2: \"#191918\",\n sand3: \"#222221\",\n sand4: \"#2a2a28\",\n sand5: \"#31312e\",\n sand6: \"#3b3a37\",\n sand7: \"#494844\",\n sand8: \"#62605b\",\n sand9: \"#6f6d66\",\n sand10: \"#7c7b74\",\n sand11: \"#b5b3ad\",\n sand12: \"#eeeeec\",\n};\nconst sandDarkA = {\n sandA1: \"#00000000\",\n sandA2: \"#f4f4f309\",\n sandA3: \"#f6f6f513\",\n sandA4: \"#fefef31b\",\n sandA5: \"#fbfbeb23\",\n sandA6: \"#fffaed2d\",\n sandA7: \"#fffbed3c\",\n sandA8: \"#fff9eb57\",\n sandA9: \"#fffae965\",\n sandA10: \"#fffdee73\",\n sandA11: \"#fffcf4b0\",\n sandA12: \"#fffffded\",\n};\nconst sandDarkP3 = {\n sand1: \"color(display-p3 0.067 0.067 0.063)\",\n sand2: \"color(display-p3 0.098 0.098 0.094)\",\n sand3: \"color(display-p3 0.135 0.135 0.129)\",\n sand4: \"color(display-p3 0.164 0.163 0.156)\",\n sand5: \"color(display-p3 0.193 0.192 0.183)\",\n sand6: \"color(display-p3 0.23 0.229 0.217)\",\n sand7: \"color(display-p3 0.285 0.282 0.267)\",\n sand8: \"color(display-p3 0.384 0.378 0.357)\",\n sand9: \"color(display-p3 0.434 0.428 0.403)\",\n sand10: \"color(display-p3 0.487 0.481 0.456)\",\n sand11: \"color(display-p3 0.707 0.703 0.68)\",\n sand12: \"color(display-p3 0.933 0.933 0.926)\",\n};\nconst sandDarkP3A = {\n sandA1: \"color(display-p3 0 0 0 / 0)\",\n sandA2: \"color(display-p3 0.992 0.992 0.988 / 0.034)\",\n sandA3: \"color(display-p3 0.996 0.996 0.992 / 0.072)\",\n sandA4: \"color(display-p3 0.992 0.992 0.953 / 0.106)\",\n sandA5: \"color(display-p3 1 1 0.965 / 0.135)\",\n sandA6: \"color(display-p3 1 0.976 0.929 / 0.177)\",\n sandA7: \"color(display-p3 1 0.984 0.929 / 0.236)\",\n sandA8: \"color(display-p3 1 0.976 0.925 / 0.341)\",\n sandA9: \"color(display-p3 1 0.98 0.925 / 0.395)\",\n sandA10: \"color(display-p3 1 0.992 0.933 / 0.45)\",\n sandA11: \"color(display-p3 1 0.996 0.961 / 0.685)\",\n sandA12: \"color(display-p3 1 1 0.992 / 0.929)\",\n};\nconst tomatoDark = {\n tomato1: \"#181111\",\n tomato2: \"#1f1513\",\n tomato3: \"#391714\",\n tomato4: \"#4e1511\",\n tomato5: \"#5e1c16\",\n tomato6: \"#6e2920\",\n tomato7: \"#853a2d\",\n tomato8: \"#ac4d39\",\n tomato9: \"#e54d2e\",\n tomato10: \"#ec6142\",\n tomato11: \"#ff977d\",\n tomato12: \"#fbd3cb\",\n};\nconst tomatoDarkA = {\n tomatoA1: \"#f1121208\",\n tomatoA2: \"#ff55330f\",\n tomatoA3: \"#ff35232b\",\n tomatoA4: \"#fd201142\",\n tomatoA5: \"#fe332153\",\n tomatoA6: \"#ff4f3864\",\n tomatoA7: \"#fd644a7d\",\n tomatoA8: \"#fe6d4ea7\",\n tomatoA9: \"#fe5431e4\",\n tomatoA10: \"#ff6847eb\",\n tomatoA11: \"#ff977d\",\n tomatoA12: \"#ffd6cefb\",\n};\nconst tomatoDarkP3 = {\n tomato1: \"color(display-p3 0.09 0.068 0.067)\",\n tomato2: \"color(display-p3 0.115 0.084 0.076)\",\n tomato3: \"color(display-p3 0.205 0.097 0.083)\",\n tomato4: \"color(display-p3 0.282 0.099 0.077)\",\n tomato5: \"color(display-p3 0.339 0.129 0.101)\",\n tomato6: \"color(display-p3 0.398 0.179 0.141)\",\n tomato7: \"color(display-p3 0.487 0.245 0.194)\",\n tomato8: \"color(display-p3 0.629 0.322 0.248)\",\n tomato9: \"color(display-p3 0.831 0.345 0.231)\",\n tomato10: \"color(display-p3 0.862 0.415 0.298)\",\n tomato11: \"color(display-p3 1 0.585 0.455)\",\n tomato12: \"color(display-p3 0.959 0.833 0.802)\",\n};\nconst tomatoDarkP3A = {\n tomatoA1: \"color(display-p3 0.973 0.071 0.071 / 0.026)\",\n tomatoA2: \"color(display-p3 0.992 0.376 0.224 / 0.051)\",\n tomatoA3: \"color(display-p3 0.996 0.282 0.176 / 0.148)\",\n tomatoA4: \"color(display-p3 1 0.204 0.118 / 0.232)\",\n tomatoA5: \"color(display-p3 1 0.286 0.192 / 0.29)\",\n tomatoA6: \"color(display-p3 1 0.392 0.278 / 0.353)\",\n tomatoA7: \"color(display-p3 1 0.459 0.349 / 0.45)\",\n tomatoA8: \"color(display-p3 1 0.49 0.369 / 0.601)\",\n tomatoA9: \"color(display-p3 1 0.408 0.267 / 0.82)\",\n tomatoA10: \"color(display-p3 1 0.478 0.341 / 0.853)\",\n tomatoA11: \"color(display-p3 1 0.585 0.455)\",\n tomatoA12: \"color(display-p3 0.959 0.833 0.802)\",\n};\nconst redDark = {\n red1: \"#191111\",\n red2: \"#201314\",\n red3: \"#3b1219\",\n red4: \"#500f1c\",\n red5: \"#611623\",\n red6: \"#72232d\",\n red7: \"#8c333a\",\n red8: \"#b54548\",\n red9: \"#e5484d\",\n red10: \"#ec5d5e\",\n red11: \"#ff9592\",\n red12: \"#ffd1d9\",\n};\nconst redDarkA = {\n redA1: \"#f4121209\",\n redA2: \"#f22f3e11\",\n redA3: \"#ff173f2d\",\n redA4: \"#fe0a3b44\",\n redA5: \"#ff204756\",\n redA6: \"#ff3e5668\",\n redA7: \"#ff536184\",\n redA8: \"#ff5d61b0\",\n redA9: \"#fe4e54e4\",\n redA10: \"#ff6465eb\",\n redA11: \"#ff9592\",\n redA12: \"#ffd1d9\",\n};\nconst redDarkP3 = {\n red1: \"color(display-p3 0.093 0.068 0.067)\",\n red2: \"color(display-p3 0.118 0.077 0.079)\",\n red3: \"color(display-p3 0.211 0.081 0.099)\",\n red4: \"color(display-p3 0.287 0.079 0.113)\",\n red5: \"color(display-p3 0.348 0.11 0.142)\",\n red6: \"color(display-p3 0.414 0.16 0.183)\",\n red7: \"color(display-p3 0.508 0.224 0.236)\",\n red8: \"color(display-p3 0.659 0.298 0.297)\",\n red9: \"color(display-p3 0.83 0.329 0.324)\",\n red10: \"color(display-p3 0.861 0.403 0.387)\",\n red11: \"color(display-p3 1 0.57 0.55)\",\n red12: \"color(display-p3 0.971 0.826 0.852)\",\n};\nconst redDarkP3A = {\n redA1: \"color(display-p3 0.984 0.071 0.071 / 0.03)\",\n redA2: \"color(display-p3 0.996 0.282 0.282 / 0.055)\",\n redA3: \"color(display-p3 1 0.169 0.271 / 0.156)\",\n redA4: \"color(display-p3 1 0.118 0.267 / 0.236)\",\n redA5: \"color(display-p3 1 0.212 0.314 / 0.303)\",\n redA6: \"color(display-p3 1 0.318 0.38 / 0.374)\",\n redA7: \"color(display-p3 1 0.4 0.424 / 0.475)\",\n redA8: \"color(display-p3 1 0.431 0.431 / 0.635)\",\n redA9: \"color(display-p3 1 0.388 0.384 / 0.82)\",\n redA10: \"color(display-p3 1 0.463 0.447 / 0.853)\",\n redA11: \"color(display-p3 1 0.57 0.55)\",\n redA12: \"color(display-p3 0.971 0.826 0.852)\",\n};\nconst rubyDark = {\n ruby1: \"#191113\",\n ruby2: \"#1e1517\",\n ruby3: \"#3a141e\",\n ruby4: \"#4e1325\",\n ruby5: \"#5e1a2e\",\n ruby6: \"#6f2539\",\n ruby7: \"#883447\",\n ruby8: \"#b3445a\",\n ruby9: \"#e54666\",\n ruby10: \"#ec5a72\",\n ruby11: \"#ff949d\",\n ruby12: \"#fed2e1\",\n};\nconst rubyDarkA = {\n rubyA1: \"#f4124a09\",\n rubyA2: \"#fe5a7f0e\",\n rubyA3: \"#ff235d2c\",\n rubyA4: \"#fd195e42\",\n rubyA5: \"#fe2d6b53\",\n rubyA6: \"#ff447665\",\n rubyA7: \"#ff577d80\",\n rubyA8: \"#ff5c7cae\",\n rubyA9: \"#fe4c70e4\",\n rubyA10: \"#ff617beb\",\n rubyA11: \"#ff949d\",\n rubyA12: \"#ffd3e2fe\",\n};\nconst rubyDarkP3 = {\n ruby1: \"color(display-p3 0.093 0.068 0.074)\",\n ruby2: \"color(display-p3 0.113 0.083 0.089)\",\n ruby3: \"color(display-p3 0.208 0.088 0.117)\",\n ruby4: \"color(display-p3 0.279 0.092 0.147)\",\n ruby5: \"color(display-p3 0.337 0.12 0.18)\",\n ruby6: \"color(display-p3 0.401 0.166 0.223)\",\n ruby7: \"color(display-p3 0.495 0.224 0.281)\",\n ruby8: \"color(display-p3 0.652 0.295 0.359)\",\n ruby9: \"color(display-p3 0.83 0.323 0.408)\",\n ruby10: \"color(display-p3 0.857 0.392 0.455)\",\n ruby11: \"color(display-p3 1 0.57 0.59)\",\n ruby12: \"color(display-p3 0.968 0.83 0.88)\",\n};\nconst rubyDarkP3A = {\n rubyA1: \"color(display-p3 0.984 0.071 0.329 / 0.03)\",\n rubyA2: \"color(display-p3 0.992 0.376 0.529 / 0.051)\",\n rubyA3: \"color(display-p3 0.996 0.196 0.404 / 0.152)\",\n rubyA4: \"color(display-p3 1 0.173 0.416 / 0.227)\",\n rubyA5: \"color(display-p3 1 0.259 0.459 / 0.29)\",\n rubyA6: \"color(display-p3 1 0.341 0.506 / 0.358)\",\n rubyA7: \"color(display-p3 1 0.412 0.541 / 0.458)\",\n rubyA8: \"color(display-p3 1 0.431 0.537 / 0.627)\",\n rubyA9: \"color(display-p3 1 0.376 0.482 / 0.82)\",\n rubyA10: \"color(display-p3 1 0.447 0.522 / 0.849)\",\n rubyA11: \"color(display-p3 1 0.57 0.59)\",\n rubyA12: \"color(display-p3 0.968 0.83 0.88)\",\n};\nconst crimsonDark = {\n crimson1: \"#191114\",\n crimson2: \"#201318\",\n crimson3: \"#381525\",\n crimson4: \"#4d122f\",\n crimson5: \"#5c1839\",\n crimson6: \"#6d2545\",\n crimson7: \"#873356\",\n crimson8: \"#b0436e\",\n crimson9: \"#e93d82\",\n crimson10: \"#ee518a\",\n crimson11: \"#ff92ad\",\n crimson12: \"#fdd3e8\",\n};\nconst crimsonDarkA = {\n crimsonA1: \"#f4126709\",\n crimsonA2: \"#f22f7a11\",\n crimsonA3: \"#fe2a8b2a\",\n crimsonA4: \"#fd158741\",\n crimsonA5: \"#fd278f51\",\n crimsonA6: \"#fe459763\",\n crimsonA7: \"#fd559b7f\",\n crimsonA8: \"#fe5b9bab\",\n crimsonA9: \"#fe418de8\",\n crimsonA10: \"#ff5693ed\",\n crimsonA11: \"#ff92ad\",\n crimsonA12: \"#ffd5eafd\",\n};\nconst crimsonDarkP3 = {\n crimson1: \"color(display-p3 0.093 0.068 0.078)\",\n crimson2: \"color(display-p3 0.117 0.078 0.095)\",\n crimson3: \"color(display-p3 0.203 0.091 0.143)\",\n crimson4: \"color(display-p3 0.277 0.087 0.182)\",\n crimson5: \"color(display-p3 0.332 0.115 0.22)\",\n crimson6: \"color(display-p3 0.394 0.162 0.268)\",\n crimson7: \"color(display-p3 0.489 0.222 0.336)\",\n crimson8: \"color(display-p3 0.638 0.289 0.429)\",\n crimson9: \"color(display-p3 0.843 0.298 0.507)\",\n crimson10: \"color(display-p3 0.864 0.364 0.539)\",\n crimson11: \"color(display-p3 1 0.56 0.66)\",\n crimson12: \"color(display-p3 0.966 0.834 0.906)\",\n};\nconst crimsonDarkP3A = {\n crimsonA1: \"color(display-p3 0.984 0.071 0.463 / 0.03)\",\n crimsonA2: \"color(display-p3 0.996 0.282 0.569 / 0.055)\",\n crimsonA3: \"color(display-p3 0.996 0.227 0.573 / 0.148)\",\n crimsonA4: \"color(display-p3 1 0.157 0.569 / 0.227)\",\n crimsonA5: \"color(display-p3 1 0.231 0.604 / 0.286)\",\n crimsonA6: \"color(display-p3 1 0.337 0.643 / 0.349)\",\n crimsonA7: \"color(display-p3 1 0.416 0.663 / 0.454)\",\n crimsonA8: \"color(display-p3 0.996 0.427 0.651 / 0.614)\",\n crimsonA9: \"color(display-p3 1 0.345 0.596 / 0.832)\",\n crimsonA10: \"color(display-p3 1 0.42 0.62 / 0.853)\",\n crimsonA11: \"color(display-p3 1 0.56 0.66)\",\n crimsonA12: \"color(display-p3 0.966 0.834 0.906)\",\n};\nconst pinkDark = {\n pink1: \"#191117\",\n pink2: \"#21121d\",\n pink3: \"#37172f\",\n pink4: \"#4b143d\",\n pink5: \"#591c47\",\n pink6: \"#692955\",\n pink7: \"#833869\",\n pink8: \"#a84885\",\n pink9: \"#d6409f\",\n pink10: \"#de51a8\",\n pink11: \"#ff8dcc\",\n pink12: \"#fdd1ea\",\n};\nconst pinkDarkA = {\n pinkA1: \"#f412bc09\",\n pinkA2: \"#f420bb12\",\n pinkA3: \"#fe37cc29\",\n pinkA4: \"#fc1ec43f\",\n pinkA5: \"#fd35c24e\",\n pinkA6: \"#fd51c75f\",\n pinkA7: \"#fd62c87b\",\n pinkA8: \"#ff68c8a2\",\n pinkA9: \"#fe49bcd4\",\n pinkA10: \"#ff5cc0dc\",\n pinkA11: \"#ff8dcc\",\n pinkA12: \"#ffd3ecfd\",\n};\nconst pinkDarkP3 = {\n pink1: \"color(display-p3 0.093 0.068 0.089)\",\n pink2: \"color(display-p3 0.121 0.073 0.11)\",\n pink3: \"color(display-p3 0.198 0.098 0.179)\",\n pink4: \"color(display-p3 0.271 0.095 0.231)\",\n pink5: \"color(display-p3 0.32 0.127 0.273)\",\n pink6: \"color(display-p3 0.382 0.177 0.326)\",\n pink7: \"color(display-p3 0.477 0.238 0.405)\",\n pink8: \"color(display-p3 0.612 0.304 0.51)\",\n pink9: \"color(display-p3 0.775 0.297 0.61)\",\n pink10: \"color(display-p3 0.808 0.356 0.645)\",\n pink11: \"color(display-p3 1 0.535 0.78)\",\n pink12: \"color(display-p3 0.964 0.826 0.912)\",\n};\nconst pinkDarkP3A = {\n pinkA1: \"color(display-p3 0.984 0.071 0.855 / 0.03)\",\n pinkA2: \"color(display-p3 1 0.2 0.8 / 0.059)\",\n pinkA3: \"color(display-p3 1 0.294 0.886 / 0.139)\",\n pinkA4: \"color(display-p3 1 0.192 0.82 / 0.219)\",\n pinkA5: \"color(display-p3 1 0.282 0.827 / 0.274)\",\n pinkA6: \"color(display-p3 1 0.396 0.835 / 0.337)\",\n pinkA7: \"color(display-p3 1 0.459 0.831 / 0.442)\",\n pinkA8: \"color(display-p3 1 0.478 0.827 / 0.585)\",\n pinkA9: \"color(display-p3 1 0.373 0.784 / 0.761)\",\n pinkA10: \"color(display-p3 1 0.435 0.792 / 0.795)\",\n pinkA11: \"color(display-p3 1 0.535 0.78)\",\n pinkA12: \"color(display-p3 0.964 0.826 0.912)\",\n};\nconst plumDark = {\n plum1: \"#181118\",\n plum2: \"#201320\",\n plum3: \"#351a35\",\n plum4: \"#451d47\",\n plum5: \"#512454\",\n plum6: \"#5e3061\",\n plum7: \"#734079\",\n plum8: \"#92549c\",\n plum9: \"#ab4aba\",\n plum10: \"#b658c4\",\n plum11: \"#e796f3\",\n plum12: \"#f4d4f4\",\n};\nconst plumDarkA = {\n plumA1: \"#f112f108\",\n plumA2: \"#f22ff211\",\n plumA3: \"#fd4cfd27\",\n plumA4: \"#f646ff3a\",\n plumA5: \"#f455ff48\",\n plumA6: \"#f66dff56\",\n plumA7: \"#f07cfd70\",\n plumA8: \"#ee84ff95\",\n plumA9: \"#e961feb6\",\n plumA10: \"#ed70ffc0\",\n plumA11: \"#f19cfef3\",\n plumA12: \"#feddfef4\",\n};\nconst plumDarkP3 = {\n plum1: \"color(display-p3 0.09 0.068 0.092)\",\n plum2: \"color(display-p3 0.118 0.077 0.121)\",\n plum3: \"color(display-p3 0.192 0.105 0.202)\",\n plum4: \"color(display-p3 0.25 0.121 0.271)\",\n plum5: \"color(display-p3 0.293 0.152 0.319)\",\n plum6: \"color(display-p3 0.343 0.198 0.372)\",\n plum7: \"color(display-p3 0.424 0.262 0.461)\",\n plum8: \"color(display-p3 0.54 0.341 0.595)\",\n plum9: \"color(display-p3 0.624 0.313 0.708)\",\n plum10: \"color(display-p3 0.666 0.365 0.748)\",\n plum11: \"color(display-p3 0.86 0.602 0.933)\",\n plum12: \"color(display-p3 0.936 0.836 0.949)\",\n};\nconst plumDarkP3A = {\n plumA1: \"color(display-p3 0.973 0.071 0.973 / 0.026)\",\n plumA2: \"color(display-p3 0.933 0.267 1 / 0.059)\",\n plumA3: \"color(display-p3 0.918 0.333 0.996 / 0.148)\",\n plumA4: \"color(display-p3 0.91 0.318 1 / 0.219)\",\n plumA5: \"color(display-p3 0.914 0.388 1 / 0.269)\",\n plumA6: \"color(display-p3 0.906 0.463 1 / 0.328)\",\n plumA7: \"color(display-p3 0.906 0.529 1 / 0.425)\",\n plumA8: \"color(display-p3 0.906 0.553 1 / 0.568)\",\n plumA9: \"color(display-p3 0.875 0.427 1 / 0.69)\",\n plumA10: \"color(display-p3 0.886 0.471 0.996 / 0.732)\",\n plumA11: \"color(display-p3 0.86 0.602 0.933)\",\n plumA12: \"color(display-p3 0.936 0.836 0.949)\",\n};\nconst purpleDark = {\n purple1: \"#18111b\",\n purple2: \"#1e1523\",\n purple3: \"#301c3b\",\n purple4: \"#3d224e\",\n purple5: \"#48295c\",\n purple6: \"#54346b\",\n purple7: \"#664282\",\n purple8: \"#8457aa\",\n purple9: \"#8e4ec6\",\n purple10: \"#9a5cd0\",\n purple11: \"#d19dff\",\n purple12: \"#ecd9fa\",\n};\nconst purpleDarkA = {\n purpleA1: \"#b412f90b\",\n purpleA2: \"#b744f714\",\n purpleA3: \"#c150ff2d\",\n purpleA4: \"#bb53fd42\",\n purpleA5: \"#be5cfd51\",\n purpleA6: \"#c16dfd61\",\n purpleA7: \"#c378fd7a\",\n purpleA8: \"#c47effa4\",\n purpleA9: \"#b661ffc2\",\n purpleA10: \"#bc6fffcd\",\n purpleA11: \"#d19dff\",\n purpleA12: \"#f1ddfffa\",\n};\nconst purpleDarkP3 = {\n purple1: \"color(display-p3 0.09 0.068 0.103)\",\n purple2: \"color(display-p3 0.113 0.082 0.134)\",\n purple3: \"color(display-p3 0.175 0.112 0.224)\",\n purple4: \"color(display-p3 0.224 0.137 0.297)\",\n purple5: \"color(display-p3 0.264 0.167 0.349)\",\n purple6: \"color(display-p3 0.311 0.208 0.406)\",\n purple7: \"color(display-p3 0.381 0.266 0.496)\",\n purple8: \"color(display-p3 0.49 0.349 0.649)\",\n purple9: \"color(display-p3 0.523 0.318 0.751)\",\n purple10: \"color(display-p3 0.57 0.373 0.791)\",\n purple11: \"color(display-p3 0.8 0.62 1)\",\n purple12: \"color(display-p3 0.913 0.854 0.971)\",\n};\nconst purpleDarkP3A = {\n purpleA1: \"color(display-p3 0.686 0.071 0.996 / 0.038)\",\n purpleA2: \"color(display-p3 0.722 0.286 0.996 / 0.072)\",\n purpleA3: \"color(display-p3 0.718 0.349 0.996 / 0.169)\",\n purpleA4: \"color(display-p3 0.702 0.353 1 / 0.248)\",\n purpleA5: \"color(display-p3 0.718 0.404 1 / 0.303)\",\n purpleA6: \"color(display-p3 0.733 0.455 1 / 0.366)\",\n purpleA7: \"color(display-p3 0.753 0.506 1 / 0.458)\",\n purpleA8: \"color(display-p3 0.749 0.522 1 / 0.622)\",\n purpleA9: \"color(display-p3 0.686 0.408 1 / 0.736)\",\n purpleA10: \"color(display-p3 0.71 0.459 1 / 0.778)\",\n purpleA11: \"color(display-p3 0.8 0.62 1)\",\n purpleA12: \"color(display-p3 0.913 0.854 0.971)\",\n};\nconst violetDark = {\n violet1: \"#14121f\",\n violet2: \"#1b1525\",\n violet3: \"#291f43\",\n violet4: \"#33255b\",\n violet5: \"#3c2e69\",\n violet6: \"#473876\",\n violet7: \"#56468b\",\n violet8: \"#6958ad\",\n violet9: \"#6e56cf\",\n violet10: \"#7d66d9\",\n violet11: \"#baa7ff\",\n violet12: \"#e2ddfe\",\n};\nconst violetDarkA = {\n violetA1: \"#4422ff0f\",\n violetA2: \"#853ff916\",\n violetA3: \"#8354fe36\",\n violetA4: \"#7d51fd50\",\n violetA5: \"#845ffd5f\",\n violetA6: \"#8f6cfd6d\",\n violetA7: \"#9879ff83\",\n violetA8: \"#977dfea8\",\n violetA9: \"#8668ffcc\",\n violetA10: \"#9176fed7\",\n violetA11: \"#baa7ff\",\n violetA12: \"#e3defffe\",\n};\nconst violetDarkP3 = {\n violet1: \"color(display-p3 0.077 0.071 0.118)\",\n violet2: \"color(display-p3 0.101 0.084 0.141)\",\n violet3: \"color(display-p3 0.154 0.123 0.256)\",\n violet4: \"color(display-p3 0.191 0.148 0.345)\",\n violet5: \"color(display-p3 0.226 0.182 0.396)\",\n violet6: \"color(display-p3 0.269 0.223 0.449)\",\n violet7: \"color(display-p3 0.326 0.277 0.53)\",\n violet8: \"color(display-p3 0.399 0.346 0.656)\",\n violet9: \"color(display-p3 0.417 0.341 0.784)\",\n violet10: \"color(display-p3 0.477 0.402 0.823)\",\n violet11: \"color(display-p3 0.72 0.65 1)\",\n violet12: \"color(display-p3 0.883 0.867 0.986)\",\n};\nconst violetDarkP3A = {\n violetA1: \"color(display-p3 0.282 0.141 0.996 / 0.055)\",\n violetA2: \"color(display-p3 0.51 0.263 1 / 0.08)\",\n violetA3: \"color(display-p3 0.494 0.337 0.996 / 0.202)\",\n violetA4: \"color(display-p3 0.49 0.345 1 / 0.299)\",\n violetA5: \"color(display-p3 0.525 0.392 1 / 0.353)\",\n violetA6: \"color(display-p3 0.569 0.455 1 / 0.408)\",\n violetA7: \"color(display-p3 0.588 0.494 1 / 0.496)\",\n violetA8: \"color(display-p3 0.596 0.51 1 / 0.631)\",\n violetA9: \"color(display-p3 0.522 0.424 1 / 0.769)\",\n violetA10: \"color(display-p3 0.576 0.482 1 / 0.811)\",\n violetA11: \"color(display-p3 0.72 0.65 1)\",\n violetA12: \"color(display-p3 0.883 0.867 0.986)\",\n};\nconst irisDark = {\n iris1: \"#13131e\",\n iris2: \"#171625\",\n iris3: \"#202248\",\n iris4: \"#262a65\",\n iris5: \"#303374\",\n iris6: \"#3d3e82\",\n iris7: \"#4a4a95\",\n iris8: \"#5958b1\",\n iris9: \"#5b5bd6\",\n iris10: \"#6e6ade\",\n iris11: \"#b1a9ff\",\n iris12: \"#e0dffe\",\n};\nconst irisDarkA = {\n irisA1: \"#3636fe0e\",\n irisA2: \"#564bf916\",\n irisA3: \"#525bff3b\",\n irisA4: \"#4d58ff5a\",\n irisA5: \"#5b62fd6b\",\n irisA6: \"#6d6ffd7a\",\n irisA7: \"#7777fe8e\",\n irisA8: \"#7b7afeac\",\n irisA9: \"#6a6afed4\",\n irisA10: \"#7d79ffdc\",\n irisA11: \"#b1a9ff\",\n irisA12: \"#e1e0fffe\",\n};\nconst irisDarkP3 = {\n iris1: \"color(display-p3 0.075 0.075 0.114)\",\n iris2: \"color(display-p3 0.089 0.086 0.14)\",\n iris3: \"color(display-p3 0.128 0.134 0.272)\",\n iris4: \"color(display-p3 0.153 0.165 0.382)\",\n iris5: \"color(display-p3 0.192 0.201 0.44)\",\n iris6: \"color(display-p3 0.239 0.241 0.491)\",\n iris7: \"color(display-p3 0.291 0.289 0.565)\",\n iris8: \"color(display-p3 0.35 0.345 0.673)\",\n iris9: \"color(display-p3 0.357 0.357 0.81)\",\n iris10: \"color(display-p3 0.428 0.416 0.843)\",\n iris11: \"color(display-p3 0.685 0.662 1)\",\n iris12: \"color(display-p3 0.878 0.875 0.986)\",\n};\nconst irisDarkP3A = {\n irisA1: \"color(display-p3 0.224 0.224 0.992 / 0.051)\",\n irisA2: \"color(display-p3 0.361 0.314 1 / 0.08)\",\n irisA3: \"color(display-p3 0.357 0.373 1 / 0.219)\",\n irisA4: \"color(display-p3 0.325 0.361 1 / 0.337)\",\n irisA5: \"color(display-p3 0.38 0.4 1 / 0.4)\",\n irisA6: \"color(display-p3 0.447 0.447 1 / 0.454)\",\n irisA7: \"color(display-p3 0.486 0.486 1 / 0.534)\",\n irisA8: \"color(display-p3 0.502 0.494 1 / 0.652)\",\n irisA9: \"color(display-p3 0.431 0.431 1 / 0.799)\",\n irisA10: \"color(display-p3 0.502 0.486 1 / 0.832)\",\n irisA11: \"color(display-p3 0.685 0.662 1)\",\n irisA12: \"color(display-p3 0.878 0.875 0.986)\",\n};\nconst indigoDark = {\n indigo1: \"#11131f\",\n indigo2: \"#141726\",\n indigo3: \"#182449\",\n indigo4: \"#1d2e62\",\n indigo5: \"#253974\",\n indigo6: \"#304384\",\n indigo7: \"#3a4f97\",\n indigo8: \"#435db1\",\n indigo9: \"#3e63dd\",\n indigo10: \"#5472e4\",\n indigo11: \"#9eb1ff\",\n indigo12: \"#d6e1ff\",\n};\nconst indigoDarkA = {\n indigoA1: \"#1133ff0f\",\n indigoA2: \"#3354fa17\",\n indigoA3: \"#2f62ff3c\",\n indigoA4: \"#3566ff57\",\n indigoA5: \"#4171fd6b\",\n indigoA6: \"#5178fd7c\",\n indigoA7: \"#5a7fff90\",\n indigoA8: \"#5b81feac\",\n indigoA9: \"#4671ffdb\",\n indigoA10: \"#5c7efee3\",\n indigoA11: \"#9eb1ff\",\n indigoA12: \"#d6e1ff\",\n};\nconst indigoDarkP3 = {\n indigo1: \"color(display-p3 0.068 0.074 0.118)\",\n indigo2: \"color(display-p3 0.081 0.089 0.144)\",\n indigo3: \"color(display-p3 0.105 0.141 0.275)\",\n indigo4: \"color(display-p3 0.129 0.18 0.369)\",\n indigo5: \"color(display-p3 0.163 0.22 0.439)\",\n indigo6: \"color(display-p3 0.203 0.262 0.5)\",\n indigo7: \"color(display-p3 0.245 0.309 0.575)\",\n indigo8: \"color(display-p3 0.285 0.362 0.674)\",\n indigo9: \"color(display-p3 0.276 0.384 0.837)\",\n indigo10: \"color(display-p3 0.354 0.445 0.866)\",\n indigo11: \"color(display-p3 0.63 0.69 1)\",\n indigo12: \"color(display-p3 0.848 0.881 0.99)\",\n};\nconst indigoDarkP3A = {\n indigoA1: \"color(display-p3 0.071 0.212 0.996 / 0.055)\",\n indigoA2: \"color(display-p3 0.251 0.345 0.988 / 0.085)\",\n indigoA3: \"color(display-p3 0.243 0.404 1 / 0.223)\",\n indigoA4: \"color(display-p3 0.263 0.42 1 / 0.324)\",\n indigoA5: \"color(display-p3 0.314 0.451 1 / 0.4)\",\n indigoA6: \"color(display-p3 0.361 0.49 1 / 0.467)\",\n indigoA7: \"color(display-p3 0.388 0.51 1 / 0.547)\",\n indigoA8: \"color(display-p3 0.404 0.518 1 / 0.652)\",\n indigoA9: \"color(display-p3 0.318 0.451 1 / 0.824)\",\n indigoA10: \"color(display-p3 0.404 0.506 1 / 0.858)\",\n indigoA11: \"color(display-p3 0.63 0.69 1)\",\n indigoA12: \"color(display-p3 0.848 0.881 0.99)\",\n};\nconst blueDark = {\n blue1: \"#0d1520\",\n blue2: \"#111927\",\n blue3: \"#0d2847\",\n blue4: \"#003362\",\n blue5: \"#004074\",\n blue6: \"#104d87\",\n blue7: \"#205d9e\",\n blue8: \"#2870bd\",\n blue9: \"#0090ff\",\n blue10: \"#3b9eff\",\n blue11: \"#70b8ff\",\n blue12: \"#c2e6ff\",\n};\nconst blueDarkA = {\n blueA1: \"#004df211\",\n blueA2: \"#1166fb18\",\n blueA3: \"#0077ff3a\",\n blueA4: \"#0075ff57\",\n blueA5: \"#0081fd6b\",\n blueA6: \"#0f89fd7f\",\n blueA7: \"#2a91fe98\",\n blueA8: \"#3094feb9\",\n blueA9: \"#0090ff\",\n blueA10: \"#3b9eff\",\n blueA11: \"#70b8ff\",\n blueA12: \"#c2e6ff\",\n};\nconst blueDarkP3 = {\n blue1: \"color(display-p3 0.057 0.081 0.122)\",\n blue2: \"color(display-p3 0.072 0.098 0.147)\",\n blue3: \"color(display-p3 0.078 0.154 0.27)\",\n blue4: \"color(display-p3 0.033 0.197 0.37)\",\n blue5: \"color(display-p3 0.08 0.245 0.441)\",\n blue6: \"color(display-p3 0.14 0.298 0.511)\",\n blue7: \"color(display-p3 0.195 0.361 0.6)\",\n blue8: \"color(display-p3 0.239 0.434 0.72)\",\n blue9: \"color(display-p3 0.247 0.556 0.969)\",\n blue10: \"color(display-p3 0.344 0.612 0.973)\",\n blue11: \"color(display-p3 0.49 0.72 1)\",\n blue12: \"color(display-p3 0.788 0.898 0.99)\",\n};\nconst blueDarkP3A = {\n blueA1: \"color(display-p3 0 0.333 1 / 0.059)\",\n blueA2: \"color(display-p3 0.114 0.435 0.988 / 0.085)\",\n blueA3: \"color(display-p3 0.122 0.463 1 / 0.219)\",\n blueA4: \"color(display-p3 0 0.467 1 / 0.324)\",\n blueA5: \"color(display-p3 0.098 0.51 1 / 0.4)\",\n blueA6: \"color(display-p3 0.224 0.557 1 / 0.475)\",\n blueA7: \"color(display-p3 0.294 0.584 1 / 0.572)\",\n blueA8: \"color(display-p3 0.314 0.592 1 / 0.702)\",\n blueA9: \"color(display-p3 0.251 0.573 0.996 / 0.967)\",\n blueA10: \"color(display-p3 0.357 0.631 1 / 0.971)\",\n blueA11: \"color(display-p3 0.49 0.72 1)\",\n blueA12: \"color(display-p3 0.788 0.898 0.99)\",\n};\nconst cyanDark = {\n cyan1: \"#0b161a\",\n cyan2: \"#101b20\",\n cyan3: \"#082c36\",\n cyan4: \"#003848\",\n cyan5: \"#004558\",\n cyan6: \"#045468\",\n cyan7: \"#12677e\",\n cyan8: \"#11809c\",\n cyan9: \"#00a2c7\",\n cyan10: \"#23afd0\",\n cyan11: \"#4ccce6\",\n cyan12: \"#b6ecf7\",\n};\nconst cyanDarkA = {\n cyanA1: \"#0091f70a\",\n cyanA2: \"#02a7f211\",\n cyanA3: \"#00befd28\",\n cyanA4: \"#00baff3b\",\n cyanA5: \"#00befd4d\",\n cyanA6: \"#00c7fd5e\",\n cyanA7: \"#14cdff75\",\n cyanA8: \"#11cfff95\",\n cyanA9: \"#00cfffc3\",\n cyanA10: \"#28d6ffcd\",\n cyanA11: \"#52e1fee5\",\n cyanA12: \"#bbf3fef7\",\n};\nconst cyanDarkP3 = {\n cyan1: \"color(display-p3 0.053 0.085 0.098)\",\n cyan2: \"color(display-p3 0.072 0.105 0.122)\",\n cyan3: \"color(display-p3 0.073 0.168 0.209)\",\n cyan4: \"color(display-p3 0.063 0.216 0.277)\",\n cyan5: \"color(display-p3 0.091 0.267 0.336)\",\n cyan6: \"color(display-p3 0.137 0.324 0.4)\",\n cyan7: \"color(display-p3 0.186 0.398 0.484)\",\n cyan8: \"color(display-p3 0.23 0.496 0.6)\",\n cyan9: \"color(display-p3 0.282 0.627 0.765)\",\n cyan10: \"color(display-p3 0.331 0.675 0.801)\",\n cyan11: \"color(display-p3 0.446 0.79 0.887)\",\n cyan12: \"color(display-p3 0.757 0.919 0.962)\",\n};\nconst cyanDarkP3A = {\n cyanA1: \"color(display-p3 0 0.647 0.992 / 0.034)\",\n cyanA2: \"color(display-p3 0.133 0.733 1 / 0.059)\",\n cyanA3: \"color(display-p3 0.122 0.741 0.996 / 0.152)\",\n cyanA4: \"color(display-p3 0.051 0.725 1 / 0.227)\",\n cyanA5: \"color(display-p3 0.149 0.757 1 / 0.29)\",\n cyanA6: \"color(display-p3 0.267 0.792 1 / 0.358)\",\n cyanA7: \"color(display-p3 0.333 0.808 1 / 0.446)\",\n cyanA8: \"color(display-p3 0.357 0.816 1 / 0.572)\",\n cyanA9: \"color(display-p3 0.357 0.82 1 / 0.748)\",\n cyanA10: \"color(display-p3 0.4 0.839 1 / 0.786)\",\n cyanA11: \"color(display-p3 0.446 0.79 0.887)\",\n cyanA12: \"color(display-p3 0.757 0.919 0.962)\",\n};\nconst tealDark = {\n teal1: \"#0d1514\",\n teal2: \"#111c1b\",\n teal3: \"#0d2d2a\",\n teal4: \"#023b37\",\n teal5: \"#084843\",\n teal6: \"#145750\",\n teal7: \"#1c6961\",\n teal8: \"#207e73\",\n teal9: \"#12a594\",\n teal10: \"#0eb39e\",\n teal11: \"#0bd8b6\",\n teal12: \"#adf0dd\",\n};\nconst tealDarkA = {\n tealA1: \"#00deab05\",\n tealA2: \"#12fbe60c\",\n tealA3: \"#00ffe61e\",\n tealA4: \"#00ffe92d\",\n tealA5: \"#00ffea3b\",\n tealA6: \"#1cffe84b\",\n tealA7: \"#2efde85f\",\n tealA8: \"#32ffe775\",\n tealA9: \"#13ffe49f\",\n tealA10: \"#0dffe0ae\",\n tealA11: \"#0afed5d6\",\n tealA12: \"#b8ffebef\",\n};\nconst tealDarkP3 = {\n teal1: \"color(display-p3 0.059 0.083 0.079)\",\n teal2: \"color(display-p3 0.075 0.11 0.107)\",\n teal3: \"color(display-p3 0.087 0.175 0.165)\",\n teal4: \"color(display-p3 0.087 0.227 0.214)\",\n teal5: \"color(display-p3 0.12 0.277 0.261)\",\n teal6: \"color(display-p3 0.162 0.335 0.314)\",\n teal7: \"color(display-p3 0.205 0.406 0.379)\",\n teal8: \"color(display-p3 0.245 0.489 0.453)\",\n teal9: \"color(display-p3 0.297 0.637 0.581)\",\n teal10: \"color(display-p3 0.319 0.69 0.62)\",\n teal11: \"color(display-p3 0.388 0.835 0.719)\",\n teal12: \"color(display-p3 0.734 0.934 0.87)\",\n};\nconst tealDarkP3A = {\n tealA1: \"color(display-p3 0 0.992 0.761 / 0.017)\",\n tealA2: \"color(display-p3 0.235 0.988 0.902 / 0.047)\",\n tealA3: \"color(display-p3 0.235 1 0.898 / 0.118)\",\n tealA4: \"color(display-p3 0.18 0.996 0.929 / 0.173)\",\n tealA5: \"color(display-p3 0.31 1 0.933 / 0.227)\",\n tealA6: \"color(display-p3 0.396 1 0.933 / 0.286)\",\n tealA7: \"color(display-p3 0.443 1 0.925 / 0.366)\",\n tealA8: \"color(display-p3 0.459 1 0.925 / 0.454)\",\n tealA9: \"color(display-p3 0.443 0.996 0.906 / 0.61)\",\n tealA10: \"color(display-p3 0.439 0.996 0.89 / 0.669)\",\n tealA11: \"color(display-p3 0.388 0.835 0.719)\",\n tealA12: \"color(display-p3 0.734 0.934 0.87)\",\n};\nconst jadeDark = {\n jade1: \"#0d1512\",\n jade2: \"#121c18\",\n jade3: \"#0f2e22\",\n jade4: \"#0b3b2c\",\n jade5: \"#114837\",\n jade6: \"#1b5745\",\n jade7: \"#246854\",\n jade8: \"#2a7e68\",\n jade9: \"#29a383\",\n jade10: \"#27b08b\",\n jade11: \"#1fd8a4\",\n jade12: \"#adf0d4\",\n};\nconst jadeDarkA = {\n jadeA1: \"#00de4505\",\n jadeA2: \"#27fba60c\",\n jadeA3: \"#02f99920\",\n jadeA4: \"#00ffaa2d\",\n jadeA5: \"#11ffb63b\",\n jadeA6: \"#34ffc24b\",\n jadeA7: \"#45fdc75e\",\n jadeA8: \"#48ffcf75\",\n jadeA9: \"#38feca9d\",\n jadeA10: \"#31fec7ab\",\n jadeA11: \"#21fec0d6\",\n jadeA12: \"#b8ffe1ef\",\n};\nconst jadeDarkP3 = {\n jade1: \"color(display-p3 0.059 0.083 0.071)\",\n jade2: \"color(display-p3 0.078 0.11 0.094)\",\n jade3: \"color(display-p3 0.091 0.176 0.138)\",\n jade4: \"color(display-p3 0.102 0.228 0.177)\",\n jade5: \"color(display-p3 0.133 0.279 0.221)\",\n jade6: \"color(display-p3 0.174 0.334 0.273)\",\n jade7: \"color(display-p3 0.219 0.402 0.335)\",\n jade8: \"color(display-p3 0.263 0.488 0.411)\",\n jade9: \"color(display-p3 0.319 0.63 0.521)\",\n jade10: \"color(display-p3 0.338 0.68 0.555)\",\n jade11: \"color(display-p3 0.4 0.835 0.656)\",\n jade12: \"color(display-p3 0.734 0.934 0.838)\",\n};\nconst jadeDarkP3A = {\n jadeA1: \"color(display-p3 0 0.992 0.298 / 0.017)\",\n jadeA2: \"color(display-p3 0.318 0.988 0.651 / 0.047)\",\n jadeA3: \"color(display-p3 0.267 1 0.667 / 0.118)\",\n jadeA4: \"color(display-p3 0.275 0.996 0.702 / 0.173)\",\n jadeA5: \"color(display-p3 0.361 1 0.741 / 0.227)\",\n jadeA6: \"color(display-p3 0.439 1 0.796 / 0.286)\",\n jadeA7: \"color(display-p3 0.49 1 0.804 / 0.362)\",\n jadeA8: \"color(display-p3 0.506 1 0.835 / 0.45)\",\n jadeA9: \"color(display-p3 0.478 0.996 0.816 / 0.606)\",\n jadeA10: \"color(display-p3 0.478 1 0.816 / 0.656)\",\n jadeA11: \"color(display-p3 0.4 0.835 0.656)\",\n jadeA12: \"color(display-p3 0.734 0.934 0.838)\",\n};\nconst greenDark = {\n green1: \"#0e1512\",\n green2: \"#121b17\",\n green3: \"#132d21\",\n green4: \"#113b29\",\n green5: \"#174933\",\n green6: \"#20573e\",\n green7: \"#28684a\",\n green8: \"#2f7c57\",\n green9: \"#30a46c\",\n green10: \"#33b074\",\n green11: \"#3dd68c\",\n green12: \"#b1f1cb\",\n};\nconst greenDarkA = {\n greenA1: \"#00de4505\",\n greenA2: \"#29f99d0b\",\n greenA3: \"#22ff991e\",\n greenA4: \"#11ff992d\",\n greenA5: \"#2bffa23c\",\n greenA6: \"#44ffaa4b\",\n greenA7: \"#50fdac5e\",\n greenA8: \"#54ffad73\",\n greenA9: \"#44ffa49e\",\n greenA10: \"#43fea4ab\",\n greenA11: \"#46fea5d4\",\n greenA12: \"#bbffd7f0\",\n};\nconst greenDarkP3 = {\n green1: \"color(display-p3 0.062 0.083 0.071)\",\n green2: \"color(display-p3 0.079 0.106 0.09)\",\n green3: \"color(display-p3 0.1 0.173 0.133)\",\n green4: \"color(display-p3 0.115 0.229 0.166)\",\n green5: \"color(display-p3 0.147 0.282 0.206)\",\n green6: \"color(display-p3 0.185 0.338 0.25)\",\n green7: \"color(display-p3 0.227 0.403 0.298)\",\n green8: \"color(display-p3 0.27 0.479 0.351)\",\n green9: \"color(display-p3 0.332 0.634 0.442)\",\n green10: \"color(display-p3 0.357 0.682 0.474)\",\n green11: \"color(display-p3 0.434 0.828 0.573)\",\n green12: \"color(display-p3 0.747 0.938 0.807)\",\n};\nconst greenDarkP3A = {\n greenA1: \"color(display-p3 0 0.992 0.298 / 0.017)\",\n greenA2: \"color(display-p3 0.341 0.98 0.616 / 0.043)\",\n greenA3: \"color(display-p3 0.376 0.996 0.655 / 0.114)\",\n greenA4: \"color(display-p3 0.341 0.996 0.635 / 0.173)\",\n greenA5: \"color(display-p3 0.408 1 0.678 / 0.232)\",\n greenA6: \"color(display-p3 0.475 1 0.706 / 0.29)\",\n greenA7: \"color(display-p3 0.514 1 0.706 / 0.362)\",\n greenA8: \"color(display-p3 0.529 1 0.718 / 0.442)\",\n greenA9: \"color(display-p3 0.502 0.996 0.682 / 0.61)\",\n greenA10: \"color(display-p3 0.506 1 0.682 / 0.66)\",\n greenA11: \"color(display-p3 0.434 0.828 0.573)\",\n greenA12: \"color(display-p3 0.747 0.938 0.807)\",\n};\nconst grassDark = {\n grass1: \"#0e1511\",\n grass2: \"#141a15\",\n grass3: \"#1b2a1e\",\n grass4: \"#1d3a24\",\n grass5: \"#25482d\",\n grass6: \"#2d5736\",\n grass7: \"#366740\",\n grass8: \"#3e7949\",\n grass9: \"#46a758\",\n grass10: \"#53b365\",\n grass11: \"#71d083\",\n grass12: \"#c2f0c2\",\n};\nconst grassDarkA = {\n grassA1: \"#00de1205\",\n grassA2: \"#5ef7780a\",\n grassA3: \"#70fe8c1b\",\n grassA4: \"#57ff802c\",\n grassA5: \"#68ff8b3b\",\n grassA6: \"#71ff8f4b\",\n grassA7: \"#77fd925d\",\n grassA8: \"#77fd9070\",\n grassA9: \"#65ff82a1\",\n grassA10: \"#72ff8dae\",\n grassA11: \"#89ff9fcd\",\n grassA12: \"#ceffceef\",\n};\nconst grassDarkP3 = {\n grass1: \"color(display-p3 0.062 0.083 0.067)\",\n grass2: \"color(display-p3 0.083 0.103 0.085)\",\n grass3: \"color(display-p3 0.118 0.163 0.122)\",\n grass4: \"color(display-p3 0.142 0.225 0.15)\",\n grass5: \"color(display-p3 0.178 0.279 0.186)\",\n grass6: \"color(display-p3 0.217 0.337 0.224)\",\n grass7: \"color(display-p3 0.258 0.4 0.264)\",\n grass8: \"color(display-p3 0.302 0.47 0.305)\",\n grass9: \"color(display-p3 0.38 0.647 0.378)\",\n grass10: \"color(display-p3 0.426 0.694 0.426)\",\n grass11: \"color(display-p3 0.535 0.807 0.542)\",\n grass12: \"color(display-p3 0.797 0.936 0.776)\",\n};\nconst grassDarkP3A = {\n grassA1: \"color(display-p3 0 0.992 0.071 / 0.017)\",\n grassA2: \"color(display-p3 0.482 0.996 0.584 / 0.038)\",\n grassA3: \"color(display-p3 0.549 0.992 0.588 / 0.106)\",\n grassA4: \"color(display-p3 0.51 0.996 0.557 / 0.169)\",\n grassA5: \"color(display-p3 0.553 1 0.588 / 0.227)\",\n grassA6: \"color(display-p3 0.584 1 0.608 / 0.29)\",\n grassA7: \"color(display-p3 0.604 1 0.616 / 0.358)\",\n grassA8: \"color(display-p3 0.608 1 0.62 / 0.433)\",\n grassA9: \"color(display-p3 0.573 1 0.569 / 0.622)\",\n grassA10: \"color(display-p3 0.6 0.996 0.6 / 0.673)\",\n grassA11: \"color(display-p3 0.535 0.807 0.542)\",\n grassA12: \"color(display-p3 0.797 0.936 0.776)\",\n};\nconst brownDark = {\n brown1: \"#12110f\",\n brown2: \"#1c1816\",\n brown3: \"#28211d\",\n brown4: \"#322922\",\n brown5: \"#3e3128\",\n brown6: \"#4d3c2f\",\n brown7: \"#614a39\",\n brown8: \"#7c5f46\",\n brown9: \"#ad7f58\",\n brown10: \"#b88c67\",\n brown11: \"#dbb594\",\n brown12: \"#f2e1ca\",\n};\nconst brownDarkA = {\n brownA1: \"#91110002\",\n brownA2: \"#fba67c0c\",\n brownA3: \"#fcb58c19\",\n brownA4: \"#fbbb8a24\",\n brownA5: \"#fcb88931\",\n brownA6: \"#fdba8741\",\n brownA7: \"#ffbb8856\",\n brownA8: \"#ffbe8773\",\n brownA9: \"#feb87da8\",\n brownA10: \"#ffc18cb3\",\n brownA11: \"#fed1aad9\",\n brownA12: \"#feecd4f2\",\n};\nconst brownDarkP3 = {\n brown1: \"color(display-p3 0.071 0.067 0.059)\",\n brown2: \"color(display-p3 0.107 0.095 0.087)\",\n brown3: \"color(display-p3 0.151 0.13 0.115)\",\n brown4: \"color(display-p3 0.191 0.161 0.138)\",\n brown5: \"color(display-p3 0.235 0.194 0.162)\",\n brown6: \"color(display-p3 0.291 0.237 0.192)\",\n brown7: \"color(display-p3 0.365 0.295 0.232)\",\n brown8: \"color(display-p3 0.469 0.377 0.287)\",\n brown9: \"color(display-p3 0.651 0.505 0.368)\",\n brown10: \"color(display-p3 0.697 0.557 0.423)\",\n brown11: \"color(display-p3 0.835 0.715 0.597)\",\n brown12: \"color(display-p3 0.938 0.885 0.802)\",\n};\nconst brownDarkP3A = {\n brownA1: \"color(display-p3 0.855 0.071 0 / 0.005)\",\n brownA2: \"color(display-p3 0.98 0.706 0.525 / 0.043)\",\n brownA3: \"color(display-p3 0.996 0.745 0.576 / 0.093)\",\n brownA4: \"color(display-p3 1 0.765 0.592 / 0.135)\",\n brownA5: \"color(display-p3 1 0.761 0.588 / 0.181)\",\n brownA6: \"color(display-p3 1 0.773 0.592 / 0.24)\",\n brownA7: \"color(display-p3 0.996 0.776 0.58 / 0.32)\",\n brownA8: \"color(display-p3 1 0.78 0.573 / 0.433)\",\n brownA9: \"color(display-p3 1 0.769 0.549 / 0.627)\",\n brownA10: \"color(display-p3 1 0.792 0.596 / 0.677)\",\n brownA11: \"color(display-p3 0.835 0.715 0.597)\",\n brownA12: \"color(display-p3 0.938 0.885 0.802)\",\n};\nconst bronzeDark = {\n bronze1: \"#141110\",\n bronze2: \"#1c1917\",\n bronze3: \"#262220\",\n bronze4: \"#302a27\",\n bronze5: \"#3b3330\",\n bronze6: \"#493e3a\",\n bronze7: \"#5a4c47\",\n bronze8: \"#6f5f58\",\n bronze9: \"#a18072\",\n bronze10: \"#ae8c7e\",\n bronze11: \"#d4b3a5\",\n bronze12: \"#ede0d9\",\n};\nconst bronzeDarkA = {\n bronzeA1: \"#d1110004\",\n bronzeA2: \"#fbbc910c\",\n bronzeA3: \"#faceb817\",\n bronzeA4: \"#facdb622\",\n bronzeA5: \"#ffd2c12d\",\n bronzeA6: \"#ffd1c03c\",\n bronzeA7: \"#fdd0c04f\",\n bronzeA8: \"#ffd6c565\",\n bronzeA9: \"#fec7b09b\",\n bronzeA10: \"#fecab5a9\",\n bronzeA11: \"#ffd7c6d1\",\n bronzeA12: \"#fff1e9ec\",\n};\nconst bronzeDarkP3 = {\n bronze1: \"color(display-p3 0.076 0.067 0.063)\",\n bronze2: \"color(display-p3 0.106 0.097 0.093)\",\n bronze3: \"color(display-p3 0.147 0.132 0.125)\",\n bronze4: \"color(display-p3 0.185 0.166 0.156)\",\n bronze5: \"color(display-p3 0.227 0.202 0.19)\",\n bronze6: \"color(display-p3 0.278 0.246 0.23)\",\n bronze7: \"color(display-p3 0.343 0.302 0.281)\",\n bronze8: \"color(display-p3 0.426 0.374 0.347)\",\n bronze9: \"color(display-p3 0.611 0.507 0.455)\",\n bronze10: \"color(display-p3 0.66 0.556 0.504)\",\n bronze11: \"color(display-p3 0.81 0.707 0.655)\",\n bronze12: \"color(display-p3 0.921 0.88 0.854)\",\n};\nconst bronzeDarkP3A = {\n bronzeA1: \"color(display-p3 0.941 0.067 0 / 0.009)\",\n bronzeA2: \"color(display-p3 0.98 0.8 0.706 / 0.043)\",\n bronzeA3: \"color(display-p3 0.988 0.851 0.761 / 0.085)\",\n bronzeA4: \"color(display-p3 0.996 0.839 0.78 / 0.127)\",\n bronzeA5: \"color(display-p3 0.996 0.863 0.773 / 0.173)\",\n bronzeA6: \"color(display-p3 1 0.863 0.796 / 0.227)\",\n bronzeA7: \"color(display-p3 1 0.867 0.8 / 0.295)\",\n bronzeA8: \"color(display-p3 1 0.859 0.788 / 0.387)\",\n bronzeA9: \"color(display-p3 1 0.82 0.733 / 0.585)\",\n bronzeA10: \"color(display-p3 1 0.839 0.761 / 0.635)\",\n bronzeA11: \"color(display-p3 0.81 0.707 0.655)\",\n bronzeA12: \"color(display-p3 0.921 0.88 0.854)\",\n};\nconst goldDark = {\n gold1: \"#121211\",\n gold2: \"#1b1a17\",\n gold3: \"#24231f\",\n gold4: \"#2d2b26\",\n gold5: \"#38352e\",\n gold6: \"#444039\",\n gold7: \"#544f46\",\n gold8: \"#696256\",\n gold9: \"#978365\",\n gold10: \"#a39073\",\n gold11: \"#cbb99f\",\n gold12: \"#e8e2d9\",\n};\nconst goldDarkA = {\n goldA1: \"#91911102\",\n goldA2: \"#f9e29d0b\",\n goldA3: \"#f8ecbb15\",\n goldA4: \"#ffeec41e\",\n goldA5: \"#feecc22a\",\n goldA6: \"#feebcb37\",\n goldA7: \"#ffedcd48\",\n goldA8: \"#fdeaca5f\",\n goldA9: \"#ffdba690\",\n goldA10: \"#fedfb09d\",\n goldA11: \"#fee7c6c8\",\n goldA12: \"#fef7ede7\",\n};\nconst goldDarkP3 = {\n gold1: \"color(display-p3 0.071 0.071 0.067)\",\n gold2: \"color(display-p3 0.104 0.101 0.09)\",\n gold3: \"color(display-p3 0.141 0.136 0.122)\",\n gold4: \"color(display-p3 0.177 0.17 0.152)\",\n gold5: \"color(display-p3 0.217 0.207 0.185)\",\n gold6: \"color(display-p3 0.265 0.252 0.225)\",\n gold7: \"color(display-p3 0.327 0.31 0.277)\",\n gold8: \"color(display-p3 0.407 0.384 0.342)\",\n gold9: \"color(display-p3 0.579 0.517 0.41)\",\n gold10: \"color(display-p3 0.628 0.566 0.463)\",\n gold11: \"color(display-p3 0.784 0.728 0.635)\",\n gold12: \"color(display-p3 0.906 0.887 0.855)\",\n};\nconst goldDarkP3A = {\n goldA1: \"color(display-p3 0.855 0.855 0.071 / 0.005)\",\n goldA2: \"color(display-p3 0.98 0.89 0.616 / 0.043)\",\n goldA3: \"color(display-p3 1 0.949 0.753 / 0.08)\",\n goldA4: \"color(display-p3 1 0.933 0.8 / 0.118)\",\n goldA5: \"color(display-p3 1 0.949 0.804 / 0.16)\",\n goldA6: \"color(display-p3 1 0.925 0.8 / 0.215)\",\n goldA7: \"color(display-p3 1 0.945 0.831 / 0.278)\",\n goldA8: \"color(display-p3 1 0.937 0.82 / 0.366)\",\n goldA9: \"color(display-p3 0.996 0.882 0.69 / 0.551)\",\n goldA10: \"color(display-p3 1 0.894 0.725 / 0.601)\",\n goldA11: \"color(display-p3 0.784 0.728 0.635)\",\n goldA12: \"color(display-p3 0.906 0.887 0.855)\",\n};\nconst skyDark = {\n sky1: \"#0d141f\",\n sky2: \"#111a27\",\n sky3: \"#112840\",\n sky4: \"#113555\",\n sky5: \"#154467\",\n sky6: \"#1b537b\",\n sky7: \"#1f6692\",\n sky8: \"#197cae\",\n sky9: \"#7ce2fe\",\n sky10: \"#a8eeff\",\n sky11: \"#75c7f0\",\n sky12: \"#c2f3ff\",\n};\nconst skyDarkA = {\n skyA1: \"#0044ff0f\",\n skyA2: \"#1171fb18\",\n skyA3: \"#1184fc33\",\n skyA4: \"#128fff49\",\n skyA5: \"#1c9dfd5d\",\n skyA6: \"#28a5ff72\",\n skyA7: \"#2badfe8b\",\n skyA8: \"#1db2fea9\",\n skyA9: \"#7ce3fffe\",\n skyA10: \"#a8eeff\",\n skyA11: \"#7cd3ffef\",\n skyA12: \"#c2f3ff\",\n};\nconst skyDarkP3 = {\n sky1: \"color(display-p3 0.056 0.078 0.116)\",\n sky2: \"color(display-p3 0.075 0.101 0.149)\",\n sky3: \"color(display-p3 0.089 0.154 0.244)\",\n sky4: \"color(display-p3 0.106 0.207 0.323)\",\n sky5: \"color(display-p3 0.135 0.261 0.394)\",\n sky6: \"color(display-p3 0.17 0.322 0.469)\",\n sky7: \"color(display-p3 0.205 0.394 0.557)\",\n sky8: \"color(display-p3 0.232 0.48 0.665)\",\n sky9: \"color(display-p3 0.585 0.877 0.983)\",\n sky10: \"color(display-p3 0.718 0.925 0.991)\",\n sky11: \"color(display-p3 0.536 0.772 0.924)\",\n sky12: \"color(display-p3 0.799 0.947 0.993)\",\n};\nconst skyDarkP3A = {\n skyA1: \"color(display-p3 0 0.282 0.996 / 0.055)\",\n skyA2: \"color(display-p3 0.157 0.467 0.992 / 0.089)\",\n skyA3: \"color(display-p3 0.192 0.522 0.996 / 0.19)\",\n skyA4: \"color(display-p3 0.212 0.584 1 / 0.274)\",\n skyA5: \"color(display-p3 0.259 0.631 1 / 0.349)\",\n skyA6: \"color(display-p3 0.302 0.655 1 / 0.433)\",\n skyA7: \"color(display-p3 0.329 0.686 1 / 0.526)\",\n skyA8: \"color(display-p3 0.325 0.71 1 / 0.643)\",\n skyA9: \"color(display-p3 0.592 0.894 1 / 0.984)\",\n skyA10: \"color(display-p3 0.722 0.933 1 / 0.992)\",\n skyA11: \"color(display-p3 0.536 0.772 0.924)\",\n skyA12: \"color(display-p3 0.799 0.947 0.993)\",\n};\nconst mintDark = {\n mint1: \"#0e1515\",\n mint2: \"#0f1b1b\",\n mint3: \"#092c2b\",\n mint4: \"#003a38\",\n mint5: \"#004744\",\n mint6: \"#105650\",\n mint7: \"#1e685f\",\n mint8: \"#277f70\",\n mint9: \"#86ead4\",\n mint10: \"#a8f5e5\",\n mint11: \"#58d5ba\",\n mint12: \"#c4f5e1\",\n};\nconst mintDarkA = {\n mintA1: \"#00dede05\",\n mintA2: \"#00f9f90b\",\n mintA3: \"#00fff61d\",\n mintA4: \"#00fff42c\",\n mintA5: \"#00fff23a\",\n mintA6: \"#0effeb4a\",\n mintA7: \"#34fde55e\",\n mintA8: \"#41ffdf76\",\n mintA9: \"#92ffe7e9\",\n mintA10: \"#aefeedf5\",\n mintA11: \"#67ffded2\",\n mintA12: \"#cbfee9f5\",\n};\nconst mintDarkP3 = {\n mint1: \"color(display-p3 0.059 0.082 0.081)\",\n mint2: \"color(display-p3 0.068 0.104 0.105)\",\n mint3: \"color(display-p3 0.077 0.17 0.168)\",\n mint4: \"color(display-p3 0.068 0.224 0.22)\",\n mint5: \"color(display-p3 0.104 0.275 0.264)\",\n mint6: \"color(display-p3 0.154 0.332 0.313)\",\n mint7: \"color(display-p3 0.207 0.403 0.373)\",\n mint8: \"color(display-p3 0.258 0.49 0.441)\",\n mint9: \"color(display-p3 0.62 0.908 0.834)\",\n mint10: \"color(display-p3 0.725 0.954 0.898)\",\n mint11: \"color(display-p3 0.482 0.825 0.733)\",\n mint12: \"color(display-p3 0.807 0.955 0.887)\",\n};\nconst mintDarkP3A = {\n mintA1: \"color(display-p3 0 0.992 0.992 / 0.017)\",\n mintA2: \"color(display-p3 0.071 0.98 0.98 / 0.043)\",\n mintA3: \"color(display-p3 0.176 0.996 0.996 / 0.11)\",\n mintA4: \"color(display-p3 0.071 0.996 0.973 / 0.169)\",\n mintA5: \"color(display-p3 0.243 1 0.949 / 0.223)\",\n mintA6: \"color(display-p3 0.369 1 0.933 / 0.286)\",\n mintA7: \"color(display-p3 0.459 1 0.914 / 0.362)\",\n mintA8: \"color(display-p3 0.49 1 0.89 / 0.454)\",\n mintA9: \"color(display-p3 0.678 0.996 0.914 / 0.904)\",\n mintA10: \"color(display-p3 0.761 1 0.941 / 0.95)\",\n mintA11: \"color(display-p3 0.482 0.825 0.733)\",\n mintA12: \"color(display-p3 0.807 0.955 0.887)\",\n};\nconst limeDark = {\n lime1: \"#11130c\",\n lime2: \"#151a10\",\n lime3: \"#1f2917\",\n lime4: \"#29371d\",\n lime5: \"#334423\",\n lime6: \"#3d522a\",\n lime7: \"#496231\",\n lime8: \"#577538\",\n lime9: \"#bdee63\",\n lime10: \"#d4ff70\",\n lime11: \"#bde56c\",\n lime12: \"#e3f7ba\",\n};\nconst limeDarkA = {\n limeA1: \"#11bb0003\",\n limeA2: \"#78f7000a\",\n limeA3: \"#9bfd4c1a\",\n limeA4: \"#a7fe5c29\",\n limeA5: \"#affe6537\",\n limeA6: \"#b2fe6d46\",\n limeA7: \"#b6ff6f57\",\n limeA8: \"#b6fd6d6c\",\n limeA9: \"#caff69ed\",\n limeA10: \"#d4ff70\",\n limeA11: \"#d1fe77e4\",\n limeA12: \"#e9febff7\",\n};\nconst limeDarkP3 = {\n lime1: \"color(display-p3 0.067 0.073 0.048)\",\n lime2: \"color(display-p3 0.086 0.1 0.067)\",\n lime3: \"color(display-p3 0.13 0.16 0.099)\",\n lime4: \"color(display-p3 0.172 0.214 0.126)\",\n lime5: \"color(display-p3 0.213 0.266 0.153)\",\n lime6: \"color(display-p3 0.257 0.321 0.182)\",\n lime7: \"color(display-p3 0.307 0.383 0.215)\",\n lime8: \"color(display-p3 0.365 0.456 0.25)\",\n lime9: \"color(display-p3 0.78 0.928 0.466)\",\n lime10: \"color(display-p3 0.865 0.995 0.519)\",\n lime11: \"color(display-p3 0.771 0.893 0.485)\",\n lime12: \"color(display-p3 0.905 0.966 0.753)\",\n};\nconst limeDarkP3A = {\n limeA1: \"color(display-p3 0.067 0.941 0 / 0.009)\",\n limeA2: \"color(display-p3 0.584 0.996 0.071 / 0.038)\",\n limeA3: \"color(display-p3 0.69 1 0.38 / 0.101)\",\n limeA4: \"color(display-p3 0.729 1 0.435 / 0.16)\",\n limeA5: \"color(display-p3 0.745 1 0.471 / 0.215)\",\n limeA6: \"color(display-p3 0.769 1 0.482 / 0.274)\",\n limeA7: \"color(display-p3 0.769 1 0.506 / 0.341)\",\n limeA8: \"color(display-p3 0.784 1 0.51 / 0.416)\",\n limeA9: \"color(display-p3 0.839 1 0.502 / 0.925)\",\n limeA10: \"color(display-p3 0.871 1 0.522 / 0.996)\",\n limeA11: \"color(display-p3 0.771 0.893 0.485)\",\n limeA12: \"color(display-p3 0.905 0.966 0.753)\",\n};\nconst yellowDark = {\n yellow1: \"#14120b\",\n yellow2: \"#1b180f\",\n yellow3: \"#2d2305\",\n yellow4: \"#362b00\",\n yellow5: \"#433500\",\n yellow6: \"#524202\",\n yellow7: \"#665417\",\n yellow8: \"#836a21\",\n yellow9: \"#ffe629\",\n yellow10: \"#ffff57\",\n yellow11: \"#f5e147\",\n yellow12: \"#f6eeb4\",\n};\nconst yellowDarkA = {\n yellowA1: \"#d1510004\",\n yellowA2: \"#f9b4000b\",\n yellowA3: \"#ffaa001e\",\n yellowA4: \"#fdb70028\",\n yellowA5: \"#febb0036\",\n yellowA6: \"#fec40046\",\n yellowA7: \"#fdcb225c\",\n yellowA8: \"#fdca327b\",\n yellowA9: \"#ffe629\",\n yellowA10: \"#ffff57\",\n yellowA11: \"#fee949f5\",\n yellowA12: \"#fef6baf6\",\n};\nconst yellowDarkP3 = {\n yellow1: \"color(display-p3 0.078 0.069 0.047)\",\n yellow2: \"color(display-p3 0.103 0.094 0.063)\",\n yellow3: \"color(display-p3 0.168 0.137 0.039)\",\n yellow4: \"color(display-p3 0.209 0.169 0)\",\n yellow5: \"color(display-p3 0.255 0.209 0)\",\n yellow6: \"color(display-p3 0.31 0.261 0.07)\",\n yellow7: \"color(display-p3 0.389 0.331 0.135)\",\n yellow8: \"color(display-p3 0.497 0.42 0.182)\",\n yellow9: \"color(display-p3 1 0.92 0.22)\",\n yellow10: \"color(display-p3 1 1 0.456)\",\n yellow11: \"color(display-p3 0.948 0.885 0.392)\",\n yellow12: \"color(display-p3 0.959 0.934 0.731)\",\n};\nconst yellowDarkP3A = {\n yellowA1: \"color(display-p3 0.973 0.369 0 / 0.013)\",\n yellowA2: \"color(display-p3 0.996 0.792 0 / 0.038)\",\n yellowA3: \"color(display-p3 0.996 0.71 0 / 0.11)\",\n yellowA4: \"color(display-p3 0.996 0.741 0 / 0.152)\",\n yellowA5: \"color(display-p3 0.996 0.765 0 / 0.202)\",\n yellowA6: \"color(display-p3 0.996 0.816 0.082 / 0.261)\",\n yellowA7: \"color(display-p3 1 0.831 0.263 / 0.345)\",\n yellowA8: \"color(display-p3 1 0.831 0.314 / 0.463)\",\n yellowA9: \"color(display-p3 1 0.922 0.22)\",\n yellowA10: \"color(display-p3 1 1 0.455)\",\n yellowA11: \"color(display-p3 0.948 0.885 0.392)\",\n yellowA12: \"color(display-p3 0.959 0.934 0.731)\",\n};\nconst amberDark = {\n amber1: \"#16120c\",\n amber2: \"#1d180f\",\n amber3: \"#302008\",\n amber4: \"#3f2700\",\n amber5: \"#4d3000\",\n amber6: \"#5c3d05\",\n amber7: \"#714f19\",\n amber8: \"#8f6424\",\n amber9: \"#ffc53d\",\n amber10: \"#ffd60a\",\n amber11: \"#ffca16\",\n amber12: \"#ffe7b3\",\n};\nconst amberDarkA = {\n amberA1: \"#e63c0006\",\n amberA2: \"#fd9b000d\",\n amberA3: \"#fa820022\",\n amberA4: \"#fc820032\",\n amberA5: \"#fd8b0041\",\n amberA6: \"#fd9b0051\",\n amberA7: \"#ffab2567\",\n amberA8: \"#ffae3587\",\n amberA9: \"#ffc53d\",\n amberA10: \"#ffd60a\",\n amberA11: \"#ffca16\",\n amberA12: \"#ffe7b3\",\n};\nconst amberDarkP3 = {\n amber1: \"color(display-p3 0.082 0.07 0.05)\",\n amber2: \"color(display-p3 0.111 0.094 0.064)\",\n amber3: \"color(display-p3 0.178 0.128 0.049)\",\n amber4: \"color(display-p3 0.239 0.156 0)\",\n amber5: \"color(display-p3 0.29 0.193 0)\",\n amber6: \"color(display-p3 0.344 0.245 0.076)\",\n amber7: \"color(display-p3 0.422 0.314 0.141)\",\n amber8: \"color(display-p3 0.535 0.399 0.189)\",\n amber9: \"color(display-p3 1 0.77 0.26)\",\n amber10: \"color(display-p3 1 0.87 0.15)\",\n amber11: \"color(display-p3 1 0.8 0.29)\",\n amber12: \"color(display-p3 0.984 0.909 0.726)\",\n};\nconst amberDarkP3A = {\n amberA1: \"color(display-p3 0.992 0.298 0 / 0.017)\",\n amberA2: \"color(display-p3 0.988 0.651 0 / 0.047)\",\n amberA3: \"color(display-p3 1 0.6 0 / 0.118)\",\n amberA4: \"color(display-p3 1 0.557 0 / 0.185)\",\n amberA5: \"color(display-p3 1 0.592 0 / 0.24)\",\n amberA6: \"color(display-p3 1 0.659 0.094 / 0.299)\",\n amberA7: \"color(display-p3 1 0.714 0.263 / 0.383)\",\n amberA8: \"color(display-p3 0.996 0.729 0.306 / 0.5)\",\n amberA9: \"color(display-p3 1 0.769 0.259)\",\n amberA10: \"color(display-p3 1 0.871 0.149)\",\n amberA11: \"color(display-p3 1 0.8 0.29)\",\n amberA12: \"color(display-p3 0.984 0.909 0.726)\",\n};\nconst orangeDark = {\n orange1: \"#17120e\",\n orange2: \"#1e160f\",\n orange3: \"#331e0b\",\n orange4: \"#462100\",\n orange5: \"#562800\",\n orange6: \"#66350c\",\n orange7: \"#7e451d\",\n orange8: \"#a35829\",\n orange9: \"#f76b15\",\n orange10: \"#ff801f\",\n orange11: \"#ffa057\",\n orange12: \"#ffe0c2\",\n};\nconst orangeDarkA = {\n orangeA1: \"#ec360007\",\n orangeA2: \"#fe6d000e\",\n orangeA3: \"#fb6a0025\",\n orangeA4: \"#ff590039\",\n orangeA5: \"#ff61004a\",\n orangeA6: \"#fd75045c\",\n orangeA7: \"#ff832c75\",\n orangeA8: \"#fe84389d\",\n orangeA9: \"#fe6d15f7\",\n orangeA10: \"#ff801f\",\n orangeA11: \"#ffa057\",\n orangeA12: \"#ffe0c2\",\n};\nconst orangeDarkP3 = {\n orange1: \"color(display-p3 0.088 0.07 0.057)\",\n orange2: \"color(display-p3 0.113 0.089 0.061)\",\n orange3: \"color(display-p3 0.189 0.12 0.056)\",\n orange4: \"color(display-p3 0.262 0.132 0)\",\n orange5: \"color(display-p3 0.315 0.168 0.016)\",\n orange6: \"color(display-p3 0.376 0.219 0.088)\",\n orange7: \"color(display-p3 0.465 0.283 0.147)\",\n orange8: \"color(display-p3 0.601 0.359 0.201)\",\n orange9: \"color(display-p3 0.9 0.45 0.2)\",\n orange10: \"color(display-p3 0.98 0.51 0.23)\",\n orange11: \"color(display-p3 1 0.63 0.38)\",\n orange12: \"color(display-p3 0.98 0.883 0.775)\",\n};\nconst orangeDarkP3A = {\n orangeA1: \"color(display-p3 0.961 0.247 0 / 0.022)\",\n orangeA2: \"color(display-p3 0.992 0.529 0 / 0.051)\",\n orangeA3: \"color(display-p3 0.996 0.486 0 / 0.131)\",\n orangeA4: \"color(display-p3 0.996 0.384 0 / 0.211)\",\n orangeA5: \"color(display-p3 1 0.455 0 / 0.265)\",\n orangeA6: \"color(display-p3 1 0.529 0.129 / 0.332)\",\n orangeA7: \"color(display-p3 1 0.569 0.251 / 0.429)\",\n orangeA8: \"color(display-p3 1 0.584 0.302 / 0.572)\",\n orangeA9: \"color(display-p3 1 0.494 0.216 / 0.895)\",\n orangeA10: \"color(display-p3 1 0.522 0.235 / 0.979)\",\n orangeA11: \"color(display-p3 1 0.63 0.38)\",\n orangeA12: \"color(display-p3 0.98 0.883 0.775)\",\n};\n\nconst gray = {\n gray1: \"#fcfcfc\",\n gray2: \"#f9f9f9\",\n gray3: \"#f0f0f0\",\n gray4: \"#e8e8e8\",\n gray5: \"#e0e0e0\",\n gray6: \"#d9d9d9\",\n gray7: \"#cecece\",\n gray8: \"#bbbbbb\",\n gray9: \"#8d8d8d\",\n gray10: \"#838383\",\n gray11: \"#646464\",\n gray12: \"#202020\",\n};\nconst grayA = {\n grayA1: \"#00000003\",\n grayA2: \"#00000006\",\n grayA3: \"#0000000f\",\n grayA4: \"#00000017\",\n grayA5: \"#0000001f\",\n grayA6: \"#00000026\",\n grayA7: \"#00000031\",\n grayA8: \"#00000044\",\n grayA9: \"#00000072\",\n grayA10: \"#0000007c\",\n grayA11: \"#0000009b\",\n grayA12: \"#000000df\",\n};\nconst grayP3 = {\n gray1: \"color(display-p3 0.988 0.988 0.988)\",\n gray2: \"color(display-p3 0.975 0.975 0.975)\",\n gray3: \"color(display-p3 0.939 0.939 0.939)\",\n gray4: \"color(display-p3 0.908 0.908 0.908)\",\n gray5: \"color(display-p3 0.88 0.88 0.88)\",\n gray6: \"color(display-p3 0.849 0.849 0.849)\",\n gray7: \"color(display-p3 0.807 0.807 0.807)\",\n gray8: \"color(display-p3 0.732 0.732 0.732)\",\n gray9: \"color(display-p3 0.553 0.553 0.553)\",\n gray10: \"color(display-p3 0.512 0.512 0.512)\",\n gray11: \"color(display-p3 0.392 0.392 0.392)\",\n gray12: \"color(display-p3 0.125 0.125 0.125)\",\n};\nconst grayP3A = {\n grayA1: \"color(display-p3 0 0 0 / 0.012)\",\n grayA2: \"color(display-p3 0 0 0 / 0.024)\",\n grayA3: \"color(display-p3 0 0 0 / 0.063)\",\n grayA4: \"color(display-p3 0 0 0 / 0.09)\",\n grayA5: \"color(display-p3 0 0 0 / 0.122)\",\n grayA6: \"color(display-p3 0 0 0 / 0.153)\",\n grayA7: \"color(display-p3 0 0 0 / 0.192)\",\n grayA8: \"color(display-p3 0 0 0 / 0.267)\",\n grayA9: \"color(display-p3 0 0 0 / 0.447)\",\n grayA10: \"color(display-p3 0 0 0 / 0.486)\",\n grayA11: \"color(display-p3 0 0 0 / 0.608)\",\n grayA12: \"color(display-p3 0 0 0 / 0.875)\",\n};\nconst mauve = {\n mauve1: \"#fdfcfd\",\n mauve2: \"#faf9fb\",\n mauve3: \"#f2eff3\",\n mauve4: \"#eae7ec\",\n mauve5: \"#e3dfe6\",\n mauve6: \"#dbd8e0\",\n mauve7: \"#d0cdd7\",\n mauve8: \"#bcbac7\",\n mauve9: \"#8e8c99\",\n mauve10: \"#84828e\",\n mauve11: \"#65636d\",\n mauve12: \"#211f26\",\n};\nconst mauveA = {\n mauveA1: \"#55005503\",\n mauveA2: \"#2b005506\",\n mauveA3: \"#30004010\",\n mauveA4: \"#20003618\",\n mauveA5: \"#20003820\",\n mauveA6: \"#14003527\",\n mauveA7: \"#10003332\",\n mauveA8: \"#08003145\",\n mauveA9: \"#05001d73\",\n mauveA10: \"#0500197d\",\n mauveA11: \"#0400119c\",\n mauveA12: \"#020008e0\",\n};\nconst mauveP3 = {\n mauve1: \"color(display-p3 0.991 0.988 0.992)\",\n mauve2: \"color(display-p3 0.98 0.976 0.984)\",\n mauve3: \"color(display-p3 0.946 0.938 0.952)\",\n mauve4: \"color(display-p3 0.915 0.906 0.925)\",\n mauve5: \"color(display-p3 0.886 0.876 0.901)\",\n mauve6: \"color(display-p3 0.856 0.846 0.875)\",\n mauve7: \"color(display-p3 0.814 0.804 0.84)\",\n mauve8: \"color(display-p3 0.735 0.728 0.777)\",\n mauve9: \"color(display-p3 0.555 0.549 0.596)\",\n mauve10: \"color(display-p3 0.514 0.508 0.552)\",\n mauve11: \"color(display-p3 0.395 0.388 0.424)\",\n mauve12: \"color(display-p3 0.128 0.122 0.147)\",\n};\nconst mauveP3A = {\n mauveA1: \"color(display-p3 0.349 0.024 0.349 / 0.012)\",\n mauveA2: \"color(display-p3 0.184 0.024 0.349 / 0.024)\",\n mauveA3: \"color(display-p3 0.129 0.008 0.255 / 0.063)\",\n mauveA4: \"color(display-p3 0.094 0.012 0.216 / 0.095)\",\n mauveA5: \"color(display-p3 0.098 0.008 0.224 / 0.126)\",\n mauveA6: \"color(display-p3 0.055 0.004 0.18 / 0.153)\",\n mauveA7: \"color(display-p3 0.067 0.008 0.184 / 0.197)\",\n mauveA8: \"color(display-p3 0.02 0.004 0.176 / 0.271)\",\n mauveA9: \"color(display-p3 0.02 0.004 0.106 / 0.451)\",\n mauveA10: \"color(display-p3 0.012 0.004 0.09 / 0.491)\",\n mauveA11: \"color(display-p3 0.016 0 0.059 / 0.612)\",\n mauveA12: \"color(display-p3 0.008 0 0.027 / 0.879)\",\n};\nconst slate = {\n slate1: \"#fcfcfd\",\n slate2: \"#f9f9fb\",\n slate3: \"#f0f0f3\",\n slate4: \"#e8e8ec\",\n slate5: \"#e0e1e6\",\n slate6: \"#d9d9e0\",\n slate7: \"#cdced6\",\n slate8: \"#b9bbc6\",\n slate9: \"#8b8d98\",\n slate10: \"#80838d\",\n slate11: \"#60646c\",\n slate12: \"#1c2024\",\n};\nconst slateA = {\n slateA1: \"#00005503\",\n slateA2: \"#00005506\",\n slateA3: \"#0000330f\",\n slateA4: \"#00002d17\",\n slateA5: \"#0009321f\",\n slateA6: \"#00002f26\",\n slateA7: \"#00062e32\",\n slateA8: \"#00083046\",\n slateA9: \"#00051d74\",\n slateA10: \"#00071b7f\",\n slateA11: \"#0007149f\",\n slateA12: \"#000509e3\",\n};\nconst slateP3 = {\n slate1: \"color(display-p3 0.988 0.988 0.992)\",\n slate2: \"color(display-p3 0.976 0.976 0.984)\",\n slate3: \"color(display-p3 0.94 0.941 0.953)\",\n slate4: \"color(display-p3 0.908 0.909 0.925)\",\n slate5: \"color(display-p3 0.88 0.881 0.901)\",\n slate6: \"color(display-p3 0.85 0.852 0.876)\",\n slate7: \"color(display-p3 0.805 0.808 0.838)\",\n slate8: \"color(display-p3 0.727 0.733 0.773)\",\n slate9: \"color(display-p3 0.547 0.553 0.592)\",\n slate10: \"color(display-p3 0.503 0.512 0.549)\",\n slate11: \"color(display-p3 0.379 0.392 0.421)\",\n slate12: \"color(display-p3 0.113 0.125 0.14)\",\n};\nconst slateP3A = {\n slateA1: \"color(display-p3 0.024 0.024 0.349 / 0.012)\",\n slateA2: \"color(display-p3 0.024 0.024 0.349 / 0.024)\",\n slateA3: \"color(display-p3 0.004 0.004 0.204 / 0.059)\",\n slateA4: \"color(display-p3 0.012 0.012 0.184 / 0.091)\",\n slateA5: \"color(display-p3 0.004 0.039 0.2 / 0.122)\",\n slateA6: \"color(display-p3 0.008 0.008 0.165 / 0.15)\",\n slateA7: \"color(display-p3 0.008 0.027 0.184 / 0.197)\",\n slateA8: \"color(display-p3 0.004 0.031 0.176 / 0.275)\",\n slateA9: \"color(display-p3 0.004 0.02 0.106 / 0.455)\",\n slateA10: \"color(display-p3 0.004 0.027 0.098 / 0.499)\",\n slateA11: \"color(display-p3 0 0.02 0.063 / 0.62)\",\n slateA12: \"color(display-p3 0 0.012 0.031 / 0.887)\",\n};\nconst sage = {\n sage1: \"#fbfdfc\",\n sage2: \"#f7f9f8\",\n sage3: \"#eef1f0\",\n sage4: \"#e6e9e8\",\n sage5: \"#dfe2e0\",\n sage6: \"#d7dad9\",\n sage7: \"#cbcfcd\",\n sage8: \"#b8bcba\",\n sage9: \"#868e8b\",\n sage10: \"#7c8481\",\n sage11: \"#5f6563\",\n sage12: \"#1a211e\",\n};\nconst sageA = {\n sageA1: \"#00804004\",\n sageA2: \"#00402008\",\n sageA3: \"#002d1e11\",\n sageA4: \"#001f1519\",\n sageA5: \"#00180820\",\n sageA6: \"#00140d28\",\n sageA7: \"#00140a34\",\n sageA8: \"#000f0847\",\n sageA9: \"#00110b79\",\n sageA10: \"#00100a83\",\n sageA11: \"#000a07a0\",\n sageA12: \"#000805e5\",\n};\nconst sageP3 = {\n sage1: \"color(display-p3 0.986 0.992 0.988)\",\n sage2: \"color(display-p3 0.97 0.977 0.974)\",\n sage3: \"color(display-p3 0.935 0.944 0.94)\",\n sage4: \"color(display-p3 0.904 0.913 0.909)\",\n sage5: \"color(display-p3 0.875 0.885 0.88)\",\n sage6: \"color(display-p3 0.844 0.854 0.849)\",\n sage7: \"color(display-p3 0.8 0.811 0.806)\",\n sage8: \"color(display-p3 0.725 0.738 0.732)\",\n sage9: \"color(display-p3 0.531 0.556 0.546)\",\n sage10: \"color(display-p3 0.492 0.515 0.506)\",\n sage11: \"color(display-p3 0.377 0.395 0.389)\",\n sage12: \"color(display-p3 0.107 0.129 0.118)\",\n};\nconst sageP3A = {\n sageA1: \"color(display-p3 0.024 0.514 0.267 / 0.016)\",\n sageA2: \"color(display-p3 0.02 0.267 0.145 / 0.032)\",\n sageA3: \"color(display-p3 0.008 0.184 0.125 / 0.067)\",\n sageA4: \"color(display-p3 0.012 0.094 0.051 / 0.095)\",\n sageA5: \"color(display-p3 0.008 0.098 0.035 / 0.126)\",\n sageA6: \"color(display-p3 0.004 0.078 0.027 / 0.157)\",\n sageA7: \"color(display-p3 0 0.059 0.039 / 0.2)\",\n sageA8: \"color(display-p3 0.004 0.047 0.031 / 0.275)\",\n sageA9: \"color(display-p3 0.004 0.059 0.035 / 0.471)\",\n sageA10: \"color(display-p3 0 0.047 0.031 / 0.51)\",\n sageA11: \"color(display-p3 0 0.031 0.02 / 0.624)\",\n sageA12: \"color(display-p3 0 0.027 0.012 / 0.895)\",\n};\nconst olive = {\n olive1: \"#fcfdfc\",\n olive2: \"#f8faf8\",\n olive3: \"#eff1ef\",\n olive4: \"#e7e9e7\",\n olive5: \"#dfe2df\",\n olive6: \"#d7dad7\",\n olive7: \"#cccfcc\",\n olive8: \"#b9bcb8\",\n olive9: \"#898e87\",\n olive10: \"#7f847d\",\n olive11: \"#60655f\",\n olive12: \"#1d211c\",\n};\nconst oliveA = {\n oliveA1: \"#00550003\",\n oliveA2: \"#00490007\",\n oliveA3: \"#00200010\",\n oliveA4: \"#00160018\",\n oliveA5: \"#00180020\",\n oliveA6: \"#00140028\",\n oliveA7: \"#000f0033\",\n oliveA8: \"#040f0047\",\n oliveA9: \"#050f0078\",\n oliveA10: \"#040e0082\",\n oliveA11: \"#020a00a0\",\n oliveA12: \"#010600e3\",\n};\nconst oliveP3 = {\n olive1: \"color(display-p3 0.989 0.992 0.989)\",\n olive2: \"color(display-p3 0.974 0.98 0.973)\",\n olive3: \"color(display-p3 0.939 0.945 0.937)\",\n olive4: \"color(display-p3 0.907 0.914 0.905)\",\n olive5: \"color(display-p3 0.878 0.885 0.875)\",\n olive6: \"color(display-p3 0.846 0.855 0.843)\",\n olive7: \"color(display-p3 0.803 0.812 0.8)\",\n olive8: \"color(display-p3 0.727 0.738 0.723)\",\n olive9: \"color(display-p3 0.541 0.556 0.532)\",\n olive10: \"color(display-p3 0.5 0.515 0.491)\",\n olive11: \"color(display-p3 0.38 0.395 0.374)\",\n olive12: \"color(display-p3 0.117 0.129 0.111)\",\n};\nconst oliveP3A = {\n oliveA1: \"color(display-p3 0.024 0.349 0.024 / 0.012)\",\n oliveA2: \"color(display-p3 0.024 0.302 0.024 / 0.028)\",\n oliveA3: \"color(display-p3 0.008 0.129 0.008 / 0.063)\",\n oliveA4: \"color(display-p3 0.012 0.094 0.012 / 0.095)\",\n oliveA5: \"color(display-p3 0.035 0.098 0.008 / 0.126)\",\n oliveA6: \"color(display-p3 0.027 0.078 0.004 / 0.157)\",\n oliveA7: \"color(display-p3 0.02 0.059 0 / 0.2)\",\n oliveA8: \"color(display-p3 0.02 0.059 0.004 / 0.279)\",\n oliveA9: \"color(display-p3 0.02 0.051 0.004 / 0.467)\",\n oliveA10: \"color(display-p3 0.024 0.047 0 / 0.51)\",\n oliveA11: \"color(display-p3 0.012 0.039 0 / 0.628)\",\n oliveA12: \"color(display-p3 0.008 0.024 0 / 0.891)\",\n};\nconst sand = {\n sand1: \"#fdfdfc\",\n sand2: \"#f9f9f8\",\n sand3: \"#f1f0ef\",\n sand4: \"#e9e8e6\",\n sand5: \"#e2e1de\",\n sand6: \"#dad9d6\",\n sand7: \"#cfceca\",\n sand8: \"#bcbbb5\",\n sand9: \"#8d8d86\",\n sand10: \"#82827c\",\n sand11: \"#63635e\",\n sand12: \"#21201c\",\n};\nconst sandA = {\n sandA1: \"#55550003\",\n sandA2: \"#25250007\",\n sandA3: \"#20100010\",\n sandA4: \"#1f150019\",\n sandA5: \"#1f180021\",\n sandA6: \"#19130029\",\n sandA7: \"#19140035\",\n sandA8: \"#1915014a\",\n sandA9: \"#0f0f0079\",\n sandA10: \"#0c0c0083\",\n sandA11: \"#080800a1\",\n sandA12: \"#060500e3\",\n};\nconst sandP3 = {\n sand1: \"color(display-p3 0.992 0.992 0.989)\",\n sand2: \"color(display-p3 0.977 0.977 0.973)\",\n sand3: \"color(display-p3 0.943 0.942 0.936)\",\n sand4: \"color(display-p3 0.913 0.912 0.903)\",\n sand5: \"color(display-p3 0.885 0.883 0.873)\",\n sand6: \"color(display-p3 0.854 0.852 0.839)\",\n sand7: \"color(display-p3 0.813 0.81 0.794)\",\n sand8: \"color(display-p3 0.738 0.734 0.713)\",\n sand9: \"color(display-p3 0.553 0.553 0.528)\",\n sand10: \"color(display-p3 0.511 0.511 0.488)\",\n sand11: \"color(display-p3 0.388 0.388 0.37)\",\n sand12: \"color(display-p3 0.129 0.126 0.111)\",\n};\nconst sandP3A = {\n sandA1: \"color(display-p3 0.349 0.349 0.024 / 0.012)\",\n sandA2: \"color(display-p3 0.161 0.161 0.024 / 0.028)\",\n sandA3: \"color(display-p3 0.067 0.067 0.008 / 0.063)\",\n sandA4: \"color(display-p3 0.129 0.129 0.012 / 0.099)\",\n sandA5: \"color(display-p3 0.098 0.067 0.008 / 0.126)\",\n sandA6: \"color(display-p3 0.102 0.075 0.004 / 0.161)\",\n sandA7: \"color(display-p3 0.098 0.098 0.004 / 0.208)\",\n sandA8: \"color(display-p3 0.086 0.075 0.004 / 0.287)\",\n sandA9: \"color(display-p3 0.051 0.051 0.004 / 0.471)\",\n sandA10: \"color(display-p3 0.047 0.047 0 / 0.514)\",\n sandA11: \"color(display-p3 0.031 0.031 0 / 0.632)\",\n sandA12: \"color(display-p3 0.024 0.02 0 / 0.891)\",\n};\nconst tomato = {\n tomato1: \"#fffcfc\",\n tomato2: \"#fff8f7\",\n tomato3: \"#feebe7\",\n tomato4: \"#ffdcd3\",\n tomato5: \"#ffcdc2\",\n tomato6: \"#fdbdaf\",\n tomato7: \"#f5a898\",\n tomato8: \"#ec8e7b\",\n tomato9: \"#e54d2e\",\n tomato10: \"#dd4425\",\n tomato11: \"#d13415\",\n tomato12: \"#5c271f\",\n};\nconst tomatoA = {\n tomatoA1: \"#ff000003\",\n tomatoA2: \"#ff200008\",\n tomatoA3: \"#f52b0018\",\n tomatoA4: \"#ff35002c\",\n tomatoA5: \"#ff2e003d\",\n tomatoA6: \"#f92d0050\",\n tomatoA7: \"#e7280067\",\n tomatoA8: \"#db250084\",\n tomatoA9: \"#df2600d1\",\n tomatoA10: \"#d72400da\",\n tomatoA11: \"#cd2200ea\",\n tomatoA12: \"#460900e0\",\n};\nconst tomatoP3 = {\n tomato1: \"color(display-p3 0.998 0.989 0.988)\",\n tomato2: \"color(display-p3 0.994 0.974 0.969)\",\n tomato3: \"color(display-p3 0.985 0.924 0.909)\",\n tomato4: \"color(display-p3 0.996 0.868 0.835)\",\n tomato5: \"color(display-p3 0.98 0.812 0.77)\",\n tomato6: \"color(display-p3 0.953 0.75 0.698)\",\n tomato7: \"color(display-p3 0.917 0.673 0.611)\",\n tomato8: \"color(display-p3 0.875 0.575 0.502)\",\n tomato9: \"color(display-p3 0.831 0.345 0.231)\",\n tomato10: \"color(display-p3 0.802 0.313 0.2)\",\n tomato11: \"color(display-p3 0.755 0.259 0.152)\",\n tomato12: \"color(display-p3 0.335 0.165 0.132)\",\n};\nconst tomatoP3A = {\n tomatoA1: \"color(display-p3 0.675 0.024 0.024 / 0.012)\",\n tomatoA2: \"color(display-p3 0.757 0.145 0.02 / 0.032)\",\n tomatoA3: \"color(display-p3 0.831 0.184 0.012 / 0.091)\",\n tomatoA4: \"color(display-p3 0.976 0.192 0.004 / 0.165)\",\n tomatoA5: \"color(display-p3 0.918 0.192 0.004 / 0.232)\",\n tomatoA6: \"color(display-p3 0.847 0.173 0.004 / 0.302)\",\n tomatoA7: \"color(display-p3 0.788 0.165 0.004 / 0.389)\",\n tomatoA8: \"color(display-p3 0.749 0.153 0.004 / 0.499)\",\n tomatoA9: \"color(display-p3 0.78 0.149 0 / 0.769)\",\n tomatoA10: \"color(display-p3 0.757 0.141 0 / 0.8)\",\n tomatoA11: \"color(display-p3 0.755 0.259 0.152)\",\n tomatoA12: \"color(display-p3 0.335 0.165 0.132)\",\n};\nconst red = {\n red1: \"#fffcfc\",\n red2: \"#fff7f7\",\n red3: \"#feebec\",\n red4: \"#ffdbdc\",\n red5: \"#ffcdce\",\n red6: \"#fdbdbe\",\n red7: \"#f4a9aa\",\n red8: \"#eb8e90\",\n red9: \"#e5484d\",\n red10: \"#dc3e42\",\n red11: \"#ce2c31\",\n red12: \"#641723\",\n};\nconst redA = {\n redA1: \"#ff000003\",\n redA2: \"#ff000008\",\n redA3: \"#f3000d14\",\n redA4: \"#ff000824\",\n redA5: \"#ff000632\",\n redA6: \"#f8000442\",\n redA7: \"#df000356\",\n redA8: \"#d2000571\",\n redA9: \"#db0007b7\",\n redA10: \"#d10005c1\",\n redA11: \"#c40006d3\",\n redA12: \"#55000de8\",\n};\nconst redP3 = {\n red1: \"color(display-p3 0.998 0.989 0.988)\",\n red2: \"color(display-p3 0.995 0.971 0.971)\",\n red3: \"color(display-p3 0.985 0.925 0.925)\",\n red4: \"color(display-p3 0.999 0.866 0.866)\",\n red5: \"color(display-p3 0.984 0.812 0.811)\",\n red6: \"color(display-p3 0.955 0.751 0.749)\",\n red7: \"color(display-p3 0.915 0.675 0.672)\",\n red8: \"color(display-p3 0.872 0.575 0.572)\",\n red9: \"color(display-p3 0.83 0.329 0.324)\",\n red10: \"color(display-p3 0.798 0.294 0.285)\",\n red11: \"color(display-p3 0.744 0.234 0.222)\",\n red12: \"color(display-p3 0.36 0.115 0.143)\",\n};\nconst redP3A = {\n redA1: \"color(display-p3 0.675 0.024 0.024 / 0.012)\",\n redA2: \"color(display-p3 0.863 0.024 0.024 / 0.028)\",\n redA3: \"color(display-p3 0.792 0.008 0.008 / 0.075)\",\n redA4: \"color(display-p3 1 0.008 0.008 / 0.134)\",\n redA5: \"color(display-p3 0.918 0.008 0.008 / 0.189)\",\n redA6: \"color(display-p3 0.831 0.02 0.004 / 0.251)\",\n redA7: \"color(display-p3 0.741 0.016 0.004 / 0.33)\",\n redA8: \"color(display-p3 0.698 0.012 0.004 / 0.428)\",\n redA9: \"color(display-p3 0.749 0.008 0 / 0.675)\",\n redA10: \"color(display-p3 0.714 0.012 0 / 0.714)\",\n redA11: \"color(display-p3 0.744 0.234 0.222)\",\n redA12: \"color(display-p3 0.36 0.115 0.143)\",\n};\nconst ruby = {\n ruby1: \"#fffcfd\",\n ruby2: \"#fff7f8\",\n ruby3: \"#feeaed\",\n ruby4: \"#ffdce1\",\n ruby5: \"#ffced6\",\n ruby6: \"#f8bfc8\",\n ruby7: \"#efacb8\",\n ruby8: \"#e592a3\",\n ruby9: \"#e54666\",\n ruby10: \"#dc3b5d\",\n ruby11: \"#ca244d\",\n ruby12: \"#64172b\",\n};\nconst rubyA = {\n rubyA1: \"#ff005503\",\n rubyA2: \"#ff002008\",\n rubyA3: \"#f3002515\",\n rubyA4: \"#ff002523\",\n rubyA5: \"#ff002a31\",\n rubyA6: \"#e4002440\",\n rubyA7: \"#ce002553\",\n rubyA8: \"#c300286d\",\n rubyA9: \"#db002cb9\",\n rubyA10: \"#d2002cc4\",\n rubyA11: \"#c10030db\",\n rubyA12: \"#550016e8\",\n};\nconst rubyP3 = {\n ruby1: \"color(display-p3 0.998 0.989 0.992)\",\n ruby2: \"color(display-p3 0.995 0.971 0.974)\",\n ruby3: \"color(display-p3 0.983 0.92 0.928)\",\n ruby4: \"color(display-p3 0.987 0.869 0.885)\",\n ruby5: \"color(display-p3 0.968 0.817 0.839)\",\n ruby6: \"color(display-p3 0.937 0.758 0.786)\",\n ruby7: \"color(display-p3 0.897 0.685 0.721)\",\n ruby8: \"color(display-p3 0.851 0.588 0.639)\",\n ruby9: \"color(display-p3 0.83 0.323 0.408)\",\n ruby10: \"color(display-p3 0.795 0.286 0.375)\",\n ruby11: \"color(display-p3 0.728 0.211 0.311)\",\n ruby12: \"color(display-p3 0.36 0.115 0.171)\",\n};\nconst rubyP3A = {\n rubyA1: \"color(display-p3 0.675 0.024 0.349 / 0.012)\",\n rubyA2: \"color(display-p3 0.863 0.024 0.024 / 0.028)\",\n rubyA3: \"color(display-p3 0.804 0.008 0.11 / 0.079)\",\n rubyA4: \"color(display-p3 0.91 0.008 0.125 / 0.13)\",\n rubyA5: \"color(display-p3 0.831 0.004 0.133 / 0.185)\",\n rubyA6: \"color(display-p3 0.745 0.004 0.118 / 0.244)\",\n rubyA7: \"color(display-p3 0.678 0.004 0.114 / 0.314)\",\n rubyA8: \"color(display-p3 0.639 0.004 0.125 / 0.412)\",\n rubyA9: \"color(display-p3 0.753 0 0.129 / 0.679)\",\n rubyA10: \"color(display-p3 0.714 0 0.125 / 0.714)\",\n rubyA11: \"color(display-p3 0.728 0.211 0.311)\",\n rubyA12: \"color(display-p3 0.36 0.115 0.171)\",\n};\nconst crimson = {\n crimson1: \"#fffcfd\",\n crimson2: \"#fef7f9\",\n crimson3: \"#ffe9f0\",\n crimson4: \"#fedce7\",\n crimson5: \"#facedd\",\n crimson6: \"#f3bed1\",\n crimson7: \"#eaacc3\",\n crimson8: \"#e093b2\",\n crimson9: \"#e93d82\",\n crimson10: \"#df3478\",\n crimson11: \"#cb1d63\",\n crimson12: \"#621639\",\n};\nconst crimsonA = {\n crimsonA1: \"#ff005503\",\n crimsonA2: \"#e0004008\",\n crimsonA3: \"#ff005216\",\n crimsonA4: \"#f8005123\",\n crimsonA5: \"#e5004f31\",\n crimsonA6: \"#d0004b41\",\n crimsonA7: \"#bf004753\",\n crimsonA8: \"#b6004a6c\",\n crimsonA9: \"#e2005bc2\",\n crimsonA10: \"#d70056cb\",\n crimsonA11: \"#c4004fe2\",\n crimsonA12: \"#530026e9\",\n};\nconst crimsonP3 = {\n crimson1: \"color(display-p3 0.998 0.989 0.992)\",\n crimson2: \"color(display-p3 0.991 0.969 0.976)\",\n crimson3: \"color(display-p3 0.987 0.917 0.941)\",\n crimson4: \"color(display-p3 0.975 0.866 0.904)\",\n crimson5: \"color(display-p3 0.953 0.813 0.864)\",\n crimson6: \"color(display-p3 0.921 0.755 0.817)\",\n crimson7: \"color(display-p3 0.88 0.683 0.761)\",\n crimson8: \"color(display-p3 0.834 0.592 0.694)\",\n crimson9: \"color(display-p3 0.843 0.298 0.507)\",\n crimson10: \"color(display-p3 0.807 0.266 0.468)\",\n crimson11: \"color(display-p3 0.731 0.195 0.388)\",\n crimson12: \"color(display-p3 0.352 0.111 0.221)\",\n};\nconst crimsonP3A = {\n crimsonA1: \"color(display-p3 0.675 0.024 0.349 / 0.012)\",\n crimsonA2: \"color(display-p3 0.757 0.02 0.267 / 0.032)\",\n crimsonA3: \"color(display-p3 0.859 0.008 0.294 / 0.083)\",\n crimsonA4: \"color(display-p3 0.827 0.008 0.298 / 0.134)\",\n crimsonA5: \"color(display-p3 0.753 0.008 0.275 / 0.189)\",\n crimsonA6: \"color(display-p3 0.682 0.004 0.247 / 0.244)\",\n crimsonA7: \"color(display-p3 0.62 0.004 0.251 / 0.318)\",\n crimsonA8: \"color(display-p3 0.6 0.004 0.251 / 0.408)\",\n crimsonA9: \"color(display-p3 0.776 0 0.298 / 0.702)\",\n crimsonA10: \"color(display-p3 0.737 0 0.275 / 0.734)\",\n crimsonA11: \"color(display-p3 0.731 0.195 0.388)\",\n crimsonA12: \"color(display-p3 0.352 0.111 0.221)\",\n};\nconst pink = {\n pink1: \"#fffcfe\",\n pink2: \"#fef7fb\",\n pink3: \"#fee9f5\",\n pink4: \"#fbdcef\",\n pink5: \"#f6cee7\",\n pink6: \"#efbfdd\",\n pink7: \"#e7acd0\",\n pink8: \"#dd93c2\",\n pink9: \"#d6409f\",\n pink10: \"#cf3897\",\n pink11: \"#c2298a\",\n pink12: \"#651249\",\n};\nconst pinkA = {\n pinkA1: \"#ff00aa03\",\n pinkA2: \"#e0008008\",\n pinkA3: \"#f4008c16\",\n pinkA4: \"#e2008b23\",\n pinkA5: \"#d1008331\",\n pinkA6: \"#c0007840\",\n pinkA7: \"#b6006f53\",\n pinkA8: \"#af006f6c\",\n pinkA9: \"#c8007fbf\",\n pinkA10: \"#c2007ac7\",\n pinkA11: \"#b60074d6\",\n pinkA12: \"#59003bed\",\n};\nconst pinkP3 = {\n pink1: \"color(display-p3 0.998 0.989 0.996)\",\n pink2: \"color(display-p3 0.992 0.97 0.985)\",\n pink3: \"color(display-p3 0.981 0.917 0.96)\",\n pink4: \"color(display-p3 0.963 0.867 0.932)\",\n pink5: \"color(display-p3 0.939 0.815 0.899)\",\n pink6: \"color(display-p3 0.907 0.756 0.859)\",\n pink7: \"color(display-p3 0.869 0.683 0.81)\",\n pink8: \"color(display-p3 0.825 0.59 0.751)\",\n pink9: \"color(display-p3 0.775 0.297 0.61)\",\n pink10: \"color(display-p3 0.748 0.27 0.581)\",\n pink11: \"color(display-p3 0.698 0.219 0.528)\",\n pink12: \"color(display-p3 0.363 0.101 0.279)\",\n};\nconst pinkP3A = {\n pinkA1: \"color(display-p3 0.675 0.024 0.675 / 0.012)\",\n pinkA2: \"color(display-p3 0.757 0.02 0.51 / 0.032)\",\n pinkA3: \"color(display-p3 0.765 0.008 0.529 / 0.083)\",\n pinkA4: \"color(display-p3 0.737 0.008 0.506 / 0.134)\",\n pinkA5: \"color(display-p3 0.663 0.004 0.451 / 0.185)\",\n pinkA6: \"color(display-p3 0.616 0.004 0.424 / 0.244)\",\n pinkA7: \"color(display-p3 0.596 0.004 0.412 / 0.318)\",\n pinkA8: \"color(display-p3 0.573 0.004 0.404 / 0.412)\",\n pinkA9: \"color(display-p3 0.682 0 0.447 / 0.702)\",\n pinkA10: \"color(display-p3 0.655 0 0.424 / 0.73)\",\n pinkA11: \"color(display-p3 0.698 0.219 0.528)\",\n pinkA12: \"color(display-p3 0.363 0.101 0.279)\",\n};\nconst plum = {\n plum1: \"#fefcff\",\n plum2: \"#fdf7fd\",\n plum3: \"#fbebfb\",\n plum4: \"#f7def8\",\n plum5: \"#f2d1f3\",\n plum6: \"#e9c2ec\",\n plum7: \"#deade3\",\n plum8: \"#cf91d8\",\n plum9: \"#ab4aba\",\n plum10: \"#a144af\",\n plum11: \"#953ea3\",\n plum12: \"#53195d\",\n};\nconst plumA = {\n plumA1: \"#aa00ff03\",\n plumA2: \"#c000c008\",\n plumA3: \"#cc00cc14\",\n plumA4: \"#c200c921\",\n plumA5: \"#b700bd2e\",\n plumA6: \"#a400b03d\",\n plumA7: \"#9900a852\",\n plumA8: \"#9000a56e\",\n plumA9: \"#89009eb5\",\n plumA10: \"#7f0092bb\",\n plumA11: \"#730086c1\",\n plumA12: \"#40004be6\",\n};\nconst plumP3 = {\n plum1: \"color(display-p3 0.995 0.988 0.999)\",\n plum2: \"color(display-p3 0.988 0.971 0.99)\",\n plum3: \"color(display-p3 0.973 0.923 0.98)\",\n plum4: \"color(display-p3 0.953 0.875 0.966)\",\n plum5: \"color(display-p3 0.926 0.825 0.945)\",\n plum6: \"color(display-p3 0.89 0.765 0.916)\",\n plum7: \"color(display-p3 0.84 0.686 0.877)\",\n plum8: \"color(display-p3 0.775 0.58 0.832)\",\n plum9: \"color(display-p3 0.624 0.313 0.708)\",\n plum10: \"color(display-p3 0.587 0.29 0.667)\",\n plum11: \"color(display-p3 0.543 0.263 0.619)\",\n plum12: \"color(display-p3 0.299 0.114 0.352)\",\n};\nconst plumP3A = {\n plumA1: \"color(display-p3 0.675 0.024 1 / 0.012)\",\n plumA2: \"color(display-p3 0.58 0.024 0.58 / 0.028)\",\n plumA3: \"color(display-p3 0.655 0.008 0.753 / 0.079)\",\n plumA4: \"color(display-p3 0.627 0.008 0.722 / 0.126)\",\n plumA5: \"color(display-p3 0.58 0.004 0.69 / 0.177)\",\n plumA6: \"color(display-p3 0.537 0.004 0.655 / 0.236)\",\n plumA7: \"color(display-p3 0.49 0.004 0.616 / 0.314)\",\n plumA8: \"color(display-p3 0.471 0.004 0.6 / 0.42)\",\n plumA9: \"color(display-p3 0.451 0 0.576 / 0.687)\",\n plumA10: \"color(display-p3 0.42 0 0.529 / 0.71)\",\n plumA11: \"color(display-p3 0.543 0.263 0.619)\",\n plumA12: \"color(display-p3 0.299 0.114 0.352)\",\n};\nconst purple = {\n purple1: \"#fefcfe\",\n purple2: \"#fbf7fe\",\n purple3: \"#f7edfe\",\n purple4: \"#f2e2fc\",\n purple5: \"#ead5f9\",\n purple6: \"#e0c4f4\",\n purple7: \"#d1afec\",\n purple8: \"#be93e4\",\n purple9: \"#8e4ec6\",\n purple10: \"#8347b9\",\n purple11: \"#8145b5\",\n purple12: \"#402060\",\n};\nconst purpleA = {\n purpleA1: \"#aa00aa03\",\n purpleA2: \"#8000e008\",\n purpleA3: \"#8e00f112\",\n purpleA4: \"#8d00e51d\",\n purpleA5: \"#8000db2a\",\n purpleA6: \"#7a01d03b\",\n purpleA7: \"#6d00c350\",\n purpleA8: \"#6600c06c\",\n purpleA9: \"#5c00adb1\",\n purpleA10: \"#53009eb8\",\n purpleA11: \"#52009aba\",\n purpleA12: \"#250049df\",\n};\nconst purpleP3 = {\n purple1: \"color(display-p3 0.995 0.988 0.996)\",\n purple2: \"color(display-p3 0.983 0.971 0.993)\",\n purple3: \"color(display-p3 0.963 0.931 0.989)\",\n purple4: \"color(display-p3 0.937 0.888 0.981)\",\n purple5: \"color(display-p3 0.904 0.837 0.966)\",\n purple6: \"color(display-p3 0.86 0.774 0.942)\",\n purple7: \"color(display-p3 0.799 0.69 0.91)\",\n purple8: \"color(display-p3 0.719 0.583 0.874)\",\n purple9: \"color(display-p3 0.523 0.318 0.751)\",\n purple10: \"color(display-p3 0.483 0.289 0.7)\",\n purple11: \"color(display-p3 0.473 0.281 0.687)\",\n purple12: \"color(display-p3 0.234 0.132 0.363)\",\n};\nconst purpleP3A = {\n purpleA1: \"color(display-p3 0.675 0.024 0.675 / 0.012)\",\n purpleA2: \"color(display-p3 0.443 0.024 0.722 / 0.028)\",\n purpleA3: \"color(display-p3 0.506 0.008 0.835 / 0.071)\",\n purpleA4: \"color(display-p3 0.451 0.004 0.831 / 0.114)\",\n purpleA5: \"color(display-p3 0.431 0.004 0.788 / 0.165)\",\n purpleA6: \"color(display-p3 0.384 0.004 0.745 / 0.228)\",\n purpleA7: \"color(display-p3 0.357 0.004 0.71 / 0.31)\",\n purpleA8: \"color(display-p3 0.322 0.004 0.702 / 0.416)\",\n purpleA9: \"color(display-p3 0.298 0 0.639 / 0.683)\",\n purpleA10: \"color(display-p3 0.271 0 0.58 / 0.71)\",\n purpleA11: \"color(display-p3 0.473 0.281 0.687)\",\n purpleA12: \"color(display-p3 0.234 0.132 0.363)\",\n};\nconst violet = {\n violet1: \"#fdfcfe\",\n violet2: \"#faf8ff\",\n violet3: \"#f4f0fe\",\n violet4: \"#ebe4ff\",\n violet5: \"#e1d9ff\",\n violet6: \"#d4cafe\",\n violet7: \"#c2b5f5\",\n violet8: \"#aa99ec\",\n violet9: \"#6e56cf\",\n violet10: \"#654dc4\",\n violet11: \"#6550b9\",\n violet12: \"#2f265f\",\n};\nconst violetA = {\n violetA1: \"#5500aa03\",\n violetA2: \"#4900ff07\",\n violetA3: \"#4400ee0f\",\n violetA4: \"#4300ff1b\",\n violetA5: \"#3600ff26\",\n violetA6: \"#3100fb35\",\n violetA7: \"#2d01dd4a\",\n violetA8: \"#2b00d066\",\n violetA9: \"#2400b7a9\",\n violetA10: \"#2300abb2\",\n violetA11: \"#1f0099af\",\n violetA12: \"#0b0043d9\",\n};\nconst violetP3 = {\n violet1: \"color(display-p3 0.991 0.988 0.995)\",\n violet2: \"color(display-p3 0.978 0.974 0.998)\",\n violet3: \"color(display-p3 0.953 0.943 0.993)\",\n violet4: \"color(display-p3 0.916 0.897 1)\",\n violet5: \"color(display-p3 0.876 0.851 1)\",\n violet6: \"color(display-p3 0.825 0.793 0.981)\",\n violet7: \"color(display-p3 0.752 0.712 0.943)\",\n violet8: \"color(display-p3 0.654 0.602 0.902)\",\n violet9: \"color(display-p3 0.417 0.341 0.784)\",\n violet10: \"color(display-p3 0.381 0.306 0.741)\",\n violet11: \"color(display-p3 0.383 0.317 0.702)\",\n violet12: \"color(display-p3 0.179 0.15 0.359)\",\n};\nconst violetP3A = {\n violetA1: \"color(display-p3 0.349 0.024 0.675 / 0.012)\",\n violetA2: \"color(display-p3 0.161 0.024 0.863 / 0.028)\",\n violetA3: \"color(display-p3 0.204 0.004 0.871 / 0.059)\",\n violetA4: \"color(display-p3 0.196 0.004 1 / 0.102)\",\n violetA5: \"color(display-p3 0.165 0.008 1 / 0.15)\",\n violetA6: \"color(display-p3 0.153 0.004 0.906 / 0.208)\",\n violetA7: \"color(display-p3 0.141 0.004 0.796 / 0.287)\",\n violetA8: \"color(display-p3 0.133 0.004 0.753 / 0.397)\",\n violetA9: \"color(display-p3 0.114 0 0.675 / 0.659)\",\n violetA10: \"color(display-p3 0.11 0 0.627 / 0.695)\",\n violetA11: \"color(display-p3 0.383 0.317 0.702)\",\n violetA12: \"color(display-p3 0.179 0.15 0.359)\",\n};\nconst iris = {\n iris1: \"#fdfdff\",\n iris2: \"#f8f8ff\",\n iris3: \"#f0f1fe\",\n iris4: \"#e6e7ff\",\n iris5: \"#dadcff\",\n iris6: \"#cbcdff\",\n iris7: \"#b8baf8\",\n iris8: \"#9b9ef0\",\n iris9: \"#5b5bd6\",\n iris10: \"#5151cd\",\n iris11: \"#5753c6\",\n iris12: \"#272962\",\n};\nconst irisA = {\n irisA1: \"#0000ff02\",\n irisA2: \"#0000ff07\",\n irisA3: \"#0011ee0f\",\n irisA4: \"#000bff19\",\n irisA5: \"#000eff25\",\n irisA6: \"#000aff34\",\n irisA7: \"#0008e647\",\n irisA8: \"#0008d964\",\n irisA9: \"#0000c0a4\",\n irisA10: \"#0000b6ae\",\n irisA11: \"#0600abac\",\n irisA12: \"#000246d8\",\n};\nconst irisP3 = {\n iris1: \"color(display-p3 0.992 0.992 0.999)\",\n iris2: \"color(display-p3 0.972 0.973 0.998)\",\n iris3: \"color(display-p3 0.943 0.945 0.992)\",\n iris4: \"color(display-p3 0.902 0.906 1)\",\n iris5: \"color(display-p3 0.857 0.861 1)\",\n iris6: \"color(display-p3 0.799 0.805 0.987)\",\n iris7: \"color(display-p3 0.721 0.727 0.955)\",\n iris8: \"color(display-p3 0.61 0.619 0.918)\",\n iris9: \"color(display-p3 0.357 0.357 0.81)\",\n iris10: \"color(display-p3 0.318 0.318 0.774)\",\n iris11: \"color(display-p3 0.337 0.326 0.748)\",\n iris12: \"color(display-p3 0.154 0.161 0.371)\",\n};\nconst irisP3A = {\n irisA1: \"color(display-p3 0.02 0.02 1 / 0.008)\",\n irisA2: \"color(display-p3 0.024 0.024 0.863 / 0.028)\",\n irisA3: \"color(display-p3 0.004 0.071 0.871 / 0.059)\",\n irisA4: \"color(display-p3 0.012 0.051 1 / 0.099)\",\n irisA5: \"color(display-p3 0.008 0.035 1 / 0.142)\",\n irisA6: \"color(display-p3 0 0.02 0.941 / 0.2)\",\n irisA7: \"color(display-p3 0.004 0.02 0.847 / 0.279)\",\n irisA8: \"color(display-p3 0.004 0.024 0.788 / 0.389)\",\n irisA9: \"color(display-p3 0 0 0.706 / 0.644)\",\n irisA10: \"color(display-p3 0 0 0.667 / 0.683)\",\n irisA11: \"color(display-p3 0.337 0.326 0.748)\",\n irisA12: \"color(display-p3 0.154 0.161 0.371)\",\n};\nconst indigo = {\n indigo1: \"#fdfdfe\",\n indigo2: \"#f7f9ff\",\n indigo3: \"#edf2fe\",\n indigo4: \"#e1e9ff\",\n indigo5: \"#d2deff\",\n indigo6: \"#c1d0ff\",\n indigo7: \"#abbdf9\",\n indigo8: \"#8da4ef\",\n indigo9: \"#3e63dd\",\n indigo10: \"#3358d4\",\n indigo11: \"#3a5bc7\",\n indigo12: \"#1f2d5c\",\n};\nconst indigoA = {\n indigoA1: \"#00008002\",\n indigoA2: \"#0040ff08\",\n indigoA3: \"#0047f112\",\n indigoA4: \"#0044ff1e\",\n indigoA5: \"#0044ff2d\",\n indigoA6: \"#003eff3e\",\n indigoA7: \"#0037ed54\",\n indigoA8: \"#0034dc72\",\n indigoA9: \"#0031d2c1\",\n indigoA10: \"#002ec9cc\",\n indigoA11: \"#002bb7c5\",\n indigoA12: \"#001046e0\",\n};\nconst indigoP3 = {\n indigo1: \"color(display-p3 0.992 0.992 0.996)\",\n indigo2: \"color(display-p3 0.971 0.977 0.998)\",\n indigo3: \"color(display-p3 0.933 0.948 0.992)\",\n indigo4: \"color(display-p3 0.885 0.914 1)\",\n indigo5: \"color(display-p3 0.831 0.87 1)\",\n indigo6: \"color(display-p3 0.767 0.814 0.995)\",\n indigo7: \"color(display-p3 0.685 0.74 0.957)\",\n indigo8: \"color(display-p3 0.569 0.639 0.916)\",\n indigo9: \"color(display-p3 0.276 0.384 0.837)\",\n indigo10: \"color(display-p3 0.234 0.343 0.801)\",\n indigo11: \"color(display-p3 0.256 0.354 0.755)\",\n indigo12: \"color(display-p3 0.133 0.175 0.348)\",\n};\nconst indigoP3A = {\n indigoA1: \"color(display-p3 0.02 0.02 0.51 / 0.008)\",\n indigoA2: \"color(display-p3 0.024 0.161 0.863 / 0.028)\",\n indigoA3: \"color(display-p3 0.008 0.239 0.886 / 0.067)\",\n indigoA4: \"color(display-p3 0.004 0.247 1 / 0.114)\",\n indigoA5: \"color(display-p3 0.004 0.235 1 / 0.169)\",\n indigoA6: \"color(display-p3 0.004 0.208 0.984 / 0.232)\",\n indigoA7: \"color(display-p3 0.004 0.176 0.863 / 0.314)\",\n indigoA8: \"color(display-p3 0.004 0.165 0.812 / 0.432)\",\n indigoA9: \"color(display-p3 0 0.153 0.773 / 0.726)\",\n indigoA10: \"color(display-p3 0 0.137 0.737 / 0.765)\",\n indigoA11: \"color(display-p3 0.256 0.354 0.755)\",\n indigoA12: \"color(display-p3 0.133 0.175 0.348)\",\n};\nconst blue = {\n blue1: \"#fbfdff\",\n blue2: \"#f4faff\",\n blue3: \"#e6f4fe\",\n blue4: \"#d5efff\",\n blue5: \"#c2e5ff\",\n blue6: \"#acd8fc\",\n blue7: \"#8ec8f6\",\n blue8: \"#5eb1ef\",\n blue9: \"#0090ff\",\n blue10: \"#0588f0\",\n blue11: \"#0d74ce\",\n blue12: \"#113264\",\n};\nconst blueA = {\n blueA1: \"#0080ff04\",\n blueA2: \"#008cff0b\",\n blueA3: \"#008ff519\",\n blueA4: \"#009eff2a\",\n blueA5: \"#0093ff3d\",\n blueA6: \"#0088f653\",\n blueA7: \"#0083eb71\",\n blueA8: \"#0084e6a1\",\n blueA9: \"#0090ff\",\n blueA10: \"#0086f0fa\",\n blueA11: \"#006dcbf2\",\n blueA12: \"#002359ee\",\n};\nconst blueP3 = {\n blue1: \"color(display-p3 0.986 0.992 0.999)\",\n blue2: \"color(display-p3 0.96 0.979 0.998)\",\n blue3: \"color(display-p3 0.912 0.956 0.991)\",\n blue4: \"color(display-p3 0.853 0.932 1)\",\n blue5: \"color(display-p3 0.788 0.894 0.998)\",\n blue6: \"color(display-p3 0.709 0.843 0.976)\",\n blue7: \"color(display-p3 0.606 0.777 0.947)\",\n blue8: \"color(display-p3 0.451 0.688 0.917)\",\n blue9: \"color(display-p3 0.247 0.556 0.969)\",\n blue10: \"color(display-p3 0.234 0.523 0.912)\",\n blue11: \"color(display-p3 0.15 0.44 0.84)\",\n blue12: \"color(display-p3 0.102 0.193 0.379)\",\n};\nconst blueP3A = {\n blueA1: \"color(display-p3 0.024 0.514 1 / 0.016)\",\n blueA2: \"color(display-p3 0.024 0.514 0.906 / 0.04)\",\n blueA3: \"color(display-p3 0.012 0.506 0.914 / 0.087)\",\n blueA4: \"color(display-p3 0.008 0.545 1 / 0.146)\",\n blueA5: \"color(display-p3 0.004 0.502 0.984 / 0.212)\",\n blueA6: \"color(display-p3 0.004 0.463 0.922 / 0.291)\",\n blueA7: \"color(display-p3 0.004 0.431 0.863 / 0.393)\",\n blueA8: \"color(display-p3 0 0.427 0.851 / 0.55)\",\n blueA9: \"color(display-p3 0 0.412 0.961 / 0.753)\",\n blueA10: \"color(display-p3 0 0.376 0.886 / 0.765)\",\n blueA11: \"color(display-p3 0.15 0.44 0.84)\",\n blueA12: \"color(display-p3 0.102 0.193 0.379)\",\n};\nconst cyan = {\n cyan1: \"#fafdfe\",\n cyan2: \"#f2fafb\",\n cyan3: \"#def7f9\",\n cyan4: \"#caf1f6\",\n cyan5: \"#b5e9f0\",\n cyan6: \"#9ddde7\",\n cyan7: \"#7dcedc\",\n cyan8: \"#3db9cf\",\n cyan9: \"#00a2c7\",\n cyan10: \"#0797b9\",\n cyan11: \"#107d98\",\n cyan12: \"#0d3c48\",\n};\nconst cyanA = {\n cyanA1: \"#0099cc05\",\n cyanA2: \"#009db10d\",\n cyanA3: \"#00c2d121\",\n cyanA4: \"#00bcd435\",\n cyanA5: \"#01b4cc4a\",\n cyanA6: \"#00a7c162\",\n cyanA7: \"#009fbb82\",\n cyanA8: \"#00a3c0c2\",\n cyanA9: \"#00a2c7\",\n cyanA10: \"#0094b7f8\",\n cyanA11: \"#007491ef\",\n cyanA12: \"#00323ef2\",\n};\nconst cyanP3 = {\n cyan1: \"color(display-p3 0.982 0.992 0.996)\",\n cyan2: \"color(display-p3 0.955 0.981 0.984)\",\n cyan3: \"color(display-p3 0.888 0.965 0.975)\",\n cyan4: \"color(display-p3 0.821 0.941 0.959)\",\n cyan5: \"color(display-p3 0.751 0.907 0.935)\",\n cyan6: \"color(display-p3 0.671 0.862 0.9)\",\n cyan7: \"color(display-p3 0.564 0.8 0.854)\",\n cyan8: \"color(display-p3 0.388 0.715 0.798)\",\n cyan9: \"color(display-p3 0.282 0.627 0.765)\",\n cyan10: \"color(display-p3 0.264 0.583 0.71)\",\n cyan11: \"color(display-p3 0.08 0.48 0.63)\",\n cyan12: \"color(display-p3 0.108 0.232 0.277)\",\n};\nconst cyanP3A = {\n cyanA1: \"color(display-p3 0.02 0.608 0.804 / 0.02)\",\n cyanA2: \"color(display-p3 0.02 0.557 0.647 / 0.044)\",\n cyanA3: \"color(display-p3 0.004 0.694 0.796 / 0.114)\",\n cyanA4: \"color(display-p3 0.004 0.678 0.784 / 0.181)\",\n cyanA5: \"color(display-p3 0.004 0.624 0.733 / 0.248)\",\n cyanA6: \"color(display-p3 0.004 0.584 0.706 / 0.33)\",\n cyanA7: \"color(display-p3 0.004 0.541 0.667 / 0.436)\",\n cyanA8: \"color(display-p3 0 0.533 0.667 / 0.612)\",\n cyanA9: \"color(display-p3 0 0.482 0.675 / 0.718)\",\n cyanA10: \"color(display-p3 0 0.435 0.608 / 0.738)\",\n cyanA11: \"color(display-p3 0.08 0.48 0.63)\",\n cyanA12: \"color(display-p3 0.108 0.232 0.277)\",\n};\nconst teal = {\n teal1: \"#fafefd\",\n teal2: \"#f3fbf9\",\n teal3: \"#e0f8f3\",\n teal4: \"#ccf3ea\",\n teal5: \"#b8eae0\",\n teal6: \"#a1ded2\",\n teal7: \"#83cdc1\",\n teal8: \"#53b9ab\",\n teal9: \"#12a594\",\n teal10: \"#0d9b8a\",\n teal11: \"#008573\",\n teal12: \"#0d3d38\",\n};\nconst tealA = {\n tealA1: \"#00cc9905\",\n tealA2: \"#00aa800c\",\n tealA3: \"#00c69d1f\",\n tealA4: \"#00c39633\",\n tealA5: \"#00b49047\",\n tealA6: \"#00a6855e\",\n tealA7: \"#0099807c\",\n tealA8: \"#009783ac\",\n tealA9: \"#009e8ced\",\n tealA10: \"#009684f2\",\n tealA11: \"#008573\",\n tealA12: \"#00332df2\",\n};\nconst tealP3 = {\n teal1: \"color(display-p3 0.983 0.996 0.992)\",\n teal2: \"color(display-p3 0.958 0.983 0.976)\",\n teal3: \"color(display-p3 0.895 0.971 0.952)\",\n teal4: \"color(display-p3 0.831 0.949 0.92)\",\n teal5: \"color(display-p3 0.761 0.914 0.878)\",\n teal6: \"color(display-p3 0.682 0.864 0.825)\",\n teal7: \"color(display-p3 0.581 0.798 0.756)\",\n teal8: \"color(display-p3 0.433 0.716 0.671)\",\n teal9: \"color(display-p3 0.297 0.637 0.581)\",\n teal10: \"color(display-p3 0.275 0.599 0.542)\",\n teal11: \"color(display-p3 0.08 0.5 0.43)\",\n teal12: \"color(display-p3 0.11 0.235 0.219)\",\n};\nconst tealP3A = {\n tealA1: \"color(display-p3 0.024 0.757 0.514 / 0.016)\",\n tealA2: \"color(display-p3 0.02 0.647 0.467 / 0.044)\",\n tealA3: \"color(display-p3 0.004 0.741 0.557 / 0.106)\",\n tealA4: \"color(display-p3 0.004 0.702 0.537 / 0.169)\",\n tealA5: \"color(display-p3 0.004 0.643 0.494 / 0.24)\",\n tealA6: \"color(display-p3 0.004 0.569 0.447 / 0.318)\",\n tealA7: \"color(display-p3 0.004 0.518 0.424 / 0.42)\",\n tealA8: \"color(display-p3 0 0.506 0.424 / 0.569)\",\n tealA9: \"color(display-p3 0 0.482 0.404 / 0.702)\",\n tealA10: \"color(display-p3 0 0.451 0.369 / 0.726)\",\n tealA11: \"color(display-p3 0.08 0.5 0.43)\",\n tealA12: \"color(display-p3 0.11 0.235 0.219)\",\n};\nconst jade = {\n jade1: \"#fbfefd\",\n jade2: \"#f4fbf7\",\n jade3: \"#e6f7ed\",\n jade4: \"#d6f1e3\",\n jade5: \"#c3e9d7\",\n jade6: \"#acdec8\",\n jade7: \"#8bceb6\",\n jade8: \"#56ba9f\",\n jade9: \"#29a383\",\n jade10: \"#26997b\",\n jade11: \"#208368\",\n jade12: \"#1d3b31\",\n};\nconst jadeA = {\n jadeA1: \"#00c08004\",\n jadeA2: \"#00a3460b\",\n jadeA3: \"#00ae4819\",\n jadeA4: \"#00a85129\",\n jadeA5: \"#00a2553c\",\n jadeA6: \"#009a5753\",\n jadeA7: \"#00945f74\",\n jadeA8: \"#00976ea9\",\n jadeA9: \"#00916bd6\",\n jadeA10: \"#008764d9\",\n jadeA11: \"#007152df\",\n jadeA12: \"#002217e2\",\n};\nconst jadeP3 = {\n jade1: \"color(display-p3 0.986 0.996 0.992)\",\n jade2: \"color(display-p3 0.962 0.983 0.969)\",\n jade3: \"color(display-p3 0.912 0.965 0.932)\",\n jade4: \"color(display-p3 0.858 0.941 0.893)\",\n jade5: \"color(display-p3 0.795 0.909 0.847)\",\n jade6: \"color(display-p3 0.715 0.864 0.791)\",\n jade7: \"color(display-p3 0.603 0.802 0.718)\",\n jade8: \"color(display-p3 0.44 0.72 0.629)\",\n jade9: \"color(display-p3 0.319 0.63 0.521)\",\n jade10: \"color(display-p3 0.299 0.592 0.488)\",\n jade11: \"color(display-p3 0.15 0.5 0.37)\",\n jade12: \"color(display-p3 0.142 0.229 0.194)\",\n};\nconst jadeP3A = {\n jadeA1: \"color(display-p3 0.024 0.757 0.514 / 0.016)\",\n jadeA2: \"color(display-p3 0.024 0.612 0.22 / 0.04)\",\n jadeA3: \"color(display-p3 0.012 0.596 0.235 / 0.087)\",\n jadeA4: \"color(display-p3 0.008 0.588 0.255 / 0.142)\",\n jadeA5: \"color(display-p3 0.004 0.561 0.251 / 0.204)\",\n jadeA6: \"color(display-p3 0.004 0.525 0.278 / 0.287)\",\n jadeA7: \"color(display-p3 0.004 0.506 0.29 / 0.397)\",\n jadeA8: \"color(display-p3 0 0.506 0.337 / 0.561)\",\n jadeA9: \"color(display-p3 0 0.459 0.298 / 0.683)\",\n jadeA10: \"color(display-p3 0 0.42 0.271 / 0.702)\",\n jadeA11: \"color(display-p3 0.15 0.5 0.37)\",\n jadeA12: \"color(display-p3 0.142 0.229 0.194)\",\n};\nconst green = {\n green1: \"#fbfefc\",\n green2: \"#f4fbf6\",\n green3: \"#e6f6eb\",\n green4: \"#d6f1df\",\n green5: \"#c4e8d1\",\n green6: \"#adddc0\",\n green7: \"#8eceaa\",\n green8: \"#5bb98b\",\n green9: \"#30a46c\",\n green10: \"#2b9a66\",\n green11: \"#218358\",\n green12: \"#193b2d\",\n};\nconst greenA = {\n greenA1: \"#00c04004\",\n greenA2: \"#00a32f0b\",\n greenA3: \"#00a43319\",\n greenA4: \"#00a83829\",\n greenA5: \"#019c393b\",\n greenA6: \"#00963c52\",\n greenA7: \"#00914071\",\n greenA8: \"#00924ba4\",\n greenA9: \"#008f4acf\",\n greenA10: \"#008647d4\",\n greenA11: \"#00713fde\",\n greenA12: \"#002616e6\",\n};\nconst greenP3 = {\n green1: \"color(display-p3 0.986 0.996 0.989)\",\n green2: \"color(display-p3 0.963 0.983 0.967)\",\n green3: \"color(display-p3 0.913 0.964 0.925)\",\n green4: \"color(display-p3 0.859 0.94 0.879)\",\n green5: \"color(display-p3 0.796 0.907 0.826)\",\n green6: \"color(display-p3 0.718 0.863 0.761)\",\n green7: \"color(display-p3 0.61 0.801 0.675)\",\n green8: \"color(display-p3 0.451 0.715 0.559)\",\n green9: \"color(display-p3 0.332 0.634 0.442)\",\n green10: \"color(display-p3 0.308 0.595 0.417)\",\n green11: \"color(display-p3 0.19 0.5 0.32)\",\n green12: \"color(display-p3 0.132 0.228 0.18)\",\n};\nconst greenP3A = {\n greenA1: \"color(display-p3 0.024 0.757 0.267 / 0.016)\",\n greenA2: \"color(display-p3 0.024 0.565 0.129 / 0.036)\",\n greenA3: \"color(display-p3 0.012 0.596 0.145 / 0.087)\",\n greenA4: \"color(display-p3 0.008 0.588 0.145 / 0.142)\",\n greenA5: \"color(display-p3 0.004 0.541 0.157 / 0.204)\",\n greenA6: \"color(display-p3 0.004 0.518 0.157 / 0.283)\",\n greenA7: \"color(display-p3 0.004 0.486 0.165 / 0.389)\",\n greenA8: \"color(display-p3 0 0.478 0.2 / 0.55)\",\n greenA9: \"color(display-p3 0 0.455 0.165 / 0.667)\",\n greenA10: \"color(display-p3 0 0.416 0.153 / 0.691)\",\n greenA11: \"color(display-p3 0.19 0.5 0.32)\",\n greenA12: \"color(display-p3 0.132 0.228 0.18)\",\n};\nconst grass = {\n grass1: \"#fbfefb\",\n grass2: \"#f5fbf5\",\n grass3: \"#e9f6e9\",\n grass4: \"#daf1db\",\n grass5: \"#c9e8ca\",\n grass6: \"#b2ddb5\",\n grass7: \"#94ce9a\",\n grass8: \"#65ba74\",\n grass9: \"#46a758\",\n grass10: \"#3e9b4f\",\n grass11: \"#2a7e3b\",\n grass12: \"#203c25\",\n};\nconst grassA = {\n grassA1: \"#00c00004\",\n grassA2: \"#0099000a\",\n grassA3: \"#00970016\",\n grassA4: \"#009f0725\",\n grassA5: \"#00930536\",\n grassA6: \"#008f0a4d\",\n grassA7: \"#018b0f6b\",\n grassA8: \"#008d199a\",\n grassA9: \"#008619b9\",\n grassA10: \"#007b17c1\",\n grassA11: \"#006514d5\",\n grassA12: \"#002006df\",\n};\nconst grassP3 = {\n grass1: \"color(display-p3 0.986 0.996 0.985)\",\n grass2: \"color(display-p3 0.966 0.983 0.964)\",\n grass3: \"color(display-p3 0.923 0.965 0.917)\",\n grass4: \"color(display-p3 0.872 0.94 0.865)\",\n grass5: \"color(display-p3 0.811 0.908 0.802)\",\n grass6: \"color(display-p3 0.733 0.864 0.724)\",\n grass7: \"color(display-p3 0.628 0.803 0.622)\",\n grass8: \"color(display-p3 0.477 0.72 0.482)\",\n grass9: \"color(display-p3 0.38 0.647 0.378)\",\n grass10: \"color(display-p3 0.344 0.598 0.342)\",\n grass11: \"color(display-p3 0.263 0.488 0.261)\",\n grass12: \"color(display-p3 0.151 0.233 0.153)\",\n};\nconst grassP3A = {\n grassA1: \"color(display-p3 0.024 0.757 0.024 / 0.016)\",\n grassA2: \"color(display-p3 0.024 0.565 0.024 / 0.036)\",\n grassA3: \"color(display-p3 0.059 0.576 0.008 / 0.083)\",\n grassA4: \"color(display-p3 0.035 0.565 0.008 / 0.134)\",\n grassA5: \"color(display-p3 0.047 0.545 0.008 / 0.197)\",\n grassA6: \"color(display-p3 0.031 0.502 0.004 / 0.275)\",\n grassA7: \"color(display-p3 0.012 0.482 0.004 / 0.377)\",\n grassA8: \"color(display-p3 0 0.467 0.008 / 0.522)\",\n grassA9: \"color(display-p3 0.008 0.435 0 / 0.624)\",\n grassA10: \"color(display-p3 0.008 0.388 0 / 0.659)\",\n grassA11: \"color(display-p3 0.263 0.488 0.261)\",\n grassA12: \"color(display-p3 0.151 0.233 0.153)\",\n};\nconst brown = {\n brown1: \"#fefdfc\",\n brown2: \"#fcf9f6\",\n brown3: \"#f6eee7\",\n brown4: \"#f0e4d9\",\n brown5: \"#ebdaca\",\n brown6: \"#e4cdb7\",\n brown7: \"#dcbc9f\",\n brown8: \"#cea37e\",\n brown9: \"#ad7f58\",\n brown10: \"#a07553\",\n brown11: \"#815e46\",\n brown12: \"#3e332e\",\n};\nconst brownA = {\n brownA1: \"#aa550003\",\n brownA2: \"#aa550009\",\n brownA3: \"#a04b0018\",\n brownA4: \"#9b4a0026\",\n brownA5: \"#9f4d0035\",\n brownA6: \"#a04e0048\",\n brownA7: \"#a34e0060\",\n brownA8: \"#9f4a0081\",\n brownA9: \"#823c00a7\",\n brownA10: \"#723300ac\",\n brownA11: \"#522100b9\",\n brownA12: \"#140600d1\",\n};\nconst brownP3 = {\n brown1: \"color(display-p3 0.995 0.992 0.989)\",\n brown2: \"color(display-p3 0.987 0.976 0.964)\",\n brown3: \"color(display-p3 0.959 0.936 0.909)\",\n brown4: \"color(display-p3 0.934 0.897 0.855)\",\n brown5: \"color(display-p3 0.909 0.856 0.798)\",\n brown6: \"color(display-p3 0.88 0.808 0.73)\",\n brown7: \"color(display-p3 0.841 0.742 0.639)\",\n brown8: \"color(display-p3 0.782 0.647 0.514)\",\n brown9: \"color(display-p3 0.651 0.505 0.368)\",\n brown10: \"color(display-p3 0.601 0.465 0.344)\",\n brown11: \"color(display-p3 0.485 0.374 0.288)\",\n brown12: \"color(display-p3 0.236 0.202 0.183)\",\n};\nconst brownP3A = {\n brownA1: \"color(display-p3 0.675 0.349 0.024 / 0.012)\",\n brownA2: \"color(display-p3 0.675 0.349 0.024 / 0.036)\",\n brownA3: \"color(display-p3 0.573 0.314 0.012 / 0.091)\",\n brownA4: \"color(display-p3 0.545 0.302 0.008 / 0.146)\",\n brownA5: \"color(display-p3 0.561 0.29 0.004 / 0.204)\",\n brownA6: \"color(display-p3 0.553 0.294 0.004 / 0.271)\",\n brownA7: \"color(display-p3 0.557 0.286 0.004 / 0.361)\",\n brownA8: \"color(display-p3 0.549 0.275 0.004 / 0.487)\",\n brownA9: \"color(display-p3 0.447 0.22 0 / 0.632)\",\n brownA10: \"color(display-p3 0.388 0.188 0 / 0.655)\",\n brownA11: \"color(display-p3 0.485 0.374 0.288)\",\n brownA12: \"color(display-p3 0.236 0.202 0.183)\",\n};\nconst bronze = {\n bronze1: \"#fdfcfc\",\n bronze2: \"#fdf7f5\",\n bronze3: \"#f6edea\",\n bronze4: \"#efe4df\",\n bronze5: \"#e7d9d3\",\n bronze6: \"#dfcdc5\",\n bronze7: \"#d3bcb3\",\n bronze8: \"#c2a499\",\n bronze9: \"#a18072\",\n bronze10: \"#957468\",\n bronze11: \"#7d5e54\",\n bronze12: \"#43302b\",\n};\nconst bronzeA = {\n bronzeA1: \"#55000003\",\n bronzeA2: \"#cc33000a\",\n bronzeA3: \"#92250015\",\n bronzeA4: \"#80280020\",\n bronzeA5: \"#7423002c\",\n bronzeA6: \"#7324003a\",\n bronzeA7: \"#6c1f004c\",\n bronzeA8: \"#671c0066\",\n bronzeA9: \"#551a008d\",\n bronzeA10: \"#4c150097\",\n bronzeA11: \"#3d0f00ab\",\n bronzeA12: \"#1d0600d4\",\n};\nconst bronzeP3 = {\n bronze1: \"color(display-p3 0.991 0.988 0.988)\",\n bronze2: \"color(display-p3 0.989 0.97 0.961)\",\n bronze3: \"color(display-p3 0.958 0.932 0.919)\",\n bronze4: \"color(display-p3 0.929 0.894 0.877)\",\n bronze5: \"color(display-p3 0.898 0.853 0.832)\",\n bronze6: \"color(display-p3 0.861 0.805 0.778)\",\n bronze7: \"color(display-p3 0.812 0.739 0.706)\",\n bronze8: \"color(display-p3 0.741 0.647 0.606)\",\n bronze9: \"color(display-p3 0.611 0.507 0.455)\",\n bronze10: \"color(display-p3 0.563 0.461 0.414)\",\n bronze11: \"color(display-p3 0.471 0.373 0.336)\",\n bronze12: \"color(display-p3 0.251 0.191 0.172)\",\n};\nconst bronzeP3A = {\n bronzeA1: \"color(display-p3 0.349 0.024 0.024 / 0.012)\",\n bronzeA2: \"color(display-p3 0.71 0.22 0.024 / 0.04)\",\n bronzeA3: \"color(display-p3 0.482 0.2 0.008 / 0.083)\",\n bronzeA4: \"color(display-p3 0.424 0.133 0.004 / 0.122)\",\n bronzeA5: \"color(display-p3 0.4 0.145 0.004 / 0.169)\",\n bronzeA6: \"color(display-p3 0.388 0.125 0.004 / 0.224)\",\n bronzeA7: \"color(display-p3 0.365 0.11 0.004 / 0.295)\",\n bronzeA8: \"color(display-p3 0.341 0.102 0.004 / 0.393)\",\n bronzeA9: \"color(display-p3 0.29 0.094 0 / 0.546)\",\n bronzeA10: \"color(display-p3 0.255 0.082 0 / 0.585)\",\n bronzeA11: \"color(display-p3 0.471 0.373 0.336)\",\n bronzeA12: \"color(display-p3 0.251 0.191 0.172)\",\n};\nconst gold = {\n gold1: \"#fdfdfc\",\n gold2: \"#faf9f2\",\n gold3: \"#f2f0e7\",\n gold4: \"#eae6db\",\n gold5: \"#e1dccf\",\n gold6: \"#d8d0bf\",\n gold7: \"#cbc0aa\",\n gold8: \"#b9a88d\",\n gold9: \"#978365\",\n gold10: \"#8c7a5e\",\n gold11: \"#71624b\",\n gold12: \"#3b352b\",\n};\nconst goldA = {\n goldA1: \"#55550003\",\n goldA2: \"#9d8a000d\",\n goldA3: \"#75600018\",\n goldA4: \"#6b4e0024\",\n goldA5: \"#60460030\",\n goldA6: \"#64440040\",\n goldA7: \"#63420055\",\n goldA8: \"#633d0072\",\n goldA9: \"#5332009a\",\n goldA10: \"#492d00a1\",\n goldA11: \"#362100b4\",\n goldA12: \"#130c00d4\",\n};\nconst goldP3 = {\n gold1: \"color(display-p3 0.992 0.992 0.989)\",\n gold2: \"color(display-p3 0.98 0.976 0.953)\",\n gold3: \"color(display-p3 0.947 0.94 0.909)\",\n gold4: \"color(display-p3 0.914 0.904 0.865)\",\n gold5: \"color(display-p3 0.88 0.865 0.816)\",\n gold6: \"color(display-p3 0.84 0.818 0.756)\",\n gold7: \"color(display-p3 0.788 0.753 0.677)\",\n gold8: \"color(display-p3 0.715 0.66 0.565)\",\n gold9: \"color(display-p3 0.579 0.517 0.41)\",\n gold10: \"color(display-p3 0.538 0.479 0.38)\",\n gold11: \"color(display-p3 0.433 0.386 0.305)\",\n gold12: \"color(display-p3 0.227 0.209 0.173)\",\n};\nconst goldP3A = {\n goldA1: \"color(display-p3 0.349 0.349 0.024 / 0.012)\",\n goldA2: \"color(display-p3 0.592 0.514 0.024 / 0.048)\",\n goldA3: \"color(display-p3 0.4 0.357 0.012 / 0.091)\",\n goldA4: \"color(display-p3 0.357 0.298 0.008 / 0.134)\",\n goldA5: \"color(display-p3 0.345 0.282 0.004 / 0.185)\",\n goldA6: \"color(display-p3 0.341 0.263 0.004 / 0.244)\",\n goldA7: \"color(display-p3 0.345 0.235 0.004 / 0.322)\",\n goldA8: \"color(display-p3 0.345 0.22 0.004 / 0.436)\",\n goldA9: \"color(display-p3 0.286 0.18 0 / 0.589)\",\n goldA10: \"color(display-p3 0.255 0.161 0 / 0.62)\",\n goldA11: \"color(display-p3 0.433 0.386 0.305)\",\n goldA12: \"color(display-p3 0.227 0.209 0.173)\",\n};\nconst sky = {\n sky1: \"#f9feff\",\n sky2: \"#f1fafd\",\n sky3: \"#e1f6fd\",\n sky4: \"#d1f0fa\",\n sky5: \"#bee7f5\",\n sky6: \"#a9daed\",\n sky7: \"#8dcae3\",\n sky8: \"#60b3d7\",\n sky9: \"#7ce2fe\",\n sky10: \"#74daf8\",\n sky11: \"#00749e\",\n sky12: \"#1d3e56\",\n};\nconst skyA = {\n skyA1: \"#00d5ff06\",\n skyA2: \"#00a4db0e\",\n skyA3: \"#00b3ee1e\",\n skyA4: \"#00ace42e\",\n skyA5: \"#00a1d841\",\n skyA6: \"#0092ca56\",\n skyA7: \"#0089c172\",\n skyA8: \"#0085bf9f\",\n skyA9: \"#00c7fe83\",\n skyA10: \"#00bcf38b\",\n skyA11: \"#00749e\",\n skyA12: \"#002540e2\",\n};\nconst skyP3 = {\n sky1: \"color(display-p3 0.98 0.995 0.999)\",\n sky2: \"color(display-p3 0.953 0.98 0.99)\",\n sky3: \"color(display-p3 0.899 0.963 0.989)\",\n sky4: \"color(display-p3 0.842 0.937 0.977)\",\n sky5: \"color(display-p3 0.777 0.9 0.954)\",\n sky6: \"color(display-p3 0.701 0.851 0.921)\",\n sky7: \"color(display-p3 0.604 0.785 0.879)\",\n sky8: \"color(display-p3 0.457 0.696 0.829)\",\n sky9: \"color(display-p3 0.585 0.877 0.983)\",\n sky10: \"color(display-p3 0.555 0.845 0.959)\",\n sky11: \"color(display-p3 0.193 0.448 0.605)\",\n sky12: \"color(display-p3 0.145 0.241 0.329)\",\n};\nconst skyP3A = {\n skyA1: \"color(display-p3 0.02 0.804 1 / 0.02)\",\n skyA2: \"color(display-p3 0.024 0.592 0.757 / 0.048)\",\n skyA3: \"color(display-p3 0.004 0.655 0.886 / 0.102)\",\n skyA4: \"color(display-p3 0.004 0.604 0.851 / 0.157)\",\n skyA5: \"color(display-p3 0.004 0.565 0.792 / 0.224)\",\n skyA6: \"color(display-p3 0.004 0.502 0.737 / 0.299)\",\n skyA7: \"color(display-p3 0.004 0.459 0.694 / 0.397)\",\n skyA8: \"color(display-p3 0 0.435 0.682 / 0.542)\",\n skyA9: \"color(display-p3 0.004 0.71 0.965 / 0.416)\",\n skyA10: \"color(display-p3 0.004 0.647 0.914 / 0.444)\",\n skyA11: \"color(display-p3 0.193 0.448 0.605)\",\n skyA12: \"color(display-p3 0.145 0.241 0.329)\",\n};\nconst mint = {\n mint1: \"#f9fefd\",\n mint2: \"#f2fbf9\",\n mint3: \"#ddf9f2\",\n mint4: \"#c8f4e9\",\n mint5: \"#b3ecde\",\n mint6: \"#9ce0d0\",\n mint7: \"#7ecfbd\",\n mint8: \"#4cbba5\",\n mint9: \"#86ead4\",\n mint10: \"#7de0cb\",\n mint11: \"#027864\",\n mint12: \"#16433c\",\n};\nconst mintA = {\n mintA1: \"#00d5aa06\",\n mintA2: \"#00b18a0d\",\n mintA3: \"#00d29e22\",\n mintA4: \"#00cc9937\",\n mintA5: \"#00c0914c\",\n mintA6: \"#00b08663\",\n mintA7: \"#00a17d81\",\n mintA8: \"#009e7fb3\",\n mintA9: \"#00d3a579\",\n mintA10: \"#00c39982\",\n mintA11: \"#007763fd\",\n mintA12: \"#00312ae9\",\n};\nconst mintP3 = {\n mint1: \"color(display-p3 0.98 0.995 0.992)\",\n mint2: \"color(display-p3 0.957 0.985 0.977)\",\n mint3: \"color(display-p3 0.888 0.972 0.95)\",\n mint4: \"color(display-p3 0.819 0.951 0.916)\",\n mint5: \"color(display-p3 0.747 0.918 0.873)\",\n mint6: \"color(display-p3 0.668 0.87 0.818)\",\n mint7: \"color(display-p3 0.567 0.805 0.744)\",\n mint8: \"color(display-p3 0.42 0.724 0.649)\",\n mint9: \"color(display-p3 0.62 0.908 0.834)\",\n mint10: \"color(display-p3 0.585 0.871 0.797)\",\n mint11: \"color(display-p3 0.203 0.463 0.397)\",\n mint12: \"color(display-p3 0.136 0.259 0.236)\",\n};\nconst mintP3A = {\n mintA1: \"color(display-p3 0.02 0.804 0.608 / 0.02)\",\n mintA2: \"color(display-p3 0.02 0.647 0.467 / 0.044)\",\n mintA3: \"color(display-p3 0.004 0.761 0.553 / 0.114)\",\n mintA4: \"color(display-p3 0.004 0.741 0.545 / 0.181)\",\n mintA5: \"color(display-p3 0.004 0.678 0.51 / 0.255)\",\n mintA6: \"color(display-p3 0.004 0.616 0.463 / 0.334)\",\n mintA7: \"color(display-p3 0.004 0.549 0.412 / 0.432)\",\n mintA8: \"color(display-p3 0 0.529 0.392 / 0.581)\",\n mintA9: \"color(display-p3 0.004 0.765 0.569 / 0.381)\",\n mintA10: \"color(display-p3 0.004 0.69 0.51 / 0.416)\",\n mintA11: \"color(display-p3 0.203 0.463 0.397)\",\n mintA12: \"color(display-p3 0.136 0.259 0.236)\",\n};\nconst lime = {\n lime1: \"#fcfdfa\",\n lime2: \"#f8faf3\",\n lime3: \"#eef6d6\",\n lime4: \"#e2f0bd\",\n lime5: \"#d3e7a6\",\n lime6: \"#c2da91\",\n lime7: \"#abc978\",\n lime8: \"#8db654\",\n lime9: \"#bdee63\",\n lime10: \"#b0e64c\",\n lime11: \"#5c7c2f\",\n lime12: \"#37401c\",\n};\nconst limeA = {\n limeA1: \"#66990005\",\n limeA2: \"#6b95000c\",\n limeA3: \"#96c80029\",\n limeA4: \"#8fc60042\",\n limeA5: \"#81bb0059\",\n limeA6: \"#72aa006e\",\n limeA7: \"#61990087\",\n limeA8: \"#559200ab\",\n limeA9: \"#93e4009c\",\n limeA10: \"#8fdc00b3\",\n limeA11: \"#375f00d0\",\n limeA12: \"#1e2900e3\",\n};\nconst limeP3 = {\n lime1: \"color(display-p3 0.989 0.992 0.981)\",\n lime2: \"color(display-p3 0.975 0.98 0.954)\",\n lime3: \"color(display-p3 0.939 0.965 0.851)\",\n lime4: \"color(display-p3 0.896 0.94 0.76)\",\n lime5: \"color(display-p3 0.843 0.903 0.678)\",\n lime6: \"color(display-p3 0.778 0.852 0.599)\",\n lime7: \"color(display-p3 0.694 0.784 0.508)\",\n lime8: \"color(display-p3 0.585 0.707 0.378)\",\n lime9: \"color(display-p3 0.78 0.928 0.466)\",\n lime10: \"color(display-p3 0.734 0.896 0.397)\",\n lime11: \"color(display-p3 0.386 0.482 0.227)\",\n lime12: \"color(display-p3 0.222 0.25 0.128)\",\n};\nconst limeP3A = {\n limeA1: \"color(display-p3 0.412 0.608 0.02 / 0.02)\",\n limeA2: \"color(display-p3 0.514 0.592 0.024 / 0.048)\",\n limeA3: \"color(display-p3 0.584 0.765 0.008 / 0.15)\",\n limeA4: \"color(display-p3 0.561 0.757 0.004 / 0.24)\",\n limeA5: \"color(display-p3 0.514 0.698 0.004 / 0.322)\",\n limeA6: \"color(display-p3 0.443 0.627 0 / 0.4)\",\n limeA7: \"color(display-p3 0.376 0.561 0.004 / 0.491)\",\n limeA8: \"color(display-p3 0.333 0.529 0 / 0.624)\",\n limeA9: \"color(display-p3 0.588 0.867 0 / 0.534)\",\n limeA10: \"color(display-p3 0.561 0.827 0 / 0.604)\",\n limeA11: \"color(display-p3 0.386 0.482 0.227)\",\n limeA12: \"color(display-p3 0.222 0.25 0.128)\",\n};\nconst yellow = {\n yellow1: \"#fdfdf9\",\n yellow2: \"#fefce9\",\n yellow3: \"#fffab8\",\n yellow4: \"#fff394\",\n yellow5: \"#ffe770\",\n yellow6: \"#f3d768\",\n yellow7: \"#e4c767\",\n yellow8: \"#d5ae39\",\n yellow9: \"#ffe629\",\n yellow10: \"#ffdc00\",\n yellow11: \"#9e6c00\",\n yellow12: \"#473b1f\",\n};\nconst yellowA = {\n yellowA1: \"#aaaa0006\",\n yellowA2: \"#f4dd0016\",\n yellowA3: \"#ffee0047\",\n yellowA4: \"#ffe3016b\",\n yellowA5: \"#ffd5008f\",\n yellowA6: \"#ebbc0097\",\n yellowA7: \"#d2a10098\",\n yellowA8: \"#c99700c6\",\n yellowA9: \"#ffe100d6\",\n yellowA10: \"#ffdc00\",\n yellowA11: \"#9e6c00\",\n yellowA12: \"#2e2000e0\",\n};\nconst yellowP3 = {\n yellow1: \"color(display-p3 0.992 0.992 0.978)\",\n yellow2: \"color(display-p3 0.995 0.99 0.922)\",\n yellow3: \"color(display-p3 0.997 0.982 0.749)\",\n yellow4: \"color(display-p3 0.992 0.953 0.627)\",\n yellow5: \"color(display-p3 0.984 0.91 0.51)\",\n yellow6: \"color(display-p3 0.934 0.847 0.474)\",\n yellow7: \"color(display-p3 0.876 0.785 0.46)\",\n yellow8: \"color(display-p3 0.811 0.689 0.313)\",\n yellow9: \"color(display-p3 1 0.92 0.22)\",\n yellow10: \"color(display-p3 0.977 0.868 0.291)\",\n yellow11: \"color(display-p3 0.6 0.44 0)\",\n yellow12: \"color(display-p3 0.271 0.233 0.137)\",\n};\nconst yellowP3A = {\n yellowA1: \"color(display-p3 0.675 0.675 0.024 / 0.024)\",\n yellowA2: \"color(display-p3 0.953 0.855 0.008 / 0.079)\",\n yellowA3: \"color(display-p3 0.988 0.925 0.004 / 0.251)\",\n yellowA4: \"color(display-p3 0.98 0.875 0.004 / 0.373)\",\n yellowA5: \"color(display-p3 0.969 0.816 0.004 / 0.491)\",\n yellowA6: \"color(display-p3 0.875 0.71 0 / 0.526)\",\n yellowA7: \"color(display-p3 0.769 0.604 0 / 0.542)\",\n yellowA8: \"color(display-p3 0.725 0.549 0 / 0.687)\",\n yellowA9: \"color(display-p3 1 0.898 0 / 0.781)\",\n yellowA10: \"color(display-p3 0.969 0.812 0 / 0.71)\",\n yellowA11: \"color(display-p3 0.6 0.44 0)\",\n yellowA12: \"color(display-p3 0.271 0.233 0.137)\",\n};\nconst amber = {\n amber1: \"#fefdfb\",\n amber2: \"#fefbe9\",\n amber3: \"#fff7c2\",\n amber4: \"#ffee9c\",\n amber5: \"#fbe577\",\n amber6: \"#f3d673\",\n amber7: \"#e9c162\",\n amber8: \"#e2a336\",\n amber9: \"#ffc53d\",\n amber10: \"#ffba18\",\n amber11: \"#ab6400\",\n amber12: \"#4f3422\",\n};\nconst amberA = {\n amberA1: \"#c0800004\",\n amberA2: \"#f4d10016\",\n amberA3: \"#ffde003d\",\n amberA4: \"#ffd40063\",\n amberA5: \"#f8cf0088\",\n amberA6: \"#eab5008c\",\n amberA7: \"#dc9b009d\",\n amberA8: \"#da8a00c9\",\n amberA9: \"#ffb300c2\",\n amberA10: \"#ffb300e7\",\n amberA11: \"#ab6400\",\n amberA12: \"#341500dd\",\n};\nconst amberP3 = {\n amber1: \"color(display-p3 0.995 0.992 0.985)\",\n amber2: \"color(display-p3 0.994 0.986 0.921)\",\n amber3: \"color(display-p3 0.994 0.969 0.782)\",\n amber4: \"color(display-p3 0.989 0.937 0.65)\",\n amber5: \"color(display-p3 0.97 0.902 0.527)\",\n amber6: \"color(display-p3 0.936 0.844 0.506)\",\n amber7: \"color(display-p3 0.89 0.762 0.443)\",\n amber8: \"color(display-p3 0.85 0.65 0.3)\",\n amber9: \"color(display-p3 1 0.77 0.26)\",\n amber10: \"color(display-p3 0.959 0.741 0.274)\",\n amber11: \"color(display-p3 0.64 0.4 0)\",\n amber12: \"color(display-p3 0.294 0.208 0.145)\",\n};\nconst amberP3A = {\n amberA1: \"color(display-p3 0.757 0.514 0.024 / 0.016)\",\n amberA2: \"color(display-p3 0.902 0.804 0.008 / 0.079)\",\n amberA3: \"color(display-p3 0.965 0.859 0.004 / 0.22)\",\n amberA4: \"color(display-p3 0.969 0.82 0.004 / 0.35)\",\n amberA5: \"color(display-p3 0.933 0.796 0.004 / 0.475)\",\n amberA6: \"color(display-p3 0.875 0.682 0.004 / 0.495)\",\n amberA7: \"color(display-p3 0.804 0.573 0 / 0.557)\",\n amberA8: \"color(display-p3 0.788 0.502 0 / 0.699)\",\n amberA9: \"color(display-p3 1 0.686 0 / 0.742)\",\n amberA10: \"color(display-p3 0.945 0.643 0 / 0.726)\",\n amberA11: \"color(display-p3 0.64 0.4 0)\",\n amberA12: \"color(display-p3 0.294 0.208 0.145)\",\n};\nconst orange = {\n orange1: \"#fefcfb\",\n orange2: \"#fff7ed\",\n orange3: \"#ffefd6\",\n orange4: \"#ffdfb5\",\n orange5: \"#ffd19a\",\n orange6: \"#ffc182\",\n orange7: \"#f5ae73\",\n orange8: \"#ec9455\",\n orange9: \"#f76b15\",\n orange10: \"#ef5f00\",\n orange11: \"#cc4e00\",\n orange12: \"#582d1d\",\n};\nconst orangeA = {\n orangeA1: \"#c0400004\",\n orangeA2: \"#ff8e0012\",\n orangeA3: \"#ff9c0029\",\n orangeA4: \"#ff91014a\",\n orangeA5: \"#ff8b0065\",\n orangeA6: \"#ff81007d\",\n orangeA7: \"#ed6c008c\",\n orangeA8: \"#e35f00aa\",\n orangeA9: \"#f65e00ea\",\n orangeA10: \"#ef5f00\",\n orangeA11: \"#cc4e00\",\n orangeA12: \"#431200e2\",\n};\nconst orangeP3 = {\n orange1: \"color(display-p3 0.995 0.988 0.985)\",\n orange2: \"color(display-p3 0.994 0.968 0.934)\",\n orange3: \"color(display-p3 0.989 0.938 0.85)\",\n orange4: \"color(display-p3 1 0.874 0.687)\",\n orange5: \"color(display-p3 1 0.821 0.583)\",\n orange6: \"color(display-p3 0.975 0.767 0.545)\",\n orange7: \"color(display-p3 0.919 0.693 0.486)\",\n orange8: \"color(display-p3 0.877 0.597 0.379)\",\n orange9: \"color(display-p3 0.9 0.45 0.2)\",\n orange10: \"color(display-p3 0.87 0.409 0.164)\",\n orange11: \"color(display-p3 0.76 0.34 0)\",\n orange12: \"color(display-p3 0.323 0.185 0.127)\",\n};\nconst orangeP3A = {\n orangeA1: \"color(display-p3 0.757 0.267 0.024 / 0.016)\",\n orangeA2: \"color(display-p3 0.886 0.533 0.008 / 0.067)\",\n orangeA3: \"color(display-p3 0.922 0.584 0.008 / 0.15)\",\n orangeA4: \"color(display-p3 1 0.604 0.004 / 0.314)\",\n orangeA5: \"color(display-p3 1 0.569 0.004 / 0.416)\",\n orangeA6: \"color(display-p3 0.949 0.494 0.004 / 0.455)\",\n orangeA7: \"color(display-p3 0.839 0.408 0 / 0.514)\",\n orangeA8: \"color(display-p3 0.804 0.349 0 / 0.62)\",\n orangeA9: \"color(display-p3 0.878 0.314 0 / 0.8)\",\n orangeA10: \"color(display-p3 0.843 0.29 0 / 0.836)\",\n orangeA11: \"color(display-p3 0.76 0.34 0)\",\n orangeA12: \"color(display-p3 0.323 0.185 0.127)\",\n};\n\nconst blackA = {\n blackA1: \"rgba(0, 0, 0, 0.05)\",\n blackA2: \"rgba(0, 0, 0, 0.1)\",\n blackA3: \"rgba(0, 0, 0, 0.15)\",\n blackA4: \"rgba(0, 0, 0, 0.2)\",\n blackA5: \"rgba(0, 0, 0, 0.3)\",\n blackA6: \"rgba(0, 0, 0, 0.4)\",\n blackA7: \"rgba(0, 0, 0, 0.5)\",\n blackA8: \"rgba(0, 0, 0, 0.6)\",\n blackA9: \"rgba(0, 0, 0, 0.7)\",\n blackA10: \"rgba(0, 0, 0, 0.8)\",\n blackA11: \"rgba(0, 0, 0, 0.9)\",\n blackA12: \"rgba(0, 0, 0, 0.95)\",\n};\nconst blackP3A = {\n blackA1: \"color(display-p3 0 0 0 / 0.05)\",\n blackA2: \"color(display-p3 0 0 0 / 0.1)\",\n blackA3: \"color(display-p3 0 0 0 / 0.15)\",\n blackA4: \"color(display-p3 0 0 0 / 0.2)\",\n blackA5: \"color(display-p3 0 0 0 / 0.3)\",\n blackA6: \"color(display-p3 0 0 0 / 0.4)\",\n blackA7: \"color(display-p3 0 0 0 / 0.5)\",\n blackA8: \"color(display-p3 0 0 0 / 0.6)\",\n blackA9: \"color(display-p3 0 0 0 / 0.7)\",\n blackA10: \"color(display-p3 0 0 0 / 0.8)\",\n blackA11: \"color(display-p3 0 0 0 / 0.9)\",\n blackA12: \"color(display-p3 0 0 0 / 0.95)\",\n};\n\nconst whiteA = {\n whiteA1: \"rgba(255, 255, 255, 0.05)\",\n whiteA2: \"rgba(255, 255, 255, 0.1)\",\n whiteA3: \"rgba(255, 255, 255, 0.15)\",\n whiteA4: \"rgba(255, 255, 255, 0.2)\",\n whiteA5: \"rgba(255, 255, 255, 0.3)\",\n whiteA6: \"rgba(255, 255, 255, 0.4)\",\n whiteA7: \"rgba(255, 255, 255, 0.5)\",\n whiteA8: \"rgba(255, 255, 255, 0.6)\",\n whiteA9: \"rgba(255, 255, 255, 0.7)\",\n whiteA10: \"rgba(255, 255, 255, 0.8)\",\n whiteA11: \"rgba(255, 255, 255, 0.9)\",\n whiteA12: \"rgba(255, 255, 255, 0.95)\",\n};\nconst whiteP3A = {\n whiteA1: \"color(display-p3 1 1 1 / 0.05)\",\n whiteA2: \"color(display-p3 1 1 1 / 0.1)\",\n whiteA3: \"color(display-p3 1 1 1 / 0.15)\",\n whiteA4: \"color(display-p3 1 1 1 / 0.2)\",\n whiteA5: \"color(display-p3 1 1 1 / 0.3)\",\n whiteA6: \"color(display-p3 1 1 1 / 0.4)\",\n whiteA7: \"color(display-p3 1 1 1 / 0.5)\",\n whiteA8: \"color(display-p3 1 1 1 / 0.6)\",\n whiteA9: \"color(display-p3 1 1 1 / 0.7)\",\n whiteA10: \"color(display-p3 1 1 1 / 0.8)\",\n whiteA11: \"color(display-p3 1 1 1 / 0.9)\",\n whiteA12: \"color(display-p3 1 1 1 / 0.95)\",\n};\n\nexport { amber, amberA, amberDark, amberDarkA, amberDarkP3, amberDarkP3A, amberP3, amberP3A, blackA, blackP3A, blue, blueA, blueDark, blueDarkA, blueDarkP3, blueDarkP3A, blueP3, blueP3A, bronze, bronzeA, bronzeDark, bronzeDarkA, bronzeDarkP3, bronzeDarkP3A, bronzeP3, bronzeP3A, brown, brownA, brownDark, brownDarkA, brownDarkP3, brownDarkP3A, brownP3, brownP3A, crimson, crimsonA, crimsonDark, crimsonDarkA, crimsonDarkP3, crimsonDarkP3A, crimsonP3, crimsonP3A, cyan, cyanA, cyanDark, cyanDarkA, cyanDarkP3, cyanDarkP3A, cyanP3, cyanP3A, gold, goldA, goldDark, goldDarkA, goldDarkP3, goldDarkP3A, goldP3, goldP3A, grass, grassA, grassDark, grassDarkA, grassDarkP3, grassDarkP3A, grassP3, grassP3A, gray, grayA, grayDark, grayDarkA, grayDarkP3, grayDarkP3A, grayP3, grayP3A, green, greenA, greenDark, greenDarkA, greenDarkP3, greenDarkP3A, greenP3, greenP3A, indigo, indigoA, indigoDark, indigoDarkA, indigoDarkP3, indigoDarkP3A, indigoP3, indigoP3A, iris, irisA, irisDark, irisDarkA, irisDarkP3, irisDarkP3A, irisP3, irisP3A, jade, jadeA, jadeDark, jadeDarkA, jadeDarkP3, jadeDarkP3A, jadeP3, jadeP3A, lime, limeA, limeDark, limeDarkA, limeDarkP3, limeDarkP3A, limeP3, limeP3A, mauve, mauveA, mauveDark, mauveDarkA, mauveDarkP3, mauveDarkP3A, mauveP3, mauveP3A, mint, mintA, mintDark, mintDarkA, mintDarkP3, mintDarkP3A, mintP3, mintP3A, olive, oliveA, oliveDark, oliveDarkA, oliveDarkP3, oliveDarkP3A, oliveP3, oliveP3A, orange, orangeA, orangeDark, orangeDarkA, orangeDarkP3, orangeDarkP3A, orangeP3, orangeP3A, pink, pinkA, pinkDark, pinkDarkA, pinkDarkP3, pinkDarkP3A, pinkP3, pinkP3A, plum, plumA, plumDark, plumDarkA, plumDarkP3, plumDarkP3A, plumP3, plumP3A, purple, purpleA, purpleDark, purpleDarkA, purpleDarkP3, purpleDarkP3A, purpleP3, purpleP3A, red, redA, redDark, redDarkA, redDarkP3, redDarkP3A, redP3, redP3A, ruby, rubyA, rubyDark, rubyDarkA, rubyDarkP3, rubyDarkP3A, rubyP3, rubyP3A, sage, sageA, sageDark, sageDarkA, sageDarkP3, sageDarkP3A, sageP3, sageP3A, sand, sandA, sandDark, sandDarkA, sandDarkP3, sandDarkP3A, sandP3, sandP3A, sky, skyA, skyDark, skyDarkA, skyDarkP3, skyDarkP3A, skyP3, skyP3A, slate, slateA, slateDark, slateDarkA, slateDarkP3, slateDarkP3A, slateP3, slateP3A, teal, tealA, tealDark, tealDarkA, tealDarkP3, tealDarkP3A, tealP3, tealP3A, tomato, tomatoA, tomatoDark, tomatoDarkA, tomatoDarkP3, tomatoDarkP3A, tomatoP3, tomatoP3A, violet, violetA, violetDark, violetDarkA, violetDarkP3, violetDarkP3A, violetP3, violetP3A, whiteA, whiteP3A, yellow, yellowA, yellowDark, yellowDarkA, yellowDarkP3, yellowDarkP3A, yellowP3, yellowP3A };\n","import { default as ColorCls } from \"color\"\r\nimport {\r\n\tgray,\r\n\tgold,\r\n\tbrown,\r\n\tyellow,\r\n\tamber,\r\n\torange,\r\n\tred,\r\n\tcrimson,\r\n\tpink,\r\n\tplum,\r\n\tpurple,\r\n\tviolet,\r\n\tiris,\r\n\tindigo,\r\n\tblue,\r\n\tcyan,\r\n\tjade,\r\n\tgrass,\r\n\tlime,\r\n\tmint,\r\n\tsky,\r\n} from \"@radix-ui/colors\"\r\nimport { CSSColor } from \"../typings\"\r\n\r\n// TODO: Move most of these constants into src/theme/variables.ts\r\nexport const primaryColor: CSSColor = \"#2D55E2\"\r\nexport const successColor: CSSColor = \"#349C55\"\r\nexport const warningColor: CSSColor = \"#FFA620\"\r\nexport const errorColor: CSSColor = \"#E24C4C\"\r\nexport const GREEN: CSSColor = \"#1fd155\"\r\nexport const YELLOW: CSSColor = \"#f5de14\"\r\nexport interface BadgeColors {\r\n\tbackgroundColor: CSSColor\r\n\ttextColor: CSSColor\r\n}\r\n\r\n// Colors used for color selection purposes\r\nexport const Colors: Record<string, CSSColor> = {\r\n\tgray: (gray as Record<string, CSSColor>).gray9!,\r\n\tgold: (gold as Record<string, CSSColor>).gold9!,\r\n\tbrown: (brown as Record<string, CSSColor>).brown9!,\r\n\tyellow: (yellow as Record<string, CSSColor>).yellow9!,\r\n\tamber: (amber as Record<string, CSSColor>).amber9!,\r\n\torange: (orange as Record<string, CSSColor>).orange9!,\r\n\tred: (red as Record<string, CSSColor>).red9!,\r\n\tcrimson: (crimson as Record<string, CSSColor>).crimson9!,\r\n\tpink: (pink as Record<string, CSSColor>).pink9!,\r\n\tplum: (plum as Record<string, CSSColor>).plum9!,\r\n\tpurple: (purple as Record<string, CSSColor>).purple9!,\r\n\tviolet: (violet as Record<string, CSSColor>).violet9!,\r\n\tiris: (iris as Record<string, CSSColor>).iris9!,\r\n\tindigo: (indigo as Record<string, CSSColor>).indigo9!,\r\n\tblue: (blue as Record<string, CSSColor>).blue9!,\r\n\tcyan: (cyan as Record<string, CSSColor>).cyan9!,\r\n\tjade: (jade as Record<string, CSSColor>).jade9!,\r\n\tgrass: (grass as Record<string, CSSColor>).grass9!,\r\n\tlime: (lime as Record<string, CSSColor>).lime9!,\r\n\tmint: (mint as Record<string, CSSColor>).mint9!,\r\n\tsky: (sky as Record<string, CSSColor>).sky9!,\r\n}\r\n\r\n// Colors used for component stages\r\nexport const ComponentStageColors: Record<string, CSSColor> = {\r\n\tindigo: (indigo as Record<string, CSSColor>).indigo9!,\r\n\tred: (red as Record<string, CSSColor>).red9!,\r\n\tviolet: (violet as Record<string, CSSColor>).violet9!,\r\n\tyellow: (yellow as Record<string, CSSColor>).yellow9!,\r\n\tjade: (jade as Record<string, CSSColor>).jade9!,\r\n\tcyan: (cyan as Record<string, CSSColor>).cyan9!,\r\n\tgold: (gold as Record<string, CSSColor>).gold9!,\r\n\torange: (orange as Record<string, CSSColor>).orange9!,\r\n\tlime: (lime as Record<string, CSSColor>).lime9!,\r\n\tsky: (sky as Record<string, CSSColor>).sky9!,\r\n\tpink: (pink as Record<string, CSSColor>).pink9!,\r\n}\r\n\r\nexport const defaultBadgeColor: CSSColor = \"#868686\"\r\n\r\n// This function adjusts a given colour into two variations for use as badge colours\r\nexport const generateBadgeColors = (rawColor: CSSColor): BadgeColors => {\r\n\tconst color = ColorCls(rawColor)\r\n\tconst safety = ColorCls(YELLOW)\r\n\tconst backgroundColor: CSSColor = color.darken(0.09).hex() as CSSColor\r\n\t// If the color matches the special yellow safety color, make the text black\r\n\tconst textColor = color.hex() === safety.hex() ? \"#000000\" : \"#FFFFFF\"\r\n\t// Alternate style:\r\n\t// const backgroundColor = color.lighten(0.4).hex()\r\n\t// const textColor = color.darken(0.6).hex()\r\n\r\n\treturn { backgroundColor, textColor }\r\n}\r\n\r\nexport function getStageColor(index: number): CSSColor {\r\n\treturn Object.values(ComponentStageColors)[index % Object.keys(ComponentStageColors).length]!\r\n}\r\n","import { memoize } from \"./optimization\"\r\n\r\n/** Only shows year if a past year */\r\nexport const getLocalDateString = memoize((date?: string | null | Date | number) => {\r\n\tif (!date) return \"\"\r\n\tconst asDate = new Date(date)\r\n\tconst isThisYear = asDate.getFullYear() === today.getFullYear()\r\n\tconst options: Intl.DateTimeFormatOptions = { day: \"numeric\", month: \"short\" }\r\n\tif (!isThisYear) options.year = \"numeric\"\r\n\treturn asDate.toLocaleDateString([], options)\r\n})\r\n\r\nconst relative = new Intl.RelativeTimeFormat([], { style: \"long\", numeric: \"auto\" })\r\nconst msInDay = 1000 * 86400\r\nconst today = new Date()\r\n\r\n/** Returns true if the given date is today */\r\nexport const isToday = (date: string | Date | number) => {\r\n\treturn new Date(date).toDateString() === today.toDateString()\r\n}\r\n\r\n/*\r\nDisplays a relative message \"in 2 days\" or \"today\" if within the given period (min, max)\r\nOtherwise, falls back to getLocalDateString()\r\n*/\r\nexport const getLocalRelativeDateString = memoize((date: string | Date | number, min: number, max: number) => {\r\n\tconst days = Math.round((new Date(date).getTime() - today.getTime()) / msInDay)\r\n\tif (days < min || days > max) return getLocalDateString(date)\r\n\treturn relative.format(days, \"days\")\r\n})\r\n","import { createSelector, createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { Category, CSSColor, Offline, RootState, Selector, SelectorWithArgs } from \"../../typings\"\r\nimport { onlyUniqueOfflineIds, restructureCreateSelectorWithArgs } from \"../../utils\"\r\n\r\ninterface CategoryVisibility {\r\n\thiddenCategoryIds: string[]\r\n\tisNullCategoryHidden: boolean\r\n}\r\n\r\nexport interface CategoryState {\r\n\tcategories: Record<string, Category>\r\n\tusedCategoryColors: CSSColor[]\r\n\t// This is a list of names of all categories that the user has hidden\r\n\tcategoryVisibility: CategoryVisibility\r\n}\r\n\r\nconst initialState: CategoryState = {\r\n\tcategories: {},\r\n\tusedCategoryColors: [],\r\n\tcategoryVisibility: {\r\n\t\thiddenCategoryIds: [],\r\n\t\tisNullCategoryHidden: false,\r\n\t},\r\n}\r\n\r\n// TODO: Use types with createSlice\r\nexport const categorySlice = createSlice({\r\n\tname: \"categories\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetCategories: (state, action: { payload: Category[] }) => {\r\n\t\t\tif (!Array.isArray(action.payload)) throw new Error(\"Expected an array of Categories\")\r\n\t\t\tif (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {\r\n\t\t\t\tthrow new Error(\"Tried to use setCategories reducer with duplicate ID's\")\r\n\t\t\t}\r\n\t\t\taction.payload.forEach((category) => {\r\n\t\t\t\tstate.categories[category.offline_id] = category\r\n\t\t\t})\r\n\t\t\t// For all previously hidden categories, only keep the settings for the categories that are still present\r\n\t\t\t// in the freshly updated list of categories\r\n\t\t\tstate.categoryVisibility.hiddenCategoryIds = state.categoryVisibility.hiddenCategoryIds.filter(\r\n\t\t\t\t(categoryId) => action.payload.some((category) => category.offline_id === categoryId),\r\n\t\t\t)\r\n\t\t},\r\n\t\taddOrReplaceCategories: (state, action: { payload: Category[] }) => {\r\n\t\t\taction.payload.forEach((category) => {\r\n\t\t\t\tstate.categories[category.offline_id] = category\r\n\t\t\t})\r\n\t\t},\r\n\t\taddCategory: (state, action: { payload: Category }) => {\r\n\t\t\tif (action.payload.offline_id in state.categories) {\r\n\t\t\t\tthrow new Error(`Tried to add duplicate category with ID: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\tstate.categories[action.payload.offline_id] = action.payload\r\n\t\t\tstate.usedCategoryColors.push(action.payload.color)\r\n\t\t},\r\n\t\tpatchCategory: (state, action: { payload: Offline<Partial<Category>> }) => {\r\n\t\t\tconst existingData = state.categories[action.payload.offline_id]\r\n\r\n\t\t\tif (existingData) {\r\n\t\t\t\tstate.categories[action.payload.offline_id] = { ...existingData, ...action.payload }\r\n\t\t\t} else {\r\n\t\t\t\tconsole.error(`Tried to patch category with ID that doesn't exist: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\t// If the updated category color changes, put it in the list\r\n\t\t\tif (action.payload.color && !(action.payload.color in state.usedCategoryColors)) {\r\n\t\t\t\tstate.usedCategoryColors.push(action.payload.color)\r\n\t\t\t}\r\n\t\t},\r\n\t\treplaceCategory: (state, action: { payload: Category }) => {\r\n\t\t\tif (action.payload.offline_id in state.categories) {\r\n\t\t\t\tstate.categories[action.payload.offline_id] = action.payload\r\n\t\t\t} else {\r\n\t\t\t\tconsole.error(`Tried to replace category with ID that doesn't exist: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\t// If the updated category color changes, put it in the list\r\n\t\t\tif (!(action.payload.color in state.usedCategoryColors)) {\r\n\t\t\t\tstate.usedCategoryColors.push(action.payload.color)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveCategory: (state, action: PayloadAction<string>) => {\r\n\t\t\tif (!action.payload) {\r\n\t\t\t\tthrow new Error(\"Category is undefined\")\r\n\t\t\t}\r\n\t\t\tconst category = state.categories[action.payload]\r\n\t\t\tif (category) {\r\n\t\t\t\tcategorySlice.caseReducers.removeColor(state, { payload: category.color })\r\n\t\t\t\tdelete state.categories[action.payload]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Tried to remove category with ID that doesn't exist: ${action.payload}`)\r\n\t\t\t}\r\n\t\t},\r\n\t\t// Pass in a null value to hide the \"No category\" category\r\n\t\thideCategory: (state, action: { payload: string | null }) => {\r\n\t\t\tconst categoryId = action.payload\r\n\t\t\tif (categoryId === null) {\r\n\t\t\t\tstate.categoryVisibility.isNullCategoryHidden = true\r\n\t\t\t} else if (!(categoryId in state.categoryVisibility.hiddenCategoryIds)) {\r\n\t\t\t\tstate.categoryVisibility.hiddenCategoryIds.push(categoryId)\r\n\t\t\t}\r\n\t\t},\r\n\t\thideAllCategories: (state) => {\r\n\t\t\t// Set the list of hidden category names to the list of all category names\r\n\t\t\tstate.categoryVisibility.hiddenCategoryIds = Object.keys(state.categories)\r\n\t\t\t// Hide the \"No category\" category\r\n\t\t\tstate.categoryVisibility.isNullCategoryHidden = true\r\n\t\t},\r\n\t\t// Pass in a null value to unhide the \"No category\" category\r\n\t\tunhideCategory: (state, action: { payload: string | null }) => {\r\n\t\t\tconst categoryId = action.payload\r\n\t\t\tif (categoryId === null) {\r\n\t\t\t\tstate.categoryVisibility.isNullCategoryHidden = false\r\n\t\t\t} else {\r\n\t\t\t\tstate.categoryVisibility.hiddenCategoryIds = state.categoryVisibility.hiddenCategoryIds.filter(\r\n\t\t\t\t\t(id) => id !== categoryId,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tunhideAllCategories: (state) => {\r\n\t\t\t// Reset the list of hidden categories\r\n\t\t\tstate.categoryVisibility.hiddenCategoryIds = []\r\n\t\t\t// Unhide the \"No category\" category\r\n\t\t\tstate.categoryVisibility.isNullCategoryHidden = false\r\n\t\t},\r\n\t\tremoveColor: (state, action: { payload: string }) => {\r\n\t\t\tstate.usedCategoryColors = state.usedCategoryColors.filter((color: string) => color !== action.payload)\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\tsetCategories,\r\n\taddCategory,\r\n\treplaceCategory,\r\n\tpatchCategory,\r\n\tremoveCategory,\r\n\thideCategory,\r\n\thideAllCategories,\r\n\tunhideCategory,\r\n\tunhideAllCategories,\r\n\tremoveColor,\r\n\taddOrReplaceCategories,\r\n} = categorySlice.actions\r\n\r\nexport const selectCategoryMapping = (state: RootState) => state.categoryReducer.categories\r\n\r\n/** Exists only to avoid importing the workspaceSlice in the categorySlice */\r\nconst _selectActiveWorkspaceId = (state: RootState) => state.workspaceReducer.activeWorkspaceId\r\nexport const selectCategories = createSelector(\r\n\t[selectCategoryMapping, _selectActiveWorkspaceId],\r\n\t(mapping, activeWorkspaceId) =>\r\n\t\tactiveWorkspaceId ? Object.values(mapping).filter((category) => category.workspace === activeWorkspaceId) : [],\r\n)\r\n\r\nexport const selectCategoriesOfWorkspace: SelectorWithArgs<string, Category[]> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectCategories, (_state, workspaceId: string) => workspaceId], (categories, workspaceId) =>\r\n\t\tcategories.filter((category) => category.workspace === workspaceId),\r\n\t),\r\n)\r\n\r\nexport const selectCategory = (offline_id: string | null) => (state: RootState) => {\r\n\tif (!offline_id) return undefined\r\n\treturn state.categoryReducer.categories[offline_id]\r\n}\r\n\r\nexport const selectUsedColors: Selector<CSSColor[]> = (state: RootState) => state.categoryReducer.usedCategoryColors\r\n\r\nexport const selectCategoryVisibility = (state: RootState) => state.categoryReducer.categoryVisibility\r\n\r\nexport const selectHiddenCategoryCount = (state: RootState) => {\r\n\tconst { hiddenCategoryIds, isNullCategoryHidden } = state.categoryReducer.categoryVisibility\r\n\tlet hiddenCategoryCount = hiddenCategoryIds.length\r\n\t// The \"No category\" category also counts as a hidden category\r\n\tif (isNullCategoryHidden) hiddenCategoryCount++\r\n\treturn hiddenCategoryCount\r\n}\r\n\r\nexport const categoryReducer: Reducer<CategoryState> = categorySlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { Component, ComponentType, RootState, Selector, SelectorWithArgs, Submitted } from \"../../typings\"\r\nimport { toOfflineIdRecord } from \"../../utils\"\r\n\r\nexport interface ComponentState {\r\n\tcomponents: Record<string, Component | Submitted<Component>>\r\n}\r\n\r\nconst initialState: ComponentState = {\r\n\tcomponents: {},\r\n}\r\nexport const componentSlice = createSlice({\r\n\tname: \"components\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\taddComponent: (state, action: { payload: Component }) => {\r\n\t\t\tstate.components[action.payload.offline_id] = action.payload\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t\taddComponentsInBatches: (state, action: { payload: (Component | Submitted<Component>)[] }) => {\r\n\t\t\t// Object.assign copies the properties from action.payload into state.components\r\n\t\t\tObject.assign(state.components, toOfflineIdRecord(action.payload))\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t\tsetComponents: (state, action: { payload: Component[] }) => {\r\n\t\t\tstate.components = toOfflineIdRecord(action.payload)\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t\tupdateComponent: (state, action: { payload: Component }) => {\r\n\t\t\tif (action.payload.offline_id in state.components) {\r\n\t\t\t\tstate.components[action.payload.offline_id] = action.payload\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Tried to update component with ID that doesn't exist: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t\tremoveComponent: (state, action: PayloadAction<string>) => {\r\n\t\t\tif (action.payload in state.components) {\r\n\t\t\t\tdelete state.components[action.payload]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Failed to remove component because ID doesn't exist: ${action.payload}`)\r\n\t\t\t}\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t\tremoveAllComponentsOfType: (state, action: PayloadAction<string>) => {\r\n\t\t\tfor (const componentId in state.components) {\r\n\t\t\t\tif (state.components[componentId]?.component_type === action.payload) {\r\n\t\t\t\t\tdelete state.components[componentId]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t},\r\n})\r\n\r\n// TODO: Reusable helper for this\r\n// When calling a selector, it returns a new object/array on each call. This causes hooks and components that depend on\r\n// components to rerender, even if the components themselves haven't changed. We know when components change (only when\r\n// one of the reducers above are called), so we can improve the performance of the app significantly by returning an old\r\n// reference until the cache has been invalidated.\r\nlet prevComponents: Component[] | null = null\r\nexport const selectComponents = (state: RootState) => {\r\n\tif (!prevComponents) {\r\n\t\tprevComponents = Object.values(state.componentReducer.components)\r\n\t}\r\n\treturn prevComponents\r\n}\r\n\r\nexport const selectComponentsFromComponentType: SelectorWithArgs<string | undefined, Component[]> =\r\n\t(componentTypeId) => (state) => {\r\n\t\tif (!componentTypeId) return []\r\n\t\tconst components = selectComponents(state)\r\n\t\treturn components.filter((component) => component.component_type === componentTypeId)\r\n\t}\r\n\r\nexport const selectComponent: SelectorWithArgs<string, Component> = (componentId) => (state: RootState) => {\r\n\treturn state.componentReducer.components[componentId]\r\n}\r\nexport const selectComponentTypeFromComponent: SelectorWithArgs<string, ComponentType> =\r\n\t(componentTypeId) => (state: RootState) => {\r\n\t\treturn state.componentTypeReducer.componentTypes[componentTypeId]\r\n\t}\r\nexport const selectComponentTypeFromComponents: Selector<Record<string, ComponentType>> = (state: RootState) => {\r\n\tconst ret: Record<string, ComponentType> = {}\r\n\tconst componentTypes = state.componentTypeReducer.componentTypes\r\n\tconst components = state.componentReducer.components\r\n\r\n\tfor (const [componentId, component] of Object.entries(components)) {\r\n\t\tconst componentType = componentTypes[component.component_type]\r\n\t\tif (!componentType) {\r\n\t\t\tconsole.error(\r\n\t\t\t\t`Component type with ID ${component.component_type} not found.\r\n\t\t\t\tExpected all referenced component types to be populated.\r\n\t\t\t\tReturning empty object to avoid fatal errors.`,\r\n\t\t\t)\r\n\t\t\treturn {}\r\n\t\t}\r\n\t\tret[componentId] = componentType\r\n\t}\r\n\r\n\treturn ret\r\n}\r\n\r\nexport const selectComponentsByType: SelectorWithArgs<string, Component[]> = (componentTypeId) => (state) => {\r\n\tconst components = state.componentReducer.components\r\n\tconst componentsOfType: Component[] = []\r\n\r\n\tfor (const component of Object.values(components)) {\r\n\t\tif (component.component_type === componentTypeId) {\r\n\t\t\tcomponentsOfType.push(component)\r\n\t\t}\r\n\t}\r\n\treturn componentsOfType\r\n}\r\n\r\nexport const selectNumberOfComponentsOfComponentType: SelectorWithArgs<string | undefined, number> =\r\n\t(componentTypeId) => (state) => {\r\n\t\tif (!componentTypeId) return 0\r\n\t\treturn selectComponentsByType(componentTypeId)(state)?.length\r\n\t}\r\n\r\nexport const selectComponentTypesFromIds: SelectorWithArgs<string[], ComponentType[]> =\r\n\t(componentTypeIds: string[]) => (state: RootState) => {\r\n\t\treturn componentTypeIds.reduce<ComponentType[]>((acc, componentTypeId) => {\r\n\t\t\tconst componentType = state.componentTypeReducer.componentTypes[componentTypeId]\r\n\t\t\tif (componentType) {\r\n\t\t\t\tacc.push(componentType)\r\n\t\t\t}\r\n\t\t\treturn acc\r\n\t\t}, [])\r\n\t}\r\n\r\nexport const {\r\n\taddComponent,\r\n\tupdateComponent,\r\n\tremoveComponent,\r\n\taddComponentsInBatches,\r\n\tsetComponents,\r\n\tremoveAllComponentsOfType,\r\n} = componentSlice.actions\r\n\r\nexport const componentReducer: Reducer<ComponentState> = componentSlice.reducer\r\n","import { createSlice, Reducer } from \"@reduxjs/toolkit\"\r\n\r\nimport { CompletedStagesMapping, Component, Model, RootState, SelectorWithArgs } from \"../../typings\"\r\n\r\nexport interface ComponentStageCompletionState {\r\n\tcompletionsByComponentId: CompletedStagesMapping\r\n}\r\n\r\nconst initialState: ComponentStageCompletionState = {\r\n\tcompletionsByComponentId: {},\r\n}\r\n\r\n// TODO: Move to typings\r\nexport interface ComponentStageCompletion extends Model {\r\n\tcomponent: string\r\n\tstage: string\r\n}\r\n\r\n// TODO: It would be much more performant if completions are stored with componentId keys and stageId[] values\r\nexport const componentStageCompletionSlice = createSlice({\r\n\tname: \"componentStageCompletions\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\taddStageCompletion: (state, action: { payload: ComponentStageCompletion }) => {\r\n\t\t\tlet stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component]\r\n\t\t\tif (!stageToCompletionDateMapping) {\r\n\t\t\t\tstageToCompletionDateMapping = {}\r\n\t\t\t\tstate.completionsByComponentId[action.payload.component] = stageToCompletionDateMapping\r\n\t\t\t}\r\n\t\t\tstageToCompletionDateMapping[action.payload.stage] = new Date().toISOString()\r\n\t\t},\r\n\t\taddStageCompletions: (state, action: { payload: CompletedStagesMapping }) => {\r\n\t\t\tfor (const [componentId, stageIdToCompletionDateMapping] of Object.entries(action.payload)) {\r\n\t\t\t\tif (Object.keys(stageIdToCompletionDateMapping).length === 0)\r\n\t\t\t\t\tthrow new Error(\r\n\t\t\t\t\t\t`Encountered empty stageIdToCompletionDateMapping argument for component ${componentId}`,\r\n\t\t\t\t\t)\r\n\t\t\t\tlet thisComponentCompletions = state.completionsByComponentId[componentId]\r\n\t\t\t\tif (thisComponentCompletions === undefined) {\r\n\t\t\t\t\tthisComponentCompletions = {}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tfor (const [stageId, completionDate] of Object.entries(stageIdToCompletionDateMapping)) {\r\n\t\t\t\t\tthisComponentCompletions[stageId] = completionDate\r\n\t\t\t\t}\r\n\r\n\t\t\t\tstate.completionsByComponentId[componentId] = thisComponentCompletions\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveStageCompletions: (state, action: { payload: ComponentStageCompletion[] }) => {\r\n\t\t\tfor (const completion of action.payload) {\r\n\t\t\t\tconst thisComponentCompletions = state.completionsByComponentId[completion.component]\r\n\r\n\t\t\t\tif (!thisComponentCompletions || !(completion.stage in thisComponentCompletions)) {\r\n\t\t\t\t\t// TODO: This should be an error. We should not construct completions to remove if the stage is not\r\n\t\t\t\t\t// completed for the component.\r\n\t\t\t\t\tconsole.warn(\r\n\t\t\t\t\t\t\"Skipping removal of uncompleted stage. This message indicates completion objects \" +\r\n\t\t\t\t\t\t\t\"are created unnecessarily.\",\r\n\t\t\t\t\t)\r\n\t\t\t\t\tcontinue\r\n\t\t\t\t}\r\n\t\t\t\tdelete thisComponentCompletions[completion.stage]\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetStageCompletions: (state, action: { payload: CompletedStagesMapping }) => {\r\n\t\t\tstate.completionsByComponentId = action.payload\r\n\t\t},\r\n\t},\r\n})\r\nexport const { addStageCompletion, addStageCompletions, removeStageCompletions, setStageCompletions } =\r\n\tcomponentStageCompletionSlice.actions\r\n\r\nexport const selectCompletedStages = (state: RootState) => {\r\n\treturn state.componentStageCompletionReducer.completionsByComponentId\r\n}\r\n\r\nexport const selectCompletedStageIdsForComponent: SelectorWithArgs<Component, string[]> =\r\n\t(component: Component) => (state: RootState) => {\r\n\t\treturn Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {})\r\n\t}\r\n\r\nexport const componentStageCompletionReducer: Reducer<ComponentStageCompletionState> =\r\n\tcomponentStageCompletionSlice.reducer\r\n","import { Reducer, createSelector, createSlice } from \"@reduxjs/toolkit\"\r\n\r\nimport { ComponentStage, RootState, SelectorWithArgs } from \"../../typings\"\r\nimport { restructureCreateSelectorWithArgs, toOfflineIdRecord } from \"../../utils\"\r\n\r\nexport interface ComponentStageState {\r\n\tstages: Record<string, ComponentStage>\r\n}\r\nconst initialState: ComponentStageState = {\r\n\tstages: {},\r\n}\r\n\r\nexport const componentStageSlice = createSlice({\r\n\tname: \"componentStages\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\taddStages: (state, action: { payload: ComponentStage[] }) => {\r\n\t\t\tObject.assign(state.stages, toOfflineIdRecord(action.payload))\r\n\t\t},\r\n\t\tupdateStages: (state, action: { payload: ComponentStage[] }) => {\r\n\t\t\tfor (const stage of action.payload) {\r\n\t\t\t\tstate.stages[stage.offline_id] = stage\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveStages: (state, action: { payload: string[] }) => {\r\n\t\t\taction.payload.forEach((id) => {\r\n\t\t\t\tdelete state.stages[id]\r\n\t\t\t})\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const selectStageMapping: (state: RootState) => Record<string, ComponentStage> = (state) =>\r\n\tstate.componentStageReducer.stages\r\n\r\nexport const selectStages: (state: RootState) => ComponentStage[] = createSelector(\r\n\t[selectStageMapping],\r\n\t(stageMapping) => {\r\n\t\treturn Object.values(stageMapping)\r\n\t},\r\n)\r\n\r\nexport const selectStagesFromComponentTypeIds: SelectorWithArgs<\r\n\tstring[],\r\n\tRecord<string, ComponentStage[]>\r\n> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[selectStages, (_state, componentTypeIds: string[]) => componentTypeIds],\r\n\t\t(stages, componentTypeIds) => {\r\n\t\t\tconst componentTypeIdsSet = new Set(componentTypeIds)\r\n\t\t\tconst ret: Record<string, ComponentStage[]> = {}\r\n\t\t\tfor (const stage of stages) {\r\n\t\t\t\tif (componentTypeIdsSet.has(stage.component_type)) {\r\n\t\t\t\t\tif (!ret[stage.component_type]) {\r\n\t\t\t\t\t\tret[stage.component_type] = []\r\n\t\t\t\t\t}\r\n\t\t\t\t\tret[stage.component_type]!.push(stage)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tfor (const key in ret) {\r\n\t\t\t\tret[key] = ret[key]!.sort((a, b) => a.priority - b.priority)\r\n\t\t\t}\r\n\t\t\treturn ret\r\n\t\t},\r\n\t),\r\n)\r\n\r\nexport const selectStagesFromComponentType: SelectorWithArgs<string, ComponentStage[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[selectStages, (_state, componentTypeId: string) => componentTypeId],\r\n\t\t\t(stages, componentTypeId) => {\r\n\t\t\t\treturn stages\r\n\t\t\t\t\t.filter((stage) => stage.component_type === componentTypeId)\r\n\t\t\t\t\t.sort((a, b) => a.priority - b.priority)\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectStagesFromStageIds: SelectorWithArgs<string[], ComponentStage[]> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectStageMapping, (_state, stageIds: string[]) => stageIds], (stageMapping, stageIds) => {\r\n\t\treturn stageIds\r\n\t\t\t.map((offline_id) => stageMapping[offline_id])\r\n\t\t\t.filter((stage): stage is ComponentStage => !!stage)\r\n\t}),\r\n)\r\n\r\nexport const { addStages, updateStages, removeStages } = componentStageSlice.actions\r\nexport const componentStageReducer: Reducer<ComponentStageState> = componentStageSlice.reducer\r\n","import { restructureCreateSelectorWithArgs, toOfflineIdRecord } from \"../../utils\"\r\nimport type { Reducer } from \"@reduxjs/toolkit\"\r\nimport { createSelector, createSlice } from \"@reduxjs/toolkit\"\r\nimport type { ComponentType, RootState, SelectorWithArgs } from \"../../typings\"\r\n\r\nexport interface ComponentTypeState {\r\n\tcomponentTypes: Record<string, ComponentType>\r\n\thiddenComponentTypeIds: Record<string, boolean>\r\n}\r\n\r\nconst initialState: ComponentTypeState = {\r\n\tcomponentTypes: {},\r\n\thiddenComponentTypeIds: {},\r\n}\r\n\r\nexport const componentTypeSlice = createSlice({\r\n\tname: \"componentTypes\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\taddComponentType: (state, action: { payload: ComponentType }) => {\r\n\t\t\tstate.componentTypes[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\tsetComponentTypes: (state, action: { payload: ComponentType[] }) => {\r\n\t\t\tstate.componentTypes = toOfflineIdRecord(action.payload)\r\n\t\t},\r\n\t\ttoggleComponentTypeVisibility: (state, action: { payload: string }) => {\r\n\t\t\tstate.hiddenComponentTypeIds[action.payload] = !state.hiddenComponentTypeIds[action.payload]\r\n\t\t},\r\n\t\tdeleteComponentType: (state, action: { payload: string }) => {\r\n\t\t\tdelete state.componentTypes[action.payload]\r\n\t\t},\r\n\t},\r\n})\r\n\r\n// TODO: Move\r\nexport type AppSelector<TResult> = (state: RootState) => TResult\r\n\r\nexport const selectComponentTypesMapping: AppSelector<Record<string, ComponentType>> = (state: RootState) =>\r\n\tstate.componentTypeReducer.componentTypes\r\n\r\nexport const selectComponentTypes: AppSelector<ComponentType[]> = createSelector(\r\n\t[selectComponentTypesMapping],\r\n\t(mapping) => Object.values(mapping),\r\n)\r\n\r\nexport const selectComponentType: SelectorWithArgs<string, ComponentType> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectComponentTypesMapping, (_state, id: string) => id], (mapping, id) => mapping[id]),\r\n)\r\n\r\ninterface selectNumberOfComponentTypesMatchingCaseInsensitiveNameProps {\r\n\tname: string | null | undefined\r\n\tcomponentTypeId: string | undefined\r\n}\r\nexport const selectNumberOfComponentTypesMatchingCaseInsensitiveName: SelectorWithArgs<\r\n\tselectNumberOfComponentTypesMatchingCaseInsensitiveNameProps,\r\n\tnumber\r\n> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[\r\n\t\t\tselectComponentTypesMapping,\r\n\t\t\t(_state, args: selectNumberOfComponentTypesMatchingCaseInsensitiveNameProps) => args,\r\n\t\t],\r\n\t\t(mapping, args) => {\r\n\t\t\tconst name = args.name?.toLowerCase() ?? null\r\n\t\t\treturn Object.values(mapping).filter(\r\n\t\t\t\t(componentType) =>\r\n\t\t\t\t\t(componentType.name?.toLowerCase() ?? null) === name &&\r\n\t\t\t\t\tcomponentType.offline_id !== args.componentTypeId,\r\n\t\t\t).length\r\n\t\t},\r\n\t),\r\n)\r\n\r\nexport const selectComponentTypesByName: SelectorWithArgs<string, ComponentType[]> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[selectComponentTypesMapping, (_state, name: string | null | undefined) => name],\r\n\t\t(mapping, name) => {\r\n\t\t\tname = name?.toLowerCase() ?? null\r\n\t\t\treturn Object.values(mapping).filter(\r\n\t\t\t\t(componentType) => (componentType.name?.toLowerCase() ?? null) === name,\r\n\t\t\t)\r\n\t\t},\r\n\t),\r\n)\r\n\r\nexport const selectHiddenComponentTypeIds: AppSelector<Record<string, boolean | undefined>> = (state: RootState) =>\r\n\tstate.componentTypeReducer.hiddenComponentTypeIds\r\n\r\nexport const { addComponentType, setComponentTypes, toggleComponentTypeVisibility, deleteComponentType } =\r\n\tcomponentTypeSlice.actions\r\nexport const componentTypeReducer: Reducer<ComponentTypeState> = componentTypeSlice.reducer\r\n","import { Reducer, createSelector, createSlice } from \"@reduxjs/toolkit\"\r\nimport { RootState, Selector, Workspace } from \"../../typings\"\r\nimport { restructureCreateSelectorWithArgs } from \"../../utils\"\r\n\r\nexport interface WorkspaceState {\r\n\tworkspaces: Record<string, Workspace>\r\n\tactiveWorkspaceId: string | null\r\n}\r\n\r\nconst initialState: WorkspaceState = {\r\n\tworkspaces: {},\r\n\tactiveWorkspaceId: null,\r\n}\r\n\r\n/**\r\n * Stores info related to the user's current workspace. For now, it's only the workspace ID which is hardcoded to 1.\r\n */\r\nexport const workspaceSlice = createSlice({\r\n\tname: \"workspace\",\r\n\tinitialState,\r\n\t// The `reducers` field lets us define reducers and generate associated actions\r\n\treducers: {\r\n\t\tsetWorkspaces: (state, action: { payload: Record<string, Workspace> }) => {\r\n\t\t\t// Redux Toolkit allows us to write \"mutating\" logic in reducers. It\r\n\t\t\t// doesn't actually mutate the state because it uses the Immer library,\r\n\t\t\t// which detects changes to a \"draft state\" and produces a brand new\r\n\t\t\t// immutable state based off those changes\r\n\t\t\tstate.workspaces = action.payload\r\n\t\t},\r\n\t\t// Takes a list of Workspaces and updates existing ones to match the payload, or adds them\r\n\t\t// to the store if they are not already present\r\n\t\taddOrReplaceWorkspaces: (state, action: { payload: Record<string, Workspace> }) => {\r\n\t\t\tObject.values(action.payload).forEach((workspace) => {\r\n\t\t\t\tstate.workspaces[workspace.offline_id] = workspace\r\n\t\t\t})\r\n\t\t},\r\n\t\taddWorkspace: (state, action: { payload: Workspace }) => {\r\n\t\t\tif (action.payload.offline_id in state.workspaces) {\r\n\t\t\t\tthrow new Error(`Tried to add duplicate workspace with name: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\tstate.workspaces[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\tremoveWorkspace: (state, action: { payload: string }) => {\r\n\t\t\tdelete state.workspaces[action.payload]\r\n\t\t},\r\n\t\tsetActiveWorkspaceId: (state, action: { payload: string | null }) => {\r\n\t\t\tstate.activeWorkspaceId = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setWorkspaces, addOrReplaceWorkspaces, addWorkspace, setActiveWorkspaceId, removeWorkspace } =\r\n\tworkspaceSlice.actions\r\n\r\n// The function below is called a selector and allows us to select a value from\r\n// the state. Selectors can also be defined inline where they're used instead of\r\n// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`\r\nexport const selectWorkspaceMapping: Selector<Record<string, Workspace>> = (state: RootState) =>\r\n\tstate.workspaceReducer.workspaces\r\n\r\nexport const selectWorkspaces = createSelector([selectWorkspaceMapping], (mapping) => Object.values(mapping))\r\n\r\nexport const selectMainWorkspace: Selector<Workspace | undefined> = createSelector([selectWorkspaces], (workspaces) => {\r\n\treturn workspaces.find((workspace) => workspace.name.toLowerCase() === \"main\")\r\n})\r\n\r\nexport const selectWorkspace = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectWorkspaceMapping, (_state, workspaceId: string) => workspaceId], (mapping, workspaceId) => {\r\n\t\treturn mapping[workspaceId]\r\n\t}),\r\n)\r\n\r\nexport const selectActiveWorkspaceId: Selector<string | null> = (state: RootState) =>\r\n\tstate.workspaceReducer.activeWorkspaceId\r\n\r\nexport const selectActiveWorkspace: Selector<Workspace | null | undefined> = createSelector(\r\n\t[selectWorkspaceMapping, selectActiveWorkspaceId],\r\n\t(mapping, activeWorkspaceId) => {\r\n\t\tif (!activeWorkspaceId) return null\r\n\t\treturn mapping[activeWorkspaceId]\r\n\t},\r\n)\r\n\r\nexport const selectPermittedWorkspaceIds: Selector<Set<string>> = createSelector(\r\n\t[selectWorkspaceMapping],\r\n\t(mapping) => {\r\n\t\treturn new Set(\r\n\t\t\tObject.values(mapping)\r\n\t\t\t\t.filter((workspace: Workspace) => workspace.permitted)\r\n\t\t\t\t.map((workspace: Workspace) => workspace.offline_id),\r\n\t\t)\r\n\t},\r\n)\r\n\r\nexport const workspaceReducer: Reducer<WorkspaceState> = workspaceSlice.reducer\r\n","import { createSelector, createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport {\r\n\tCreated,\r\n\tIssue,\r\n\tIssueAttachment,\r\n\tIssueComment,\r\n\tRootState,\r\n\tSearchableRecentResult,\r\n\tSearchArgs,\r\n\tSearchResult,\r\n\tSelector,\r\n\tSelectorWithArgs,\r\n\tStored,\r\n\tSubmitted,\r\n} from \"../../typings\"\r\nimport { IssueStatus } from \"../../enums\"\r\nimport { issueToSearchResult, logOnlyOnce, onlyUniqueOfflineIds, restructureCreateSelectorWithArgs } from \"../../utils\"\r\nimport { selectCategoryVisibility } from \"./categorySlice.ts\"\r\nimport { selectActiveWorkspaceId, selectWorkspaceMapping } from \"./workspaceSlice.ts\"\r\n\r\nconst maxRecentIssues = 10\r\ninterface RecentIssueId {\r\n\tofflineId: string\r\n\tlastOpenedEpochTime: number\r\n}\r\n\r\nexport interface IssueState {\r\n\tissues: Record<string, Stored<Issue>>\r\n\tattachments: Record<string, Stored<IssueAttachment>>\r\n\tcomments: Record<string, Stored<IssueComment>>\r\n\tvisibleStatuses: IssueStatus[]\r\n\tvisibleUserIds: (number | null)[] | null\r\n\tisFetchingInitialData: boolean\r\n\trecentIssueIds: RecentIssueId[]\r\n\tactiveIssueId: string | null\r\n}\r\n\r\nconst initialState: IssueState = {\r\n\tissues: {},\r\n\tattachments: {},\r\n\tcomments: {},\r\n\tvisibleStatuses: [IssueStatus.BACKLOG, IssueStatus.SELECTED],\r\n\tisFetchingInitialData: false,\r\n\tvisibleUserIds: null,\r\n\trecentIssueIds: [],\r\n\tactiveIssueId: null,\r\n}\r\n\r\n/**\r\n * Manages issues and categories stored offline.\r\n * Issue and category functionality is combined because they modify each other.\r\n * For example, if a category's color is changed then all issues with the category must be changed too.\r\n */\r\nexport const issueSlice = createSlice({\r\n\tname: \"issues\",\r\n\tinitialState,\r\n\textraReducers: (builder) =>\r\n\t\tbuilder.addCase(\"RESET\", (state) => {\r\n\t\t\tObject.assign(state, initialState)\r\n\t\t}),\r\n\treducers: {\r\n\t\tsetIssues: (state, action: { payload: Created<Issue>[] }) => {\r\n\t\t\tif (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {\r\n\t\t\t\tthrow new Error(\"Tried to use setIssues reducer with duplicate ID's\")\r\n\t\t\t}\r\n\t\t\t// Go through the list of issues and have each be stored with their offline_id as the key\r\n\t\t\taction.payload.forEach((issue) => {\r\n\t\t\t\tstate.issues[issue.offline_id] = issue\r\n\t\t\t})\r\n\t\t},\r\n\t\t// TODO: Reusable function\r\n\t\tsetAttachments: (state, action: PayloadAction<Created<IssueAttachment>[]>) => {\r\n\t\t\tfor (const attachment of action.payload) {\r\n\t\t\t\tstate.attachments[attachment.offline_id] = attachment\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetActiveIssueId: (state, action: { payload: string | null }) => {\r\n\t\t\tstate.activeIssueId = action.payload\r\n\t\t},\r\n\t\taddIssue: (state, action: { payload: Submitted<Issue> }) => {\r\n\t\t\tif (action.payload.offline_id in state.issues) {\r\n\t\t\t\tthrow new Error(`Tried to add duplicate issue with ID: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\tstate.issues[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\t// TODO: Reusable function\r\n\t\taddAttachment: (state, action: PayloadAction<Submitted<IssueAttachment>>) => {\r\n\t\t\tif (action.payload.offline_id in state.attachments) {\r\n\t\t\t\tthrow new Error(`Attachment ${action.payload.offline_id} already exists.`)\r\n\t\t\t}\r\n\t\t\tstate.attachments[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\taddAttachments: (state, action: PayloadAction<Submitted<IssueAttachment>[]>) => {\r\n\t\t\tfor (const attachment of action.payload) {\r\n\t\t\t\tstate.attachments[attachment.offline_id] = attachment\r\n\t\t\t}\r\n\t\t},\r\n\t\tupdateIssue: (state, action: { payload: Submitted<Partial<Issue>> }) => {\r\n\t\t\t// If we encounter an issue with the same ID, we will update it\r\n\t\t\tif (action.payload.offline_id in state.issues) {\r\n\t\t\t\tstate.issues[action.payload.offline_id] = {\r\n\t\t\t\t\t...state.issues[action.payload.offline_id],\r\n\t\t\t\t\t...action.payload,\r\n\t\t\t\t} as Stored<Issue>\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Tried to update issue with ID that doesn't exist: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t},\r\n\t\t// TODO: Reusable function\r\n\t\tupdateAttachment: (state, action: PayloadAction<Submitted<IssueAttachment>>) => {\r\n\t\t\tif (action.payload.offline_id in state.attachments) {\r\n\t\t\t\tstate.attachments[action.payload.offline_id] = action.payload\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Attachment ${action.payload.offline_id} does not exist.`)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveIssue: (state, action: PayloadAction<string>) => {\r\n\t\t\tif (action.payload in state.issues) {\r\n\t\t\t\tdelete state.issues[action.payload]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Failed to remove issue because ID doesn't exist: ${action.payload}`)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveAttachment: (state, action: PayloadAction<string>) => {\r\n\t\t\tif (action.payload in state.attachments) {\r\n\t\t\t\tdelete state.attachments[action.payload]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Attachment ${action.payload} does not exist.`)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveAttachmentsOfIssue: (state, action: PayloadAction<string>) => {\r\n\t\t\tconst attachments = Object.values(state.attachments).filter((a) => a.issue_id === action.payload)\r\n\t\t\tfor (const attachment of attachments) {\r\n\t\t\t\tdelete state.attachments[attachment.offline_id]\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetVisibleStatuses: (state, action: PayloadAction<IssueStatus[]>) => {\r\n\t\t\tstate.visibleStatuses = action.payload\r\n\t\t},\r\n\t\tsetIsFetchingInitialData: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.isFetchingInitialData = action.payload\r\n\t\t},\r\n\t\tsetVisibleUserIds: (state, action: { payload: (number | null)[] }) => {\r\n\t\t\tstate.visibleUserIds = [...new Set(action.payload)]\r\n\t\t},\r\n\t\tsetIssueComments: (state, action: PayloadAction<Created<IssueComment>[]>) => {\r\n\t\t\t// NOTE: Does not delete old comments. Name is misleading. We should standardize all names.\r\n\t\t\tfor (const comment of action.payload) {\r\n\t\t\t\tstate.comments[comment.offline_id] = comment\r\n\t\t\t}\r\n\t\t},\r\n\t\taddOrReplaceIssueComment: (state, action: PayloadAction<Submitted<IssueComment>>) => {\r\n\t\t\tstate.comments[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\tremoveIssueComment: (state, action: PayloadAction<string>) => {\r\n\t\t\tif (action.payload in state.comments) {\r\n\t\t\t\tdelete state.comments[action.payload]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Failed to remove issue comment because ID doesn't exist: ${action.payload}`)\r\n\t\t\t}\r\n\t\t},\r\n\t\tcleanRecentIssues: (state) => {\r\n\t\t\tstate.recentIssueIds = state.recentIssueIds.filter((recentIssue) => state.issues[recentIssue.offlineId])\r\n\t\t},\r\n\t\taddToRecentIssues: (state, action: { payload: string }) => {\r\n\t\t\tstate.recentIssueIds = state.recentIssueIds.filter(\r\n\t\t\t\t(recentIssue) => recentIssue.offlineId !== action.payload,\r\n\t\t\t)\r\n\t\t\tstate.recentIssueIds.push({ offlineId: action.payload.toLowerCase(), lastOpenedEpochTime: Date.now() })\r\n\r\n\t\t\tif (state.recentIssueIds.length > maxRecentIssues) {\r\n\t\t\t\tstate.recentIssueIds.shift()\r\n\t\t\t}\r\n\t\t},\r\n\t\tresetRecentIssues: (state) => {\r\n\t\t\tstate.recentIssueIds = []\r\n\t\t},\r\n\t\tremoveRecentIssue: (state, action: PayloadAction<string>) => {\r\n\t\t\tconst indexToRemove = state.recentIssueIds.findIndex((item) => {\r\n\t\t\t\treturn item.offlineId == action.payload\r\n\t\t\t})\r\n\t\t\tif (indexToRemove !== -1) {\r\n\t\t\t\tstate.recentIssueIds.splice(indexToRemove, 1)\r\n\t\t\t}\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\taddAttachment,\r\n\taddAttachments,\r\n\taddIssue,\r\n\taddOrReplaceIssueComment,\r\n\taddToRecentIssues,\r\n\tcleanRecentIssues,\r\n\tremoveAttachment,\r\n\tremoveAttachmentsOfIssue,\r\n\tremoveIssue,\r\n\tremoveIssueComment,\r\n\tremoveRecentIssue,\r\n\tresetRecentIssues,\r\n\tsetActiveIssueId,\r\n\tsetAttachments,\r\n\tsetIsFetchingInitialData,\r\n\tsetIssueComments,\r\n\tsetIssues,\r\n\tsetVisibleStatuses,\r\n\tsetVisibleUserIds,\r\n\tupdateAttachment,\r\n\tupdateIssue,\r\n} = issueSlice.actions\r\nexport interface IssueFilterArgs {\r\n\tfilterByAssignedTo: boolean\r\n\tfilterByStatus: boolean\r\n\tfilterByCategory: boolean\r\n\tfilterByWorkspace: boolean\r\n}\r\n\r\nexport const selectIssueMapping = (state: RootState) => state.issueReducer.issues\r\nexport const selectRecentIssueIds = (state: RootState) => state.issueReducer.recentIssueIds\r\nexport const selectVisibleUserIds = (state: RootState) => state.issueReducer.visibleUserIds\r\nexport const selectVisibleStatuses = (state: RootState) => state.issueReducer.visibleStatuses\r\n\r\nexport const selectIssues: SelectorWithArgs<IssueFilterArgs, Stored<Issue>[]> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[\r\n\t\t\tselectIssueMapping,\r\n\t\t\tselectVisibleUserIds,\r\n\t\t\tselectVisibleStatuses,\r\n\t\t\tselectCategoryVisibility,\r\n\t\t\tselectActiveWorkspaceId,\r\n\t\t\t(_state, args: IssueFilterArgs) => args,\r\n\t\t],\r\n\t\t(mapping, visibleUserIds, visibleStatuses, categoryVisibility, activeWorkspaceId, args) => {\r\n\t\t\tlet ret = Object.values(mapping)\r\n\t\t\tconst visibleUserIdsSet = new Set(visibleUserIds)\r\n\t\t\tconst visibleStatusesSet = new Set(visibleStatuses)\r\n\r\n\t\t\tif (args.filterByAssignedTo && visibleUserIds?.length) {\r\n\t\t\t\tret = ret.filter((issue) => {\r\n\t\t\t\t\treturn visibleUserIdsSet.has(issue.assigned_to || null)\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t\tif (args.filterByStatus) {\r\n\t\t\t\tret = ret.filter((issue) => {\r\n\t\t\t\t\treturn visibleStatusesSet.has(issue.status)\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t\tif (args.filterByCategory) {\r\n\t\t\t\tconst isNullCategoryHidden = categoryVisibility.isNullCategoryHidden\r\n\t\t\t\tconst hiddenCategoryIds = categoryVisibility.hiddenCategoryIds\r\n\t\t\t\tret = ret.filter((issue) => {\r\n\t\t\t\t\tif (!issue.category) {\r\n\t\t\t\t\t\treturn !isNullCategoryHidden\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn !hiddenCategoryIds.includes(issue.category)\r\n\t\t\t\t})\r\n\t\t\t\tif (args.filterByWorkspace) {\r\n\t\t\t\t\tret = ret.filter((issue) => {\r\n\t\t\t\t\t\treturn activeWorkspaceId && issue.visible_in_workspaces.includes(activeWorkspaceId)\r\n\t\t\t\t\t})\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn ret\r\n\t\t},\r\n\t),\r\n)\r\n\r\nexport const selectActiveIssueId = (state: RootState) => state.issueReducer.activeIssueId\r\nexport const selectIssueAttachmentMapping = (state: RootState) => state.issueReducer.attachments\r\nexport const selectIssueAttachments: Selector<Stored<IssueAttachment>[]> = createSelector(\r\n\t[selectIssueAttachmentMapping],\r\n\t(mapping) => Object.values(mapping),\r\n)\r\n\r\nexport const selectPhotoAttachmentsOfIssue: SelectorWithArgs<string, Stored<IssueAttachment>[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[selectIssueAttachmentMapping, (_state: RootState, issueId: string) => issueId],\r\n\t\t\t(attachmentMapping, issueId) => {\r\n\t\t\t\tif (!issueId) return undefined\r\n\t\t\t\treturn Object.values(attachmentMapping).filter(\r\n\t\t\t\t\t(attachment) =>\r\n\t\t\t\t\t\tattachment.issue_id === issueId &&\r\n\t\t\t\t\t\tattachment.file_type &&\r\n\t\t\t\t\t\tattachment.file_type.startsWith(\"image/\"),\r\n\t\t\t\t)\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectCommentMapping = (state: RootState) => state.issueReducer.comments\r\n\r\nexport const selectCommentsOfIssue = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectCommentMapping, (_state, issueId: string) => issueId], (commentMapping, issueId: string) => {\r\n\t\treturn Object.values(commentMapping).filter((comment) => comment.issue === issueId)\r\n\t}),\r\n)\r\n\r\nexport const selectFileAttachmentsOfIssue = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[selectIssueAttachmentMapping, (_state, issueId: string) => issueId],\r\n\t\t(attachmentMapping, issueId) => {\r\n\t\t\tif (!issueId) return undefined\r\n\t\t\treturn Object.values(attachmentMapping).filter(\r\n\t\t\t\t(attachment) =>\r\n\t\t\t\t\t// Files with file_type that is null or not an image file\r\n\t\t\t\t\tattachment.issue_id === issueId &&\r\n\t\t\t\t\t(!attachment.file_type || !attachment.file_type.startsWith(\"image/\")),\r\n\t\t\t)\r\n\t\t},\r\n\t),\r\n)\r\nexport const selectIssue: SelectorWithArgs<string, Stored<Issue> | undefined> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectIssueMapping, (_state, id: string) => id], (mapping, id) => {\r\n\t\treturn mapping[id]\r\n\t}),\r\n)\r\nexport const selectIsFetchingInitialData = (state: RootState) => state.issueReducer.isFetchingInitialData\r\nexport const selectAllAttachments = createSelector([selectIssueAttachmentMapping], (mapping) => Object.values(mapping))\r\n\r\n// TODO: Cache?\r\nexport const searchIssues: SelectorWithArgs<SearchArgs, SearchResult<Stored<Issue>>[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[selectIssueMapping, selectWorkspaceMapping, (_state, searchArgs: SearchArgs) => searchArgs],\r\n\t\t\t(mapping, workspaceMapping, searchArgs) => {\r\n\t\t\t\tlet searchTerm = searchArgs.searchTerm\r\n\t\t\t\tconst maxResults = searchArgs.maxResults\r\n\t\t\t\tsearchTerm = searchTerm.toLowerCase()\r\n\t\t\t\tconst ret: SearchResult<Stored<Issue>>[] = []\r\n\t\t\t\tconst issues = Object.values(mapping)\r\n\t\t\t\t// This is more performant than repeatedly calling .length\r\n\t\t\t\tlet nbResults = 0\r\n\t\t\t\tfor (const issue of issues) {\r\n\t\t\t\t\t// First, get rid of any issues with no index_workspace. This can happen if the index workspace was deleted,\r\n\t\t\t\t\t// but the server hasn't responded with a new index in the main workspace. If no index_workspace is\r\n\t\t\t\t\t// available, we can't calculate the \"tag\" of the search result.\r\n\t\t\t\t\t// TODO: It's still possible to support search by showing a blank tag.\r\n\t\t\t\t\tif (!issue.index_workspace) {\r\n\t\t\t\t\t\tlogOnlyOnce(\r\n\t\t\t\t\t\t\t\"issue-has-no-index-workspace\",\r\n\t\t\t\t\t\t\tissue.offline_id,\r\n\t\t\t\t\t\t\t\"warn\",\r\n\t\t\t\t\t\t\t`Issue ${issue.offline_id} has no index_workspace and cannot be searched.`,\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t\tcontinue\r\n\t\t\t\t\t}\r\n\t\t\t\t\tconst workspace = workspaceMapping[issue.index_workspace]\r\n\r\n\t\t\t\t\tif (!workspace) {\r\n\t\t\t\t\t\tlogOnlyOnce(\r\n\t\t\t\t\t\t\t\"issue-has-non-existent-index-workspace\",\r\n\t\t\t\t\t\t\tissue.offline_id,\r\n\t\t\t\t\t\t\t\"warn\",\r\n\t\t\t\t\t\t\t`Encountered issue with an index_workspace that doesn't exist. Issue ${issue.offline_id} has \r\n\t\t\t\t\tindex_workspace = ${issue.index_workspace}, which does not exist in:`,\r\n\t\t\t\t\t\t\tObject.keys(workspaceMapping),\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t\tcontinue\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tconst workspaceAbbreviation = workspace.abbreviation\r\n\t\t\t\t\tif (!workspaceAbbreviation) {\r\n\t\t\t\t\t\tlogOnlyOnce(\r\n\t\t\t\t\t\t\t\"workspace-has-no-abbreviation\",\r\n\t\t\t\t\t\t\tworkspace.offline_id,\r\n\t\t\t\t\t\t\t\"error\",\r\n\t\t\t\t\t\t\t`Workspace ${workspace.name} has no abbreviation. Not including any issues in search.`,\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t\tcontinue\r\n\t\t\t\t\t}\r\n\t\t\t\t\tconst tag = \"index\" in issue ? `${workspaceAbbreviation.toUpperCase()}-${issue.index}` : null\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\t(issue.title || \"\").toLowerCase().includes(searchTerm) ||\r\n\t\t\t\t\t\t(tag && tag.toLowerCase().includes(searchTerm))\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\tret.push(issueToSearchResult(issue, tag))\r\n\t\t\t\t\t\tnbResults++\r\n\t\t\t\t\t\tif (maxResults && nbResults >= maxResults) {\r\n\t\t\t\t\t\t\treturn ret\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn ret\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectRecentIssuesAsSearchResults: Selector<SearchableRecentResult<Stored<Issue>>[]> = createSelector(\r\n\t[selectIssueMapping, selectRecentIssueIds, selectWorkspaceMapping],\r\n\t(issueMapping, recentIssueIds, workspaceMapping) => {\r\n\t\tconst ret: SearchableRecentResult<Stored<Issue>>[] = []\r\n\t\tfor (const recentIssueResult of recentIssueIds) {\r\n\t\t\tconst issue = issueMapping[recentIssueResult.offlineId]\r\n\t\t\tif (!issue) {\r\n\t\t\t\t// Recent issue has been deleted. Remove it from the list.\r\n\t\t\t\tconsole.info(\"Recent issue no longer exists\")\r\n\t\t\t\tcontinue\r\n\t\t\t}\r\n\t\t\tif (\"index\" in issue && issue.index_workspace) {\r\n\t\t\t\tconst indexWorkspace = workspaceMapping[issue.index_workspace]\r\n\t\t\t\tif (!indexWorkspace) {\r\n\t\t\t\t\t// Prevent repeated logging, which hurts performance.\r\n\t\t\t\t\tlogOnlyOnce(\r\n\t\t\t\t\t\t\"issue-has-index-but-not-index-workspace\",\r\n\t\t\t\t\t\tissue.offline_id,\r\n\t\t\t\t\t\t\"warn\",\r\n\t\t\t\t\t\t`Issue ${issue.offline_id} has an index but no index_workspace. This may be because the \r\n\t\t\t\t\tworkspace has been deleted, but the new index has not been returned by the server yet. It will not\r\n\t\t\t\t\tbe included in search results.`,\r\n\t\t\t\t\t)\r\n\t\t\t\t\tcontinue\r\n\t\t\t\t}\r\n\t\t\t\tconst workspaceTag = `${indexWorkspace.abbreviation}-${issue.index}`\r\n\t\t\t\tconst searchResult = {\r\n\t\t\t\t\t...issueToSearchResult(issue, workspaceTag),\r\n\t\t\t\t\tlastOpenedEpochTime: recentIssueResult.lastOpenedEpochTime,\r\n\t\t\t\t} satisfies SearchableRecentResult<Stored<Issue>>\r\n\t\t\t\tret.push(searchResult)\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn ret\r\n\t},\r\n)\r\n\r\nexport const issueReducer: Reducer<IssueState> = issueSlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { SelectorWithArgs } from \"typings\"\r\n\r\ninterface S3UploadUrl {\r\n\turl: string\r\n\tfields: Record<string, string>\r\n\t/** the time the upload url expires */\r\n\texp?: number\r\n}\r\n\r\nexport interface FileState {\r\n\t// maps sha1 hash to upload URL\r\n\ts3Urls: Record<string, S3UploadUrl>\r\n}\r\n\r\ninterface S3UrlPayload {\r\n\tsha1: string\r\n\turl: string\r\n\tfields: Record<string, string>\r\n}\r\n\r\nconst initialState: FileState = {\r\n\ts3Urls: {},\r\n}\r\n\r\nconst msPerHour = 1000 * 60 * 60\r\nconst msPerWeek = msPerHour * 24 * 7\r\n\r\n/**\r\n * Stores the auth state of the app (tokens, and whether user is logged in or not)\r\n */\r\nexport const fileSlice = createSlice({\r\n\tname: \"file\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetUploadUrl: (state, action: PayloadAction<S3UrlPayload>) => {\r\n\t\t\tconst { url, fields, sha1 } = action.payload\r\n\t\t\tconst today = new Date()\r\n\t\t\tconst weekFromToday = new Date(today.getTime() + msPerWeek)\r\n\r\n\t\t\tstate.s3Urls[sha1] = {\r\n\t\t\t\turl,\r\n\t\t\t\tfields,\r\n\t\t\t\texp: weekFromToday.getTime(),\r\n\t\t\t}\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setUploadUrl } = fileSlice.actions\r\n\r\nexport const selectUploadUrl: SelectorWithArgs<string, S3UploadUrl> = (sha1: string) => (state) => {\r\n\tconst url = state.fileReducer.s3Urls[sha1]\r\n\tif (!url) {\r\n\t\treturn undefined\r\n\t}\r\n\r\n\tconst today = new Date().getTime()\r\n\tconst expiringWithinAnHour = (url.exp ?? today) - today < msPerHour\r\n\tif (expiringWithinAnHour) return undefined\r\n\r\n\treturn url\r\n}\r\n\r\nexport const fileReducer: Reducer<FileState> = fileSlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { MapStyle } from \"../../enums\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport interface MapState {\r\n\tmapStyle: MapStyle\r\n\t// This setting controls whether the map should show permanent tooltips of each issue's name\r\n\tshowTooltips: boolean\r\n\tcenterMapToProject: boolean\r\n}\r\n\r\nconst initialState: MapState = {\r\n\t// TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed\r\n\tmapStyle: import.meta.env.DEV ? MapStyle.SATELLITE : MapStyle.SATELLITE,\r\n\tshowTooltips: false,\r\n\tcenterMapToProject: false,\r\n}\r\n\r\n/**\r\n * Stores map settings and current location\r\n */\r\nexport const mapSlice = createSlice({\r\n\tname: \"map\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetMapStyle: (state, action: PayloadAction<MapStyle>) => {\r\n\t\t\tstate.mapStyle = action.payload\r\n\t\t},\r\n\t\tsetShowTooltips: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.showTooltips = action.payload\r\n\t\t},\r\n\t\tsetCenterMapToProject: (state, action: { payload: boolean }) => {\r\n\t\t\tstate.centerMapToProject = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setMapStyle, setShowTooltips, setCenterMapToProject } = mapSlice.actions\r\n\r\nexport const selectMapStyle = (state: RootState) => state.mapReducer.mapStyle\r\nexport const selectShowTooltips = (state: RootState) => state.mapReducer.showTooltips\r\nexport const selectCenterMapToProject = (state: RootState) => state.mapReducer.centerMapToProject\r\n\r\nexport const mapReducer: Reducer<MapState> = mapSlice.reducer\r\n","import { Reducer, createSlice } from \"@reduxjs/toolkit\"\r\nimport { Organization } from \"typings/models/organizations\"\r\nimport { Selector, SelectorWithArgs } from \"typings/store\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport interface OrganizationState {\r\n\torganizations: Record<number, Organization>\r\n\tactiveOrganizationId: number | null\r\n}\r\n\r\nconst initialState: OrganizationState = {\r\n\torganizations: {},\r\n\tactiveOrganizationId: null,\r\n}\r\n\r\nexport const organizationSlice = createSlice({\r\n\tname: \"organizations\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetOrganizations: (state, action: { payload: Organization[] }) => {\r\n\t\t\tfor (const org of action.payload) {\r\n\t\t\t\tstate.organizations[org.id] = org\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetActiveOrganizationId: (state, action: { payload: number }) => {\r\n\t\t\tstate.activeOrganizationId = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setOrganizations, setActiveOrganizationId } = organizationSlice.actions\r\n\r\nexport const selectActiveOrganizationId: Selector<number | null> = (state: RootState) => {\r\n\treturn state.organizationReducer.activeOrganizationId\r\n}\r\nexport const selectOrganizations: Selector<Organization[]> = (state: RootState) => {\r\n\treturn Object.values(state.organizationReducer.organizations)\r\n}\r\n\r\nexport const selectActiveOrganization: Selector<Organization | null> = (state: RootState) => {\r\n\tconst id = selectActiveOrganizationId(state)\r\n\tif (!id) {\r\n\t\treturn null\r\n\t}\r\n\tconst organization = state.organizationReducer.organizations[id]\r\n\tif (!organization) {\r\n\t\treturn null\r\n\t}\r\n\treturn organization\r\n}\r\n\r\nexport const selectOrganization: SelectorWithArgs<number, Organization | undefined> =\r\n\t(id: number) => (state: RootState) => {\r\n\t\treturn state.organizationReducer.organizations[id]\r\n\t}\r\n\r\nexport const organizationReducer: Reducer<OrganizationState> = organizationSlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport type { FullOfflineAction } from \"../store\"\r\nimport type { RequestDetails } from \"../../sdk\"\r\nimport { v4 as uuidv4 } from \"uuid\"\r\nimport { SDKRequest } from \"../../sdk\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport const createOfflineAction = (request: SDKRequest, baseUrl: string): FullOfflineAction => {\r\n\tconst requestWithUuid = request.uuid ? (request as RequestDetails) : { ...request, uuid: uuidv4() }\r\n\treturn {\r\n\t\tpayload: requestWithUuid,\r\n\t\ttype: \"\",\r\n\t\tmeta: {\r\n\t\t\toffline: {\r\n\t\t\t\teffect: {\r\n\t\t\t\t\ttimestamp: new Date().toISOString(),\r\n\t\t\t\t\trequest: requestWithUuid,\r\n\t\t\t\t\tBASE_URL: baseUrl,\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t},\r\n\t}\r\n}\r\n\r\nexport interface OutboxState {\r\n\t/** A list of requests marked for deletion. Once the offline slice encounters one of these, */\r\n\tdeletedRequests: string[]\r\n\t/** The timestamp of the last retry of an outgoing request. (Number of milliseconds since the epoch.) */\r\n\tlatestRetryTime: number\r\n}\r\n\r\nconst initialState: OutboxState = {\r\n\tdeletedRequests: [],\r\n\tlatestRetryTime: 0,\r\n}\r\n\r\n/**\r\n * This slice primarily exists as an interface to enqueue API requests to the redux-offline slice. Any dispatched action\r\n * with an `offline` field in its metadata will be handled by redux-offline. This slice is just a sensible place to\r\n * \"dump\" no-op actions for enqueueing requests to the outbox. At the same time, we can use this slice to keep track of\r\n * requests that have been marked for deletion, so that we can skip them instead of sending the request.\r\n */\r\nexport const outboxSlice = createSlice({\r\n\tname: \"outbox\",\r\n\tinitialState: initialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\t// enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox\r\n\t\t// Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store\r\n\t\t// Then this reducer enqueueRequest() is responsible for adding the actual request data to the outbox\r\n\t\tenqueueRequest: {\r\n\t\t\treducer: (state, _action: PayloadAction<RequestDetails>) => {\r\n\t\t\t\treturn state\r\n\t\t\t},\r\n\t\t\tprepare: (payload: SDKRequest & { BASE_URL: string }): FullOfflineAction => {\r\n\t\t\t\tconsole.debug(\"Preparing to enqueue request\", payload)\r\n\t\t\t\tconst { BASE_URL, ...rest } = payload\r\n\t\t\t\treturn createOfflineAction(rest, BASE_URL)\r\n\t\t\t},\r\n\t\t},\r\n\t\tmarkForDeletion(state, action: PayloadAction<string>) {\r\n\t\t\tstate.deletedRequests.push(action.payload)\r\n\t\t},\r\n\t\tmarkAsDeleted(state, action: PayloadAction<string>) {\r\n\t\t\tconst index = state.deletedRequests.indexOf(action.payload)\r\n\t\t\tif (index !== -1) state.deletedRequests.splice(index, 1)\r\n\t\t},\r\n\t\t_setLatestRetryTime: (state, action: PayloadAction<number>) => {\r\n\t\t\tstate.latestRetryTime = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const selectDeletedRequests = (state: RootState) => state.outboxReducer.deletedRequests\r\nexport const selectLatestRetryTime = (state: RootState) => state.outboxReducer.latestRetryTime\r\n\r\nexport const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions\r\nexport const outboxReducer: Reducer<OutboxState> = outboxSlice.reducer\r\n","import { Reducer, createSlice } from \"@reduxjs/toolkit\"\r\n\r\nimport { ProjectAccess, RootState, Selector, SelectorWithArgs, User } from \"../../typings\"\r\nimport { onlyUniqueOfflineIds } from \"../../utils\"\r\n\r\nexport interface ProjectAccessState {\r\n\tprojectAccesses: Record<string, ProjectAccess>\r\n}\r\n\r\nconst initialState: ProjectAccessState = {\r\n\tprojectAccesses: {},\r\n}\r\n\r\nexport const projectAccessSlice = createSlice({\r\n\tname: \"projectAccess\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetProjectAccesses: (state, action: { payload: ProjectAccess[] }) => {\r\n\t\t\tif (!Array.isArray(action.payload)) throw new Error(\"Expected an array of ProjectAccess\")\r\n\t\t\tif (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {\r\n\t\t\t\tthrow new Error(\"Tried to use setProjectAccesses reducer with duplicate ID's\")\r\n\t\t\t}\r\n\t\t\tconst projectAccesses: Record<string, ProjectAccess> = {}\r\n\t\t\tfor (const projectAccess of action.payload) {\r\n\t\t\t\tprojectAccesses[projectAccess.offline_id] = projectAccess\r\n\t\t\t}\r\n\t\t\tstate.projectAccesses = projectAccesses\r\n\t\t},\r\n\t\tupdateProjectAccess: (state, action: { payload: ProjectAccess }) => {\r\n\t\t\tif (action.payload.offline_id in state.projectAccesses) {\r\n\t\t\t\tstate.projectAccesses[action.payload.offline_id] = action.payload\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Tried to update project access with ID that doesn't exist: ${action.payload.offline_id}`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveProjectAccess: (state, action: { payload: ProjectAccess }) => {\r\n\t\t\tif (action.payload.offline_id in state.projectAccesses) {\r\n\t\t\t\tdelete state.projectAccesses[action.payload.offline_id]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Tried to remove project access with ID that doesn't exist: ${action.payload.offline_id}`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveProjectAccessesOfProject: (state, action: { payload: number }) => {\r\n\t\t\tfor (const projectAccess of Object.values(state.projectAccesses)) {\r\n\t\t\t\tif (projectAccess.project === action.payload) {\r\n\t\t\t\t\tdelete state.projectAccesses[projectAccess.offline_id]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setProjectAccesses, updateProjectAccess, removeProjectAccess, removeProjectAccessesOfProject } =\r\n\tprojectAccessSlice.actions\r\n\r\nexport const selectProjectAccesses = (state: RootState) => {\r\n\treturn state.projectAccessReducer.projectAccesses\r\n}\r\n\r\nexport const selectProjectAccess: SelectorWithArgs<string, ProjectAccess> =\r\n\t(projectAccessId: string) => (state: RootState) => {\r\n\t\treturn state.projectAccessReducer.projectAccesses[projectAccessId]\r\n\t}\r\n\r\nexport const selectActiveProjectAccess: Selector<ProjectAccess | null> = (state: RootState) => {\r\n\tconst currentUser = state.userReducer.currentUser\r\n\tconst activeProjectId = state.projectReducer.activeProjectId\r\n\treturn (\r\n\t\tObject.values(state.projectAccessReducer.projectAccesses).find((projectAccess) => {\r\n\t\t\treturn projectAccess.user === currentUser.id && projectAccess.project === activeProjectId\r\n\t\t}) ?? null\r\n\t)\r\n}\r\n\r\nexport const selectProjectAccessForUser: SelectorWithArgs<User, ProjectAccess | undefined> =\r\n\t(user: User) => (state: RootState) => {\r\n\t\treturn Object.values(state.projectAccessReducer.projectAccesses).find(\r\n\t\t\t(projectAccess) => projectAccess.user === user.id,\r\n\t\t)\r\n\t}\r\n\r\nexport const selectProjectAccessUserMapping: Selector<Record<string, ProjectAccess>> = (state: RootState) => {\r\n\tconst projectAccesses: Record<string, ProjectAccess> = {}\r\n\tfor (const projectAccess of Object.values(state.projectAccessReducer.projectAccesses)) {\r\n\t\tprojectAccesses[projectAccess.user] = projectAccess\r\n\t}\r\n\treturn projectAccesses\r\n}\r\n\r\nexport const projectAccessReducer: Reducer<ProjectAccessState> = projectAccessSlice.reducer\r\n","import { OfflineModel } from \"./base\"\r\n\r\nexport interface ProjectAccess extends OfflineModel {\r\n\tuser: number\r\n\tproject: number\r\n\taccess_level: number\r\n}\r\n\r\nexport enum ProjectAccessLevel {\r\n\tBASIC = 0,\r\n\tADMIN = 2,\r\n}\r\n\r\nexport interface OrganizationAccess extends OfflineModel {\r\n\tuser: number\r\n\torganization: number\r\n\taccess_level: number\r\n}\r\n\r\n// TODO: Move\r\nexport enum OrganizationAccessLevel {\r\n\tBASIC = 0,\r\n\tADMIN = 2,\r\n}\r\n","import { FileObject, Model } from \"./base\"\r\nimport L from \"leaflet\"\r\n\r\n// TODO: Move\r\nexport enum ProjectType {\r\n\tPERSONAL = 0,\r\n\tORGANIZATION = 2,\r\n}\r\n\r\nexport interface Project extends Model {\r\n\tid: number\r\n\tname: string\r\n\towner_organization: number | null\r\n\towner_user: number | null\r\n\tbounds: [L.LatLngTuple, L.LatLngTuple] | undefined\r\n}\r\n\r\nexport interface ProjectFile extends Model, FileObject {\r\n\toffline_id: string\r\n\tname: string\r\n\tz_index: number\r\n\tbounds?: [L.LatLngTuple, L.LatLngTuple]\r\n\tproject: number\r\n\t// This is generated as needed in order to have a local object URL to use when a project file is created but hasn't\r\n\t// been accepted by the backend yet, thus giving it a cloud URL.\r\n\t// TODO: I don't think this is necessary. Can't we just piggyback on the `file` field, overwriting it with the cloud\r\n\t// URL as soon as possible?\r\n\tobjectURL?: string\r\n}\r\n\r\nexport type ProjectPayload = Omit<Project, \"id\" | \"file\" | \"fileBlob\">\r\n","import { RegistrationPayload } from \"./users\"\r\nimport { OfflineModel } from \"./base\"\r\n\r\nexport type EmailVerificationPayload = undefined | RegistrationPayload | Omit<RegistrationPayload, \"username\" | \"email\">\r\n\r\nexport interface EmailVerificationReturn {\r\n\tusername?: string\r\n\tproject?: number\r\n}\r\n\r\nexport enum VerificationCodeType {\r\n\tUSER_REGISTRATION = 0,\r\n\tAPPLICATION_INVITE = 2,\r\n\tPROJECT_INVITE = 4,\r\n\tORGANIZATION_INVITE = 6,\r\n\tADD_EMAIL_DOMAIN = 8,\r\n\tRESET_PASSWORD = 10,\r\n}\r\n\r\nexport interface VerificationCode extends OfflineModel {\r\n\tverification_code: string\r\n\tverification_type: VerificationCodeType\r\n\torganization?: number\r\n\tproject?: number\r\n\tuser?: number\r\n}\r\n","import { Reducer, createSlice } from \"@reduxjs/toolkit\"\r\n\r\nimport { Project, ProjectType, RootState, Selector } from \"../../typings\"\r\n\r\nexport interface ProjectState {\r\n\tprojects: Record<number, Project>\r\n\tactiveProjectId: number | null\r\n\trecentProjectIds: number[]\r\n\trecentSearchableQueries: string[]\r\n\t// TODO: This is not really a global state that needs to be persisted\r\n\tcreateProjectType: ProjectType\r\n}\r\n\r\nconst initialState: ProjectState = {\r\n\tprojects: {},\r\n\tactiveProjectId: null,\r\n\trecentProjectIds: [],\r\n\trecentSearchableQueries: [],\r\n\tcreateProjectType: ProjectType.PERSONAL,\r\n}\r\n\r\nexport const projectSlice = createSlice({\r\n\tname: \"projects\",\r\n\tinitialState,\r\n\treducers: {\r\n\t\tsetProjects: (state, action: { payload: Project[] }) => {\r\n\t\t\tconst projectsMap: Record<number, Project> = {}\r\n\t\t\taction.payload.forEach((project) => {\r\n\t\t\t\tprojectsMap[project.id] = project\r\n\t\t\t})\r\n\t\t\tstate.projects = projectsMap\r\n\r\n\t\t\tif (state.recentProjectIds.length === 0) {\r\n\t\t\t\tstate.recentProjectIds = action.payload.map((project) => project.id)\r\n\t\t\t} else {\r\n\t\t\t\tstate.recentProjectIds.unshift(\r\n\t\t\t\t\t...action.payload.map((project) => project.id).filter((id) => !state.recentProjectIds.includes(id)),\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetActiveProjectId: (state, action: { payload: number | null }) => {\r\n\t\t\tstate.activeProjectId = action.payload\r\n\t\t\tif (action.payload !== null) {\r\n\t\t\t\tstate.recentProjectIds = state.recentProjectIds.filter((id) => id !== action.payload)\r\n\t\t\t\tstate.recentProjectIds.push(action.payload)\r\n\t\t\t}\r\n\t\t},\r\n\t\tupdateOrCreateProject: (state, action: { payload: Project }) => {\r\n\t\t\tstate.projects[action.payload.id] = action.payload\r\n\t\t},\r\n\t\t// Takes a list of Projects and updates existing ones to match the payload, or adds them\r\n\t\t// to the store if they are not already present\r\n\t\tupdateOrCreateProjects: (state, action: { payload: Project[] }) => {\r\n\t\t\taction.payload.forEach((project) => {\r\n\t\t\t\tstate.projects[project.id] = project\r\n\t\t\t})\r\n\t\t},\r\n\t\tsetCreateProjectType: (state, action: { payload: ProjectType }) => {\r\n\t\t\tstate.createProjectType = action.payload\r\n\t\t},\r\n\t\tdeleteProject: (state, action: { payload: Project }) => {\r\n\t\t\tdelete state.projects[action.payload.id]\r\n\t\t\tstate.recentProjectIds = state.recentProjectIds.filter((id) => id !== action.payload.id)\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\tsetProjects,\r\n\tupdateOrCreateProject,\r\n\tupdateOrCreateProjects: addOrReplaceProjects,\r\n\tsetActiveProjectId,\r\n\tsetCreateProjectType,\r\n\tdeleteProject,\r\n} = projectSlice.actions\r\n\r\nexport const selectProjects: Selector<Record<number, Project>> = (state: RootState) => state.projectReducer.projects\r\nexport const selectActiveProjectId = (state: RootState): number | null => state.projectReducer.activeProjectId\r\nexport const selectActiveProject = (state: RootState): Project | null => {\r\n\tconst activeProjectId = selectActiveProjectId(state)\r\n\tif (!activeProjectId) {\r\n\t\treturn null\r\n\t}\r\n\treturn state.projectReducer.projects[activeProjectId] ?? null\r\n}\r\nexport const selectRecentProjects = (state: RootState): number[] => {\r\n\treturn state.projectReducer.recentProjectIds\r\n}\r\nexport const selectCreateProjectType = (state: RootState): ProjectType => state.projectReducer.createProjectType\r\n\r\nexport const projectReducer: Reducer<ProjectState> = projectSlice.reducer\r\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\r\n\r\nimport L from \"leaflet\"\r\nimport { ProjectFile, RootState, Selector } from \"../../typings\"\r\nimport { selectActiveProjectId } from \"./projectSlice.ts\"\r\n\r\nexport interface ProjectFileState {\r\n\tprojectFiles: Record<string, ProjectFile>\r\n\tactiveProjectFileId: string | null\r\n\t/**\r\n\t * State variable which is set true by web client to mark that the activeProjectFile is a new one that was just\r\n\t * imported and not a pre-existing one which is being edited\r\n\t */\r\n\tisImportingProjectFile: boolean\r\n\t// undefined means visible (visible by default)\r\n\tenabledProjectFiles: Record<string, boolean | undefined>\r\n}\r\n\r\nconst initialState: ProjectFileState = {\r\n\tprojectFiles: {},\r\n\tactiveProjectFileId: null,\r\n\tisImportingProjectFile: false,\r\n\tenabledProjectFiles: {},\r\n}\r\n\r\nexport const projectFileSlice = createSlice({\r\n\tname: \"projectFiles\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\taddOrReplaceProjectFiles: (state, action: { payload: ProjectFile[] }) => {\r\n\t\t\tfor (let fileObj of action.payload) {\r\n\t\t\t\tlet file = fileObj.file\r\n\t\t\t\tif (file.includes(\"+\")) {\r\n\t\t\t\t\tconsole.warn(\"Attempting to apply fix for image URL with '+' character:\", file)\r\n\t\t\t\t\t// We have a src such as this:\r\n\t\t\t\t\t// https://example.com/my-svg.svg+xml\r\n\t\t\t\t\t// Or:\r\n\t\t\t\t\t// blob://.../my-svg.svg+xml\r\n\t\t\t\t\t// We want just the `my-svg.svg+xml` part.\r\n\t\t\t\t\tconst parts = file.split(\"/\")\r\n\t\t\t\t\tif (parts.length < 2) {\r\n\t\t\t\t\t\tthrow new Error(\"Invalid URL: \" + file)\r\n\t\t\t\t\t}\r\n\t\t\t\t\tconst lastPart = encodeURIComponent(parts[parts.length - 1]!)\r\n\t\t\t\t\t// Reconstruct the URL with the fixed last part.\r\n\t\t\t\t\tfile = parts.slice(0, -1).join(\"/\") + \"/\" + lastPart\r\n\t\t\t\t\tconsole.warn(\"Fixed URL:\", file)\r\n\t\t\t\t\tfileObj = { ...fileObj, file }\r\n\t\t\t\t}\r\n\t\t\t\tstate.projectFiles[fileObj.offline_id] = fileObj\r\n\t\t\t}\r\n\t\t},\r\n\t\taddOrReplaceProjectFile: (state, action: { payload: ProjectFile }) => {\r\n\t\t\tif (!action.payload.project) {\r\n\t\t\t\tthrow new Error(\"ProjectFile has no project. A project must be set before storing.\")\r\n\t\t\t}\r\n\t\t\tstate.projectFiles[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\tsetProjectFileVisible: (state, action: { payload: { fileId: string; visible: boolean } }) => {\r\n\t\t\tstate.enabledProjectFiles[action.payload.fileId] = action.payload.visible\r\n\t\t},\r\n\t\tsetIsImportingProjectFile: (state, action: { payload: boolean }) => {\r\n\t\t\tstate.isImportingProjectFile = action.payload\r\n\t\t},\r\n\t\tsaveActiveProjectFileBounds: (state, action: { payload: [L.LatLngTuple, L.LatLngTuple] }) => {\r\n\t\t\tconst activeProjectFileId = state.activeProjectFileId\r\n\t\t\tif (!activeProjectFileId) {\r\n\t\t\t\tthrow new Error(\"Tried to save bounds for active project file, but no active project file was set.\")\r\n\t\t\t}\r\n\t\t\tif (!state.projectFiles[activeProjectFileId]) {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Tried to save bounds for active project file, but project file with ID ${activeProjectFileId} \r\n\t\t\t\t\tdoesn't exist.`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t\tstate.projectFiles[activeProjectFileId]!.bounds = action.payload\r\n\t\t},\r\n\t\t// TODO: Move to MapContext. Should not be persisted.\r\n\t\tsetActiveProjectFileId: (state, action: { payload: string | null }) => {\r\n\t\t\tstate.activeProjectFileId = action.payload\r\n\t\t\tif (action.payload) {\r\n\t\t\t\tstate.enabledProjectFiles[action.payload] = true\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveProjectFile: (state, action: { payload: string }) => {\r\n\t\t\tdelete state.projectFiles[action.payload]\r\n\t\t\tdelete state.enabledProjectFiles[action.payload]\r\n\t\t},\r\n\t\tremoveProjectFilesOfProject: (state, action: { payload: number }) => {\r\n\t\t\tconst filesToDelete = Object.values(state.projectFiles).filter((file) => file.project === action.payload)\r\n\t\t\tfor (const file of filesToDelete) {\r\n\t\t\t\tdelete state.projectFiles[file.offline_id]\r\n\t\t\t\tdelete state.enabledProjectFiles[file.offline_id]\r\n\t\t\t}\r\n\t\t},\r\n\t\tresetProjectFileObjectUrls: (state, ..._args: []) => {\r\n\t\t\tfor (const key in state.projectFiles) {\r\n\t\t\t\tdelete state.projectFiles[key]!.objectURL\r\n\t\t\t}\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\taddOrReplaceProjectFiles,\r\n\taddOrReplaceProjectFile,\r\n\tsetProjectFileVisible,\r\n\tsetIsImportingProjectFile,\r\n\tsetActiveProjectFileId,\r\n\tsaveActiveProjectFileBounds,\r\n\tremoveProjectFile,\r\n\tremoveProjectFilesOfProject,\r\n\tresetProjectFileObjectUrls,\r\n} = projectFileSlice.actions\r\n\r\nexport const selectEnabledProjectFiles = (state: RootState) => state.projectFileReducer.enabledProjectFiles\r\n\r\nexport const selectProjectFileVisibility: Selector<Record<string, boolean>> = createSelector(\r\n\t[selectEnabledProjectFiles],\r\n\t(enabledProjectFiles) => {\r\n\t\tconst ret: Record<string, boolean> = {}\r\n\t\tfor (const [fileId, enabled] of Object.entries(enabledProjectFiles)) {\r\n\t\t\tret[fileId] = enabled === true || enabled === undefined\r\n\t\t}\r\n\t\treturn ret\r\n\t},\r\n)\r\n\r\nexport const selectEnabledProjectFileMapping = (state: RootState) => state.projectFileReducer.projectFiles\r\n\r\nexport const selectProjectFiles = createSelector(\r\n\t[selectEnabledProjectFileMapping, selectActiveProjectId],\r\n\t(mapping, activeProjectId) => {\r\n\t\treturn Object.values(mapping)\r\n\t\t\t.filter((file) => file.project === activeProjectId)\r\n\t\t\t.sort((a, b) => a.z_index - b.z_index)\r\n\t},\r\n)\r\n\r\nexport const selectActiveProjectFileId: Selector<string | null> = (state: RootState) =>\r\n\tstate.projectFileReducer.activeProjectFileId\r\n\r\nexport const selectIsImportingProjectFile: Selector<boolean> = (state: RootState) =>\r\n\tstate.projectFileReducer.isImportingProjectFile\r\n\r\nexport const projectFileReducer: Reducer<ProjectFileState> = projectFileSlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport interface RehydratedState {\r\n\tisRehydrated: boolean\r\n}\r\n\r\nconst initialState: RehydratedState = {\r\n\tisRehydrated: false,\r\n}\r\n\r\n// rehydratedSlice is used to indicate when the Redux store has finished rehydrating its state from localForage\r\n// Once finished, the app renders, which prevents the annoying login screen flickering issue\r\nexport const rehydratedSlice = createSlice({\r\n\tname: \"rehydrated\",\r\n\tinitialState,\r\n\t// The `reducers` field lets us define reducers and generate associated actions\r\n\treducers: {\r\n\t\tsetRehydrated: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.isRehydrated = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\n// export const { setRehydrated } = rehydratedSlice.actions\r\n\r\n// The function below is called a selector and allows us to select a value from\r\n// the state. Selectors can also be defined inline where they're used instead of\r\n// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`\r\nexport const selectRehydrated = (state: RootState) => state.rehydratedReducer.isRehydrated\r\n\r\nexport const rehydratedReducer: Reducer<RehydratedState> = rehydratedSlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { Appearance, RootState } from \"../../typings\"\r\n\r\nexport interface SettingState {\r\n\tuseIssueTemplate: boolean\r\n\tplacementMode: boolean\r\n\tenableClustering: boolean\r\n\tsvgLayout: boolean\r\n\texpandedSections: Record<string, boolean>\r\n\tappearance: Appearance\r\n}\r\n\r\nconst initialState: SettingState = {\r\n\tuseIssueTemplate: false,\r\n\tplacementMode: false,\r\n\tenableClustering: true,\r\n\tsvgLayout: false,\r\n\texpandedSections: {\r\n\t\tIssues: true,\r\n\t\t\"Map Layers\": false,\r\n\t\tComponents: false,\r\n\t\tExperimental: false,\r\n\t},\r\n\tappearance: \"dark\",\r\n}\r\n\r\nexport const settingSlice = createSlice({\r\n\tname: \"settings\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetEnableDuplicateIssues: (state, action: PayloadAction<boolean>) => {\r\n\t\t\t// The logic here is the same as in workspaceSlice.ts. I want to create\r\n\t\t\t// a way for the store to know the state of a clicked button, and\r\n\t\t\t// in the future maybe other features of the application.\r\n\t\t\tstate.useIssueTemplate = action.payload\r\n\t\t},\r\n\t\tsetEnablePlacementMode: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.placementMode = action.payload\r\n\t\t},\r\n\t\tsetEnableSvgLayout: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.svgLayout = action.payload\r\n\t\t},\r\n\t\tsetSectionExpanded: (state, action: PayloadAction<Record<string, boolean>>) => {\r\n\t\t\tObject.assign(state.expandedSections, action.payload)\r\n\t\t},\r\n\t\tsetEnableClustering: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.enableClustering = action.payload\r\n\t\t},\r\n\t\tsetAppearance: (state, action: PayloadAction<\"dark\" | \"light\">) => {\r\n\t\t\tstate.appearance = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\tsetEnableDuplicateIssues,\r\n\tsetEnablePlacementMode,\r\n\tsetSectionExpanded,\r\n\tsetEnableClustering,\r\n\tsetAppearance,\r\n} = settingSlice.actions\r\n\r\nexport const selectEnablePlacementMode = (state: RootState) => state.settingReducer.placementMode\r\nexport const selectEnableDuplicateIssues = (state: RootState) => state.settingReducer.useIssueTemplate\r\nexport const selectEnableSvgLayout = (state: RootState) => state.settingReducer.svgLayout\r\nexport const selectExpandedSections = (state: RootState) => state.settingReducer.expandedSections\r\nexport const selectEnableClustering = (state: RootState) => state.settingReducer.enableClustering\r\nexport const selectAppearance = (state: RootState) => state.settingReducer.appearance\r\nexport const settingReducer: Reducer<SettingState> = settingSlice.reducer\r\n","import { createSelector, createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\n\r\nimport {\r\n\tCachedUserForm,\r\n\tUserForm,\r\n\tUserFormRevision,\r\n\tUserFormSubmission,\r\n\tUserFormSubmissionAttachment,\r\n} from \"typings/models/forms\"\r\nimport { SearchArgs } from \"typings/search\"\r\nimport { Selector, SelectorWithArgs } from \"typings/store\"\r\nimport { shallowEqual } from \"react-redux\"\r\nimport { restructureCreateSelectorWithArgs } from \"utils/utils\"\r\nimport { RootState, Stored, Submitted } from \"../../typings\"\r\n\r\nconst LATEST_REVISION_CACHE: Record<string, UserFormRevision | null> = {}\r\n\r\nfunction considerCachingRevision(revision?: UserFormRevision | null, formId?: string, preferPending = false) {\r\n\tif (!revision) {\r\n\t\tif (!formId) {\r\n\t\t\tthrow new Error(\"If revision is null, formId is required.\")\r\n\t\t}\r\n\t\tconst currentLatestRevision = getLatestRevisionFromCache(formId)\r\n\t\tif (currentLatestRevision) return\r\n\t\tLATEST_REVISION_CACHE[formId] = null\r\n\t\treturn\r\n\t}\r\n\tif (revision.revision === \"Pending\") {\r\n\t\tif (preferPending) {\r\n\t\t\tLATEST_REVISION_CACHE[revision.form] = revision\r\n\t\t}\r\n\t\treturn\r\n\t}\r\n\tconst cachedRevision = LATEST_REVISION_CACHE[revision.form]?.revision\r\n\tif (revision.revision > (typeof cachedRevision === \"number\" ? cachedRevision : -1)) {\r\n\t\tLATEST_REVISION_CACHE[revision.form] = revision\r\n\t}\r\n}\r\n\r\nfunction getLatestRevisionFromCache(formId: string): UserFormRevision | null | undefined {\r\n\treturn LATEST_REVISION_CACHE[formId]\r\n}\r\n\r\nexport interface UserFormState {\r\n\tuserForms: Record<string, Stored<UserForm>>\r\n\tsubmissions: Record<string, UserFormSubmission>\r\n\tsubmissionAttachments: Record<UserFormSubmission[\"offline_id\"], UserFormSubmissionAttachment[]>\r\n\trevisions: Record<string, UserFormRevision>\r\n}\r\n\r\nconst initialState: UserFormState = {\r\n\tuserForms: {},\r\n\trevisions: {},\r\n\tsubmissions: {},\r\n\tsubmissionAttachments: {},\r\n}\r\n\r\nexport const userFormSlice = createSlice({\r\n\tname: \"userForms\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetUserForms: (state, action: { payload: Submitted<UserForm>[] }) => {\r\n\t\t\tstate.userForms = {}\r\n\t\t\taction.payload.forEach((userForm) => {\r\n\t\t\t\tstate.userForms[userForm.offline_id] = userForm\r\n\t\t\t})\r\n\t\t},\r\n\t\taddUserForm: (state, action: { payload: Submitted<UserForm> }) => {\r\n\t\t\tstate.userForms[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\taddUserForms: (state, action: { payload: Submitted<UserForm>[] }) => {\r\n\t\t\taction.payload.forEach((userForm) => {\r\n\t\t\t\tstate.userForms[userForm.offline_id] = userForm\r\n\t\t\t})\r\n\t\t},\r\n\t\taddUserFormRevisions: (state, action: { payload: UserFormRevision[] }) => {\r\n\t\t\taction.payload.forEach((userFormRevision) => {\r\n\t\t\t\tstate.revisions[userFormRevision.offline_id] = userFormRevision\r\n\t\t\t\tconsiderCachingRevision(userFormRevision)\r\n\t\t\t})\r\n\t\t},\r\n\t\taddUserFormRevision: (state, action: PayloadAction<UserFormRevision>) => {\r\n\t\t\tstate.revisions[action.payload.offline_id] = action.payload\r\n\t\t\tconsiderCachingRevision(action.payload)\r\n\t\t},\r\n\t\tdeleteUserFormRevision: (state, action: PayloadAction<string>) => {\r\n\t\t\tdelete state.revisions[action.payload]\r\n\t\t\tdelete LATEST_REVISION_CACHE[action.payload]\r\n\t\t},\r\n\t\tdeleteUserFormRevisions: (state, action: { payload: UserFormRevision[] }) => {\r\n\t\t\tfor (const userFormRevision of action.payload) {\r\n\t\t\t\tdelete state.revisions[userFormRevision.offline_id]\r\n\t\t\t\tdelete LATEST_REVISION_CACHE[userFormRevision.offline_id]\r\n\t\t\t}\r\n\t\t},\r\n\t\taddUserFormSubmission: (state, action: { payload: UserFormSubmission }) => {\r\n\t\t\tstate.submissions[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\taddUserFormSubmissionAttachment: (state, action: { payload: UserFormSubmissionAttachment }) => {\r\n\t\t\tconst submissionId = action.payload.submission\r\n\t\t\tconst submissionAttachments = state.submissionAttachments[submissionId]\r\n\t\t\tif (submissionAttachments) {\r\n\t\t\t\tsubmissionAttachments.push(action.payload)\r\n\t\t\t} else {\r\n\t\t\t\tstate.submissionAttachments[submissionId] = [action.payload]\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetUserFormSubmissionAttachments: (state, action: { payload: UserFormSubmissionAttachment[] }) => {\r\n\t\t\tstate.submissionAttachments = {}\r\n\t\t\tfor (const attachment of action.payload) {\r\n\t\t\t\tconst submissionId = attachment.submission\r\n\t\t\t\tconst submissionAttachments = state.submissionAttachments[submissionId]\r\n\t\t\t\tif (submissionAttachments) {\r\n\t\t\t\t\tsubmissionAttachments.push(attachment)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstate.submissionAttachments[submissionId] = [attachment]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\tdeleteUserFormSubmission: (state, action: PayloadAction<string>) => {\r\n\t\t\tdelete state.submissions[action.payload]\r\n\t\t},\r\n\t\tdeleteUserFormSubmissions: (state, action: { payload: UserFormSubmission[] }) => {\r\n\t\t\tfor (const userFormSubmission of action.payload) {\r\n\t\t\t\tdelete state.submissions[userFormSubmission.offline_id]\r\n\t\t\t}\r\n\t\t},\r\n\t\taddUserFormSubmissions: (state, action: { payload: UserFormSubmission[] }) => {\r\n\t\t\tfor (const submission of action.payload) {\r\n\t\t\t\tstate.submissions[submission.offline_id] = submission\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetUserFormSubmissions: (state, action: { payload: UserFormSubmission[] }) => {\r\n\t\t\tstate.submissions = {}\r\n\t\t\taction.payload.forEach((submission) => {\r\n\t\t\t\tstate.submissions[submission.offline_id] = submission\r\n\t\t\t})\r\n\t\t},\r\n\t\tfavoriteForm: (state, action: { payload: { formId: string } }) => {\r\n\t\t\tconst { formId } = action.payload\r\n\t\t\tconst form = state.userForms[formId]\r\n\t\t\tif (!form) {\r\n\t\t\t\tthrow new Error(\"No form exists with the id \" + formId)\r\n\t\t\t}\r\n\t\t\tform.favorite = true\r\n\t\t},\r\n\t\tunfavoriteForm: (state, action: { payload: { formId: string } }) => {\r\n\t\t\tconst { formId } = action.payload\r\n\t\t\tconst form = state.userForms[formId]\r\n\t\t\tif (!form) {\r\n\t\t\t\tthrow new Error(\"No form exists with the id \" + formId)\r\n\t\t\t}\r\n\t\t\tform.favorite = false\r\n\t\t},\r\n\t\tdeleteUserForm: (state, action: { payload: string }) => {\r\n\t\t\tdelete state.userForms[action.payload]\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\taddUserForm,\r\n\taddUserForms,\r\n\taddUserFormRevisions,\r\n\taddUserFormSubmission,\r\n\taddUserFormSubmissions,\r\n\tdeleteUserFormSubmission,\r\n\tdeleteUserFormSubmissions,\r\n\tfavoriteForm,\r\n\tunfavoriteForm,\r\n\tdeleteUserForm,\r\n\tdeleteUserFormRevision,\r\n\tdeleteUserFormRevisions,\r\n\tsetUserFormSubmissions,\r\n\taddUserFormRevision,\r\n\taddUserFormSubmissionAttachment,\r\n\tsetUserFormSubmissionAttachments,\r\n} = userFormSlice.actions\r\n\r\nexport type UserFormSearchArgs = SearchArgs<{\r\n\t/** `undefined` means don't filter by favorite. `boolean` filters forms. */\r\n\tfavorites?: boolean\r\n\t/** organization owner */\r\n\towner_organization?: number\r\n\t/** user owner */\r\n\towner_user?: number\r\n}>\r\n\r\nexport const selectSubmissionAttachments: SelectorWithArgs<string, UserFormSubmissionAttachment[]> =\r\n\t(submissionId: string) => (state: RootState) => {\r\n\t\treturn state.userFormReducer.submissionAttachments[submissionId] || []\r\n\t}\r\n\r\nexport const selectFilteredUserForms: SelectorWithArgs<UserFormSearchArgs, CachedUserForm[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[\r\n\t\t\t\t(state: RootState) => state.userFormReducer.userForms,\r\n\t\t\t\t(state: RootState) => state.userFormReducer.revisions,\r\n\t\t\t\t(_state: RootState, search: UserFormSearchArgs) => search,\r\n\t\t\t],\r\n\t\t\t(userForms, revisions, search) => {\r\n\t\t\t\tconst { searchTerm, maxResults, favorites, owner_organization, owner_user } = search\r\n\r\n\t\t\t\tconst favoriteMatches: CachedUserForm[] = []\r\n\t\t\t\tconst regularMatches: CachedUserForm[] = []\r\n\r\n\t\t\t\tfor (const [userFormId, userForm] of Object.entries(userForms)) {\r\n\t\t\t\t\t// if filtering by favorites, skip forms with the wrong favorite status\r\n\t\t\t\t\tif (favorites !== undefined && userForm.favorite != favorites) continue\r\n\r\n\t\t\t\t\t// if filtering by organizations, skip forms with the wrong organization\r\n\t\t\t\t\tif (Number.isInteger(owner_organization) && owner_organization !== userForm.owner_organization) {\r\n\t\t\t\t\t\tcontinue\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// if filtering by owners, skip forms with the wrong owner\r\n\t\t\t\t\tif (Number.isInteger(owner_user) && owner_user !== userForm.owner_user) continue\r\n\r\n\t\t\t\t\t// find the latest revision for this form (note: expensive)\r\n\t\t\t\t\tconst latestRevision = _selectLatestFormRevision(revisions, userFormId)\r\n\r\n\t\t\t\t\tif (latestRevision.title.toLowerCase().includes(searchTerm.toLowerCase())) {\r\n\t\t\t\t\t\tif (userForm.favorite) {\r\n\t\t\t\t\t\t\tfavoriteMatches.push({ ...userForm, latestRevision: latestRevision })\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tregularMatches.push({ ...userForm, latestRevision: latestRevision })\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// if we've found enough matches, stop searching\r\n\t\t\t\t\t// only count favorites as favorites are displayed first\r\n\t\t\t\t\tif (favoriteMatches.length >= maxResults) {\r\n\t\t\t\t\t\tbreak\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst maxRegularMatches = maxResults - favoriteMatches.length\r\n\r\n\t\t\t\treturn [...favoriteMatches, ...regularMatches.slice(0, maxRegularMatches)]\r\n\t\t\t},\r\n\t\t\t// as the argument is an object, we check the first level of properties for equality\r\n\t\t\t{ memoizeOptions: { equalityCheck: shallowEqual } },\r\n\t\t),\r\n\t)\r\n\r\nexport const selectFormRevision: SelectorWithArgs<string, UserFormRevision> =\r\n\t(revisionId: string) => (state: RootState) => {\r\n\t\treturn state.userFormReducer.revisions[revisionId]\r\n\t}\r\n\r\n// takes user form state revisions instead of the whole state as an argument\r\nconst _selectLatestFormRevision = (revisions: UserFormState[\"revisions\"], formId: string): UserFormRevision => {\r\n\tlet ret: UserFormRevision | null = null\r\n\r\n\tfor (const candidate of Object.values(revisions)) {\r\n\t\tif (candidate.form === formId && (!ret || ret.revision < candidate.revision)) {\r\n\t\t\tret = candidate\r\n\t\t}\r\n\t}\r\n\r\n\tif (!ret) {\r\n\t\tthrow new Error(\"No revision found for form \" + formId)\r\n\t}\r\n\r\n\treturn ret\r\n}\r\n\r\nexport const selectLatestFormRevision: SelectorWithArgs<string, UserFormRevision> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[(state: RootState) => state.userFormReducer.revisions, (_state: RootState, formId: string) => formId],\r\n\t\t(revisions, formId) => {\r\n\t\t\tif (!formId) {\r\n\t\t\t\tthrow new Error(\"formId is required\")\r\n\t\t\t}\r\n\r\n\t\t\treturn _selectLatestFormRevision(revisions, formId)\r\n\t\t},\r\n\t),\r\n)\r\n\r\nexport const selectUserForm: SelectorWithArgs<string, Stored<UserForm>> = (formId: string) => (state: RootState) => {\r\n\treturn state.userFormReducer.userForms[formId]\r\n}\r\n\r\nconst selectSubmissionMapping = (state: RootState) => state.userFormReducer.submissions\r\nconst selectSubmissions = createSelector([selectSubmissionMapping], (submissions) => Object.values(submissions))\r\nconst selectRevisionMapping = (state: RootState) => state.userFormReducer.revisions\r\n\r\nconst selectRevisions = createSelector([selectRevisionMapping], (revisions) => Object.values(revisions))\r\n\r\nexport const selectRevisionsForForm: SelectorWithArgs<string, UserFormRevision[]> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectRevisions, (_state: RootState, formId: string) => formId], (revisions, formId) => {\r\n\t\treturn revisions.filter((revision) => {\r\n\t\t\treturn revision.form === formId\r\n\t\t})\r\n\t}),\r\n)\r\n\r\nexport const selectSubmissionsForForm: SelectorWithArgs<string, UserFormSubmission[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[selectSubmissions, selectRevisionMapping, (_state: RootState, formId: string) => formId],\r\n\t\t\t(submissions, revisionMapping, formId) => {\r\n\t\t\t\treturn Object.values(submissions).filter((submission) => {\r\n\t\t\t\t\tconst revision = revisionMapping[submission.form_revision]\r\n\t\t\t\t\treturn revision?.form === formId\r\n\t\t\t\t})\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectSubmissionsForIssue: SelectorWithArgs<string, UserFormSubmission[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[(state: RootState) => state.userFormReducer.submissions, (_state: RootState, issueId: string) => issueId],\r\n\t\t\t(submissions, issueId) => {\r\n\t\t\t\treturn Object.values(submissions).filter((submission) => {\r\n\t\t\t\t\treturn submission.issue === issueId\r\n\t\t\t\t})\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectSubmissionsForComponent: SelectorWithArgs<string, UserFormSubmission[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[selectSubmissions, (_state: RootState, componentId: string) => componentId],\r\n\t\t\t(submissions, componentId) => {\r\n\t\t\t\treturn submissions.filter((submission) => {\r\n\t\t\t\t\treturn submission.component === componentId\r\n\t\t\t\t})\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectUserFormMapping: Selector<Record<Stored<UserForm>[\"offline_id\"], UserForm>> = (state: RootState) => {\r\n\treturn state.userFormReducer.userForms\r\n}\r\n\r\nexport const selectLatestRevisionByFormId: Selector<Record<Stored<UserForm>[\"offline_id\"], UserFormRevision>> =\r\n\tcreateSelector([selectRevisionMapping], (revisions) => {\r\n\t\tconst latestRevisions: Record<string, UserFormRevision> = {}\r\n\t\tfor (const revision of Object.values(revisions)) {\r\n\t\t\tconst formId = revision.form\r\n\t\t\tconst currentLatestRevision = latestRevisions[formId]\r\n\t\t\tif (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {\r\n\t\t\t\tlatestRevisions[formId] = revision\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn latestRevisions\r\n\t})\r\n\r\nexport const selectNumberOfUserForms: Selector<number> = createSelector([selectUserFormMapping], (userForms) => {\r\n\treturn Object.keys(userForms).length\r\n})\r\n\r\nexport const userFormReducer: Reducer<UserFormState> = userFormSlice.reducer\r\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\r\nimport { selectProjectAccessUserMapping } from \"./projectAccessSlice\"\r\nimport { RootState, Selector, SelectorWithArgs, User } from \"../../typings\"\r\nimport { ProjectAccessLevel } from \"typings/models/access\"\r\n\r\nexport interface UserState {\r\n\tcurrentUser: User\r\n\tusers: Record<number, User>\r\n}\r\n\r\nconst initialState: UserState = {\r\n\tusers: {},\r\n\tcurrentUser: {\r\n\t\tid: 0,\r\n\t\tusername: \"\",\r\n\t\temail: \"\",\r\n\t\tprofile: { file: null, file_sha1: null, favourite_project_ids: [], tour_step: -1 },\r\n\t},\r\n}\r\n\r\nexport const userSlice = createSlice({\r\n\tname: \"users\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetUsers: (state, action: { payload: User[] }) => {\r\n\t\t\tconst usersMapping: Record<string, User> = {}\r\n\t\t\taction.payload.forEach((user) => {\r\n\t\t\t\tusersMapping[user.id] = user\r\n\t\t\t})\r\n\t\t\tstate.users = usersMapping\r\n\t\t},\r\n\t\tsetCurrentUser: (state, action: { payload: User }) => {\r\n\t\t\tstate.currentUser = action.payload\r\n\t\t},\r\n\t\tsetProfilePicture: (state, action: { payload: { file?: string; file_sha1?: string } }) => {\r\n\t\t\tstate.currentUser.profile.file = action.payload.file ?? null\r\n\t\t\tstate.currentUser.profile.file_sha1 = action.payload.file_sha1 ?? null\r\n\r\n\t\t\tconst currentUser = state.users[state.currentUser.id]\r\n\r\n\t\t\tif (!currentUser) {\r\n\t\t\t\tthrow new Error(\"Unable to find current user in users slice\")\r\n\t\t\t}\r\n\r\n\t\t\tcurrentUser.profile.file = action.payload.file ?? null\r\n\t\t\tcurrentUser.profile.file_sha1 = action.payload.file_sha1 ?? null\r\n\t\t},\r\n\t\taddFavouriteProjectId: (state, action: { payload: number }) => {\r\n\t\t\tstate.currentUser.profile.favourite_project_ids.push(action.payload)\r\n\t\t},\r\n\t\tremoveFavouriteProjectId: (state, action: { payload: number }) => {\r\n\t\t\tstate.currentUser.profile.favourite_project_ids = state.currentUser.profile.favourite_project_ids.filter(\r\n\t\t\t\t(id) => id !== action.payload,\r\n\t\t\t)\r\n\t\t},\r\n\t\tsetTourStep: (state, action: { payload: number }) => {\r\n\t\t\tstate.currentUser.profile.tour_step = action.payload\r\n\t\t},\r\n\t\tremoveUser: (state, action: { payload: number }) => {\r\n\t\t\tdelete state.users[action.payload]\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\tsetCurrentUser,\r\n\tsetProfilePicture,\r\n\tsetUsers,\r\n\taddFavouriteProjectId,\r\n\tremoveFavouriteProjectId,\r\n\tsetTourStep,\r\n\tremoveUser,\r\n} = userSlice.actions\r\n\r\nexport const selectCurrentUser = (state: RootState) => state.userReducer.currentUser\r\nexport const selectUser: SelectorWithArgs<number | null, User | undefined> = (userId) => (state) => {\r\n\tif (userId === null) return undefined\r\n\treturn state.userReducer.users[userId]\r\n}\r\nexport const selectUsersAsMapping = (state: RootState) => state.userReducer.users\r\nexport const selectFavouriteProjects = (state: RootState): number[] =>\r\n\tstate.userReducer.currentUser.profile.favourite_project_ids\r\n\r\nexport const selectSortedUsers: Selector<User[]> = createSelector(\r\n\t[selectCurrentUser, selectUsersAsMapping, selectProjectAccessUserMapping],\r\n\t(currentUser, userMapping, projectAccessMapping) => {\r\n\t\treturn Object.values(userMapping).sort((userA, userB) => {\r\n\t\t\tif (userA.id === currentUser.id) {\r\n\t\t\t\treturn -1\r\n\t\t\t} else if (userB.id === currentUser.id) {\r\n\t\t\t\treturn 1\r\n\t\t\t}\r\n\t\t\tconst projectAccessesA = projectAccessMapping[userA.id]\r\n\t\t\tconst projectAccessesB = projectAccessMapping[userB.id]\r\n\t\t\tif (projectAccessesA?.access_level === projectAccessesB?.access_level) {\r\n\t\t\t\treturn userA.username.localeCompare(userB.username)\r\n\t\t\t}\r\n\t\t\tif (projectAccessesA?.access_level === ProjectAccessLevel.ADMIN) {\r\n\t\t\t\treturn -1\r\n\t\t\t}\r\n\t\t\treturn 1\r\n\t\t})\r\n\t},\r\n)\r\n\r\nexport const userReducer: Reducer<UserState> = userSlice.reducer\r\n","import { Reducer, createSlice } from \"@reduxjs/toolkit\"\r\n\r\nimport { RootState, Selector, SelectorWithArgs } from \"typings\"\r\nimport { OfflineIdMapping, OrganizationAccess, User } from \"typings/models\"\r\nimport { onlyUniqueOfflineIds } from \"utils\"\r\n\r\nexport interface OrganizationAccessState {\r\n\torganizationAccesses: OfflineIdMapping<OrganizationAccess>\r\n\tactiveOrganizationAccessId: string | null\r\n}\r\n\r\nconst initialState: OrganizationAccessState = {\r\n\torganizationAccesses: {},\r\n\tactiveOrganizationAccessId: null,\r\n}\r\n\r\nexport const organizationAccessSlice = createSlice({\r\n\tname: \"organizationAccess\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetOrganizationAccesses: (state, action: { payload: OrganizationAccess[] }) => {\r\n\t\t\tif (!Array.isArray(action.payload)) throw new Error(\"Expected an array of OrganizationAccess\")\r\n\t\t\tif (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {\r\n\t\t\t\tthrow new Error(\"Tried to use setOrganizationAccesses reducer with duplicate ID's\")\r\n\t\t\t}\r\n\t\t\tconst organizationAccesses: OfflineIdMapping<OrganizationAccess> = {}\r\n\t\t\tfor (const organizationAccess of action.payload) {\r\n\t\t\t\torganizationAccesses[organizationAccess.offline_id] = organizationAccess\r\n\t\t\t}\r\n\t\t\tstate.organizationAccesses = organizationAccesses\r\n\t\t},\r\n\t\tupdateOrganizationAccess: (state, action: { payload: OrganizationAccess }) => {\r\n\t\t\tif (action.payload.offline_id in state.organizationAccesses) {\r\n\t\t\t\tstate.organizationAccesses[action.payload.offline_id] = action.payload\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Tried to update organization access with ID that doesn't exist: ${action.payload.offline_id}`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveOrganizationAccess: (state, action: { payload: OrganizationAccess }) => {\r\n\t\t\tif (action.payload.offline_id in state.organizationAccesses) {\r\n\t\t\t\tdelete state.organizationAccesses[action.payload.offline_id]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Tried to remove organization access with ID that doesn't exist: ${action.payload.offline_id}`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetActiveOrganizationAccessId: (state, action: { payload: string | null }) => {\r\n\t\t\tstate.activeOrganizationAccessId = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\tsetOrganizationAccesses,\r\n\tupdateOrganizationAccess,\r\n\tremoveOrganizationAccess,\r\n\tsetActiveOrganizationAccessId,\r\n} = organizationAccessSlice.actions\r\n\r\nexport const selectOrganizationAccesses = (state: RootState) => {\r\n\treturn state.organizationAccessReducer.organizationAccesses\r\n}\r\n\r\nexport const selectOrganizationAccess: SelectorWithArgs<string, OrganizationAccess> =\r\n\t(organizationAccessId: string) => (state: RootState) => {\r\n\t\treturn state.organizationAccessReducer.organizationAccesses[organizationAccessId]\r\n\t}\r\n\r\nexport const selectActiveOrganizationAccess: Selector<OrganizationAccess | null> = (state) => {\r\n\tconst activeOrganizationAccessId = state.organizationAccessReducer.activeOrganizationAccessId\r\n\tif (!activeOrganizationAccessId) {\r\n\t\treturn null\r\n\t}\r\n\treturn state.organizationAccessReducer.organizationAccesses[activeOrganizationAccessId] ?? null\r\n}\r\n\r\nexport const selectOrganizationAccessForUser: SelectorWithArgs<User, OrganizationAccess | undefined> =\r\n\t(user: User) => (state: RootState) => {\r\n\t\treturn Object.values(state.organizationAccessReducer.organizationAccesses).find(\r\n\t\t\t(organizationAccess) => organizationAccess.user === user.id,\r\n\t\t)\r\n\t}\r\n\r\nexport const selectOrganizationAccessUserMapping = (state: RootState) => {\r\n\tconst organizationAccesses = {}\r\n\tObject.values(state.organizationAccessReducer.organizationAccesses).forEach((organizationAccess) => {\r\n\t\torganizationAccesses[organizationAccess.user] = organizationAccess\r\n\t})\r\n\treturn organizationAccesses\r\n}\r\n\r\nexport const organizationAccessReducer: Reducer<OrganizationAccessState> = organizationAccessSlice.reducer\r\n","import { createSlice, Reducer } from \"@reduxjs/toolkit\"\r\n\r\nexport interface VersioningState {\r\n\tversion: number\r\n}\r\n\r\nconst initialState: VersioningState = {\r\n\tversion: 0,\r\n}\r\n\r\n/**\r\n * Version of the offline redux store\r\n */\r\nexport const versioningSlice = createSlice({\r\n\tname: \"versioning\",\r\n\tinitialState,\r\n\treducers: {},\r\n})\r\n\r\nexport const versioningReducer: Reducer<VersioningState> = versioningSlice.reducer\r\n","// NOTE: Also update $full-component-marker-size in src/theme/_variables.sass\r\nexport const fullComponentMarkerSize = 45 // px\r\n","import { IssuePriority, IssueStatus } from \"../enums\"\r\n\r\nexport const DEFAULT_ISSUE_STATUS = IssueStatus.BACKLOG\r\nexport const DEFAULT_ISSUE_PRIORITY = IssuePriority.MEDIUM\r\n","export const OUTBOX_RETRY_DELAY = 5000 // milliseconds\r\n","import { AnyAction, applyMiddleware, compose, Reducer } from \"redux\"\r\nimport { offline } from \"@redux-offline/redux-offline\"\r\nimport offlineConfig from \"@redux-offline/redux-offline/lib/defaults\"\r\nimport localforage from \"localforage\"\r\nimport createMigration from \"redux-persist-migrate\"\r\nimport { combineReducers, configureStore, createNextState } from \"@reduxjs/toolkit\"\r\nimport {\r\n\tConfig,\r\n\tOfflineAction,\r\n\tOfflineMetadata,\r\n\tOfflineState,\r\n\tResultAction,\r\n} from \"@redux-offline/redux-offline/lib/types\"\r\nimport request from \"superagent\"\r\nimport { HttpMethod } from \"../enums\"\r\nimport { manifest } from \"./migrations\"\r\n\r\n// There are two \"blobs\": The Blob type from the \"buffer\" package (part of node),\r\n// and the Blob type from the browser. For some reason, superagent uses the \"buffer\"\r\n// version after moving code from hemora-web to overmap-core. This overwrites the name\r\n// \"Blob\". There are minor differences between the two interfaces (remove the type casting\r\n// of the `file` argument to `req.field()` in performRequest() to see the error), but it's\r\n// unlikely that we'll run into any problems.\r\nimport { Blob } from \"buffer\"\r\nimport {\r\n\tAPIError,\r\n\tmakeClient,\r\n\ttype OfflineMetaEffect,\r\n\tOutboxCoordinator,\r\n\ttype OvermapSDK,\r\n\tRequestDetails,\r\n} from \"../sdk\"\r\nimport { ToastProps, unsafeShowToast } from \"@overmap-ai/blocks\"\r\nimport {\r\n\t_setLatestRetryTime,\r\n\tauthReducer,\r\n\tcategoryReducer,\r\n\tcomponentReducer,\r\n\tcomponentStageCompletionReducer,\r\n\tcomponentStageReducer,\r\n\tcomponentTypeReducer,\r\n\tfileReducer,\r\n\tissueReducer,\r\n\tmapReducer,\r\n\tmarkAsDeleted,\r\n\torganizationAccessReducer,\r\n\torganizationReducer,\r\n\toutboxReducer,\r\n\tprojectAccessReducer,\r\n\tprojectFileReducer,\r\n\tprojectReducer,\r\n\trehydratedReducer,\r\n\tselectAccessToken,\r\n\tselectCategoriesOfWorkspace,\r\n\tselectMainWorkspace,\r\n\tsettingReducer,\r\n\tuserFormReducer,\r\n\tuserReducer,\r\n\tworkspaceReducer,\r\n} from \"./slices\"\r\nimport { versioningReducer } from \"./slices/versioningSlice\"\r\nimport { clientStore } from \"contexts\"\r\nimport { OUTBOX_RETRY_DELAY } from \"../constants\"\r\nimport { RootState } from \"../typings\"\r\n\r\n// NOTE: If changing, also change it in migrations.ts (avoid circular imports)\r\nconst VERSION_REDUCER_KEY = \"versioning\"\r\n\r\nexport const overmapReducers = {\r\n\t// TODO: attachmentReducer,\r\n\t[VERSION_REDUCER_KEY]: versioningReducer,\r\n\tfileReducer,\r\n\tauthReducer,\r\n\tcategoryReducer,\r\n\tcomponentReducer,\r\n\tcomponentStageCompletionReducer,\r\n\tcomponentStageReducer,\r\n\tcomponentTypeReducer,\r\n\tissueReducer,\r\n\tmapReducer,\r\n\torganizationReducer,\r\n\toutboxReducer,\r\n\tprojectReducer,\r\n\tprojectAccessReducer,\r\n\torganizationAccessReducer,\r\n\tprojectFileReducer,\r\n\trehydratedReducer,\r\n\tsettingReducer,\r\n\tuserFormReducer,\r\n\tuserReducer,\r\n\tworkspaceReducer,\r\n} as const\r\n\r\nexport const overmapReducer = combineReducers(overmapReducers)\r\n\r\n// Special action to revert all slices to their initial state. A reducer for this is added to each slice using\r\n// `extraReducers` in the slice definition.\r\nexport const resetStore = \"RESET\"\r\n\r\nfunction handleWorkspaceRemoval(draft: RootState, action: AnyAction): void {\r\n\tconst workspaceId = (action as AnyAction & { payload: string }).payload\r\n\tconst issuesVisibleInWorkspace = Object.values(draft.issueReducer.issues).filter((issue) =>\r\n\t\tissue.visible_in_workspaces.includes(workspaceId),\r\n\t)\r\n\r\n\tconst mainWorkspace = selectMainWorkspace(draft)\r\n\tif (!mainWorkspace) {\r\n\t\tthrow new Error(\"Main workspace not found\")\r\n\t}\r\n\tif (action.payload === mainWorkspace.offline_id) {\r\n\t\tthrow new Error(\"Tried to delete main workspace\")\r\n\t}\r\n\r\n\t// Find categories about to be deleted. If the issue has this category, we will have to remove it.\r\n\tconst categoriesInThisWorkspace = new Set<string>(\r\n\t\t(selectCategoriesOfWorkspace(workspaceId)(draft) ?? []).map((category) => category.offline_id),\r\n\t)\r\n\tfor (const issue of issuesVisibleInWorkspace) {\r\n\t\tif (issue.category && categoriesInThisWorkspace.has(issue.category)) {\r\n\t\t\tissue.category = null\r\n\t\t}\r\n\t}\r\n\r\n\t// If the deleted workspace was the index_workspace, we need to update the index_workspace to be the\r\n\t// main workspace.\r\n\t// NOTE: Issues are always visible in the index_workspace, so we can expect to find the index_workspace\r\n\t// in visible_in_workspaces.\r\n\tconst issuesWithThisWorkspaceIndex = issuesVisibleInWorkspace.filter(\r\n\t\t(issue) => issue.index_workspace === action.payload,\r\n\t)\r\n\r\n\tfor (const issue of issuesWithThisWorkspaceIndex) {\r\n\t\t// NOTE: Indexes of WorkspaceIndexedModels are updated after a reload in the workspace service. For now,\r\n\t\t// we'll just update the index_workspace of indexed models (currently issues and forms).\r\n\t\tissue.index_workspace = mainWorkspace.offline_id\r\n\t\tif (!issue.visible_in_workspaces.includes(mainWorkspace.offline_id)) {\r\n\t\t\tissue.visible_in_workspaces.push(mainWorkspace.offline_id)\r\n\t\t}\r\n\t}\r\n\r\n\t// Remove the workspace from the visible_in_workspaces of all issues\r\n\tfor (const issue of issuesVisibleInWorkspace) {\r\n\t\tconst indexOfWorkspace = issue.visible_in_workspaces.indexOf(workspaceId)\r\n\t\tif (indexOfWorkspace === -1) {\r\n\t\t\t// This is unexpected because we already filtered by visible_in_workspaces.\r\n\t\t\tthrow new Error(\"Workspace not found in issue's visible_in_workspaces\")\r\n\t\t}\r\n\t\tissue.visible_in_workspaces.splice(indexOfWorkspace, 1)\r\n\t}\r\n\r\n\t// Lastly, some sanity checks to make sure we didn't miss anything.\r\n\tfor (const issue of issuesVisibleInWorkspace) {\r\n\t\tif (issue.visible_in_workspaces.length === 0) {\r\n\t\t\tthrow new Error(`Unexpected error: Issue ${issue.offline_id} has no visible_in_workspaces`)\r\n\t\t}\r\n\t\tif (issue.index_workspace === action.payload || !issue.index_workspace) {\r\n\t\t\tthrow new Error(`Failed to update index_workspace of issue ${issue.offline_id} to main workspace`)\r\n\t\t}\r\n\t}\r\n\r\n\tconst indexedForms = Object.values(draft.userFormReducer.userForms).filter(\r\n\t\t(form) => form.index_workspace === workspaceId,\r\n\t)\r\n\t// Update the index_workspace of all forms that are indexed by the workspace being removed\r\n\tfor (const form of indexedForms) {\r\n\t\tform.index_workspace = mainWorkspace.offline_id\r\n\t}\r\n}\r\n\r\n// Clear the store and reset all reducers on logout\r\nexport const rootReducer: Reducer<RootState> = (state, action): RootState => {\r\n\tif (action.type === \"auth/setLoggedIn\" && !action.payload) {\r\n\t\treturn overmapReducer(undefined, action) as RootState\r\n\t}\r\n\r\n\tlet mutatedState = state\r\n\r\n\tif (state && action.type === \"workspace/removeWorkspace\") {\r\n\t\tmutatedState = createNextState(state, (draft) => {\r\n\t\t\thandleWorkspaceRemoval(draft, action)\r\n\t\t})\r\n\t}\r\n\r\n\treturn overmapReducer(mutatedState, action) as RootState\r\n}\r\n\r\nexport interface FullOfflineMetadata extends OfflineMetadata {\r\n\teffect: OfflineMetaEffect\r\n}\r\n\r\nexport interface FullOfflineAction extends OfflineAction {\r\n\tmeta: { offline: FullOfflineMetadata }\r\n\t// Redundantly store request details in the unused `payload` property to make TypeScript happy\r\n\tpayload: RequestDetails\r\n}\r\n\r\nlet __OUTBOX_COORDINATOR: OutboxCoordinator | null = null\r\n\r\nfunction _getOutboxCoordinator(): OutboxCoordinator {\r\n\tif (!__OUTBOX_COORDINATOR) {\r\n\t\t__OUTBOX_COORDINATOR = new OutboxCoordinator()\r\n\t}\r\n\treturn __OUTBOX_COORDINATOR\r\n}\r\n\r\n// This callback is run when the Redux store has finished rehydrating itself from localForage\r\n// We signal to the rest of the app that hydration has finished\r\nconst persistCallback = (err: null | Error) => {\r\n\tif (err) throw err\r\n\tif (clientStore) {\r\n\t\tclientStore.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\r\n\t} else {\r\n\t\tconsole.error(\"Client store not set\")\r\n\t}\r\n}\r\n\r\nexport const enqueue: Config[\"queue\"][\"enqueue\"] = (_array, item, _context) => {\r\n\tconst coordinator = _getOutboxCoordinator()\r\n\tcoordinator.addRequest(item as FullOfflineAction)\r\n\treturn coordinator.getQueue()\r\n}\r\n\r\nexport const dequeue: Config[\"queue\"][\"dequeue\"] = (_array, item, _context) => {\r\n\tconst coordinator = _getOutboxCoordinator()\r\n\t// The redux-offline type leaves out the \"offlineAction\" property\r\n\ttype BadMetaType = ResultAction[\"meta\"]\r\n\ttype CorrectedMetaType = BadMetaType & { offlineAction: FullOfflineAction }\r\n\tconst meta = item.meta as CorrectedMetaType\r\n\tconst uuid = meta.offlineAction.payload.uuid\r\n\tcoordinator.remove(uuid)\r\n\treturn coordinator.getQueue()\r\n}\r\n\r\n// This is called an \"effect reconciler\", and it turns an offline action into a real API request\r\nasync function effect(_effect: OfflineMetaEffect, action: FullOfflineAction) {\r\n\t// REASON: Handling of unexpected case\r\n\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\r\n\tif (!action.payload) {\r\n\t\tthrow new Error(\"Received empty payload\")\r\n\t}\r\n\r\n\t// We pass the action through a chain of middleware, which can do some useful things and then perform the action.\r\n\t// `runMiddleware` returns a Promise<Response> if everything goes well.\r\n\treturn runMiddleware(action)\r\n}\r\n\r\nconst customConfig: Partial<Config> = {\r\n\t...offlineConfig,\r\n\teffect: effect as Config[\"effect\"],\r\n\t// Casting needed because we are saving FullOfflineAction objects, not just OfflineAction objects,\r\n\t// but redux-offline does not know this.\r\n\tdiscard: discard as Config[\"discard\"],\r\n\treturnPromises: true,\r\n\tpersistCallback,\r\n\tretry: retry as Config[\"retry\"],\r\n\t// Modify the configuration of the offline store to use localforage\r\n\t// which uses IndexedDB by default (persists even on mobile when installed as a PWA, unlike localStorage)\r\n\tpersistOptions: { storage: localforage },\r\n\t// TODO: custom enqueue implementation to take care of intelligently cancelling \"create/delete same issue\",\r\n\t// and custom dequeue for e.g. if user insists on removing a failed a \"create issue\", then remove the \"edit\r\n\t// that same issue\"\r\n\tqueue: {\r\n\t\t...offlineConfig.queue,\r\n\t\tenqueue,\r\n\t\tdequeue,\r\n\t\t// Bad typing, undefined is actually fine, and the action is a FullOfflineAction, not just an OfflineAction.\r\n\t\tpeek: (...args) => peek(...(args as Parameters<typeof peek>))!,\r\n\t} satisfies Config[\"queue\"],\r\n}\r\n\r\n// migration to compose into store\r\nconst migration = createMigration(manifest, VERSION_REDUCER_KEY) as (_: unknown) => unknown\r\n\r\n/**\r\n * Enhancer for the Redux store that adds offline support and needed middleware for overmap.\r\n * Add to your store's `enhancers` array.\r\n */\r\nexport const overmapEnhancer = compose(offline(customConfig), migration)\r\n\r\nexport const defaultStore = configureStore({\r\n\treducer: rootReducer,\r\n\tenhancers: [compose(applyMiddleware(), overmapEnhancer)],\r\n\tmiddleware: (getDefaultMiddleware) => {\r\n\t\treturn getDefaultMiddleware({\r\n\t\t\t// TODO: Enable periodically to find problems\r\n\t\t\tserializableCheck: false,\r\n\t\t\timmutableCheck: false,\r\n\t\t})\r\n\t},\r\n})\r\n\r\n/**\r\n * Makes a best-effort attempt to extract a request.Response from an error object.\r\n * @param error The error object\r\n */\r\nfunction extractResponseFromError(error: unknown): request.Response | undefined {\r\n\tfunction isResponse(response: unknown): response is request.Response {\r\n\t\t// Just some keys we know are on a request.Response\r\n\t\tconst knownKeys = [\"ok\", \"redirect\", \"clientError\", \"serverError\", \"error\"]\r\n\t\treturn typeof response === \"object\" && response !== null && knownKeys.every((key) => key in response)\r\n\t}\r\n\r\n\tif (isResponse(error)) return error\r\n\tif (typeof error === \"object\" && error !== null) {\r\n\t\tconst typedError = error as { response?: { response?: request.Response } }\r\n\t\tif (isResponse(typedError.response)) return typedError.response\r\n\t\tif (typedError.response && isResponse(typedError.response.response)) return typedError.response.response\r\n\t}\r\n\treturn undefined\r\n}\r\n\r\n/**\r\n * Makes a best-effort attempt to extract an error message from a request.Response or an error object.\r\n * @param errorRes The response object from a request, if available\r\n * @param err The error object, if available\r\n */\r\nfunction extractErrorMessage(errorRes: request.Response | undefined, err: unknown): string | undefined {\r\n\tif (errorRes?.body) {\r\n\t\tif (typeof errorRes.body === \"object\") {\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\r\n\t\t\tif (typeof errorRes.body.error === \"string\") return errorRes.body.error as string\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\r\n\t\t\tif (typeof errorRes.body.message === \"string\") return errorRes.body.message as string\r\n\t\t} else if (typeof errorRes.body === \"string\") return errorRes.body\r\n\t} else if (errorRes?.text) {\r\n\t\treturn errorRes.text\r\n\t} else if (err instanceof Error) {\r\n\t\treturn err.message\r\n\t}\r\n\treturn undefined\r\n}\r\n\r\n// Executes an offline action by making the API request specified in the action's offline metadata\r\nexport async function performRequest(action: FullOfflineAction, client: OvermapSDK): Promise<request.Response> {\r\n\t// Checks access token, renews if expiring soon\r\n\tasync function checkToken() {\r\n\t\t// TODO: If another check is already in progress, skip this check.\r\n\t\t// TODO: Enqueue\r\n\t\tif (client.auth.tokenIsExpiringSoon()) {\r\n\t\t\tawait client.auth.renewTokens()\r\n\t\t}\r\n\t}\r\n\r\n\tconst state: RootState = client.store.getState()\r\n\tif (state.outboxReducer.deletedRequests.includes(action.payload.uuid)) {\r\n\t\t// The request has been marked for deletion, so we don't want to perform it.\r\n\t\t// Instead, throw an error, so it will be retried and discarded in the `discard` function.\r\n\t\tthrow new Error(\"Request was marked for deletion\")\r\n\t}\r\n\r\n\tif (action.payload.checkAuth !== false) {\r\n\t\ttry {\r\n\t\t\tawait checkToken()\r\n\t\t} catch (e) {\r\n\t\t\tif (e instanceof APIError) {\r\n\t\t\t\t// Renewing tokens has failed; we should sign out the user.\r\n\t\t\t\tawait client.auth.logout()\r\n\t\t\t\treturn Promise.reject(e)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tconsole.debug(\"Done checking tokens\")\r\n\r\n\tconst defaultSettings = {\r\n\t\tqueryParams: \"\",\r\n\t\tisAuthNeeded: true,\r\n\t}\r\n\r\n\tconst offlineEffect = action.meta.offline.effect\r\n\tconst { payload, headers, method, queryParams, attachmentHash, isExternalUrl, isAuthNeeded, isResponseBlob } = {\r\n\t\t...defaultSettings,\r\n\t\t...offlineEffect.request,\r\n\t}\r\n\tconst requestDetails = offlineEffect.request\r\n\tlet url = requestDetails.url\r\n\tconst file = attachmentHash ? await client.files.fetchCache(attachmentHash) : undefined\r\n\tconst accessToken = selectAccessToken(state)\r\n\r\n\tif (attachmentHash && !file) {\r\n\t\tthrow new Error(`Cannot upload file ${attachmentHash} because it's not cached.`)\r\n\t}\r\n\r\n\tif ((!isExternalUrl || import.meta.env.DEV) && !url.startsWith(\"http\")) {\r\n\t\tif (!url.startsWith(\"/\") && !url.startsWith(\"blob:\")) {\r\n\t\t\turl = \"/\" + url\r\n\t\t\tif (import.meta.env.DEV) {\r\n\t\t\t\tconsole.trace(`You have passed a host-relative URL: ${url}`)\r\n\t\t\t}\r\n\t\t}\r\n\t\turl = client.API_URL + url\r\n\t}\r\n\r\n\tconst addPayload = (req: request.SuperAgentRequest) => {\r\n\t\tif (attachmentHash) {\r\n\t\t\tconst s3url = requestDetails.s3url\r\n\t\t\tif (!s3url) throw new Error(`No S3 URL for file ${attachmentHash}`)\r\n\t\t\tif (\"warning\" in s3url) throw new Error(`S3 URL warning for file ${attachmentHash}`)\r\n\t\t\tif (!file) throw new Error(`No file for file ${attachmentHash}`)\r\n\t\t\tconst s3Sha1Checksum = s3url.fields[\"x-amz-checksum-sha1\"]\r\n\t\t\tif (!s3Sha1Checksum) throw new Error(`No checksum for file ${attachmentHash}`)\r\n\t\t\treturn req\r\n\t\t\t\t.set(\"x-amz-checksum-sha1\", s3Sha1Checksum)\r\n\t\t\t\t.field({ ...payload, ...s3url.fields })\r\n\t\t\t\t.attach(\"file\", file as unknown as Blob)\r\n\t\t}\r\n\t\treturn req.send(payload)\r\n\t}\r\n\r\n\tconst methodRequestMapping: Record<HttpMethod, () => request.SuperAgentRequest> = {\r\n\t\t[HttpMethod.GET]: () => {\r\n\t\t\tif (isResponseBlob) {\r\n\t\t\t\treturn request.get(url.toString()).responseType(\"blob\")\r\n\t\t\t}\r\n\t\t\treturn request.get(url.toString())\r\n\t\t},\r\n\t\t[HttpMethod.POST]: () => {\r\n\t\t\tconst ret = request.post(url.toString())\r\n\t\t\treturn addPayload(ret)\r\n\t\t},\r\n\t\t[HttpMethod.PATCH]: () => {\r\n\t\t\tconst ret = request.patch(url.toString())\r\n\t\t\treturn addPayload(ret)\r\n\t\t},\r\n\t\t[HttpMethod.PUT]: () => {\r\n\t\t\tconst ret = request.put(url.toString())\r\n\t\t\treturn addPayload(ret)\r\n\t\t},\r\n\t\t[HttpMethod.DELETE]: () => {\r\n\t\t\tconst ret = request.delete(url.toString())\r\n\t\t\treturn addPayload(ret)\r\n\t\t},\r\n\t}\r\n\r\n\tconst selectedRequest = methodRequestMapping[method]\r\n\r\n\tlet requestToSend = selectedRequest()\r\n\tif (isAuthNeeded) {\r\n\t\trequestToSend = requestToSend.set(\"Authorization\", `Bearer ${accessToken}`)\r\n\t}\r\n\tif (headers) {\r\n\t\trequestToSend = requestToSend.set(headers)\r\n\t}\r\n\r\n\ttry {\r\n\t\treturn await requestToSend.query(queryParams)\r\n\t} catch (error) {\r\n\t\t// Observed error types: Error, request.Response\r\n\t\t// If it's an Error, it has a `response.response` property that is a request.Response.\r\n\t\tconst errorResponse = extractResponseFromError(error)\r\n\t\tconst status: number | undefined = errorResponse?.status\r\n\r\n\t\tif (status === 401) {\r\n\t\t\tconsole.debug(\"Forbidden; renewing tokens and retrying.\")\r\n\t\t\ttry {\r\n\t\t\t\tawait client.auth.renewTokens()\r\n\t\t\t\tconsole.debug(\"Successfully renewed tokens; retrying request.\")\r\n\t\t\t\treturn await requestToSend.query(queryParams)\r\n\t\t\t} catch (error) {\r\n\t\t\t\tconsole.warn(\"Failed to renew tokens.\", error)\r\n\t\t\t\tconst loggedIn = state.authReducer.isLoggedIn\r\n\t\t\t\tif (loggedIn) {\r\n\t\t\t\t\tconsole.warn(\"Signing out already signed-in user.\")\r\n\t\t\t\t\tawait client.auth.logout()\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// This is only expected when signing in for the first time with invalid credentials.\r\n\t\t\t\t\tconsole.warn(\"No signed-in user to sign out.\")\r\n\t\t\t\t}\r\n\t\t\t\tthrow new APIError(\"You have been signed out due to inactivity.\", errorResponse, {\r\n\t\t\t\t\tdiscard: true,\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// TODO: Error codes for all APIErrors.\r\n\t\t// TODO: Constant for all messages.\r\n\t\tconst apiErrorMessage = extractErrorMessage(errorResponse, error) || \"An unexpected error occurred.\"\r\n\r\n\t\tthrow new APIError(apiErrorMessage, errorResponse, {\r\n\t\t\tdiscard: discardStatuses.includes(status!),\r\n\t\t})\r\n\t}\r\n}\r\n\r\ninterface MiddlewareChainer {\r\n\tthen: (next: OfflineMiddleware) => MiddlewareChainer\r\n\tcompile: () => OfflineMiddleware[]\r\n}\r\n\r\nclass MiddlewareChainerPrivate {\r\n\t_all: OfflineMiddleware[]\r\n\t_previous?: OfflineMiddleware\r\n\r\n\tconstructor(current: OfflineMiddleware) {\r\n\t\tthis._all = [current]\r\n\t\tthis._previous = current\r\n\t\tthis.then = this.then.bind(this)\r\n\t\tthis.compile = this.compile.bind(this)\r\n\t}\r\n\r\n\tthen(next: OfflineMiddleware): MiddlewareChainer {\r\n\t\tif (this._previous) this._previous.next = next // \"next\" is now \"current\"\r\n\t\tthis._all.push(next)\r\n\t\tthis._previous = next // \"next\" is now \"previous\"\r\n\r\n\t\treturn {\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/unbound-method\r\n\t\t\tthen: this.then,\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/unbound-method\r\n\t\t\tcompile: this.compile,\r\n\t\t}\r\n\t}\r\n\r\n\tcompile() {\r\n\t\treturn this._all\r\n\t}\r\n}\r\n\r\nabstract class OfflineMiddleware {\r\n\tnext: OfflineMiddleware | null\r\n\r\n\tconstructor() {\r\n\t\tthis.next = null\r\n\t}\r\n\r\n\tthen(next: OfflineMiddleware): MiddlewareChainer {\r\n\t\treturn new MiddlewareChainerPrivate(this).then(next)\r\n\t}\r\n\r\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\r\n\t\tif (this.next) {\r\n\t\t\treturn this.next.run(action)\r\n\t\t} else {\r\n\t\t\tconsole.debug(`All middleware finished with ${this.constructor.name}, performing request:`, action)\r\n\t\t\tconst baseUrl = action.meta.offline.effect.BASE_URL\r\n\t\t\tif (!clientStore) throw new Error(\"Client store not set\")\r\n\t\t\t// At the end of the middleware chain, we want to perform the action\r\n\t\t\treturn performRequest(action, makeClient(baseUrl, clientStore))\r\n\t\t}\r\n\t}\r\n}\r\n\r\nclass OfflineAnalyticsMiddleware extends OfflineMiddleware {\r\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\r\n\t\t// TODO: Store some statistics on which actions are called and enqueue reports periodically\r\n\t\treturn super.run(action)\r\n\t}\r\n}\r\n\r\nclass RateLimitingMiddleware extends OfflineMiddleware {\r\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\r\n\t\t// TODO: Consider rate limits (enable offline mode programmatically to reduce rate)\r\n\t\treturn super.run(action)\r\n\t}\r\n}\r\n\r\nconst allMiddleware = new OfflineAnalyticsMiddleware().then(new RateLimitingMiddleware()).compile()\r\n\r\nfunction runMiddleware(action: FullOfflineAction) {\r\n\treturn allMiddleware[0]?.run(action)\r\n}\r\n\r\n// These status codes are due to a fundamental problem that can never be corrected except by manual intervention.\r\n// TODO: 400 (Bad Request) should result in the user being given a chance to amend their request to be valid.\r\nconst discardStatuses = [400, 409, 403, 404]\r\nconst statusMessages: Record<number, ToastProps | undefined> = {\r\n\t403: { title: \"Forbidden\", description: \"You are not authorized to perform this action.\", severity: \"danger\" },\r\n\t404: { title: \"Not found\", description: \"The requested resource was not found.\", severity: \"danger\" },\r\n}\r\n\r\n// TODO:\r\n/*\r\nconst statusHandlers: Record<number, SimpleToastMessage> = {\r\n\t401: { title: \"You have been logged out\", description: \"Please log in again to continue using the app.\", element: <FormRenderer ...> },\r\n}\r\n */\r\n\r\n// Discard function is used by Redux Offline to decide whether to discard an action or not, based on the error\r\n// that the effect reconciler threw and/or the action\r\nexport function discard(reason: unknown, action: FullOfflineAction, retries = 0): boolean {\r\n\t// TODO: If 401, renew auth and return false\r\n\t// TODO: If 400, set state to rescue mode, allowing the user to fix the request and retry (or discard)\r\n\r\n\tconsole.debug(\r\n\t\t\"Considering discarding request due to error:\",\r\n\t\treason,\r\n\t\t`(${typeof reason})`,\r\n\t\t\"\\nAction:\",\r\n\t\taction,\r\n\t\t\"\\nRetries:\",\r\n\t\tretries,\r\n\t)\r\n\r\n\tif (!(reason instanceof Error)) {\r\n\t\tconsole.error(\r\n\t\t\t\"ENCOUNTERED NON-ERROR ERROR:\",\r\n\t\t\treason,\r\n\t\t\t\"(throwing immediately, which may lead to unexpected behavior)\",\r\n\t\t)\r\n\t\tthrow reason\r\n\t}\r\n\r\n\tconst state = clientStore!.getState()\r\n\tconst deletedRequests = state.outboxReducer.deletedRequests\r\n\tconst uuid = action.payload.uuid\r\n\r\n\t// NOTE: Doesn't really return true, but TypeScript doesn't need to know that.\r\n\t// Adding a `return true` would be meaningless since we are throwing the passed error.\r\n\tfunction rollbackAndThrow(): true {\r\n\t\tclientStore!.dispatch(markAsDeleted(uuid))\r\n\t\t_getOutboxCoordinator().remove(action.payload.uuid)\r\n\t\tconst rollbackAction = action.meta.offline.rollback\r\n\t\tif (rollbackAction) {\r\n\t\t\tconsole.warn(\"Rolling back request due to SDK error:\", action)\r\n\t\t\tclientStore!.dispatch(rollbackAction)\r\n\t\t}\r\n\t\tthrow reason\r\n\t}\r\n\r\n\tif (reason instanceof APIError && reason.options.discard) {\r\n\t\tconsole.debug(\"Discarding request due to explicit discard:\", action)\r\n\t\treturn rollbackAndThrow()\r\n\t}\r\n\r\n\tif (deletedRequests.includes(uuid)) {\r\n\t\tconsole.debug(\"Discarding request due to deletion:\", action)\r\n\t\treturn rollbackAndThrow()\r\n\t}\r\n\r\n\tif (reason instanceof APIError) {\r\n\t\tconst status: number | undefined = reason.status || reason.response?.status\r\n\t\tif (!status) {\r\n\t\t\tconsole.warn(\"Error has no status code:\", reason)\r\n\t\t}\r\n\t\tif (status !== undefined && discardStatuses.includes(status)) {\r\n\t\t\tconsole.warn(\"Discarding request due to error:\", reason, \"\\nAction:\", action)\r\n\t\t\tconst message = statusMessages[status]\r\n\t\t\tif (message) {\r\n\t\t\t\tif (unsafeShowToast) {\r\n\t\t\t\t\tunsafeShowToast(message)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconsole.error(`Could not display toast for status ${status} because there is no toast handle.`)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t_getOutboxCoordinator().remove(action.payload.uuid)\r\n\t\t\treason.options.discard = true\r\n\t\t\trollbackAndThrow()\r\n\t\t}\r\n\t}\r\n\r\n\tconsole.debug(\"Registering a retry for request:\", action.payload.uuid)\r\n\t// All failures due to any other reason should be retried indefinitely. It will not block the outbox thanks to\r\n\t// OutboxCoordinator.\r\n\t_getOutboxCoordinator().registerRetry(action.payload.uuid)\r\n\treturn false\r\n}\r\n\r\n// Peek function is used by Redux Offline to determine the next action of the outbox to execute.\r\n// We are overriding the default implementation (return array[0]) with our own to support our graph-based outbox.\r\nfunction peek(\r\n\t_array: FullOfflineAction[],\r\n\t_item: unknown,\r\n\t_context: { offline: OfflineState },\r\n): OfflineAction | undefined {\r\n\treturn _getOutboxCoordinator().peek()\r\n}\r\n\r\n// Retry function is used by Redux Offline to determine how long to retry an action, given number of retries\r\nfunction retry(_action: FullOfflineAction, _retries: number): number | undefined {\r\n\t// Always retry, but wait a few seconds after a failed request. We have our own custom discard/retry logic.\r\n\tclientStore!.dispatch(_setLatestRetryTime(new Date().getTime()))\r\n\treturn OUTBOX_RETRY_DELAY\r\n}\r\n\r\n// export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, RootState, unknown, Action<string>>\r\n","import { TypedUseSelectorHook, useDispatch, useSelector } from \"react-redux\"\r\nimport { AppDispatch, RootState } from \"../typings\"\r\n\r\n// Use throughout the app instead of plain `useDispatch` and `useSelector`\r\nexport const useAppDispatch = () => useDispatch<AppDispatch>()\r\n\r\nexport const useAppSelector: TypedUseSelectorHook<RootState> = useSelector\r\n","import request from \"superagent\"\r\nimport { DeferredPromise } from \"../../utils/async/DeferredPromise\"\r\nimport type { OvermapSDK } from \"../sdk\"\r\nimport { OfflineMetaEffect, SDKRequest } from \"../typings\"\r\nimport { discard, enqueueRequest, FullOfflineAction, performRequest } from \"../../store\"\r\nimport { APIError } from \"../errors.ts\"\r\nimport { v4 as uuidv4 } from \"uuid\"\r\n\r\n/**\r\n * Abstract base class for building a service that can enqueue API requests\r\n */\r\nexport abstract class BaseApiService {\r\n\tprotected readonly client: OvermapSDK\r\n\r\n\tconstructor(sdk: OvermapSDK) {\r\n\t\tthis.client = sdk\r\n\t}\r\n\r\n\t/**\r\n\t * Enqueues an API request to the offline outbox.\r\n\t * @param requestDetails An SDKRequest object containing the details of the request.\r\n\t * @protected\r\n\t */\r\n\tprotected async enqueueRequest<TResult>(requestDetails: SDKRequest): Promise<TResult> {\r\n\t\t// enqueueRequest is a wrapper for _enqueueRequest that ensures the result is not an APIError unless\r\n\t\t// `.catch()` is triggered.\r\n\t\treturn this._enqueueRequest<TResult>(requestDetails).then((result) => {\r\n\t\t\tif (result instanceof APIError) {\r\n\t\t\t\tthrow result\r\n\t\t\t}\r\n\t\t\treturn result\r\n\t\t})\r\n\t}\r\n\r\n\t/**\r\n\t * Enqueues an API request to the Redux Offline outbox\r\n\t * @protected\r\n\t */\r\n\tprivate _enqueueRequest<TResult>(requestDetails: SDKRequest): DeferredPromise<TResult | APIError> {\r\n\t\t// We'll receive a Response object, but we want to return just the body of the response. This means\r\n\t\t// that we must inject a callback in the middle. We will use two promises:\r\n\t\tconst promise = new DeferredPromise<TResult | APIError>()\r\n\r\n\t\t// We dispatch an action that will eventually result in a request.\r\n\t\tconst requestDetailsWithBaseUrl = { ...requestDetails, BASE_URL: this.client.API_URL }\r\n\t\tconst { store } = this.client\r\n\r\n\t\tif (requestDetails.immediate) {\r\n\t\t\tconst requestWithUuid = {\r\n\t\t\t\t...requestDetailsWithBaseUrl,\r\n\t\t\t\tuuid: requestDetails.uuid ?? uuidv4(),\r\n\t\t\t}\r\n\t\t\t// TODO: Does this result in sending the request multiple times?\r\n\t\t\t// Should performRequest accept pure requestDetails?\r\n\t\t\t// (It shouldn't result in dupes because we're not dispatching an action.)\r\n\t\t\tconst fullOfflineAction: FullOfflineAction = {\r\n\t\t\t\tpayload: requestWithUuid,\r\n\t\t\t\ttype: \"\",\r\n\t\t\t\tmeta: {\r\n\t\t\t\t\toffline: {\r\n\t\t\t\t\t\teffect: {\r\n\t\t\t\t\t\t\ttimestamp: new Date().toISOString(),\r\n\t\t\t\t\t\t\trequest: requestWithUuid,\r\n\t\t\t\t\t\t\tBASE_URL: this.client.API_URL,\r\n\t\t\t\t\t\t} satisfies OfflineMetaEffect,\r\n\t\t\t\t\t},\r\n\t\t\t\t},\r\n\t\t\t}\r\n\t\t\tperformRequest(fullOfflineAction, this.client)\r\n\t\t\t\t.then((result) => {\r\n\t\t\t\t\tpromise.resolve(result.body as TResult)\r\n\t\t\t\t})\r\n\t\t\t\t.catch((error) => {\r\n\t\t\t\t\tdiscard(error, fullOfflineAction)\r\n\t\t\t\t\tpromise.reject(error)\r\n\t\t\t\t})\r\n\t\t} else {\r\n\t\t\tconst innerPromise: Promise<request.Response> = store.dispatch(\r\n\t\t\t\tenqueueRequest(requestDetailsWithBaseUrl),\r\n\t\t\t) as unknown as Promise<request.Response>\r\n\r\n\t\t\tconst successOrUndefinedHandler = (response: request.Response | undefined) => {\r\n\t\t\t\tif (response) {\r\n\t\t\t\t\tpromise.resolve(response.body as TResult)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconst error = new APIError(\r\n\t\t\t\t\t\t\"Could not get a response from the server.\",\r\n\t\t\t\t\t\tresponse satisfies undefined,\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tdiscard: true,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t)\r\n\t\t\t\t\tpromise.reject(error)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Handles errors from the inner promise (which performs the request) and rejects the outer promise, which has\r\n\t\t\t * been returned to the caller by the time this is triggered. This handler is only expected to be triggered if\r\n\t\t\t * the request has been discarded from the outbox.\r\n\t\t\t * @param error The error that caused the request to be discarded. Expected to be an APIError instance.\r\n\t\t\t */\r\n\t\t\tconst errorHandler = (error: APIError) => {\r\n\t\t\t\terror.options.discard = true\r\n\t\t\t\tpromise.reject(error)\r\n\t\t\t}\r\n\r\n\t\t\tinnerPromise.then(successOrUndefinedHandler, errorHandler)\r\n\t\t}\r\n\r\n\t\treturn promise\r\n\t}\r\n}\r\n\r\n// TODO: Make abstract class for fetching all, updating one, deleting one, etc., of TModel.\r\n","import { BaseApiService } from \"./BaseApiService\"\r\n\r\nimport type { OptimisticGenericResult, OptimisticModelResult, OptimisticMultipleModelResult } from \"../typings\"\r\nimport { Created, IssueAttachment, MaybeObjectURL, PhotoAttachmentPayload } from \"../../typings\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { hashFile, offline } from \"../../utils\"\r\nimport { addAttachment, removeAttachment, updateAttachment } from \"../../store\"\r\n\r\n// TODO: Use FileService\r\n/**\r\n * Handles creation and caching of attachments\r\n */\r\nexport class AttachmentService extends BaseApiService {\r\n\tfetchAll(projectId: number): OptimisticMultipleModelResult<IssueAttachment> {\r\n\t\tconst promise = this.enqueueRequest<IssueAttachment[]>({\r\n\t\t\tdescription: \"Fetch attachments\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/attachments/${projectId}/`,\r\n\t\t\tblocks: [],\r\n\t\t\tblockers: [],\r\n\t\t})\r\n\t\tconst allAttachments: IssueAttachment[] = Object.values(this.client.store.getState().issueReducer.attachments)\r\n\t\treturn [allAttachments, promise]\r\n\t}\r\n\t// Attachments aren't models, so we use the OptimisticGenericResult type instead\r\n\tasync add(attachmentPayload: PhotoAttachmentPayload): Promise<OptimisticModelResult<IssueAttachment>> {\r\n\t\tconst { description, issue_id, file_sha1, offline_id } = attachmentPayload\r\n\r\n\t\tif (!attachmentPayload.file.objectURL) {\r\n\t\t\tthrow new Error(\"Expected attachmentPayload.file.objectURL to be defined.\")\r\n\t\t}\r\n\r\n\t\t// We don't have a public URL yet, but we have a local objectURL. We'll use that as the file location for now.\r\n\t\t// It will be replaced by a real, online S3 URL once the attachment is created and loaded from the server on the\r\n\t\t// next login.\r\n\t\tconst offlineAttachment: IssueAttachment = {\r\n\t\t\t...attachmentPayload,\r\n\t\t\tfile: attachmentPayload.file.objectURL,\r\n\t\t\tfile_name: attachmentPayload.file.name,\r\n\t\t\tfile_type: attachmentPayload.file.type,\r\n\t\t}\r\n\r\n\t\tawait this.client.files.addCache(attachmentPayload.file, file_sha1)\r\n\r\n\t\tthis.client.store.dispatch(addAttachment(offlineAttachment))\r\n\r\n\t\tconst [fileProps] = await this.client.files.uploadFileToS3(file_sha1)\r\n\t\t// TODO: Handle response from server and verify tentative URL\r\n\t\tconst promise = this.enqueueRequest<Created<IssueAttachment>>({\r\n\t\t\tdescription: \"Create attachment\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/issues/${issue_id}/attach/`,\r\n\t\t\tblocks: [offline_id, issue_id],\r\n\t\t\tblockers: [file_sha1],\r\n\t\t\tpayload: {\r\n\t\t\t\toffline_id,\r\n\t\t\t\tissue: issue_id,\r\n\t\t\t\tdescription: description ?? \"\",\r\n\t\t\t\tsubmitted_at: new Date().getTime() / 1000,\r\n\t\t\t\t...fileProps,\r\n\t\t\t},\r\n\t\t})\r\n\r\n\t\treturn [offlineAttachment, promise]\r\n\t}\r\n\r\n\tasync attachFilesToIssue(\r\n\t\tfilesToSubmit: File[],\r\n\t\tissueId: string,\r\n\t): Promise<PromiseSettledResult<OptimisticGenericResult<IssueAttachment>>[]> {\r\n\t\treturn Promise.allSettled<OptimisticModelResult<IssueAttachment>>(\r\n\t\t\tfilesToSubmit.map((file) => {\r\n\t\t\t\tif (!(file instanceof File)) {\r\n\t\t\t\t\tthrow new Error(\"Expected a File instance.\")\r\n\t\t\t\t}\r\n\t\t\t\tconst photoAttachmentPromise = async (file: File) => {\r\n\t\t\t\t\tconst hash = await hashFile(file)\r\n\t\t\t\t\tconst attachment: PhotoAttachmentPayload = offline({\r\n\t\t\t\t\t\tfile,\r\n\t\t\t\t\t\t// No description for now\r\n\t\t\t\t\t\tissue_id: issueId,\r\n\t\t\t\t\t\tfile_sha1: hash,\r\n\t\t\t\t\t})\r\n\t\t\t\t\treturn await this.add(attachment)\r\n\t\t\t\t}\r\n\t\t\t\treturn photoAttachmentPromise(file)\r\n\t\t\t}),\r\n\t\t)\r\n\t}\r\n\r\n\tasync replaceFile(\r\n\t\tattachmentId: string,\r\n\t\tnewFile: MaybeObjectURL<File>,\r\n\t): Promise<OptimisticModelResult<IssueAttachment>> {\r\n\t\tconst { store } = this.client\r\n\t\tconst attachment: IssueAttachment | undefined = store.getState().issueReducer.attachments[attachmentId]\r\n\t\tif (!attachment) throw new Error(`Attachment ${attachmentId} not found`)\r\n\t\tlet oldFile: File | undefined = undefined\r\n\t\tconst newSha1 = await hashFile(newFile)\r\n\r\n\t\tconst performRequest: () => Promise<IssueAttachment> = async () => {\r\n\t\t\toldFile = await this.client.files.fetchCache(attachment.file_sha1)\r\n\t\t\tif (!oldFile) {\r\n\t\t\t\tconsole.error(`Failed to fetch old file from cache for sha1 ${attachment.file_sha1}.`)\r\n\t\t\t}\r\n\t\t\tif (!newFile.objectURL) {\r\n\t\t\t\tthrow new Error(`newFile[\"objectURL\"] is unexpectedly ${newFile.objectURL}`)\r\n\t\t\t}\r\n\t\t\tstore.dispatch(updateAttachment({ ...attachment, file_sha1: newSha1, file: URL.createObjectURL(newFile) }))\r\n\t\t\tawait this.client.files.addCache(newFile, newSha1)\r\n\r\n\t\t\tconst [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {\r\n\t\t\t\t// Revert to the old attachment details (which were gotten from the store before the request was sent)\r\n\t\t\t\tstore.dispatch(updateAttachment(attachment))\r\n\t\t\t\tthrow e\r\n\t\t\t})\r\n\r\n\t\t\tconst promise = this.enqueueRequest<Created<IssueAttachment>>({\r\n\t\t\t\tdescription: \"Edit attachment\",\r\n\t\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\t\turl: `/attachments/${attachment.offline_id}/`,\r\n\t\t\t\tisResponseBlob: false,\r\n\t\t\t\tpayload: fileProps,\r\n\t\t\t\tblockers: [attachmentId, newSha1],\r\n\t\t\t\tblocks: [attachmentId, newSha1],\r\n\t\t\t})\r\n\r\n\t\t\ttry {\r\n\t\t\t\tconst result = await promise\r\n\t\t\t\tvoid this.client.files.removeCache(attachment.file_sha1)\r\n\t\t\t\treturn result\r\n\t\t\t} catch (e) {\r\n\t\t\t\tif (oldFile) {\r\n\t\t\t\t\tstore.dispatch(\r\n\t\t\t\t\t\tupdateAttachment({\r\n\t\t\t\t\t\t\t...attachment,\r\n\t\t\t\t\t\t\tfile_sha1: attachment.file_sha1,\r\n\t\t\t\t\t\t\tfile: URL.createObjectURL(oldFile),\r\n\t\t\t\t\t\t}),\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t\tthrow e\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst offlineAttachment = {\r\n\t\t\t...attachment,\r\n\t\t\tfile_sha1: newSha1,\r\n\t\t\tfile: URL.createObjectURL(newFile),\r\n\t\t}\r\n\t\tconst promise = performRequest()\r\n\t\treturn [offlineAttachment, promise]\r\n\t}\r\n\r\n\t/**\r\n\t * Deletes an attachment and associated data in the cloud, in the Redux store and the cache.\r\n\t * @param attachmentId\r\n\t */\r\n\tdelete(attachmentId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst storeStateIssueReducer = store.getState().issueReducer\r\n\t\tconst attachment = storeStateIssueReducer.attachments[attachmentId]\r\n\t\tif (!attachment) {\r\n\t\t\tthrow new Error(`Attachment ${attachmentId} not found`)\r\n\t\t}\r\n\t\tstore.dispatch(removeAttachment(attachmentId))\r\n\t\tvoid this.client.files.removeCache(attachment.file_sha1)\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete attachment\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/attachments/${attachmentId}/`,\r\n\t\t\tblockers: [attachmentId],\r\n\t\t\tblocks: [attachmentId],\r\n\t\t})\r\n\t}\r\n}\r\n","import { Credentials, TokenPair } from \"../typings\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { hashFile } from \"utils/file\"\r\nimport {\r\n\taddFavouriteProjectId,\r\n\tclearTokens,\r\n\tmarkForDeletion,\r\n\tremoveFavouriteProjectId,\r\n\tresetStore,\r\n\tsetActiveOrganizationAccessId,\r\n\tsetActiveProjectId,\r\n\tsetActiveWorkspaceId,\r\n\tsetLoggedIn,\r\n\tsetProfilePicture,\r\n\tsetTokens,\r\n\tsetTourStep,\r\n} from \"../../store\"\r\nimport { RegistrationPayload } from \"../../typings\"\r\nimport jwtDecode, { JwtPayload } from \"jwt-decode\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { RESET_STATE } from \"@redux-offline/redux-offline/lib/constants\"\r\nimport { v4 as uuidv4 } from \"uuid\"\r\nimport localforage from \"localforage\"\r\n\r\n// Number of seconds until expiry that we consider as \"expiring soon\"\r\nconst EXPIRING_SOON_THRESHOLD = 1800\r\n\r\n// TODO: Rename `accessToken` and `refreshToken` to `access` and `refresh` respectively, then remove this function and\r\n// just return the response directly.\r\nfunction parseTokens(response: { access: string; refresh: string }): TokenPair {\r\n\tif (!response.access) throw new Error(\"Missing access token\")\r\n\tif (!response.refresh) throw new Error(\"Missing refresh token\")\r\n\treturn { accessToken: response.access, refreshToken: response.refresh }\r\n}\r\n\r\n/**\r\n * Handles login, logout and renewing tokens\r\n */\r\nexport class AuthService extends BaseApiService {\r\n\tprivate _getAccessToken = () => this.client.store.getState().authReducer.accessToken\r\n\tprivate _getRefreshToken = () => this.client.store.getState().authReducer.refreshToken\r\n\r\n\t// _getTokenPair and _getRenewedTokens don't need to use enqueueRequest from the BaseApiService because\r\n\t// they are very simple. However, if we need robust error handling or want these operations to queue in the Outbox,\r\n\t// we will use enqueueRequest.\r\n\r\n\t/**\r\n\t * Takes credentials and gets a token pair\r\n\t * @async\r\n\t * @param credentials The username and password for obtaining a token pair\r\n\t * @param logoutOnFailure Whether to log out if the request fails\r\n\t * @returns An array containing two elements: 1) a Promise for the access and refresh tokens, and 2) the UUID of the\r\n\t * request, so the request can be cancelled if necessary.\r\n\t */\r\n\tprivate _getTokenPair = (credentials: Credentials, logoutOnFailure = true): [Promise<TokenPair>, string] => {\r\n\t\t// Used to cancel after a timeout\r\n\t\tconst uuid = uuidv4()\r\n\t\ttry {\r\n\t\t\tconst responsePromise = this.enqueueRequest<{ access: string; refresh: string }>({\r\n\t\t\t\tuuid,\r\n\t\t\t\tdescription: \"Get token pair\",\r\n\t\t\t\tmethod: HttpMethod.POST,\r\n\t\t\t\turl: \"/api/token/\",\r\n\t\t\t\tpayload: credentials,\r\n\t\t\t\tisAuthNeeded: false,\r\n\t\t\t\tblockers: [],\r\n\t\t\t\tblocks: [],\r\n\t\t\t})\r\n\t\t\treturn [responsePromise.then(parseTokens), uuid]\r\n\t\t} catch (e) {\r\n\t\t\tif (logoutOnFailure) {\r\n\t\t\t\tvoid this.logout().then()\r\n\t\t\t}\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Takes refresh token and gets a new token pair\r\n\t * @async\r\n\t * @param {string} refreshToken The refresh token used to get new tokens\r\n\t * @returns {Promise<TokenPair>} The new access and refresh tokens\r\n\t */\r\n\tprivate _getRenewedTokens = async (refreshToken: string): Promise<TokenPair> => {\r\n\t\tinterface MaybeTokenPair {\r\n\t\t\taccess?: string\r\n\t\t\trefresh?: string\r\n\t\t}\r\n\r\n\t\tconst response = await this.enqueueRequest<MaybeTokenPair>({\r\n\t\t\tdescription: \"Get renewed tokens\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: \"/api/token/refresh/\",\r\n\t\t\tpayload: { refresh: refreshToken },\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t\t// Don't wait for an auth check since this is a refresh token request.\r\n\t\t\tcheckAuth: false,\r\n\t\t\t// Don't wait for other requests to finish, or we might end up in a deadlock.\r\n\t\t\timmediate: true,\r\n\t\t})\r\n\t\tif (!response.access) throw new Error(\"Missing access token\")\r\n\t\tif (!response.refresh) throw new Error(\"Missing refresh token\")\r\n\t\treturn { accessToken: response.access, refreshToken: response.refresh }\r\n\t}\r\n\r\n\t/**\r\n\t * Attempts to log into Hemora using given credentials\r\n\t * @param {string} username\r\n\t * @param {string} password\r\n\t */\r\n\tasync login(username: string, password: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\t// false: Don't log out on failure because we're not currently logged in. Instead, throw and show an error.\r\n\t\tconst [promise, uuid] = this._getTokenPair({ username, password }, false)\r\n\t\tconst initialDataUuid = uuidv4()\r\n\r\n\t\t// The goal: Cancel the request if it takes too long\r\n\t\tconst timeout = 5 // seconds\r\n\t\tlet timedOut = false\r\n\t\tlet initialDataRequestFinished = false\r\n\r\n\t\tconst timeoutPromise = new Promise<undefined>((_, reject) => {\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\tif (initialDataRequestFinished) {\r\n\t\t\t\t\treturn undefined\r\n\t\t\t\t}\r\n\t\t\t\ttimedOut = true\r\n\t\t\t\tstore.dispatch(markForDeletion(uuid))\r\n\t\t\t\tstore.dispatch(markForDeletion(initialDataUuid))\r\n\t\t\t\treject(new Error(`Request timed out after ${timeout} seconds`))\r\n\t\t\t}, timeout * 1000)\r\n\t\t})\r\n\t\tconst successPromise: Promise<undefined> = promise.then((tokens) => {\r\n\t\t\tif (timedOut) {\r\n\t\t\t\treturn undefined\r\n\t\t\t}\r\n\t\t\tstore.dispatch(setTokens(tokens))\r\n\r\n\t\t\t// fetchInitialData returns necessary app information and initializes the store with values\r\n\t\t\t// according to what the logged user has access to. Overwrites information on login.\r\n\t\t\treturn this.client.main.fetchInitialData(true, initialDataUuid).then(() => {\r\n\t\t\t\tif (timedOut) {\r\n\t\t\t\t\treturn undefined\r\n\t\t\t\t}\r\n\t\t\t\tinitialDataRequestFinished = true\r\n\t\t\t\tstore.dispatch(setLoggedIn(true))\r\n\t\t\t\tstore.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\r\n\t\t\t\treturn undefined\r\n\t\t\t})\r\n\t\t})\r\n\r\n\t\treturn Promise.race([timeoutPromise, successPromise])\r\n\t}\r\n\r\n\t/**\r\n\t * Logs the user out\r\n\t */\r\n\tasync logout() {\r\n\t\tconst { store } = this.client\r\n\t\t// This also sends an action to the store.ts rootReducer function, allowing\r\n\t\t// the store to be reset upon sending an undefined state to the other\r\n\t\t// reducers.\r\n\t\tstore.dispatch(setLoggedIn(false))\r\n\t\tstore.dispatch(clearTokens())\r\n\t\tstore.dispatch(setActiveProjectId(null))\r\n\t\tstore.dispatch(setActiveOrganizationAccessId(null))\r\n\t\tstore.dispatch(setActiveWorkspaceId(null))\r\n\t\t// Clear the outbox\r\n\t\tstore.dispatch({ type: RESET_STATE })\r\n\t\t// TODO: Consider using only one of the two approaches\r\n\t\t// For good measure:\r\n\t\tstore.dispatch({ type: resetStore })\r\n\t\t// Clear localforage\r\n\t\tawait localforage.clear()\r\n\t\twindow.location.reload()\r\n\t}\r\n\r\n\t/**\r\n\t * Attempts to renew tokens\r\n\t */\r\n\tasync renewTokens() {\r\n\t\tconst { store } = this.client\r\n\t\tconst dyingRefreshToken = this._getRefreshToken()\r\n\t\tif (!dyingRefreshToken) {\r\n\t\t\tthrow new Error(\"No refresh token found\")\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\tconst { accessToken, refreshToken } = await this._getRenewedTokens(dyingRefreshToken)\r\n\t\t\tconsole.log(\"Got renewed tokens\")\r\n\t\t\tstore.dispatch(setTokens({ accessToken, refreshToken }))\r\n\t\t} catch (e) {\r\n\t\t\t// TODO: This is temporary behaviour, replace it with login button on outbox failed requests\r\n\t\t\t// that failed because of a 401 Unauthorized\r\n\t\t\tconsole.error(\"Could not renew tokens; logging out.\")\r\n\t\t\tawait this.logout()\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Register a new user\r\n\t */\r\n\tregister(payload: RegistrationPayload): Promise<undefined> {\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Register\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: \"/authentication/users/register/\",\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tpayload,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync resetPassword(email: string): Promise<undefined> {\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Reset password\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: \"/authentication/users/reset-password/\",\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tpayload: {\r\n\t\t\t\temail: email,\r\n\t\t\t},\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\t/**\r\n\t * Checks whether the tokens will be expiring soon\r\n\t * @returns {boolean}\r\n\t */\r\n\ttokenIsExpiringSoon(): boolean {\r\n\t\tconst accessToken = this._getAccessToken()\r\n\t\tif (!accessToken) {\r\n\t\t\t// If the access token doesn't exist, it's not expiring.\r\n\t\t\treturn false\r\n\t\t}\r\n\t\t// Convert the current date from milliseconds to seconds (divide by 1000)\r\n\t\tconst currentDate = Date.now() / 1000\r\n\t\t// Find the expiration date of access token (in seconds)\r\n\t\tlet expiryDate: number\r\n\t\t// jwtDecode may throw an error if the access token is an empty string (logged out)\r\n\t\ttry {\r\n\t\t\t// REASON: Bad types\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error,@typescript-eslint/ban-ts-comment\r\n\t\t\t// @ts-ignore\r\n\r\n\t\t\texpiryDate = jwtDecode<JwtPayload>(accessToken).exp ?? currentDate\r\n\t\t} catch {\r\n\t\t\t// Enforce expiration if unable to decode token\r\n\t\t\texpiryDate = currentDate\r\n\t\t}\r\n\t\tconst secondsUntilExpiry = expiryDate - currentDate\r\n\t\treturn secondsUntilExpiry < EXPIRING_SOON_THRESHOLD\r\n\t}\r\n\r\n\tasync replaceProfilePicture(file: File): Promise<undefined> {\r\n\t\tconst hash = await hashFile(file)\r\n\r\n\t\tawait this.client.files.addCache(file, hash)\r\n\t\tconst { store } = this.client\r\n\r\n\t\tconst [fileProps] = await this.client.files.uploadFileToS3(hash)\r\n\r\n\t\tstore.dispatch(setProfilePicture({ file: `/files/${fileProps.file}`, file_sha1: hash }))\r\n\r\n\t\t// TODO: Handle response from server and verify tentative URL\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Replace profile picture\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: \"/authentication/users/profile-details/\",\r\n\t\t\tpayload: fileProps,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync addFavouriteProjectId(projectId: number): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(addFavouriteProjectId(projectId))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Add favourite project\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/authentication/users/favourite-project/${projectId}/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync removeFavouriteProjectId(projectId: number): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(removeFavouriteProjectId(projectId))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Add favourite project\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/authentication/users/unfavourite-project/${projectId}/`,\r\n\t\t\tblockers: [`favorite-project-${projectId}`],\r\n\t\t\tblocks: [`favorite-project-${projectId}`],\r\n\t\t})\r\n\t}\r\n\r\n\tasync setTourStep(stepIndex: number): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(setTourStep(stepIndex))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Set tour step\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: \"/authentication/users/profile-details/\",\r\n\t\t\tpayload: {\r\n\t\t\t\ttour_step: stepIndex,\r\n\t\t\t},\r\n\t\t\tblockers: [\"set-tour-step\"],\r\n\t\t\tblocks: [\"set-tour-step\"],\r\n\t\t})\r\n\t}\r\n\r\n\tasync joinApplication(\r\n\t\tprojectInviteId: string,\r\n\t\tverification_code: string,\r\n\t\tusername: string,\r\n\t\tpassword: string,\r\n\t): Promise<undefined> {\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Join application\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/authentication/join-app/${projectInviteId}/${verification_code}/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tusername,\r\n\t\t\t\tpassword,\r\n\t\t\t},\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { Category, Created, Offline, Payload, Stored } from \"../../typings\"\r\nimport { OptimisticEmptyResult, OptimisticGenericResult, OptimisticModelResult } from \"../typings\"\r\nimport { offline } from \"../../utils\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { addCategory, patchCategory, removeCategory, setCategories } from \"../../store\"\r\n\r\n/**\r\n * Handles the creation of Category Service\r\n * TODO: Support editing and deleting categories\r\n */\r\nexport class CategoryService extends BaseApiService {\r\n\tadd(category: Omit<Payload<Category>, \"workspace\">, workspaceId: string): OptimisticModelResult<Category> {\r\n\t\tconst offlineCategory = offline(category)\r\n\t\tconst categoryWithWorkspace = { ...offlineCategory, workspace: workspaceId }\r\n\t\tthis.client.store.dispatch(addCategory(categoryWithWorkspace))\r\n\r\n\t\tconst promise = this.enqueueRequest<Category>({\r\n\t\t\tdescription: \"Create Category\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: \"/categories/\",\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tpayload: offlineCategory,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offlineCategory.offline_id],\r\n\t\t})\r\n\t\treturn [categoryWithWorkspace, promise]\r\n\t}\r\n\tfetchAll(projectId: number): OptimisticGenericResult<Category[]> {\r\n\t\tconst promise = this.enqueueRequest<Category[]>({\r\n\t\t\tdescription: \"Get categories\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${projectId}/categories/`,\r\n\t\t\tblocks: [],\r\n\t\t\tblockers: [],\r\n\t\t})\r\n\r\n\t\t// Right now we are assuming that categories are generic and not a Model\r\n\t\t// Make fetchAll return OptimisticMultipleModelResult<Category>\r\n\t\tconst offlineCategories = Object.values(this.client.store.getState().categoryReducer.categories)\r\n\t\treturn [offlineCategories, promise]\r\n\t}\r\n\r\n\tupdate(category: Offline<Partial<Category>>, workspaceId: string): OptimisticModelResult<Category> {\r\n\t\tconst existingCategory = this.client.store.getState().categoryReducer.categories[category.offline_id]\r\n\r\n\t\tif (!existingCategory) {\r\n\t\t\tthrow new Error(`Expected an existing category with offline_id ${category.offline_id}`)\r\n\t\t}\r\n\r\n\t\tthis.client.store.dispatch(patchCategory(category))\r\n\t\tconst optimisticCategory: Stored<Category> = { ...existingCategory, ...category }\r\n\r\n\t\tconst promise = this.enqueueRequest<Created<Category>>({\r\n\t\t\tdescription: \"Edit Category\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/categories/${category.offline_id}/`,\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tpayload: category,\r\n\t\t\tblockers: [category.offline_id],\r\n\t\t\tblocks: [category.offline_id],\r\n\t\t})\r\n\t\treturn [optimisticCategory, promise]\r\n\t}\r\n\tremove(category: Category, workspaceId: string): OptimisticEmptyResult {\r\n\t\tthis.client.store.dispatch(removeCategory(category.offline_id))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete Category\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/categories/${category.offline_id}/`,\r\n\t\t\t// TODO: Shouldn't be necessary to specify workspace_id here\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tblockers: [category.offline_id],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\t/**\r\n\t * Overwrites the store with whatever categories are on the server.\r\n\t * @returns A promise that resolves to an empty result.\r\n\t * @throws An APIError if the request fails.\r\n\t * @throws An Error if there is no active project, or for any other unexpected error.\r\n\t * @example\r\n\t * ```typescript\r\n\t * try {\r\n\t * \t await sdk.category.refreshStore()\r\n\t * } catch (e) {\r\n\t * \t if (e instanceof APIError) {\r\n\t * \t // handle error\r\n\t * \t return\r\n\t * \t }\r\n\t * \t throw e\r\n\t * }\r\n\t * ```\r\n\t */\r\n\tasync refreshStore(): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst projectId = store.getState().projectReducer.activeProjectId\r\n\t\tif (!projectId) {\r\n\t\t\tthrow new Error(\"No active project\")\r\n\t\t}\r\n\t\tconst [_offlineCategories, promise] = this.fetchAll(projectId)\r\n\t\tconst result = await promise\r\n\t\t// temporary error handling\r\n\t\tstore.dispatch(setCategories(result))\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { Component, Payload, RootState, Submitted } from \"../../typings\"\r\nimport { ApiResult, OptimisticEmptyResult, OptimisticModelResult } from \"../typings\"\r\nimport { offline } from \"../../utils\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport {\r\n\taddComponent,\r\n\taddComponentsInBatches,\r\n\tremoveAllComponentsOfType,\r\n\tremoveComponent,\r\n\tselectComponentsByType,\r\n\tselectComponentsFromComponentType,\r\n\tsetComponents,\r\n\tupdateComponent,\r\n} from \"../../store\"\r\nimport { clientStore } from \"../../contexts\"\r\n\r\nexport class ComponentService extends BaseApiService {\r\n\t// Basic CRUD functions\r\n\tadd(component: Payload<Component>, workspaceId: string): OptimisticModelResult<Component> {\r\n\t\tconst offlineComponent = offline(component)\r\n\t\tthis.client.store.dispatch(addComponent(offlineComponent))\r\n\t\tconst promise = this.enqueueRequest<Component>({\r\n\t\t\tdescription: \"Create Component\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/components/types/${offlineComponent.component_type}/add-components/`,\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tpayload: { components: [offlineComponent] },\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offlineComponent.offline_id],\r\n\t\t})\r\n\t\treturn [offlineComponent, promise]\r\n\t}\r\n\tupdate(component: Component, workspaceId: string): OptimisticModelResult<Component> {\r\n\t\tthis.client.store.dispatch(updateComponent(component))\r\n\t\tconst promise = this.enqueueRequest<Component>({\r\n\t\t\tdescription: \"Edit component\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/components/${component.offline_id}/`,\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tpayload: component,\r\n\t\t\tblockers: [component.offline_id],\r\n\t\t\tblocks: [component.offline_id],\r\n\t\t})\r\n\t\treturn [component, promise]\r\n\t}\r\n\tremove(id: string): OptimisticEmptyResult {\r\n\t\tthis.client.store.dispatch(removeComponent(id))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete issue\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/components/${id}/`,\r\n\t\t\tblockers: [id],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\tdeleteAllByComponentType(componentTypeId: string): Promise<ApiResult<undefined>> {\r\n\t\tif (!clientStore) throw new Error(\"Client store not initialized\")\r\n\t\tconst allComponentsOfType = selectComponentsFromComponentType(componentTypeId)(clientStore.getState())\r\n\t\tconst affectedComponentIds = (allComponentsOfType || []).map((c) => c.offline_id)\r\n\t\tconst affectedOfflineIds = [componentTypeId, ...affectedComponentIds]\r\n\t\tconst { store } = this.client\r\n\t\tconst state: RootState = store.getState()\r\n\t\tconst componentsOfThisType: Component[] | undefined = selectComponentsByType(componentTypeId)(state)\r\n\t\tstore.dispatch(removeAllComponentsOfType(componentTypeId))\r\n\t\tconst promise = this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Batch delete components by component type\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/components/types/${componentTypeId}/delete-all-of-type/`,\r\n\t\t\tblockers: affectedOfflineIds,\r\n\t\t\tblocks: affectedOfflineIds,\r\n\t\t})\r\n\t\tpromise.catch((err) => {\r\n\t\t\t// If the request fails, we need to add the components back to the store\r\n\t\t\tif (componentsOfThisType) {\r\n\t\t\t\tstore.dispatch(addComponentsInBatches(componentsOfThisType))\r\n\t\t\t}\r\n\t\t\tthrow err\r\n\t\t})\r\n\t\treturn promise\r\n\t}\r\n\taddBatch(\r\n\t\tcomponentsToCreate: Payload<Component>[],\r\n\t\tworkspaceId: string,\r\n\t\tcomponentTypeId: string,\r\n\t): Promise<ApiResult<Record<string, Component>>> {\r\n\t\tconst fullComponents: Submitted<Component>[] = componentsToCreate.map((component) => {\r\n\t\t\treturn { ...offline(component), submitted_at: new Date().toISOString() }\r\n\t\t})\r\n\t\tconst { store } = this.client\r\n\t\tstore.dispatch(addComponentsInBatches(fullComponents))\r\n\t\tconst promise = this.enqueueRequest<Record<string, Component>>({\r\n\t\t\tdescription: \"Batch create components\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/components/types/${componentTypeId}/add-components/`,\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tpayload: {\r\n\t\t\t\tcomponents: fullComponents,\r\n\t\t\t},\r\n\t\t\tblockers: [componentTypeId],\r\n\t\t\tblocks: fullComponents.map((c) => c.offline_id),\r\n\t\t})\r\n\t\tvoid promise\r\n\t\t\t.then((result) => {\r\n\t\t\t\tfor (const component of Object.values(result)) {\r\n\t\t\t\t\tstore.dispatch(updateComponent(component))\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t.catch((e) => {\r\n\t\t\t\tfor (const component of fullComponents) {\r\n\t\t\t\t\tstore.dispatch(removeComponent(component.offline_id))\r\n\t\t\t\t}\r\n\t\t\t\tthrow e\r\n\t\t\t})\r\n\t\treturn promise\r\n\t}\r\n\r\n\tasync refreshStore(replace: boolean): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<Component[]>({\r\n\t\t\tdescription: \"Get components\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/components/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tif (replace) {\r\n\t\t\tstore.dispatch(setComponents(result))\r\n\t\t} else {\r\n\t\t\tstore.dispatch(addComponentsInBatches(result))\r\n\t\t}\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { addStageCompletion, addStageCompletions, ComponentStageCompletion, removeStageCompletions } from \"../../store\"\r\nimport { OptimisticEmptyResult, OptimisticModelResult } from \"../typings\"\r\nimport { offline } from \"../../utils\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { CompletedStagesMapping, Created, Payload } from \"../../typings\"\r\n\r\nexport class ComponentStageCompletionService extends BaseApiService {\r\n\tadd(componentId: string, stageId: string): OptimisticModelResult<ComponentStageCompletion> {\r\n\t\tconst { store } = this.client\r\n\t\tconst componentType = store.getState().componentReducer.components[componentId]?.component_type\r\n\t\tif (!componentType) {\r\n\t\t\tthrow new Error(`Component ${componentId} not found`)\r\n\t\t}\r\n\t\tconst offlineCompletion = offline({\r\n\t\t\tcomponent: componentId,\r\n\t\t\tstage: stageId,\r\n\t\t})\r\n\r\n\t\tstore.dispatch(addStageCompletion(offlineCompletion))\r\n\t\tconst promise = this.enqueueRequest<Created<ComponentStageCompletion>>({\r\n\t\t\tdescription: \"Mark stage as completed\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/components/types/${componentType}/complete-stages/`,\r\n\t\t\t// TODO: Add submitted_at to model\r\n\t\t\tpayload: { completions: [{ ...offlineCompletion, submitted_at: new Date().getTime() / 1000 }] },\r\n\t\t\tblockers: [componentId, stageId],\r\n\t\t\tblocks: [offlineCompletion.offline_id],\r\n\t\t})\r\n\t\treturn [offlineCompletion, promise]\r\n\t}\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<CompletedStagesMapping>({\r\n\t\t\tdescription: \"Get completed stages\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/component-stage-completions/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tstore.dispatch(addStageCompletions(result))\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a collection of ComponentStageCompletions, marking the referenced stages as completed for the referenced\r\n\t * components. It's REQUIRED that all components referenced all have the SAME component type.\r\n\t * @param componentTypeId The ID of the component type for which we are completing stages (we can only complete\r\n\t * stages for one component type at a time)\r\n\t * @param stageCompletions\r\n\t */\r\n\tasync bulkAdd(componentTypeId: string, stageCompletions: Payload<ComponentStageCompletion>[]) {\r\n\t\tconst offlineStagesCompletions = stageCompletions.map((completion) => {\r\n\t\t\treturn offline(completion)\r\n\t\t})\r\n\t\tconst asMapping: CompletedStagesMapping = {}\r\n\t\tfor (const completion of stageCompletions) {\r\n\t\t\tconst stageToCompletionDateMapping = asMapping[completion.component] || {}\r\n\t\t\tstageToCompletionDateMapping[completion.stage] = new Date().toISOString()\r\n\t\t\tasMapping[completion.component] = stageToCompletionDateMapping\r\n\t\t}\r\n\t\tthis.client.store.dispatch(addStageCompletions(asMapping))\r\n\t\tawait this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Mark multiple stage as completed\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/components/types/${componentTypeId}/complete-stages/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tcompletions: offlineStagesCompletions,\r\n\t\t\t},\r\n\t\t\tblockers: [\r\n\t\t\t\tcomponentTypeId,\r\n\t\t\t\t...stageCompletions.map((c) => c.component),\r\n\t\t\t\t...stageCompletions.map((c) => c.stage),\r\n\t\t\t],\r\n\t\t\tblocks: offlineStagesCompletions.map((c) => c.offline_id),\r\n\t\t})\r\n\t}\r\n\tbulkDelete(stageId: string, componentIds: string[]): OptimisticEmptyResult {\r\n\t\tconst completionsToRemove: ComponentStageCompletion[] = componentIds.map((componentId) => {\r\n\t\t\treturn {\r\n\t\t\t\tcomponent: componentId,\r\n\t\t\t\tstage: stageId,\r\n\t\t\t}\r\n\t\t})\r\n\t\tthis.client.store.dispatch(removeStageCompletions(completionsToRemove))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: `Undo stage for ${componentIds.length} component(s)`,\r\n\t\t\t// TODO: Rename to setCompletedStages\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/components/stages/${stageId}/undo-stages/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tcomponents: componentIds,\r\n\t\t\t},\r\n\t\t\tblockers: [stageId, ...componentIds],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { ComponentStage, ComponentStagePayload, Payload } from \"../../typings\"\r\nimport { offline } from \"../../utils\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { addStages, removeStages, selectStagesFromStageIds, updateStages } from \"../../store\"\r\n\r\nexport class ComponentStageService extends BaseApiService {\r\n\tasync bulkCreateStages(\r\n\t\tstagesToSubmit: Payload<ComponentStagePayload>[],\r\n\t\tcomponentTypeId: string,\r\n\t\tworkspaceId: string,\r\n\t): Promise<ComponentStage[]> {\r\n\t\tconst payload: ComponentStagePayload[] = stagesToSubmit.map((stage) => {\r\n\t\t\treturn offline(stage)\r\n\t\t})\r\n\t\tconst fullStages = payload.map((stage) => {\r\n\t\t\treturn { ...stage, component_type: componentTypeId }\r\n\t\t})\r\n\t\tthis.client.store.dispatch(addStages(fullStages))\r\n\t\treturn this.enqueueRequest<ComponentStage[]>({\r\n\t\t\tdescription: \"Add component stages\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/components/types/${componentTypeId}/add-stages/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tstages: payload,\r\n\t\t\t},\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tblockers: [componentTypeId, workspaceId],\r\n\t\t\tblocks: payload.map(({ offline_id }) => offline_id),\r\n\t\t})\r\n\t}\r\n\r\n\tasync bulkUpdateStages(stagesToUpdate: ComponentStage[], componentTypeId: string): Promise<ComponentStage[]> {\r\n\t\tconst store = this.client.store\r\n\t\tconst state = store.getState()\r\n\t\tconst prevStages: ComponentStage[] | undefined = selectStagesFromStageIds(\r\n\t\t\tstagesToUpdate.map(({ offline_id }) => offline_id),\r\n\t\t)(state)\r\n\r\n\t\tif (!prevStages) {\r\n\t\t\tthrow new Error(\"Could not find the desired stages to update within the store\")\r\n\t\t}\r\n\r\n\t\tstore.dispatch(updateStages(stagesToUpdate))\r\n\t\treturn this.enqueueRequest<ComponentStage[]>({\r\n\t\t\tdescription: \"Edit component stages\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/components/types/${componentTypeId}/bulk-update-stages/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tstages: stagesToUpdate,\r\n\t\t\t},\r\n\t\t\tblockers: [componentTypeId],\r\n\t\t\tblocks: stagesToUpdate.map(({ offline_id }) => offline_id),\r\n\t\t}).catch((e) => {\r\n\t\t\t// restore stages in store if request fails\r\n\t\t\tstore.dispatch(updateStages(prevStages))\r\n\t\t\tthrow e\r\n\t\t})\r\n\t}\r\n\r\n\tasync bulkDelete(idsToDelete: string[]): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(removeStages(idsToDelete))\r\n\t\treturn this.enqueueRequest({\r\n\t\t\tdescription: \"Delete component stages\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: \"/components/stages/bulk-delete/\",\r\n\t\t\tpayload: {\r\n\t\t\t\tstage_ids: idsToDelete,\r\n\t\t\t},\r\n\t\t\tblockers: idsToDelete,\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync update(componentStage: ComponentStage): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(addStages([componentStage]))\r\n\t\treturn this.enqueueRequest({\r\n\t\t\tdescription: \"Update component stage\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/components/stages/${componentStage.offline_id}/`,\r\n\t\t\tpayload: componentStage,\r\n\t\t\tblockers: [componentStage.offline_id],\r\n\t\t\tblocks: [componentStage.offline_id],\r\n\t\t})\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<ComponentStage[]>({\r\n\t\t\tdescription: \"Get component stages\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/component-stages/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tstore.dispatch(addStages(result))\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { offline } from \"../../utils\"\r\nimport {\r\n\taddComponentType,\r\n\taddStages,\r\n\tdeleteComponentType,\r\n\tremoveStages,\r\n\tselectComponentType,\r\n\tselectStagesFromComponentType,\r\n\tsetComponentTypes,\r\n} from \"../../store\"\r\nimport { ComponentStage, ComponentType, Payload } from \"../../typings\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { OptimisticModelResult } from \"../typings\"\r\n\r\nexport class ComponentTypeService extends BaseApiService {\r\n\tadd(componentType: Payload<ComponentType>): OptimisticModelResult<ComponentType> {\r\n\t\tconst offlineComponentType = offline(componentType)\r\n\t\tconst { store } = this.client\r\n\t\tconst activeProjectId = store.getState().projectReducer.activeProjectId\r\n\r\n\t\tstore.dispatch(addComponentType(offlineComponentType))\r\n\t\tconst promise = this.enqueueRequest<ComponentType>({\r\n\t\t\tdescription: \"Create ComponentType\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/projects/${activeProjectId}/component-types/`,\r\n\t\t\tpayload: { ...offlineComponentType },\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offlineComponentType.offline_id],\r\n\t\t})\r\n\t\treturn [offlineComponentType, promise]\r\n\t}\r\n\r\n\tupdate(componentType: ComponentType): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(addComponentType(componentType))\r\n\t\treturn this.enqueueRequest({\r\n\t\t\tdescription: \"Update ComponentType\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/components/types/${componentType.offline_id}/`,\r\n\t\t\tpayload: componentType,\r\n\t\t\tblockers: [componentType.offline_id],\r\n\t\t\tblocks: [componentType.offline_id],\r\n\t\t})\r\n\t}\r\n\tasync delete(componentTypeId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\t// Get Component Stages in state associated with Component Type to be deleted\r\n\t\tconst componentType = selectComponentType(componentTypeId)(state)\r\n\t\tif (!componentType) {\r\n\t\t\tthrow new Error(\"Expected componentType to exist\")\r\n\t\t}\r\n\t\tconst componentTypeStages = selectStagesFromComponentType(componentTypeId)(state) ?? []\r\n\t\tstore.dispatch(\r\n\t\t\tremoveStages(\r\n\t\t\t\tcomponentTypeStages.map((componentTypeStage: ComponentStage) => componentTypeStage.offline_id),\r\n\t\t\t),\r\n\t\t)\r\n\t\tstore.dispatch(deleteComponentType(componentTypeId))\r\n\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete ComponentType\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/components/types/${componentTypeId}/`,\r\n\t\t\tblockers: [componentTypeId],\r\n\t\t\tblocks: [],\r\n\t\t}).catch((e) => {\r\n\t\t\tstore.dispatch(addComponentType(componentType))\r\n\t\t\tstore.dispatch(addStages(componentTypeStages))\r\n\t\t\tthrow e\r\n\t\t})\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<ComponentType[]>({\r\n\t\t\tdescription: \"Get component types\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/component-types/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tstore.dispatch(setComponentTypes(result))\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { Created, IssueComment, Payload, Submitted } from \"../../typings\"\r\nimport { offline, onlyUniqueOfflineIds, truncate } from \"../../utils\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { addOrReplaceIssueComment, removeIssueComment, setIssueComments } from \"../../store\"\r\nimport { OptimisticModelResult } from \"../typings.ts\"\r\n\r\nexport class IssueCommentService extends BaseApiService {\r\n\tadd(comment: Omit<Payload<IssueComment>, \"author\">): OptimisticModelResult<IssueComment> {\r\n\t\tconst offlinePayload: Omit<IssueComment, \"author\" | \"created_at\"> = offline(comment)\r\n\t\tconst submittedAt = new Date().toISOString()\r\n\t\tconst { store } = this.client\r\n\t\tconst offlineComment: Submitted<IssueComment> = {\r\n\t\t\t...offlinePayload,\r\n\t\t\tauthor: store.getState().userReducer.currentUser.id,\r\n\t\t\tcreated_at: submittedAt,\r\n\t\t}\r\n\t\tstore.dispatch(addOrReplaceIssueComment(offlineComment))\r\n\t\tconst promise = this.enqueueRequest<Created<IssueComment>>({\r\n\t\t\tdescription: `${truncate(comment.content, 80)}`,\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/issues/${comment.issue}/comment/`,\r\n\t\t\tpayload: { ...offlinePayload, submitted_at: submittedAt },\r\n\t\t\tblockers: [comment.issue],\r\n\t\t\tblocks: [offlinePayload.offline_id],\r\n\t\t})\r\n\t\treturn [offlineComment, promise]\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<Created<IssueComment>[]>({\r\n\t\t\tdescription: \"Get comments\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\t// TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\r\n\t\tlet filteredResult = result.filter(onlyUniqueOfflineIds)\r\n\t\tfilteredResult = filteredResult.map((comment) => {\r\n\t\t\treturn { ...comment }\r\n\t\t})\r\n\t\tif (result.length !== filteredResult.length) {\r\n\t\t\tconsole.error(\r\n\t\t\t\t`Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`,\r\n\t\t\t)\r\n\t\t}\r\n\t\tstore.dispatch(setIssueComments(filteredResult))\r\n\t}\r\n\r\n\tupdate(comment: Submitted<IssueComment>): OptimisticModelResult<IssueComment> {\r\n\t\tthis.client.store.dispatch(addOrReplaceIssueComment(comment))\r\n\t\tconst promise = this.enqueueRequest<Created<IssueComment>>({\r\n\t\t\tdescription: `Edit comment: ${truncate(comment.content, 80)}`,\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/issues/comments/${comment.offline_id}/`,\r\n\t\t\tpayload: comment,\r\n\t\t\tblockers: [comment.issue],\r\n\t\t\tblocks: [comment.offline_id],\r\n\t\t})\r\n\t\treturn [comment, promise]\r\n\t}\r\n\r\n\tremove(offline_id: string): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(removeIssueComment(offline_id))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete comment\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/issues/comments/${offline_id}/`,\r\n\t\t\tblockers: [offline_id],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { OptimisticModelResult, OptimisticMultipleModelResult } from \"../typings\"\r\nimport { Created, Issue, Submitted } from \"../../typings\"\r\nimport { offline, onlyUniqueOfflineIds } from \"../../utils\"\r\nimport {\r\n\taddAttachments,\r\n\taddIssue,\r\n\taddToRecentIssues,\r\n\tremoveAttachmentsOfIssue,\r\n\tremoveIssue,\r\n\tselectPhotoAttachmentsOfIssue,\r\n\tsetIssues,\r\n\tupdateIssue,\r\n} from \"../../store\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { DEFAULT_ISSUE_PRIORITY, DEFAULT_ISSUE_STATUS } from \"../../constants\"\r\nimport { unsafeShowToast } from \"@overmap-ai/blocks\"\r\nimport { APIError } from \"../errors.ts\"\r\n\r\n/**\r\n * Handles CRUD operations on issues\r\n */\r\nexport class IssueService extends BaseApiService {\r\n\t// Basic CRUD functions\r\n\t// TODO: Once all models are represented in `Created<TModel>`, use `Created` in `OptimisticModelResult`, so we don't\r\n\t// have to repeat it for all optimistic model results (all optimistic results are created).\r\n\tadd(issue: Issue): OptimisticModelResult<Issue> {\r\n\t\tconst { store } = this.client\r\n\t\tconst dateWithoutMilliseconds = new Date()\r\n\t\tconst state = store.getState()\r\n\t\tconst workspaceId = state.workspaceReducer.activeWorkspaceId\r\n\t\tconst currentUserId = state.userReducer.currentUser.id\r\n\t\tdateWithoutMilliseconds.setMilliseconds(0)\r\n\r\n\t\tif (!workspaceId) {\r\n\t\t\tthrow new Error(\"No active workspace ID while creating issue.\")\r\n\t\t}\r\n\r\n\t\tconst issuePayload: Submitted<Issue> = offline({\r\n\t\t\t...issue,\r\n\t\t\tsubmitted_at: dateWithoutMilliseconds.toISOString(),\r\n\t\t\tindex_workspace: workspaceId,\r\n\t\t\tcreated_by: currentUserId,\r\n\t\t\tstatus: issue.status ?? DEFAULT_ISSUE_STATUS,\r\n\t\t\tpriority: issue.priority ?? DEFAULT_ISSUE_PRIORITY,\r\n\t\t})\r\n\r\n\t\tstore.dispatch(addIssue(issuePayload))\r\n\t\tstore.dispatch(addToRecentIssues(issuePayload.offline_id))\r\n\r\n\t\tconst promise = this.enqueueRequest<Created<Issue>>({\r\n\t\t\tdescription: \"Create issue\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: \"/issues/\",\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId,\r\n\t\t\t},\r\n\t\t\tpayload: issuePayload,\r\n\t\t\tblockers: [\r\n\t\t\t\t...(issuePayload.index_workspace ? [issuePayload.index_workspace] : []),\r\n\t\t\t\t...issuePayload.visible_in_workspaces,\r\n\t\t\t],\r\n\t\t\tblocks: [issuePayload.offline_id],\r\n\t\t})\r\n\t\tvoid promise\r\n\t\t\t.then((result: Created<Issue>) => {\r\n\t\t\t\tstore.dispatch(updateIssue(result)) // Updates the index in the store\r\n\t\t\t})\r\n\t\t\t.catch((error) => {\r\n\t\t\t\tconsole.error(error)\r\n\t\t\t\tif (error instanceof APIError) {\r\n\t\t\t\t\tunsafeShowToast?.({\r\n\t\t\t\t\t\ttitle: \"Could not create issue\",\r\n\t\t\t\t\t\tdescription: \"An unexpected error occurred while creating the issue.\",\r\n\t\t\t\t\t})\r\n\t\t\t\t}\r\n\t\t\t\tstore.dispatch(removeIssue(issuePayload.offline_id))\r\n\t\t\t\tthrow error\r\n\t\t\t})\r\n\t\treturn [issuePayload, promise]\r\n\t}\r\n\r\n\tfetchAll(projectId: number): OptimisticMultipleModelResult<Issue> {\r\n\t\tconst promise: Promise<Created<Issue>[]> = this.enqueueRequest<Created<Issue>[]>({\r\n\t\t\tdescription: \"Get issues\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${projectId}/issues/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t}).then((result) => {\r\n\t\t\tconst filteredResult = result.filter(onlyUniqueOfflineIds)\r\n\t\t\tif (result.length !== filteredResult.length) {\r\n\t\t\t\tconsole.error(\r\n\t\t\t\t\t`Received duplicate issues from the API (new length ${filteredResult.length});\r\n\t\t\t\t\t\t filtered in browser.`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t\treturn filteredResult\r\n\t\t})\r\n\r\n\t\tconst offlineIssues = Object.values(this.client.store.getState().issueReducer.issues)\r\n\t\treturn [offlineIssues, promise]\r\n\t}\r\n\r\n\tupdate(issue: Submitted<Partial<Issue>>): OptimisticModelResult<Issue> {\r\n\t\tthis.client.store.dispatch(updateIssue(issue))\r\n\t\tconst promise = this.enqueueRequest<Created<Issue>>({\r\n\t\t\tdescription: \"Edit issue\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/issues/${issue.offline_id}/`,\r\n\t\t\tpayload: issue,\r\n\t\t\tblockers: [issue.offline_id],\r\n\t\t\tblocks: [issue.offline_id],\r\n\t\t})\r\n\t\tconst fullIssue = this.client.store.getState().issueReducer.issues[issue.offline_id]!\r\n\t\treturn [fullIssue, promise]\r\n\t}\r\n\r\n\tasync remove(id: string): Promise<undefined> {\r\n\t\tconst state = this.client.store.getState()\r\n\t\tconst backup = state.issueReducer.issues[id]\r\n\t\tif (!backup) {\r\n\t\t\tthrow new Error(`No issue with id ${id} found in the store`)\r\n\t\t}\r\n\t\tconst attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue_id === id)\r\n\t\tconst attachmentsOfIssue = selectPhotoAttachmentsOfIssue(id)(state)\r\n\t\tthis.client.store.dispatch(removeIssue(id))\r\n\t\tif (attachmentsOfIssue) {\r\n\t\t\tthis.client.store.dispatch(removeAttachmentsOfIssue(id))\r\n\t\t}\r\n\t\ttry {\r\n\t\t\t// REASON: Need to await to trigger the catch block.\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\r\n\t\t\treturn await this.enqueueRequest<undefined>({\r\n\t\t\t\tdescription: \"Delete issue\",\r\n\t\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\t\turl: `/issues/${id}/`,\r\n\t\t\t\tblockers: [id],\r\n\t\t\t\tblocks: [],\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\tthis.client.store.dispatch(addIssue(backup))\r\n\t\t\tthis.client.store.dispatch(addAttachments(attachments))\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\t// Special functions\r\n\tasync refreshStore(): Promise<undefined> {\r\n\t\t// TODO: This is called far too often.\r\n\t\tconst { store } = this.client\r\n\t\tconst projectId = store.getState().projectReducer.activeProjectId\r\n\t\tif (!projectId) {\r\n\t\t\tthrow new Error(\"No active project\")\r\n\t\t}\r\n\t\tconst [_offlineIssues, promise] = this.fetchAll(projectId)\r\n\t\tconst result = await promise\r\n\t\tstore.dispatch(setIssues(result))\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { Category, Organization, Project, User, Workspace } from \"../../typings\"\r\nimport {\r\n\taddOrReplaceCategories,\r\n\taddOrReplaceProjects,\r\n\taddOrReplaceWorkspaces,\r\n\tresetRecentIssues,\r\n\tsetActiveOrganizationId,\r\n\tsetActiveProjectId,\r\n\tsetActiveWorkspaceId,\r\n\tsetAttachments,\r\n\tsetCategories,\r\n\tsetCurrentUser,\r\n\tsetIsFetchingInitialData,\r\n\tsetOrganizations,\r\n\tsetProjects,\r\n\tsetUsers,\r\n\tsetWorkspaces,\r\n} from \"../../store\"\r\nimport { HttpMethod } from \"../../enums\"\r\n\r\nexport interface InitialAPIData {\r\n\tprojects: (Project & {\r\n\t\tworkspaces: {\r\n\t\t\tcategories?: Category[]\r\n\t\t\toffline_id: string\r\n\t\t\tname: string\r\n\t\t\tabbreviation: string\r\n\t\t\tpermitted: boolean\r\n\t\t}[]\r\n\t})[]\r\n\torganizations: Organization[]\r\n\tuser: User\r\n}\r\n\r\nexport class MainService extends BaseApiService {\r\n\tasync fetchInitialData(replaceExisting: boolean, uuid?: string): Promise<InitialAPIData> {\r\n\t\tif (replaceExisting) {\r\n\t\t\tthis.client.store.dispatch(setIsFetchingInitialData(true))\r\n\t\t}\r\n\t\treturn this.enqueueRequest<InitialAPIData>({\r\n\t\t\tuuid,\r\n\t\t\tdescription: \"Get initial data\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: \"/main/initial-data/\",\r\n\t\t\tpayload: {},\r\n\t\t\tisAuthNeeded: true,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t}).then((result) => {\r\n\t\t\tvoid this._processInitialData(result, replaceExisting)\r\n\t\t\treturn result\r\n\t\t})\r\n\t}\r\n\r\n\tasync fetchUsers(projectId: number): Promise<User[]> {\r\n\t\treturn this.enqueueRequest({\r\n\t\t\tdescription: \"Fetch users\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${projectId}/users/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\t// TODO:\r\n\t// Don't accept updateStore in ComponentService.list. Just return the offline objects and promise. Here, if\r\n\t// overwrite, use setComponents. Otherwise, use bulkAddComponents.\r\n\r\n\tasync _processInitialData(data: InitialAPIData, overwrite: boolean) {\r\n\t\tconst workspaces: Record<string, Workspace> = {}\r\n\t\tconst projects: Project[] = []\r\n\t\tconst categories: Category[] = []\r\n\t\tconst projectsData = data.projects\r\n\r\n\t\tconst { store } = this.client\r\n\t\tconst oldProjectId = store.getState().projectReducer.activeProjectId\r\n\t\tlet currentProjectId: number | undefined | null = oldProjectId ?? projectsData[0]?.id\r\n\t\tstore.dispatch(setActiveProjectId(currentProjectId ?? null))\r\n\t\tlet isProjectIdValid = false\r\n\r\n\t\tfor (const projectData of projectsData) {\r\n\t\t\tprojects.push({\r\n\t\t\t\tid: projectData.id,\r\n\t\t\t\tname: projectData.name,\r\n\t\t\t\towner_organization: projectData.owner_organization,\r\n\t\t\t\towner_user: projectData.owner_user,\r\n\t\t\t\tbounds: projectData.bounds,\r\n\t\t\t})\r\n\t\t\tif (currentProjectId === projectData.id) {\r\n\t\t\t\tisProjectIdValid = true\r\n\t\t\t\tfor (const workspaceData of projectData.workspaces) {\r\n\t\t\t\t\tconst workspace = { ...workspaceData, project: projectData.id }\r\n\t\t\t\t\tif (workspace.categories) {\r\n\t\t\t\t\t\tfor (const category of workspace.categories) {\r\n\t\t\t\t\t\t\tcategories.push(category)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdelete workspace.categories\r\n\t\t\t\t\tworkspaces[workspace.offline_id] = workspace\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tstore.dispatch(setCurrentUser(data.user))\r\n\t\tconst organizationsData = data.organizations\r\n\t\tstore.dispatch(setOrganizations(organizationsData))\r\n\r\n\t\t// TODO: Add ability to select if there are multiple\r\n\t\tconst firstOrg = organizationsData[0]\r\n\t\tconst currProjObj = projects.find((project) => project.id === currentProjectId)\r\n\t\tconst isOrgProject = !!currProjObj?.owner_organization\r\n\t\tif (isOrgProject && currProjObj.owner_organization) {\r\n\t\t\tstore.dispatch(setActiveOrganizationId(currProjObj.owner_organization))\r\n\t\t} else if (firstOrg) {\r\n\t\t\tconsole.warn(\r\n\t\t\t\t\"No active organization; using the first available one. TODO: No active organization in personal projects.\",\r\n\t\t\t)\r\n\t\t\t// TODO: Should not set an active organization in a personal project\r\n\t\t\tstore.dispatch(setActiveOrganizationId(firstOrg.id))\r\n\t\t}\r\n\r\n\t\tif (!isProjectIdValid) {\r\n\t\t\tif (projects.length !== 0) {\r\n\t\t\t\tcurrentProjectId = projects[0]!.id\r\n\t\t\t\tstore.dispatch(setActiveProjectId(currentProjectId))\r\n\t\t\t\t// If `projects` has a length, so does `projectsData`\r\n\t\t\t\tconst projectData = projectsData[0]!\r\n\t\t\t\tfor (const workspaceData of projectData.workspaces) {\r\n\t\t\t\t\tconst workspace = { ...workspaceData, project: projectData.id }\r\n\t\t\t\t\tif (workspace.categories) {\r\n\t\t\t\t\t\tfor (const category of workspace.categories) {\r\n\t\t\t\t\t\t\tcategories.push(category)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdelete workspace.categories\r\n\t\t\t\t\tworkspaces[workspace.offline_id] = workspace\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tcurrentProjectId = null\r\n\t\t\t\tstore.dispatch(setActiveProjectId(currentProjectId))\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (currentProjectId) {\r\n\t\t\tconst usersResultPromise = this.fetchUsers(currentProjectId)\r\n\t\t\tconst projectAccessRefreshPromise = this.client.projectAccesses.refreshStore()\r\n\t\t\tconst organizationAccessRefreshPromise = this.client.organizationAccess.refreshStore()\r\n\t\t\tconst usersResult = await usersResultPromise\r\n\t\t\tawait projectAccessRefreshPromise\r\n\t\t\tawait organizationAccessRefreshPromise\r\n\t\t\tstore.dispatch(setUsers(usersResult))\r\n\t\t}\r\n\r\n\t\tlet currentWorkspaceId: string | undefined\r\n\t\tconst oldWorkspaceId = this.client.store.getState().workspaceReducer.activeWorkspaceId\r\n\t\tif (overwrite || !oldWorkspaceId) {\r\n\t\t\tcurrentWorkspaceId = Object.values(workspaces).at(0)?.offline_id\r\n\t\t} else {\r\n\t\t\tcurrentWorkspaceId = oldWorkspaceId\r\n\t\t}\r\n\r\n\t\tif (currentWorkspaceId && currentProjectId) {\r\n\t\t\tstore.dispatch(setActiveWorkspaceId(currentWorkspaceId))\r\n\r\n\t\t\t// TODO: Request all requests at once, then write to the store in the correct order.\r\n\t\t\t// We can even return a `initial_color` for components as a backup before stages and types are loaded.\r\n\t\t\t// At least use `blocks` and `blockers` instead of chaining.\r\n\t\t\t// TODO: Only overwrite if `overwrite === true`\r\n\t\t\tvoid this.client.categories.refreshStore().then(() => {\r\n\t\t\t\tvoid this.client.issues.refreshStore().then(() => {\r\n\t\t\t\t\tvoid this.client.issueComments.refreshStore().then()\r\n\t\t\t\t})\r\n\t\t\t})\r\n\t\t\tvoid this.client.projectFiles.refreshStore().then()\r\n\t\t\tvoid this.client.componentTypes.refreshStore().then(() => {\r\n\t\t\t\tvoid this.client.componentStages.refreshStore().then(() => {\r\n\t\t\t\t\tvoid this.client.components.refreshStore(overwrite).then()\r\n\t\t\t\t})\r\n\t\t\t\tvoid this.client.componentStageCompletions.refreshStore().then()\r\n\t\t\t})\r\n\t\t\tvoid this.client.userForms.refreshStore().then(() => {\r\n\t\t\t\tvoid this.client.userFormSubmissions.refreshStore().then()\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\t// TODO: Everything in the `if (currentWorkspace)` block above should go in here:\r\n\t\tif (currentProjectId) {\r\n\t\t\tconst [_offlineAttachments, promise] = this.client.attachments.fetchAll(currentProjectId)\r\n\t\t\tvoid promise.then((result) => {\r\n\t\t\t\tstore.dispatch(setAttachments(result))\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\tstore.dispatch(setIsFetchingInitialData(false))\r\n\r\n\t\t// TODO: Follow same pattern as above (refreshStore)\r\n\t\tif (overwrite) {\r\n\t\t\tconsole.log(\"Overwriting data\")\r\n\t\t\tstore.dispatch(setProjects(projects))\r\n\t\t\tstore.dispatch(setWorkspaces(workspaces))\r\n\t\t\tstore.dispatch(setCategories(categories))\r\n\t\t\tstore.dispatch(resetRecentIssues())\r\n\t\t} else {\r\n\t\t\tconsole.log(\"Updating data (collisions will be replaced)\")\r\n\t\t\tstore.dispatch(addOrReplaceProjects(projects))\r\n\t\t\tstore.dispatch(addOrReplaceWorkspaces(workspaces))\r\n\t\t\tstore.dispatch(addOrReplaceCategories(categories))\r\n\t\t}\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { OptimisticEmptyResult, OptimisticGenericResult, OptimisticModelResult } from \"../typings\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { removeProjectAccess, removeUser, setProjectAccesses, updateProjectAccess } from \"../../store\"\r\nimport { ProjectAccess } from \"../../typings\"\r\n\r\n/**\r\n * Handles the creation of ProjectAccess Service\r\n */\r\nexport class ProjectAccessService extends BaseApiService {\r\n\tfetchAll(projectId: number): OptimisticGenericResult<ProjectAccess[]> {\r\n\t\tconst { store } = this.client\r\n\t\tconst promise = this.enqueueRequest<ProjectAccess[]>({\r\n\t\t\tdescription: \"Get project accesses\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${projectId}/access/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tconst offlineProjectAccesses = Object.values(store.getState().projectAccessReducer.projectAccesses)\r\n\t\treturn [offlineProjectAccesses, promise]\r\n\t}\r\n\r\n\tupdate(projectAccess: ProjectAccess): OptimisticModelResult<ProjectAccess> {\r\n\t\tthis.client.store.dispatch(updateProjectAccess(projectAccess))\r\n\t\tconst promise = this.enqueueRequest<ProjectAccess>({\r\n\t\t\tdescription: \"Edit project access\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/access/${projectAccess.offline_id}/`,\r\n\t\t\tpayload: projectAccess,\r\n\t\t\tblockers: [projectAccess.offline_id],\r\n\t\t\tblocks: [projectAccess.offline_id],\r\n\t\t})\r\n\t\treturn [projectAccess, promise]\r\n\t}\r\n\t// TODO: Re-add user to project if removal fails\r\n\tremove(projectAccess: ProjectAccess): OptimisticEmptyResult {\r\n\t\tconst { store } = this.client\r\n\r\n\t\tstore.dispatch(removeProjectAccess(projectAccess))\r\n\t\tstore.dispatch(removeUser(projectAccess.user))\r\n\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete project access\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/access/${projectAccess.offline_id}/`,\r\n\t\t\tblockers: [projectAccess.offline_id],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst projectId = state.projectReducer.activeProjectId\r\n\t\tconst currentUser = state.userReducer.currentUser\r\n\t\tif (!projectId) {\r\n\t\t\tthrow new Error(\"No active project\")\r\n\t\t}\r\n\t\tconst [_offlineProjectAccesses, promise] = this.fetchAll(projectId)\r\n\t\tconst result: ProjectAccess[] = await promise\r\n\t\tconst activeProjectAccess = result.find((projectAccess) => projectAccess.user === currentUser.id)\r\n\t\tif (!activeProjectAccess) {\r\n\t\t\tthrow new Error(\"Current user does not have a project access instance\")\r\n\t\t}\r\n\t\tstore.dispatch(setProjectAccesses(result))\r\n\t}\r\n}\r\n","import { HttpMethod } from \"enums/api\"\r\nimport { ProjectFile } from \"typings/models/projects\"\r\nimport { OptimisticGenericResult, SDKRequest } from \"../typings\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport {\r\n\taddOrReplaceProjectFile,\r\n\taddOrReplaceProjectFiles,\r\n\tremoveProjectFile,\r\n\tsaveActiveProjectFileBounds,\r\n\tsetActiveProjectFileId,\r\n\tsetIsImportingProjectFile,\r\n} from \"store/slices/projectFileSlice\"\r\n\r\n/**\r\n * Handles creation and caching of ProjectFiles\r\n */\r\nexport class ProjectFileService extends BaseApiService {\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<ProjectFile[]>({\r\n\t\t\tdescription: \"Get project files\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/files/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tstore.dispatch(addOrReplaceProjectFiles(result))\r\n\t}\r\n\r\n\tasync saveExisting(file: ProjectFile): Promise<ProjectFile> {\r\n\t\tif (!file.offline_id) {\r\n\t\t\tthrow new Error(\r\n\t\t\t\t\"You can only use this method to save existing project files. The one provided has no offline_id.\",\r\n\t\t\t)\r\n\t\t}\r\n\t\tconst editableData: { file?: unknown } = { ...file }\r\n\t\tdelete editableData.file\r\n\t\tconst promise = this.enqueueRequest<ProjectFile>({\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/projects/files/${file.offline_id}/`,\r\n\t\t\tpayload: editableData,\r\n\t\t\tblockers: [file.offline_id],\r\n\t\t\tblocks: [file.offline_id],\r\n\t\t})\r\n\t\tvoid promise.then((result) => {\r\n\t\t\tthis.client.store.dispatch(addOrReplaceProjectFile(result))\r\n\t\t})\r\n\t\treturn promise\r\n\t}\r\n\tsaveActive(): OptimisticGenericResult<ProjectFile> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst activeProjectFileId = state.projectFileReducer.activeProjectFileId\r\n\t\tconst activeProjectId = state.projectReducer.activeProjectId\r\n\t\tif (!activeProjectFileId) {\r\n\t\t\tthrow new Error(\"No active project file\")\r\n\t\t}\r\n\t\tif (!activeProjectId) {\r\n\t\t\tthrow new Error(\"No active project\")\r\n\t\t}\r\n\t\tconst activeProjectFile = state.projectFileReducer.projectFiles[activeProjectFileId]\r\n\t\tif (!activeProjectFile) {\r\n\t\t\tthrow new Error(\"No active project file\")\r\n\t\t}\r\n\r\n\t\tlet requestDetails: SDKRequest | Promise<SDKRequest>\r\n\t\tconst existing = typeof activeProjectFile.file === \"string\" && !activeProjectFile.file.startsWith(\"blob:\")\r\n\t\tif (existing) {\r\n\t\t\tconst editableData: { file?: unknown } = { ...activeProjectFile }\r\n\t\t\tdelete editableData.file\r\n\t\t\trequestDetails = {\r\n\t\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\t\turl: `/projects/files/${activeProjectFileId}/`,\r\n\t\t\t\tpayload: editableData,\r\n\t\t\t\tblockers: [activeProjectFileId],\r\n\t\t\t\tblocks: [activeProjectFileId],\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\trequestDetails = new Promise<SDKRequest>((resolve, reject) => {\r\n\t\t\t\tthis.client.files\r\n\t\t\t\t\t.uploadFileToS3(activeProjectFile.file_sha1)\r\n\t\t\t\t\t.then(([fileProps]) => {\r\n\t\t\t\t\t\tresolve({\r\n\t\t\t\t\t\t\tmethod: HttpMethod.POST,\r\n\t\t\t\t\t\t\turl: `/projects/${activeProjectId}/files/`,\r\n\t\t\t\t\t\t\tpayload: {\r\n\t\t\t\t\t\t\t\t...activeProjectFile,\r\n\t\t\t\t\t\t\t\tbounds: JSON.stringify(activeProjectFile.bounds),\r\n\t\t\t\t\t\t\t\t...fileProps,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tblockers: [activeProjectFileId],\r\n\t\t\t\t\t\t\tblocks: [activeProjectFileId],\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t})\r\n\t\t\t\t\t.catch(reject)\r\n\t\t\t})\r\n\t\t}\r\n\t\tconst promise = Promise.resolve(requestDetails).then((requestDetails) => {\r\n\t\t\treturn this.enqueueRequest<ProjectFile>(requestDetails)\r\n\t\t})\r\n\t\tvoid promise.then((result) => {\r\n\t\t\tstore.dispatch(addOrReplaceProjectFile(result))\r\n\t\t})\r\n\t\tstore.dispatch(saveActiveProjectFileBounds)\r\n\t\tstore.dispatch(setActiveProjectFileId(null))\r\n\t\tstore.dispatch(setIsImportingProjectFile(false))\r\n\t\treturn [activeProjectFile, promise]\r\n\t}\r\n\r\n\tdelete(projectFileId: string): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(removeProjectFile(projectFileId))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/projects/files/${projectFileId}`,\r\n\t\t\tblockers: [projectFileId],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","import { HttpMethod } from \"enums/api\"\r\nimport { Project } from \"typings/models/projects\"\r\nimport type { ApiSuccessResult } from \"../typings\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { v4 as uuidv4 } from \"uuid\"\r\nimport { Created, Payload } from \"../../typings\"\r\nimport {\r\n\taddOrReplaceProjectFiles,\r\n\tdeleteProject,\r\n\tremoveProjectAccessesOfProject,\r\n\tremoveProjectFilesOfProject,\r\n\tselectProjectAccesses,\r\n\tselectProjectFiles,\r\n\tselectProjects,\r\n\tsetActiveProjectId,\r\n\tsetProjectAccesses,\r\n\tsetProjects,\r\n\tupdateOrCreateProject,\r\n} from \"../../store\"\r\n\r\ninterface JoinProjectResponse {\r\n\tusername: string\r\n}\r\n\r\nexport class ProjectService extends BaseApiService {\r\n\t/**\r\n\t * Creates a new project. Due to the nature of project creation,\r\n\t * @param project A Payload<Project> object containing project attributes.\r\n\t * @returns A promise that resolves to a Project.\r\n\t * @throws An APIError if the server returns an error, or any other error that may occur.\r\n\t */\r\n\tasync add(project: Payload<Project>): Promise<Project> {\r\n\t\tif (!project.bounds) {\r\n\t\t\tthrow new Error(\"Project bounds were not set before trying to create a project\")\r\n\t\t}\r\n\t\tif (!project.owner_organization && !project.owner_user) {\r\n\t\t\tthrow new Error(\"Project type was not chosen when trying to create a project\")\r\n\t\t}\r\n\t\tconst isOrganizationProject = !!project.owner_organization\r\n\t\tconst activeOrganization = this.client.store.getState().organizationReducer.activeOrganizationId\r\n\t\tif (isOrganizationProject && (!activeOrganization || project.owner_organization !== activeOrganization)) {\r\n\t\t\tthrow new Error(\"User tried creating organization project for organization they do not belong to.\")\r\n\t\t}\r\n\t\tconst url = isOrganizationProject ? `/organizations/${project.owner_organization}/projects/` : \"/projects/\"\r\n\t\tconst projectType = isOrganizationProject\r\n\t\t\t? { organization_owner: project.owner_organization }\r\n\t\t\t: { user_owner: project.owner_user }\r\n\t\tconst result = await this.enqueueRequest<Created<Project>>({\r\n\t\t\tdescription: \"Create project\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl,\r\n\t\t\tpayload: {\r\n\t\t\t\tname: project.name,\r\n\t\t\t\tbounds: {\r\n\t\t\t\t\ttype: \"MultiPoint\",\r\n\t\t\t\t\tcoordinates: [project.bounds[0], project.bounds[1]],\r\n\t\t\t\t},\r\n\t\t\t\t...projectType,\r\n\t\t\t},\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tawait this.client.main.fetchInitialData(true)\r\n\t\treturn result\r\n\t}\r\n\r\n\tasync update(project: Project): Promise<Project> {\r\n\t\tconst { store } = this.client\r\n\t\tif (!project.bounds) {\r\n\t\t\tthrow new Error(\"Project bounds were not set before trying to create a project\")\r\n\t\t}\r\n\r\n\t\tstore.dispatch(updateOrCreateProject(project))\r\n\t\treturn await this.enqueueRequest<Project>({\r\n\t\t\tdescription: \"Update project\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/projects/${project.id}/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tname: project.name,\r\n\t\t\t\tbounds: {\r\n\t\t\t\t\ttype: \"MultiPoint\",\r\n\t\t\t\t\tcoordinates: [project.bounds[0], project.bounds[1]],\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t\tblockers: [project.id.toString()],\r\n\t\t\tblocks: [project.id.toString()],\r\n\t\t})\r\n\t}\r\n\r\n\tasync delete(projectId: number): Promise<ApiSuccessResult<undefined>> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst projects = selectProjects(state)\r\n\t\tconst project = projects[projectId]\r\n\t\tif (!project) {\r\n\t\t\tthrow new Error(\"Expected project to exist\")\r\n\t\t}\r\n\r\n\t\tconst activeProjectId = state.projectReducer.activeProjectId\r\n\t\tif (activeProjectId === projectId) {\r\n\t\t\tstore.dispatch({ type: \"project/setActiveProjectId\", payload: null })\r\n\t\t}\r\n\r\n\t\t// Selector needed to restore if the request fails\r\n\t\tconst filesToDelete = selectProjectFiles(state).filter((file) => file.project === projectId)\r\n\t\tstore.dispatch(removeProjectFilesOfProject(project.id))\r\n\r\n\t\t// Selector needed to restore if the request fails\r\n\t\tconst projectAccesses = selectProjectAccesses(state)\r\n\t\tstore.dispatch(removeProjectAccessesOfProject(project.id))\r\n\r\n\t\t// Necessary to prevent no projects view from showing when project is deleted\r\n\t\tstore.dispatch({ type: \"rehydrated/setRehydrated\", payload: false })\r\n\t\tstore.dispatch(deleteProject(project))\r\n\r\n\t\ttry {\r\n\t\t\tawait this.enqueueRequest<undefined>({\r\n\t\t\t\tdescription: \"Delete project\",\r\n\t\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\t\turl: `/projects/${projectId}/`,\r\n\t\t\t\tblockers: [projectId.toString()],\r\n\t\t\t\tblocks: [],\r\n\t\t\t})\r\n\t\t\tstore.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\r\n\t\t} catch (e) {\r\n\t\t\tstore.dispatch(setProjects(Object.values(projects)))\r\n\t\t\tstore.dispatch(setProjectAccesses(Object.values(projectAccesses)))\r\n\t\t\tstore.dispatch(addOrReplaceProjectFiles(filesToDelete))\r\n\t\t\tstore.dispatch(setActiveProjectId(activeProjectId))\r\n\t\t\tstore.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\tinvite(projectId: number, email: string): Promise<undefined> {\r\n\t\tconst offline_id: string = uuidv4()\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Invite user to project\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/projects/${projectId}/invite/${email}/`,\r\n\t\t\tpayload: {\r\n\t\t\t\toffline_id,\r\n\t\t\t},\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offline_id],\r\n\t\t})\r\n\t}\r\n\r\n\tjoinProject(projectId: number, userId: number, inviteCode: string): Promise<ApiSuccessResult<JoinProjectResponse>> {\r\n\t\treturn this.enqueueRequest<JoinProjectResponse>({\r\n\t\t\tdescription: \"Join project\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${projectId}/join-project/${userId}/${inviteCode}/`,\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","import { HttpMethod } from \"enums/api\"\r\nimport {\r\n\taddUserForm,\r\n\taddUserFormRevision,\r\n\taddUserFormRevisions,\r\n\taddUserForms,\r\n\taddUserFormSubmissions,\r\n\tdeleteUserForm,\r\n\tdeleteUserFormRevision,\r\n\tdeleteUserFormRevisions,\r\n\tdeleteUserFormSubmissions,\r\n\tfavoriteForm,\r\n\tselectRevisionsForForm,\r\n\tselectSubmissionsForForm,\r\n\tselectUserForm,\r\n\tunfavoriteForm,\r\n} from \"store/slices/userFormSlice\"\r\nimport { SubmittedUserForm, UserForm, UserFormRevision, UserFormRevisionPayload } from \"typings/models/forms\"\r\nimport { OptimisticModelResult } from \"../typings\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { offline } from \"utils/offline\"\r\nimport { Created, RootState } from \"../../typings\"\r\n\r\nexport class UserFormService extends BaseApiService {\r\n\tprivate add(\r\n\t\tstate: RootState,\r\n\t\tinitialRevision: UserFormRevisionPayload,\r\n\t\turl: string,\r\n\t\townerUser: number | undefined,\r\n\t\townerOrganization?: number,\r\n\t): [UserForm, UserFormRevision, Promise<UserFormRevision>] {\r\n\t\tif (!!ownerUser === !!ownerOrganization) {\r\n\t\t\tthrow new Error(\"Exactly one of ownerUser and ownerOrganization must be defined.\")\r\n\t\t}\r\n\r\n\t\tconst ownerAttrs = {\r\n\t\t\towner_user: ownerUser,\r\n\t\t\towner_organization: ownerOrganization,\r\n\t\t} as\r\n\t\t\t| {\r\n\t\t\t\t\towner_user: number\r\n\t\t\t\t\towner_organization: undefined\r\n\t\t\t }\r\n\t\t\t| {\r\n\t\t\t\t\towner_user: undefined\r\n\t\t\t\t\towner_organization: number\r\n\t\t\t }\r\n\r\n\t\tconst currentUser = state.userReducer.currentUser\r\n\t\tconst activeWorkspaceId = state.workspaceReducer.activeWorkspaceId\r\n\t\t// NOTE: Creating forms only requires an offline ID, nothing else (except for the initial revision).\r\n\t\tconst offlineFormPayload = offline({})\r\n\t\tconst offlineRevisionPayload = offline(initialRevision)\r\n\t\tconst retForm: SubmittedUserForm = {\r\n\t\t\t...offlineFormPayload,\r\n\t\t\tindex_workspace: activeWorkspaceId,\r\n\t\t\tfavorite: true,\r\n\t\t\tsubmitted_at: new Date().toISOString(),\r\n\t\t\tcreated_by: currentUser.id,\r\n\t\t\t...ownerAttrs,\r\n\t\t}\r\n\t\tconst retRevision: UserFormRevision = {\r\n\t\t\t...offlineRevisionPayload,\r\n\t\t\tcreated_by: currentUser.id,\r\n\t\t\tform: retForm.offline_id,\r\n\t\t\trevision: 0,\r\n\t\t}\r\n\t\tconst { store } = this.client\r\n\t\tstore.dispatch(addUserForm(retForm))\r\n\t\tstore.dispatch(addUserFormRevision(retRevision))\r\n\r\n\t\tconst formPromise = this.enqueueRequest<UserFormRevision>({\r\n\t\t\tdescription: \"Create form\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl,\r\n\t\t\tqueryParams: activeWorkspaceId\r\n\t\t\t\t? {\r\n\t\t\t\t\t\tworkspace_id: activeWorkspaceId,\r\n\t\t\t\t }\r\n\t\t\t\t: undefined,\r\n\t\t\tpayload: { ...offlineFormPayload, initial_revision: offlineRevisionPayload },\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offlineFormPayload.offline_id, offlineRevisionPayload.offline_id],\r\n\t\t})\r\n\r\n\t\tvoid formPromise.catch((e) => {\r\n\t\t\tstore.dispatch(deleteUserForm(retForm.offline_id))\r\n\t\t\tstore.dispatch(deleteUserFormRevision(retRevision.offline_id))\r\n\t\t\tthrow e\r\n\t\t})\r\n\r\n\t\treturn [retForm, retRevision, formPromise]\r\n\t}\r\n\taddForOrganization(\r\n\t\tinitialRevision: UserFormRevisionPayload,\r\n\t): [UserForm, UserFormRevision, Promise<UserFormRevision>] {\r\n\t\tconst state: RootState = this.client.store.getState()\r\n\t\tconst activeOrganizationId = state.organizationReducer.activeOrganizationId\r\n\r\n\t\tif (!activeOrganizationId) {\r\n\t\t\tthrow new Error(\"Cannot add forms for organization when there is no active organization.\")\r\n\t\t}\r\n\t\treturn this.add(\r\n\t\t\tstate,\r\n\t\t\tinitialRevision,\r\n\t\t\t`/forms/in-organization/${activeOrganizationId}/`,\r\n\t\t\tundefined,\r\n\t\t\tactiveOrganizationId,\r\n\t\t)\r\n\t}\r\n\r\n\taddForCurrentUser(initialRevision: UserFormRevision): [UserForm, UserFormRevision, Promise<UserFormRevision>] {\r\n\t\tconst state: RootState = this.client.store.getState()\r\n\t\tconst currentUser = state.userReducer.currentUser\r\n\t\treturn this.add(state, initialRevision, \"/forms/my-forms/\", currentUser.id)\r\n\t}\r\n\tcreateRevision(formId: string, revision: UserFormRevisionPayload): OptimisticModelResult<UserFormRevision> {\r\n\t\tconst offlineRevision = offline(revision)\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst activeProjectId = state.projectReducer.activeProjectId\r\n\t\tif (!activeProjectId) {\r\n\t\t\tthrow new Error(\"Cannot create form revision when there is no active project.\")\r\n\t\t}\r\n\t\tconst currentUserId = state.userReducer.currentUser.id\r\n\t\tconst fullRevision: UserFormRevision = {\r\n\t\t\t...offlineRevision,\r\n\t\t\tcreated_by: currentUserId,\r\n\t\t\trevision: \"Pending\",\r\n\t\t\tform: formId,\r\n\t\t}\r\n\t\t// TODO: Rename to addOrReplaceUserFormRevision or make two separate methods. Standardize across services.\r\n\t\tstore.dispatch(addUserFormRevision(fullRevision))\r\n\t\tconst promise = this.enqueueRequest<UserFormRevision>({\r\n\t\t\tdescription: \"Create form revision\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/forms/${formId}/`,\r\n\t\t\tpayload: { initial_revision: offlineRevision },\r\n\t\t\tqueryParams: {\r\n\t\t\t\tproject_id: activeProjectId.toString(),\r\n\t\t\t},\r\n\t\t\tblockers: [formId],\r\n\t\t\tblocks: [offlineRevision.offline_id],\r\n\t\t})\r\n\t\tvoid promise\r\n\t\t\t.then((result) => {\r\n\t\t\t\tstore.dispatch(addUserFormRevision(result))\r\n\t\t\t})\r\n\t\t\t.catch(() => {\r\n\t\t\t\tstore.dispatch(deleteUserFormRevision(fullRevision.offline_id))\r\n\t\t\t})\r\n\t\treturn [fullRevision, promise]\r\n\t}\r\n\r\n\tasync favorite(formId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst activeProjectId = store.getState().projectReducer.activeProjectId\r\n\t\tstore.dispatch(favoriteForm({ formId }))\r\n\t\ttry {\r\n\t\t\tawait this.enqueueRequest({\r\n\t\t\t\tdescription: \"Favorite form\",\r\n\t\t\t\tmethod: HttpMethod.POST,\r\n\t\t\t\turl: `/forms/${formId}/favorite/${activeProjectId}/`,\r\n\t\t\t\tblockers: [formId, `favorite-${formId}`],\r\n\t\t\t\tblocks: [`favorite-${formId}`],\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\tstore.dispatch(unfavoriteForm({ formId }))\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\tasync unfavorite(formId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst activeProjectId = store.getState().projectReducer.activeProjectId\r\n\t\tstore.dispatch(unfavoriteForm({ formId }))\r\n\t\ttry {\r\n\t\t\t// REASON: Need to await to trigger the catch block.\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\r\n\t\t\treturn await this.enqueueRequest<undefined>({\r\n\t\t\t\tdescription: \"Unfavorite form\",\r\n\t\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\t\turl: `/forms/${formId}/unfavorite/${activeProjectId}/`,\r\n\t\t\t\tblockers: [formId, `favorite-${formId}`],\r\n\t\t\t\tblocks: [`favorite-${formId}`],\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\tstore.dispatch(favoriteForm({ formId }))\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\tasync delete(formId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst userForm = selectUserForm(formId)(state)\r\n\t\tif (!userForm) {\r\n\t\t\tthrow new Error(\"Expected userForm to exist\")\r\n\t\t}\r\n\t\t// Delete all submissions for this form\r\n\t\tconst userFormSubmissions = selectSubmissionsForForm(formId)(state)\r\n\t\tif (userFormSubmissions && userFormSubmissions.length > 0) {\r\n\t\t\tstore.dispatch(deleteUserFormSubmissions(userFormSubmissions))\r\n\t\t}\r\n\r\n\t\t// Delete all revisions for this form\r\n\t\tconst userFormRevisions = selectRevisionsForForm(formId)(state)\r\n\t\tif (userFormRevisions && userFormRevisions.length > 0) {\r\n\t\t\tstore.dispatch(deleteUserFormRevisions(userFormRevisions))\r\n\t\t}\r\n\r\n\t\t// Delete the form itself\r\n\t\tstore.dispatch(deleteUserForm(formId))\r\n\r\n\t\ttry {\r\n\t\t\t// REASON: Need to await to trigger the catch block.\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\r\n\t\t\treturn await this.enqueueRequest<undefined>({\r\n\t\t\t\tdescription: \"Delete form\",\r\n\t\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\t\turl: `/forms/${formId}/`,\r\n\t\t\t\tblockers: [formId],\r\n\t\t\t\tblocks: [],\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\tstore.dispatch(addUserForm(userForm))\r\n\t\t\tif (userFormRevisions && userFormRevisions.length > 0) {\r\n\t\t\t\tstore.dispatch(addUserFormRevisions(userFormRevisions))\r\n\t\t\t}\r\n\t\t\tif (userFormSubmissions && userFormSubmissions.length > 0) {\r\n\t\t\t\tstore.dispatch(addUserFormSubmissions(userFormSubmissions))\r\n\t\t\t}\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<{ forms: Created<UserForm>[]; revisions: UserFormRevision[] }>({\r\n\t\t\tdescription: \"Fetch user forms\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/forms/in-project/${store.getState().projectReducer.activeProjectId}/forms/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tstore.dispatch(addUserForms(Object.values(result.forms)))\r\n\t\tstore.dispatch(addUserFormRevisions(Object.values(result.revisions)))\r\n\t}\r\n}\r\n","import { Offline } from \"typings/models/base\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { UserFormSubmission, UserFormSubmissionAttachment, UserFormSubmissionPayload } from \"typings/models/forms\"\r\nimport { OptimisticModelResult } from \"../typings\"\r\nimport { HttpMethod } from \"enums/api\"\r\nimport {\r\n\taddUserFormSubmission,\r\n\taddUserFormSubmissionAttachment,\r\n\tdeleteUserFormSubmission,\r\n\tsetUserFormSubmissionAttachments,\r\n\tsetUserFormSubmissions,\r\n} from \"store/slices/userFormSlice\"\r\nimport { FieldValue } from \"forms\"\r\nimport { hashFile, offline } from \"utils\"\r\n\r\nconst isArrayOfFiles = (value: unknown): value is File[] => {\r\n\treturn Array.isArray(value) && value[0] instanceof File\r\n}\r\n\r\nconst separateFilesFromValues = (payload: Offline<UserFormSubmissionPayload>) => {\r\n\tconst { values } = payload\r\n\tconst files: Record<string, File[]> = {}\r\n\tconst newValues: Record<string, FieldValue> = {}\r\n\tfor (const key in values) {\r\n\t\tconst value = values[key]\r\n\r\n\t\tif (value === undefined) throw new Error(\"Expected value to be defined\")\r\n\r\n\t\tif (value instanceof File) {\r\n\t\t\tfiles[key] = [value]\r\n\t\t} else if (isArrayOfFiles(value)) {\r\n\t\t\tfiles[key] = value\r\n\t\t} else {\r\n\t\t\tnewValues[key] = value\r\n\t\t}\r\n\t}\r\n\r\n\tconst payloadWithoutFiles = {\r\n\t\t...payload,\r\n\t\tvalues: newValues,\r\n\t}\r\n\r\n\treturn { payloadWithoutFiles, files }\r\n}\r\n\r\nexport class UserFormSubmissionService extends BaseApiService {\r\n\tadd(payload: Offline<UserFormSubmissionPayload>): OptimisticModelResult<UserFormSubmission> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst activeProjectId = state.projectReducer.activeProjectId\r\n\r\n\t\tif (!activeProjectId) {\r\n\t\t\tthrow new Error(\"Expected an active project\")\r\n\t\t}\r\n\r\n\t\tconst { payloadWithoutFiles, files } = separateFilesFromValues(payload)\r\n\t\tconst promise = this.enqueueRequest<UserFormSubmission>({\r\n\t\t\tdescription: \"Respond to form\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/forms/revisions/${payload.form_revision}/respond/`,\r\n\t\t\tpayload: { ...payloadWithoutFiles, project: activeProjectId },\r\n\t\t\tblockers: [payload.issue, payload.component].filter((x) => x !== undefined) as string[],\r\n\t\t\tblocks: [payload.offline_id],\r\n\t\t})\r\n\r\n\t\t// attach files to submission, after uploading them to S3\r\n\t\tconst attachFilesPromises = Object.entries(files).map(async ([key, fileArray]) => {\r\n\t\t\tconst attachResults: UserFormSubmissionAttachment[] = []\r\n\t\t\tfor (const file of fileArray) {\r\n\t\t\t\tconst sha1 = await hashFile(file)\r\n\t\t\t\tawait this.client.files.addCache(file, sha1)\r\n\t\t\t\tconst [fileProps] = await this.client.files.uploadFileToS3(sha1)\r\n\t\t\t\tconst submissionAttachmentPayload: UserFormSubmissionAttachment = offline({\r\n\t\t\t\t\t...fileProps,\r\n\t\t\t\t\tsubmission: payload.offline_id,\r\n\t\t\t\t\tfield_identifier: key,\r\n\t\t\t\t})\r\n\t\t\t\tconst attach = await this.enqueueRequest<UserFormSubmissionAttachment>({\r\n\t\t\t\t\tdescription: \"Attach file to form submission\",\r\n\t\t\t\t\tmethod: HttpMethod.POST,\r\n\t\t\t\t\turl: `/forms/submission/${payload.offline_id}/attachments/`,\r\n\t\t\t\t\tpayload: submissionAttachmentPayload,\r\n\t\t\t\t\tblockers: [payload.component, payload.issue, payload.form_revision].filter(\r\n\t\t\t\t\t\t(x) => x !== undefined,\r\n\t\t\t\t\t) as string[],\r\n\t\t\t\t\tblocks: [submissionAttachmentPayload.offline_id],\r\n\t\t\t\t})\r\n\t\t\t\tconst offlinePayload = {\r\n\t\t\t\t\t...submissionAttachmentPayload,\r\n\t\t\t\t\tfile: URL.createObjectURL(file),\r\n\t\t\t\t}\r\n\t\t\t\tstore.dispatch(addUserFormSubmissionAttachment(offlinePayload))\r\n\r\n\t\t\t\tattachResults.push(attach)\r\n\t\t\t}\r\n\r\n\t\t\treturn attachResults\r\n\t\t})\r\n\r\n\t\tconst fullOfflineResult: UserFormSubmission = {\r\n\t\t\t...payload,\r\n\t\t\tcreated_by: state.userReducer.currentUser.id,\r\n\t\t\tcreated_at: new Date().toISOString(),\r\n\t\t}\r\n\t\tconst offlineResultWithoutFiles = {\r\n\t\t\t...fullOfflineResult,\r\n\t\t\t...payloadWithoutFiles,\r\n\t\t}\r\n\t\tstore.dispatch(addUserFormSubmission(offlineResultWithoutFiles))\r\n\t\tvoid promise\r\n\t\t\t.then((result) => {\r\n\t\t\t\tstore.dispatch(addUserFormSubmission(result))\r\n\t\t\t\treturn result\r\n\t\t\t})\r\n\t\t\t.catch(() => {\r\n\t\t\t\tstore.dispatch(deleteUserFormSubmission(payload.offline_id))\r\n\t\t\t})\r\n\r\n\t\tconst settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise)\r\n\r\n\t\treturn [fullOfflineResult, settledPromise]\r\n\t}\r\n\r\n\tasync delete(submissionId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst submission = state.userFormReducer.submissions[submissionId]\r\n\t\tstore.dispatch(deleteUserFormSubmission(submissionId))\r\n\t\ttry {\r\n\t\t\t// REASON: Need to await to trigger the catch block.\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\r\n\t\t\treturn await this.enqueueRequest<undefined>({\r\n\t\t\t\tdescription: \"Delete user form submissions\",\r\n\t\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\t\turl: `/forms/submissions/${submissionId}/`,\r\n\t\t\t\tblockers: [submissionId],\r\n\t\t\t\tblocks: [],\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\tif (submission) {\r\n\t\t\t\tstore.dispatch(addUserFormSubmission(submission))\r\n\t\t\t}\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst projectId = store.getState().projectReducer.activeProjectId\r\n\t\tconst submissions = await this.enqueueRequest<UserFormSubmission[]>({\r\n\t\t\tdescription: \"Fetch form submissions\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/forms/in-project/${projectId}/submissions/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\r\n\t\tstore.dispatch(setUserFormSubmissions(submissions))\r\n\r\n\t\tconst attachments = await this.enqueueRequest<UserFormSubmissionAttachment[]>({\r\n\t\t\tdescription: \"Fetch form attachments\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/forms/in-project/${projectId}/attachments/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\r\n\t\tstore.dispatch(setUserFormSubmissionAttachments(attachments))\r\n\t}\r\n}\r\n","import { HttpMethod } from \"enums/api\"\r\nimport { addOrReplaceWorkspaces, addWorkspace, removeWorkspace } from \"store/slices/workspaceSlice\"\r\nimport { Payload } from \"typings/models/base\"\r\nimport { Workspace } from \"typings/models/workspace\"\r\nimport { ApiResult, OptimisticModelResult } from \"../typings\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { offline } from \"utils/offline\"\r\n\r\nexport class WorkspaceService extends BaseApiService {\r\n\tadd(workspace: Payload<Workspace>): OptimisticModelResult<Workspace> {\r\n\t\tconst { store } = this.client\r\n\t\tconst offlineWorkspace = offline(workspace)\r\n\t\tstore.dispatch(addWorkspace(offlineWorkspace))\r\n\t\tconst promise = this.enqueueRequest<Workspace>({\r\n\t\t\tdescription: \"Create Workspace\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/workspaces/`,\r\n\t\t\tpayload: offlineWorkspace,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offlineWorkspace.offline_id],\r\n\t\t})\r\n\t\tvoid promise\r\n\t\t\t.then((result) => {\r\n\t\t\t\tstore.dispatch(addOrReplaceWorkspaces({ [offlineWorkspace.offline_id]: result }))\r\n\t\t\t})\r\n\t\t\t.catch(() => {\r\n\t\t\t\tstore.dispatch(removeWorkspace(offlineWorkspace.offline_id))\r\n\t\t\t})\r\n\r\n\t\treturn [offlineWorkspace, promise]\r\n\t}\r\n\r\n\tupdate(workspace: Workspace): OptimisticModelResult<Workspace> {\r\n\t\tconst { store } = this.client\r\n\t\tstore.dispatch(addOrReplaceWorkspaces({ [workspace.offline_id]: workspace }))\r\n\t\tconst promise = this.enqueueRequest<Workspace>({\r\n\t\t\tdescription: \"Update Workspace\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/workspaces/${workspace.offline_id}/`,\r\n\t\t\tpayload: workspace,\r\n\t\t\tblockers: [workspace.offline_id],\r\n\t\t\tblocks: [workspace.offline_id],\r\n\t\t})\r\n\r\n\t\treturn [workspace, promise]\r\n\t}\r\n\r\n\tdelete(workspaceId: string): Promise<ApiResult<undefined>> {\r\n\t\tconst { store } = this.client\r\n\t\tconst promise = this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete Workspace\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/workspaces/${workspaceId}/`,\r\n\t\t\tblockers: [workspaceId],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tconst originalWorkspace = store.getState().workspaceReducer.workspaces[workspaceId]\r\n\t\tstore.dispatch(removeWorkspace(workspaceId))\r\n\t\tvoid promise\r\n\t\t\t.then(() => {\r\n\t\t\t\t// After deleting a workspace, we need to fetch the initial data again because workspace indexes will have\r\n\t\t\t\t// changed.\r\n\t\t\t\tvoid this.client.main.fetchInitialData(true).then()\r\n\t\t\t})\r\n\t\t\t.catch((reason) => {\r\n\t\t\t\tif (originalWorkspace) {\r\n\t\t\t\t\tstore.dispatch(addWorkspace(originalWorkspace))\r\n\t\t\t\t}\r\n\t\t\t\tthrow reason\r\n\t\t\t})\r\n\t\treturn promise\r\n\t}\r\n}\r\n","import { HttpMethod } from \"enums\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { OrganizationAccess } from \"typings/models\"\r\nimport { setActiveOrganizationAccessId, setOrganizationAccesses } from \"store/slices\"\r\n\r\n/**\r\n * Handles the creation of OrganizationAccess Service\r\n */\r\nexport class OrganizationAccessService extends BaseApiService {\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst organizationId = state.organizationReducer.activeOrganizationId\r\n\t\tif (!organizationId) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tconst result = await this.enqueueRequest<OrganizationAccess[]>({\r\n\t\t\tdescription: \"Get organization accesses\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/organizations/${organizationId}/access/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tconst currentUser = state.userReducer.currentUser\r\n\t\tconst organizationAccesses = result\r\n\t\tconst activeOrganizationAccess = organizationAccesses.find(\r\n\t\t\t(organizationAccess) => organizationAccess.user === currentUser.id,\r\n\t\t)\r\n\t\tif (!activeOrganizationAccess) {\r\n\t\t\tthrow new Error(\"Current user does not have an organization access instance\")\r\n\t\t}\r\n\t\tstore.dispatch(setOrganizationAccesses(organizationAccesses))\r\n\t\tstore.dispatch(setActiveOrganizationAccessId(activeOrganizationAccess.offline_id))\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\n\r\n// TODO: add more methods, add error handling, add quota management etc, make it work for any Attachment\r\n// Goal is to not use more than 80% of quota, as full utilization would stop the Redux offline store from\r\n// functioning properly as well\r\nimport { DBSchema, IDBPDatabase, openDB } from \"idb\"\r\nimport { HttpMethod } from \"enums\"\r\nimport { fileToBlob, getFileS3Key, getRenamedFile, hashFile } from \"utils\"\r\nimport { selectUploadUrl, setUploadUrl } from \"store/slices/fileSlice\"\r\nimport { RootState } from \"../../typings\"\r\nimport { APIError } from \"../errors.ts\"\r\nimport { SDKRequest } from \"../typings.ts\"\r\n\r\nexport interface GetS3UrlSuccessResponse {\r\n\turl: string\r\n\tfields: Record<string, string>\r\n}\r\n\r\ninterface GetS3UrlWarningResponse {\r\n\twarning: string\r\n}\r\n\r\nexport type GetS3UrlResponse = GetS3UrlSuccessResponse | GetS3UrlWarningResponse\r\n\r\ninterface DatabaseFileProperties {\r\n\tfile_name: string\r\n\tfile_sha1: string\r\n\t/** When uploading, this is the s3 key of the file.\r\n\t * When downloading, this is the s3 public url.\r\n\t */\r\n\tfile: string\r\n}\r\n\r\ninterface FileCacheDB extends DBSchema {\r\n\tfiles: {\r\n\t\tvalue: File\r\n\t\tkey: string\r\n\t}\r\n}\r\n\r\nconst cachedRequestPromises: Record<string, Promise<File> | undefined> = {}\r\n// Used to minimize writing to the cache.\r\nconst _cachedKeys = new Set<string>()\r\n\r\n// <ANALYTICS>\r\nlet _filePutCacheHits = 0\r\nlet _filePutCacheMisses = 0\r\nlet _totalCount = 0\r\nconst summarizeEvery = 20\r\n// </ANALYTICS>\r\n\r\nexport class FileService extends BaseApiService {\r\n\t// NOTE: If you alter the schema (of the IndexedDB database) in any way, you must increment the version in order to\r\n\t// migrate the store. This allows idb to automatically migrate the user's existing data to the new schema.\r\n\tprivate _dbPromise = openDB<FileCacheDB>(\"fileCache\", 1, {\r\n\t\tupgrade(db) {\r\n\t\t\tdb.createObjectStore(\"files\")\r\n\t\t},\r\n\t})\r\n\r\n\tprivate async renewUploadUrl(sha1: string): Promise<GetS3UrlResponse> {\r\n\t\tconst file = await this.fetchCache(sha1)\r\n\t\tif (!file) throw new Error(`File with sha1 ${sha1} not found in cache`)\r\n\t\tconst key = await getFileS3Key(file, sha1)\r\n\r\n\t\tconst s3UploadUrl = await this.enqueueRequest<GetS3UrlResponse>({\r\n\t\t\tdescription: \"Get S3 URL\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: \"/authentication/files/presigned-upload-url/\",\r\n\t\t\tqueryParams: { key, type: file.type },\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [`s3-${key}`],\r\n\t\t})\r\n\r\n\t\tif (\"url\" in s3UploadUrl) {\r\n\t\t\t// TODO: Why save it to the store?\r\n\t\t\tthis.client.store.dispatch(setUploadUrl({ sha1, ...s3UploadUrl }))\r\n\t\t}\r\n\t\treturn s3UploadUrl\r\n\t}\r\n\r\n\t/**\r\n\t * Adds a file to the cache using the sha1 hash as the key and returns the sha1 hash.\r\n\t * @param file The file to add to the cache\r\n\t * TODO: This should be removed once the bug described in [1] is fixed.\r\n\t * @param sha1 The sha1 hash of the file to cache.\r\n\t */\r\n\tasync addCache(file: File, sha1: string): Promise<void> {\r\n\t\tif (_cachedKeys.has(sha1)) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\t// TODO: Check\r\n\t\tif (!file.type) {\r\n\t\t\tconst parts = file.name.split(\".\")\r\n\t\t\tconst extension = parts[parts.length - 1]\r\n\t\t\tfile = new File([file], file.name, { type: extension })\r\n\t\t}\r\n\t\tif (!file.name || !file.size || !file.type) {\r\n\t\t\tthrow new Error(\"Cannot add files to cache that do not have a name, size and type.\")\r\n\t\t}\r\n\t\tconst fileStorage: IDBPDatabase<FileCacheDB> = await this._dbPromise\r\n\t\t// TODO: Is this an improvement or not?\r\n\t\tconst alreadyCached = !!(await fileStorage.get(\"files\", sha1))\r\n\t\tif (!alreadyCached) {\r\n\t\t\tawait fileStorage.put(\"files\", file, sha1)\r\n\t\t\t_filePutCacheMisses++\r\n\t\t} else {\r\n\t\t\tconsole.error(\"File already cached (this is unexpected at this point):\", file.name, sha1)\r\n\t\t\t_filePutCacheHits++\r\n\t\t}\r\n\t\t_cachedKeys.add(sha1)\r\n\t\t_totalCount++\r\n\t\tif (_totalCount % summarizeEvery === 0) {\r\n\t\t\t// TODO: If this ends up hitting the console more often than not, they `alreadyCached` check might be more\r\n\t\t\t// performant than overwriting the identical file in the database. Because all file names saved are based\r\n\t\t\t// on the sha1 hash, we can guarantee that the files are identical, so there is no point in overwriting.\r\n\t\t\tconsole.debug(\r\n\t\t\t\t\"File cache summary: \" +\r\n\t\t\t\t\t`${_filePutCacheHits} hits and ${_filePutCacheMisses} misses, ` +\r\n\t\t\t\t\t`${(_filePutCacheHits / (_filePutCacheHits + _filePutCacheMisses)) * 100}% hit rate over ` +\r\n\t\t\t\t\t`${_totalCount} calls to addCache.`,\r\n\t\t\t)\r\n\t\t}\r\n\t}\r\n\r\n\tasync removeCache(sha1: string): Promise<void> {\r\n\t\tawait (await this._dbPromise).delete(\"files\", sha1)\r\n\t\t_cachedKeys.delete(sha1)\r\n\t}\r\n\r\n\tasync fetchCache(sha1: string): Promise<File | undefined> {\r\n\t\treturn (await this._dbPromise).get(\"files\", sha1)\r\n\t}\r\n\r\n\tasync getOrRenewUploadUrl(sha1: string): Promise<GetS3UrlResponse> {\r\n\t\tconst state: RootState = this.client.store.getState()\r\n\t\tconst uploadUrl = selectUploadUrl(sha1)(state)\r\n\r\n\t\treturn uploadUrl ?? (await this.renewUploadUrl(sha1))\r\n\t}\r\n\r\n\t/** Ensure the file has been added to the file cache before calling `uploadFileToS3()` */\r\n\tasync uploadFileToS3(sha1: string): Promise<[DatabaseFileProperties, Promise<undefined>]> {\r\n\t\tconst file = await this.fetchCache(sha1)\r\n\r\n\t\tif (!file) throw new Error(`File with sha1 ${sha1} not found in cache`)\r\n\r\n\t\tconst key = await getFileS3Key(file, sha1)\r\n\t\tconst dbFileProperties: DatabaseFileProperties = {\r\n\t\t\tfile_name: file.name,\r\n\t\t\tfile_sha1: sha1,\r\n\t\t\tfile: key,\r\n\t\t}\r\n\t\tconst fileUploadUrlResponse: GetS3UrlResponse = await this.getOrRenewUploadUrl(sha1)\r\n\r\n\t\tif (\"warning\" in fileUploadUrlResponse) {\r\n\t\t\tif (fileUploadUrlResponse.warning === \"already_uploaded\") {\r\n\t\t\t\treturn [dbFileProperties, Promise.resolve(undefined).then()]\r\n\t\t\t}\r\n\t\t\tthrow new Error(fileUploadUrlResponse.warning)\r\n\t\t}\r\n\r\n\t\tconst url = fileUploadUrlResponse.url\r\n\t\tconst promise = this.enqueueRequest<undefined>({\r\n\t\t\turl,\r\n\t\t\tdescription: \"Upload file\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\tisExternalUrl: true,\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tattachmentHash: sha1,\r\n\t\t\tblockers: [`s3-${key}`],\r\n\t\t\tblocks: [sha1],\r\n\t\t\ts3url: fileUploadUrlResponse,\r\n\t\t} satisfies SDKRequest)\r\n\r\n\t\treturn [dbFileProperties, promise]\r\n\t}\r\n\r\n\t/**\r\n\t * Fetches a file based on its URL and SHA1. SHA1 values should be known ahead of time because the SHA1 and URL of\r\n\t * any file is stored in a FileModelMixin (see backend). If the expected SHA1 doesn't match the actual SHA1 of the\r\n\t * file, an error will be thrown.\r\n\t * @param url The URL from which to get the file.\r\n\t * @param expectedSha1 The expected SHA1 of the file. If this doesn't match the actual SHA1 of the file, an error\r\n\t * will be thrown.\r\n\t * @param downloadedName (Optional) The name to give the file after download. Set to the name of an attachment, for\r\n\t * example.\r\n\t */\r\n\tasync fetchFileFromUrl(url: string, expectedSha1: string, downloadedName?: string | undefined): Promise<File> {\r\n\t\tconst requestCacheKey: string = url.split(\"?\")[0] ?? url\r\n\r\n\t\tconst cachedResult = await this.fetchCache(expectedSha1)\r\n\r\n\t\tif (cachedResult) {\r\n\t\t\tif (!cachedResult.name) {\r\n\t\t\t\tthrow new Error(\"Cached file unexpectedly has no name.\")\r\n\t\t\t}\r\n\t\t\treturn cachedResult\r\n\t\t}\r\n\r\n\t\tif (url.startsWith(\"blob:\")) {\r\n\t\t\tconst blob = await fileToBlob(url)\r\n\t\t\tconst file = new File([blob], downloadedName ?? expectedSha1, { type: blob.type })\r\n\t\t\tawait this.addCache(file, expectedSha1)\r\n\t\t\treturn file\r\n\t\t}\r\n\r\n\t\tlet promise = cachedRequestPromises[requestCacheKey]\r\n\t\tlet isFirstRequest = true\r\n\r\n\t\tif (!promise) {\r\n\t\t\tpromise = this.enqueueRequest<File>({\r\n\t\t\t\tdescription: \"Download file\",\r\n\t\t\t\tmethod: HttpMethod.GET,\r\n\t\t\t\turl,\r\n\t\t\t\t// If in development, we should assume the files are saved at localhost by the Django development server.\r\n\t\t\t\t// Setting this to true will lead to localhost:8000 being prepended to the URL.\r\n\t\t\t\tisExternalUrl: import.meta.env.PROD || url.startsWith(\"https://\"),\r\n\t\t\t\tisResponseBlob: true,\r\n\t\t\t\tisAuthNeeded: false,\r\n\t\t\t\tblockers: [expectedSha1],\r\n\t\t\t\tblocks: [expectedSha1],\r\n\t\t\t})\r\n\t\t\tcachedRequestPromises[requestCacheKey] = promise\r\n\t\t} else {\r\n\t\t\tisFirstRequest = false\r\n\t\t}\r\n\r\n\t\tlet file: File\r\n\r\n\t\ttry {\r\n\t\t\tfile = await promise\r\n\t\t} catch (e) {\r\n\t\t\tif (isFirstRequest && e instanceof APIError) {\r\n\t\t\t\t// Don't cache failed promises\r\n\t\t\t\tdelete cachedRequestPromises[requestCacheKey]\r\n\t\t\t}\r\n\t\t\tthrow e\r\n\t\t}\r\n\r\n\t\tif (isFirstRequest) {\r\n\t\t\t// The first request for this image (in case there are concurrent ones) has the responsibility to cache the\r\n\t\t\t// file itself.\r\n\t\t\tconst actualSha1 = await hashFile(file)\r\n\t\t\tif (actualSha1 !== expectedSha1) {\r\n\t\t\t\tconst message = `The hash of the file returned from the server (${actualSha1}) does not match the \r\n\t\t\t\t\texpected hash (${expectedSha1}). This can happen if you're using a local development server and the \r\n\t\t\t\t\tisExternalUrl flag in the request details is set to true, because instead of requesting the local\r\n\t\t\t\t\tREST API, you will be requesting localhost:80 (where this app runs), resulting in a transformed blob\r\n\t\t\t\t\t(with an offline_id attached) being returned. Alternatively, you may be running with \r\n\t\t\t\t\timport.meta.env.PROD, which will result in some file requests being treated as\r\n\t\t\t\t\texternal URLs and therefore not prepended with VITE_API_URL.`\r\n\r\n\t\t\t\tthrow new Error(message)\r\n\t\t\t}\r\n\t\t\t// All files need a name. Otherwise, they might end up with duplicated keys in the PrimeReact FileUpload\r\n\t\t\t// component (it uses the name, size and type as the key).\r\n\t\t\tconst extension = file.type.split(\"/\")[1]\r\n\t\t\tif (!extension) {\r\n\t\t\t\tthrow new Error(\"File has no extension\")\r\n\t\t\t}\r\n\t\t\tconst fileName = downloadedName ?? actualSha1 + \".\" + extension\r\n\r\n\t\t\tfile = getRenamedFile(file, fileName)\r\n\r\n\t\t\tif (!file.name) {\r\n\t\t\t\tthrow new Error(\"Failed to set file's name\")\r\n\t\t\t}\r\n\r\n\t\t\tawait this.addCache(file, actualSha1)\r\n\r\n\t\t\t// Overwrite the cached promise, so it returns the renamed file\r\n\t\t\tcachedRequestPromises[requestCacheKey] = new Promise((resolve) => {\r\n\t\t\t\tresolve(file)\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\treturn file\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { SDKRequest } from \"../../sdk\"\r\nimport { EmailVerificationPayload, EmailVerificationReturn, VerificationCode } from \"../../typings\"\r\n\r\nexport class EmailVerificationService extends BaseApiService {\r\n\tasync getVerificationCode(verificationCode: string): Promise<VerificationCode> {\r\n\t\tconst requestDetails: SDKRequest = {\r\n\t\t\tdescription: \"Get verification code\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/verification/email-verification/${verificationCode}/`,\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t}\r\n\t\treturn this.enqueueRequest<VerificationCode>(requestDetails)\r\n\t}\r\n\r\n\tvalidateVerificationCode(\r\n\t\tverificationCode: string,\r\n\t\tpayload: EmailVerificationPayload | undefined = undefined,\r\n\t): Promise<EmailVerificationReturn> {\r\n\t\tconst requestDetails: SDKRequest = {\r\n\t\t\tdescription: \"Validate verification code\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/verification/email-verification/${verificationCode}/`,\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tpayload,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t}\r\n\t\treturn this.enqueueRequest<EmailVerificationReturn>(requestDetails)\r\n\t}\r\n}\r\n","// The shape of an object that describes the details of an API request\r\nimport {\r\n\tAttachmentService,\r\n\tAuthService,\r\n\tCategoryService,\r\n\tComponentService,\r\n\tComponentStageCompletionService,\r\n\tComponentStageService,\r\n\tComponentTypeService,\r\n\tEmailVerificationService,\r\n\tFileService,\r\n\tIssueCommentService,\r\n\tIssueService,\r\n\tMainService,\r\n\tOrganizationAccessService,\r\n\tProjectAccessService,\r\n\tProjectFileService,\r\n\tProjectService,\r\n\tUserFormService,\r\n\tUserFormSubmissionService,\r\n\tWorkspaceService,\r\n} from \"./services\"\r\nimport { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore.js\"\r\nimport { RootState } from \"../typings\"\r\n\r\n// This is a bundle of the services that our app uses. These can be used in tandem with the types\r\n// declared above in order to execute requests to the backend (queued or otherwise). To use it,\r\n// you can declare a \"PlaceholderName-Service.ts\" and have CRUD methods to send to the backend,\r\n// and call it by using `sdk.PlaceHolderName.CRUD_METHOD`\r\nexport class OvermapSDK {\r\n\treadonly API_URL: string\r\n\treadonly store: ToolkitStore<RootState>\r\n\r\n\tconstructor(apiUrl: string, store: ToolkitStore<RootState>) {\r\n\t\tthis.API_URL = apiUrl\r\n\t\tthis.store = store\r\n\t}\r\n\r\n\tfiles = new FileService(this)\r\n\tattachments = new AttachmentService(this)\r\n\tauth = new AuthService(this)\r\n\tcategories = new CategoryService(this)\r\n\tprojectAccesses = new ProjectAccessService(this)\r\n\torganizationAccess = new OrganizationAccessService(this)\r\n\tissues = new IssueService(this)\r\n\tissueComments = new IssueCommentService(this)\r\n\tworkspaces = new WorkspaceService(this)\r\n\tmain = new MainService(this)\r\n\tcomponents = new ComponentService(this)\r\n\tcomponentTypes = new ComponentTypeService(this)\r\n\tcomponentStages = new ComponentStageService(this)\r\n\tcomponentStageCompletions = new ComponentStageCompletionService(this)\r\n\tuserForms = new UserFormService(this)\r\n\tuserFormSubmissions = new UserFormSubmissionService(this)\r\n\tprojects = new ProjectService(this)\r\n\tprojectFiles = new ProjectFileService(this)\r\n\temailVerification = new EmailVerificationService(this)\r\n}\r\n\r\n// Instance of the API that the whole app uses\r\nexport const makeClient = (apiUrl: string, store: ToolkitStore<RootState>) => new OvermapSDK(apiUrl, store)\r\n","import React, { useEffect, useMemo } from \"react\"\r\nimport { makeClient, OvermapSDK } from \"../../sdk\"\r\nimport { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport interface ISDKContext {\r\n\tsdk: OvermapSDK\r\n}\r\n\r\n/** The client store is the store passed to the SDKProvider\r\n * and is used where the SDKProvider is not available.\r\n */\r\nexport let clientStore: ToolkitStore<RootState> | undefined\r\n\r\ninterface SDKProviderProps {\r\n\tchildren: React.ReactNode\r\n\tAPI_URL: string\r\n\tstore: ToolkitStore<RootState>\r\n}\r\n\r\nconst SDKContext = React.createContext<ISDKContext>({} as ISDKContext)\r\n\r\nconst SDKProvider = ({ children, API_URL, store }: SDKProviderProps) => {\r\n\tconst client = useMemo(() => makeClient(API_URL, store), [API_URL, store])\r\n\r\n\tuseEffect(() => {\r\n\t\tclientStore = store\r\n\t}, [store])\r\n\r\n\t// TODO: Implement dependency graphs in the outbox\r\n\treturn <SDKContext.Provider value={{ sdk: client }}>{children}</SDKContext.Provider>\r\n}\r\n\r\nexport { SDKProvider, SDKContext }\r\n","import React from \"react\"\r\nimport { SDKContext } from \"./sdk\"\r\n\r\n/**\r\n * useSDK\r\n */\r\n\r\nexport const useSDK = () => {\r\n\treturn React.useContext(SDKContext)\r\n}\r\n","// Combines all the contexts into one context for the convenience of the user of the overmap-ui library.\r\n\r\nimport React from \"react\"\r\nimport { AlertDialogProvider, DefaultTheme, ToastProvider } from \"@overmap-ai/blocks\"\r\nimport { SDKProvider } from \"./sdk\"\r\n\r\nimport { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore\"\r\nimport { RootState } from \"../typings\"\r\n\r\ninterface OvermapProviderProps {\r\n\tchildren: React.ReactNode\r\n\tproduction?: boolean\r\n\tdisableDefaultTheme?: boolean\r\n\tstore: ToolkitStore<RootState>\r\n}\r\n\r\nconst OvermapContext = React.createContext(null)\r\n\r\nconst PRODUCTION_URL = \"https://api.wordn.io\"\r\nconst STAGING_URL = \"https://test-api.hemora.ca\"\r\n\r\nconst OvermapProvider = (props: OvermapProviderProps) => {\r\n\tconst { children, production, disableDefaultTheme = false, store } = props\r\n\r\n\tlet ret = (\r\n\t\t<AlertDialogProvider>\r\n\t\t\t<ToastProvider>\r\n\t\t\t\t<SDKProvider API_URL={production ? PRODUCTION_URL : STAGING_URL} store={store}>\r\n\t\t\t\t\t{children}\r\n\t\t\t\t</SDKProvider>\r\n\t\t\t</ToastProvider>\r\n\t\t</AlertDialogProvider>\r\n\t)\r\n\r\n\tif (!disableDefaultTheme) {\r\n\t\tret = <DefaultTheme>{ret}</DefaultTheme>\r\n\t}\r\n\treturn <OvermapContext.Provider value={null}>{ret}</OvermapContext.Provider>\r\n}\r\n\r\nexport { OvermapProvider, OvermapContext }\r\n"],"names":["DepGraph","request","uuid","o","toPrimitive","toPropertyKey","r","defineProperty","randomString","process","_objectSpread","HttpMethod","IssuePriority","IssueStatus","MapStyle","VERSION_REDUCER_KEY","_a","migration","initialState","createSlice","useState","useEffect","file","uuidv4","self","useRef","createSelector","today","ProjectAccessLevel","OrganizationAccessLevel","ProjectType","VerificationCodeType","shallowEqual","combineReducers","createNextState","clientStore","offline","configureStore","error","unsafeShowToast","useDispatch","useSelector","performRequest","promise","RESET_STATE","requestDetails","openDB","exports","useMemo","jsx","AlertDialogProvider","ToastProvider","DefaultTheme"],"mappings":"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","x_google_ignoreList":[3,4,5,6,7,8,23]}
|
|
1
|
+
{"version":3,"file":"overmap-core.umd.cjs","sources":["../src/sdk/classes/OutboxCoordinator.ts","../src/sdk/errors.ts","../src/utils/async/DeferredPromise.ts","../node_modules/redux/node_modules/@babel/runtime/helpers/esm/typeof.js","../node_modules/redux/node_modules/@babel/runtime/helpers/esm/toPrimitive.js","../node_modules/redux/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js","../node_modules/redux/node_modules/@babel/runtime/helpers/esm/defineProperty.js","../node_modules/redux/node_modules/@babel/runtime/helpers/esm/objectSpread2.js","../node_modules/redux/es/redux.js","../src/enums/api.ts","../src/enums/issue.ts","../src/enums/map.ts","../src/store/migrations.ts","../src/store/slices/authSlice.ts","../src/utils/coordinates.ts","../src/utils/css.ts","../src/utils/file.ts","../src/utils/logging.ts","../src/utils/offline.ts","../src/utils/search.ts","../src/utils/string.ts","../src/utils/utils.ts","../src/utils/optimization.ts","../node_modules/@radix-ui/colors/index.mjs","../src/utils/colors.ts","../src/utils/date.ts","../src/store/slices/categorySlice.ts","../src/store/slices/componentSlice.ts","../src/store/slices/ComponentStageCompletionSlice.ts","../src/store/slices/componentStageSlice.ts","../src/store/slices/componentTypeSlice.ts","../src/store/slices/workspaceSlice.ts","../src/store/slices/issueSlice.ts","../src/store/slices/fileSlice.ts","../src/store/slices/mapSlice.ts","../src/typings/models/access.ts","../src/typings/models/projects.ts","../src/typings/models/emailVerification.ts","../src/store/slices/userSlice.ts","../src/store/slices/organizationAccessSlice.ts","../src/store/slices/organizationSlice.ts","../src/store/slices/outboxSlice.ts","../src/store/slices/projectAccessSlice.ts","../src/store/slices/projectSlice.ts","../src/store/slices/projectFileSlice.ts","../src/store/slices/rehydratedSlice.ts","../src/store/slices/settingsSlice.ts","../src/store/slices/userFormSlice.ts","../src/store/slices/emailDomainsSlice.ts","../src/store/slices/versioningSlice.ts","../src/constants/ui.ts","../src/constants/defaults.ts","../src/constants/offline.ts","../src/store/store.ts","../src/store/hooks.ts","../src/sdk/services/BaseApiService.ts","../src/sdk/services/AttachmentService.ts","../src/sdk/services/AuthService.ts","../src/sdk/services/CategoryService.ts","../src/sdk/services/ComponentService.ts","../src/sdk/services/ComponentStageCompletionService.ts","../src/sdk/services/ComponentStageService.ts","../src/sdk/services/ComponentTypeService.ts","../src/sdk/services/IssueCommentService.ts","../src/sdk/services/IssueService.ts","../src/sdk/services/MainService.ts","../src/sdk/services/ProjectAccessService.ts","../src/sdk/services/ProjectFileService.ts","../src/sdk/services/ProjectService.ts","../src/sdk/services/UserFormService.ts","../src/sdk/services/UserFormSubmissionService.ts","../src/sdk/services/WorkspaceService.ts","../src/sdk/services/OrganizationAccessService.ts","../src/sdk/services/FileService.ts","../src/sdk/services/EmailVerificationService.ts","../src/sdk/services/EmailDomainsService.ts","../src/sdk/services/OrganizationService.ts","../src/sdk/sdk.ts","../src/contexts/sdk/sdk.tsx","../src/contexts/sdk/hooks.ts","../src/contexts/overmap.tsx"],"sourcesContent":["import { DepGraph } from \"dependency-graph\"\r\nimport type { FullOfflineAction } from \"../../store\"\r\nimport { Outbox } from \"@redux-offline/redux-offline/lib/types\"\r\n\r\n// TODO: Tests:\r\n// - Bulk-create components, then delete one of those components. Ensure the dependency to the bulk-create is found.\r\n\r\nexport class OutboxCoordinator {\r\n\tgraph: DepGraph<FullOfflineAction>\r\n\trequestAttemptCounter: Record<string, number>\r\n\r\n\tconstructor() {\r\n\t\tthis.graph = new DepGraph()\r\n\t\tthis.requestAttemptCounter = {}\r\n\t}\r\n\r\n\t/**\r\n\t * Used when the app is loaded. Reconstructs the dependency graph based on an outbox from the redux-offline store.\r\n\t */\r\n\tstatic fromOutbox(outbox: Outbox) {\r\n\t\tconst ret = new OutboxCoordinator()\r\n\r\n\t\tfor (let i = 0; i < outbox.length; i++) {\r\n\t\t\tconst outboxItem = outbox[i] as FullOfflineAction | undefined\r\n\t\t\tif (!outboxItem) {\r\n\t\t\t\tconsole.error(\"Outbox item was undefined\")\r\n\t\t\t\tcontinue\r\n\t\t\t}\r\n\t\t\tret.sneakRequest(outboxItem)\r\n\t\t\t// Add any dependencies to requests that were added before this one\r\n\t\t\tfor (let j = 0; j < i; j++) {\r\n\t\t\t\tconst previousOutboxItem = outbox[j] as FullOfflineAction | undefined\r\n\t\t\t\tif (!previousOutboxItem) {\r\n\t\t\t\t\tconsole.error(\"Previous outbox item was undefined\")\r\n\t\t\t\t\tcontinue\r\n\t\t\t\t}\r\n\t\t\t\tif (previousOutboxItem.payload.uuid === outboxItem.payload.uuid) {\r\n\t\t\t\t\tcontinue // Skip self\r\n\t\t\t\t}\r\n\t\t\t\tif (previousOutboxItem.payload.blocks.some((block) => outboxItem.payload.blockers.includes(block))) {\r\n\t\t\t\t\tOutboxCoordinator._addDependency(\r\n\t\t\t\t\t\toutboxItem.payload.uuid,\r\n\t\t\t\t\t\tpreviousOutboxItem.payload.uuid,\r\n\t\t\t\t\t\tret.graph,\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn ret\r\n\t}\r\n\r\n\t_addDependency(from: string, to: string) {\r\n\t\tOutboxCoordinator._addDependency(from, to, this.graph)\r\n\t}\r\n\r\n\tstatic _addDependency(from: string, to: string, graph: DepGraph<FullOfflineAction>) {\r\n\t\tif (from === to) {\r\n\t\t\tthrow new Error(`Tried to add dependency from node to itself: ${from}`)\r\n\t\t}\r\n\t\tconst fromExists = graph.hasNode(from)\r\n\t\tif (!fromExists) {\r\n\t\t\tthrow new Error(`Tried to add dependency from non-existent node: ${from} (to node: ${to})`)\r\n\t\t}\r\n\t\tconst toExists = graph.hasNode(to)\r\n\t\tif (!toExists) {\r\n\t\t\tthrow new Error(`Tried to add dependency to non-existent node: ${to} (from node: ${from})`)\r\n\t\t}\r\n\t\tgraph.addDependency(from, to)\r\n\t}\r\n\r\n\t/**\r\n\t * If there are one or more nodes in the graph, we find all nodes that match a dependency of the request and add a\r\n\t * dependency from the new request node to that node.\r\n\t */\r\n\taddRequest(request: FullOfflineAction) {\r\n\t\tthis.graph.addNode(request.payload.uuid, request)\r\n\r\n\t\tif (request.payload.blockers.length === 0 || this.graph.size() === 1) {\r\n\t\t\t// The request has no dependencies, or there are no other nodes in the graph, so there are no dependencies\r\n\t\t\t// to create.\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Create dependencies according to the request's blockers\r\n\t\tfor (const node of this.graph.overallOrder()) {\r\n\t\t\tif (node === request.payload.uuid) continue // Skip the node we just added\r\n\t\t\tconst details = this.graph.getNodeData(node)\r\n\t\t\t// 1. Any node matching this request's offline_id\r\n\t\t\tif (request.payload.blockers.some((blocker) => details.payload.blocks.includes(blocker))) {\r\n\t\t\t\tthis._addDependency(request.payload.uuid, node)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Inserts a request at the beginning of the queue. This could be used for requests that were popped, then failed,\r\n\t * and need to be re-enqueued at the front of the queue. Any requests that were previously blocked by this request\r\n\t * will be blocked by this request again. No blockers will be added to this request because it is assumed that the\r\n\t * request was already unblocked when it was popped.\r\n\t * @param request The request to insert at the beginning of the queue.\r\n\t */\r\n\tinsertRequest(request: FullOfflineAction) {\r\n\t\tthis.graph.addNode(request.payload.uuid, request)\r\n\r\n\t\t// Create dependencies according to the request's blockers\r\n\t\tfor (const node of this.graph.overallOrder()) {\r\n\t\t\tif (node === request.payload.uuid) continue // Skip the request we just inserted\r\n\t\t\tconst details = this.graph.getNodeData(node)\r\n\t\t\t// 1. Any node matching this request's offline_id\r\n\t\t\tif (details.payload.blockers.some((blocker) => request.payload.blocks.includes(blocker))) {\r\n\t\t\t\tthis._addDependency(node, request.payload.uuid)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Sneaks a request into the dependency graph without creating any blockers. Useful for reconstructing the graph\r\n\t * (from the offline store's outbox state) when the app is loaded.\r\n\t */\r\n\tsneakRequest(request: FullOfflineAction) {\r\n\t\tthis.graph.addNode(request.payload.uuid, request)\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the next node in line to be sent. This is the unblocked node with the fewest number of attempts. If there\r\n\t * are multiple nodes with the same number of attempts, the first one (by insertion order) will be returned.\r\n\t */\r\n\t_getNextNode(): string | undefined {\r\n\t\tconst leafNodes = this.graph.overallOrder(true)\r\n\t\tlet minAttempts = Infinity\r\n\t\tlet minAttemptsNode: string | undefined\r\n\t\tfor (const node of leafNodes) {\r\n\t\t\tconst attempts = this.requestAttemptCounter[node] || 0\r\n\t\t\tif (attempts < minAttempts) {\r\n\t\t\t\tminAttempts = attempts\r\n\t\t\t\tminAttemptsNode = node\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn minAttemptsNode\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the next request in line to be sent without removing it.\r\n\t */\r\n\tpeek(): FullOfflineAction | undefined {\r\n\t\tconst nextNode = this._getNextNode()\r\n\t\tif (!nextNode) return undefined\r\n\t\treturn this.graph.getNodeData(nextNode)\r\n\t}\r\n\r\n\t/**\r\n\t * Removes a request from the graph. This should be called when a request is successfully sent.\r\n\t * @param uuid The UUID of the request to remove.\r\n\t */\r\n\tremove(uuid: string): void {\r\n\t\tthis.graph.removeNode(uuid)\r\n\t\tdelete this.requestAttemptCounter[uuid]\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the next request in line to be sent and removes it from the graph.\r\n\t */\r\n\tpop(): FullOfflineAction | undefined {\r\n\t\tconst nextRequestDetails = this.peek()\r\n\t\tif (nextRequestDetails) {\r\n\t\t\tthis.graph.removeNode(nextRequestDetails.payload.uuid)\r\n\t\t}\r\n\t\treturn nextRequestDetails\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the current queue for the outbox. Should be called to get a new value for the outbox slice every time a\r\n\t * request is enqueued. It will be used to render the outbox items in a single lane.\r\n\t */\r\n\tgetQueue(): FullOfflineAction[] {\r\n\t\tconst ret = this.graph.overallOrder().map((nodeName) => this.graph.getNodeData(nodeName))\r\n\r\n\t\t// We will return the normal overall order, except we put the request with the fewest number of attempts at the\r\n\t\t// front of the queue, assuming it is not blocked.\r\n\t\tconst nextNode = this._getNextNode()\r\n\t\tif (nextNode) {\r\n\t\t\tconst nextRequestDetails = this.graph.getNodeData(nextNode)\r\n\t\t\tconst nextRequestIndex = ret.findIndex(\r\n\t\t\t\t(request) => request.payload.uuid === nextRequestDetails.payload.uuid,\r\n\t\t\t)\r\n\t\t\tif (nextRequestIndex !== -1) {\r\n\t\t\t\tret.splice(nextRequestIndex, 1)\r\n\t\t\t\tret.unshift(nextRequestDetails)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn ret\r\n\t}\r\n\r\n\t/**\r\n\t * Gets a list of requests that can currently be sent (requests with no unresolved dependencies). Used to process\r\n\t * the next ready request in case the request at the front of the queue is failing.\r\n\t */\r\n\tgetReady(): FullOfflineAction[] {\r\n\t\tlet ret = this.graph.overallOrder(true).map((nodeName) => this.graph.getNodeData(nodeName))\r\n\t\t// First, order by insertion order\r\n\t\tret = ret.sort((a, b) => {\r\n\t\t\treturn a.meta.offline.effect.timestamp.localeCompare(b.meta.offline.effect.timestamp)\r\n\t\t})\r\n\t\t// Then, order by number of attempts\r\n\t\tret = ret.sort((a, b) => {\r\n\t\t\tconst aAttempts = this.requestAttemptCounter[a.payload.uuid] || 0\r\n\t\t\tconst bAttempts = this.requestAttemptCounter[b.payload.uuid] || 0\r\n\t\t\t// If these are equal, we want to keep the insertion order, which should be maintained from the previous\r\n\t\t\t// sort if we return 0.\r\n\t\t\treturn aAttempts - bAttempts\r\n\t\t})\r\n\t\treturn ret\r\n\t}\r\n\r\n\tregisterRetry(uuid: string): void {\r\n\t\tthis.requestAttemptCounter[uuid] = (this.requestAttemptCounter[uuid] || 0) + 1\r\n\t}\r\n}\r\n\r\n// TODO: Consider auto-discovering UUIDs instead of (or in addition to) explicitly passing them to `enqueueRequest`\r\n/**\r\n * Given a request, returns an array of discovered UUIDs referenced in the request.\r\n * Discovers UUIDs in the URL, body, and query string.\r\n * @param request\r\n */\r\n/*\r\nfunction _discoverUuids(request: RequestDetails): Set<string> {\r\n\t// We need to consider:\r\n\t// 1. Any UUID in the URL\r\n\t// 2. Any UUID in the body\r\n\t// 3. Any UUID in the query parameters\r\n\r\n\tconst ret = new Set<string>()\r\n\r\n\tfunction discoverUuidsInArray(values: unknown[]): void {\r\n\t\tfor (const value of values) {\r\n\t\t\tif (typeof value === \"string\" && value.length === 36 && UUID_REGEX.test(value)) {\r\n\t\t\t\tret.add(value)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tconst urlParts = request.url.split(\"/\")\r\n\r\n\tdiscoverUuidsInArray(urlParts)\r\n\r\n\tif (request.payload) {\r\n\t\tdiscoverUuidsInArray(Object.values(request.payload))\r\n\t}\r\n\r\n\tif (request.queryParams) {\r\n\t\tdiscoverUuidsInArray(Object.values(request.queryParams))\r\n\t}\r\n\r\n\treturn ret\r\n}\r\n */\r\n","// Contains custom error classes used by the SDK\r\n\r\nimport request from \"superagent\"\r\n\r\nexport interface APIErrorOptions {\r\n\tdiscard: boolean\r\n}\r\n\r\nexport class APIError extends Error {\r\n\t// NOTE: Needs to conform to NetworkError in @redux-offline/redux-offline, which has `status` and `response`.\r\n\tstatus: number\r\n\tmessage: string\r\n\tresponse: request.Response | undefined\r\n\toptions: APIErrorOptions\r\n\r\n\tconstructor(message: string, response?: request.Response, options?: APIErrorOptions) {\r\n\t\tsuper(response?.text)\r\n\t\tthis.message = message\r\n\t\tthis.status = response?.status ?? 0\r\n\t\tthis.response = response\r\n\t\tthis.options = options ?? { discard: false }\r\n\t}\r\n}\r\n","// https://gist.github.com/GFoley83/5877f6c09fbcfd62569c51dc91444cf0\r\n\r\n/**\r\n * A new instance of deferred is constructed by calling `new DeferredPromise<T>()`.\r\n * The purpose of the deferred object is to expose the associated Promise\r\n * instance APIs that can be used for signaling the successful\r\n * or unsuccessful completion, as well as the state of the task.\r\n * @export\r\n * @class DeferredPromise\r\n * @implements {Promise<T>}\r\n * @template T\r\n * @example\r\n * const deferred = new DeferredPromise<string>()\r\n * console.log(deferred.state) // \"pending\"\r\n *\r\n * deferred\r\n * .then(str => console.log(str))\r\n * .catch(err => console.error(err))\r\n *\r\n * deferred.resolve(\"Foo\")\r\n * console.log(deferred.state) // \"fulfilled\"\r\n * // deferred.reject(\"Bar\")\r\n */\r\nexport class DeferredPromise<T> implements Promise<T> {\r\n\t[Symbol.toStringTag] = \"Promise\"\r\n\r\n\tprivate _promise: Promise<T>\r\n\tprivate _resolve: null | ((value?: T | PromiseLike<T>) => void)\r\n\tprivate _reject: null | ((reason?: unknown) => void)\r\n\tprivate _state: \"pending\" | \"fulfilled\" | \"rejected\" = \"pending\"\r\n\r\n\tpublic get state(): \"pending\" | \"fulfilled\" | \"rejected\" {\r\n\t\treturn this._state\r\n\t}\r\n\r\n\tconstructor() {\r\n\t\tthis._resolve = null\r\n\t\tthis._reject = null\r\n\r\n\t\tthis._promise = new Promise<T>((resolve, reject) => {\r\n\t\t\tthis._resolve = resolve as (value?: T | PromiseLike<T>) => void\r\n\t\t\tthis._reject = reject\r\n\t\t})\r\n\t}\r\n\r\n\tpublic then<TResult1, TResult2>(\r\n\t\tonFulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>,\r\n\t\tonRejected?: (reason: unknown) => TResult2 | PromiseLike<TResult2>,\r\n\t): Promise<TResult1 | TResult2> {\r\n\t\treturn this._promise.then(onFulfilled, onRejected)\r\n\t}\r\n\r\n\tpublic catch<TResult>(onRejected?: (reason: unknown) => TResult | PromiseLike<TResult>): Promise<T | TResult> {\r\n\t\treturn this._promise.catch(onRejected)\r\n\t}\r\n\r\n\tpublic resolve(value?: T | PromiseLike<T>): void {\r\n\t\tif (!this._resolve) throw new Error(\"No resolve callback\")\r\n\t\tthis._resolve(value)\r\n\t\tthis._state = \"fulfilled\"\r\n\t}\r\n\r\n\tpublic reject(reason?: unknown): void {\r\n\t\tif (!this._reject) throw reason\r\n\t\tthis._reject(reason)\r\n\t\tthis._state = \"rejected\"\r\n\t}\r\n\r\n\tpublic finally(_onFinally?: (() => void) | undefined | null): Promise<T> {\r\n\t\tthrow new Error(\"`finally` not implemented\")\r\n\t}\r\n}\r\n","export default function _typeof(o) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) {\n return typeof o;\n } : function (o) {\n return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o;\n }, _typeof(o);\n}","import _typeof from \"./typeof.js\";\nexport default function _toPrimitive(input, hint) {\n if (_typeof(input) !== \"object\" || input === null) return input;\n var prim = input[Symbol.toPrimitive];\n if (prim !== undefined) {\n var res = prim.call(input, hint || \"default\");\n if (_typeof(res) !== \"object\") return res;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (hint === \"string\" ? String : Number)(input);\n}","import _typeof from \"./typeof.js\";\nimport toPrimitive from \"./toPrimitive.js\";\nexport default function _toPropertyKey(arg) {\n var key = toPrimitive(arg, \"string\");\n return _typeof(key) === \"symbol\" ? key : String(key);\n}","import toPropertyKey from \"./toPropertyKey.js\";\nexport default function _defineProperty(obj, key, value) {\n key = toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}","import defineProperty from \"./defineProperty.js\";\nfunction ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n}\nexport default function _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n}","import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';\n\n/**\n * Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js\n *\n * Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes\n * during build.\n * @param {number} code\n */\nfunction formatProdErrorMessage(code) {\n return \"Minified Redux error #\" + code + \"; visit https://redux.js.org/Errors?code=\" + code + \" for the full message or \" + 'use the non-minified dev environment for full errors. ';\n}\n\n// Inlined version of the `symbol-observable` polyfill\nvar $$observable = (function () {\n return typeof Symbol === 'function' && Symbol.observable || '@@observable';\n})();\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nvar randomString = function randomString() {\n return Math.random().toString(36).substring(7).split('').join('.');\n};\n\nvar ActionTypes = {\n INIT: \"@@redux/INIT\" + randomString(),\n REPLACE: \"@@redux/REPLACE\" + randomString(),\n PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {\n return \"@@redux/PROBE_UNKNOWN_ACTION\" + randomString();\n }\n};\n\n/**\n * @param {any} obj The object to inspect.\n * @returns {boolean} True if the argument appears to be a plain object.\n */\nfunction isPlainObject(obj) {\n if (typeof obj !== 'object' || obj === null) return false;\n var proto = obj;\n\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n\n return Object.getPrototypeOf(obj) === proto;\n}\n\n// Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of\nfunction miniKindOf(val) {\n if (val === void 0) return 'undefined';\n if (val === null) return 'null';\n var type = typeof val;\n\n switch (type) {\n case 'boolean':\n case 'string':\n case 'number':\n case 'symbol':\n case 'function':\n {\n return type;\n }\n }\n\n if (Array.isArray(val)) return 'array';\n if (isDate(val)) return 'date';\n if (isError(val)) return 'error';\n var constructorName = ctorName(val);\n\n switch (constructorName) {\n case 'Symbol':\n case 'Promise':\n case 'WeakMap':\n case 'WeakSet':\n case 'Map':\n case 'Set':\n return constructorName;\n } // other\n\n\n return type.slice(8, -1).toLowerCase().replace(/\\s/g, '');\n}\n\nfunction ctorName(val) {\n return typeof val.constructor === 'function' ? val.constructor.name : null;\n}\n\nfunction isError(val) {\n return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number';\n}\n\nfunction isDate(val) {\n if (val instanceof Date) return true;\n return typeof val.toDateString === 'function' && typeof val.getDate === 'function' && typeof val.setDate === 'function';\n}\n\nfunction kindOf(val) {\n var typeOfVal = typeof val;\n\n if (process.env.NODE_ENV !== 'production') {\n typeOfVal = miniKindOf(val);\n }\n\n return typeOfVal;\n}\n\n/**\n * @deprecated\n *\n * **We recommend using the `configureStore` method\n * of the `@reduxjs/toolkit` package**, which replaces `createStore`.\n *\n * Redux Toolkit is our recommended approach for writing Redux logic today,\n * including store setup, reducers, data fetching, and more.\n *\n * **For more details, please read this Redux docs page:**\n * **https://redux.js.org/introduction/why-rtk-is-redux-today**\n *\n * `configureStore` from Redux Toolkit is an improved version of `createStore` that\n * simplifies setup and helps avoid common bugs.\n *\n * You should not be using the `redux` core package by itself today, except for learning purposes.\n * The `createStore` method from the core `redux` package will not be removed, but we encourage\n * all users to migrate to using Redux Toolkit for all Redux code.\n *\n * If you want to use `createStore` without this visual deprecation warning, use\n * the `legacy_createStore` import instead:\n *\n * `import { legacy_createStore as createStore} from 'redux'`\n *\n */\n\nfunction createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(0) : 'It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.');\n }\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(1) : \"Expected the enhancer to be a function. Instead, received: '\" + kindOf(enhancer) + \"'\");\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(2) : \"Expected the root reducer to be a function. Instead, received: '\" + kindOf(reducer) + \"'\");\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n /**\n * This makes a shallow copy of currentListeners so we can use\n * nextListeners as a temporary list while dispatching.\n *\n * This prevents any bugs around consumers calling\n * subscribe/unsubscribe in the middle of a dispatch.\n */\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n\n\n function getState() {\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(3) : 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.');\n }\n\n return currentState;\n }\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n\n\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(4) : \"Expected the listener to be a function. Instead, received: '\" + kindOf(listener) + \"'\");\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(5) : 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');\n }\n\n var isSubscribed = true;\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(6) : 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');\n }\n\n isSubscribed = false;\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n currentListeners = null;\n };\n }\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n\n\n function dispatch(action) {\n if (!isPlainObject(action)) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(7) : \"Actions must be plain objects. Instead, the actual type was: '\" + kindOf(action) + \"'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.\");\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(8) : 'Actions may not have an undefined \"type\" property. You may have misspelled an action type string constant.');\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(9) : 'Reducers may not dispatch actions.');\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n\n for (var i = 0; i < listeners.length; i++) {\n var listener = listeners[i];\n listener();\n }\n\n return action;\n }\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n\n\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(10) : \"Expected the nextReducer to be a function. Instead, received: '\" + kindOf(nextReducer));\n }\n\n currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT.\n // Any reducers that existed in both the new and old rootReducer\n // will receive the previous state. This effectively populates\n // the new state tree with any relevant data from the old one.\n\n dispatch({\n type: ActionTypes.REPLACE\n });\n }\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/tc39/proposal-observable\n */\n\n\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object' || observer === null) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(11) : \"Expected the observer to be an object. Instead, received: '\" + kindOf(observer) + \"'\");\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return {\n unsubscribe: unsubscribe\n };\n }\n }, _ref[$$observable] = function () {\n return this;\n }, _ref;\n } // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n\n\n dispatch({\n type: ActionTypes.INIT\n });\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[$$observable] = observable, _ref2;\n}\n/**\n * Creates a Redux store that holds the state tree.\n *\n * **We recommend using `configureStore` from the\n * `@reduxjs/toolkit` package**, which replaces `createStore`:\n * **https://redux.js.org/introduction/why-rtk-is-redux-today**\n *\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} [enhancer] The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\n\nvar legacy_createStore = createStore;\n\n/**\n * Prints a warning in the console if it exists.\n *\n * @param {String} message The warning message.\n * @returns {void}\n */\nfunction warning(message) {\n /* eslint-disable no-console */\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error(message);\n }\n /* eslint-enable no-console */\n\n\n try {\n // This error was thrown as a convenience so that if you enable\n // \"break on all exceptions\" in your console,\n // it would pause the execution at this line.\n throw new Error(message);\n } catch (e) {} // eslint-disable-line no-empty\n\n}\n\nfunction getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {\n var reducerKeys = Object.keys(reducers);\n var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';\n\n if (reducerKeys.length === 0) {\n return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';\n }\n\n if (!isPlainObject(inputState)) {\n return \"The \" + argumentName + \" has unexpected type of \\\"\" + kindOf(inputState) + \"\\\". Expected argument to be an object with the following \" + (\"keys: \\\"\" + reducerKeys.join('\", \"') + \"\\\"\");\n }\n\n var unexpectedKeys = Object.keys(inputState).filter(function (key) {\n return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];\n });\n unexpectedKeys.forEach(function (key) {\n unexpectedKeyCache[key] = true;\n });\n if (action && action.type === ActionTypes.REPLACE) return;\n\n if (unexpectedKeys.length > 0) {\n return \"Unexpected \" + (unexpectedKeys.length > 1 ? 'keys' : 'key') + \" \" + (\"\\\"\" + unexpectedKeys.join('\", \"') + \"\\\" found in \" + argumentName + \". \") + \"Expected to find one of the known reducer keys instead: \" + (\"\\\"\" + reducerKeys.join('\", \"') + \"\\\". Unexpected keys will be ignored.\");\n }\n}\n\nfunction assertReducerShape(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, {\n type: ActionTypes.INIT\n });\n\n if (typeof initialState === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(12) : \"The slice reducer for key \\\"\" + key + \"\\\" returned undefined during initialization. \" + \"If the state passed to the reducer is undefined, you must \" + \"explicitly return the initial state. The initial state may \" + \"not be undefined. If you don't want to set a value for this reducer, \" + \"you can use null instead of undefined.\");\n }\n\n if (typeof reducer(undefined, {\n type: ActionTypes.PROBE_UNKNOWN_ACTION()\n }) === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(13) : \"The slice reducer for key \\\"\" + key + \"\\\" returned undefined when probed with a random type. \" + (\"Don't try to handle '\" + ActionTypes.INIT + \"' or other actions in \\\"redux/*\\\" \") + \"namespace. They are considered private. Instead, you must return the \" + \"current state for any unknown actions, unless it is undefined, \" + \"in which case you must return the initial state, regardless of the \" + \"action type. The initial state may not be undefined, but can be null.\");\n }\n });\n}\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\n\n\nfunction combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (process.env.NODE_ENV !== 'production') {\n if (typeof reducers[key] === 'undefined') {\n warning(\"No reducer provided for key \\\"\" + key + \"\\\"\");\n }\n }\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n\n var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same\n // keys multiple times.\n\n var unexpectedKeyCache;\n\n if (process.env.NODE_ENV !== 'production') {\n unexpectedKeyCache = {};\n }\n\n var shapeAssertionError;\n\n try {\n assertReducerShape(finalReducers);\n } catch (e) {\n shapeAssertionError = e;\n }\n\n return function combination(state, action) {\n if (state === void 0) {\n state = {};\n }\n\n if (shapeAssertionError) {\n throw shapeAssertionError;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);\n\n if (warningMessage) {\n warning(warningMessage);\n }\n }\n\n var hasChanged = false;\n var nextState = {};\n\n for (var _i = 0; _i < finalReducerKeys.length; _i++) {\n var _key = finalReducerKeys[_i];\n var reducer = finalReducers[_key];\n var previousStateForKey = state[_key];\n var nextStateForKey = reducer(previousStateForKey, action);\n\n if (typeof nextStateForKey === 'undefined') {\n var actionType = action && action.type;\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(14) : \"When called with an action of type \" + (actionType ? \"\\\"\" + String(actionType) + \"\\\"\" : '(unknown type)') + \", the slice reducer for key \\\"\" + _key + \"\\\" returned undefined. \" + \"To ignore an action, you must explicitly return the previous state. \" + \"If you want this reducer to hold no value, you can return null instead of undefined.\");\n }\n\n nextState[_key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n\n hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length;\n return hasChanged ? nextState : state;\n };\n}\n\nfunction bindActionCreator(actionCreator, dispatch) {\n return function () {\n return dispatch(actionCreator.apply(this, arguments));\n };\n}\n/**\n * Turns an object whose values are action creators, into an object with the\n * same keys, but with every function wrapped into a `dispatch` call so they\n * may be invoked directly. This is just a convenience method, as you can call\n * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.\n *\n * For convenience, you can also pass an action creator as the first argument,\n * and get a dispatch wrapped function in return.\n *\n * @param {Function|Object} actionCreators An object whose values are action\n * creator functions. One handy way to obtain it is to use ES6 `import * as`\n * syntax. You may also pass a single function.\n *\n * @param {Function} dispatch The `dispatch` function available on your Redux\n * store.\n *\n * @returns {Function|Object} The object mimicking the original object, but with\n * every action creator wrapped into the `dispatch` call. If you passed a\n * function as `actionCreators`, the return value will also be a single\n * function.\n */\n\n\nfunction bindActionCreators(actionCreators, dispatch) {\n if (typeof actionCreators === 'function') {\n return bindActionCreator(actionCreators, dispatch);\n }\n\n if (typeof actionCreators !== 'object' || actionCreators === null) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(16) : \"bindActionCreators expected an object or a function, but instead received: '\" + kindOf(actionCreators) + \"'. \" + \"Did you write \\\"import ActionCreators from\\\" instead of \\\"import * as ActionCreators from\\\"?\");\n }\n\n var boundActionCreators = {};\n\n for (var key in actionCreators) {\n var actionCreator = actionCreators[key];\n\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);\n }\n }\n\n return boundActionCreators;\n}\n\n/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\nfunction compose() {\n for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n return funcs.reduce(function (a, b) {\n return function () {\n return a(b.apply(void 0, arguments));\n };\n });\n}\n\n/**\n * Creates a store enhancer that applies middleware to the dispatch method\n * of the Redux store. This is handy for a variety of tasks, such as expressing\n * asynchronous actions in a concise manner, or logging every action payload.\n *\n * See `redux-thunk` package as an example of the Redux middleware.\n *\n * Because middleware is potentially asynchronous, this should be the first\n * store enhancer in the composition chain.\n *\n * Note that each middleware will be given the `dispatch` and `getState` functions\n * as named arguments.\n *\n * @param {...Function} middlewares The middleware chain to be applied.\n * @returns {Function} A store enhancer applying the middleware.\n */\n\nfunction applyMiddleware() {\n for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {\n middlewares[_key] = arguments[_key];\n }\n\n return function (createStore) {\n return function () {\n var store = createStore.apply(void 0, arguments);\n\n var _dispatch = function dispatch() {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(15) : 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.');\n };\n\n var middlewareAPI = {\n getState: store.getState,\n dispatch: function dispatch() {\n return _dispatch.apply(void 0, arguments);\n }\n };\n var chain = middlewares.map(function (middleware) {\n return middleware(middlewareAPI);\n });\n _dispatch = compose.apply(void 0, chain)(store.dispatch);\n return _objectSpread(_objectSpread({}, store), {}, {\n dispatch: _dispatch\n });\n };\n };\n}\n\nexport { ActionTypes as __DO_NOT_USE__ActionTypes, applyMiddleware, bindActionCreators, combineReducers, compose, createStore, legacy_createStore };\n","export const enum HttpMethod {\r\n\tGET = \"GET\",\r\n\tPOST = \"POST\",\r\n\tPATCH = \"PATCH\",\r\n\tPUT = \"PUT\",\r\n\tDELETE = \"DELETE\",\r\n\t// TODO: Add support\r\n\t// OPTIONS = \"OPTIONS\",\r\n}\r\n","export enum IssuePriority {\r\n\tLOWEST = 0,\r\n\tLOW = 2,\r\n\tMEDIUM = 4,\r\n\tHIGH = 6,\r\n\tHIGHEST = 8,\r\n}\r\n\r\nexport enum IssueStatus {\r\n\tBACKLOG = 0,\r\n\tSELECTED = 2,\r\n\tDONE = 4,\r\n}\r\n","// We can call the first three \"Sun, Moon, Earth\" in the UI, but more descriptive names are used in development\r\nexport enum MapStyle {\r\n\tLIGHT = \"LIGHT\",\r\n\tDARK = \"DARK\",\r\n\tSATELLITE = \"SATELLITE\",\r\n\tNONE = \"NONE\",\r\n}\r\n","// TODO: This is deprecated and moved into redux-persist. See: https://github.com/wildlifela/redux-persist-migrate\r\n// It also doesn't seem to be doing much.\r\n\r\nimport type { Manifest, Migrator } from \"../typings\"\r\n\r\n// NOTE: If changing, also change it in store.ts (avoid circular imports)\r\nconst VERSION_REDUCER_KEY = \"versioning\"\r\n\r\ntype WrapMigrator = (migrator: Migrator) => Migrator\r\n\r\n// gets the most recent (largest) version number\r\nconst latestVersion = () => migrations.length - 1\r\n\r\n// if unset, set the app version to the latest\r\n// this is the case when someone opens the app for the first time\r\nconst initialVersioning: Migrator = (state) => {\r\n\t// @ts-expect-error This is the only time it's OK to set the version.\r\n\tstate[VERSION_REDUCER_KEY] = { version: latestVersion() }\r\n\treturn state\r\n}\r\n\r\n// migration that signs the user out due to the redux store being changed in a breaking way\r\nconst signOut: Migrator = () => {\r\n\t// set the app version to the latest so that this migration is not run again\r\n\treturn initialVersioning({})\r\n}\r\n\r\n// Added a new state to the outbox slice\r\nconst createOutboxState: Migrator = (state) => {\r\n\tif (state.outboxReducer) {\r\n\t\tstate.outboxReducer.deletedRequests = []\r\n\t}\r\n\treturn state\r\n}\r\n\r\n// wraps migrations with the skipAfterInitialVersioning check for convenience\r\nconst wrapMigration: WrapMigrator = (migrator) => (state) => {\r\n\t// REASON: This happened to GCS\r\n\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\r\n\tif (state === undefined) {\r\n\t\tstate = {}\r\n\t}\r\n\r\n\tif (state[VERSION_REDUCER_KEY]?.version === latestVersion()) return state\r\n\r\n\treturn migrator(state)\r\n}\r\n\r\n// migrations take in a RootState, modify it, and then return the updated root state\r\n// add new migrations to the **end** of this array\r\n// ensure initialVersioning() is always the first migration\r\nconst migrations: Migrator[] = [initialVersioning, signOut, signOut, createOutboxState]\r\n\r\n// used by redux-persist-migrate to run the migrations when rehydrating the app\r\nexport const manifest: Manifest = Object.fromEntries(migrations.map((migration, i) => [i, wrapMigration(migration)]))\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { TokenPair } from \"sdk/typings\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport interface AuthState {\r\n\taccessToken: string\r\n\trefreshToken: string\r\n\tisLoggedIn: boolean\r\n}\r\n\r\nconst initialState: AuthState = {\r\n\taccessToken: \"\",\r\n\trefreshToken: \"\",\r\n\tisLoggedIn: false,\r\n}\r\n\r\n/**\r\n * Stores the auth state of the app (tokens, and whether user is logged in or not)\r\n */\r\nexport const authSlice = createSlice({\r\n\tname: \"auth\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetTokens: (state, action: PayloadAction<TokenPair>) => {\r\n\t\t\tstate.accessToken = action.payload.accessToken\r\n\t\t\tstate.refreshToken = action.payload.refreshToken\r\n\t\t},\r\n\t\tclearTokens: (state) => {\r\n\t\t\tstate.accessToken = \"\"\r\n\t\t\tstate.refreshToken = \"\"\r\n\t\t},\r\n\t\tsetLoggedIn: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tif (!action.payload) {\r\n\t\t\t\tauthSlice.caseReducers.clearTokens(state)\r\n\t\t\t}\r\n\t\t\tstate.isLoggedIn = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setTokens, clearTokens, setLoggedIn } = authSlice.actions\r\nexport const selectAccessToken = (state: RootState) => state.authReducer.accessToken\r\nexport const selectIsLoggedIn = (state: RootState) => state.authReducer.isLoggedIn\r\n\r\nexport const authReducer: Reducer<AuthState> = authSlice.reducer\r\n","import L from \"leaflet\"\r\nimport { Coordinates, Geometry, Marker } from \"../typings\"\r\n\r\n// Convert our Coordinates type into a Leaflet LatLngLiteral\r\nexport const coordinatesToLiteral = (coordinates: Coordinates): L.LatLngLiteral => {\r\n\treturn { lng: coordinates[0], lat: coordinates[1] }\r\n}\r\n\r\n// Convert a Leaflet LatLngLiteral into our Coordinates type\r\nexport const literalToCoordinates = (literal: L.LatLngLiteral): Coordinates => {\r\n\treturn [literal.lng, literal.lat]\r\n}\r\n\r\n/**\r\n * Flip coordinates from [lng, lat] to [lat, lng]\r\n */\r\nexport const flipCoordinates = (coordinates: L.LatLngTuple): Coordinates => {\r\n\treturn [coordinates[1], coordinates[0]]\r\n}\r\n\r\nexport const markerToCoordinates: (marker: Marker) => Coordinates = (marker) => {\r\n\treturn flipCoordinates(marker.geometry.coordinates)\r\n}\r\n\r\nexport function offsetPositionByMeters(\r\n\toriginalPosition: L.LatLng,\r\n\tlatMeters: number,\r\n\tlngMeters: number,\r\n): L.LatLngLiteral {\r\n\tconst { lat, lng } = originalPosition\r\n\tconst earthRadius = 6378137 // Earth's radius in meters.\r\n\tconst metersPerDegree = (2 * Math.PI * earthRadius) / 360\r\n\t// The significance of one degree decreases the closer you get to a pole. This accounts for that.\r\n\tconst newLng = lng + lngMeters / metersPerDegree / Math.cos((lat * Math.PI) / 180)\r\n\tconst newLat = lat - latMeters / metersPerDegree\r\n\treturn { lat: newLat, lng: newLng }\r\n}\r\n\r\nexport const coordinatesToPointGeometry = (coordinates: Coordinates): Geometry => {\r\n\treturn {\r\n\t\ttype: \"Point\",\r\n\t\tcoordinates,\r\n\t}\r\n}\r\n\r\nexport const createPointMarker = (coordinates: Coordinates): Marker => {\r\n\treturn {\r\n\t\ttype: \"Feature\",\r\n\t\tgeometry: coordinatesToPointGeometry(coordinates),\r\n\t\tproperties: {},\r\n\t}\r\n}\r\n\r\nexport const coordinatesAreEqual = (a: Coordinates, b: Coordinates): boolean => {\r\n\treturn a[0] === b[0] && a[1] === b[1]\r\n}\r\n\r\n// export const coordinatesAreNearlyEqual = (a: Coordinates, b: Coordinates, thresholdMeters: number): boolean => {\r\n// return a === b\r\n// TODO: Fix\r\n// const diffLat = Math.abs(a[1] - b[1])\r\n// Length in km of 1° of latitude = always 111.32 km\r\n// const diffLatMeters = diffLat * 111320\r\n// if (diffLatMeters < thresholdMeters) return true\r\n// Length in km of 1° of longitude = 40075 km * cos(latitude) / 360'\r\n// const aVal = a[0] // Optimization\r\n// const diffLong = Math.abs(aVal - b[0])\r\n// const diffLongMeters = diffLong * ((40075000 * Math.cos(aVal)) / 360)\r\n// return diffLongMeters < thresholdMeters\r\n// }\r\n\r\n// This converts a Coordinate [lng, lat] to \"lat, lng\" string format with an option to round the numbers\r\nexport const coordinatesToText = (coordinates: Coordinates | null | undefined, decimalPlaces?: number) => {\r\n\tif (!coordinates) return \"(No Location)\"\r\n\tconst { lat, lng } = coordinatesToLiteral(coordinates)\r\n\tif (decimalPlaces) return `${lat.toFixed(decimalPlaces)}, ${lng.toFixed(decimalPlaces)}`\r\n\treturn `${lat}, ${lng}`\r\n}\r\n\r\nexport const coordinatesToUrlText = (coordinates: Coordinates) => {\r\n\tconst { lat, lng } = coordinatesToLiteral(coordinates)\r\n\treturn `${lat}%2C${lng}`\r\n}\r\n\r\nexport const getMarkerCoordinates = (marker: Marker | null): Coordinates | undefined => {\r\n\treturn marker?.geometry.coordinates\r\n}\r\n\r\nexport const markerCoordinatesToText = (marker: Marker | null, decimalPlaces?: number): string => {\r\n\tconst coordinates: Coordinates | undefined = getMarkerCoordinates(marker)\r\n\tif (coordinates) return coordinatesToText(coordinates, decimalPlaces)\r\n\treturn \"(No location)\"\r\n}\r\n\r\n// Opens coordinates in Google maps\r\nexport const openCoordsInGoogleMaps = (coordinates: Coordinates) => {\r\n\tconst url = `https://www.google.com/maps/search/?api=1&query=${coordinatesToUrlText(coordinates)}`\r\n\twindow.open(url)\r\n}\r\n\r\nexport const openDirectionsInGoogleMaps = (startingPoint: Coordinates, destination: Coordinates) => {\r\n\tconst startingPointUrl = coordinatesToUrlText(startingPoint)\r\n\tconst destinationUrl = coordinatesToUrlText(destination)\r\n\tconst url = `https://www.google.com/maps/dir/?api=1&origin=${startingPointUrl}&destination=${destinationUrl}`\r\n\twindow.open(url)\r\n}\r\n\r\nexport const worldBounds: [L.LatLngTuple, L.LatLngTuple] = [\r\n\t[90, -180],\r\n\t[-90, 180],\r\n]\r\n","/**\r\n * Combines multiple class names into a single string. Keys are class names and values are booleans.\r\n * If the value is true, the key is added to the string.\r\n */\r\nexport function classNames(...args: (object | string | undefined | null | number)[]): string {\r\n\tconst classes: string[] = []\r\n\tfor (const arg of args) {\r\n\t\tif (!arg) {\r\n\t\t\tcontinue\r\n\t\t}\r\n\t\tif (typeof arg === \"string\") {\r\n\t\t\tclasses.push(arg)\r\n\t\t} else if (typeof arg === \"object\") {\r\n\t\t\tfor (const [key, value] of Object.entries(arg)) {\r\n\t\t\t\tif (value) {\r\n\t\t\t\t\tclasses.push(key)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn classes.join(\" \")\r\n}\r\n","import { useSDK } from \"contexts/sdk\"\r\nimport { useEffect, useState } from \"react\"\r\n\r\n// See: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string\r\nfunction hex(buffer: ArrayBufferLike): string {\r\n\tconst hashArray = new Uint8Array(buffer)\r\n\r\n\treturn hashArray.reduce((data, byte) => data + byte.toString(16).padStart(2, \"0\"), \"\")\r\n}\r\n\r\nexport const getFileS3Key = async (file: File, hash?: string) => {\r\n\tif (!hash) {\r\n\t\thash = await hashFile(file)\r\n\t}\r\n\tlet fileType = file.type\r\n\tif (fileType.includes(\"/\")) {\r\n\t\tfileType = fileType.split(\"/\")[1]!\r\n\t}\r\n\tif (!fileType) {\r\n\t\tthrow new Error(`Could not extract file type from ${file.type}`)\r\n\t}\r\n\treturn `${hash}.${fileType}`\r\n}\r\n\r\nexport function hashFile(file: Blob): Promise<string> {\r\n\treturn new Promise((resolve, reject) => {\r\n\t\tconst reader = new FileReader()\r\n\t\t// Provide an onload callback for this instance of FileReader\r\n\t\t// This is called once reader.readAsArrayBuffer() is done\r\n\t\treader.onload = () => {\r\n\t\t\tconst fileResult = reader.result as ArrayBuffer | null\r\n\t\t\tif (!fileResult) {\r\n\t\t\t\treject()\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\r\n\t\t\tvoid crypto.subtle.digest(\"SHA-1\", fileResult).then((hash) => {\r\n\t\t\t\tconst sha1result = hex(hash)\r\n\t\t\t\tresolve(sha1result)\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\t// calling reader.readAsArrayBuffer and providing a file should trigger the callback above\r\n\t\t// as soon as readAsArrayBuffer is complete\r\n\t\treader.readAsArrayBuffer(file)\r\n\t})\r\n}\r\n\r\nexport function getFileIdentifier(file: File): string {\r\n\tif (!file.name || !file.type || !file.size) {\r\n\t\tconst message = \"File has no name, type, and/or size\"\r\n\t\tconsole.error(`${message}`, file)\r\n\t\tthrow new Error(`${message}.`)\r\n\t}\r\n\treturn `${file.name}&${file.type}${file.size}`\r\n}\r\n\r\nexport function getRenamedFile(file: File, newName: string): File & { name: string } {\r\n\treturn new File([file], newName, { type: file.type })\r\n}\r\n\r\nexport function downloadInMemoryFile(filename: string, text: string) {\r\n\tconst element = document.createElement(\"a\")\r\n\telement.setAttribute(\"href\", \"data:text/plain;charset=utf-8,\" + encodeURIComponent(text))\r\n\telement.setAttribute(\"download\", filename)\r\n\r\n\telement.style.display = \"none\"\r\n\tdocument.body.appendChild(element)\r\n\r\n\telement.click()\r\n\r\n\tdocument.body.removeChild(element)\r\n}\r\n\r\nexport const fileToBlob = async (dataUrl: string): Promise<Blob> => {\r\n\t// TODO: Is this as reliable and supported as this?\r\n\t// https://www.nixtu.info/2013/06/how-to-upload-canvas-data-to-server.html\r\n\treturn (await fetch(dataUrl)).blob()\r\n}\r\n\r\nexport const blobToBase64 = (blob: Blob): Promise<string> => {\r\n\treturn new Promise((resolve, _) => {\r\n\t\tconst reader = new FileReader()\r\n\t\treader.onloadend = () => {\r\n\t\t\tresolve(reader.result?.toString() || \"\")\r\n\t\t}\r\n\t\treader.readAsDataURL(blob)\r\n\t})\r\n}\r\n\r\nexport interface useFileSrcProps {\r\n\tfile: string | null\r\n\tfileSha1: string | null\r\n\tplaceholder?: string\r\n}\r\n\r\n// TODO:\r\n/** Converts a profile `file` and `fileSha1` into an img src that can be rendered. This relies on an API request. */\r\nexport const useFileSrc = (props: useFileSrcProps) => {\r\n\tconst { file, fileSha1, placeholder } = props\r\n\tconst [src, setSrc] = useState(placeholder)\r\n\tconst { sdk } = useSDK()\r\n\r\n\t// Fetch the photo file, return false\r\n\tuseEffect(() => {\r\n\t\t// use the default placeholder if no file or fileSha1\r\n\t\tif (!fileSha1 || !file) return\r\n\r\n\t\tsdk.files\r\n\t\t\t.fetchFileFromUrl(file, fileSha1)\r\n\t\t\t.then((file) => {\r\n\t\t\t\tsetSrc(URL.createObjectURL(file))\r\n\t\t\t})\r\n\t\t\t.catch((reason) => {\r\n\t\t\t\tconsole.error(`Failed to fetch file ${file} (${fileSha1}):\\n`, reason)\r\n\t\t\t})\r\n\t}, [file, fileSha1, sdk.files])\r\n\r\n\treturn src\r\n}\r\n","const logCache: Record<string, Record<string, boolean> | undefined> = {}\r\n\r\n/**\r\n * Logging the same message over and over again in a loop takes a lot of resources and makes the app laggy. This utility\r\n * function accepts a log ID (e.g. \"issue-has-no-index-workspace\") and an object ID (e.g. the offline_id of an issue),\r\n * and only logs the message on the first call with the same combination of logId and objId.\r\n * @param logId An arbitrary but unique identifier for this \"type of message\".\r\n * @param objId A unique identifier for the object the message regards. Can be an arbitrary string, e.g. \"current-user\"\r\n * or an actual object ID, e.g. the offline_id of an issue.\r\n * @param level The log level to use. For example, \"debug\" means `console.debug` will be called.\r\n * @param args The arguments to pass to the console log method.\r\n */\r\nexport function logOnlyOnce(\r\n\tlogId: string,\r\n\tobjId: string,\r\n\tlevel: \"debug\" | \"info\" | \"warn\" | \"error\",\r\n\t...args: unknown[]\r\n) {\r\n\tconst thisLogIdCache = logCache[logId]\r\n\tlet shouldLog = false\r\n\tif (!thisLogIdCache) {\r\n\t\tlogCache[logId] = { [objId]: true }\r\n\t\tshouldLog = true\r\n\t} else {\r\n\t\tconst hasLoggedForThisObject = thisLogIdCache[objId]\r\n\t\tif (!hasLoggedForThisObject) {\r\n\t\t\tthisLogIdCache[objId] = true\r\n\t\t\tshouldLog = true\r\n\t\t}\r\n\t}\r\n\tif (shouldLog) {\r\n\t\tconsole[level](...args)\r\n\t}\r\n}\r\n","import { Offline, OfflineModel } from \"../typings\"\r\nimport { v4 as uuidv4 } from \"uuid\"\r\n\r\n/**\r\n * Adds a generated UUID to the \"offline_id\" key of the object.\r\n * @param draft The model data to add the offline_id to\r\n */\r\nexport function offline<T>(draft: T): Offline<T> {\r\n\treturn { ...draft, offline_id: uuidv4() } as Offline<T>\r\n}\r\n\r\n/**\r\n * Converts an array of OfflineModel objects to a Record<string, TModel>, mapping an offline ID to the object with that\r\n * offline ID.\r\n * @param array An array of offline model instances\r\n */\r\nexport function toOfflineIdRecord<TModel extends OfflineModel>(array: TModel[]): Record<string, TModel> {\r\n\tconst asMapping: Record<string, TModel> = {}\r\n\tfor (const item of array) {\r\n\t\tasMapping[item.offline_id] = item\r\n\t}\r\n\treturn asMapping\r\n}\r\n","import { SearchResult, Stored } from \"../typings\"\r\nimport { Issue } from \"../typings\"\r\n\r\nexport const issueToSearchResult = (issue: Stored<Issue>, tag: string | null): SearchResult<Stored<Issue>> => {\r\n\treturn {\r\n\t\tlabel: issue.title || \"\",\r\n\t\ttypeLabel: \"issue\",\r\n\t\ttag: tag,\r\n\t\titem: issue,\r\n\t}\r\n}\r\n","/**\r\n * Returns a file-safe string from arbitrary text. Will return maximum 255 characters, which is the longest safe\r\n * Long File Name (LFN).\r\n * WARNING! May give poor performance in big loops.\r\n * @param str The string to make safe for file names.\r\n * @param extension An extension (not including a period) to be added after a period at the end of the string. The\r\n * character limit of the returned string includes the extension, meaning characters from str will be removed to\r\n * accommodate it if necessary.\r\n * @param maxLength The maximum length of the resulting file name. Defaults to 255.\r\n */\r\nexport function toFileNameSafeString(str: string, extension: string | undefined = undefined, maxLength = 255): string {\r\n\tlet ret = str.replace(/[^a-z0-9_\\-.]/gi, \"_\").replace(/_{2,}/g, \"_\")\r\n\tif (!extension) {\r\n\t\tconst parts = str.split(\".\")\r\n\t\tif (parts.length > 1) {\r\n\t\t\textension = parts[parts.length - 1]\r\n\t\t}\r\n\t}\r\n\tif (extension && !extension.startsWith(\".\")) {\r\n\t\textension = \".\" + extension\r\n\t}\r\n\tconst extensionLengthWithPeriod = extension ? extension.length : 0\r\n\r\n\tif (ret.length + extensionLengthWithPeriod > maxLength) {\r\n\t\tret = ret.slice(0, maxLength - extensionLengthWithPeriod) + (extension || \"\")\r\n\t}\r\n\treturn ret\r\n}\r\n\r\nexport function spacesToDashesLower(value: string): string {\r\n\treturn value.toLowerCase().replace(\" \", \"-\")\r\n}\r\n\r\nexport function slugify(str: string, underscore = false) {\r\n\treturn str\r\n\t\t.normalize(\"NFKD\")\r\n\t\t.toLowerCase()\r\n\t\t.replace(/[^\\w\\s-]/g, \"\")\r\n\t\t.trim()\r\n\t\t.replace(/[-\\s]+/g, underscore ? \"_\" : \"-\")\r\n}\r\n\r\n/**\r\n * Given a string, returns a truncated version of it with an ellipsis character at the end if it is longer than\r\n * maxLength. The resulting string will be no longer than maxLength. Note that the ellipsis is only one character long.\r\n * @param str The string to truncate.\r\n * @param maxLength The maximum length of the resulting string, including the ellipsis.\r\n */\r\nexport function truncate(str: string, maxLength: number) {\r\n\tif (str.length <= maxLength) {\r\n\t\treturn str\r\n\t}\r\n\t// -1 to account for the ellipsis character\r\n\tconst subString = str.slice(0, maxLength - 1)\r\n\treturn subString.slice(0, subString.lastIndexOf(\" \")) + \"…\"\r\n}\r\n","import { Coordinates, IssueAttachment, OfflineModel, RootState } from \"../typings\"\r\n\r\ntype MemoizedSelectorWithArgs<TArgs, TRet> = (state: RootState, args: TArgs) => TRet\r\n\r\n// makes the createSelector function fit the current pattern for selectors with arguments\r\nexport const restructureCreateSelectorWithArgs =\r\n\t<TArgs, TRet>(selector: MemoizedSelectorWithArgs<TArgs, TRet>) =>\r\n\t(args: TArgs) =>\r\n\t(state: RootState) =>\r\n\t\tselector(state, args)\r\n\r\nexport function onlyUniqueOfflineIds(value: OfflineModel, index: number, self: OfflineModel[]) {\r\n\treturn self.findIndex((v) => v.offline_id === value.offline_id) === index\r\n}\r\n\r\nexport function onlyUniqueHashes(value: IssueAttachment, index: number, self: IssueAttachment[]) {\r\n\treturn (\r\n\t\tself.findIndex((v: IssueAttachment) => {\r\n\t\t\treturn v.file_sha1 === value.file_sha1\r\n\t\t}) === index\r\n\t)\r\n}\r\n\r\n/**\r\n *\r\n * @param bounds order: [northEast, southWest]\r\n * @param coordinates\r\n */\r\nexport function boundsContainPoint(bounds: [Coordinates, Coordinates], coordinates: Coordinates): boolean {\r\n\t// TODO: this is flipped for Marker (Geometry)\r\n\treturn (\r\n\t\tbounds[0][0] > coordinates[0] &&\r\n\t\tbounds[1][0] < coordinates[0] &&\r\n\t\tbounds[0][1] > coordinates[1] &&\r\n\t\tbounds[1][1] < coordinates[1]\r\n\t)\r\n}\r\n\r\nexport const emailRegex = /^.+@.+\\..+$/\r\n","import React, { useEffect, useRef } from \"react\"\r\n\r\nlet debug = false\r\n\r\nconst REACT_APP_DEBUG_MEMOIZATION = (import.meta.env.REACT_APP_DEBUG_MEMOIZATION as string | undefined) || \"\"\r\n\r\nif ([\"true\", \"1\"].includes(REACT_APP_DEBUG_MEMOIZATION.toLowerCase())) {\r\n\tdebug = true\r\n}\r\n\r\nexport function shallowEqual(objA: object, objB: object) {\r\n\t// Check if they're the same object (objA is objB) -- just a quick reference check\r\n\tif (objA === objB) return true\r\n\r\n\tif (typeof objA !== typeof objB) {\r\n\t\treturn false\r\n\t}\r\n\r\n\tconst keysA = Object.keys(objA)\r\n\tconst keysB = Object.keys(objB)\r\n\r\n\t// Only calculate this once\r\n\tconst keysALength = keysA.length\r\n\tif (keysALength !== keysB.length) return false\r\n\r\n\tfor (let i = 0; i < keysALength; i++) {\r\n\t\tif (!Object.prototype.hasOwnProperty.call(objB, keysA[i]!) || objA[keysA[i]!] !== objB[keysA[i]!]) {\r\n\t\t\treturn false\r\n\t\t}\r\n\t}\r\n\r\n\treturn true\r\n}\r\n\r\nexport function memoize<T extends (...args) => unknown>(func: T): T {\r\n\t// Taken from https://www.sitepoint.com/implementing-memoization-in-javascript/\r\n\tconst memo = {}\r\n\r\n\treturn function () {\r\n\t\t// eslint-disable-next-line prefer-rest-params\r\n\t\tconst args = Array.prototype.slice.call(arguments)\r\n\r\n\t\t// SEE: https://stackoverflow.com/questions/10173956/how-to-use-array-as-key-in-javascript\r\n\r\n\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n\t\t// @ts-expect-error\r\n\t\tif (args in memo) {\r\n\t\t\tif (debug) {\r\n\t\t\t\tconsole.debug(`Memoization debug: Using memorized return value for ${func.toString()}(`, args, \")\")\r\n\t\t\t}\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n\t\t\t// @ts-expect-error\r\n\t\t\treturn memo[args] as T\r\n\t\t} else {\r\n\t\t\tif (debug) {\r\n\t\t\t\tconsole.debug(`Memoization debug: Cache miss! Memoizing ${func.toString()}(`, args, \")\")\r\n\t\t\t}\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n\t\t\t// @ts-expect-error\r\n\t\t\treturn (memo[args] = func.apply(this, args))\r\n\t\t}\r\n\t} as T\r\n}\r\n\r\nexport type EqualityChecker<TArgs> = (current: TArgs, previous: TArgs) => boolean\r\n\r\nexport function useMemoCompare<TValue>(\r\n\tnext: TValue | undefined,\r\n\tcompare: (prev: TValue | undefined, next: TValue | undefined) => boolean,\r\n): TValue | undefined {\r\n\t// Ref for storing previous value\r\n\tconst previousRef = useRef<TValue>()\r\n\tconst previous: TValue | undefined = previousRef.current\r\n\r\n\t// Pass previous and next value to compare function\r\n\t// to determine whether to consider them equal.\r\n\tconst isEqual = compare(previous, next)\r\n\r\n\t// If not equal update previousRef to next value.\r\n\t// We only update if not equal so that this hook continues to return\r\n\t// the same old value if compare keeps returning true.\r\n\tuseEffect(() => {\r\n\t\tif (!isEqual) {\r\n\t\t\tpreviousRef.current = next\r\n\t\t}\r\n\t})\r\n\r\n\t// Finally, if equal then return the previous value\r\n\treturn isEqual ? previous : next\r\n}\r\n\r\n/**\r\n * Performs an equality check by contents in order.\r\n * Reference types like objects and arrays are compared by reference.\r\n */\r\nexport function areArraysEqual(first: unknown[], second: unknown[]) {\r\n\tif (first.length !== second.length) return false\r\n\tfor (let i = 0; i < first.length; i++) {\r\n\t\tif (first[i] !== second[i]) return false\r\n\t}\r\n\treturn true\r\n}\r\n\r\nexport const genericMemo: <T>(component: T) => T = React.memo\r\n","const grayDark = {\n gray1: \"#111111\",\n gray2: \"#191919\",\n gray3: \"#222222\",\n gray4: \"#2a2a2a\",\n gray5: \"#313131\",\n gray6: \"#3a3a3a\",\n gray7: \"#484848\",\n gray8: \"#606060\",\n gray9: \"#6e6e6e\",\n gray10: \"#7b7b7b\",\n gray11: \"#b4b4b4\",\n gray12: \"#eeeeee\",\n};\nconst grayDarkA = {\n grayA1: \"#00000000\",\n grayA2: \"#ffffff09\",\n grayA3: \"#ffffff12\",\n grayA4: \"#ffffff1b\",\n grayA5: \"#ffffff22\",\n grayA6: \"#ffffff2c\",\n grayA7: \"#ffffff3b\",\n grayA8: \"#ffffff55\",\n grayA9: \"#ffffff64\",\n grayA10: \"#ffffff72\",\n grayA11: \"#ffffffaf\",\n grayA12: \"#ffffffed\",\n};\nconst grayDarkP3 = {\n gray1: \"color(display-p3 0.067 0.067 0.067)\",\n gray2: \"color(display-p3 0.098 0.098 0.098)\",\n gray3: \"color(display-p3 0.135 0.135 0.135)\",\n gray4: \"color(display-p3 0.163 0.163 0.163)\",\n gray5: \"color(display-p3 0.192 0.192 0.192)\",\n gray6: \"color(display-p3 0.228 0.228 0.228)\",\n gray7: \"color(display-p3 0.283 0.283 0.283)\",\n gray8: \"color(display-p3 0.375 0.375 0.375)\",\n gray9: \"color(display-p3 0.431 0.431 0.431)\",\n gray10: \"color(display-p3 0.484 0.484 0.484)\",\n gray11: \"color(display-p3 0.706 0.706 0.706)\",\n gray12: \"color(display-p3 0.933 0.933 0.933)\",\n};\nconst grayDarkP3A = {\n grayA1: \"color(display-p3 0 0 0 / 0)\",\n grayA2: \"color(display-p3 1 1 1 / 0.034)\",\n grayA3: \"color(display-p3 1 1 1 / 0.071)\",\n grayA4: \"color(display-p3 1 1 1 / 0.105)\",\n grayA5: \"color(display-p3 1 1 1 / 0.134)\",\n grayA6: \"color(display-p3 1 1 1 / 0.172)\",\n grayA7: \"color(display-p3 1 1 1 / 0.231)\",\n grayA8: \"color(display-p3 1 1 1 / 0.332)\",\n grayA9: \"color(display-p3 1 1 1 / 0.391)\",\n grayA10: \"color(display-p3 1 1 1 / 0.445)\",\n grayA11: \"color(display-p3 1 1 1 / 0.685)\",\n grayA12: \"color(display-p3 1 1 1 / 0.929)\",\n};\nconst mauveDark = {\n mauve1: \"#121113\",\n mauve2: \"#1a191b\",\n mauve3: \"#232225\",\n mauve4: \"#2b292d\",\n mauve5: \"#323035\",\n mauve6: \"#3c393f\",\n mauve7: \"#49474e\",\n mauve8: \"#625f69\",\n mauve9: \"#6f6d78\",\n mauve10: \"#7c7a85\",\n mauve11: \"#b5b2bc\",\n mauve12: \"#eeeef0\",\n};\nconst mauveDarkA = {\n mauveA1: \"#00000000\",\n mauveA2: \"#f5f4f609\",\n mauveA3: \"#ebeaf814\",\n mauveA4: \"#eee5f81d\",\n mauveA5: \"#efe6fe25\",\n mauveA6: \"#f1e6fd30\",\n mauveA7: \"#eee9ff40\",\n mauveA8: \"#eee7ff5d\",\n mauveA9: \"#eae6fd6e\",\n mauveA10: \"#ece9fd7c\",\n mauveA11: \"#f5f1ffb7\",\n mauveA12: \"#fdfdffef\",\n};\nconst mauveDarkP3 = {\n mauve1: \"color(display-p3 0.07 0.067 0.074)\",\n mauve2: \"color(display-p3 0.101 0.098 0.105)\",\n mauve3: \"color(display-p3 0.138 0.134 0.144)\",\n mauve4: \"color(display-p3 0.167 0.161 0.175)\",\n mauve5: \"color(display-p3 0.196 0.189 0.206)\",\n mauve6: \"color(display-p3 0.232 0.225 0.245)\",\n mauve7: \"color(display-p3 0.286 0.277 0.302)\",\n mauve8: \"color(display-p3 0.383 0.373 0.408)\",\n mauve9: \"color(display-p3 0.434 0.428 0.467)\",\n mauve10: \"color(display-p3 0.487 0.48 0.519)\",\n mauve11: \"color(display-p3 0.707 0.7 0.735)\",\n mauve12: \"color(display-p3 0.933 0.933 0.94)\",\n};\nconst mauveDarkP3A = {\n mauveA1: \"color(display-p3 0 0 0 / 0)\",\n mauveA2: \"color(display-p3 0.996 0.992 1 / 0.034)\",\n mauveA3: \"color(display-p3 0.937 0.933 0.992 / 0.077)\",\n mauveA4: \"color(display-p3 0.957 0.918 0.996 / 0.111)\",\n mauveA5: \"color(display-p3 0.937 0.906 0.996 / 0.145)\",\n mauveA6: \"color(display-p3 0.953 0.925 0.996 / 0.183)\",\n mauveA7: \"color(display-p3 0.945 0.929 1 / 0.246)\",\n mauveA8: \"color(display-p3 0.937 0.918 1 / 0.361)\",\n mauveA9: \"color(display-p3 0.933 0.918 1 / 0.424)\",\n mauveA10: \"color(display-p3 0.941 0.925 1 / 0.479)\",\n mauveA11: \"color(display-p3 0.965 0.961 1 / 0.712)\",\n mauveA12: \"color(display-p3 0.992 0.992 1 / 0.937)\",\n};\nconst slateDark = {\n slate1: \"#111113\",\n slate2: \"#18191b\",\n slate3: \"#212225\",\n slate4: \"#272a2d\",\n slate5: \"#2e3135\",\n slate6: \"#363a3f\",\n slate7: \"#43484e\",\n slate8: \"#5a6169\",\n slate9: \"#696e77\",\n slate10: \"#777b84\",\n slate11: \"#b0b4ba\",\n slate12: \"#edeef0\",\n};\nconst slateDarkA = {\n slateA1: \"#00000000\",\n slateA2: \"#d8f4f609\",\n slateA3: \"#ddeaf814\",\n slateA4: \"#d3edf81d\",\n slateA5: \"#d9edfe25\",\n slateA6: \"#d6ebfd30\",\n slateA7: \"#d9edff40\",\n slateA8: \"#d9edff5d\",\n slateA9: \"#dfebfd6d\",\n slateA10: \"#e5edfd7b\",\n slateA11: \"#f1f7feb5\",\n slateA12: \"#fcfdffef\",\n};\nconst slateDarkP3 = {\n slate1: \"color(display-p3 0.067 0.067 0.074)\",\n slate2: \"color(display-p3 0.095 0.098 0.105)\",\n slate3: \"color(display-p3 0.13 0.135 0.145)\",\n slate4: \"color(display-p3 0.156 0.163 0.176)\",\n slate5: \"color(display-p3 0.183 0.191 0.206)\",\n slate6: \"color(display-p3 0.215 0.226 0.244)\",\n slate7: \"color(display-p3 0.265 0.28 0.302)\",\n slate8: \"color(display-p3 0.357 0.381 0.409)\",\n slate9: \"color(display-p3 0.415 0.431 0.463)\",\n slate10: \"color(display-p3 0.469 0.483 0.514)\",\n slate11: \"color(display-p3 0.692 0.704 0.728)\",\n slate12: \"color(display-p3 0.93 0.933 0.94)\",\n};\nconst slateDarkP3A = {\n slateA1: \"color(display-p3 0 0 0 / 0)\",\n slateA2: \"color(display-p3 0.875 0.992 1 / 0.034)\",\n slateA3: \"color(display-p3 0.882 0.933 0.992 / 0.077)\",\n slateA4: \"color(display-p3 0.882 0.953 0.996 / 0.111)\",\n slateA5: \"color(display-p3 0.878 0.929 0.996 / 0.145)\",\n slateA6: \"color(display-p3 0.882 0.949 0.996 / 0.183)\",\n slateA7: \"color(display-p3 0.882 0.929 1 / 0.246)\",\n slateA8: \"color(display-p3 0.871 0.937 1 / 0.361)\",\n slateA9: \"color(display-p3 0.898 0.937 1 / 0.42)\",\n slateA10: \"color(display-p3 0.918 0.945 1 / 0.475)\",\n slateA11: \"color(display-p3 0.949 0.969 0.996 / 0.708)\",\n slateA12: \"color(display-p3 0.988 0.992 1 / 0.937)\",\n};\nconst sageDark = {\n sage1: \"#101211\",\n sage2: \"#171918\",\n sage3: \"#202221\",\n sage4: \"#272a29\",\n sage5: \"#2e3130\",\n sage6: \"#373b39\",\n sage7: \"#444947\",\n sage8: \"#5b625f\",\n sage9: \"#63706b\",\n sage10: \"#717d79\",\n sage11: \"#adb5b2\",\n sage12: \"#eceeed\",\n};\nconst sageDarkA = {\n sageA1: \"#00000000\",\n sageA2: \"#f0f2f108\",\n sageA3: \"#f3f5f412\",\n sageA4: \"#f2fefd1a\",\n sageA5: \"#f1fbfa22\",\n sageA6: \"#edfbf42d\",\n sageA7: \"#edfcf73c\",\n sageA8: \"#ebfdf657\",\n sageA9: \"#dffdf266\",\n sageA10: \"#e5fdf674\",\n sageA11: \"#f4fefbb0\",\n sageA12: \"#fdfffeed\",\n};\nconst sageDarkP3 = {\n sage1: \"color(display-p3 0.064 0.07 0.067)\",\n sage2: \"color(display-p3 0.092 0.098 0.094)\",\n sage3: \"color(display-p3 0.128 0.135 0.131)\",\n sage4: \"color(display-p3 0.155 0.164 0.159)\",\n sage5: \"color(display-p3 0.183 0.193 0.188)\",\n sage6: \"color(display-p3 0.218 0.23 0.224)\",\n sage7: \"color(display-p3 0.269 0.285 0.277)\",\n sage8: \"color(display-p3 0.362 0.382 0.373)\",\n sage9: \"color(display-p3 0.398 0.438 0.421)\",\n sage10: \"color(display-p3 0.453 0.49 0.474)\",\n sage11: \"color(display-p3 0.685 0.709 0.697)\",\n sage12: \"color(display-p3 0.927 0.933 0.93)\",\n};\nconst sageDarkP3A = {\n sageA1: \"color(display-p3 0 0 0 / 0)\",\n sageA2: \"color(display-p3 0.976 0.988 0.984 / 0.03)\",\n sageA3: \"color(display-p3 0.992 0.945 0.941 / 0.072)\",\n sageA4: \"color(display-p3 0.988 0.996 0.992 / 0.102)\",\n sageA5: \"color(display-p3 0.992 1 0.996 / 0.131)\",\n sageA6: \"color(display-p3 0.973 1 0.976 / 0.173)\",\n sageA7: \"color(display-p3 0.957 1 0.976 / 0.233)\",\n sageA8: \"color(display-p3 0.957 1 0.984 / 0.334)\",\n sageA9: \"color(display-p3 0.902 1 0.957 / 0.397)\",\n sageA10: \"color(display-p3 0.929 1 0.973 / 0.452)\",\n sageA11: \"color(display-p3 0.969 1 0.988 / 0.688)\",\n sageA12: \"color(display-p3 0.992 1 0.996 / 0.929)\",\n};\nconst oliveDark = {\n olive1: \"#111210\",\n olive2: \"#181917\",\n olive3: \"#212220\",\n olive4: \"#282a27\",\n olive5: \"#2f312e\",\n olive6: \"#383a36\",\n olive7: \"#454843\",\n olive8: \"#5c625b\",\n olive9: \"#687066\",\n olive10: \"#767d74\",\n olive11: \"#afb5ad\",\n olive12: \"#eceeec\",\n};\nconst oliveDarkA = {\n oliveA1: \"#00000000\",\n oliveA2: \"#f1f2f008\",\n oliveA3: \"#f4f5f312\",\n oliveA4: \"#f3fef21a\",\n oliveA5: \"#f2fbf122\",\n oliveA6: \"#f4faed2c\",\n oliveA7: \"#f2fced3b\",\n oliveA8: \"#edfdeb57\",\n oliveA9: \"#ebfde766\",\n oliveA10: \"#f0fdec74\",\n oliveA11: \"#f6fef4b0\",\n oliveA12: \"#fdfffded\",\n};\nconst oliveDarkP3 = {\n olive1: \"color(display-p3 0.067 0.07 0.063)\",\n olive2: \"color(display-p3 0.095 0.098 0.091)\",\n olive3: \"color(display-p3 0.131 0.135 0.126)\",\n olive4: \"color(display-p3 0.158 0.163 0.153)\",\n olive5: \"color(display-p3 0.186 0.192 0.18)\",\n olive6: \"color(display-p3 0.221 0.229 0.215)\",\n olive7: \"color(display-p3 0.273 0.284 0.266)\",\n olive8: \"color(display-p3 0.365 0.382 0.359)\",\n olive9: \"color(display-p3 0.414 0.438 0.404)\",\n olive10: \"color(display-p3 0.467 0.49 0.458)\",\n olive11: \"color(display-p3 0.69 0.709 0.682)\",\n olive12: \"color(display-p3 0.927 0.933 0.926)\",\n};\nconst oliveDarkP3A = {\n oliveA1: \"color(display-p3 0 0 0 / 0)\",\n oliveA2: \"color(display-p3 0.984 0.988 0.976 / 0.03)\",\n oliveA3: \"color(display-p3 0.992 0.996 0.988 / 0.068)\",\n oliveA4: \"color(display-p3 0.953 0.996 0.949 / 0.102)\",\n oliveA5: \"color(display-p3 0.969 1 0.965 / 0.131)\",\n oliveA6: \"color(display-p3 0.973 1 0.969 / 0.169)\",\n oliveA7: \"color(display-p3 0.98 1 0.961 / 0.228)\",\n oliveA8: \"color(display-p3 0.961 1 0.957 / 0.334)\",\n oliveA9: \"color(display-p3 0.949 1 0.922 / 0.397)\",\n oliveA10: \"color(display-p3 0.953 1 0.941 / 0.452)\",\n oliveA11: \"color(display-p3 0.976 1 0.965 / 0.688)\",\n oliveA12: \"color(display-p3 0.992 1 0.992 / 0.929)\",\n};\nconst sandDark = {\n sand1: \"#111110\",\n sand2: \"#191918\",\n sand3: \"#222221\",\n sand4: \"#2a2a28\",\n sand5: \"#31312e\",\n sand6: \"#3b3a37\",\n sand7: \"#494844\",\n sand8: \"#62605b\",\n sand9: \"#6f6d66\",\n sand10: \"#7c7b74\",\n sand11: \"#b5b3ad\",\n sand12: \"#eeeeec\",\n};\nconst sandDarkA = {\n sandA1: \"#00000000\",\n sandA2: \"#f4f4f309\",\n sandA3: \"#f6f6f513\",\n sandA4: \"#fefef31b\",\n sandA5: \"#fbfbeb23\",\n sandA6: \"#fffaed2d\",\n sandA7: \"#fffbed3c\",\n sandA8: \"#fff9eb57\",\n sandA9: \"#fffae965\",\n sandA10: \"#fffdee73\",\n sandA11: \"#fffcf4b0\",\n sandA12: \"#fffffded\",\n};\nconst sandDarkP3 = {\n sand1: \"color(display-p3 0.067 0.067 0.063)\",\n sand2: \"color(display-p3 0.098 0.098 0.094)\",\n sand3: \"color(display-p3 0.135 0.135 0.129)\",\n sand4: \"color(display-p3 0.164 0.163 0.156)\",\n sand5: \"color(display-p3 0.193 0.192 0.183)\",\n sand6: \"color(display-p3 0.23 0.229 0.217)\",\n sand7: \"color(display-p3 0.285 0.282 0.267)\",\n sand8: \"color(display-p3 0.384 0.378 0.357)\",\n sand9: \"color(display-p3 0.434 0.428 0.403)\",\n sand10: \"color(display-p3 0.487 0.481 0.456)\",\n sand11: \"color(display-p3 0.707 0.703 0.68)\",\n sand12: \"color(display-p3 0.933 0.933 0.926)\",\n};\nconst sandDarkP3A = {\n sandA1: \"color(display-p3 0 0 0 / 0)\",\n sandA2: \"color(display-p3 0.992 0.992 0.988 / 0.034)\",\n sandA3: \"color(display-p3 0.996 0.996 0.992 / 0.072)\",\n sandA4: \"color(display-p3 0.992 0.992 0.953 / 0.106)\",\n sandA5: \"color(display-p3 1 1 0.965 / 0.135)\",\n sandA6: \"color(display-p3 1 0.976 0.929 / 0.177)\",\n sandA7: \"color(display-p3 1 0.984 0.929 / 0.236)\",\n sandA8: \"color(display-p3 1 0.976 0.925 / 0.341)\",\n sandA9: \"color(display-p3 1 0.98 0.925 / 0.395)\",\n sandA10: \"color(display-p3 1 0.992 0.933 / 0.45)\",\n sandA11: \"color(display-p3 1 0.996 0.961 / 0.685)\",\n sandA12: \"color(display-p3 1 1 0.992 / 0.929)\",\n};\nconst tomatoDark = {\n tomato1: \"#181111\",\n tomato2: \"#1f1513\",\n tomato3: \"#391714\",\n tomato4: \"#4e1511\",\n tomato5: \"#5e1c16\",\n tomato6: \"#6e2920\",\n tomato7: \"#853a2d\",\n tomato8: \"#ac4d39\",\n tomato9: \"#e54d2e\",\n tomato10: \"#ec6142\",\n tomato11: \"#ff977d\",\n tomato12: \"#fbd3cb\",\n};\nconst tomatoDarkA = {\n tomatoA1: \"#f1121208\",\n tomatoA2: \"#ff55330f\",\n tomatoA3: \"#ff35232b\",\n tomatoA4: \"#fd201142\",\n tomatoA5: \"#fe332153\",\n tomatoA6: \"#ff4f3864\",\n tomatoA7: \"#fd644a7d\",\n tomatoA8: \"#fe6d4ea7\",\n tomatoA9: \"#fe5431e4\",\n tomatoA10: \"#ff6847eb\",\n tomatoA11: \"#ff977d\",\n tomatoA12: \"#ffd6cefb\",\n};\nconst tomatoDarkP3 = {\n tomato1: \"color(display-p3 0.09 0.068 0.067)\",\n tomato2: \"color(display-p3 0.115 0.084 0.076)\",\n tomato3: \"color(display-p3 0.205 0.097 0.083)\",\n tomato4: \"color(display-p3 0.282 0.099 0.077)\",\n tomato5: \"color(display-p3 0.339 0.129 0.101)\",\n tomato6: \"color(display-p3 0.398 0.179 0.141)\",\n tomato7: \"color(display-p3 0.487 0.245 0.194)\",\n tomato8: \"color(display-p3 0.629 0.322 0.248)\",\n tomato9: \"color(display-p3 0.831 0.345 0.231)\",\n tomato10: \"color(display-p3 0.862 0.415 0.298)\",\n tomato11: \"color(display-p3 1 0.585 0.455)\",\n tomato12: \"color(display-p3 0.959 0.833 0.802)\",\n};\nconst tomatoDarkP3A = {\n tomatoA1: \"color(display-p3 0.973 0.071 0.071 / 0.026)\",\n tomatoA2: \"color(display-p3 0.992 0.376 0.224 / 0.051)\",\n tomatoA3: \"color(display-p3 0.996 0.282 0.176 / 0.148)\",\n tomatoA4: \"color(display-p3 1 0.204 0.118 / 0.232)\",\n tomatoA5: \"color(display-p3 1 0.286 0.192 / 0.29)\",\n tomatoA6: \"color(display-p3 1 0.392 0.278 / 0.353)\",\n tomatoA7: \"color(display-p3 1 0.459 0.349 / 0.45)\",\n tomatoA8: \"color(display-p3 1 0.49 0.369 / 0.601)\",\n tomatoA9: \"color(display-p3 1 0.408 0.267 / 0.82)\",\n tomatoA10: \"color(display-p3 1 0.478 0.341 / 0.853)\",\n tomatoA11: \"color(display-p3 1 0.585 0.455)\",\n tomatoA12: \"color(display-p3 0.959 0.833 0.802)\",\n};\nconst redDark = {\n red1: \"#191111\",\n red2: \"#201314\",\n red3: \"#3b1219\",\n red4: \"#500f1c\",\n red5: \"#611623\",\n red6: \"#72232d\",\n red7: \"#8c333a\",\n red8: \"#b54548\",\n red9: \"#e5484d\",\n red10: \"#ec5d5e\",\n red11: \"#ff9592\",\n red12: \"#ffd1d9\",\n};\nconst redDarkA = {\n redA1: \"#f4121209\",\n redA2: \"#f22f3e11\",\n redA3: \"#ff173f2d\",\n redA4: \"#fe0a3b44\",\n redA5: \"#ff204756\",\n redA6: \"#ff3e5668\",\n redA7: \"#ff536184\",\n redA8: \"#ff5d61b0\",\n redA9: \"#fe4e54e4\",\n redA10: \"#ff6465eb\",\n redA11: \"#ff9592\",\n redA12: \"#ffd1d9\",\n};\nconst redDarkP3 = {\n red1: \"color(display-p3 0.093 0.068 0.067)\",\n red2: \"color(display-p3 0.118 0.077 0.079)\",\n red3: \"color(display-p3 0.211 0.081 0.099)\",\n red4: \"color(display-p3 0.287 0.079 0.113)\",\n red5: \"color(display-p3 0.348 0.11 0.142)\",\n red6: \"color(display-p3 0.414 0.16 0.183)\",\n red7: \"color(display-p3 0.508 0.224 0.236)\",\n red8: \"color(display-p3 0.659 0.298 0.297)\",\n red9: \"color(display-p3 0.83 0.329 0.324)\",\n red10: \"color(display-p3 0.861 0.403 0.387)\",\n red11: \"color(display-p3 1 0.57 0.55)\",\n red12: \"color(display-p3 0.971 0.826 0.852)\",\n};\nconst redDarkP3A = {\n redA1: \"color(display-p3 0.984 0.071 0.071 / 0.03)\",\n redA2: \"color(display-p3 0.996 0.282 0.282 / 0.055)\",\n redA3: \"color(display-p3 1 0.169 0.271 / 0.156)\",\n redA4: \"color(display-p3 1 0.118 0.267 / 0.236)\",\n redA5: \"color(display-p3 1 0.212 0.314 / 0.303)\",\n redA6: \"color(display-p3 1 0.318 0.38 / 0.374)\",\n redA7: \"color(display-p3 1 0.4 0.424 / 0.475)\",\n redA8: \"color(display-p3 1 0.431 0.431 / 0.635)\",\n redA9: \"color(display-p3 1 0.388 0.384 / 0.82)\",\n redA10: \"color(display-p3 1 0.463 0.447 / 0.853)\",\n redA11: \"color(display-p3 1 0.57 0.55)\",\n redA12: \"color(display-p3 0.971 0.826 0.852)\",\n};\nconst rubyDark = {\n ruby1: \"#191113\",\n ruby2: \"#1e1517\",\n ruby3: \"#3a141e\",\n ruby4: \"#4e1325\",\n ruby5: \"#5e1a2e\",\n ruby6: \"#6f2539\",\n ruby7: \"#883447\",\n ruby8: \"#b3445a\",\n ruby9: \"#e54666\",\n ruby10: \"#ec5a72\",\n ruby11: \"#ff949d\",\n ruby12: \"#fed2e1\",\n};\nconst rubyDarkA = {\n rubyA1: \"#f4124a09\",\n rubyA2: \"#fe5a7f0e\",\n rubyA3: \"#ff235d2c\",\n rubyA4: \"#fd195e42\",\n rubyA5: \"#fe2d6b53\",\n rubyA6: \"#ff447665\",\n rubyA7: \"#ff577d80\",\n rubyA8: \"#ff5c7cae\",\n rubyA9: \"#fe4c70e4\",\n rubyA10: \"#ff617beb\",\n rubyA11: \"#ff949d\",\n rubyA12: \"#ffd3e2fe\",\n};\nconst rubyDarkP3 = {\n ruby1: \"color(display-p3 0.093 0.068 0.074)\",\n ruby2: \"color(display-p3 0.113 0.083 0.089)\",\n ruby3: \"color(display-p3 0.208 0.088 0.117)\",\n ruby4: \"color(display-p3 0.279 0.092 0.147)\",\n ruby5: \"color(display-p3 0.337 0.12 0.18)\",\n ruby6: \"color(display-p3 0.401 0.166 0.223)\",\n ruby7: \"color(display-p3 0.495 0.224 0.281)\",\n ruby8: \"color(display-p3 0.652 0.295 0.359)\",\n ruby9: \"color(display-p3 0.83 0.323 0.408)\",\n ruby10: \"color(display-p3 0.857 0.392 0.455)\",\n ruby11: \"color(display-p3 1 0.57 0.59)\",\n ruby12: \"color(display-p3 0.968 0.83 0.88)\",\n};\nconst rubyDarkP3A = {\n rubyA1: \"color(display-p3 0.984 0.071 0.329 / 0.03)\",\n rubyA2: \"color(display-p3 0.992 0.376 0.529 / 0.051)\",\n rubyA3: \"color(display-p3 0.996 0.196 0.404 / 0.152)\",\n rubyA4: \"color(display-p3 1 0.173 0.416 / 0.227)\",\n rubyA5: \"color(display-p3 1 0.259 0.459 / 0.29)\",\n rubyA6: \"color(display-p3 1 0.341 0.506 / 0.358)\",\n rubyA7: \"color(display-p3 1 0.412 0.541 / 0.458)\",\n rubyA8: \"color(display-p3 1 0.431 0.537 / 0.627)\",\n rubyA9: \"color(display-p3 1 0.376 0.482 / 0.82)\",\n rubyA10: \"color(display-p3 1 0.447 0.522 / 0.849)\",\n rubyA11: \"color(display-p3 1 0.57 0.59)\",\n rubyA12: \"color(display-p3 0.968 0.83 0.88)\",\n};\nconst crimsonDark = {\n crimson1: \"#191114\",\n crimson2: \"#201318\",\n crimson3: \"#381525\",\n crimson4: \"#4d122f\",\n crimson5: \"#5c1839\",\n crimson6: \"#6d2545\",\n crimson7: \"#873356\",\n crimson8: \"#b0436e\",\n crimson9: \"#e93d82\",\n crimson10: \"#ee518a\",\n crimson11: \"#ff92ad\",\n crimson12: \"#fdd3e8\",\n};\nconst crimsonDarkA = {\n crimsonA1: \"#f4126709\",\n crimsonA2: \"#f22f7a11\",\n crimsonA3: \"#fe2a8b2a\",\n crimsonA4: \"#fd158741\",\n crimsonA5: \"#fd278f51\",\n crimsonA6: \"#fe459763\",\n crimsonA7: \"#fd559b7f\",\n crimsonA8: \"#fe5b9bab\",\n crimsonA9: \"#fe418de8\",\n crimsonA10: \"#ff5693ed\",\n crimsonA11: \"#ff92ad\",\n crimsonA12: \"#ffd5eafd\",\n};\nconst crimsonDarkP3 = {\n crimson1: \"color(display-p3 0.093 0.068 0.078)\",\n crimson2: \"color(display-p3 0.117 0.078 0.095)\",\n crimson3: \"color(display-p3 0.203 0.091 0.143)\",\n crimson4: \"color(display-p3 0.277 0.087 0.182)\",\n crimson5: \"color(display-p3 0.332 0.115 0.22)\",\n crimson6: \"color(display-p3 0.394 0.162 0.268)\",\n crimson7: \"color(display-p3 0.489 0.222 0.336)\",\n crimson8: \"color(display-p3 0.638 0.289 0.429)\",\n crimson9: \"color(display-p3 0.843 0.298 0.507)\",\n crimson10: \"color(display-p3 0.864 0.364 0.539)\",\n crimson11: \"color(display-p3 1 0.56 0.66)\",\n crimson12: \"color(display-p3 0.966 0.834 0.906)\",\n};\nconst crimsonDarkP3A = {\n crimsonA1: \"color(display-p3 0.984 0.071 0.463 / 0.03)\",\n crimsonA2: \"color(display-p3 0.996 0.282 0.569 / 0.055)\",\n crimsonA3: \"color(display-p3 0.996 0.227 0.573 / 0.148)\",\n crimsonA4: \"color(display-p3 1 0.157 0.569 / 0.227)\",\n crimsonA5: \"color(display-p3 1 0.231 0.604 / 0.286)\",\n crimsonA6: \"color(display-p3 1 0.337 0.643 / 0.349)\",\n crimsonA7: \"color(display-p3 1 0.416 0.663 / 0.454)\",\n crimsonA8: \"color(display-p3 0.996 0.427 0.651 / 0.614)\",\n crimsonA9: \"color(display-p3 1 0.345 0.596 / 0.832)\",\n crimsonA10: \"color(display-p3 1 0.42 0.62 / 0.853)\",\n crimsonA11: \"color(display-p3 1 0.56 0.66)\",\n crimsonA12: \"color(display-p3 0.966 0.834 0.906)\",\n};\nconst pinkDark = {\n pink1: \"#191117\",\n pink2: \"#21121d\",\n pink3: \"#37172f\",\n pink4: \"#4b143d\",\n pink5: \"#591c47\",\n pink6: \"#692955\",\n pink7: \"#833869\",\n pink8: \"#a84885\",\n pink9: \"#d6409f\",\n pink10: \"#de51a8\",\n pink11: \"#ff8dcc\",\n pink12: \"#fdd1ea\",\n};\nconst pinkDarkA = {\n pinkA1: \"#f412bc09\",\n pinkA2: \"#f420bb12\",\n pinkA3: \"#fe37cc29\",\n pinkA4: \"#fc1ec43f\",\n pinkA5: \"#fd35c24e\",\n pinkA6: \"#fd51c75f\",\n pinkA7: \"#fd62c87b\",\n pinkA8: \"#ff68c8a2\",\n pinkA9: \"#fe49bcd4\",\n pinkA10: \"#ff5cc0dc\",\n pinkA11: \"#ff8dcc\",\n pinkA12: \"#ffd3ecfd\",\n};\nconst pinkDarkP3 = {\n pink1: \"color(display-p3 0.093 0.068 0.089)\",\n pink2: \"color(display-p3 0.121 0.073 0.11)\",\n pink3: \"color(display-p3 0.198 0.098 0.179)\",\n pink4: \"color(display-p3 0.271 0.095 0.231)\",\n pink5: \"color(display-p3 0.32 0.127 0.273)\",\n pink6: \"color(display-p3 0.382 0.177 0.326)\",\n pink7: \"color(display-p3 0.477 0.238 0.405)\",\n pink8: \"color(display-p3 0.612 0.304 0.51)\",\n pink9: \"color(display-p3 0.775 0.297 0.61)\",\n pink10: \"color(display-p3 0.808 0.356 0.645)\",\n pink11: \"color(display-p3 1 0.535 0.78)\",\n pink12: \"color(display-p3 0.964 0.826 0.912)\",\n};\nconst pinkDarkP3A = {\n pinkA1: \"color(display-p3 0.984 0.071 0.855 / 0.03)\",\n pinkA2: \"color(display-p3 1 0.2 0.8 / 0.059)\",\n pinkA3: \"color(display-p3 1 0.294 0.886 / 0.139)\",\n pinkA4: \"color(display-p3 1 0.192 0.82 / 0.219)\",\n pinkA5: \"color(display-p3 1 0.282 0.827 / 0.274)\",\n pinkA6: \"color(display-p3 1 0.396 0.835 / 0.337)\",\n pinkA7: \"color(display-p3 1 0.459 0.831 / 0.442)\",\n pinkA8: \"color(display-p3 1 0.478 0.827 / 0.585)\",\n pinkA9: \"color(display-p3 1 0.373 0.784 / 0.761)\",\n pinkA10: \"color(display-p3 1 0.435 0.792 / 0.795)\",\n pinkA11: \"color(display-p3 1 0.535 0.78)\",\n pinkA12: \"color(display-p3 0.964 0.826 0.912)\",\n};\nconst plumDark = {\n plum1: \"#181118\",\n plum2: \"#201320\",\n plum3: \"#351a35\",\n plum4: \"#451d47\",\n plum5: \"#512454\",\n plum6: \"#5e3061\",\n plum7: \"#734079\",\n plum8: \"#92549c\",\n plum9: \"#ab4aba\",\n plum10: \"#b658c4\",\n plum11: \"#e796f3\",\n plum12: \"#f4d4f4\",\n};\nconst plumDarkA = {\n plumA1: \"#f112f108\",\n plumA2: \"#f22ff211\",\n plumA3: \"#fd4cfd27\",\n plumA4: \"#f646ff3a\",\n plumA5: \"#f455ff48\",\n plumA6: \"#f66dff56\",\n plumA7: \"#f07cfd70\",\n plumA8: \"#ee84ff95\",\n plumA9: \"#e961feb6\",\n plumA10: \"#ed70ffc0\",\n plumA11: \"#f19cfef3\",\n plumA12: \"#feddfef4\",\n};\nconst plumDarkP3 = {\n plum1: \"color(display-p3 0.09 0.068 0.092)\",\n plum2: \"color(display-p3 0.118 0.077 0.121)\",\n plum3: \"color(display-p3 0.192 0.105 0.202)\",\n plum4: \"color(display-p3 0.25 0.121 0.271)\",\n plum5: \"color(display-p3 0.293 0.152 0.319)\",\n plum6: \"color(display-p3 0.343 0.198 0.372)\",\n plum7: \"color(display-p3 0.424 0.262 0.461)\",\n plum8: \"color(display-p3 0.54 0.341 0.595)\",\n plum9: \"color(display-p3 0.624 0.313 0.708)\",\n plum10: \"color(display-p3 0.666 0.365 0.748)\",\n plum11: \"color(display-p3 0.86 0.602 0.933)\",\n plum12: \"color(display-p3 0.936 0.836 0.949)\",\n};\nconst plumDarkP3A = {\n plumA1: \"color(display-p3 0.973 0.071 0.973 / 0.026)\",\n plumA2: \"color(display-p3 0.933 0.267 1 / 0.059)\",\n plumA3: \"color(display-p3 0.918 0.333 0.996 / 0.148)\",\n plumA4: \"color(display-p3 0.91 0.318 1 / 0.219)\",\n plumA5: \"color(display-p3 0.914 0.388 1 / 0.269)\",\n plumA6: \"color(display-p3 0.906 0.463 1 / 0.328)\",\n plumA7: \"color(display-p3 0.906 0.529 1 / 0.425)\",\n plumA8: \"color(display-p3 0.906 0.553 1 / 0.568)\",\n plumA9: \"color(display-p3 0.875 0.427 1 / 0.69)\",\n plumA10: \"color(display-p3 0.886 0.471 0.996 / 0.732)\",\n plumA11: \"color(display-p3 0.86 0.602 0.933)\",\n plumA12: \"color(display-p3 0.936 0.836 0.949)\",\n};\nconst purpleDark = {\n purple1: \"#18111b\",\n purple2: \"#1e1523\",\n purple3: \"#301c3b\",\n purple4: \"#3d224e\",\n purple5: \"#48295c\",\n purple6: \"#54346b\",\n purple7: \"#664282\",\n purple8: \"#8457aa\",\n purple9: \"#8e4ec6\",\n purple10: \"#9a5cd0\",\n purple11: \"#d19dff\",\n purple12: \"#ecd9fa\",\n};\nconst purpleDarkA = {\n purpleA1: \"#b412f90b\",\n purpleA2: \"#b744f714\",\n purpleA3: \"#c150ff2d\",\n purpleA4: \"#bb53fd42\",\n purpleA5: \"#be5cfd51\",\n purpleA6: \"#c16dfd61\",\n purpleA7: \"#c378fd7a\",\n purpleA8: \"#c47effa4\",\n purpleA9: \"#b661ffc2\",\n purpleA10: \"#bc6fffcd\",\n purpleA11: \"#d19dff\",\n purpleA12: \"#f1ddfffa\",\n};\nconst purpleDarkP3 = {\n purple1: \"color(display-p3 0.09 0.068 0.103)\",\n purple2: \"color(display-p3 0.113 0.082 0.134)\",\n purple3: \"color(display-p3 0.175 0.112 0.224)\",\n purple4: \"color(display-p3 0.224 0.137 0.297)\",\n purple5: \"color(display-p3 0.264 0.167 0.349)\",\n purple6: \"color(display-p3 0.311 0.208 0.406)\",\n purple7: \"color(display-p3 0.381 0.266 0.496)\",\n purple8: \"color(display-p3 0.49 0.349 0.649)\",\n purple9: \"color(display-p3 0.523 0.318 0.751)\",\n purple10: \"color(display-p3 0.57 0.373 0.791)\",\n purple11: \"color(display-p3 0.8 0.62 1)\",\n purple12: \"color(display-p3 0.913 0.854 0.971)\",\n};\nconst purpleDarkP3A = {\n purpleA1: \"color(display-p3 0.686 0.071 0.996 / 0.038)\",\n purpleA2: \"color(display-p3 0.722 0.286 0.996 / 0.072)\",\n purpleA3: \"color(display-p3 0.718 0.349 0.996 / 0.169)\",\n purpleA4: \"color(display-p3 0.702 0.353 1 / 0.248)\",\n purpleA5: \"color(display-p3 0.718 0.404 1 / 0.303)\",\n purpleA6: \"color(display-p3 0.733 0.455 1 / 0.366)\",\n purpleA7: \"color(display-p3 0.753 0.506 1 / 0.458)\",\n purpleA8: \"color(display-p3 0.749 0.522 1 / 0.622)\",\n purpleA9: \"color(display-p3 0.686 0.408 1 / 0.736)\",\n purpleA10: \"color(display-p3 0.71 0.459 1 / 0.778)\",\n purpleA11: \"color(display-p3 0.8 0.62 1)\",\n purpleA12: \"color(display-p3 0.913 0.854 0.971)\",\n};\nconst violetDark = {\n violet1: \"#14121f\",\n violet2: \"#1b1525\",\n violet3: \"#291f43\",\n violet4: \"#33255b\",\n violet5: \"#3c2e69\",\n violet6: \"#473876\",\n violet7: \"#56468b\",\n violet8: \"#6958ad\",\n violet9: \"#6e56cf\",\n violet10: \"#7d66d9\",\n violet11: \"#baa7ff\",\n violet12: \"#e2ddfe\",\n};\nconst violetDarkA = {\n violetA1: \"#4422ff0f\",\n violetA2: \"#853ff916\",\n violetA3: \"#8354fe36\",\n violetA4: \"#7d51fd50\",\n violetA5: \"#845ffd5f\",\n violetA6: \"#8f6cfd6d\",\n violetA7: \"#9879ff83\",\n violetA8: \"#977dfea8\",\n violetA9: \"#8668ffcc\",\n violetA10: \"#9176fed7\",\n violetA11: \"#baa7ff\",\n violetA12: \"#e3defffe\",\n};\nconst violetDarkP3 = {\n violet1: \"color(display-p3 0.077 0.071 0.118)\",\n violet2: \"color(display-p3 0.101 0.084 0.141)\",\n violet3: \"color(display-p3 0.154 0.123 0.256)\",\n violet4: \"color(display-p3 0.191 0.148 0.345)\",\n violet5: \"color(display-p3 0.226 0.182 0.396)\",\n violet6: \"color(display-p3 0.269 0.223 0.449)\",\n violet7: \"color(display-p3 0.326 0.277 0.53)\",\n violet8: \"color(display-p3 0.399 0.346 0.656)\",\n violet9: \"color(display-p3 0.417 0.341 0.784)\",\n violet10: \"color(display-p3 0.477 0.402 0.823)\",\n violet11: \"color(display-p3 0.72 0.65 1)\",\n violet12: \"color(display-p3 0.883 0.867 0.986)\",\n};\nconst violetDarkP3A = {\n violetA1: \"color(display-p3 0.282 0.141 0.996 / 0.055)\",\n violetA2: \"color(display-p3 0.51 0.263 1 / 0.08)\",\n violetA3: \"color(display-p3 0.494 0.337 0.996 / 0.202)\",\n violetA4: \"color(display-p3 0.49 0.345 1 / 0.299)\",\n violetA5: \"color(display-p3 0.525 0.392 1 / 0.353)\",\n violetA6: \"color(display-p3 0.569 0.455 1 / 0.408)\",\n violetA7: \"color(display-p3 0.588 0.494 1 / 0.496)\",\n violetA8: \"color(display-p3 0.596 0.51 1 / 0.631)\",\n violetA9: \"color(display-p3 0.522 0.424 1 / 0.769)\",\n violetA10: \"color(display-p3 0.576 0.482 1 / 0.811)\",\n violetA11: \"color(display-p3 0.72 0.65 1)\",\n violetA12: \"color(display-p3 0.883 0.867 0.986)\",\n};\nconst irisDark = {\n iris1: \"#13131e\",\n iris2: \"#171625\",\n iris3: \"#202248\",\n iris4: \"#262a65\",\n iris5: \"#303374\",\n iris6: \"#3d3e82\",\n iris7: \"#4a4a95\",\n iris8: \"#5958b1\",\n iris9: \"#5b5bd6\",\n iris10: \"#6e6ade\",\n iris11: \"#b1a9ff\",\n iris12: \"#e0dffe\",\n};\nconst irisDarkA = {\n irisA1: \"#3636fe0e\",\n irisA2: \"#564bf916\",\n irisA3: \"#525bff3b\",\n irisA4: \"#4d58ff5a\",\n irisA5: \"#5b62fd6b\",\n irisA6: \"#6d6ffd7a\",\n irisA7: \"#7777fe8e\",\n irisA8: \"#7b7afeac\",\n irisA9: \"#6a6afed4\",\n irisA10: \"#7d79ffdc\",\n irisA11: \"#b1a9ff\",\n irisA12: \"#e1e0fffe\",\n};\nconst irisDarkP3 = {\n iris1: \"color(display-p3 0.075 0.075 0.114)\",\n iris2: \"color(display-p3 0.089 0.086 0.14)\",\n iris3: \"color(display-p3 0.128 0.134 0.272)\",\n iris4: \"color(display-p3 0.153 0.165 0.382)\",\n iris5: \"color(display-p3 0.192 0.201 0.44)\",\n iris6: \"color(display-p3 0.239 0.241 0.491)\",\n iris7: \"color(display-p3 0.291 0.289 0.565)\",\n iris8: \"color(display-p3 0.35 0.345 0.673)\",\n iris9: \"color(display-p3 0.357 0.357 0.81)\",\n iris10: \"color(display-p3 0.428 0.416 0.843)\",\n iris11: \"color(display-p3 0.685 0.662 1)\",\n iris12: \"color(display-p3 0.878 0.875 0.986)\",\n};\nconst irisDarkP3A = {\n irisA1: \"color(display-p3 0.224 0.224 0.992 / 0.051)\",\n irisA2: \"color(display-p3 0.361 0.314 1 / 0.08)\",\n irisA3: \"color(display-p3 0.357 0.373 1 / 0.219)\",\n irisA4: \"color(display-p3 0.325 0.361 1 / 0.337)\",\n irisA5: \"color(display-p3 0.38 0.4 1 / 0.4)\",\n irisA6: \"color(display-p3 0.447 0.447 1 / 0.454)\",\n irisA7: \"color(display-p3 0.486 0.486 1 / 0.534)\",\n irisA8: \"color(display-p3 0.502 0.494 1 / 0.652)\",\n irisA9: \"color(display-p3 0.431 0.431 1 / 0.799)\",\n irisA10: \"color(display-p3 0.502 0.486 1 / 0.832)\",\n irisA11: \"color(display-p3 0.685 0.662 1)\",\n irisA12: \"color(display-p3 0.878 0.875 0.986)\",\n};\nconst indigoDark = {\n indigo1: \"#11131f\",\n indigo2: \"#141726\",\n indigo3: \"#182449\",\n indigo4: \"#1d2e62\",\n indigo5: \"#253974\",\n indigo6: \"#304384\",\n indigo7: \"#3a4f97\",\n indigo8: \"#435db1\",\n indigo9: \"#3e63dd\",\n indigo10: \"#5472e4\",\n indigo11: \"#9eb1ff\",\n indigo12: \"#d6e1ff\",\n};\nconst indigoDarkA = {\n indigoA1: \"#1133ff0f\",\n indigoA2: \"#3354fa17\",\n indigoA3: \"#2f62ff3c\",\n indigoA4: \"#3566ff57\",\n indigoA5: \"#4171fd6b\",\n indigoA6: \"#5178fd7c\",\n indigoA7: \"#5a7fff90\",\n indigoA8: \"#5b81feac\",\n indigoA9: \"#4671ffdb\",\n indigoA10: \"#5c7efee3\",\n indigoA11: \"#9eb1ff\",\n indigoA12: \"#d6e1ff\",\n};\nconst indigoDarkP3 = {\n indigo1: \"color(display-p3 0.068 0.074 0.118)\",\n indigo2: \"color(display-p3 0.081 0.089 0.144)\",\n indigo3: \"color(display-p3 0.105 0.141 0.275)\",\n indigo4: \"color(display-p3 0.129 0.18 0.369)\",\n indigo5: \"color(display-p3 0.163 0.22 0.439)\",\n indigo6: \"color(display-p3 0.203 0.262 0.5)\",\n indigo7: \"color(display-p3 0.245 0.309 0.575)\",\n indigo8: \"color(display-p3 0.285 0.362 0.674)\",\n indigo9: \"color(display-p3 0.276 0.384 0.837)\",\n indigo10: \"color(display-p3 0.354 0.445 0.866)\",\n indigo11: \"color(display-p3 0.63 0.69 1)\",\n indigo12: \"color(display-p3 0.848 0.881 0.99)\",\n};\nconst indigoDarkP3A = {\n indigoA1: \"color(display-p3 0.071 0.212 0.996 / 0.055)\",\n indigoA2: \"color(display-p3 0.251 0.345 0.988 / 0.085)\",\n indigoA3: \"color(display-p3 0.243 0.404 1 / 0.223)\",\n indigoA4: \"color(display-p3 0.263 0.42 1 / 0.324)\",\n indigoA5: \"color(display-p3 0.314 0.451 1 / 0.4)\",\n indigoA6: \"color(display-p3 0.361 0.49 1 / 0.467)\",\n indigoA7: \"color(display-p3 0.388 0.51 1 / 0.547)\",\n indigoA8: \"color(display-p3 0.404 0.518 1 / 0.652)\",\n indigoA9: \"color(display-p3 0.318 0.451 1 / 0.824)\",\n indigoA10: \"color(display-p3 0.404 0.506 1 / 0.858)\",\n indigoA11: \"color(display-p3 0.63 0.69 1)\",\n indigoA12: \"color(display-p3 0.848 0.881 0.99)\",\n};\nconst blueDark = {\n blue1: \"#0d1520\",\n blue2: \"#111927\",\n blue3: \"#0d2847\",\n blue4: \"#003362\",\n blue5: \"#004074\",\n blue6: \"#104d87\",\n blue7: \"#205d9e\",\n blue8: \"#2870bd\",\n blue9: \"#0090ff\",\n blue10: \"#3b9eff\",\n blue11: \"#70b8ff\",\n blue12: \"#c2e6ff\",\n};\nconst blueDarkA = {\n blueA1: \"#004df211\",\n blueA2: \"#1166fb18\",\n blueA3: \"#0077ff3a\",\n blueA4: \"#0075ff57\",\n blueA5: \"#0081fd6b\",\n blueA6: \"#0f89fd7f\",\n blueA7: \"#2a91fe98\",\n blueA8: \"#3094feb9\",\n blueA9: \"#0090ff\",\n blueA10: \"#3b9eff\",\n blueA11: \"#70b8ff\",\n blueA12: \"#c2e6ff\",\n};\nconst blueDarkP3 = {\n blue1: \"color(display-p3 0.057 0.081 0.122)\",\n blue2: \"color(display-p3 0.072 0.098 0.147)\",\n blue3: \"color(display-p3 0.078 0.154 0.27)\",\n blue4: \"color(display-p3 0.033 0.197 0.37)\",\n blue5: \"color(display-p3 0.08 0.245 0.441)\",\n blue6: \"color(display-p3 0.14 0.298 0.511)\",\n blue7: \"color(display-p3 0.195 0.361 0.6)\",\n blue8: \"color(display-p3 0.239 0.434 0.72)\",\n blue9: \"color(display-p3 0.247 0.556 0.969)\",\n blue10: \"color(display-p3 0.344 0.612 0.973)\",\n blue11: \"color(display-p3 0.49 0.72 1)\",\n blue12: \"color(display-p3 0.788 0.898 0.99)\",\n};\nconst blueDarkP3A = {\n blueA1: \"color(display-p3 0 0.333 1 / 0.059)\",\n blueA2: \"color(display-p3 0.114 0.435 0.988 / 0.085)\",\n blueA3: \"color(display-p3 0.122 0.463 1 / 0.219)\",\n blueA4: \"color(display-p3 0 0.467 1 / 0.324)\",\n blueA5: \"color(display-p3 0.098 0.51 1 / 0.4)\",\n blueA6: \"color(display-p3 0.224 0.557 1 / 0.475)\",\n blueA7: \"color(display-p3 0.294 0.584 1 / 0.572)\",\n blueA8: \"color(display-p3 0.314 0.592 1 / 0.702)\",\n blueA9: \"color(display-p3 0.251 0.573 0.996 / 0.967)\",\n blueA10: \"color(display-p3 0.357 0.631 1 / 0.971)\",\n blueA11: \"color(display-p3 0.49 0.72 1)\",\n blueA12: \"color(display-p3 0.788 0.898 0.99)\",\n};\nconst cyanDark = {\n cyan1: \"#0b161a\",\n cyan2: \"#101b20\",\n cyan3: \"#082c36\",\n cyan4: \"#003848\",\n cyan5: \"#004558\",\n cyan6: \"#045468\",\n cyan7: \"#12677e\",\n cyan8: \"#11809c\",\n cyan9: \"#00a2c7\",\n cyan10: \"#23afd0\",\n cyan11: \"#4ccce6\",\n cyan12: \"#b6ecf7\",\n};\nconst cyanDarkA = {\n cyanA1: \"#0091f70a\",\n cyanA2: \"#02a7f211\",\n cyanA3: \"#00befd28\",\n cyanA4: \"#00baff3b\",\n cyanA5: \"#00befd4d\",\n cyanA6: \"#00c7fd5e\",\n cyanA7: \"#14cdff75\",\n cyanA8: \"#11cfff95\",\n cyanA9: \"#00cfffc3\",\n cyanA10: \"#28d6ffcd\",\n cyanA11: \"#52e1fee5\",\n cyanA12: \"#bbf3fef7\",\n};\nconst cyanDarkP3 = {\n cyan1: \"color(display-p3 0.053 0.085 0.098)\",\n cyan2: \"color(display-p3 0.072 0.105 0.122)\",\n cyan3: \"color(display-p3 0.073 0.168 0.209)\",\n cyan4: \"color(display-p3 0.063 0.216 0.277)\",\n cyan5: \"color(display-p3 0.091 0.267 0.336)\",\n cyan6: \"color(display-p3 0.137 0.324 0.4)\",\n cyan7: \"color(display-p3 0.186 0.398 0.484)\",\n cyan8: \"color(display-p3 0.23 0.496 0.6)\",\n cyan9: \"color(display-p3 0.282 0.627 0.765)\",\n cyan10: \"color(display-p3 0.331 0.675 0.801)\",\n cyan11: \"color(display-p3 0.446 0.79 0.887)\",\n cyan12: \"color(display-p3 0.757 0.919 0.962)\",\n};\nconst cyanDarkP3A = {\n cyanA1: \"color(display-p3 0 0.647 0.992 / 0.034)\",\n cyanA2: \"color(display-p3 0.133 0.733 1 / 0.059)\",\n cyanA3: \"color(display-p3 0.122 0.741 0.996 / 0.152)\",\n cyanA4: \"color(display-p3 0.051 0.725 1 / 0.227)\",\n cyanA5: \"color(display-p3 0.149 0.757 1 / 0.29)\",\n cyanA6: \"color(display-p3 0.267 0.792 1 / 0.358)\",\n cyanA7: \"color(display-p3 0.333 0.808 1 / 0.446)\",\n cyanA8: \"color(display-p3 0.357 0.816 1 / 0.572)\",\n cyanA9: \"color(display-p3 0.357 0.82 1 / 0.748)\",\n cyanA10: \"color(display-p3 0.4 0.839 1 / 0.786)\",\n cyanA11: \"color(display-p3 0.446 0.79 0.887)\",\n cyanA12: \"color(display-p3 0.757 0.919 0.962)\",\n};\nconst tealDark = {\n teal1: \"#0d1514\",\n teal2: \"#111c1b\",\n teal3: \"#0d2d2a\",\n teal4: \"#023b37\",\n teal5: \"#084843\",\n teal6: \"#145750\",\n teal7: \"#1c6961\",\n teal8: \"#207e73\",\n teal9: \"#12a594\",\n teal10: \"#0eb39e\",\n teal11: \"#0bd8b6\",\n teal12: \"#adf0dd\",\n};\nconst tealDarkA = {\n tealA1: \"#00deab05\",\n tealA2: \"#12fbe60c\",\n tealA3: \"#00ffe61e\",\n tealA4: \"#00ffe92d\",\n tealA5: \"#00ffea3b\",\n tealA6: \"#1cffe84b\",\n tealA7: \"#2efde85f\",\n tealA8: \"#32ffe775\",\n tealA9: \"#13ffe49f\",\n tealA10: \"#0dffe0ae\",\n tealA11: \"#0afed5d6\",\n tealA12: \"#b8ffebef\",\n};\nconst tealDarkP3 = {\n teal1: \"color(display-p3 0.059 0.083 0.079)\",\n teal2: \"color(display-p3 0.075 0.11 0.107)\",\n teal3: \"color(display-p3 0.087 0.175 0.165)\",\n teal4: \"color(display-p3 0.087 0.227 0.214)\",\n teal5: \"color(display-p3 0.12 0.277 0.261)\",\n teal6: \"color(display-p3 0.162 0.335 0.314)\",\n teal7: \"color(display-p3 0.205 0.406 0.379)\",\n teal8: \"color(display-p3 0.245 0.489 0.453)\",\n teal9: \"color(display-p3 0.297 0.637 0.581)\",\n teal10: \"color(display-p3 0.319 0.69 0.62)\",\n teal11: \"color(display-p3 0.388 0.835 0.719)\",\n teal12: \"color(display-p3 0.734 0.934 0.87)\",\n};\nconst tealDarkP3A = {\n tealA1: \"color(display-p3 0 0.992 0.761 / 0.017)\",\n tealA2: \"color(display-p3 0.235 0.988 0.902 / 0.047)\",\n tealA3: \"color(display-p3 0.235 1 0.898 / 0.118)\",\n tealA4: \"color(display-p3 0.18 0.996 0.929 / 0.173)\",\n tealA5: \"color(display-p3 0.31 1 0.933 / 0.227)\",\n tealA6: \"color(display-p3 0.396 1 0.933 / 0.286)\",\n tealA7: \"color(display-p3 0.443 1 0.925 / 0.366)\",\n tealA8: \"color(display-p3 0.459 1 0.925 / 0.454)\",\n tealA9: \"color(display-p3 0.443 0.996 0.906 / 0.61)\",\n tealA10: \"color(display-p3 0.439 0.996 0.89 / 0.669)\",\n tealA11: \"color(display-p3 0.388 0.835 0.719)\",\n tealA12: \"color(display-p3 0.734 0.934 0.87)\",\n};\nconst jadeDark = {\n jade1: \"#0d1512\",\n jade2: \"#121c18\",\n jade3: \"#0f2e22\",\n jade4: \"#0b3b2c\",\n jade5: \"#114837\",\n jade6: \"#1b5745\",\n jade7: \"#246854\",\n jade8: \"#2a7e68\",\n jade9: \"#29a383\",\n jade10: \"#27b08b\",\n jade11: \"#1fd8a4\",\n jade12: \"#adf0d4\",\n};\nconst jadeDarkA = {\n jadeA1: \"#00de4505\",\n jadeA2: \"#27fba60c\",\n jadeA3: \"#02f99920\",\n jadeA4: \"#00ffaa2d\",\n jadeA5: \"#11ffb63b\",\n jadeA6: \"#34ffc24b\",\n jadeA7: \"#45fdc75e\",\n jadeA8: \"#48ffcf75\",\n jadeA9: \"#38feca9d\",\n jadeA10: \"#31fec7ab\",\n jadeA11: \"#21fec0d6\",\n jadeA12: \"#b8ffe1ef\",\n};\nconst jadeDarkP3 = {\n jade1: \"color(display-p3 0.059 0.083 0.071)\",\n jade2: \"color(display-p3 0.078 0.11 0.094)\",\n jade3: \"color(display-p3 0.091 0.176 0.138)\",\n jade4: \"color(display-p3 0.102 0.228 0.177)\",\n jade5: \"color(display-p3 0.133 0.279 0.221)\",\n jade6: \"color(display-p3 0.174 0.334 0.273)\",\n jade7: \"color(display-p3 0.219 0.402 0.335)\",\n jade8: \"color(display-p3 0.263 0.488 0.411)\",\n jade9: \"color(display-p3 0.319 0.63 0.521)\",\n jade10: \"color(display-p3 0.338 0.68 0.555)\",\n jade11: \"color(display-p3 0.4 0.835 0.656)\",\n jade12: \"color(display-p3 0.734 0.934 0.838)\",\n};\nconst jadeDarkP3A = {\n jadeA1: \"color(display-p3 0 0.992 0.298 / 0.017)\",\n jadeA2: \"color(display-p3 0.318 0.988 0.651 / 0.047)\",\n jadeA3: \"color(display-p3 0.267 1 0.667 / 0.118)\",\n jadeA4: \"color(display-p3 0.275 0.996 0.702 / 0.173)\",\n jadeA5: \"color(display-p3 0.361 1 0.741 / 0.227)\",\n jadeA6: \"color(display-p3 0.439 1 0.796 / 0.286)\",\n jadeA7: \"color(display-p3 0.49 1 0.804 / 0.362)\",\n jadeA8: \"color(display-p3 0.506 1 0.835 / 0.45)\",\n jadeA9: \"color(display-p3 0.478 0.996 0.816 / 0.606)\",\n jadeA10: \"color(display-p3 0.478 1 0.816 / 0.656)\",\n jadeA11: \"color(display-p3 0.4 0.835 0.656)\",\n jadeA12: \"color(display-p3 0.734 0.934 0.838)\",\n};\nconst greenDark = {\n green1: \"#0e1512\",\n green2: \"#121b17\",\n green3: \"#132d21\",\n green4: \"#113b29\",\n green5: \"#174933\",\n green6: \"#20573e\",\n green7: \"#28684a\",\n green8: \"#2f7c57\",\n green9: \"#30a46c\",\n green10: \"#33b074\",\n green11: \"#3dd68c\",\n green12: \"#b1f1cb\",\n};\nconst greenDarkA = {\n greenA1: \"#00de4505\",\n greenA2: \"#29f99d0b\",\n greenA3: \"#22ff991e\",\n greenA4: \"#11ff992d\",\n greenA5: \"#2bffa23c\",\n greenA6: \"#44ffaa4b\",\n greenA7: \"#50fdac5e\",\n greenA8: \"#54ffad73\",\n greenA9: \"#44ffa49e\",\n greenA10: \"#43fea4ab\",\n greenA11: \"#46fea5d4\",\n greenA12: \"#bbffd7f0\",\n};\nconst greenDarkP3 = {\n green1: \"color(display-p3 0.062 0.083 0.071)\",\n green2: \"color(display-p3 0.079 0.106 0.09)\",\n green3: \"color(display-p3 0.1 0.173 0.133)\",\n green4: \"color(display-p3 0.115 0.229 0.166)\",\n green5: \"color(display-p3 0.147 0.282 0.206)\",\n green6: \"color(display-p3 0.185 0.338 0.25)\",\n green7: \"color(display-p3 0.227 0.403 0.298)\",\n green8: \"color(display-p3 0.27 0.479 0.351)\",\n green9: \"color(display-p3 0.332 0.634 0.442)\",\n green10: \"color(display-p3 0.357 0.682 0.474)\",\n green11: \"color(display-p3 0.434 0.828 0.573)\",\n green12: \"color(display-p3 0.747 0.938 0.807)\",\n};\nconst greenDarkP3A = {\n greenA1: \"color(display-p3 0 0.992 0.298 / 0.017)\",\n greenA2: \"color(display-p3 0.341 0.98 0.616 / 0.043)\",\n greenA3: \"color(display-p3 0.376 0.996 0.655 / 0.114)\",\n greenA4: \"color(display-p3 0.341 0.996 0.635 / 0.173)\",\n greenA5: \"color(display-p3 0.408 1 0.678 / 0.232)\",\n greenA6: \"color(display-p3 0.475 1 0.706 / 0.29)\",\n greenA7: \"color(display-p3 0.514 1 0.706 / 0.362)\",\n greenA8: \"color(display-p3 0.529 1 0.718 / 0.442)\",\n greenA9: \"color(display-p3 0.502 0.996 0.682 / 0.61)\",\n greenA10: \"color(display-p3 0.506 1 0.682 / 0.66)\",\n greenA11: \"color(display-p3 0.434 0.828 0.573)\",\n greenA12: \"color(display-p3 0.747 0.938 0.807)\",\n};\nconst grassDark = {\n grass1: \"#0e1511\",\n grass2: \"#141a15\",\n grass3: \"#1b2a1e\",\n grass4: \"#1d3a24\",\n grass5: \"#25482d\",\n grass6: \"#2d5736\",\n grass7: \"#366740\",\n grass8: \"#3e7949\",\n grass9: \"#46a758\",\n grass10: \"#53b365\",\n grass11: \"#71d083\",\n grass12: \"#c2f0c2\",\n};\nconst grassDarkA = {\n grassA1: \"#00de1205\",\n grassA2: \"#5ef7780a\",\n grassA3: \"#70fe8c1b\",\n grassA4: \"#57ff802c\",\n grassA5: \"#68ff8b3b\",\n grassA6: \"#71ff8f4b\",\n grassA7: \"#77fd925d\",\n grassA8: \"#77fd9070\",\n grassA9: \"#65ff82a1\",\n grassA10: \"#72ff8dae\",\n grassA11: \"#89ff9fcd\",\n grassA12: \"#ceffceef\",\n};\nconst grassDarkP3 = {\n grass1: \"color(display-p3 0.062 0.083 0.067)\",\n grass2: \"color(display-p3 0.083 0.103 0.085)\",\n grass3: \"color(display-p3 0.118 0.163 0.122)\",\n grass4: \"color(display-p3 0.142 0.225 0.15)\",\n grass5: \"color(display-p3 0.178 0.279 0.186)\",\n grass6: \"color(display-p3 0.217 0.337 0.224)\",\n grass7: \"color(display-p3 0.258 0.4 0.264)\",\n grass8: \"color(display-p3 0.302 0.47 0.305)\",\n grass9: \"color(display-p3 0.38 0.647 0.378)\",\n grass10: \"color(display-p3 0.426 0.694 0.426)\",\n grass11: \"color(display-p3 0.535 0.807 0.542)\",\n grass12: \"color(display-p3 0.797 0.936 0.776)\",\n};\nconst grassDarkP3A = {\n grassA1: \"color(display-p3 0 0.992 0.071 / 0.017)\",\n grassA2: \"color(display-p3 0.482 0.996 0.584 / 0.038)\",\n grassA3: \"color(display-p3 0.549 0.992 0.588 / 0.106)\",\n grassA4: \"color(display-p3 0.51 0.996 0.557 / 0.169)\",\n grassA5: \"color(display-p3 0.553 1 0.588 / 0.227)\",\n grassA6: \"color(display-p3 0.584 1 0.608 / 0.29)\",\n grassA7: \"color(display-p3 0.604 1 0.616 / 0.358)\",\n grassA8: \"color(display-p3 0.608 1 0.62 / 0.433)\",\n grassA9: \"color(display-p3 0.573 1 0.569 / 0.622)\",\n grassA10: \"color(display-p3 0.6 0.996 0.6 / 0.673)\",\n grassA11: \"color(display-p3 0.535 0.807 0.542)\",\n grassA12: \"color(display-p3 0.797 0.936 0.776)\",\n};\nconst brownDark = {\n brown1: \"#12110f\",\n brown2: \"#1c1816\",\n brown3: \"#28211d\",\n brown4: \"#322922\",\n brown5: \"#3e3128\",\n brown6: \"#4d3c2f\",\n brown7: \"#614a39\",\n brown8: \"#7c5f46\",\n brown9: \"#ad7f58\",\n brown10: \"#b88c67\",\n brown11: \"#dbb594\",\n brown12: \"#f2e1ca\",\n};\nconst brownDarkA = {\n brownA1: \"#91110002\",\n brownA2: \"#fba67c0c\",\n brownA3: \"#fcb58c19\",\n brownA4: \"#fbbb8a24\",\n brownA5: \"#fcb88931\",\n brownA6: \"#fdba8741\",\n brownA7: \"#ffbb8856\",\n brownA8: \"#ffbe8773\",\n brownA9: \"#feb87da8\",\n brownA10: \"#ffc18cb3\",\n brownA11: \"#fed1aad9\",\n brownA12: \"#feecd4f2\",\n};\nconst brownDarkP3 = {\n brown1: \"color(display-p3 0.071 0.067 0.059)\",\n brown2: \"color(display-p3 0.107 0.095 0.087)\",\n brown3: \"color(display-p3 0.151 0.13 0.115)\",\n brown4: \"color(display-p3 0.191 0.161 0.138)\",\n brown5: \"color(display-p3 0.235 0.194 0.162)\",\n brown6: \"color(display-p3 0.291 0.237 0.192)\",\n brown7: \"color(display-p3 0.365 0.295 0.232)\",\n brown8: \"color(display-p3 0.469 0.377 0.287)\",\n brown9: \"color(display-p3 0.651 0.505 0.368)\",\n brown10: \"color(display-p3 0.697 0.557 0.423)\",\n brown11: \"color(display-p3 0.835 0.715 0.597)\",\n brown12: \"color(display-p3 0.938 0.885 0.802)\",\n};\nconst brownDarkP3A = {\n brownA1: \"color(display-p3 0.855 0.071 0 / 0.005)\",\n brownA2: \"color(display-p3 0.98 0.706 0.525 / 0.043)\",\n brownA3: \"color(display-p3 0.996 0.745 0.576 / 0.093)\",\n brownA4: \"color(display-p3 1 0.765 0.592 / 0.135)\",\n brownA5: \"color(display-p3 1 0.761 0.588 / 0.181)\",\n brownA6: \"color(display-p3 1 0.773 0.592 / 0.24)\",\n brownA7: \"color(display-p3 0.996 0.776 0.58 / 0.32)\",\n brownA8: \"color(display-p3 1 0.78 0.573 / 0.433)\",\n brownA9: \"color(display-p3 1 0.769 0.549 / 0.627)\",\n brownA10: \"color(display-p3 1 0.792 0.596 / 0.677)\",\n brownA11: \"color(display-p3 0.835 0.715 0.597)\",\n brownA12: \"color(display-p3 0.938 0.885 0.802)\",\n};\nconst bronzeDark = {\n bronze1: \"#141110\",\n bronze2: \"#1c1917\",\n bronze3: \"#262220\",\n bronze4: \"#302a27\",\n bronze5: \"#3b3330\",\n bronze6: \"#493e3a\",\n bronze7: \"#5a4c47\",\n bronze8: \"#6f5f58\",\n bronze9: \"#a18072\",\n bronze10: \"#ae8c7e\",\n bronze11: \"#d4b3a5\",\n bronze12: \"#ede0d9\",\n};\nconst bronzeDarkA = {\n bronzeA1: \"#d1110004\",\n bronzeA2: \"#fbbc910c\",\n bronzeA3: \"#faceb817\",\n bronzeA4: \"#facdb622\",\n bronzeA5: \"#ffd2c12d\",\n bronzeA6: \"#ffd1c03c\",\n bronzeA7: \"#fdd0c04f\",\n bronzeA8: \"#ffd6c565\",\n bronzeA9: \"#fec7b09b\",\n bronzeA10: \"#fecab5a9\",\n bronzeA11: \"#ffd7c6d1\",\n bronzeA12: \"#fff1e9ec\",\n};\nconst bronzeDarkP3 = {\n bronze1: \"color(display-p3 0.076 0.067 0.063)\",\n bronze2: \"color(display-p3 0.106 0.097 0.093)\",\n bronze3: \"color(display-p3 0.147 0.132 0.125)\",\n bronze4: \"color(display-p3 0.185 0.166 0.156)\",\n bronze5: \"color(display-p3 0.227 0.202 0.19)\",\n bronze6: \"color(display-p3 0.278 0.246 0.23)\",\n bronze7: \"color(display-p3 0.343 0.302 0.281)\",\n bronze8: \"color(display-p3 0.426 0.374 0.347)\",\n bronze9: \"color(display-p3 0.611 0.507 0.455)\",\n bronze10: \"color(display-p3 0.66 0.556 0.504)\",\n bronze11: \"color(display-p3 0.81 0.707 0.655)\",\n bronze12: \"color(display-p3 0.921 0.88 0.854)\",\n};\nconst bronzeDarkP3A = {\n bronzeA1: \"color(display-p3 0.941 0.067 0 / 0.009)\",\n bronzeA2: \"color(display-p3 0.98 0.8 0.706 / 0.043)\",\n bronzeA3: \"color(display-p3 0.988 0.851 0.761 / 0.085)\",\n bronzeA4: \"color(display-p3 0.996 0.839 0.78 / 0.127)\",\n bronzeA5: \"color(display-p3 0.996 0.863 0.773 / 0.173)\",\n bronzeA6: \"color(display-p3 1 0.863 0.796 / 0.227)\",\n bronzeA7: \"color(display-p3 1 0.867 0.8 / 0.295)\",\n bronzeA8: \"color(display-p3 1 0.859 0.788 / 0.387)\",\n bronzeA9: \"color(display-p3 1 0.82 0.733 / 0.585)\",\n bronzeA10: \"color(display-p3 1 0.839 0.761 / 0.635)\",\n bronzeA11: \"color(display-p3 0.81 0.707 0.655)\",\n bronzeA12: \"color(display-p3 0.921 0.88 0.854)\",\n};\nconst goldDark = {\n gold1: \"#121211\",\n gold2: \"#1b1a17\",\n gold3: \"#24231f\",\n gold4: \"#2d2b26\",\n gold5: \"#38352e\",\n gold6: \"#444039\",\n gold7: \"#544f46\",\n gold8: \"#696256\",\n gold9: \"#978365\",\n gold10: \"#a39073\",\n gold11: \"#cbb99f\",\n gold12: \"#e8e2d9\",\n};\nconst goldDarkA = {\n goldA1: \"#91911102\",\n goldA2: \"#f9e29d0b\",\n goldA3: \"#f8ecbb15\",\n goldA4: \"#ffeec41e\",\n goldA5: \"#feecc22a\",\n goldA6: \"#feebcb37\",\n goldA7: \"#ffedcd48\",\n goldA8: \"#fdeaca5f\",\n goldA9: \"#ffdba690\",\n goldA10: \"#fedfb09d\",\n goldA11: \"#fee7c6c8\",\n goldA12: \"#fef7ede7\",\n};\nconst goldDarkP3 = {\n gold1: \"color(display-p3 0.071 0.071 0.067)\",\n gold2: \"color(display-p3 0.104 0.101 0.09)\",\n gold3: \"color(display-p3 0.141 0.136 0.122)\",\n gold4: \"color(display-p3 0.177 0.17 0.152)\",\n gold5: \"color(display-p3 0.217 0.207 0.185)\",\n gold6: \"color(display-p3 0.265 0.252 0.225)\",\n gold7: \"color(display-p3 0.327 0.31 0.277)\",\n gold8: \"color(display-p3 0.407 0.384 0.342)\",\n gold9: \"color(display-p3 0.579 0.517 0.41)\",\n gold10: \"color(display-p3 0.628 0.566 0.463)\",\n gold11: \"color(display-p3 0.784 0.728 0.635)\",\n gold12: \"color(display-p3 0.906 0.887 0.855)\",\n};\nconst goldDarkP3A = {\n goldA1: \"color(display-p3 0.855 0.855 0.071 / 0.005)\",\n goldA2: \"color(display-p3 0.98 0.89 0.616 / 0.043)\",\n goldA3: \"color(display-p3 1 0.949 0.753 / 0.08)\",\n goldA4: \"color(display-p3 1 0.933 0.8 / 0.118)\",\n goldA5: \"color(display-p3 1 0.949 0.804 / 0.16)\",\n goldA6: \"color(display-p3 1 0.925 0.8 / 0.215)\",\n goldA7: \"color(display-p3 1 0.945 0.831 / 0.278)\",\n goldA8: \"color(display-p3 1 0.937 0.82 / 0.366)\",\n goldA9: \"color(display-p3 0.996 0.882 0.69 / 0.551)\",\n goldA10: \"color(display-p3 1 0.894 0.725 / 0.601)\",\n goldA11: \"color(display-p3 0.784 0.728 0.635)\",\n goldA12: \"color(display-p3 0.906 0.887 0.855)\",\n};\nconst skyDark = {\n sky1: \"#0d141f\",\n sky2: \"#111a27\",\n sky3: \"#112840\",\n sky4: \"#113555\",\n sky5: \"#154467\",\n sky6: \"#1b537b\",\n sky7: \"#1f6692\",\n sky8: \"#197cae\",\n sky9: \"#7ce2fe\",\n sky10: \"#a8eeff\",\n sky11: \"#75c7f0\",\n sky12: \"#c2f3ff\",\n};\nconst skyDarkA = {\n skyA1: \"#0044ff0f\",\n skyA2: \"#1171fb18\",\n skyA3: \"#1184fc33\",\n skyA4: \"#128fff49\",\n skyA5: \"#1c9dfd5d\",\n skyA6: \"#28a5ff72\",\n skyA7: \"#2badfe8b\",\n skyA8: \"#1db2fea9\",\n skyA9: \"#7ce3fffe\",\n skyA10: \"#a8eeff\",\n skyA11: \"#7cd3ffef\",\n skyA12: \"#c2f3ff\",\n};\nconst skyDarkP3 = {\n sky1: \"color(display-p3 0.056 0.078 0.116)\",\n sky2: \"color(display-p3 0.075 0.101 0.149)\",\n sky3: \"color(display-p3 0.089 0.154 0.244)\",\n sky4: \"color(display-p3 0.106 0.207 0.323)\",\n sky5: \"color(display-p3 0.135 0.261 0.394)\",\n sky6: \"color(display-p3 0.17 0.322 0.469)\",\n sky7: \"color(display-p3 0.205 0.394 0.557)\",\n sky8: \"color(display-p3 0.232 0.48 0.665)\",\n sky9: \"color(display-p3 0.585 0.877 0.983)\",\n sky10: \"color(display-p3 0.718 0.925 0.991)\",\n sky11: \"color(display-p3 0.536 0.772 0.924)\",\n sky12: \"color(display-p3 0.799 0.947 0.993)\",\n};\nconst skyDarkP3A = {\n skyA1: \"color(display-p3 0 0.282 0.996 / 0.055)\",\n skyA2: \"color(display-p3 0.157 0.467 0.992 / 0.089)\",\n skyA3: \"color(display-p3 0.192 0.522 0.996 / 0.19)\",\n skyA4: \"color(display-p3 0.212 0.584 1 / 0.274)\",\n skyA5: \"color(display-p3 0.259 0.631 1 / 0.349)\",\n skyA6: \"color(display-p3 0.302 0.655 1 / 0.433)\",\n skyA7: \"color(display-p3 0.329 0.686 1 / 0.526)\",\n skyA8: \"color(display-p3 0.325 0.71 1 / 0.643)\",\n skyA9: \"color(display-p3 0.592 0.894 1 / 0.984)\",\n skyA10: \"color(display-p3 0.722 0.933 1 / 0.992)\",\n skyA11: \"color(display-p3 0.536 0.772 0.924)\",\n skyA12: \"color(display-p3 0.799 0.947 0.993)\",\n};\nconst mintDark = {\n mint1: \"#0e1515\",\n mint2: \"#0f1b1b\",\n mint3: \"#092c2b\",\n mint4: \"#003a38\",\n mint5: \"#004744\",\n mint6: \"#105650\",\n mint7: \"#1e685f\",\n mint8: \"#277f70\",\n mint9: \"#86ead4\",\n mint10: \"#a8f5e5\",\n mint11: \"#58d5ba\",\n mint12: \"#c4f5e1\",\n};\nconst mintDarkA = {\n mintA1: \"#00dede05\",\n mintA2: \"#00f9f90b\",\n mintA3: \"#00fff61d\",\n mintA4: \"#00fff42c\",\n mintA5: \"#00fff23a\",\n mintA6: \"#0effeb4a\",\n mintA7: \"#34fde55e\",\n mintA8: \"#41ffdf76\",\n mintA9: \"#92ffe7e9\",\n mintA10: \"#aefeedf5\",\n mintA11: \"#67ffded2\",\n mintA12: \"#cbfee9f5\",\n};\nconst mintDarkP3 = {\n mint1: \"color(display-p3 0.059 0.082 0.081)\",\n mint2: \"color(display-p3 0.068 0.104 0.105)\",\n mint3: \"color(display-p3 0.077 0.17 0.168)\",\n mint4: \"color(display-p3 0.068 0.224 0.22)\",\n mint5: \"color(display-p3 0.104 0.275 0.264)\",\n mint6: \"color(display-p3 0.154 0.332 0.313)\",\n mint7: \"color(display-p3 0.207 0.403 0.373)\",\n mint8: \"color(display-p3 0.258 0.49 0.441)\",\n mint9: \"color(display-p3 0.62 0.908 0.834)\",\n mint10: \"color(display-p3 0.725 0.954 0.898)\",\n mint11: \"color(display-p3 0.482 0.825 0.733)\",\n mint12: \"color(display-p3 0.807 0.955 0.887)\",\n};\nconst mintDarkP3A = {\n mintA1: \"color(display-p3 0 0.992 0.992 / 0.017)\",\n mintA2: \"color(display-p3 0.071 0.98 0.98 / 0.043)\",\n mintA3: \"color(display-p3 0.176 0.996 0.996 / 0.11)\",\n mintA4: \"color(display-p3 0.071 0.996 0.973 / 0.169)\",\n mintA5: \"color(display-p3 0.243 1 0.949 / 0.223)\",\n mintA6: \"color(display-p3 0.369 1 0.933 / 0.286)\",\n mintA7: \"color(display-p3 0.459 1 0.914 / 0.362)\",\n mintA8: \"color(display-p3 0.49 1 0.89 / 0.454)\",\n mintA9: \"color(display-p3 0.678 0.996 0.914 / 0.904)\",\n mintA10: \"color(display-p3 0.761 1 0.941 / 0.95)\",\n mintA11: \"color(display-p3 0.482 0.825 0.733)\",\n mintA12: \"color(display-p3 0.807 0.955 0.887)\",\n};\nconst limeDark = {\n lime1: \"#11130c\",\n lime2: \"#151a10\",\n lime3: \"#1f2917\",\n lime4: \"#29371d\",\n lime5: \"#334423\",\n lime6: \"#3d522a\",\n lime7: \"#496231\",\n lime8: \"#577538\",\n lime9: \"#bdee63\",\n lime10: \"#d4ff70\",\n lime11: \"#bde56c\",\n lime12: \"#e3f7ba\",\n};\nconst limeDarkA = {\n limeA1: \"#11bb0003\",\n limeA2: \"#78f7000a\",\n limeA3: \"#9bfd4c1a\",\n limeA4: \"#a7fe5c29\",\n limeA5: \"#affe6537\",\n limeA6: \"#b2fe6d46\",\n limeA7: \"#b6ff6f57\",\n limeA8: \"#b6fd6d6c\",\n limeA9: \"#caff69ed\",\n limeA10: \"#d4ff70\",\n limeA11: \"#d1fe77e4\",\n limeA12: \"#e9febff7\",\n};\nconst limeDarkP3 = {\n lime1: \"color(display-p3 0.067 0.073 0.048)\",\n lime2: \"color(display-p3 0.086 0.1 0.067)\",\n lime3: \"color(display-p3 0.13 0.16 0.099)\",\n lime4: \"color(display-p3 0.172 0.214 0.126)\",\n lime5: \"color(display-p3 0.213 0.266 0.153)\",\n lime6: \"color(display-p3 0.257 0.321 0.182)\",\n lime7: \"color(display-p3 0.307 0.383 0.215)\",\n lime8: \"color(display-p3 0.365 0.456 0.25)\",\n lime9: \"color(display-p3 0.78 0.928 0.466)\",\n lime10: \"color(display-p3 0.865 0.995 0.519)\",\n lime11: \"color(display-p3 0.771 0.893 0.485)\",\n lime12: \"color(display-p3 0.905 0.966 0.753)\",\n};\nconst limeDarkP3A = {\n limeA1: \"color(display-p3 0.067 0.941 0 / 0.009)\",\n limeA2: \"color(display-p3 0.584 0.996 0.071 / 0.038)\",\n limeA3: \"color(display-p3 0.69 1 0.38 / 0.101)\",\n limeA4: \"color(display-p3 0.729 1 0.435 / 0.16)\",\n limeA5: \"color(display-p3 0.745 1 0.471 / 0.215)\",\n limeA6: \"color(display-p3 0.769 1 0.482 / 0.274)\",\n limeA7: \"color(display-p3 0.769 1 0.506 / 0.341)\",\n limeA8: \"color(display-p3 0.784 1 0.51 / 0.416)\",\n limeA9: \"color(display-p3 0.839 1 0.502 / 0.925)\",\n limeA10: \"color(display-p3 0.871 1 0.522 / 0.996)\",\n limeA11: \"color(display-p3 0.771 0.893 0.485)\",\n limeA12: \"color(display-p3 0.905 0.966 0.753)\",\n};\nconst yellowDark = {\n yellow1: \"#14120b\",\n yellow2: \"#1b180f\",\n yellow3: \"#2d2305\",\n yellow4: \"#362b00\",\n yellow5: \"#433500\",\n yellow6: \"#524202\",\n yellow7: \"#665417\",\n yellow8: \"#836a21\",\n yellow9: \"#ffe629\",\n yellow10: \"#ffff57\",\n yellow11: \"#f5e147\",\n yellow12: \"#f6eeb4\",\n};\nconst yellowDarkA = {\n yellowA1: \"#d1510004\",\n yellowA2: \"#f9b4000b\",\n yellowA3: \"#ffaa001e\",\n yellowA4: \"#fdb70028\",\n yellowA5: \"#febb0036\",\n yellowA6: \"#fec40046\",\n yellowA7: \"#fdcb225c\",\n yellowA8: \"#fdca327b\",\n yellowA9: \"#ffe629\",\n yellowA10: \"#ffff57\",\n yellowA11: \"#fee949f5\",\n yellowA12: \"#fef6baf6\",\n};\nconst yellowDarkP3 = {\n yellow1: \"color(display-p3 0.078 0.069 0.047)\",\n yellow2: \"color(display-p3 0.103 0.094 0.063)\",\n yellow3: \"color(display-p3 0.168 0.137 0.039)\",\n yellow4: \"color(display-p3 0.209 0.169 0)\",\n yellow5: \"color(display-p3 0.255 0.209 0)\",\n yellow6: \"color(display-p3 0.31 0.261 0.07)\",\n yellow7: \"color(display-p3 0.389 0.331 0.135)\",\n yellow8: \"color(display-p3 0.497 0.42 0.182)\",\n yellow9: \"color(display-p3 1 0.92 0.22)\",\n yellow10: \"color(display-p3 1 1 0.456)\",\n yellow11: \"color(display-p3 0.948 0.885 0.392)\",\n yellow12: \"color(display-p3 0.959 0.934 0.731)\",\n};\nconst yellowDarkP3A = {\n yellowA1: \"color(display-p3 0.973 0.369 0 / 0.013)\",\n yellowA2: \"color(display-p3 0.996 0.792 0 / 0.038)\",\n yellowA3: \"color(display-p3 0.996 0.71 0 / 0.11)\",\n yellowA4: \"color(display-p3 0.996 0.741 0 / 0.152)\",\n yellowA5: \"color(display-p3 0.996 0.765 0 / 0.202)\",\n yellowA6: \"color(display-p3 0.996 0.816 0.082 / 0.261)\",\n yellowA7: \"color(display-p3 1 0.831 0.263 / 0.345)\",\n yellowA8: \"color(display-p3 1 0.831 0.314 / 0.463)\",\n yellowA9: \"color(display-p3 1 0.922 0.22)\",\n yellowA10: \"color(display-p3 1 1 0.455)\",\n yellowA11: \"color(display-p3 0.948 0.885 0.392)\",\n yellowA12: \"color(display-p3 0.959 0.934 0.731)\",\n};\nconst amberDark = {\n amber1: \"#16120c\",\n amber2: \"#1d180f\",\n amber3: \"#302008\",\n amber4: \"#3f2700\",\n amber5: \"#4d3000\",\n amber6: \"#5c3d05\",\n amber7: \"#714f19\",\n amber8: \"#8f6424\",\n amber9: \"#ffc53d\",\n amber10: \"#ffd60a\",\n amber11: \"#ffca16\",\n amber12: \"#ffe7b3\",\n};\nconst amberDarkA = {\n amberA1: \"#e63c0006\",\n amberA2: \"#fd9b000d\",\n amberA3: \"#fa820022\",\n amberA4: \"#fc820032\",\n amberA5: \"#fd8b0041\",\n amberA6: \"#fd9b0051\",\n amberA7: \"#ffab2567\",\n amberA8: \"#ffae3587\",\n amberA9: \"#ffc53d\",\n amberA10: \"#ffd60a\",\n amberA11: \"#ffca16\",\n amberA12: \"#ffe7b3\",\n};\nconst amberDarkP3 = {\n amber1: \"color(display-p3 0.082 0.07 0.05)\",\n amber2: \"color(display-p3 0.111 0.094 0.064)\",\n amber3: \"color(display-p3 0.178 0.128 0.049)\",\n amber4: \"color(display-p3 0.239 0.156 0)\",\n amber5: \"color(display-p3 0.29 0.193 0)\",\n amber6: \"color(display-p3 0.344 0.245 0.076)\",\n amber7: \"color(display-p3 0.422 0.314 0.141)\",\n amber8: \"color(display-p3 0.535 0.399 0.189)\",\n amber9: \"color(display-p3 1 0.77 0.26)\",\n amber10: \"color(display-p3 1 0.87 0.15)\",\n amber11: \"color(display-p3 1 0.8 0.29)\",\n amber12: \"color(display-p3 0.984 0.909 0.726)\",\n};\nconst amberDarkP3A = {\n amberA1: \"color(display-p3 0.992 0.298 0 / 0.017)\",\n amberA2: \"color(display-p3 0.988 0.651 0 / 0.047)\",\n amberA3: \"color(display-p3 1 0.6 0 / 0.118)\",\n amberA4: \"color(display-p3 1 0.557 0 / 0.185)\",\n amberA5: \"color(display-p3 1 0.592 0 / 0.24)\",\n amberA6: \"color(display-p3 1 0.659 0.094 / 0.299)\",\n amberA7: \"color(display-p3 1 0.714 0.263 / 0.383)\",\n amberA8: \"color(display-p3 0.996 0.729 0.306 / 0.5)\",\n amberA9: \"color(display-p3 1 0.769 0.259)\",\n amberA10: \"color(display-p3 1 0.871 0.149)\",\n amberA11: \"color(display-p3 1 0.8 0.29)\",\n amberA12: \"color(display-p3 0.984 0.909 0.726)\",\n};\nconst orangeDark = {\n orange1: \"#17120e\",\n orange2: \"#1e160f\",\n orange3: \"#331e0b\",\n orange4: \"#462100\",\n orange5: \"#562800\",\n orange6: \"#66350c\",\n orange7: \"#7e451d\",\n orange8: \"#a35829\",\n orange9: \"#f76b15\",\n orange10: \"#ff801f\",\n orange11: \"#ffa057\",\n orange12: \"#ffe0c2\",\n};\nconst orangeDarkA = {\n orangeA1: \"#ec360007\",\n orangeA2: \"#fe6d000e\",\n orangeA3: \"#fb6a0025\",\n orangeA4: \"#ff590039\",\n orangeA5: \"#ff61004a\",\n orangeA6: \"#fd75045c\",\n orangeA7: \"#ff832c75\",\n orangeA8: \"#fe84389d\",\n orangeA9: \"#fe6d15f7\",\n orangeA10: \"#ff801f\",\n orangeA11: \"#ffa057\",\n orangeA12: \"#ffe0c2\",\n};\nconst orangeDarkP3 = {\n orange1: \"color(display-p3 0.088 0.07 0.057)\",\n orange2: \"color(display-p3 0.113 0.089 0.061)\",\n orange3: \"color(display-p3 0.189 0.12 0.056)\",\n orange4: \"color(display-p3 0.262 0.132 0)\",\n orange5: \"color(display-p3 0.315 0.168 0.016)\",\n orange6: \"color(display-p3 0.376 0.219 0.088)\",\n orange7: \"color(display-p3 0.465 0.283 0.147)\",\n orange8: \"color(display-p3 0.601 0.359 0.201)\",\n orange9: \"color(display-p3 0.9 0.45 0.2)\",\n orange10: \"color(display-p3 0.98 0.51 0.23)\",\n orange11: \"color(display-p3 1 0.63 0.38)\",\n orange12: \"color(display-p3 0.98 0.883 0.775)\",\n};\nconst orangeDarkP3A = {\n orangeA1: \"color(display-p3 0.961 0.247 0 / 0.022)\",\n orangeA2: \"color(display-p3 0.992 0.529 0 / 0.051)\",\n orangeA3: \"color(display-p3 0.996 0.486 0 / 0.131)\",\n orangeA4: \"color(display-p3 0.996 0.384 0 / 0.211)\",\n orangeA5: \"color(display-p3 1 0.455 0 / 0.265)\",\n orangeA6: \"color(display-p3 1 0.529 0.129 / 0.332)\",\n orangeA7: \"color(display-p3 1 0.569 0.251 / 0.429)\",\n orangeA8: \"color(display-p3 1 0.584 0.302 / 0.572)\",\n orangeA9: \"color(display-p3 1 0.494 0.216 / 0.895)\",\n orangeA10: \"color(display-p3 1 0.522 0.235 / 0.979)\",\n orangeA11: \"color(display-p3 1 0.63 0.38)\",\n orangeA12: \"color(display-p3 0.98 0.883 0.775)\",\n};\n\nconst gray = {\n gray1: \"#fcfcfc\",\n gray2: \"#f9f9f9\",\n gray3: \"#f0f0f0\",\n gray4: \"#e8e8e8\",\n gray5: \"#e0e0e0\",\n gray6: \"#d9d9d9\",\n gray7: \"#cecece\",\n gray8: \"#bbbbbb\",\n gray9: \"#8d8d8d\",\n gray10: \"#838383\",\n gray11: \"#646464\",\n gray12: \"#202020\",\n};\nconst grayA = {\n grayA1: \"#00000003\",\n grayA2: \"#00000006\",\n grayA3: \"#0000000f\",\n grayA4: \"#00000017\",\n grayA5: \"#0000001f\",\n grayA6: \"#00000026\",\n grayA7: \"#00000031\",\n grayA8: \"#00000044\",\n grayA9: \"#00000072\",\n grayA10: \"#0000007c\",\n grayA11: \"#0000009b\",\n grayA12: \"#000000df\",\n};\nconst grayP3 = {\n gray1: \"color(display-p3 0.988 0.988 0.988)\",\n gray2: \"color(display-p3 0.975 0.975 0.975)\",\n gray3: \"color(display-p3 0.939 0.939 0.939)\",\n gray4: \"color(display-p3 0.908 0.908 0.908)\",\n gray5: \"color(display-p3 0.88 0.88 0.88)\",\n gray6: \"color(display-p3 0.849 0.849 0.849)\",\n gray7: \"color(display-p3 0.807 0.807 0.807)\",\n gray8: \"color(display-p3 0.732 0.732 0.732)\",\n gray9: \"color(display-p3 0.553 0.553 0.553)\",\n gray10: \"color(display-p3 0.512 0.512 0.512)\",\n gray11: \"color(display-p3 0.392 0.392 0.392)\",\n gray12: \"color(display-p3 0.125 0.125 0.125)\",\n};\nconst grayP3A = {\n grayA1: \"color(display-p3 0 0 0 / 0.012)\",\n grayA2: \"color(display-p3 0 0 0 / 0.024)\",\n grayA3: \"color(display-p3 0 0 0 / 0.063)\",\n grayA4: \"color(display-p3 0 0 0 / 0.09)\",\n grayA5: \"color(display-p3 0 0 0 / 0.122)\",\n grayA6: \"color(display-p3 0 0 0 / 0.153)\",\n grayA7: \"color(display-p3 0 0 0 / 0.192)\",\n grayA8: \"color(display-p3 0 0 0 / 0.267)\",\n grayA9: \"color(display-p3 0 0 0 / 0.447)\",\n grayA10: \"color(display-p3 0 0 0 / 0.486)\",\n grayA11: \"color(display-p3 0 0 0 / 0.608)\",\n grayA12: \"color(display-p3 0 0 0 / 0.875)\",\n};\nconst mauve = {\n mauve1: \"#fdfcfd\",\n mauve2: \"#faf9fb\",\n mauve3: \"#f2eff3\",\n mauve4: \"#eae7ec\",\n mauve5: \"#e3dfe6\",\n mauve6: \"#dbd8e0\",\n mauve7: \"#d0cdd7\",\n mauve8: \"#bcbac7\",\n mauve9: \"#8e8c99\",\n mauve10: \"#84828e\",\n mauve11: \"#65636d\",\n mauve12: \"#211f26\",\n};\nconst mauveA = {\n mauveA1: \"#55005503\",\n mauveA2: \"#2b005506\",\n mauveA3: \"#30004010\",\n mauveA4: \"#20003618\",\n mauveA5: \"#20003820\",\n mauveA6: \"#14003527\",\n mauveA7: \"#10003332\",\n mauveA8: \"#08003145\",\n mauveA9: \"#05001d73\",\n mauveA10: \"#0500197d\",\n mauveA11: \"#0400119c\",\n mauveA12: \"#020008e0\",\n};\nconst mauveP3 = {\n mauve1: \"color(display-p3 0.991 0.988 0.992)\",\n mauve2: \"color(display-p3 0.98 0.976 0.984)\",\n mauve3: \"color(display-p3 0.946 0.938 0.952)\",\n mauve4: \"color(display-p3 0.915 0.906 0.925)\",\n mauve5: \"color(display-p3 0.886 0.876 0.901)\",\n mauve6: \"color(display-p3 0.856 0.846 0.875)\",\n mauve7: \"color(display-p3 0.814 0.804 0.84)\",\n mauve8: \"color(display-p3 0.735 0.728 0.777)\",\n mauve9: \"color(display-p3 0.555 0.549 0.596)\",\n mauve10: \"color(display-p3 0.514 0.508 0.552)\",\n mauve11: \"color(display-p3 0.395 0.388 0.424)\",\n mauve12: \"color(display-p3 0.128 0.122 0.147)\",\n};\nconst mauveP3A = {\n mauveA1: \"color(display-p3 0.349 0.024 0.349 / 0.012)\",\n mauveA2: \"color(display-p3 0.184 0.024 0.349 / 0.024)\",\n mauveA3: \"color(display-p3 0.129 0.008 0.255 / 0.063)\",\n mauveA4: \"color(display-p3 0.094 0.012 0.216 / 0.095)\",\n mauveA5: \"color(display-p3 0.098 0.008 0.224 / 0.126)\",\n mauveA6: \"color(display-p3 0.055 0.004 0.18 / 0.153)\",\n mauveA7: \"color(display-p3 0.067 0.008 0.184 / 0.197)\",\n mauveA8: \"color(display-p3 0.02 0.004 0.176 / 0.271)\",\n mauveA9: \"color(display-p3 0.02 0.004 0.106 / 0.451)\",\n mauveA10: \"color(display-p3 0.012 0.004 0.09 / 0.491)\",\n mauveA11: \"color(display-p3 0.016 0 0.059 / 0.612)\",\n mauveA12: \"color(display-p3 0.008 0 0.027 / 0.879)\",\n};\nconst slate = {\n slate1: \"#fcfcfd\",\n slate2: \"#f9f9fb\",\n slate3: \"#f0f0f3\",\n slate4: \"#e8e8ec\",\n slate5: \"#e0e1e6\",\n slate6: \"#d9d9e0\",\n slate7: \"#cdced6\",\n slate8: \"#b9bbc6\",\n slate9: \"#8b8d98\",\n slate10: \"#80838d\",\n slate11: \"#60646c\",\n slate12: \"#1c2024\",\n};\nconst slateA = {\n slateA1: \"#00005503\",\n slateA2: \"#00005506\",\n slateA3: \"#0000330f\",\n slateA4: \"#00002d17\",\n slateA5: \"#0009321f\",\n slateA6: \"#00002f26\",\n slateA7: \"#00062e32\",\n slateA8: \"#00083046\",\n slateA9: \"#00051d74\",\n slateA10: \"#00071b7f\",\n slateA11: \"#0007149f\",\n slateA12: \"#000509e3\",\n};\nconst slateP3 = {\n slate1: \"color(display-p3 0.988 0.988 0.992)\",\n slate2: \"color(display-p3 0.976 0.976 0.984)\",\n slate3: \"color(display-p3 0.94 0.941 0.953)\",\n slate4: \"color(display-p3 0.908 0.909 0.925)\",\n slate5: \"color(display-p3 0.88 0.881 0.901)\",\n slate6: \"color(display-p3 0.85 0.852 0.876)\",\n slate7: \"color(display-p3 0.805 0.808 0.838)\",\n slate8: \"color(display-p3 0.727 0.733 0.773)\",\n slate9: \"color(display-p3 0.547 0.553 0.592)\",\n slate10: \"color(display-p3 0.503 0.512 0.549)\",\n slate11: \"color(display-p3 0.379 0.392 0.421)\",\n slate12: \"color(display-p3 0.113 0.125 0.14)\",\n};\nconst slateP3A = {\n slateA1: \"color(display-p3 0.024 0.024 0.349 / 0.012)\",\n slateA2: \"color(display-p3 0.024 0.024 0.349 / 0.024)\",\n slateA3: \"color(display-p3 0.004 0.004 0.204 / 0.059)\",\n slateA4: \"color(display-p3 0.012 0.012 0.184 / 0.091)\",\n slateA5: \"color(display-p3 0.004 0.039 0.2 / 0.122)\",\n slateA6: \"color(display-p3 0.008 0.008 0.165 / 0.15)\",\n slateA7: \"color(display-p3 0.008 0.027 0.184 / 0.197)\",\n slateA8: \"color(display-p3 0.004 0.031 0.176 / 0.275)\",\n slateA9: \"color(display-p3 0.004 0.02 0.106 / 0.455)\",\n slateA10: \"color(display-p3 0.004 0.027 0.098 / 0.499)\",\n slateA11: \"color(display-p3 0 0.02 0.063 / 0.62)\",\n slateA12: \"color(display-p3 0 0.012 0.031 / 0.887)\",\n};\nconst sage = {\n sage1: \"#fbfdfc\",\n sage2: \"#f7f9f8\",\n sage3: \"#eef1f0\",\n sage4: \"#e6e9e8\",\n sage5: \"#dfe2e0\",\n sage6: \"#d7dad9\",\n sage7: \"#cbcfcd\",\n sage8: \"#b8bcba\",\n sage9: \"#868e8b\",\n sage10: \"#7c8481\",\n sage11: \"#5f6563\",\n sage12: \"#1a211e\",\n};\nconst sageA = {\n sageA1: \"#00804004\",\n sageA2: \"#00402008\",\n sageA3: \"#002d1e11\",\n sageA4: \"#001f1519\",\n sageA5: \"#00180820\",\n sageA6: \"#00140d28\",\n sageA7: \"#00140a34\",\n sageA8: \"#000f0847\",\n sageA9: \"#00110b79\",\n sageA10: \"#00100a83\",\n sageA11: \"#000a07a0\",\n sageA12: \"#000805e5\",\n};\nconst sageP3 = {\n sage1: \"color(display-p3 0.986 0.992 0.988)\",\n sage2: \"color(display-p3 0.97 0.977 0.974)\",\n sage3: \"color(display-p3 0.935 0.944 0.94)\",\n sage4: \"color(display-p3 0.904 0.913 0.909)\",\n sage5: \"color(display-p3 0.875 0.885 0.88)\",\n sage6: \"color(display-p3 0.844 0.854 0.849)\",\n sage7: \"color(display-p3 0.8 0.811 0.806)\",\n sage8: \"color(display-p3 0.725 0.738 0.732)\",\n sage9: \"color(display-p3 0.531 0.556 0.546)\",\n sage10: \"color(display-p3 0.492 0.515 0.506)\",\n sage11: \"color(display-p3 0.377 0.395 0.389)\",\n sage12: \"color(display-p3 0.107 0.129 0.118)\",\n};\nconst sageP3A = {\n sageA1: \"color(display-p3 0.024 0.514 0.267 / 0.016)\",\n sageA2: \"color(display-p3 0.02 0.267 0.145 / 0.032)\",\n sageA3: \"color(display-p3 0.008 0.184 0.125 / 0.067)\",\n sageA4: \"color(display-p3 0.012 0.094 0.051 / 0.095)\",\n sageA5: \"color(display-p3 0.008 0.098 0.035 / 0.126)\",\n sageA6: \"color(display-p3 0.004 0.078 0.027 / 0.157)\",\n sageA7: \"color(display-p3 0 0.059 0.039 / 0.2)\",\n sageA8: \"color(display-p3 0.004 0.047 0.031 / 0.275)\",\n sageA9: \"color(display-p3 0.004 0.059 0.035 / 0.471)\",\n sageA10: \"color(display-p3 0 0.047 0.031 / 0.51)\",\n sageA11: \"color(display-p3 0 0.031 0.02 / 0.624)\",\n sageA12: \"color(display-p3 0 0.027 0.012 / 0.895)\",\n};\nconst olive = {\n olive1: \"#fcfdfc\",\n olive2: \"#f8faf8\",\n olive3: \"#eff1ef\",\n olive4: \"#e7e9e7\",\n olive5: \"#dfe2df\",\n olive6: \"#d7dad7\",\n olive7: \"#cccfcc\",\n olive8: \"#b9bcb8\",\n olive9: \"#898e87\",\n olive10: \"#7f847d\",\n olive11: \"#60655f\",\n olive12: \"#1d211c\",\n};\nconst oliveA = {\n oliveA1: \"#00550003\",\n oliveA2: \"#00490007\",\n oliveA3: \"#00200010\",\n oliveA4: \"#00160018\",\n oliveA5: \"#00180020\",\n oliveA6: \"#00140028\",\n oliveA7: \"#000f0033\",\n oliveA8: \"#040f0047\",\n oliveA9: \"#050f0078\",\n oliveA10: \"#040e0082\",\n oliveA11: \"#020a00a0\",\n oliveA12: \"#010600e3\",\n};\nconst oliveP3 = {\n olive1: \"color(display-p3 0.989 0.992 0.989)\",\n olive2: \"color(display-p3 0.974 0.98 0.973)\",\n olive3: \"color(display-p3 0.939 0.945 0.937)\",\n olive4: \"color(display-p3 0.907 0.914 0.905)\",\n olive5: \"color(display-p3 0.878 0.885 0.875)\",\n olive6: \"color(display-p3 0.846 0.855 0.843)\",\n olive7: \"color(display-p3 0.803 0.812 0.8)\",\n olive8: \"color(display-p3 0.727 0.738 0.723)\",\n olive9: \"color(display-p3 0.541 0.556 0.532)\",\n olive10: \"color(display-p3 0.5 0.515 0.491)\",\n olive11: \"color(display-p3 0.38 0.395 0.374)\",\n olive12: \"color(display-p3 0.117 0.129 0.111)\",\n};\nconst oliveP3A = {\n oliveA1: \"color(display-p3 0.024 0.349 0.024 / 0.012)\",\n oliveA2: \"color(display-p3 0.024 0.302 0.024 / 0.028)\",\n oliveA3: \"color(display-p3 0.008 0.129 0.008 / 0.063)\",\n oliveA4: \"color(display-p3 0.012 0.094 0.012 / 0.095)\",\n oliveA5: \"color(display-p3 0.035 0.098 0.008 / 0.126)\",\n oliveA6: \"color(display-p3 0.027 0.078 0.004 / 0.157)\",\n oliveA7: \"color(display-p3 0.02 0.059 0 / 0.2)\",\n oliveA8: \"color(display-p3 0.02 0.059 0.004 / 0.279)\",\n oliveA9: \"color(display-p3 0.02 0.051 0.004 / 0.467)\",\n oliveA10: \"color(display-p3 0.024 0.047 0 / 0.51)\",\n oliveA11: \"color(display-p3 0.012 0.039 0 / 0.628)\",\n oliveA12: \"color(display-p3 0.008 0.024 0 / 0.891)\",\n};\nconst sand = {\n sand1: \"#fdfdfc\",\n sand2: \"#f9f9f8\",\n sand3: \"#f1f0ef\",\n sand4: \"#e9e8e6\",\n sand5: \"#e2e1de\",\n sand6: \"#dad9d6\",\n sand7: \"#cfceca\",\n sand8: \"#bcbbb5\",\n sand9: \"#8d8d86\",\n sand10: \"#82827c\",\n sand11: \"#63635e\",\n sand12: \"#21201c\",\n};\nconst sandA = {\n sandA1: \"#55550003\",\n sandA2: \"#25250007\",\n sandA3: \"#20100010\",\n sandA4: \"#1f150019\",\n sandA5: \"#1f180021\",\n sandA6: \"#19130029\",\n sandA7: \"#19140035\",\n sandA8: \"#1915014a\",\n sandA9: \"#0f0f0079\",\n sandA10: \"#0c0c0083\",\n sandA11: \"#080800a1\",\n sandA12: \"#060500e3\",\n};\nconst sandP3 = {\n sand1: \"color(display-p3 0.992 0.992 0.989)\",\n sand2: \"color(display-p3 0.977 0.977 0.973)\",\n sand3: \"color(display-p3 0.943 0.942 0.936)\",\n sand4: \"color(display-p3 0.913 0.912 0.903)\",\n sand5: \"color(display-p3 0.885 0.883 0.873)\",\n sand6: \"color(display-p3 0.854 0.852 0.839)\",\n sand7: \"color(display-p3 0.813 0.81 0.794)\",\n sand8: \"color(display-p3 0.738 0.734 0.713)\",\n sand9: \"color(display-p3 0.553 0.553 0.528)\",\n sand10: \"color(display-p3 0.511 0.511 0.488)\",\n sand11: \"color(display-p3 0.388 0.388 0.37)\",\n sand12: \"color(display-p3 0.129 0.126 0.111)\",\n};\nconst sandP3A = {\n sandA1: \"color(display-p3 0.349 0.349 0.024 / 0.012)\",\n sandA2: \"color(display-p3 0.161 0.161 0.024 / 0.028)\",\n sandA3: \"color(display-p3 0.067 0.067 0.008 / 0.063)\",\n sandA4: \"color(display-p3 0.129 0.129 0.012 / 0.099)\",\n sandA5: \"color(display-p3 0.098 0.067 0.008 / 0.126)\",\n sandA6: \"color(display-p3 0.102 0.075 0.004 / 0.161)\",\n sandA7: \"color(display-p3 0.098 0.098 0.004 / 0.208)\",\n sandA8: \"color(display-p3 0.086 0.075 0.004 / 0.287)\",\n sandA9: \"color(display-p3 0.051 0.051 0.004 / 0.471)\",\n sandA10: \"color(display-p3 0.047 0.047 0 / 0.514)\",\n sandA11: \"color(display-p3 0.031 0.031 0 / 0.632)\",\n sandA12: \"color(display-p3 0.024 0.02 0 / 0.891)\",\n};\nconst tomato = {\n tomato1: \"#fffcfc\",\n tomato2: \"#fff8f7\",\n tomato3: \"#feebe7\",\n tomato4: \"#ffdcd3\",\n tomato5: \"#ffcdc2\",\n tomato6: \"#fdbdaf\",\n tomato7: \"#f5a898\",\n tomato8: \"#ec8e7b\",\n tomato9: \"#e54d2e\",\n tomato10: \"#dd4425\",\n tomato11: \"#d13415\",\n tomato12: \"#5c271f\",\n};\nconst tomatoA = {\n tomatoA1: \"#ff000003\",\n tomatoA2: \"#ff200008\",\n tomatoA3: \"#f52b0018\",\n tomatoA4: \"#ff35002c\",\n tomatoA5: \"#ff2e003d\",\n tomatoA6: \"#f92d0050\",\n tomatoA7: \"#e7280067\",\n tomatoA8: \"#db250084\",\n tomatoA9: \"#df2600d1\",\n tomatoA10: \"#d72400da\",\n tomatoA11: \"#cd2200ea\",\n tomatoA12: \"#460900e0\",\n};\nconst tomatoP3 = {\n tomato1: \"color(display-p3 0.998 0.989 0.988)\",\n tomato2: \"color(display-p3 0.994 0.974 0.969)\",\n tomato3: \"color(display-p3 0.985 0.924 0.909)\",\n tomato4: \"color(display-p3 0.996 0.868 0.835)\",\n tomato5: \"color(display-p3 0.98 0.812 0.77)\",\n tomato6: \"color(display-p3 0.953 0.75 0.698)\",\n tomato7: \"color(display-p3 0.917 0.673 0.611)\",\n tomato8: \"color(display-p3 0.875 0.575 0.502)\",\n tomato9: \"color(display-p3 0.831 0.345 0.231)\",\n tomato10: \"color(display-p3 0.802 0.313 0.2)\",\n tomato11: \"color(display-p3 0.755 0.259 0.152)\",\n tomato12: \"color(display-p3 0.335 0.165 0.132)\",\n};\nconst tomatoP3A = {\n tomatoA1: \"color(display-p3 0.675 0.024 0.024 / 0.012)\",\n tomatoA2: \"color(display-p3 0.757 0.145 0.02 / 0.032)\",\n tomatoA3: \"color(display-p3 0.831 0.184 0.012 / 0.091)\",\n tomatoA4: \"color(display-p3 0.976 0.192 0.004 / 0.165)\",\n tomatoA5: \"color(display-p3 0.918 0.192 0.004 / 0.232)\",\n tomatoA6: \"color(display-p3 0.847 0.173 0.004 / 0.302)\",\n tomatoA7: \"color(display-p3 0.788 0.165 0.004 / 0.389)\",\n tomatoA8: \"color(display-p3 0.749 0.153 0.004 / 0.499)\",\n tomatoA9: \"color(display-p3 0.78 0.149 0 / 0.769)\",\n tomatoA10: \"color(display-p3 0.757 0.141 0 / 0.8)\",\n tomatoA11: \"color(display-p3 0.755 0.259 0.152)\",\n tomatoA12: \"color(display-p3 0.335 0.165 0.132)\",\n};\nconst red = {\n red1: \"#fffcfc\",\n red2: \"#fff7f7\",\n red3: \"#feebec\",\n red4: \"#ffdbdc\",\n red5: \"#ffcdce\",\n red6: \"#fdbdbe\",\n red7: \"#f4a9aa\",\n red8: \"#eb8e90\",\n red9: \"#e5484d\",\n red10: \"#dc3e42\",\n red11: \"#ce2c31\",\n red12: \"#641723\",\n};\nconst redA = {\n redA1: \"#ff000003\",\n redA2: \"#ff000008\",\n redA3: \"#f3000d14\",\n redA4: \"#ff000824\",\n redA5: \"#ff000632\",\n redA6: \"#f8000442\",\n redA7: \"#df000356\",\n redA8: \"#d2000571\",\n redA9: \"#db0007b7\",\n redA10: \"#d10005c1\",\n redA11: \"#c40006d3\",\n redA12: \"#55000de8\",\n};\nconst redP3 = {\n red1: \"color(display-p3 0.998 0.989 0.988)\",\n red2: \"color(display-p3 0.995 0.971 0.971)\",\n red3: \"color(display-p3 0.985 0.925 0.925)\",\n red4: \"color(display-p3 0.999 0.866 0.866)\",\n red5: \"color(display-p3 0.984 0.812 0.811)\",\n red6: \"color(display-p3 0.955 0.751 0.749)\",\n red7: \"color(display-p3 0.915 0.675 0.672)\",\n red8: \"color(display-p3 0.872 0.575 0.572)\",\n red9: \"color(display-p3 0.83 0.329 0.324)\",\n red10: \"color(display-p3 0.798 0.294 0.285)\",\n red11: \"color(display-p3 0.744 0.234 0.222)\",\n red12: \"color(display-p3 0.36 0.115 0.143)\",\n};\nconst redP3A = {\n redA1: \"color(display-p3 0.675 0.024 0.024 / 0.012)\",\n redA2: \"color(display-p3 0.863 0.024 0.024 / 0.028)\",\n redA3: \"color(display-p3 0.792 0.008 0.008 / 0.075)\",\n redA4: \"color(display-p3 1 0.008 0.008 / 0.134)\",\n redA5: \"color(display-p3 0.918 0.008 0.008 / 0.189)\",\n redA6: \"color(display-p3 0.831 0.02 0.004 / 0.251)\",\n redA7: \"color(display-p3 0.741 0.016 0.004 / 0.33)\",\n redA8: \"color(display-p3 0.698 0.012 0.004 / 0.428)\",\n redA9: \"color(display-p3 0.749 0.008 0 / 0.675)\",\n redA10: \"color(display-p3 0.714 0.012 0 / 0.714)\",\n redA11: \"color(display-p3 0.744 0.234 0.222)\",\n redA12: \"color(display-p3 0.36 0.115 0.143)\",\n};\nconst ruby = {\n ruby1: \"#fffcfd\",\n ruby2: \"#fff7f8\",\n ruby3: \"#feeaed\",\n ruby4: \"#ffdce1\",\n ruby5: \"#ffced6\",\n ruby6: \"#f8bfc8\",\n ruby7: \"#efacb8\",\n ruby8: \"#e592a3\",\n ruby9: \"#e54666\",\n ruby10: \"#dc3b5d\",\n ruby11: \"#ca244d\",\n ruby12: \"#64172b\",\n};\nconst rubyA = {\n rubyA1: \"#ff005503\",\n rubyA2: \"#ff002008\",\n rubyA3: \"#f3002515\",\n rubyA4: \"#ff002523\",\n rubyA5: \"#ff002a31\",\n rubyA6: \"#e4002440\",\n rubyA7: \"#ce002553\",\n rubyA8: \"#c300286d\",\n rubyA9: \"#db002cb9\",\n rubyA10: \"#d2002cc4\",\n rubyA11: \"#c10030db\",\n rubyA12: \"#550016e8\",\n};\nconst rubyP3 = {\n ruby1: \"color(display-p3 0.998 0.989 0.992)\",\n ruby2: \"color(display-p3 0.995 0.971 0.974)\",\n ruby3: \"color(display-p3 0.983 0.92 0.928)\",\n ruby4: \"color(display-p3 0.987 0.869 0.885)\",\n ruby5: \"color(display-p3 0.968 0.817 0.839)\",\n ruby6: \"color(display-p3 0.937 0.758 0.786)\",\n ruby7: \"color(display-p3 0.897 0.685 0.721)\",\n ruby8: \"color(display-p3 0.851 0.588 0.639)\",\n ruby9: \"color(display-p3 0.83 0.323 0.408)\",\n ruby10: \"color(display-p3 0.795 0.286 0.375)\",\n ruby11: \"color(display-p3 0.728 0.211 0.311)\",\n ruby12: \"color(display-p3 0.36 0.115 0.171)\",\n};\nconst rubyP3A = {\n rubyA1: \"color(display-p3 0.675 0.024 0.349 / 0.012)\",\n rubyA2: \"color(display-p3 0.863 0.024 0.024 / 0.028)\",\n rubyA3: \"color(display-p3 0.804 0.008 0.11 / 0.079)\",\n rubyA4: \"color(display-p3 0.91 0.008 0.125 / 0.13)\",\n rubyA5: \"color(display-p3 0.831 0.004 0.133 / 0.185)\",\n rubyA6: \"color(display-p3 0.745 0.004 0.118 / 0.244)\",\n rubyA7: \"color(display-p3 0.678 0.004 0.114 / 0.314)\",\n rubyA8: \"color(display-p3 0.639 0.004 0.125 / 0.412)\",\n rubyA9: \"color(display-p3 0.753 0 0.129 / 0.679)\",\n rubyA10: \"color(display-p3 0.714 0 0.125 / 0.714)\",\n rubyA11: \"color(display-p3 0.728 0.211 0.311)\",\n rubyA12: \"color(display-p3 0.36 0.115 0.171)\",\n};\nconst crimson = {\n crimson1: \"#fffcfd\",\n crimson2: \"#fef7f9\",\n crimson3: \"#ffe9f0\",\n crimson4: \"#fedce7\",\n crimson5: \"#facedd\",\n crimson6: \"#f3bed1\",\n crimson7: \"#eaacc3\",\n crimson8: \"#e093b2\",\n crimson9: \"#e93d82\",\n crimson10: \"#df3478\",\n crimson11: \"#cb1d63\",\n crimson12: \"#621639\",\n};\nconst crimsonA = {\n crimsonA1: \"#ff005503\",\n crimsonA2: \"#e0004008\",\n crimsonA3: \"#ff005216\",\n crimsonA4: \"#f8005123\",\n crimsonA5: \"#e5004f31\",\n crimsonA6: \"#d0004b41\",\n crimsonA7: \"#bf004753\",\n crimsonA8: \"#b6004a6c\",\n crimsonA9: \"#e2005bc2\",\n crimsonA10: \"#d70056cb\",\n crimsonA11: \"#c4004fe2\",\n crimsonA12: \"#530026e9\",\n};\nconst crimsonP3 = {\n crimson1: \"color(display-p3 0.998 0.989 0.992)\",\n crimson2: \"color(display-p3 0.991 0.969 0.976)\",\n crimson3: \"color(display-p3 0.987 0.917 0.941)\",\n crimson4: \"color(display-p3 0.975 0.866 0.904)\",\n crimson5: \"color(display-p3 0.953 0.813 0.864)\",\n crimson6: \"color(display-p3 0.921 0.755 0.817)\",\n crimson7: \"color(display-p3 0.88 0.683 0.761)\",\n crimson8: \"color(display-p3 0.834 0.592 0.694)\",\n crimson9: \"color(display-p3 0.843 0.298 0.507)\",\n crimson10: \"color(display-p3 0.807 0.266 0.468)\",\n crimson11: \"color(display-p3 0.731 0.195 0.388)\",\n crimson12: \"color(display-p3 0.352 0.111 0.221)\",\n};\nconst crimsonP3A = {\n crimsonA1: \"color(display-p3 0.675 0.024 0.349 / 0.012)\",\n crimsonA2: \"color(display-p3 0.757 0.02 0.267 / 0.032)\",\n crimsonA3: \"color(display-p3 0.859 0.008 0.294 / 0.083)\",\n crimsonA4: \"color(display-p3 0.827 0.008 0.298 / 0.134)\",\n crimsonA5: \"color(display-p3 0.753 0.008 0.275 / 0.189)\",\n crimsonA6: \"color(display-p3 0.682 0.004 0.247 / 0.244)\",\n crimsonA7: \"color(display-p3 0.62 0.004 0.251 / 0.318)\",\n crimsonA8: \"color(display-p3 0.6 0.004 0.251 / 0.408)\",\n crimsonA9: \"color(display-p3 0.776 0 0.298 / 0.702)\",\n crimsonA10: \"color(display-p3 0.737 0 0.275 / 0.734)\",\n crimsonA11: \"color(display-p3 0.731 0.195 0.388)\",\n crimsonA12: \"color(display-p3 0.352 0.111 0.221)\",\n};\nconst pink = {\n pink1: \"#fffcfe\",\n pink2: \"#fef7fb\",\n pink3: \"#fee9f5\",\n pink4: \"#fbdcef\",\n pink5: \"#f6cee7\",\n pink6: \"#efbfdd\",\n pink7: \"#e7acd0\",\n pink8: \"#dd93c2\",\n pink9: \"#d6409f\",\n pink10: \"#cf3897\",\n pink11: \"#c2298a\",\n pink12: \"#651249\",\n};\nconst pinkA = {\n pinkA1: \"#ff00aa03\",\n pinkA2: \"#e0008008\",\n pinkA3: \"#f4008c16\",\n pinkA4: \"#e2008b23\",\n pinkA5: \"#d1008331\",\n pinkA6: \"#c0007840\",\n pinkA7: \"#b6006f53\",\n pinkA8: \"#af006f6c\",\n pinkA9: \"#c8007fbf\",\n pinkA10: \"#c2007ac7\",\n pinkA11: \"#b60074d6\",\n pinkA12: \"#59003bed\",\n};\nconst pinkP3 = {\n pink1: \"color(display-p3 0.998 0.989 0.996)\",\n pink2: \"color(display-p3 0.992 0.97 0.985)\",\n pink3: \"color(display-p3 0.981 0.917 0.96)\",\n pink4: \"color(display-p3 0.963 0.867 0.932)\",\n pink5: \"color(display-p3 0.939 0.815 0.899)\",\n pink6: \"color(display-p3 0.907 0.756 0.859)\",\n pink7: \"color(display-p3 0.869 0.683 0.81)\",\n pink8: \"color(display-p3 0.825 0.59 0.751)\",\n pink9: \"color(display-p3 0.775 0.297 0.61)\",\n pink10: \"color(display-p3 0.748 0.27 0.581)\",\n pink11: \"color(display-p3 0.698 0.219 0.528)\",\n pink12: \"color(display-p3 0.363 0.101 0.279)\",\n};\nconst pinkP3A = {\n pinkA1: \"color(display-p3 0.675 0.024 0.675 / 0.012)\",\n pinkA2: \"color(display-p3 0.757 0.02 0.51 / 0.032)\",\n pinkA3: \"color(display-p3 0.765 0.008 0.529 / 0.083)\",\n pinkA4: \"color(display-p3 0.737 0.008 0.506 / 0.134)\",\n pinkA5: \"color(display-p3 0.663 0.004 0.451 / 0.185)\",\n pinkA6: \"color(display-p3 0.616 0.004 0.424 / 0.244)\",\n pinkA7: \"color(display-p3 0.596 0.004 0.412 / 0.318)\",\n pinkA8: \"color(display-p3 0.573 0.004 0.404 / 0.412)\",\n pinkA9: \"color(display-p3 0.682 0 0.447 / 0.702)\",\n pinkA10: \"color(display-p3 0.655 0 0.424 / 0.73)\",\n pinkA11: \"color(display-p3 0.698 0.219 0.528)\",\n pinkA12: \"color(display-p3 0.363 0.101 0.279)\",\n};\nconst plum = {\n plum1: \"#fefcff\",\n plum2: \"#fdf7fd\",\n plum3: \"#fbebfb\",\n plum4: \"#f7def8\",\n plum5: \"#f2d1f3\",\n plum6: \"#e9c2ec\",\n plum7: \"#deade3\",\n plum8: \"#cf91d8\",\n plum9: \"#ab4aba\",\n plum10: \"#a144af\",\n plum11: \"#953ea3\",\n plum12: \"#53195d\",\n};\nconst plumA = {\n plumA1: \"#aa00ff03\",\n plumA2: \"#c000c008\",\n plumA3: \"#cc00cc14\",\n plumA4: \"#c200c921\",\n plumA5: \"#b700bd2e\",\n plumA6: \"#a400b03d\",\n plumA7: \"#9900a852\",\n plumA8: \"#9000a56e\",\n plumA9: \"#89009eb5\",\n plumA10: \"#7f0092bb\",\n plumA11: \"#730086c1\",\n plumA12: \"#40004be6\",\n};\nconst plumP3 = {\n plum1: \"color(display-p3 0.995 0.988 0.999)\",\n plum2: \"color(display-p3 0.988 0.971 0.99)\",\n plum3: \"color(display-p3 0.973 0.923 0.98)\",\n plum4: \"color(display-p3 0.953 0.875 0.966)\",\n plum5: \"color(display-p3 0.926 0.825 0.945)\",\n plum6: \"color(display-p3 0.89 0.765 0.916)\",\n plum7: \"color(display-p3 0.84 0.686 0.877)\",\n plum8: \"color(display-p3 0.775 0.58 0.832)\",\n plum9: \"color(display-p3 0.624 0.313 0.708)\",\n plum10: \"color(display-p3 0.587 0.29 0.667)\",\n plum11: \"color(display-p3 0.543 0.263 0.619)\",\n plum12: \"color(display-p3 0.299 0.114 0.352)\",\n};\nconst plumP3A = {\n plumA1: \"color(display-p3 0.675 0.024 1 / 0.012)\",\n plumA2: \"color(display-p3 0.58 0.024 0.58 / 0.028)\",\n plumA3: \"color(display-p3 0.655 0.008 0.753 / 0.079)\",\n plumA4: \"color(display-p3 0.627 0.008 0.722 / 0.126)\",\n plumA5: \"color(display-p3 0.58 0.004 0.69 / 0.177)\",\n plumA6: \"color(display-p3 0.537 0.004 0.655 / 0.236)\",\n plumA7: \"color(display-p3 0.49 0.004 0.616 / 0.314)\",\n plumA8: \"color(display-p3 0.471 0.004 0.6 / 0.42)\",\n plumA9: \"color(display-p3 0.451 0 0.576 / 0.687)\",\n plumA10: \"color(display-p3 0.42 0 0.529 / 0.71)\",\n plumA11: \"color(display-p3 0.543 0.263 0.619)\",\n plumA12: \"color(display-p3 0.299 0.114 0.352)\",\n};\nconst purple = {\n purple1: \"#fefcfe\",\n purple2: \"#fbf7fe\",\n purple3: \"#f7edfe\",\n purple4: \"#f2e2fc\",\n purple5: \"#ead5f9\",\n purple6: \"#e0c4f4\",\n purple7: \"#d1afec\",\n purple8: \"#be93e4\",\n purple9: \"#8e4ec6\",\n purple10: \"#8347b9\",\n purple11: \"#8145b5\",\n purple12: \"#402060\",\n};\nconst purpleA = {\n purpleA1: \"#aa00aa03\",\n purpleA2: \"#8000e008\",\n purpleA3: \"#8e00f112\",\n purpleA4: \"#8d00e51d\",\n purpleA5: \"#8000db2a\",\n purpleA6: \"#7a01d03b\",\n purpleA7: \"#6d00c350\",\n purpleA8: \"#6600c06c\",\n purpleA9: \"#5c00adb1\",\n purpleA10: \"#53009eb8\",\n purpleA11: \"#52009aba\",\n purpleA12: \"#250049df\",\n};\nconst purpleP3 = {\n purple1: \"color(display-p3 0.995 0.988 0.996)\",\n purple2: \"color(display-p3 0.983 0.971 0.993)\",\n purple3: \"color(display-p3 0.963 0.931 0.989)\",\n purple4: \"color(display-p3 0.937 0.888 0.981)\",\n purple5: \"color(display-p3 0.904 0.837 0.966)\",\n purple6: \"color(display-p3 0.86 0.774 0.942)\",\n purple7: \"color(display-p3 0.799 0.69 0.91)\",\n purple8: \"color(display-p3 0.719 0.583 0.874)\",\n purple9: \"color(display-p3 0.523 0.318 0.751)\",\n purple10: \"color(display-p3 0.483 0.289 0.7)\",\n purple11: \"color(display-p3 0.473 0.281 0.687)\",\n purple12: \"color(display-p3 0.234 0.132 0.363)\",\n};\nconst purpleP3A = {\n purpleA1: \"color(display-p3 0.675 0.024 0.675 / 0.012)\",\n purpleA2: \"color(display-p3 0.443 0.024 0.722 / 0.028)\",\n purpleA3: \"color(display-p3 0.506 0.008 0.835 / 0.071)\",\n purpleA4: \"color(display-p3 0.451 0.004 0.831 / 0.114)\",\n purpleA5: \"color(display-p3 0.431 0.004 0.788 / 0.165)\",\n purpleA6: \"color(display-p3 0.384 0.004 0.745 / 0.228)\",\n purpleA7: \"color(display-p3 0.357 0.004 0.71 / 0.31)\",\n purpleA8: \"color(display-p3 0.322 0.004 0.702 / 0.416)\",\n purpleA9: \"color(display-p3 0.298 0 0.639 / 0.683)\",\n purpleA10: \"color(display-p3 0.271 0 0.58 / 0.71)\",\n purpleA11: \"color(display-p3 0.473 0.281 0.687)\",\n purpleA12: \"color(display-p3 0.234 0.132 0.363)\",\n};\nconst violet = {\n violet1: \"#fdfcfe\",\n violet2: \"#faf8ff\",\n violet3: \"#f4f0fe\",\n violet4: \"#ebe4ff\",\n violet5: \"#e1d9ff\",\n violet6: \"#d4cafe\",\n violet7: \"#c2b5f5\",\n violet8: \"#aa99ec\",\n violet9: \"#6e56cf\",\n violet10: \"#654dc4\",\n violet11: \"#6550b9\",\n violet12: \"#2f265f\",\n};\nconst violetA = {\n violetA1: \"#5500aa03\",\n violetA2: \"#4900ff07\",\n violetA3: \"#4400ee0f\",\n violetA4: \"#4300ff1b\",\n violetA5: \"#3600ff26\",\n violetA6: \"#3100fb35\",\n violetA7: \"#2d01dd4a\",\n violetA8: \"#2b00d066\",\n violetA9: \"#2400b7a9\",\n violetA10: \"#2300abb2\",\n violetA11: \"#1f0099af\",\n violetA12: \"#0b0043d9\",\n};\nconst violetP3 = {\n violet1: \"color(display-p3 0.991 0.988 0.995)\",\n violet2: \"color(display-p3 0.978 0.974 0.998)\",\n violet3: \"color(display-p3 0.953 0.943 0.993)\",\n violet4: \"color(display-p3 0.916 0.897 1)\",\n violet5: \"color(display-p3 0.876 0.851 1)\",\n violet6: \"color(display-p3 0.825 0.793 0.981)\",\n violet7: \"color(display-p3 0.752 0.712 0.943)\",\n violet8: \"color(display-p3 0.654 0.602 0.902)\",\n violet9: \"color(display-p3 0.417 0.341 0.784)\",\n violet10: \"color(display-p3 0.381 0.306 0.741)\",\n violet11: \"color(display-p3 0.383 0.317 0.702)\",\n violet12: \"color(display-p3 0.179 0.15 0.359)\",\n};\nconst violetP3A = {\n violetA1: \"color(display-p3 0.349 0.024 0.675 / 0.012)\",\n violetA2: \"color(display-p3 0.161 0.024 0.863 / 0.028)\",\n violetA3: \"color(display-p3 0.204 0.004 0.871 / 0.059)\",\n violetA4: \"color(display-p3 0.196 0.004 1 / 0.102)\",\n violetA5: \"color(display-p3 0.165 0.008 1 / 0.15)\",\n violetA6: \"color(display-p3 0.153 0.004 0.906 / 0.208)\",\n violetA7: \"color(display-p3 0.141 0.004 0.796 / 0.287)\",\n violetA8: \"color(display-p3 0.133 0.004 0.753 / 0.397)\",\n violetA9: \"color(display-p3 0.114 0 0.675 / 0.659)\",\n violetA10: \"color(display-p3 0.11 0 0.627 / 0.695)\",\n violetA11: \"color(display-p3 0.383 0.317 0.702)\",\n violetA12: \"color(display-p3 0.179 0.15 0.359)\",\n};\nconst iris = {\n iris1: \"#fdfdff\",\n iris2: \"#f8f8ff\",\n iris3: \"#f0f1fe\",\n iris4: \"#e6e7ff\",\n iris5: \"#dadcff\",\n iris6: \"#cbcdff\",\n iris7: \"#b8baf8\",\n iris8: \"#9b9ef0\",\n iris9: \"#5b5bd6\",\n iris10: \"#5151cd\",\n iris11: \"#5753c6\",\n iris12: \"#272962\",\n};\nconst irisA = {\n irisA1: \"#0000ff02\",\n irisA2: \"#0000ff07\",\n irisA3: \"#0011ee0f\",\n irisA4: \"#000bff19\",\n irisA5: \"#000eff25\",\n irisA6: \"#000aff34\",\n irisA7: \"#0008e647\",\n irisA8: \"#0008d964\",\n irisA9: \"#0000c0a4\",\n irisA10: \"#0000b6ae\",\n irisA11: \"#0600abac\",\n irisA12: \"#000246d8\",\n};\nconst irisP3 = {\n iris1: \"color(display-p3 0.992 0.992 0.999)\",\n iris2: \"color(display-p3 0.972 0.973 0.998)\",\n iris3: \"color(display-p3 0.943 0.945 0.992)\",\n iris4: \"color(display-p3 0.902 0.906 1)\",\n iris5: \"color(display-p3 0.857 0.861 1)\",\n iris6: \"color(display-p3 0.799 0.805 0.987)\",\n iris7: \"color(display-p3 0.721 0.727 0.955)\",\n iris8: \"color(display-p3 0.61 0.619 0.918)\",\n iris9: \"color(display-p3 0.357 0.357 0.81)\",\n iris10: \"color(display-p3 0.318 0.318 0.774)\",\n iris11: \"color(display-p3 0.337 0.326 0.748)\",\n iris12: \"color(display-p3 0.154 0.161 0.371)\",\n};\nconst irisP3A = {\n irisA1: \"color(display-p3 0.02 0.02 1 / 0.008)\",\n irisA2: \"color(display-p3 0.024 0.024 0.863 / 0.028)\",\n irisA3: \"color(display-p3 0.004 0.071 0.871 / 0.059)\",\n irisA4: \"color(display-p3 0.012 0.051 1 / 0.099)\",\n irisA5: \"color(display-p3 0.008 0.035 1 / 0.142)\",\n irisA6: \"color(display-p3 0 0.02 0.941 / 0.2)\",\n irisA7: \"color(display-p3 0.004 0.02 0.847 / 0.279)\",\n irisA8: \"color(display-p3 0.004 0.024 0.788 / 0.389)\",\n irisA9: \"color(display-p3 0 0 0.706 / 0.644)\",\n irisA10: \"color(display-p3 0 0 0.667 / 0.683)\",\n irisA11: \"color(display-p3 0.337 0.326 0.748)\",\n irisA12: \"color(display-p3 0.154 0.161 0.371)\",\n};\nconst indigo = {\n indigo1: \"#fdfdfe\",\n indigo2: \"#f7f9ff\",\n indigo3: \"#edf2fe\",\n indigo4: \"#e1e9ff\",\n indigo5: \"#d2deff\",\n indigo6: \"#c1d0ff\",\n indigo7: \"#abbdf9\",\n indigo8: \"#8da4ef\",\n indigo9: \"#3e63dd\",\n indigo10: \"#3358d4\",\n indigo11: \"#3a5bc7\",\n indigo12: \"#1f2d5c\",\n};\nconst indigoA = {\n indigoA1: \"#00008002\",\n indigoA2: \"#0040ff08\",\n indigoA3: \"#0047f112\",\n indigoA4: \"#0044ff1e\",\n indigoA5: \"#0044ff2d\",\n indigoA6: \"#003eff3e\",\n indigoA7: \"#0037ed54\",\n indigoA8: \"#0034dc72\",\n indigoA9: \"#0031d2c1\",\n indigoA10: \"#002ec9cc\",\n indigoA11: \"#002bb7c5\",\n indigoA12: \"#001046e0\",\n};\nconst indigoP3 = {\n indigo1: \"color(display-p3 0.992 0.992 0.996)\",\n indigo2: \"color(display-p3 0.971 0.977 0.998)\",\n indigo3: \"color(display-p3 0.933 0.948 0.992)\",\n indigo4: \"color(display-p3 0.885 0.914 1)\",\n indigo5: \"color(display-p3 0.831 0.87 1)\",\n indigo6: \"color(display-p3 0.767 0.814 0.995)\",\n indigo7: \"color(display-p3 0.685 0.74 0.957)\",\n indigo8: \"color(display-p3 0.569 0.639 0.916)\",\n indigo9: \"color(display-p3 0.276 0.384 0.837)\",\n indigo10: \"color(display-p3 0.234 0.343 0.801)\",\n indigo11: \"color(display-p3 0.256 0.354 0.755)\",\n indigo12: \"color(display-p3 0.133 0.175 0.348)\",\n};\nconst indigoP3A = {\n indigoA1: \"color(display-p3 0.02 0.02 0.51 / 0.008)\",\n indigoA2: \"color(display-p3 0.024 0.161 0.863 / 0.028)\",\n indigoA3: \"color(display-p3 0.008 0.239 0.886 / 0.067)\",\n indigoA4: \"color(display-p3 0.004 0.247 1 / 0.114)\",\n indigoA5: \"color(display-p3 0.004 0.235 1 / 0.169)\",\n indigoA6: \"color(display-p3 0.004 0.208 0.984 / 0.232)\",\n indigoA7: \"color(display-p3 0.004 0.176 0.863 / 0.314)\",\n indigoA8: \"color(display-p3 0.004 0.165 0.812 / 0.432)\",\n indigoA9: \"color(display-p3 0 0.153 0.773 / 0.726)\",\n indigoA10: \"color(display-p3 0 0.137 0.737 / 0.765)\",\n indigoA11: \"color(display-p3 0.256 0.354 0.755)\",\n indigoA12: \"color(display-p3 0.133 0.175 0.348)\",\n};\nconst blue = {\n blue1: \"#fbfdff\",\n blue2: \"#f4faff\",\n blue3: \"#e6f4fe\",\n blue4: \"#d5efff\",\n blue5: \"#c2e5ff\",\n blue6: \"#acd8fc\",\n blue7: \"#8ec8f6\",\n blue8: \"#5eb1ef\",\n blue9: \"#0090ff\",\n blue10: \"#0588f0\",\n blue11: \"#0d74ce\",\n blue12: \"#113264\",\n};\nconst blueA = {\n blueA1: \"#0080ff04\",\n blueA2: \"#008cff0b\",\n blueA3: \"#008ff519\",\n blueA4: \"#009eff2a\",\n blueA5: \"#0093ff3d\",\n blueA6: \"#0088f653\",\n blueA7: \"#0083eb71\",\n blueA8: \"#0084e6a1\",\n blueA9: \"#0090ff\",\n blueA10: \"#0086f0fa\",\n blueA11: \"#006dcbf2\",\n blueA12: \"#002359ee\",\n};\nconst blueP3 = {\n blue1: \"color(display-p3 0.986 0.992 0.999)\",\n blue2: \"color(display-p3 0.96 0.979 0.998)\",\n blue3: \"color(display-p3 0.912 0.956 0.991)\",\n blue4: \"color(display-p3 0.853 0.932 1)\",\n blue5: \"color(display-p3 0.788 0.894 0.998)\",\n blue6: \"color(display-p3 0.709 0.843 0.976)\",\n blue7: \"color(display-p3 0.606 0.777 0.947)\",\n blue8: \"color(display-p3 0.451 0.688 0.917)\",\n blue9: \"color(display-p3 0.247 0.556 0.969)\",\n blue10: \"color(display-p3 0.234 0.523 0.912)\",\n blue11: \"color(display-p3 0.15 0.44 0.84)\",\n blue12: \"color(display-p3 0.102 0.193 0.379)\",\n};\nconst blueP3A = {\n blueA1: \"color(display-p3 0.024 0.514 1 / 0.016)\",\n blueA2: \"color(display-p3 0.024 0.514 0.906 / 0.04)\",\n blueA3: \"color(display-p3 0.012 0.506 0.914 / 0.087)\",\n blueA4: \"color(display-p3 0.008 0.545 1 / 0.146)\",\n blueA5: \"color(display-p3 0.004 0.502 0.984 / 0.212)\",\n blueA6: \"color(display-p3 0.004 0.463 0.922 / 0.291)\",\n blueA7: \"color(display-p3 0.004 0.431 0.863 / 0.393)\",\n blueA8: \"color(display-p3 0 0.427 0.851 / 0.55)\",\n blueA9: \"color(display-p3 0 0.412 0.961 / 0.753)\",\n blueA10: \"color(display-p3 0 0.376 0.886 / 0.765)\",\n blueA11: \"color(display-p3 0.15 0.44 0.84)\",\n blueA12: \"color(display-p3 0.102 0.193 0.379)\",\n};\nconst cyan = {\n cyan1: \"#fafdfe\",\n cyan2: \"#f2fafb\",\n cyan3: \"#def7f9\",\n cyan4: \"#caf1f6\",\n cyan5: \"#b5e9f0\",\n cyan6: \"#9ddde7\",\n cyan7: \"#7dcedc\",\n cyan8: \"#3db9cf\",\n cyan9: \"#00a2c7\",\n cyan10: \"#0797b9\",\n cyan11: \"#107d98\",\n cyan12: \"#0d3c48\",\n};\nconst cyanA = {\n cyanA1: \"#0099cc05\",\n cyanA2: \"#009db10d\",\n cyanA3: \"#00c2d121\",\n cyanA4: \"#00bcd435\",\n cyanA5: \"#01b4cc4a\",\n cyanA6: \"#00a7c162\",\n cyanA7: \"#009fbb82\",\n cyanA8: \"#00a3c0c2\",\n cyanA9: \"#00a2c7\",\n cyanA10: \"#0094b7f8\",\n cyanA11: \"#007491ef\",\n cyanA12: \"#00323ef2\",\n};\nconst cyanP3 = {\n cyan1: \"color(display-p3 0.982 0.992 0.996)\",\n cyan2: \"color(display-p3 0.955 0.981 0.984)\",\n cyan3: \"color(display-p3 0.888 0.965 0.975)\",\n cyan4: \"color(display-p3 0.821 0.941 0.959)\",\n cyan5: \"color(display-p3 0.751 0.907 0.935)\",\n cyan6: \"color(display-p3 0.671 0.862 0.9)\",\n cyan7: \"color(display-p3 0.564 0.8 0.854)\",\n cyan8: \"color(display-p3 0.388 0.715 0.798)\",\n cyan9: \"color(display-p3 0.282 0.627 0.765)\",\n cyan10: \"color(display-p3 0.264 0.583 0.71)\",\n cyan11: \"color(display-p3 0.08 0.48 0.63)\",\n cyan12: \"color(display-p3 0.108 0.232 0.277)\",\n};\nconst cyanP3A = {\n cyanA1: \"color(display-p3 0.02 0.608 0.804 / 0.02)\",\n cyanA2: \"color(display-p3 0.02 0.557 0.647 / 0.044)\",\n cyanA3: \"color(display-p3 0.004 0.694 0.796 / 0.114)\",\n cyanA4: \"color(display-p3 0.004 0.678 0.784 / 0.181)\",\n cyanA5: \"color(display-p3 0.004 0.624 0.733 / 0.248)\",\n cyanA6: \"color(display-p3 0.004 0.584 0.706 / 0.33)\",\n cyanA7: \"color(display-p3 0.004 0.541 0.667 / 0.436)\",\n cyanA8: \"color(display-p3 0 0.533 0.667 / 0.612)\",\n cyanA9: \"color(display-p3 0 0.482 0.675 / 0.718)\",\n cyanA10: \"color(display-p3 0 0.435 0.608 / 0.738)\",\n cyanA11: \"color(display-p3 0.08 0.48 0.63)\",\n cyanA12: \"color(display-p3 0.108 0.232 0.277)\",\n};\nconst teal = {\n teal1: \"#fafefd\",\n teal2: \"#f3fbf9\",\n teal3: \"#e0f8f3\",\n teal4: \"#ccf3ea\",\n teal5: \"#b8eae0\",\n teal6: \"#a1ded2\",\n teal7: \"#83cdc1\",\n teal8: \"#53b9ab\",\n teal9: \"#12a594\",\n teal10: \"#0d9b8a\",\n teal11: \"#008573\",\n teal12: \"#0d3d38\",\n};\nconst tealA = {\n tealA1: \"#00cc9905\",\n tealA2: \"#00aa800c\",\n tealA3: \"#00c69d1f\",\n tealA4: \"#00c39633\",\n tealA5: \"#00b49047\",\n tealA6: \"#00a6855e\",\n tealA7: \"#0099807c\",\n tealA8: \"#009783ac\",\n tealA9: \"#009e8ced\",\n tealA10: \"#009684f2\",\n tealA11: \"#008573\",\n tealA12: \"#00332df2\",\n};\nconst tealP3 = {\n teal1: \"color(display-p3 0.983 0.996 0.992)\",\n teal2: \"color(display-p3 0.958 0.983 0.976)\",\n teal3: \"color(display-p3 0.895 0.971 0.952)\",\n teal4: \"color(display-p3 0.831 0.949 0.92)\",\n teal5: \"color(display-p3 0.761 0.914 0.878)\",\n teal6: \"color(display-p3 0.682 0.864 0.825)\",\n teal7: \"color(display-p3 0.581 0.798 0.756)\",\n teal8: \"color(display-p3 0.433 0.716 0.671)\",\n teal9: \"color(display-p3 0.297 0.637 0.581)\",\n teal10: \"color(display-p3 0.275 0.599 0.542)\",\n teal11: \"color(display-p3 0.08 0.5 0.43)\",\n teal12: \"color(display-p3 0.11 0.235 0.219)\",\n};\nconst tealP3A = {\n tealA1: \"color(display-p3 0.024 0.757 0.514 / 0.016)\",\n tealA2: \"color(display-p3 0.02 0.647 0.467 / 0.044)\",\n tealA3: \"color(display-p3 0.004 0.741 0.557 / 0.106)\",\n tealA4: \"color(display-p3 0.004 0.702 0.537 / 0.169)\",\n tealA5: \"color(display-p3 0.004 0.643 0.494 / 0.24)\",\n tealA6: \"color(display-p3 0.004 0.569 0.447 / 0.318)\",\n tealA7: \"color(display-p3 0.004 0.518 0.424 / 0.42)\",\n tealA8: \"color(display-p3 0 0.506 0.424 / 0.569)\",\n tealA9: \"color(display-p3 0 0.482 0.404 / 0.702)\",\n tealA10: \"color(display-p3 0 0.451 0.369 / 0.726)\",\n tealA11: \"color(display-p3 0.08 0.5 0.43)\",\n tealA12: \"color(display-p3 0.11 0.235 0.219)\",\n};\nconst jade = {\n jade1: \"#fbfefd\",\n jade2: \"#f4fbf7\",\n jade3: \"#e6f7ed\",\n jade4: \"#d6f1e3\",\n jade5: \"#c3e9d7\",\n jade6: \"#acdec8\",\n jade7: \"#8bceb6\",\n jade8: \"#56ba9f\",\n jade9: \"#29a383\",\n jade10: \"#26997b\",\n jade11: \"#208368\",\n jade12: \"#1d3b31\",\n};\nconst jadeA = {\n jadeA1: \"#00c08004\",\n jadeA2: \"#00a3460b\",\n jadeA3: \"#00ae4819\",\n jadeA4: \"#00a85129\",\n jadeA5: \"#00a2553c\",\n jadeA6: \"#009a5753\",\n jadeA7: \"#00945f74\",\n jadeA8: \"#00976ea9\",\n jadeA9: \"#00916bd6\",\n jadeA10: \"#008764d9\",\n jadeA11: \"#007152df\",\n jadeA12: \"#002217e2\",\n};\nconst jadeP3 = {\n jade1: \"color(display-p3 0.986 0.996 0.992)\",\n jade2: \"color(display-p3 0.962 0.983 0.969)\",\n jade3: \"color(display-p3 0.912 0.965 0.932)\",\n jade4: \"color(display-p3 0.858 0.941 0.893)\",\n jade5: \"color(display-p3 0.795 0.909 0.847)\",\n jade6: \"color(display-p3 0.715 0.864 0.791)\",\n jade7: \"color(display-p3 0.603 0.802 0.718)\",\n jade8: \"color(display-p3 0.44 0.72 0.629)\",\n jade9: \"color(display-p3 0.319 0.63 0.521)\",\n jade10: \"color(display-p3 0.299 0.592 0.488)\",\n jade11: \"color(display-p3 0.15 0.5 0.37)\",\n jade12: \"color(display-p3 0.142 0.229 0.194)\",\n};\nconst jadeP3A = {\n jadeA1: \"color(display-p3 0.024 0.757 0.514 / 0.016)\",\n jadeA2: \"color(display-p3 0.024 0.612 0.22 / 0.04)\",\n jadeA3: \"color(display-p3 0.012 0.596 0.235 / 0.087)\",\n jadeA4: \"color(display-p3 0.008 0.588 0.255 / 0.142)\",\n jadeA5: \"color(display-p3 0.004 0.561 0.251 / 0.204)\",\n jadeA6: \"color(display-p3 0.004 0.525 0.278 / 0.287)\",\n jadeA7: \"color(display-p3 0.004 0.506 0.29 / 0.397)\",\n jadeA8: \"color(display-p3 0 0.506 0.337 / 0.561)\",\n jadeA9: \"color(display-p3 0 0.459 0.298 / 0.683)\",\n jadeA10: \"color(display-p3 0 0.42 0.271 / 0.702)\",\n jadeA11: \"color(display-p3 0.15 0.5 0.37)\",\n jadeA12: \"color(display-p3 0.142 0.229 0.194)\",\n};\nconst green = {\n green1: \"#fbfefc\",\n green2: \"#f4fbf6\",\n green3: \"#e6f6eb\",\n green4: \"#d6f1df\",\n green5: \"#c4e8d1\",\n green6: \"#adddc0\",\n green7: \"#8eceaa\",\n green8: \"#5bb98b\",\n green9: \"#30a46c\",\n green10: \"#2b9a66\",\n green11: \"#218358\",\n green12: \"#193b2d\",\n};\nconst greenA = {\n greenA1: \"#00c04004\",\n greenA2: \"#00a32f0b\",\n greenA3: \"#00a43319\",\n greenA4: \"#00a83829\",\n greenA5: \"#019c393b\",\n greenA6: \"#00963c52\",\n greenA7: \"#00914071\",\n greenA8: \"#00924ba4\",\n greenA9: \"#008f4acf\",\n greenA10: \"#008647d4\",\n greenA11: \"#00713fde\",\n greenA12: \"#002616e6\",\n};\nconst greenP3 = {\n green1: \"color(display-p3 0.986 0.996 0.989)\",\n green2: \"color(display-p3 0.963 0.983 0.967)\",\n green3: \"color(display-p3 0.913 0.964 0.925)\",\n green4: \"color(display-p3 0.859 0.94 0.879)\",\n green5: \"color(display-p3 0.796 0.907 0.826)\",\n green6: \"color(display-p3 0.718 0.863 0.761)\",\n green7: \"color(display-p3 0.61 0.801 0.675)\",\n green8: \"color(display-p3 0.451 0.715 0.559)\",\n green9: \"color(display-p3 0.332 0.634 0.442)\",\n green10: \"color(display-p3 0.308 0.595 0.417)\",\n green11: \"color(display-p3 0.19 0.5 0.32)\",\n green12: \"color(display-p3 0.132 0.228 0.18)\",\n};\nconst greenP3A = {\n greenA1: \"color(display-p3 0.024 0.757 0.267 / 0.016)\",\n greenA2: \"color(display-p3 0.024 0.565 0.129 / 0.036)\",\n greenA3: \"color(display-p3 0.012 0.596 0.145 / 0.087)\",\n greenA4: \"color(display-p3 0.008 0.588 0.145 / 0.142)\",\n greenA5: \"color(display-p3 0.004 0.541 0.157 / 0.204)\",\n greenA6: \"color(display-p3 0.004 0.518 0.157 / 0.283)\",\n greenA7: \"color(display-p3 0.004 0.486 0.165 / 0.389)\",\n greenA8: \"color(display-p3 0 0.478 0.2 / 0.55)\",\n greenA9: \"color(display-p3 0 0.455 0.165 / 0.667)\",\n greenA10: \"color(display-p3 0 0.416 0.153 / 0.691)\",\n greenA11: \"color(display-p3 0.19 0.5 0.32)\",\n greenA12: \"color(display-p3 0.132 0.228 0.18)\",\n};\nconst grass = {\n grass1: \"#fbfefb\",\n grass2: \"#f5fbf5\",\n grass3: \"#e9f6e9\",\n grass4: \"#daf1db\",\n grass5: \"#c9e8ca\",\n grass6: \"#b2ddb5\",\n grass7: \"#94ce9a\",\n grass8: \"#65ba74\",\n grass9: \"#46a758\",\n grass10: \"#3e9b4f\",\n grass11: \"#2a7e3b\",\n grass12: \"#203c25\",\n};\nconst grassA = {\n grassA1: \"#00c00004\",\n grassA2: \"#0099000a\",\n grassA3: \"#00970016\",\n grassA4: \"#009f0725\",\n grassA5: \"#00930536\",\n grassA6: \"#008f0a4d\",\n grassA7: \"#018b0f6b\",\n grassA8: \"#008d199a\",\n grassA9: \"#008619b9\",\n grassA10: \"#007b17c1\",\n grassA11: \"#006514d5\",\n grassA12: \"#002006df\",\n};\nconst grassP3 = {\n grass1: \"color(display-p3 0.986 0.996 0.985)\",\n grass2: \"color(display-p3 0.966 0.983 0.964)\",\n grass3: \"color(display-p3 0.923 0.965 0.917)\",\n grass4: \"color(display-p3 0.872 0.94 0.865)\",\n grass5: \"color(display-p3 0.811 0.908 0.802)\",\n grass6: \"color(display-p3 0.733 0.864 0.724)\",\n grass7: \"color(display-p3 0.628 0.803 0.622)\",\n grass8: \"color(display-p3 0.477 0.72 0.482)\",\n grass9: \"color(display-p3 0.38 0.647 0.378)\",\n grass10: \"color(display-p3 0.344 0.598 0.342)\",\n grass11: \"color(display-p3 0.263 0.488 0.261)\",\n grass12: \"color(display-p3 0.151 0.233 0.153)\",\n};\nconst grassP3A = {\n grassA1: \"color(display-p3 0.024 0.757 0.024 / 0.016)\",\n grassA2: \"color(display-p3 0.024 0.565 0.024 / 0.036)\",\n grassA3: \"color(display-p3 0.059 0.576 0.008 / 0.083)\",\n grassA4: \"color(display-p3 0.035 0.565 0.008 / 0.134)\",\n grassA5: \"color(display-p3 0.047 0.545 0.008 / 0.197)\",\n grassA6: \"color(display-p3 0.031 0.502 0.004 / 0.275)\",\n grassA7: \"color(display-p3 0.012 0.482 0.004 / 0.377)\",\n grassA8: \"color(display-p3 0 0.467 0.008 / 0.522)\",\n grassA9: \"color(display-p3 0.008 0.435 0 / 0.624)\",\n grassA10: \"color(display-p3 0.008 0.388 0 / 0.659)\",\n grassA11: \"color(display-p3 0.263 0.488 0.261)\",\n grassA12: \"color(display-p3 0.151 0.233 0.153)\",\n};\nconst brown = {\n brown1: \"#fefdfc\",\n brown2: \"#fcf9f6\",\n brown3: \"#f6eee7\",\n brown4: \"#f0e4d9\",\n brown5: \"#ebdaca\",\n brown6: \"#e4cdb7\",\n brown7: \"#dcbc9f\",\n brown8: \"#cea37e\",\n brown9: \"#ad7f58\",\n brown10: \"#a07553\",\n brown11: \"#815e46\",\n brown12: \"#3e332e\",\n};\nconst brownA = {\n brownA1: \"#aa550003\",\n brownA2: \"#aa550009\",\n brownA3: \"#a04b0018\",\n brownA4: \"#9b4a0026\",\n brownA5: \"#9f4d0035\",\n brownA6: \"#a04e0048\",\n brownA7: \"#a34e0060\",\n brownA8: \"#9f4a0081\",\n brownA9: \"#823c00a7\",\n brownA10: \"#723300ac\",\n brownA11: \"#522100b9\",\n brownA12: \"#140600d1\",\n};\nconst brownP3 = {\n brown1: \"color(display-p3 0.995 0.992 0.989)\",\n brown2: \"color(display-p3 0.987 0.976 0.964)\",\n brown3: \"color(display-p3 0.959 0.936 0.909)\",\n brown4: \"color(display-p3 0.934 0.897 0.855)\",\n brown5: \"color(display-p3 0.909 0.856 0.798)\",\n brown6: \"color(display-p3 0.88 0.808 0.73)\",\n brown7: \"color(display-p3 0.841 0.742 0.639)\",\n brown8: \"color(display-p3 0.782 0.647 0.514)\",\n brown9: \"color(display-p3 0.651 0.505 0.368)\",\n brown10: \"color(display-p3 0.601 0.465 0.344)\",\n brown11: \"color(display-p3 0.485 0.374 0.288)\",\n brown12: \"color(display-p3 0.236 0.202 0.183)\",\n};\nconst brownP3A = {\n brownA1: \"color(display-p3 0.675 0.349 0.024 / 0.012)\",\n brownA2: \"color(display-p3 0.675 0.349 0.024 / 0.036)\",\n brownA3: \"color(display-p3 0.573 0.314 0.012 / 0.091)\",\n brownA4: \"color(display-p3 0.545 0.302 0.008 / 0.146)\",\n brownA5: \"color(display-p3 0.561 0.29 0.004 / 0.204)\",\n brownA6: \"color(display-p3 0.553 0.294 0.004 / 0.271)\",\n brownA7: \"color(display-p3 0.557 0.286 0.004 / 0.361)\",\n brownA8: \"color(display-p3 0.549 0.275 0.004 / 0.487)\",\n brownA9: \"color(display-p3 0.447 0.22 0 / 0.632)\",\n brownA10: \"color(display-p3 0.388 0.188 0 / 0.655)\",\n brownA11: \"color(display-p3 0.485 0.374 0.288)\",\n brownA12: \"color(display-p3 0.236 0.202 0.183)\",\n};\nconst bronze = {\n bronze1: \"#fdfcfc\",\n bronze2: \"#fdf7f5\",\n bronze3: \"#f6edea\",\n bronze4: \"#efe4df\",\n bronze5: \"#e7d9d3\",\n bronze6: \"#dfcdc5\",\n bronze7: \"#d3bcb3\",\n bronze8: \"#c2a499\",\n bronze9: \"#a18072\",\n bronze10: \"#957468\",\n bronze11: \"#7d5e54\",\n bronze12: \"#43302b\",\n};\nconst bronzeA = {\n bronzeA1: \"#55000003\",\n bronzeA2: \"#cc33000a\",\n bronzeA3: \"#92250015\",\n bronzeA4: \"#80280020\",\n bronzeA5: \"#7423002c\",\n bronzeA6: \"#7324003a\",\n bronzeA7: \"#6c1f004c\",\n bronzeA8: \"#671c0066\",\n bronzeA9: \"#551a008d\",\n bronzeA10: \"#4c150097\",\n bronzeA11: \"#3d0f00ab\",\n bronzeA12: \"#1d0600d4\",\n};\nconst bronzeP3 = {\n bronze1: \"color(display-p3 0.991 0.988 0.988)\",\n bronze2: \"color(display-p3 0.989 0.97 0.961)\",\n bronze3: \"color(display-p3 0.958 0.932 0.919)\",\n bronze4: \"color(display-p3 0.929 0.894 0.877)\",\n bronze5: \"color(display-p3 0.898 0.853 0.832)\",\n bronze6: \"color(display-p3 0.861 0.805 0.778)\",\n bronze7: \"color(display-p3 0.812 0.739 0.706)\",\n bronze8: \"color(display-p3 0.741 0.647 0.606)\",\n bronze9: \"color(display-p3 0.611 0.507 0.455)\",\n bronze10: \"color(display-p3 0.563 0.461 0.414)\",\n bronze11: \"color(display-p3 0.471 0.373 0.336)\",\n bronze12: \"color(display-p3 0.251 0.191 0.172)\",\n};\nconst bronzeP3A = {\n bronzeA1: \"color(display-p3 0.349 0.024 0.024 / 0.012)\",\n bronzeA2: \"color(display-p3 0.71 0.22 0.024 / 0.04)\",\n bronzeA3: \"color(display-p3 0.482 0.2 0.008 / 0.083)\",\n bronzeA4: \"color(display-p3 0.424 0.133 0.004 / 0.122)\",\n bronzeA5: \"color(display-p3 0.4 0.145 0.004 / 0.169)\",\n bronzeA6: \"color(display-p3 0.388 0.125 0.004 / 0.224)\",\n bronzeA7: \"color(display-p3 0.365 0.11 0.004 / 0.295)\",\n bronzeA8: \"color(display-p3 0.341 0.102 0.004 / 0.393)\",\n bronzeA9: \"color(display-p3 0.29 0.094 0 / 0.546)\",\n bronzeA10: \"color(display-p3 0.255 0.082 0 / 0.585)\",\n bronzeA11: \"color(display-p3 0.471 0.373 0.336)\",\n bronzeA12: \"color(display-p3 0.251 0.191 0.172)\",\n};\nconst gold = {\n gold1: \"#fdfdfc\",\n gold2: \"#faf9f2\",\n gold3: \"#f2f0e7\",\n gold4: \"#eae6db\",\n gold5: \"#e1dccf\",\n gold6: \"#d8d0bf\",\n gold7: \"#cbc0aa\",\n gold8: \"#b9a88d\",\n gold9: \"#978365\",\n gold10: \"#8c7a5e\",\n gold11: \"#71624b\",\n gold12: \"#3b352b\",\n};\nconst goldA = {\n goldA1: \"#55550003\",\n goldA2: \"#9d8a000d\",\n goldA3: \"#75600018\",\n goldA4: \"#6b4e0024\",\n goldA5: \"#60460030\",\n goldA6: \"#64440040\",\n goldA7: \"#63420055\",\n goldA8: \"#633d0072\",\n goldA9: \"#5332009a\",\n goldA10: \"#492d00a1\",\n goldA11: \"#362100b4\",\n goldA12: \"#130c00d4\",\n};\nconst goldP3 = {\n gold1: \"color(display-p3 0.992 0.992 0.989)\",\n gold2: \"color(display-p3 0.98 0.976 0.953)\",\n gold3: \"color(display-p3 0.947 0.94 0.909)\",\n gold4: \"color(display-p3 0.914 0.904 0.865)\",\n gold5: \"color(display-p3 0.88 0.865 0.816)\",\n gold6: \"color(display-p3 0.84 0.818 0.756)\",\n gold7: \"color(display-p3 0.788 0.753 0.677)\",\n gold8: \"color(display-p3 0.715 0.66 0.565)\",\n gold9: \"color(display-p3 0.579 0.517 0.41)\",\n gold10: \"color(display-p3 0.538 0.479 0.38)\",\n gold11: \"color(display-p3 0.433 0.386 0.305)\",\n gold12: \"color(display-p3 0.227 0.209 0.173)\",\n};\nconst goldP3A = {\n goldA1: \"color(display-p3 0.349 0.349 0.024 / 0.012)\",\n goldA2: \"color(display-p3 0.592 0.514 0.024 / 0.048)\",\n goldA3: \"color(display-p3 0.4 0.357 0.012 / 0.091)\",\n goldA4: \"color(display-p3 0.357 0.298 0.008 / 0.134)\",\n goldA5: \"color(display-p3 0.345 0.282 0.004 / 0.185)\",\n goldA6: \"color(display-p3 0.341 0.263 0.004 / 0.244)\",\n goldA7: \"color(display-p3 0.345 0.235 0.004 / 0.322)\",\n goldA8: \"color(display-p3 0.345 0.22 0.004 / 0.436)\",\n goldA9: \"color(display-p3 0.286 0.18 0 / 0.589)\",\n goldA10: \"color(display-p3 0.255 0.161 0 / 0.62)\",\n goldA11: \"color(display-p3 0.433 0.386 0.305)\",\n goldA12: \"color(display-p3 0.227 0.209 0.173)\",\n};\nconst sky = {\n sky1: \"#f9feff\",\n sky2: \"#f1fafd\",\n sky3: \"#e1f6fd\",\n sky4: \"#d1f0fa\",\n sky5: \"#bee7f5\",\n sky6: \"#a9daed\",\n sky7: \"#8dcae3\",\n sky8: \"#60b3d7\",\n sky9: \"#7ce2fe\",\n sky10: \"#74daf8\",\n sky11: \"#00749e\",\n sky12: \"#1d3e56\",\n};\nconst skyA = {\n skyA1: \"#00d5ff06\",\n skyA2: \"#00a4db0e\",\n skyA3: \"#00b3ee1e\",\n skyA4: \"#00ace42e\",\n skyA5: \"#00a1d841\",\n skyA6: \"#0092ca56\",\n skyA7: \"#0089c172\",\n skyA8: \"#0085bf9f\",\n skyA9: \"#00c7fe83\",\n skyA10: \"#00bcf38b\",\n skyA11: \"#00749e\",\n skyA12: \"#002540e2\",\n};\nconst skyP3 = {\n sky1: \"color(display-p3 0.98 0.995 0.999)\",\n sky2: \"color(display-p3 0.953 0.98 0.99)\",\n sky3: \"color(display-p3 0.899 0.963 0.989)\",\n sky4: \"color(display-p3 0.842 0.937 0.977)\",\n sky5: \"color(display-p3 0.777 0.9 0.954)\",\n sky6: \"color(display-p3 0.701 0.851 0.921)\",\n sky7: \"color(display-p3 0.604 0.785 0.879)\",\n sky8: \"color(display-p3 0.457 0.696 0.829)\",\n sky9: \"color(display-p3 0.585 0.877 0.983)\",\n sky10: \"color(display-p3 0.555 0.845 0.959)\",\n sky11: \"color(display-p3 0.193 0.448 0.605)\",\n sky12: \"color(display-p3 0.145 0.241 0.329)\",\n};\nconst skyP3A = {\n skyA1: \"color(display-p3 0.02 0.804 1 / 0.02)\",\n skyA2: \"color(display-p3 0.024 0.592 0.757 / 0.048)\",\n skyA3: \"color(display-p3 0.004 0.655 0.886 / 0.102)\",\n skyA4: \"color(display-p3 0.004 0.604 0.851 / 0.157)\",\n skyA5: \"color(display-p3 0.004 0.565 0.792 / 0.224)\",\n skyA6: \"color(display-p3 0.004 0.502 0.737 / 0.299)\",\n skyA7: \"color(display-p3 0.004 0.459 0.694 / 0.397)\",\n skyA8: \"color(display-p3 0 0.435 0.682 / 0.542)\",\n skyA9: \"color(display-p3 0.004 0.71 0.965 / 0.416)\",\n skyA10: \"color(display-p3 0.004 0.647 0.914 / 0.444)\",\n skyA11: \"color(display-p3 0.193 0.448 0.605)\",\n skyA12: \"color(display-p3 0.145 0.241 0.329)\",\n};\nconst mint = {\n mint1: \"#f9fefd\",\n mint2: \"#f2fbf9\",\n mint3: \"#ddf9f2\",\n mint4: \"#c8f4e9\",\n mint5: \"#b3ecde\",\n mint6: \"#9ce0d0\",\n mint7: \"#7ecfbd\",\n mint8: \"#4cbba5\",\n mint9: \"#86ead4\",\n mint10: \"#7de0cb\",\n mint11: \"#027864\",\n mint12: \"#16433c\",\n};\nconst mintA = {\n mintA1: \"#00d5aa06\",\n mintA2: \"#00b18a0d\",\n mintA3: \"#00d29e22\",\n mintA4: \"#00cc9937\",\n mintA5: \"#00c0914c\",\n mintA6: \"#00b08663\",\n mintA7: \"#00a17d81\",\n mintA8: \"#009e7fb3\",\n mintA9: \"#00d3a579\",\n mintA10: \"#00c39982\",\n mintA11: \"#007763fd\",\n mintA12: \"#00312ae9\",\n};\nconst mintP3 = {\n mint1: \"color(display-p3 0.98 0.995 0.992)\",\n mint2: \"color(display-p3 0.957 0.985 0.977)\",\n mint3: \"color(display-p3 0.888 0.972 0.95)\",\n mint4: \"color(display-p3 0.819 0.951 0.916)\",\n mint5: \"color(display-p3 0.747 0.918 0.873)\",\n mint6: \"color(display-p3 0.668 0.87 0.818)\",\n mint7: \"color(display-p3 0.567 0.805 0.744)\",\n mint8: \"color(display-p3 0.42 0.724 0.649)\",\n mint9: \"color(display-p3 0.62 0.908 0.834)\",\n mint10: \"color(display-p3 0.585 0.871 0.797)\",\n mint11: \"color(display-p3 0.203 0.463 0.397)\",\n mint12: \"color(display-p3 0.136 0.259 0.236)\",\n};\nconst mintP3A = {\n mintA1: \"color(display-p3 0.02 0.804 0.608 / 0.02)\",\n mintA2: \"color(display-p3 0.02 0.647 0.467 / 0.044)\",\n mintA3: \"color(display-p3 0.004 0.761 0.553 / 0.114)\",\n mintA4: \"color(display-p3 0.004 0.741 0.545 / 0.181)\",\n mintA5: \"color(display-p3 0.004 0.678 0.51 / 0.255)\",\n mintA6: \"color(display-p3 0.004 0.616 0.463 / 0.334)\",\n mintA7: \"color(display-p3 0.004 0.549 0.412 / 0.432)\",\n mintA8: \"color(display-p3 0 0.529 0.392 / 0.581)\",\n mintA9: \"color(display-p3 0.004 0.765 0.569 / 0.381)\",\n mintA10: \"color(display-p3 0.004 0.69 0.51 / 0.416)\",\n mintA11: \"color(display-p3 0.203 0.463 0.397)\",\n mintA12: \"color(display-p3 0.136 0.259 0.236)\",\n};\nconst lime = {\n lime1: \"#fcfdfa\",\n lime2: \"#f8faf3\",\n lime3: \"#eef6d6\",\n lime4: \"#e2f0bd\",\n lime5: \"#d3e7a6\",\n lime6: \"#c2da91\",\n lime7: \"#abc978\",\n lime8: \"#8db654\",\n lime9: \"#bdee63\",\n lime10: \"#b0e64c\",\n lime11: \"#5c7c2f\",\n lime12: \"#37401c\",\n};\nconst limeA = {\n limeA1: \"#66990005\",\n limeA2: \"#6b95000c\",\n limeA3: \"#96c80029\",\n limeA4: \"#8fc60042\",\n limeA5: \"#81bb0059\",\n limeA6: \"#72aa006e\",\n limeA7: \"#61990087\",\n limeA8: \"#559200ab\",\n limeA9: \"#93e4009c\",\n limeA10: \"#8fdc00b3\",\n limeA11: \"#375f00d0\",\n limeA12: \"#1e2900e3\",\n};\nconst limeP3 = {\n lime1: \"color(display-p3 0.989 0.992 0.981)\",\n lime2: \"color(display-p3 0.975 0.98 0.954)\",\n lime3: \"color(display-p3 0.939 0.965 0.851)\",\n lime4: \"color(display-p3 0.896 0.94 0.76)\",\n lime5: \"color(display-p3 0.843 0.903 0.678)\",\n lime6: \"color(display-p3 0.778 0.852 0.599)\",\n lime7: \"color(display-p3 0.694 0.784 0.508)\",\n lime8: \"color(display-p3 0.585 0.707 0.378)\",\n lime9: \"color(display-p3 0.78 0.928 0.466)\",\n lime10: \"color(display-p3 0.734 0.896 0.397)\",\n lime11: \"color(display-p3 0.386 0.482 0.227)\",\n lime12: \"color(display-p3 0.222 0.25 0.128)\",\n};\nconst limeP3A = {\n limeA1: \"color(display-p3 0.412 0.608 0.02 / 0.02)\",\n limeA2: \"color(display-p3 0.514 0.592 0.024 / 0.048)\",\n limeA3: \"color(display-p3 0.584 0.765 0.008 / 0.15)\",\n limeA4: \"color(display-p3 0.561 0.757 0.004 / 0.24)\",\n limeA5: \"color(display-p3 0.514 0.698 0.004 / 0.322)\",\n limeA6: \"color(display-p3 0.443 0.627 0 / 0.4)\",\n limeA7: \"color(display-p3 0.376 0.561 0.004 / 0.491)\",\n limeA8: \"color(display-p3 0.333 0.529 0 / 0.624)\",\n limeA9: \"color(display-p3 0.588 0.867 0 / 0.534)\",\n limeA10: \"color(display-p3 0.561 0.827 0 / 0.604)\",\n limeA11: \"color(display-p3 0.386 0.482 0.227)\",\n limeA12: \"color(display-p3 0.222 0.25 0.128)\",\n};\nconst yellow = {\n yellow1: \"#fdfdf9\",\n yellow2: \"#fefce9\",\n yellow3: \"#fffab8\",\n yellow4: \"#fff394\",\n yellow5: \"#ffe770\",\n yellow6: \"#f3d768\",\n yellow7: \"#e4c767\",\n yellow8: \"#d5ae39\",\n yellow9: \"#ffe629\",\n yellow10: \"#ffdc00\",\n yellow11: \"#9e6c00\",\n yellow12: \"#473b1f\",\n};\nconst yellowA = {\n yellowA1: \"#aaaa0006\",\n yellowA2: \"#f4dd0016\",\n yellowA3: \"#ffee0047\",\n yellowA4: \"#ffe3016b\",\n yellowA5: \"#ffd5008f\",\n yellowA6: \"#ebbc0097\",\n yellowA7: \"#d2a10098\",\n yellowA8: \"#c99700c6\",\n yellowA9: \"#ffe100d6\",\n yellowA10: \"#ffdc00\",\n yellowA11: \"#9e6c00\",\n yellowA12: \"#2e2000e0\",\n};\nconst yellowP3 = {\n yellow1: \"color(display-p3 0.992 0.992 0.978)\",\n yellow2: \"color(display-p3 0.995 0.99 0.922)\",\n yellow3: \"color(display-p3 0.997 0.982 0.749)\",\n yellow4: \"color(display-p3 0.992 0.953 0.627)\",\n yellow5: \"color(display-p3 0.984 0.91 0.51)\",\n yellow6: \"color(display-p3 0.934 0.847 0.474)\",\n yellow7: \"color(display-p3 0.876 0.785 0.46)\",\n yellow8: \"color(display-p3 0.811 0.689 0.313)\",\n yellow9: \"color(display-p3 1 0.92 0.22)\",\n yellow10: \"color(display-p3 0.977 0.868 0.291)\",\n yellow11: \"color(display-p3 0.6 0.44 0)\",\n yellow12: \"color(display-p3 0.271 0.233 0.137)\",\n};\nconst yellowP3A = {\n yellowA1: \"color(display-p3 0.675 0.675 0.024 / 0.024)\",\n yellowA2: \"color(display-p3 0.953 0.855 0.008 / 0.079)\",\n yellowA3: \"color(display-p3 0.988 0.925 0.004 / 0.251)\",\n yellowA4: \"color(display-p3 0.98 0.875 0.004 / 0.373)\",\n yellowA5: \"color(display-p3 0.969 0.816 0.004 / 0.491)\",\n yellowA6: \"color(display-p3 0.875 0.71 0 / 0.526)\",\n yellowA7: \"color(display-p3 0.769 0.604 0 / 0.542)\",\n yellowA8: \"color(display-p3 0.725 0.549 0 / 0.687)\",\n yellowA9: \"color(display-p3 1 0.898 0 / 0.781)\",\n yellowA10: \"color(display-p3 0.969 0.812 0 / 0.71)\",\n yellowA11: \"color(display-p3 0.6 0.44 0)\",\n yellowA12: \"color(display-p3 0.271 0.233 0.137)\",\n};\nconst amber = {\n amber1: \"#fefdfb\",\n amber2: \"#fefbe9\",\n amber3: \"#fff7c2\",\n amber4: \"#ffee9c\",\n amber5: \"#fbe577\",\n amber6: \"#f3d673\",\n amber7: \"#e9c162\",\n amber8: \"#e2a336\",\n amber9: \"#ffc53d\",\n amber10: \"#ffba18\",\n amber11: \"#ab6400\",\n amber12: \"#4f3422\",\n};\nconst amberA = {\n amberA1: \"#c0800004\",\n amberA2: \"#f4d10016\",\n amberA3: \"#ffde003d\",\n amberA4: \"#ffd40063\",\n amberA5: \"#f8cf0088\",\n amberA6: \"#eab5008c\",\n amberA7: \"#dc9b009d\",\n amberA8: \"#da8a00c9\",\n amberA9: \"#ffb300c2\",\n amberA10: \"#ffb300e7\",\n amberA11: \"#ab6400\",\n amberA12: \"#341500dd\",\n};\nconst amberP3 = {\n amber1: \"color(display-p3 0.995 0.992 0.985)\",\n amber2: \"color(display-p3 0.994 0.986 0.921)\",\n amber3: \"color(display-p3 0.994 0.969 0.782)\",\n amber4: \"color(display-p3 0.989 0.937 0.65)\",\n amber5: \"color(display-p3 0.97 0.902 0.527)\",\n amber6: \"color(display-p3 0.936 0.844 0.506)\",\n amber7: \"color(display-p3 0.89 0.762 0.443)\",\n amber8: \"color(display-p3 0.85 0.65 0.3)\",\n amber9: \"color(display-p3 1 0.77 0.26)\",\n amber10: \"color(display-p3 0.959 0.741 0.274)\",\n amber11: \"color(display-p3 0.64 0.4 0)\",\n amber12: \"color(display-p3 0.294 0.208 0.145)\",\n};\nconst amberP3A = {\n amberA1: \"color(display-p3 0.757 0.514 0.024 / 0.016)\",\n amberA2: \"color(display-p3 0.902 0.804 0.008 / 0.079)\",\n amberA3: \"color(display-p3 0.965 0.859 0.004 / 0.22)\",\n amberA4: \"color(display-p3 0.969 0.82 0.004 / 0.35)\",\n amberA5: \"color(display-p3 0.933 0.796 0.004 / 0.475)\",\n amberA6: \"color(display-p3 0.875 0.682 0.004 / 0.495)\",\n amberA7: \"color(display-p3 0.804 0.573 0 / 0.557)\",\n amberA8: \"color(display-p3 0.788 0.502 0 / 0.699)\",\n amberA9: \"color(display-p3 1 0.686 0 / 0.742)\",\n amberA10: \"color(display-p3 0.945 0.643 0 / 0.726)\",\n amberA11: \"color(display-p3 0.64 0.4 0)\",\n amberA12: \"color(display-p3 0.294 0.208 0.145)\",\n};\nconst orange = {\n orange1: \"#fefcfb\",\n orange2: \"#fff7ed\",\n orange3: \"#ffefd6\",\n orange4: \"#ffdfb5\",\n orange5: \"#ffd19a\",\n orange6: \"#ffc182\",\n orange7: \"#f5ae73\",\n orange8: \"#ec9455\",\n orange9: \"#f76b15\",\n orange10: \"#ef5f00\",\n orange11: \"#cc4e00\",\n orange12: \"#582d1d\",\n};\nconst orangeA = {\n orangeA1: \"#c0400004\",\n orangeA2: \"#ff8e0012\",\n orangeA3: \"#ff9c0029\",\n orangeA4: \"#ff91014a\",\n orangeA5: \"#ff8b0065\",\n orangeA6: \"#ff81007d\",\n orangeA7: \"#ed6c008c\",\n orangeA8: \"#e35f00aa\",\n orangeA9: \"#f65e00ea\",\n orangeA10: \"#ef5f00\",\n orangeA11: \"#cc4e00\",\n orangeA12: \"#431200e2\",\n};\nconst orangeP3 = {\n orange1: \"color(display-p3 0.995 0.988 0.985)\",\n orange2: \"color(display-p3 0.994 0.968 0.934)\",\n orange3: \"color(display-p3 0.989 0.938 0.85)\",\n orange4: \"color(display-p3 1 0.874 0.687)\",\n orange5: \"color(display-p3 1 0.821 0.583)\",\n orange6: \"color(display-p3 0.975 0.767 0.545)\",\n orange7: \"color(display-p3 0.919 0.693 0.486)\",\n orange8: \"color(display-p3 0.877 0.597 0.379)\",\n orange9: \"color(display-p3 0.9 0.45 0.2)\",\n orange10: \"color(display-p3 0.87 0.409 0.164)\",\n orange11: \"color(display-p3 0.76 0.34 0)\",\n orange12: \"color(display-p3 0.323 0.185 0.127)\",\n};\nconst orangeP3A = {\n orangeA1: \"color(display-p3 0.757 0.267 0.024 / 0.016)\",\n orangeA2: \"color(display-p3 0.886 0.533 0.008 / 0.067)\",\n orangeA3: \"color(display-p3 0.922 0.584 0.008 / 0.15)\",\n orangeA4: \"color(display-p3 1 0.604 0.004 / 0.314)\",\n orangeA5: \"color(display-p3 1 0.569 0.004 / 0.416)\",\n orangeA6: \"color(display-p3 0.949 0.494 0.004 / 0.455)\",\n orangeA7: \"color(display-p3 0.839 0.408 0 / 0.514)\",\n orangeA8: \"color(display-p3 0.804 0.349 0 / 0.62)\",\n orangeA9: \"color(display-p3 0.878 0.314 0 / 0.8)\",\n orangeA10: \"color(display-p3 0.843 0.29 0 / 0.836)\",\n orangeA11: \"color(display-p3 0.76 0.34 0)\",\n orangeA12: \"color(display-p3 0.323 0.185 0.127)\",\n};\n\nconst blackA = {\n blackA1: \"rgba(0, 0, 0, 0.05)\",\n blackA2: \"rgba(0, 0, 0, 0.1)\",\n blackA3: \"rgba(0, 0, 0, 0.15)\",\n blackA4: \"rgba(0, 0, 0, 0.2)\",\n blackA5: \"rgba(0, 0, 0, 0.3)\",\n blackA6: \"rgba(0, 0, 0, 0.4)\",\n blackA7: \"rgba(0, 0, 0, 0.5)\",\n blackA8: \"rgba(0, 0, 0, 0.6)\",\n blackA9: \"rgba(0, 0, 0, 0.7)\",\n blackA10: \"rgba(0, 0, 0, 0.8)\",\n blackA11: \"rgba(0, 0, 0, 0.9)\",\n blackA12: \"rgba(0, 0, 0, 0.95)\",\n};\nconst blackP3A = {\n blackA1: \"color(display-p3 0 0 0 / 0.05)\",\n blackA2: \"color(display-p3 0 0 0 / 0.1)\",\n blackA3: \"color(display-p3 0 0 0 / 0.15)\",\n blackA4: \"color(display-p3 0 0 0 / 0.2)\",\n blackA5: \"color(display-p3 0 0 0 / 0.3)\",\n blackA6: \"color(display-p3 0 0 0 / 0.4)\",\n blackA7: \"color(display-p3 0 0 0 / 0.5)\",\n blackA8: \"color(display-p3 0 0 0 / 0.6)\",\n blackA9: \"color(display-p3 0 0 0 / 0.7)\",\n blackA10: \"color(display-p3 0 0 0 / 0.8)\",\n blackA11: \"color(display-p3 0 0 0 / 0.9)\",\n blackA12: \"color(display-p3 0 0 0 / 0.95)\",\n};\n\nconst whiteA = {\n whiteA1: \"rgba(255, 255, 255, 0.05)\",\n whiteA2: \"rgba(255, 255, 255, 0.1)\",\n whiteA3: \"rgba(255, 255, 255, 0.15)\",\n whiteA4: \"rgba(255, 255, 255, 0.2)\",\n whiteA5: \"rgba(255, 255, 255, 0.3)\",\n whiteA6: \"rgba(255, 255, 255, 0.4)\",\n whiteA7: \"rgba(255, 255, 255, 0.5)\",\n whiteA8: \"rgba(255, 255, 255, 0.6)\",\n whiteA9: \"rgba(255, 255, 255, 0.7)\",\n whiteA10: \"rgba(255, 255, 255, 0.8)\",\n whiteA11: \"rgba(255, 255, 255, 0.9)\",\n whiteA12: \"rgba(255, 255, 255, 0.95)\",\n};\nconst whiteP3A = {\n whiteA1: \"color(display-p3 1 1 1 / 0.05)\",\n whiteA2: \"color(display-p3 1 1 1 / 0.1)\",\n whiteA3: \"color(display-p3 1 1 1 / 0.15)\",\n whiteA4: \"color(display-p3 1 1 1 / 0.2)\",\n whiteA5: \"color(display-p3 1 1 1 / 0.3)\",\n whiteA6: \"color(display-p3 1 1 1 / 0.4)\",\n whiteA7: \"color(display-p3 1 1 1 / 0.5)\",\n whiteA8: \"color(display-p3 1 1 1 / 0.6)\",\n whiteA9: \"color(display-p3 1 1 1 / 0.7)\",\n whiteA10: \"color(display-p3 1 1 1 / 0.8)\",\n whiteA11: \"color(display-p3 1 1 1 / 0.9)\",\n whiteA12: \"color(display-p3 1 1 1 / 0.95)\",\n};\n\nexport { amber, amberA, amberDark, amberDarkA, amberDarkP3, amberDarkP3A, amberP3, amberP3A, blackA, blackP3A, blue, blueA, blueDark, blueDarkA, blueDarkP3, blueDarkP3A, blueP3, blueP3A, bronze, bronzeA, bronzeDark, bronzeDarkA, bronzeDarkP3, bronzeDarkP3A, bronzeP3, bronzeP3A, brown, brownA, brownDark, brownDarkA, brownDarkP3, brownDarkP3A, brownP3, brownP3A, crimson, crimsonA, crimsonDark, crimsonDarkA, crimsonDarkP3, crimsonDarkP3A, crimsonP3, crimsonP3A, cyan, cyanA, cyanDark, cyanDarkA, cyanDarkP3, cyanDarkP3A, cyanP3, cyanP3A, gold, goldA, goldDark, goldDarkA, goldDarkP3, goldDarkP3A, goldP3, goldP3A, grass, grassA, grassDark, grassDarkA, grassDarkP3, grassDarkP3A, grassP3, grassP3A, gray, grayA, grayDark, grayDarkA, grayDarkP3, grayDarkP3A, grayP3, grayP3A, green, greenA, greenDark, greenDarkA, greenDarkP3, greenDarkP3A, greenP3, greenP3A, indigo, indigoA, indigoDark, indigoDarkA, indigoDarkP3, indigoDarkP3A, indigoP3, indigoP3A, iris, irisA, irisDark, irisDarkA, irisDarkP3, irisDarkP3A, irisP3, irisP3A, jade, jadeA, jadeDark, jadeDarkA, jadeDarkP3, jadeDarkP3A, jadeP3, jadeP3A, lime, limeA, limeDark, limeDarkA, limeDarkP3, limeDarkP3A, limeP3, limeP3A, mauve, mauveA, mauveDark, mauveDarkA, mauveDarkP3, mauveDarkP3A, mauveP3, mauveP3A, mint, mintA, mintDark, mintDarkA, mintDarkP3, mintDarkP3A, mintP3, mintP3A, olive, oliveA, oliveDark, oliveDarkA, oliveDarkP3, oliveDarkP3A, oliveP3, oliveP3A, orange, orangeA, orangeDark, orangeDarkA, orangeDarkP3, orangeDarkP3A, orangeP3, orangeP3A, pink, pinkA, pinkDark, pinkDarkA, pinkDarkP3, pinkDarkP3A, pinkP3, pinkP3A, plum, plumA, plumDark, plumDarkA, plumDarkP3, plumDarkP3A, plumP3, plumP3A, purple, purpleA, purpleDark, purpleDarkA, purpleDarkP3, purpleDarkP3A, purpleP3, purpleP3A, red, redA, redDark, redDarkA, redDarkP3, redDarkP3A, redP3, redP3A, ruby, rubyA, rubyDark, rubyDarkA, rubyDarkP3, rubyDarkP3A, rubyP3, rubyP3A, sage, sageA, sageDark, sageDarkA, sageDarkP3, sageDarkP3A, sageP3, sageP3A, sand, sandA, sandDark, sandDarkA, sandDarkP3, sandDarkP3A, sandP3, sandP3A, sky, skyA, skyDark, skyDarkA, skyDarkP3, skyDarkP3A, skyP3, skyP3A, slate, slateA, slateDark, slateDarkA, slateDarkP3, slateDarkP3A, slateP3, slateP3A, teal, tealA, tealDark, tealDarkA, tealDarkP3, tealDarkP3A, tealP3, tealP3A, tomato, tomatoA, tomatoDark, tomatoDarkA, tomatoDarkP3, tomatoDarkP3A, tomatoP3, tomatoP3A, violet, violetA, violetDark, violetDarkA, violetDarkP3, violetDarkP3A, violetP3, violetP3A, whiteA, whiteP3A, yellow, yellowA, yellowDark, yellowDarkA, yellowDarkP3, yellowDarkP3A, yellowP3, yellowP3A };\n","import { default as ColorCls } from \"color\"\r\nimport {\r\n\tgray,\r\n\tgold,\r\n\tbrown,\r\n\tyellow,\r\n\tamber,\r\n\torange,\r\n\tred,\r\n\tcrimson,\r\n\tpink,\r\n\tplum,\r\n\tpurple,\r\n\tviolet,\r\n\tiris,\r\n\tindigo,\r\n\tblue,\r\n\tcyan,\r\n\tjade,\r\n\tgrass,\r\n\tlime,\r\n\tmint,\r\n\tsky,\r\n} from \"@radix-ui/colors\"\r\nimport { CSSColor } from \"../typings\"\r\n\r\n// TODO: Move most of these constants into src/theme/variables.ts\r\nexport const primaryColor: CSSColor = \"#2D55E2\"\r\nexport const successColor: CSSColor = \"#349C55\"\r\nexport const warningColor: CSSColor = \"#FFA620\"\r\nexport const errorColor: CSSColor = \"#E24C4C\"\r\nexport const GREEN: CSSColor = \"#1fd155\"\r\nexport const YELLOW: CSSColor = \"#f5de14\"\r\nexport interface BadgeColors {\r\n\tbackgroundColor: CSSColor\r\n\ttextColor: CSSColor\r\n}\r\n\r\n// Colors used for color selection purposes\r\nexport const Colors: Record<string, CSSColor> = {\r\n\tgray: (gray as Record<string, CSSColor>).gray9!,\r\n\tgold: (gold as Record<string, CSSColor>).gold9!,\r\n\tbrown: (brown as Record<string, CSSColor>).brown9!,\r\n\tyellow: (yellow as Record<string, CSSColor>).yellow9!,\r\n\tamber: (amber as Record<string, CSSColor>).amber9!,\r\n\torange: (orange as Record<string, CSSColor>).orange9!,\r\n\tred: (red as Record<string, CSSColor>).red9!,\r\n\tcrimson: (crimson as Record<string, CSSColor>).crimson9!,\r\n\tpink: (pink as Record<string, CSSColor>).pink9!,\r\n\tplum: (plum as Record<string, CSSColor>).plum9!,\r\n\tpurple: (purple as Record<string, CSSColor>).purple9!,\r\n\tviolet: (violet as Record<string, CSSColor>).violet9!,\r\n\tiris: (iris as Record<string, CSSColor>).iris9!,\r\n\tindigo: (indigo as Record<string, CSSColor>).indigo9!,\r\n\tblue: (blue as Record<string, CSSColor>).blue9!,\r\n\tcyan: (cyan as Record<string, CSSColor>).cyan9!,\r\n\tjade: (jade as Record<string, CSSColor>).jade9!,\r\n\tgrass: (grass as Record<string, CSSColor>).grass9!,\r\n\tlime: (lime as Record<string, CSSColor>).lime9!,\r\n\tmint: (mint as Record<string, CSSColor>).mint9!,\r\n\tsky: (sky as Record<string, CSSColor>).sky9!,\r\n}\r\n\r\n// Colors used for component stages\r\nexport const ComponentStageColors: Record<string, CSSColor> = {\r\n\tindigo: (indigo as Record<string, CSSColor>).indigo9!,\r\n\tred: (red as Record<string, CSSColor>).red9!,\r\n\tviolet: (violet as Record<string, CSSColor>).violet9!,\r\n\tyellow: (yellow as Record<string, CSSColor>).yellow9!,\r\n\tjade: (jade as Record<string, CSSColor>).jade9!,\r\n\tcyan: (cyan as Record<string, CSSColor>).cyan9!,\r\n\tgold: (gold as Record<string, CSSColor>).gold9!,\r\n\torange: (orange as Record<string, CSSColor>).orange9!,\r\n\tlime: (lime as Record<string, CSSColor>).lime9!,\r\n\tsky: (sky as Record<string, CSSColor>).sky9!,\r\n\tpink: (pink as Record<string, CSSColor>).pink9!,\r\n}\r\n\r\nexport const defaultBadgeColor: CSSColor = \"#868686\"\r\n\r\n// This function adjusts a given colour into two variations for use as badge colours\r\nexport const generateBadgeColors = (rawColor: CSSColor): BadgeColors => {\r\n\tconst color = ColorCls(rawColor)\r\n\tconst safety = ColorCls(YELLOW)\r\n\tconst backgroundColor: CSSColor = color.darken(0.09).hex() as CSSColor\r\n\t// If the color matches the special yellow safety color, make the text black\r\n\tconst textColor = color.hex() === safety.hex() ? \"#000000\" : \"#FFFFFF\"\r\n\t// Alternate style:\r\n\t// const backgroundColor = color.lighten(0.4).hex()\r\n\t// const textColor = color.darken(0.6).hex()\r\n\r\n\treturn { backgroundColor, textColor }\r\n}\r\n\r\nexport function getStageColor(index: number): CSSColor {\r\n\treturn Object.values(ComponentStageColors)[index % Object.keys(ComponentStageColors).length]!\r\n}\r\n","import { memoize } from \"./optimization\"\r\n\r\n/** Only shows year if a past year */\r\nexport const getLocalDateString = memoize((date?: string | null | Date | number) => {\r\n\tif (!date) return \"\"\r\n\tconst asDate = new Date(date)\r\n\tconst isThisYear = asDate.getFullYear() === today.getFullYear()\r\n\tconst options: Intl.DateTimeFormatOptions = { day: \"numeric\", month: \"short\" }\r\n\tif (!isThisYear) options.year = \"numeric\"\r\n\treturn asDate.toLocaleDateString([], options)\r\n})\r\n\r\nconst relative = new Intl.RelativeTimeFormat([], { style: \"long\", numeric: \"auto\" })\r\nconst msInDay = 1000 * 86400\r\nconst today = new Date()\r\n\r\n/** Returns true if the given date is today */\r\nexport const isToday = (date: string | Date | number) => {\r\n\treturn new Date(date).toDateString() === today.toDateString()\r\n}\r\n\r\n/*\r\nDisplays a relative message \"in 2 days\" or \"today\" if within the given period (min, max)\r\nOtherwise, falls back to getLocalDateString()\r\n*/\r\nexport const getLocalRelativeDateString = memoize((date: string | Date | number, min: number, max: number) => {\r\n\tconst days = Math.round((new Date(date).getTime() - today.getTime()) / msInDay)\r\n\tif (days < min || days > max) return getLocalDateString(date)\r\n\treturn relative.format(days, \"days\")\r\n})\r\n","import { createSelector, createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { Category, CSSColor, Offline, RootState, Selector, SelectorWithArgs } from \"../../typings\"\r\nimport { onlyUniqueOfflineIds, restructureCreateSelectorWithArgs } from \"../../utils\"\r\n\r\ninterface CategoryVisibility {\r\n\thiddenCategoryIds: string[]\r\n\tisNullCategoryHidden: boolean\r\n}\r\n\r\nexport interface CategoryState {\r\n\tcategories: Record<string, Category>\r\n\tusedCategoryColors: CSSColor[]\r\n\t// This is a list of names of all categories that the user has hidden\r\n\tcategoryVisibility: CategoryVisibility\r\n}\r\n\r\nconst initialState: CategoryState = {\r\n\tcategories: {},\r\n\tusedCategoryColors: [],\r\n\tcategoryVisibility: {\r\n\t\thiddenCategoryIds: [],\r\n\t\tisNullCategoryHidden: false,\r\n\t},\r\n}\r\n\r\n// TODO: Use types with createSlice\r\nexport const categorySlice = createSlice({\r\n\tname: \"categories\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetCategories: (state, action: { payload: Category[] }) => {\r\n\t\t\tif (!Array.isArray(action.payload)) throw new Error(\"Expected an array of Categories\")\r\n\t\t\tif (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {\r\n\t\t\t\tthrow new Error(\"Tried to use setCategories reducer with duplicate ID's\")\r\n\t\t\t}\r\n\t\t\taction.payload.forEach((category) => {\r\n\t\t\t\tstate.categories[category.offline_id] = category\r\n\t\t\t})\r\n\t\t\t// For all previously hidden categories, only keep the settings for the categories that are still present\r\n\t\t\t// in the freshly updated list of categories\r\n\t\t\tstate.categoryVisibility.hiddenCategoryIds = state.categoryVisibility.hiddenCategoryIds.filter(\r\n\t\t\t\t(categoryId) => action.payload.some((category) => category.offline_id === categoryId),\r\n\t\t\t)\r\n\t\t},\r\n\t\taddOrReplaceCategories: (state, action: { payload: Category[] }) => {\r\n\t\t\taction.payload.forEach((category) => {\r\n\t\t\t\tstate.categories[category.offline_id] = category\r\n\t\t\t})\r\n\t\t},\r\n\t\taddCategory: (state, action: { payload: Category }) => {\r\n\t\t\tif (action.payload.offline_id in state.categories) {\r\n\t\t\t\tthrow new Error(`Tried to add duplicate category with ID: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\tstate.categories[action.payload.offline_id] = action.payload\r\n\t\t\tstate.usedCategoryColors.push(action.payload.color)\r\n\t\t},\r\n\t\tpatchCategory: (state, action: { payload: Offline<Partial<Category>> }) => {\r\n\t\t\tconst existingData = state.categories[action.payload.offline_id]\r\n\r\n\t\t\tif (existingData) {\r\n\t\t\t\tstate.categories[action.payload.offline_id] = { ...existingData, ...action.payload }\r\n\t\t\t} else {\r\n\t\t\t\tconsole.error(`Tried to patch category with ID that doesn't exist: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\t// If the updated category color changes, put it in the list\r\n\t\t\tif (action.payload.color && !(action.payload.color in state.usedCategoryColors)) {\r\n\t\t\t\tstate.usedCategoryColors.push(action.payload.color)\r\n\t\t\t}\r\n\t\t},\r\n\t\treplaceCategory: (state, action: { payload: Category }) => {\r\n\t\t\tif (action.payload.offline_id in state.categories) {\r\n\t\t\t\tstate.categories[action.payload.offline_id] = action.payload\r\n\t\t\t} else {\r\n\t\t\t\tconsole.error(`Tried to replace category with ID that doesn't exist: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\t// If the updated category color changes, put it in the list\r\n\t\t\tif (!(action.payload.color in state.usedCategoryColors)) {\r\n\t\t\t\tstate.usedCategoryColors.push(action.payload.color)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveCategory: (state, action: PayloadAction<string>) => {\r\n\t\t\tif (!action.payload) {\r\n\t\t\t\tthrow new Error(\"Category is undefined\")\r\n\t\t\t}\r\n\t\t\tconst category = state.categories[action.payload]\r\n\t\t\tif (category) {\r\n\t\t\t\tcategorySlice.caseReducers.removeColor(state, { payload: category.color })\r\n\t\t\t\tdelete state.categories[action.payload]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Tried to remove category with ID that doesn't exist: ${action.payload}`)\r\n\t\t\t}\r\n\t\t},\r\n\t\t// Pass in a null value to hide the \"No category\" category\r\n\t\thideCategory: (state, action: { payload: string | null }) => {\r\n\t\t\tconst categoryId = action.payload\r\n\t\t\tif (categoryId === null) {\r\n\t\t\t\tstate.categoryVisibility.isNullCategoryHidden = true\r\n\t\t\t} else if (!(categoryId in state.categoryVisibility.hiddenCategoryIds)) {\r\n\t\t\t\tstate.categoryVisibility.hiddenCategoryIds.push(categoryId)\r\n\t\t\t}\r\n\t\t},\r\n\t\thideAllCategories: (state) => {\r\n\t\t\t// Set the list of hidden category names to the list of all category names\r\n\t\t\tstate.categoryVisibility.hiddenCategoryIds = Object.keys(state.categories)\r\n\t\t\t// Hide the \"No category\" category\r\n\t\t\tstate.categoryVisibility.isNullCategoryHidden = true\r\n\t\t},\r\n\t\t// Pass in a null value to unhide the \"No category\" category\r\n\t\tunhideCategory: (state, action: { payload: string | null }) => {\r\n\t\t\tconst categoryId = action.payload\r\n\t\t\tif (categoryId === null) {\r\n\t\t\t\tstate.categoryVisibility.isNullCategoryHidden = false\r\n\t\t\t} else {\r\n\t\t\t\tstate.categoryVisibility.hiddenCategoryIds = state.categoryVisibility.hiddenCategoryIds.filter(\r\n\t\t\t\t\t(id) => id !== categoryId,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tunhideAllCategories: (state) => {\r\n\t\t\t// Reset the list of hidden categories\r\n\t\t\tstate.categoryVisibility.hiddenCategoryIds = []\r\n\t\t\t// Unhide the \"No category\" category\r\n\t\t\tstate.categoryVisibility.isNullCategoryHidden = false\r\n\t\t},\r\n\t\tremoveColor: (state, action: { payload: string }) => {\r\n\t\t\tstate.usedCategoryColors = state.usedCategoryColors.filter((color: string) => color !== action.payload)\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\tsetCategories,\r\n\taddCategory,\r\n\treplaceCategory,\r\n\tpatchCategory,\r\n\tremoveCategory,\r\n\thideCategory,\r\n\thideAllCategories,\r\n\tunhideCategory,\r\n\tunhideAllCategories,\r\n\tremoveColor,\r\n\taddOrReplaceCategories,\r\n} = categorySlice.actions\r\n\r\nexport const selectCategoryMapping = (state: RootState) => state.categoryReducer.categories\r\n\r\n/** Exists only to avoid importing the workspaceSlice in the categorySlice */\r\nconst _selectActiveWorkspaceId = (state: RootState) => state.workspaceReducer.activeWorkspaceId\r\nexport const selectCategories = createSelector(\r\n\t[selectCategoryMapping, _selectActiveWorkspaceId],\r\n\t(mapping, activeWorkspaceId) =>\r\n\t\tactiveWorkspaceId ? Object.values(mapping).filter((category) => category.workspace === activeWorkspaceId) : [],\r\n)\r\n\r\nexport const selectCategoriesOfWorkspace: SelectorWithArgs<string, Category[]> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectCategories, (_state, workspaceId: string) => workspaceId], (categories, workspaceId) =>\r\n\t\tcategories.filter((category) => category.workspace === workspaceId),\r\n\t),\r\n)\r\n\r\nexport const selectCategory = (offline_id: string | null) => (state: RootState) => {\r\n\tif (!offline_id) return undefined\r\n\treturn state.categoryReducer.categories[offline_id]\r\n}\r\n\r\nexport const selectUsedColors: Selector<CSSColor[]> = (state: RootState) => state.categoryReducer.usedCategoryColors\r\n\r\nexport const selectCategoryVisibility = (state: RootState) => state.categoryReducer.categoryVisibility\r\n\r\nexport const selectHiddenCategoryCount = (state: RootState) => {\r\n\tconst { hiddenCategoryIds, isNullCategoryHidden } = state.categoryReducer.categoryVisibility\r\n\tlet hiddenCategoryCount = hiddenCategoryIds.length\r\n\t// The \"No category\" category also counts as a hidden category\r\n\tif (isNullCategoryHidden) hiddenCategoryCount++\r\n\treturn hiddenCategoryCount\r\n}\r\n\r\nexport const categoryReducer: Reducer<CategoryState> = categorySlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { Component, ComponentType, RootState, Selector, SelectorWithArgs, Submitted } from \"../../typings\"\r\nimport { toOfflineIdRecord } from \"../../utils\"\r\n\r\nexport interface ComponentState {\r\n\tcomponents: Record<string, Component | Submitted<Component>>\r\n}\r\n\r\nconst initialState: ComponentState = {\r\n\tcomponents: {},\r\n}\r\nexport const componentSlice = createSlice({\r\n\tname: \"components\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\taddComponent: (state, action: { payload: Component }) => {\r\n\t\t\tstate.components[action.payload.offline_id] = action.payload\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t\taddComponentsInBatches: (state, action: { payload: (Component | Submitted<Component>)[] }) => {\r\n\t\t\t// Object.assign copies the properties from action.payload into state.components\r\n\t\t\tObject.assign(state.components, toOfflineIdRecord(action.payload))\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t\tsetComponents: (state, action: { payload: Component[] }) => {\r\n\t\t\tstate.components = toOfflineIdRecord(action.payload)\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t\tupdateComponent: (state, action: { payload: Component }) => {\r\n\t\t\tif (action.payload.offline_id in state.components) {\r\n\t\t\t\tstate.components[action.payload.offline_id] = action.payload\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Tried to update component with ID that doesn't exist: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t\tremoveComponent: (state, action: PayloadAction<string>) => {\r\n\t\t\tif (action.payload in state.components) {\r\n\t\t\t\tdelete state.components[action.payload]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Failed to remove component because ID doesn't exist: ${action.payload}`)\r\n\t\t\t}\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t\tremoveAllComponentsOfType: (state, action: PayloadAction<string>) => {\r\n\t\t\tfor (const componentId in state.components) {\r\n\t\t\t\tif (state.components[componentId]?.component_type === action.payload) {\r\n\t\t\t\t\tdelete state.components[componentId]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Invalidate components cache\r\n\t\t\tprevComponents = null\r\n\t\t},\r\n\t},\r\n})\r\n\r\n// TODO: Reusable helper for this\r\n// When calling a selector, it returns a new object/array on each call. This causes hooks and components that depend on\r\n// components to rerender, even if the components themselves haven't changed. We know when components change (only when\r\n// one of the reducers above are called), so we can improve the performance of the app significantly by returning an old\r\n// reference until the cache has been invalidated.\r\nlet prevComponents: Component[] | null = null\r\nexport const selectComponents = (state: RootState) => {\r\n\tif (!prevComponents) {\r\n\t\tprevComponents = Object.values(state.componentReducer.components)\r\n\t}\r\n\treturn prevComponents\r\n}\r\n\r\nexport const selectComponentsFromComponentType: SelectorWithArgs<string | undefined, Component[]> =\r\n\t(componentTypeId) => (state) => {\r\n\t\tif (!componentTypeId) return []\r\n\t\tconst components = selectComponents(state)\r\n\t\treturn components.filter((component) => component.component_type === componentTypeId)\r\n\t}\r\n\r\nexport const selectComponent: SelectorWithArgs<string, Component> = (componentId) => (state: RootState) => {\r\n\treturn state.componentReducer.components[componentId]\r\n}\r\nexport const selectComponentTypeFromComponent: SelectorWithArgs<string, ComponentType> =\r\n\t(componentTypeId) => (state: RootState) => {\r\n\t\treturn state.componentTypeReducer.componentTypes[componentTypeId]\r\n\t}\r\nexport const selectComponentTypeFromComponents: Selector<Record<string, ComponentType>> = (state: RootState) => {\r\n\tconst ret: Record<string, ComponentType> = {}\r\n\tconst componentTypes = state.componentTypeReducer.componentTypes\r\n\tconst components = state.componentReducer.components\r\n\r\n\tfor (const [componentId, component] of Object.entries(components)) {\r\n\t\tconst componentType = componentTypes[component.component_type]\r\n\t\tif (!componentType) {\r\n\t\t\tconsole.error(\r\n\t\t\t\t`Component type with ID ${component.component_type} not found.\r\n\t\t\t\tExpected all referenced component types to be populated.\r\n\t\t\t\tReturning empty object to avoid fatal errors.`,\r\n\t\t\t)\r\n\t\t\treturn {}\r\n\t\t}\r\n\t\tret[componentId] = componentType\r\n\t}\r\n\r\n\treturn ret\r\n}\r\n\r\nexport const selectComponentsByType: SelectorWithArgs<string, Component[]> = (componentTypeId) => (state) => {\r\n\tconst components = state.componentReducer.components\r\n\tconst componentsOfType: Component[] = []\r\n\r\n\tfor (const component of Object.values(components)) {\r\n\t\tif (component.component_type === componentTypeId) {\r\n\t\t\tcomponentsOfType.push(component)\r\n\t\t}\r\n\t}\r\n\treturn componentsOfType\r\n}\r\n\r\nexport const selectNumberOfComponentsOfComponentType: SelectorWithArgs<string | undefined, number> =\r\n\t(componentTypeId) => (state) => {\r\n\t\tif (!componentTypeId) return 0\r\n\t\treturn selectComponentsByType(componentTypeId)(state)?.length\r\n\t}\r\n\r\nexport const selectComponentTypesFromIds: SelectorWithArgs<string[], ComponentType[]> =\r\n\t(componentTypeIds: string[]) => (state: RootState) => {\r\n\t\treturn componentTypeIds.reduce<ComponentType[]>((acc, componentTypeId) => {\r\n\t\t\tconst componentType = state.componentTypeReducer.componentTypes[componentTypeId]\r\n\t\t\tif (componentType) {\r\n\t\t\t\tacc.push(componentType)\r\n\t\t\t}\r\n\t\t\treturn acc\r\n\t\t}, [])\r\n\t}\r\n\r\nexport const {\r\n\taddComponent,\r\n\tupdateComponent,\r\n\tremoveComponent,\r\n\taddComponentsInBatches,\r\n\tsetComponents,\r\n\tremoveAllComponentsOfType,\r\n} = componentSlice.actions\r\n\r\nexport const componentReducer: Reducer<ComponentState> = componentSlice.reducer\r\n","import { createSlice, Reducer } from \"@reduxjs/toolkit\"\r\n\r\nimport { CompletedStagesMapping, Component, Model, RootState, SelectorWithArgs } from \"../../typings\"\r\n\r\nexport interface ComponentStageCompletionState {\r\n\tcompletionsByComponentId: CompletedStagesMapping\r\n}\r\n\r\nconst initialState: ComponentStageCompletionState = {\r\n\tcompletionsByComponentId: {},\r\n}\r\n\r\n// TODO: Move to typings\r\nexport interface ComponentStageCompletion extends Model {\r\n\tcomponent: string\r\n\tstage: string\r\n}\r\n\r\n// TODO: It would be much more performant if completions are stored with componentId keys and stageId[] values\r\nexport const componentStageCompletionSlice = createSlice({\r\n\tname: \"componentStageCompletions\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\taddStageCompletion: (state, action: { payload: ComponentStageCompletion }) => {\r\n\t\t\tlet stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component]\r\n\t\t\tif (!stageToCompletionDateMapping) {\r\n\t\t\t\tstageToCompletionDateMapping = {}\r\n\t\t\t\tstate.completionsByComponentId[action.payload.component] = stageToCompletionDateMapping\r\n\t\t\t}\r\n\t\t\tstageToCompletionDateMapping[action.payload.stage] = new Date().toISOString()\r\n\t\t},\r\n\t\taddStageCompletions: (state, action: { payload: CompletedStagesMapping }) => {\r\n\t\t\tfor (const [componentId, stageIdToCompletionDateMapping] of Object.entries(action.payload)) {\r\n\t\t\t\tif (Object.keys(stageIdToCompletionDateMapping).length === 0)\r\n\t\t\t\t\tthrow new Error(\r\n\t\t\t\t\t\t`Encountered empty stageIdToCompletionDateMapping argument for component ${componentId}`,\r\n\t\t\t\t\t)\r\n\t\t\t\tlet thisComponentCompletions = state.completionsByComponentId[componentId]\r\n\t\t\t\tif (thisComponentCompletions === undefined) {\r\n\t\t\t\t\tthisComponentCompletions = {}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tfor (const [stageId, completionDate] of Object.entries(stageIdToCompletionDateMapping)) {\r\n\t\t\t\t\tthisComponentCompletions[stageId] = completionDate\r\n\t\t\t\t}\r\n\r\n\t\t\t\tstate.completionsByComponentId[componentId] = thisComponentCompletions\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveStageCompletions: (state, action: { payload: ComponentStageCompletion[] }) => {\r\n\t\t\tfor (const completion of action.payload) {\r\n\t\t\t\tconst thisComponentCompletions = state.completionsByComponentId[completion.component]\r\n\r\n\t\t\t\tif (!thisComponentCompletions || !(completion.stage in thisComponentCompletions)) {\r\n\t\t\t\t\t// TODO: This should be an error. We should not construct completions to remove if the stage is not\r\n\t\t\t\t\t// completed for the component.\r\n\t\t\t\t\tconsole.warn(\r\n\t\t\t\t\t\t\"Skipping removal of uncompleted stage. This message indicates completion objects \" +\r\n\t\t\t\t\t\t\t\"are created unnecessarily.\",\r\n\t\t\t\t\t)\r\n\t\t\t\t\tcontinue\r\n\t\t\t\t}\r\n\t\t\t\tdelete thisComponentCompletions[completion.stage]\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetStageCompletions: (state, action: { payload: CompletedStagesMapping }) => {\r\n\t\t\tstate.completionsByComponentId = action.payload\r\n\t\t},\r\n\t},\r\n})\r\nexport const { addStageCompletion, addStageCompletions, removeStageCompletions, setStageCompletions } =\r\n\tcomponentStageCompletionSlice.actions\r\n\r\nexport const selectCompletedStages = (state: RootState) => {\r\n\treturn state.componentStageCompletionReducer.completionsByComponentId\r\n}\r\n\r\nexport const selectCompletedStageIdsForComponent: SelectorWithArgs<Component, string[]> =\r\n\t(component: Component) => (state: RootState) => {\r\n\t\treturn Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {})\r\n\t}\r\n\r\nexport const componentStageCompletionReducer: Reducer<ComponentStageCompletionState> =\r\n\tcomponentStageCompletionSlice.reducer\r\n","import { Reducer, createSelector, createSlice } from \"@reduxjs/toolkit\"\r\n\r\nimport { ComponentStage, RootState, SelectorWithArgs } from \"../../typings\"\r\nimport { restructureCreateSelectorWithArgs, toOfflineIdRecord } from \"../../utils\"\r\n\r\nexport interface ComponentStageState {\r\n\tstages: Record<string, ComponentStage>\r\n}\r\nconst initialState: ComponentStageState = {\r\n\tstages: {},\r\n}\r\n\r\nexport const componentStageSlice = createSlice({\r\n\tname: \"componentStages\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\taddStages: (state, action: { payload: ComponentStage[] }) => {\r\n\t\t\tObject.assign(state.stages, toOfflineIdRecord(action.payload))\r\n\t\t},\r\n\t\tupdateStages: (state, action: { payload: ComponentStage[] }) => {\r\n\t\t\tfor (const stage of action.payload) {\r\n\t\t\t\tstate.stages[stage.offline_id] = stage\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveStages: (state, action: { payload: string[] }) => {\r\n\t\t\taction.payload.forEach((id) => {\r\n\t\t\t\tdelete state.stages[id]\r\n\t\t\t})\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const selectStageMapping: (state: RootState) => Record<string, ComponentStage> = (state) =>\r\n\tstate.componentStageReducer.stages\r\n\r\nexport const selectStages: (state: RootState) => ComponentStage[] = createSelector(\r\n\t[selectStageMapping],\r\n\t(stageMapping) => {\r\n\t\treturn Object.values(stageMapping)\r\n\t},\r\n)\r\n\r\nexport const selectStagesFromComponentTypeIds: SelectorWithArgs<\r\n\tstring[],\r\n\tRecord<string, ComponentStage[]>\r\n> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[selectStages, (_state, componentTypeIds: string[]) => componentTypeIds],\r\n\t\t(stages, componentTypeIds) => {\r\n\t\t\tconst componentTypeIdsSet = new Set(componentTypeIds)\r\n\t\t\tconst ret: Record<string, ComponentStage[]> = {}\r\n\t\t\tfor (const stage of stages) {\r\n\t\t\t\tif (componentTypeIdsSet.has(stage.component_type)) {\r\n\t\t\t\t\tif (!ret[stage.component_type]) {\r\n\t\t\t\t\t\tret[stage.component_type] = []\r\n\t\t\t\t\t}\r\n\t\t\t\t\tret[stage.component_type]!.push(stage)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tfor (const key in ret) {\r\n\t\t\t\tret[key] = ret[key]!.sort((a, b) => a.priority - b.priority)\r\n\t\t\t}\r\n\t\t\treturn ret\r\n\t\t},\r\n\t),\r\n)\r\n\r\nexport const selectStagesFromComponentType: SelectorWithArgs<string, ComponentStage[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[selectStages, (_state, componentTypeId: string) => componentTypeId],\r\n\t\t\t(stages, componentTypeId) => {\r\n\t\t\t\treturn stages\r\n\t\t\t\t\t.filter((stage) => stage.component_type === componentTypeId)\r\n\t\t\t\t\t.sort((a, b) => a.priority - b.priority)\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectStagesFromStageIds: SelectorWithArgs<string[], ComponentStage[]> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectStageMapping, (_state, stageIds: string[]) => stageIds], (stageMapping, stageIds) => {\r\n\t\treturn stageIds\r\n\t\t\t.map((offline_id) => stageMapping[offline_id])\r\n\t\t\t.filter((stage): stage is ComponentStage => !!stage)\r\n\t}),\r\n)\r\n\r\nexport const { addStages, updateStages, removeStages } = componentStageSlice.actions\r\nexport const componentStageReducer: Reducer<ComponentStageState> = componentStageSlice.reducer\r\n","import { restructureCreateSelectorWithArgs, toOfflineIdRecord } from \"../../utils\"\r\nimport type { Reducer } from \"@reduxjs/toolkit\"\r\nimport { createSelector, createSlice } from \"@reduxjs/toolkit\"\r\nimport type { ComponentType, RootState, SelectorWithArgs } from \"../../typings\"\r\n\r\nexport interface ComponentTypeState {\r\n\tcomponentTypes: Record<string, ComponentType>\r\n\thiddenComponentTypeIds: Record<string, boolean>\r\n}\r\n\r\nconst initialState: ComponentTypeState = {\r\n\tcomponentTypes: {},\r\n\thiddenComponentTypeIds: {},\r\n}\r\n\r\nexport const componentTypeSlice = createSlice({\r\n\tname: \"componentTypes\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\taddComponentType: (state, action: { payload: ComponentType }) => {\r\n\t\t\tstate.componentTypes[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\tsetComponentTypes: (state, action: { payload: ComponentType[] }) => {\r\n\t\t\tstate.componentTypes = toOfflineIdRecord(action.payload)\r\n\t\t},\r\n\t\ttoggleComponentTypeVisibility: (state, action: { payload: string }) => {\r\n\t\t\tstate.hiddenComponentTypeIds[action.payload] = !state.hiddenComponentTypeIds[action.payload]\r\n\t\t},\r\n\t\tdeleteComponentType: (state, action: { payload: string }) => {\r\n\t\t\tdelete state.componentTypes[action.payload]\r\n\t\t},\r\n\t},\r\n})\r\n\r\n// TODO: Move\r\nexport type AppSelector<TResult> = (state: RootState) => TResult\r\n\r\nexport const selectComponentTypesMapping: AppSelector<Record<string, ComponentType>> = (state: RootState) =>\r\n\tstate.componentTypeReducer.componentTypes\r\n\r\nexport const selectComponentTypes: AppSelector<ComponentType[]> = createSelector(\r\n\t[selectComponentTypesMapping],\r\n\t(mapping) => Object.values(mapping),\r\n)\r\n\r\nexport const selectComponentType: SelectorWithArgs<string, ComponentType> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectComponentTypesMapping, (_state, id: string) => id], (mapping, id) => mapping[id]),\r\n)\r\n\r\ninterface selectNumberOfComponentTypesMatchingCaseInsensitiveNameProps {\r\n\tname: string | null | undefined\r\n\tcomponentTypeId: string | undefined\r\n}\r\nexport const selectNumberOfComponentTypesMatchingCaseInsensitiveName: SelectorWithArgs<\r\n\tselectNumberOfComponentTypesMatchingCaseInsensitiveNameProps,\r\n\tnumber\r\n> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[\r\n\t\t\tselectComponentTypesMapping,\r\n\t\t\t(_state, args: selectNumberOfComponentTypesMatchingCaseInsensitiveNameProps) => args,\r\n\t\t],\r\n\t\t(mapping, args) => {\r\n\t\t\tconst name = args.name?.toLowerCase() ?? null\r\n\t\t\treturn Object.values(mapping).filter(\r\n\t\t\t\t(componentType) =>\r\n\t\t\t\t\t(componentType.name?.toLowerCase() ?? null) === name &&\r\n\t\t\t\t\tcomponentType.offline_id !== args.componentTypeId,\r\n\t\t\t).length\r\n\t\t},\r\n\t),\r\n)\r\n\r\nexport const selectComponentTypesByName: SelectorWithArgs<string, ComponentType[]> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[selectComponentTypesMapping, (_state, name: string | null | undefined) => name],\r\n\t\t(mapping, name) => {\r\n\t\t\tname = name?.toLowerCase() ?? null\r\n\t\t\treturn Object.values(mapping).filter(\r\n\t\t\t\t(componentType) => (componentType.name?.toLowerCase() ?? null) === name,\r\n\t\t\t)\r\n\t\t},\r\n\t),\r\n)\r\n\r\nexport const selectHiddenComponentTypeIds: AppSelector<Record<string, boolean | undefined>> = (state: RootState) =>\r\n\tstate.componentTypeReducer.hiddenComponentTypeIds\r\n\r\nexport const { addComponentType, setComponentTypes, toggleComponentTypeVisibility, deleteComponentType } =\r\n\tcomponentTypeSlice.actions\r\nexport const componentTypeReducer: Reducer<ComponentTypeState> = componentTypeSlice.reducer\r\n","import { Reducer, createSelector, createSlice } from \"@reduxjs/toolkit\"\r\nimport { RootState, Selector, Workspace } from \"../../typings\"\r\nimport { restructureCreateSelectorWithArgs } from \"../../utils\"\r\n\r\nexport interface WorkspaceState {\r\n\tworkspaces: Record<string, Workspace>\r\n\tactiveWorkspaceId: string | null\r\n}\r\n\r\nconst initialState: WorkspaceState = {\r\n\tworkspaces: {},\r\n\tactiveWorkspaceId: null,\r\n}\r\n\r\n/**\r\n * Stores info related to the user's current workspace. For now, it's only the workspace ID which is hardcoded to 1.\r\n */\r\nexport const workspaceSlice = createSlice({\r\n\tname: \"workspace\",\r\n\tinitialState,\r\n\t// The `reducers` field lets us define reducers and generate associated actions\r\n\treducers: {\r\n\t\tsetWorkspaces: (state, action: { payload: Record<string, Workspace> }) => {\r\n\t\t\t// Redux Toolkit allows us to write \"mutating\" logic in reducers. It\r\n\t\t\t// doesn't actually mutate the state because it uses the Immer library,\r\n\t\t\t// which detects changes to a \"draft state\" and produces a brand new\r\n\t\t\t// immutable state based off those changes\r\n\t\t\tstate.workspaces = action.payload\r\n\t\t},\r\n\t\t// Takes a list of Workspaces and updates existing ones to match the payload, or adds them\r\n\t\t// to the store if they are not already present\r\n\t\taddOrReplaceWorkspaces: (state, action: { payload: Record<string, Workspace> }) => {\r\n\t\t\tObject.values(action.payload).forEach((workspace) => {\r\n\t\t\t\tstate.workspaces[workspace.offline_id] = workspace\r\n\t\t\t})\r\n\t\t},\r\n\t\taddWorkspace: (state, action: { payload: Workspace }) => {\r\n\t\t\tif (action.payload.offline_id in state.workspaces) {\r\n\t\t\t\tthrow new Error(`Tried to add duplicate workspace with name: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\tstate.workspaces[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\tremoveWorkspace: (state, action: { payload: string }) => {\r\n\t\t\tdelete state.workspaces[action.payload]\r\n\t\t},\r\n\t\tsetActiveWorkspaceId: (state, action: { payload: string | null }) => {\r\n\t\t\tstate.activeWorkspaceId = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setWorkspaces, addOrReplaceWorkspaces, addWorkspace, setActiveWorkspaceId, removeWorkspace } =\r\n\tworkspaceSlice.actions\r\n\r\n// The function below is called a selector and allows us to select a value from\r\n// the state. Selectors can also be defined inline where they're used instead of\r\n// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`\r\nexport const selectWorkspaceMapping: Selector<Record<string, Workspace>> = (state: RootState) =>\r\n\tstate.workspaceReducer.workspaces\r\n\r\nexport const selectWorkspaces = createSelector([selectWorkspaceMapping], (mapping) => Object.values(mapping))\r\n\r\nexport const selectMainWorkspace: Selector<Workspace | undefined> = createSelector([selectWorkspaces], (workspaces) => {\r\n\treturn workspaces.find((workspace) => workspace.name.toLowerCase() === \"main\")\r\n})\r\n\r\nexport const selectWorkspace = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectWorkspaceMapping, (_state, workspaceId: string) => workspaceId], (mapping, workspaceId) => {\r\n\t\treturn mapping[workspaceId]\r\n\t}),\r\n)\r\n\r\nexport const selectActiveWorkspaceId: Selector<string | null> = (state: RootState) =>\r\n\tstate.workspaceReducer.activeWorkspaceId\r\n\r\nexport const selectActiveWorkspace: Selector<Workspace | null | undefined> = createSelector(\r\n\t[selectWorkspaceMapping, selectActiveWorkspaceId],\r\n\t(mapping, activeWorkspaceId) => {\r\n\t\tif (!activeWorkspaceId) return null\r\n\t\treturn mapping[activeWorkspaceId]\r\n\t},\r\n)\r\n\r\nexport const selectPermittedWorkspaceIds: Selector<Set<string>> = createSelector(\r\n\t[selectWorkspaceMapping],\r\n\t(mapping) => {\r\n\t\treturn new Set(\r\n\t\t\tObject.values(mapping)\r\n\t\t\t\t.filter((workspace: Workspace) => workspace.permitted)\r\n\t\t\t\t.map((workspace: Workspace) => workspace.offline_id),\r\n\t\t)\r\n\t},\r\n)\r\n\r\nexport const workspaceReducer: Reducer<WorkspaceState> = workspaceSlice.reducer\r\n","import { createSelector, createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport {\r\n\tCreated,\r\n\tIssue,\r\n\tIssueAttachment,\r\n\tIssueComment,\r\n\tRootState,\r\n\tSearchableRecentResult,\r\n\tSearchArgs,\r\n\tSearchResult,\r\n\tSelector,\r\n\tSelectorWithArgs,\r\n\tStored,\r\n\tSubmitted,\r\n} from \"../../typings\"\r\nimport { IssueStatus } from \"../../enums\"\r\nimport { issueToSearchResult, logOnlyOnce, onlyUniqueOfflineIds, restructureCreateSelectorWithArgs } from \"../../utils\"\r\nimport { selectCategoryVisibility } from \"./categorySlice.ts\"\r\nimport { selectActiveWorkspaceId, selectWorkspaceMapping } from \"./workspaceSlice.ts\"\r\n\r\nconst maxRecentIssues = 10\r\ninterface RecentIssueId {\r\n\tofflineId: string\r\n\tlastOpenedEpochTime: number\r\n}\r\n\r\nexport interface IssueState {\r\n\tissues: Record<string, Stored<Issue>>\r\n\tattachments: Record<string, Stored<IssueAttachment>>\r\n\tcomments: Record<string, Stored<IssueComment>>\r\n\tvisibleStatuses: IssueStatus[]\r\n\tvisibleUserIds: (number | null)[] | null\r\n\tisFetchingInitialData: boolean\r\n\trecentIssueIds: RecentIssueId[]\r\n\tactiveIssueId: string | null\r\n}\r\n\r\nconst initialState: IssueState = {\r\n\tissues: {},\r\n\tattachments: {},\r\n\tcomments: {},\r\n\tvisibleStatuses: [IssueStatus.BACKLOG, IssueStatus.SELECTED],\r\n\tisFetchingInitialData: false,\r\n\tvisibleUserIds: null,\r\n\trecentIssueIds: [],\r\n\tactiveIssueId: null,\r\n}\r\n\r\n/**\r\n * Manages issues and categories stored offline.\r\n * Issue and category functionality is combined because they modify each other.\r\n * For example, if a category's color is changed then all issues with the category must be changed too.\r\n */\r\nexport const issueSlice = createSlice({\r\n\tname: \"issues\",\r\n\tinitialState,\r\n\textraReducers: (builder) =>\r\n\t\tbuilder.addCase(\"RESET\", (state) => {\r\n\t\t\tObject.assign(state, initialState)\r\n\t\t}),\r\n\treducers: {\r\n\t\tsetIssues: (state, action: { payload: Created<Issue>[] }) => {\r\n\t\t\tif (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {\r\n\t\t\t\tthrow new Error(\"Tried to use setIssues reducer with duplicate ID's\")\r\n\t\t\t}\r\n\t\t\t// Go through the list of issues and have each be stored with their offline_id as the key\r\n\t\t\taction.payload.forEach((issue) => {\r\n\t\t\t\tstate.issues[issue.offline_id] = issue\r\n\t\t\t})\r\n\t\t},\r\n\t\t// TODO: Reusable function\r\n\t\tsetAttachments: (state, action: PayloadAction<Created<IssueAttachment>[]>) => {\r\n\t\t\tfor (const attachment of action.payload) {\r\n\t\t\t\tstate.attachments[attachment.offline_id] = attachment\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetActiveIssueId: (state, action: { payload: string | null }) => {\r\n\t\t\tstate.activeIssueId = action.payload\r\n\t\t},\r\n\t\taddIssue: (state, action: { payload: Submitted<Issue> }) => {\r\n\t\t\tif (action.payload.offline_id in state.issues) {\r\n\t\t\t\tthrow new Error(`Tried to add duplicate issue with ID: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t\tstate.issues[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\t// TODO: Reusable function\r\n\t\taddAttachment: (state, action: PayloadAction<Submitted<IssueAttachment>>) => {\r\n\t\t\tif (action.payload.offline_id in state.attachments) {\r\n\t\t\t\tthrow new Error(`Attachment ${action.payload.offline_id} already exists.`)\r\n\t\t\t}\r\n\t\t\tstate.attachments[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\taddAttachments: (state, action: PayloadAction<Submitted<IssueAttachment>[]>) => {\r\n\t\t\tfor (const attachment of action.payload) {\r\n\t\t\t\tstate.attachments[attachment.offline_id] = attachment\r\n\t\t\t}\r\n\t\t},\r\n\t\tupdateIssue: (state, action: { payload: Submitted<Partial<Issue>> }) => {\r\n\t\t\t// If we encounter an issue with the same ID, we will update it\r\n\t\t\tif (action.payload.offline_id in state.issues) {\r\n\t\t\t\tstate.issues[action.payload.offline_id] = {\r\n\t\t\t\t\t...state.issues[action.payload.offline_id],\r\n\t\t\t\t\t...action.payload,\r\n\t\t\t\t} as Stored<Issue>\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Tried to update issue with ID that doesn't exist: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t},\r\n\t\t// TODO: Reusable function\r\n\t\tupdateAttachment: (state, action: PayloadAction<Submitted<IssueAttachment>>) => {\r\n\t\t\tif (action.payload.offline_id in state.attachments) {\r\n\t\t\t\tstate.attachments[action.payload.offline_id] = action.payload\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Attachment ${action.payload.offline_id} does not exist.`)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveIssue: (state, action: PayloadAction<string>) => {\r\n\t\t\tif (action.payload in state.issues) {\r\n\t\t\t\tdelete state.issues[action.payload]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Failed to remove issue because ID doesn't exist: ${action.payload}`)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveAttachment: (state, action: PayloadAction<string>) => {\r\n\t\t\tif (action.payload in state.attachments) {\r\n\t\t\t\tdelete state.attachments[action.payload]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Attachment ${action.payload} does not exist.`)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveAttachmentsOfIssue: (state, action: PayloadAction<string>) => {\r\n\t\t\tconst attachments = Object.values(state.attachments).filter((a) => a.issue_id === action.payload)\r\n\t\t\tfor (const attachment of attachments) {\r\n\t\t\t\tdelete state.attachments[attachment.offline_id]\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetVisibleStatuses: (state, action: PayloadAction<IssueStatus[]>) => {\r\n\t\t\tstate.visibleStatuses = action.payload\r\n\t\t},\r\n\t\tsetIsFetchingInitialData: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.isFetchingInitialData = action.payload\r\n\t\t},\r\n\t\tsetVisibleUserIds: (state, action: { payload: (number | null)[] }) => {\r\n\t\t\tstate.visibleUserIds = [...new Set(action.payload)]\r\n\t\t},\r\n\t\tsetIssueComments: (state, action: PayloadAction<Created<IssueComment>[]>) => {\r\n\t\t\t// NOTE: Does not delete old comments. Name is misleading. We should standardize all names.\r\n\t\t\tfor (const comment of action.payload) {\r\n\t\t\t\tstate.comments[comment.offline_id] = comment\r\n\t\t\t}\r\n\t\t},\r\n\t\taddOrReplaceIssueComment: (state, action: PayloadAction<Submitted<IssueComment>>) => {\r\n\t\t\tstate.comments[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\tremoveIssueComment: (state, action: PayloadAction<string>) => {\r\n\t\t\tif (action.payload in state.comments) {\r\n\t\t\t\tdelete state.comments[action.payload]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Failed to remove issue comment because ID doesn't exist: ${action.payload}`)\r\n\t\t\t}\r\n\t\t},\r\n\t\tcleanRecentIssues: (state) => {\r\n\t\t\tstate.recentIssueIds = state.recentIssueIds.filter((recentIssue) => state.issues[recentIssue.offlineId])\r\n\t\t},\r\n\t\taddToRecentIssues: (state, action: { payload: string }) => {\r\n\t\t\tstate.recentIssueIds = state.recentIssueIds.filter(\r\n\t\t\t\t(recentIssue) => recentIssue.offlineId !== action.payload,\r\n\t\t\t)\r\n\t\t\tstate.recentIssueIds.push({ offlineId: action.payload.toLowerCase(), lastOpenedEpochTime: Date.now() })\r\n\r\n\t\t\tif (state.recentIssueIds.length > maxRecentIssues) {\r\n\t\t\t\tstate.recentIssueIds.shift()\r\n\t\t\t}\r\n\t\t},\r\n\t\tresetRecentIssues: (state) => {\r\n\t\t\tstate.recentIssueIds = []\r\n\t\t},\r\n\t\tremoveRecentIssue: (state, action: PayloadAction<string>) => {\r\n\t\t\tconst indexToRemove = state.recentIssueIds.findIndex((item) => {\r\n\t\t\t\treturn item.offlineId == action.payload\r\n\t\t\t})\r\n\t\t\tif (indexToRemove !== -1) {\r\n\t\t\t\tstate.recentIssueIds.splice(indexToRemove, 1)\r\n\t\t\t}\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\taddAttachment,\r\n\taddAttachments,\r\n\taddIssue,\r\n\taddOrReplaceIssueComment,\r\n\taddToRecentIssues,\r\n\tcleanRecentIssues,\r\n\tremoveAttachment,\r\n\tremoveAttachmentsOfIssue,\r\n\tremoveIssue,\r\n\tremoveIssueComment,\r\n\tremoveRecentIssue,\r\n\tresetRecentIssues,\r\n\tsetActiveIssueId,\r\n\tsetAttachments,\r\n\tsetIsFetchingInitialData,\r\n\tsetIssueComments,\r\n\tsetIssues,\r\n\tsetVisibleStatuses,\r\n\tsetVisibleUserIds,\r\n\tupdateAttachment,\r\n\tupdateIssue,\r\n} = issueSlice.actions\r\nexport interface IssueFilterArgs {\r\n\tfilterByAssignedTo: boolean\r\n\tfilterByStatus: boolean\r\n\tfilterByCategory: boolean\r\n\tfilterByWorkspace: boolean\r\n}\r\n\r\nexport const selectIssueMapping = (state: RootState) => state.issueReducer.issues\r\nexport const selectRecentIssueIds = (state: RootState) => state.issueReducer.recentIssueIds\r\nexport const selectVisibleUserIds = (state: RootState) => state.issueReducer.visibleUserIds\r\nexport const selectVisibleStatuses = (state: RootState) => state.issueReducer.visibleStatuses\r\n\r\nexport const selectIssues: SelectorWithArgs<IssueFilterArgs, Stored<Issue>[]> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[\r\n\t\t\tselectIssueMapping,\r\n\t\t\tselectVisibleUserIds,\r\n\t\t\tselectVisibleStatuses,\r\n\t\t\tselectCategoryVisibility,\r\n\t\t\tselectActiveWorkspaceId,\r\n\t\t\t(_state, args: IssueFilterArgs) => args,\r\n\t\t],\r\n\t\t(mapping, visibleUserIds, visibleStatuses, categoryVisibility, activeWorkspaceId, args) => {\r\n\t\t\tlet ret = Object.values(mapping)\r\n\t\t\tconst visibleUserIdsSet = new Set(visibleUserIds)\r\n\t\t\tconst visibleStatusesSet = new Set(visibleStatuses)\r\n\r\n\t\t\tif (args.filterByAssignedTo && visibleUserIds?.length) {\r\n\t\t\t\tret = ret.filter((issue) => {\r\n\t\t\t\t\treturn visibleUserIdsSet.has(issue.assigned_to || null)\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t\tif (args.filterByStatus) {\r\n\t\t\t\tret = ret.filter((issue) => {\r\n\t\t\t\t\treturn visibleStatusesSet.has(issue.status)\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t\tif (args.filterByCategory) {\r\n\t\t\t\tconst isNullCategoryHidden = categoryVisibility.isNullCategoryHidden\r\n\t\t\t\tconst hiddenCategoryIds = categoryVisibility.hiddenCategoryIds\r\n\t\t\t\tret = ret.filter((issue) => {\r\n\t\t\t\t\tif (!issue.category) {\r\n\t\t\t\t\t\treturn !isNullCategoryHidden\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn !hiddenCategoryIds.includes(issue.category)\r\n\t\t\t\t})\r\n\t\t\t\tif (args.filterByWorkspace) {\r\n\t\t\t\t\tret = ret.filter((issue) => {\r\n\t\t\t\t\t\treturn activeWorkspaceId && issue.visible_in_workspaces.includes(activeWorkspaceId)\r\n\t\t\t\t\t})\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn ret\r\n\t\t},\r\n\t),\r\n)\r\n\r\nexport const selectActiveIssueId = (state: RootState) => state.issueReducer.activeIssueId\r\nexport const selectIssueAttachmentMapping = (state: RootState) => state.issueReducer.attachments\r\nexport const selectIssueAttachments: Selector<Stored<IssueAttachment>[]> = createSelector(\r\n\t[selectIssueAttachmentMapping],\r\n\t(mapping) => Object.values(mapping),\r\n)\r\n\r\nexport const selectPhotoAttachmentsOfIssue: SelectorWithArgs<string, Stored<IssueAttachment>[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[selectIssueAttachmentMapping, (_state: RootState, issueId: string) => issueId],\r\n\t\t\t(attachmentMapping, issueId) => {\r\n\t\t\t\tif (!issueId) return undefined\r\n\t\t\t\treturn Object.values(attachmentMapping).filter(\r\n\t\t\t\t\t(attachment) =>\r\n\t\t\t\t\t\tattachment.issue_id === issueId &&\r\n\t\t\t\t\t\tattachment.file_type &&\r\n\t\t\t\t\t\tattachment.file_type.startsWith(\"image/\"),\r\n\t\t\t\t)\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectCommentMapping = (state: RootState) => state.issueReducer.comments\r\n\r\nexport const selectCommentsOfIssue = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectCommentMapping, (_state, issueId: string) => issueId], (commentMapping, issueId: string) => {\r\n\t\treturn Object.values(commentMapping).filter((comment) => comment.issue === issueId)\r\n\t}),\r\n)\r\n\r\nexport const selectFileAttachmentsOfIssue = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[selectIssueAttachmentMapping, (_state, issueId: string) => issueId],\r\n\t\t(attachmentMapping, issueId) => {\r\n\t\t\tif (!issueId) return undefined\r\n\t\t\treturn Object.values(attachmentMapping).filter(\r\n\t\t\t\t(attachment) =>\r\n\t\t\t\t\t// Files with file_type that is null or not an image file\r\n\t\t\t\t\tattachment.issue_id === issueId &&\r\n\t\t\t\t\t(!attachment.file_type || !attachment.file_type.startsWith(\"image/\")),\r\n\t\t\t)\r\n\t\t},\r\n\t),\r\n)\r\nexport const selectIssue: SelectorWithArgs<string, Stored<Issue> | undefined> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectIssueMapping, (_state, id: string) => id], (mapping, id) => {\r\n\t\treturn mapping[id]\r\n\t}),\r\n)\r\nexport const selectIsFetchingInitialData = (state: RootState) => state.issueReducer.isFetchingInitialData\r\nexport const selectAllAttachments = createSelector([selectIssueAttachmentMapping], (mapping) => Object.values(mapping))\r\n\r\n// TODO: Cache?\r\nexport const searchIssues: SelectorWithArgs<SearchArgs, SearchResult<Stored<Issue>>[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[selectIssueMapping, selectWorkspaceMapping, (_state, searchArgs: SearchArgs) => searchArgs],\r\n\t\t\t(mapping, workspaceMapping, searchArgs) => {\r\n\t\t\t\tlet searchTerm = searchArgs.searchTerm\r\n\t\t\t\tconst maxResults = searchArgs.maxResults\r\n\t\t\t\tsearchTerm = searchTerm.toLowerCase()\r\n\t\t\t\tconst ret: SearchResult<Stored<Issue>>[] = []\r\n\t\t\t\tconst issues = Object.values(mapping)\r\n\t\t\t\t// This is more performant than repeatedly calling .length\r\n\t\t\t\tlet nbResults = 0\r\n\t\t\t\tfor (const issue of issues) {\r\n\t\t\t\t\t// First, get rid of any issues with no index_workspace. This can happen if the index workspace was deleted,\r\n\t\t\t\t\t// but the server hasn't responded with a new index in the main workspace. If no index_workspace is\r\n\t\t\t\t\t// available, we can't calculate the \"tag\" of the search result.\r\n\t\t\t\t\t// TODO: It's still possible to support search by showing a blank tag.\r\n\t\t\t\t\tif (!issue.index_workspace) {\r\n\t\t\t\t\t\tlogOnlyOnce(\r\n\t\t\t\t\t\t\t\"issue-has-no-index-workspace\",\r\n\t\t\t\t\t\t\tissue.offline_id,\r\n\t\t\t\t\t\t\t\"warn\",\r\n\t\t\t\t\t\t\t`Issue ${issue.offline_id} has no index_workspace and cannot be searched.`,\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t\tcontinue\r\n\t\t\t\t\t}\r\n\t\t\t\t\tconst workspace = workspaceMapping[issue.index_workspace]\r\n\r\n\t\t\t\t\tif (!workspace) {\r\n\t\t\t\t\t\tlogOnlyOnce(\r\n\t\t\t\t\t\t\t\"issue-has-non-existent-index-workspace\",\r\n\t\t\t\t\t\t\tissue.offline_id,\r\n\t\t\t\t\t\t\t\"warn\",\r\n\t\t\t\t\t\t\t`Encountered issue with an index_workspace that doesn't exist. Issue ${issue.offline_id} has \r\n\t\t\t\t\tindex_workspace = ${issue.index_workspace}, which does not exist in:`,\r\n\t\t\t\t\t\t\tObject.keys(workspaceMapping),\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t\tcontinue\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tconst workspaceAbbreviation = workspace.abbreviation\r\n\t\t\t\t\tif (!workspaceAbbreviation) {\r\n\t\t\t\t\t\tlogOnlyOnce(\r\n\t\t\t\t\t\t\t\"workspace-has-no-abbreviation\",\r\n\t\t\t\t\t\t\tworkspace.offline_id,\r\n\t\t\t\t\t\t\t\"error\",\r\n\t\t\t\t\t\t\t`Workspace ${workspace.name} has no abbreviation. Not including any issues in search.`,\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t\tcontinue\r\n\t\t\t\t\t}\r\n\t\t\t\t\tconst tag = \"index\" in issue ? `${workspaceAbbreviation.toUpperCase()}-${issue.index}` : null\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\t(issue.title || \"\").toLowerCase().includes(searchTerm) ||\r\n\t\t\t\t\t\t(tag && tag.toLowerCase().includes(searchTerm))\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\tret.push(issueToSearchResult(issue, tag))\r\n\t\t\t\t\t\tnbResults++\r\n\t\t\t\t\t\tif (maxResults && nbResults >= maxResults) {\r\n\t\t\t\t\t\t\treturn ret\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn ret\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectRecentIssuesAsSearchResults: Selector<SearchableRecentResult<Stored<Issue>>[]> = createSelector(\r\n\t[selectIssueMapping, selectRecentIssueIds, selectWorkspaceMapping],\r\n\t(issueMapping, recentIssueIds, workspaceMapping) => {\r\n\t\tconst ret: SearchableRecentResult<Stored<Issue>>[] = []\r\n\t\tfor (const recentIssueResult of recentIssueIds) {\r\n\t\t\tconst issue = issueMapping[recentIssueResult.offlineId]\r\n\t\t\tif (!issue) {\r\n\t\t\t\t// Recent issue has been deleted. Remove it from the list.\r\n\t\t\t\tconsole.info(\"Recent issue no longer exists\")\r\n\t\t\t\tcontinue\r\n\t\t\t}\r\n\t\t\tif (\"index\" in issue && issue.index_workspace) {\r\n\t\t\t\tconst indexWorkspace = workspaceMapping[issue.index_workspace]\r\n\t\t\t\tif (!indexWorkspace) {\r\n\t\t\t\t\t// Prevent repeated logging, which hurts performance.\r\n\t\t\t\t\tlogOnlyOnce(\r\n\t\t\t\t\t\t\"issue-has-index-but-not-index-workspace\",\r\n\t\t\t\t\t\tissue.offline_id,\r\n\t\t\t\t\t\t\"warn\",\r\n\t\t\t\t\t\t`Issue ${issue.offline_id} has an index but no index_workspace. This may be because the \r\n\t\t\t\t\tworkspace has been deleted, but the new index has not been returned by the server yet. It will not\r\n\t\t\t\t\tbe included in search results.`,\r\n\t\t\t\t\t)\r\n\t\t\t\t\tcontinue\r\n\t\t\t\t}\r\n\t\t\t\tconst workspaceTag = `${indexWorkspace.abbreviation}-${issue.index}`\r\n\t\t\t\tconst searchResult = {\r\n\t\t\t\t\t...issueToSearchResult(issue, workspaceTag),\r\n\t\t\t\t\tlastOpenedEpochTime: recentIssueResult.lastOpenedEpochTime,\r\n\t\t\t\t} satisfies SearchableRecentResult<Stored<Issue>>\r\n\t\t\t\tret.push(searchResult)\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn ret\r\n\t},\r\n)\r\n\r\nexport const issueReducer: Reducer<IssueState> = issueSlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { SelectorWithArgs } from \"typings\"\r\n\r\ninterface S3UploadUrl {\r\n\turl: string\r\n\tfields: Record<string, string>\r\n\t/** the time the upload url expires */\r\n\texp?: number\r\n}\r\n\r\nexport interface FileState {\r\n\t// maps sha1 hash to upload URL\r\n\ts3Urls: Record<string, S3UploadUrl>\r\n}\r\n\r\ninterface S3UrlPayload {\r\n\tsha1: string\r\n\turl: string\r\n\tfields: Record<string, string>\r\n}\r\n\r\nconst initialState: FileState = {\r\n\ts3Urls: {},\r\n}\r\n\r\nconst msPerHour = 1000 * 60 * 60\r\nconst msPerWeek = msPerHour * 24 * 7\r\n\r\n/**\r\n * Stores the auth state of the app (tokens, and whether user is logged in or not)\r\n */\r\nexport const fileSlice = createSlice({\r\n\tname: \"file\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetUploadUrl: (state, action: PayloadAction<S3UrlPayload>) => {\r\n\t\t\tconst { url, fields, sha1 } = action.payload\r\n\t\t\tconst today = new Date()\r\n\t\t\tconst weekFromToday = new Date(today.getTime() + msPerWeek)\r\n\r\n\t\t\tstate.s3Urls[sha1] = {\r\n\t\t\t\turl,\r\n\t\t\t\tfields,\r\n\t\t\t\texp: weekFromToday.getTime(),\r\n\t\t\t}\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setUploadUrl } = fileSlice.actions\r\n\r\nexport const selectUploadUrl: SelectorWithArgs<string, S3UploadUrl> = (sha1: string) => (state) => {\r\n\tconst url = state.fileReducer.s3Urls[sha1]\r\n\tif (!url) {\r\n\t\treturn undefined\r\n\t}\r\n\r\n\tconst today = new Date().getTime()\r\n\tconst expiringWithinAnHour = (url.exp ?? today) - today < msPerHour\r\n\tif (expiringWithinAnHour) return undefined\r\n\r\n\treturn url\r\n}\r\n\r\nexport const fileReducer: Reducer<FileState> = fileSlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { MapStyle } from \"../../enums\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport interface MapState {\r\n\tmapStyle: MapStyle\r\n\t// This setting controls whether the map should show permanent tooltips of each issue's name\r\n\tshowTooltips: boolean\r\n\tcenterMapToProject: boolean\r\n}\r\n\r\nconst initialState: MapState = {\r\n\t// TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed\r\n\tmapStyle: import.meta.env.DEV ? MapStyle.SATELLITE : MapStyle.SATELLITE,\r\n\tshowTooltips: false,\r\n\tcenterMapToProject: false,\r\n}\r\n\r\n/**\r\n * Stores map settings and current location\r\n */\r\nexport const mapSlice = createSlice({\r\n\tname: \"map\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetMapStyle: (state, action: PayloadAction<MapStyle>) => {\r\n\t\t\tstate.mapStyle = action.payload\r\n\t\t},\r\n\t\tsetShowTooltips: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.showTooltips = action.payload\r\n\t\t},\r\n\t\tsetCenterMapToProject: (state, action: { payload: boolean }) => {\r\n\t\t\tstate.centerMapToProject = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setMapStyle, setShowTooltips, setCenterMapToProject } = mapSlice.actions\r\n\r\nexport const selectMapStyle = (state: RootState) => state.mapReducer.mapStyle\r\nexport const selectShowTooltips = (state: RootState) => state.mapReducer.showTooltips\r\nexport const selectCenterMapToProject = (state: RootState) => state.mapReducer.centerMapToProject\r\n\r\nexport const mapReducer: Reducer<MapState> = mapSlice.reducer\r\n","import { OfflineModel } from \"./base\"\r\n\r\nexport interface ProjectAccess extends OfflineModel {\r\n\tuser: number\r\n\tproject: number\r\n\taccess_level: number\r\n}\r\n\r\nexport enum ProjectAccessLevel {\r\n\tBASIC = 0,\r\n\tADMIN = 2,\r\n}\r\n\r\nexport interface OrganizationAccess extends OfflineModel {\r\n\tuser: number\r\n\torganization: number\r\n\taccess_level: OrganizationAccessLevel\r\n}\r\n\r\n// TODO: Move\r\nexport enum OrganizationAccessLevel {\r\n\tBASIC = 0,\r\n\tADMIN = 2,\r\n}\r\n","import { FileObject, Model } from \"./base\"\r\nimport L from \"leaflet\"\r\n\r\n// TODO: Move\r\nexport enum ProjectType {\r\n\tPERSONAL = 0,\r\n\tORGANIZATION = 2,\r\n}\r\n\r\nexport interface Project extends Model {\r\n\tid: number\r\n\tname: string\r\n\towner_organization: number | null\r\n\towner_user: number | null\r\n\tbounds: [L.LatLngTuple, L.LatLngTuple] | undefined\r\n}\r\n\r\nexport interface ProjectFile extends Model, FileObject {\r\n\toffline_id: string\r\n\tname: string\r\n\tz_index: number\r\n\tbounds?: [L.LatLngTuple, L.LatLngTuple]\r\n\tproject: number\r\n\t// This is generated as needed in order to have a local object URL to use when a project file is created but hasn't\r\n\t// been accepted by the backend yet, thus giving it a cloud URL.\r\n\t// TODO: I don't think this is necessary. Can't we just piggyback on the `file` field, overwriting it with the cloud\r\n\t// URL as soon as possible?\r\n\tobjectURL?: string\r\n}\r\n\r\nexport type ProjectPayload = Omit<Project, \"id\" | \"file\" | \"fileBlob\">\r\n","import { RegistrationPayload } from \"./users\"\r\nimport { OfflineModel } from \"./base\"\r\n\r\nexport type EmailVerificationPayload = undefined | RegistrationPayload | Omit<RegistrationPayload, \"username\" | \"email\">\r\n\r\nexport interface EmailVerificationReturn {\r\n\tusername?: string\r\n\tproject?: number\r\n}\r\n\r\nexport enum VerificationCodeType {\r\n\tUSER_REGISTRATION = 0,\r\n\tAPPLICATION_INVITE = 2,\r\n\tPROJECT_INVITE = 4,\r\n\tORGANIZATION_INVITE = 6,\r\n\tADD_EMAIL_DOMAIN = 8,\r\n\tRESET_PASSWORD = 10,\r\n}\r\n\r\nexport interface VerificationCode extends OfflineModel {\r\n\tverification_code: string\r\n\tverification_type: VerificationCodeType\r\n\torganization?: number\r\n\tproject?: number\r\n\tuser?: number\r\n}\r\n","import { createSlice, Reducer } from \"@reduxjs/toolkit\"\r\nimport { RootState, SelectorWithArgs, User } from \"../../typings\"\r\n\r\nexport interface UserState {\r\n\tcurrentUser: User\r\n\tusers: Record<number, User>\r\n}\r\n\r\nconst initialState: UserState = {\r\n\tusers: {},\r\n\tcurrentUser: {\r\n\t\tid: 0,\r\n\t\tusername: \"\",\r\n\t\temail: \"\",\r\n\t\tprofile: { file: null, file_sha1: null, favourite_project_ids: [], tour_step: -1 },\r\n\t},\r\n}\r\n\r\nexport const userSlice = createSlice({\r\n\tname: \"users\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetUsers: (state, action: { payload: User[] }) => {\r\n\t\t\tconst usersMapping: Record<string, User> = {}\r\n\t\t\taction.payload.forEach((user) => {\r\n\t\t\t\tusersMapping[user.id] = user\r\n\t\t\t})\r\n\t\t\tstate.users = usersMapping\r\n\t\t},\r\n\t\taddUsers: (state, action: { payload: User[] }) => {\r\n\t\t\tfor (const user of action.payload) {\r\n\t\t\t\tstate.users[user.id] = user\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetCurrentUser: (state, action: { payload: User }) => {\r\n\t\t\tstate.currentUser = action.payload\r\n\t\t},\r\n\t\tsetProfilePicture: (state, action: { payload: { file?: string; file_sha1?: string } }) => {\r\n\t\t\tstate.currentUser.profile.file = action.payload.file ?? null\r\n\t\t\tstate.currentUser.profile.file_sha1 = action.payload.file_sha1 ?? null\r\n\r\n\t\t\tconst currentUser = state.users[state.currentUser.id]\r\n\r\n\t\t\tif (!currentUser) {\r\n\t\t\t\tthrow new Error(\"Unable to find current user in users slice\")\r\n\t\t\t}\r\n\r\n\t\t\tcurrentUser.profile.file = action.payload.file ?? null\r\n\t\t\tcurrentUser.profile.file_sha1 = action.payload.file_sha1 ?? null\r\n\t\t},\r\n\t\taddFavouriteProjectId: (state, action: { payload: number }) => {\r\n\t\t\tstate.currentUser.profile.favourite_project_ids.push(action.payload)\r\n\t\t},\r\n\t\tremoveFavouriteProjectId: (state, action: { payload: number }) => {\r\n\t\t\tstate.currentUser.profile.favourite_project_ids = state.currentUser.profile.favourite_project_ids.filter(\r\n\t\t\t\t(id) => id !== action.payload,\r\n\t\t\t)\r\n\t\t},\r\n\t\tsetTourStep: (state, action: { payload: number }) => {\r\n\t\t\tstate.currentUser.profile.tour_step = action.payload\r\n\t\t},\r\n\t\tremoveUser: (state, action: { payload: number }) => {\r\n\t\t\tdelete state.users[action.payload]\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\tsetCurrentUser,\r\n\tsetProfilePicture,\r\n\tsetUsers,\r\n\taddUsers,\r\n\taddFavouriteProjectId,\r\n\tremoveFavouriteProjectId,\r\n\tsetTourStep,\r\n\tremoveUser,\r\n} = userSlice.actions\r\n\r\nexport const selectCurrentUser = (state: RootState) => state.userReducer.currentUser\r\nexport const selectUser: SelectorWithArgs<number | null, User | undefined> = (userId) => (state) => {\r\n\tif (userId === null) return undefined\r\n\treturn state.userReducer.users[userId]\r\n}\r\nexport const selectUsersAsMapping = (state: RootState) => state.userReducer.users\r\nexport const selectFavouriteProjects = (state: RootState): number[] =>\r\n\tstate.userReducer.currentUser.profile.favourite_project_ids\r\n\r\nexport const userReducer: Reducer<UserState> = userSlice.reducer\r\n","import { Reducer, createSlice } from \"@reduxjs/toolkit\"\r\n\r\nimport { RootState, Selector, SelectorWithArgs } from \"typings\"\r\nimport { OfflineIdMapping, OrganizationAccess, User } from \"typings/models\"\r\nimport { onlyUniqueOfflineIds } from \"utils\"\r\n\r\nexport interface OrganizationAccessState {\r\n\torganizationAccesses: OfflineIdMapping<OrganizationAccess>\r\n\tactiveOrganizationAccessId: string | null\r\n}\r\n\r\nconst initialState: OrganizationAccessState = {\r\n\torganizationAccesses: {},\r\n\tactiveOrganizationAccessId: null,\r\n}\r\n\r\nexport const organizationAccessSlice = createSlice({\r\n\tname: \"organizationAccess\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetOrganizationAccesses: (state, action: { payload: OrganizationAccess[] }) => {\r\n\t\t\tif (!Array.isArray(action.payload)) throw new Error(\"Expected an array of OrganizationAccess\")\r\n\t\t\tif (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {\r\n\t\t\t\tthrow new Error(\"Tried to use setOrganizationAccesses reducer with duplicate ID's\")\r\n\t\t\t}\r\n\t\t\tconst organizationAccesses: OfflineIdMapping<OrganizationAccess> = {}\r\n\t\t\tfor (const organizationAccess of action.payload) {\r\n\t\t\t\torganizationAccesses[organizationAccess.offline_id] = organizationAccess\r\n\t\t\t}\r\n\t\t\tstate.organizationAccesses = organizationAccesses\r\n\t\t},\r\n\t\tupdateOrganizationAccess: (state, action: { payload: OrganizationAccess }) => {\r\n\t\t\tif (action.payload.offline_id in state.organizationAccesses) {\r\n\t\t\t\tstate.organizationAccesses[action.payload.offline_id] = action.payload\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Tried to update organization access with ID that doesn't exist: ${action.payload.offline_id}`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveOrganizationAccess: (state, action: { payload: OrganizationAccess }) => {\r\n\t\t\tif (action.payload.offline_id in state.organizationAccesses) {\r\n\t\t\t\tdelete state.organizationAccesses[action.payload.offline_id]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Tried to remove organization access with ID that doesn't exist: ${action.payload.offline_id}`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetActiveOrganizationAccessId: (state, action: { payload: string | null }) => {\r\n\t\t\tstate.activeOrganizationAccessId = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\tsetOrganizationAccesses,\r\n\tupdateOrganizationAccess,\r\n\tremoveOrganizationAccess,\r\n\tsetActiveOrganizationAccessId,\r\n} = organizationAccessSlice.actions\r\nexport const selectOrganizationAccesses = (state: RootState) => {\r\n\treturn state.organizationAccessReducer.organizationAccesses\r\n}\r\n\r\nexport const selectOrganizationAccess: SelectorWithArgs<string, OrganizationAccess> =\r\n\t(organizationAccessId: string) => (state: RootState) => {\r\n\t\treturn state.organizationAccessReducer.organizationAccesses[organizationAccessId]\r\n\t}\r\n\r\nexport const selectActiveOrganizationAccess: Selector<OrganizationAccess | null> = (state) => {\r\n\tconst activeOrganizationAccessId = state.organizationAccessReducer.activeOrganizationAccessId\r\n\tif (!activeOrganizationAccessId) {\r\n\t\treturn null\r\n\t}\r\n\treturn state.organizationAccessReducer.organizationAccesses[activeOrganizationAccessId] ?? null\r\n}\r\n\r\nexport const selectOrganizationAccessForUser: SelectorWithArgs<User, OrganizationAccess | undefined> =\r\n\t(user: User) => (state: RootState) => {\r\n\t\treturn Object.values(state.organizationAccessReducer.organizationAccesses).find(\r\n\t\t\t(organizationAccess: OrganizationAccess) => organizationAccess.user === user.id,\r\n\t\t)\r\n\t}\r\n\r\nexport const selectOrganizationAccessUserMapping = (state: RootState) => {\r\n\tconst organizationAccesses = {}\r\n\tfor (const organizationAccess of Object.values(state.organizationAccessReducer.organizationAccesses)) {\r\n\t\torganizationAccesses[organizationAccess.user] = organizationAccess\r\n\t}\r\n\treturn organizationAccesses\r\n}\r\n\r\nexport const organizationAccessReducer: Reducer<OrganizationAccessState> = organizationAccessSlice.reducer\r\n","import { Reducer, createSlice, createSelector } from \"@reduxjs/toolkit\"\r\nimport { Selector, SelectorWithArgs } from \"typings/store\"\r\nimport { RootState, User, Organization, OfflineIdMapping } from \"../../typings\"\r\nimport { OrganizationAccess, OrganizationAccessLevel } from \"../../typings/models\"\r\nimport { selectCurrentUser, selectUsersAsMapping } from \"./userSlice\"\r\nimport { selectOrganizationAccesses, selectOrganizationAccessUserMapping } from \"./organizationAccessSlice.ts\"\r\n\r\nexport interface OrganizationState {\r\n\torganizations: Record<number, Organization>\r\n\tactiveOrganizationId: number | null\r\n}\r\n\r\nconst initialState: OrganizationState = {\r\n\torganizations: {},\r\n\tactiveOrganizationId: null,\r\n}\r\n\r\nexport const organizationSlice = createSlice({\r\n\tname: \"organizations\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetOrganizations: (state, action: { payload: Organization[] }) => {\r\n\t\t\tfor (const org of action.payload) {\r\n\t\t\t\tstate.organizations[org.id] = org\r\n\t\t\t}\r\n\t\t},\r\n\t\tupdateActiveOrganization: (state, action: { payload: Organization }) => {\r\n\t\t\tif (!state.activeOrganizationId) {\r\n\t\t\t\tthrow new Error(\"Cannot update name of active organization. Active organization ID does not exist\")\r\n\t\t\t}\r\n\t\t\tif (state.activeOrganizationId !== action.payload.id) {\r\n\t\t\t\tthrow new Error(\"Tried updating active organization with different organization\")\r\n\t\t\t}\r\n\t\t\tstate.organizations[state.activeOrganizationId] = action.payload\r\n\t\t},\r\n\t\tsetActiveOrganizationId: (state, action: { payload: number }) => {\r\n\t\t\tstate.activeOrganizationId = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setOrganizations, setActiveOrganizationId, updateActiveOrganization } = organizationSlice.actions\r\n\r\nexport const selectActiveOrganizationId: Selector<number | null> = (state: RootState) => {\r\n\treturn state.organizationReducer.activeOrganizationId\r\n}\r\nexport const selectOrganizations: Selector<Organization[]> = (state: RootState) => {\r\n\treturn Object.values(state.organizationReducer.organizations)\r\n}\r\n\r\nexport const selectActiveOrganization: Selector<Organization | null> = (state: RootState) => {\r\n\tconst id = selectActiveOrganizationId(state)\r\n\tif (!id) {\r\n\t\treturn null\r\n\t}\r\n\tconst organization = state.organizationReducer.organizations[id]\r\n\tif (!organization) {\r\n\t\treturn null\r\n\t}\r\n\treturn organization\r\n}\r\n\r\nexport const selectOrganizationUsersIds: Selector<number[]> = createSelector(\r\n\t[selectOrganizationAccesses],\r\n\t(organizationAccesses: OfflineIdMapping<OrganizationAccess>) =>\r\n\t\tObject.values(organizationAccesses).map((organizationAccess: OrganizationAccess) => organizationAccess.user),\r\n)\r\n\r\nexport const selectOrganizationUsersAsMapping: Selector<Record<number, User>> = createSelector(\r\n\t[selectOrganizationUsersIds, selectUsersAsMapping],\r\n\t(organizationUserIds: number[], users: Record<number, User>) =>\r\n\t\torganizationUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {}),\r\n)\r\n\r\nexport const selectSortedOrganizationUsers: Selector<User[]> = createSelector(\r\n\t[selectCurrentUser, selectOrganizationUsersAsMapping, selectOrganizationAccessUserMapping],\r\n\t(\r\n\t\tcurrentUser: User,\r\n\t\tuserMapping: Record<number, User>,\r\n\t\torganizationAccessMapping: Record<number, OrganizationAccess>,\r\n\t) => {\r\n\t\treturn Object.values(userMapping).sort((userA: User, userB: User) => {\r\n\t\t\tif (userA.id === currentUser.id) {\r\n\t\t\t\treturn -1\r\n\t\t\t} else if (userB.id === currentUser.id) {\r\n\t\t\t\treturn 1\r\n\t\t\t}\r\n\t\t\tconst organizationAccessesA: OrganizationAccess | undefined = organizationAccessMapping[userA.id]\r\n\t\t\tconst organizationAccessesB: OrganizationAccess | undefined = organizationAccessMapping[userB.id]\r\n\t\t\tif (organizationAccessesA?.access_level === organizationAccessesB?.access_level) {\r\n\t\t\t\treturn userA.username.localeCompare(userB.username)\r\n\t\t\t}\r\n\t\t\tif (organizationAccessesA?.access_level === OrganizationAccessLevel.ADMIN) {\r\n\t\t\t\treturn -1\r\n\t\t\t}\r\n\t\t\treturn 1\r\n\t\t})\r\n\t},\r\n)\r\n\r\nexport const selectOrganization: SelectorWithArgs<number, Organization | undefined> =\r\n\t(id: number) => (state: RootState) => {\r\n\t\treturn state.organizationReducer.organizations[id]\r\n\t}\r\n\r\nexport const organizationReducer: Reducer<OrganizationState> = organizationSlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport type { FullOfflineAction } from \"../store\"\r\nimport type { RequestDetails } from \"../../sdk\"\r\nimport { v4 as uuidv4 } from \"uuid\"\r\nimport { SDKRequest } from \"../../sdk\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport const createOfflineAction = (request: SDKRequest, baseUrl: string): FullOfflineAction => {\r\n\tconst requestWithUuid = request.uuid ? (request as RequestDetails) : { ...request, uuid: uuidv4() }\r\n\treturn {\r\n\t\tpayload: requestWithUuid,\r\n\t\ttype: \"\",\r\n\t\tmeta: {\r\n\t\t\toffline: {\r\n\t\t\t\teffect: {\r\n\t\t\t\t\ttimestamp: new Date().toISOString(),\r\n\t\t\t\t\trequest: requestWithUuid,\r\n\t\t\t\t\tBASE_URL: baseUrl,\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t},\r\n\t}\r\n}\r\n\r\nexport interface OutboxState {\r\n\t/** A list of requests marked for deletion. Once the offline slice encounters one of these, */\r\n\tdeletedRequests: string[]\r\n\t/** The timestamp of the last retry of an outgoing request. (Number of milliseconds since the epoch.) */\r\n\tlatestRetryTime: number\r\n}\r\n\r\nconst initialState: OutboxState = {\r\n\tdeletedRequests: [],\r\n\tlatestRetryTime: 0,\r\n}\r\n\r\n/**\r\n * This slice primarily exists as an interface to enqueue API requests to the redux-offline slice. Any dispatched action\r\n * with an `offline` field in its metadata will be handled by redux-offline. This slice is just a sensible place to\r\n * \"dump\" no-op actions for enqueueing requests to the outbox. At the same time, we can use this slice to keep track of\r\n * requests that have been marked for deletion, so that we can skip them instead of sending the request.\r\n */\r\nexport const outboxSlice = createSlice({\r\n\tname: \"outbox\",\r\n\tinitialState: initialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\t// enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox\r\n\t\t// Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store\r\n\t\t// Then this reducer enqueueRequest() is responsible for adding the actual request data to the outbox\r\n\t\tenqueueRequest: {\r\n\t\t\treducer: (state, _action: PayloadAction<RequestDetails>) => {\r\n\t\t\t\treturn state\r\n\t\t\t},\r\n\t\t\tprepare: (payload: SDKRequest & { BASE_URL: string }): FullOfflineAction => {\r\n\t\t\t\tconsole.debug(\"Preparing to enqueue request\", payload)\r\n\t\t\t\tconst { BASE_URL, ...rest } = payload\r\n\t\t\t\treturn createOfflineAction(rest, BASE_URL)\r\n\t\t\t},\r\n\t\t},\r\n\t\tmarkForDeletion(state, action: PayloadAction<string>) {\r\n\t\t\tstate.deletedRequests.push(action.payload)\r\n\t\t},\r\n\t\tmarkAsDeleted(state, action: PayloadAction<string>) {\r\n\t\t\tconst index = state.deletedRequests.indexOf(action.payload)\r\n\t\t\tif (index !== -1) state.deletedRequests.splice(index, 1)\r\n\t\t},\r\n\t\t_setLatestRetryTime: (state, action: PayloadAction<number>) => {\r\n\t\t\tstate.latestRetryTime = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const selectDeletedRequests = (state: RootState) => state.outboxReducer.deletedRequests\r\nexport const selectLatestRetryTime = (state: RootState) => state.outboxReducer.latestRetryTime\r\n\r\nexport const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions\r\nexport const outboxReducer: Reducer<OutboxState> = outboxSlice.reducer\r\n","import { Reducer, createSlice } from \"@reduxjs/toolkit\"\r\nimport { ProjectAccess, RootState, Selector, SelectorWithArgs, User } from \"../../typings\"\r\nimport { onlyUniqueOfflineIds } from \"../../utils\"\r\n\r\nexport interface ProjectAccessState {\r\n\tprojectAccesses: Record<string, ProjectAccess>\r\n}\r\n\r\nconst initialState: ProjectAccessState = {\r\n\tprojectAccesses: {},\r\n}\r\n\r\nexport const projectAccessSlice = createSlice({\r\n\tname: \"projectAccess\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetProjectAccesses: (state, action: { payload: ProjectAccess[] }) => {\r\n\t\t\tif (!Array.isArray(action.payload)) throw new Error(\"Expected an array of ProjectAccess\")\r\n\t\t\tif (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {\r\n\t\t\t\tthrow new Error(\"Tried to use setProjectAccesses reducer with duplicate ID's\")\r\n\t\t\t}\r\n\t\t\tconst projectAccesses: Record<string, ProjectAccess> = {}\r\n\t\t\tfor (const projectAccess of action.payload) {\r\n\t\t\t\tprojectAccesses[projectAccess.offline_id] = projectAccess\r\n\t\t\t}\r\n\t\t\tstate.projectAccesses = projectAccesses\r\n\t\t},\r\n\t\tupdateProjectAccess: (state, action: { payload: ProjectAccess }) => {\r\n\t\t\tif (action.payload.offline_id in state.projectAccesses) {\r\n\t\t\t\tstate.projectAccesses[action.payload.offline_id] = action.payload\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Tried to update project access with ID that doesn't exist: ${action.payload.offline_id}`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveProjectAccess: (state, action: { payload: ProjectAccess }) => {\r\n\t\t\tif (action.payload.offline_id in state.projectAccesses) {\r\n\t\t\t\tdelete state.projectAccesses[action.payload.offline_id]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Tried to remove project access with ID that doesn't exist: ${action.payload.offline_id}`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveProjectAccessesOfProject: (state, action: { payload: number }) => {\r\n\t\t\tfor (const projectAccess of Object.values(state.projectAccesses) as ProjectAccess[]) {\r\n\t\t\t\tif (projectAccess.project === action.payload) {\r\n\t\t\t\t\tdelete state.projectAccesses[projectAccess.offline_id]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setProjectAccesses, updateProjectAccess, removeProjectAccess, removeProjectAccessesOfProject } =\r\n\tprojectAccessSlice.actions\r\n\r\nexport const selectProjectAccesses = (state: RootState) => {\r\n\treturn state.projectAccessReducer.projectAccesses\r\n}\r\n\r\nexport const selectProjectAccess: SelectorWithArgs<string, ProjectAccess> =\r\n\t(projectAccessId: string) => (state: RootState) => {\r\n\t\treturn state.projectAccessReducer.projectAccesses[projectAccessId]\r\n\t}\r\n\r\nexport const selectActiveProjectAccess: Selector<ProjectAccess | null> = (state: RootState) => {\r\n\tconst currentUser = state.userReducer.currentUser\r\n\tconst activeProjectId = state.projectReducer.activeProjectId\r\n\treturn (\r\n\t\tObject.values(state.projectAccessReducer.projectAccesses).find((projectAccess: ProjectAccess) => {\r\n\t\t\treturn projectAccess.user === currentUser.id && projectAccess.project === activeProjectId\r\n\t\t}) ?? null\r\n\t)\r\n}\r\n\r\nexport const selectProjectAccessForUser: SelectorWithArgs<User, ProjectAccess | undefined> =\r\n\t(user: User) => (state: RootState) => {\r\n\t\treturn Object.values(state.projectAccessReducer.projectAccesses).find(\r\n\t\t\t(projectAccess: ProjectAccess) => projectAccess.user === user.id,\r\n\t\t)\r\n\t}\r\n\r\nexport const selectProjectAccessUserMapping: Selector<Record<string, ProjectAccess>> = (state: RootState) => {\r\n\tconst projectAccesses: Record<string, ProjectAccess> = {}\r\n\tfor (const projectAccess of Object.values(state.projectAccessReducer.projectAccesses)) {\r\n\t\tprojectAccesses[projectAccess.user] = projectAccess\r\n\t}\r\n\treturn projectAccesses\r\n}\r\n\r\nexport const projectAccessReducer: Reducer<ProjectAccessState> = projectAccessSlice.reducer\r\n","import { Reducer, createSlice, createSelector } from \"@reduxjs/toolkit\"\r\nimport {\r\n\tOfflineIdMapping,\r\n\tProject,\r\n\tProjectAccess,\r\n\tProjectAccessLevel,\r\n\tProjectType,\r\n\tRootState,\r\n\tSelector,\r\n\tUser,\r\n} from \"../../typings\"\r\nimport { selectProjectAccesses, selectProjectAccessUserMapping } from \"./projectAccessSlice.ts\"\r\nimport { selectCurrentUser, selectUsersAsMapping } from \"./userSlice.ts\"\r\n\r\nexport interface ProjectState {\r\n\tprojects: Record<number, Project>\r\n\tactiveProjectId: number | null\r\n\trecentProjectIds: number[]\r\n\trecentSearchableQueries: string[]\r\n\t// TODO: This is not really a global state that needs to be persisted\r\n\tcreateProjectType: ProjectType\r\n}\r\n\r\nconst initialState: ProjectState = {\r\n\tprojects: {},\r\n\tactiveProjectId: null,\r\n\trecentProjectIds: [],\r\n\trecentSearchableQueries: [],\r\n\tcreateProjectType: ProjectType.PERSONAL,\r\n}\r\n\r\nexport const projectSlice = createSlice({\r\n\tname: \"projects\",\r\n\tinitialState,\r\n\treducers: {\r\n\t\tsetProjects: (state, action: { payload: Project[] }) => {\r\n\t\t\tconst projectsMap: Record<number, Project> = {}\r\n\t\t\taction.payload.forEach((project) => {\r\n\t\t\t\tprojectsMap[project.id] = project\r\n\t\t\t})\r\n\t\t\tstate.projects = projectsMap\r\n\r\n\t\t\tif (state.recentProjectIds.length === 0) {\r\n\t\t\t\tstate.recentProjectIds = action.payload.map((project) => project.id)\r\n\t\t\t} else {\r\n\t\t\t\tstate.recentProjectIds.unshift(\r\n\t\t\t\t\t...action.payload.map((project) => project.id).filter((id) => !state.recentProjectIds.includes(id)),\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetActiveProjectId: (state, action: { payload: number | null }) => {\r\n\t\t\tstate.activeProjectId = action.payload\r\n\t\t\tif (action.payload !== null) {\r\n\t\t\t\tstate.recentProjectIds = state.recentProjectIds.filter((id) => id !== action.payload)\r\n\t\t\t\tstate.recentProjectIds.push(action.payload)\r\n\t\t\t}\r\n\t\t},\r\n\t\tupdateOrCreateProject: (state, action: { payload: Project }) => {\r\n\t\t\tstate.projects[action.payload.id] = action.payload\r\n\t\t},\r\n\t\t// Takes a list of Projects and updates existing ones to match the payload, or adds them\r\n\t\t// to the store if they are not already present\r\n\t\tupdateOrCreateProjects: (state, action: { payload: Project[] }) => {\r\n\t\t\taction.payload.forEach((project) => {\r\n\t\t\t\tstate.projects[project.id] = project\r\n\t\t\t})\r\n\t\t},\r\n\t\tsetCreateProjectType: (state, action: { payload: ProjectType }) => {\r\n\t\t\tstate.createProjectType = action.payload\r\n\t\t},\r\n\t\tdeleteProject: (state, action: { payload: Project }) => {\r\n\t\t\tdelete state.projects[action.payload.id]\r\n\t\t\tstate.recentProjectIds = state.recentProjectIds.filter((id) => id !== action.payload.id)\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\tsetProjects,\r\n\tupdateOrCreateProject,\r\n\tupdateOrCreateProjects: addOrReplaceProjects,\r\n\tsetActiveProjectId,\r\n\tsetCreateProjectType,\r\n\tdeleteProject,\r\n} = projectSlice.actions\r\n\r\nexport const selectProjects: Selector<Record<number, Project>> = (state: RootState) => state.projectReducer.projects\r\nexport const selectActiveProjectId = (state: RootState): number | null => state.projectReducer.activeProjectId\r\nexport const selectActiveProject = (state: RootState): Project | null => {\r\n\tconst activeProjectId = selectActiveProjectId(state)\r\n\tif (!activeProjectId) {\r\n\t\treturn null\r\n\t}\r\n\treturn state.projectReducer.projects[activeProjectId] ?? null\r\n}\r\nexport const selectRecentProjects = (state: RootState): number[] => {\r\n\treturn state.projectReducer.recentProjectIds\r\n}\r\nexport const selectCreateProjectType = (state: RootState): ProjectType => state.projectReducer.createProjectType\r\n\r\nexport const projectReducer: Reducer<ProjectState> = projectSlice.reducer\r\n\r\nexport const selectProjectUsersIds: Selector<number[]> = createSelector(\r\n\t[selectProjectAccesses],\r\n\t(projectAccesses: OfflineIdMapping<ProjectAccess>) =>\r\n\t\tObject.values(projectAccesses).map((projectAccess: ProjectAccess) => projectAccess.user),\r\n)\r\n\r\nexport const selectProjectUsersAsMapping: Selector<Record<number, User>> = createSelector(\r\n\t[selectProjectUsersIds, selectUsersAsMapping],\r\n\t(projectUserIds: number[], users: Record<number, User>) =>\r\n\t\tprojectUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {}),\r\n)\r\n\r\nexport const selectSortedProjectUsers: Selector<User[]> = createSelector(\r\n\t[selectCurrentUser, selectProjectUsersAsMapping, selectProjectAccessUserMapping],\r\n\t(currentUser: User, userMapping: Record<number, User>, projectAccessMapping: Record<number, ProjectAccess>) => {\r\n\t\treturn Object.values(userMapping).sort((userA, userB) => {\r\n\t\t\tif (userA.id === currentUser.id) {\r\n\t\t\t\treturn -1\r\n\t\t\t} else if (userB.id === currentUser.id) {\r\n\t\t\t\treturn 1\r\n\t\t\t}\r\n\t\t\tconst projectAccessesA = projectAccessMapping[userA.id]\r\n\t\t\tconst projectAccessesB = projectAccessMapping[userB.id]\r\n\t\t\tif (projectAccessesA?.access_level === projectAccessesB?.access_level) {\r\n\t\t\t\treturn userA.username.localeCompare(userB.username)\r\n\t\t\t}\r\n\t\t\tif (projectAccessesA?.access_level === ProjectAccessLevel.ADMIN) {\r\n\t\t\t\treturn -1\r\n\t\t\t}\r\n\t\t\treturn 1\r\n\t\t})\r\n\t},\r\n)\r\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\r\n\r\nimport L from \"leaflet\"\r\nimport { ProjectFile, RootState, Selector } from \"../../typings\"\r\nimport { selectActiveProjectId } from \"./projectSlice.ts\"\r\n\r\nexport interface ProjectFileState {\r\n\tprojectFiles: Record<string, ProjectFile>\r\n\tactiveProjectFileId: string | null\r\n\t/**\r\n\t * State variable which is set true by web client to mark that the activeProjectFile is a new one that was just\r\n\t * imported and not a pre-existing one which is being edited\r\n\t */\r\n\tisImportingProjectFile: boolean\r\n\t// undefined means visible (visible by default)\r\n\tenabledProjectFiles: Record<string, boolean | undefined>\r\n}\r\n\r\nconst initialState: ProjectFileState = {\r\n\tprojectFiles: {},\r\n\tactiveProjectFileId: null,\r\n\tisImportingProjectFile: false,\r\n\tenabledProjectFiles: {},\r\n}\r\n\r\nexport const projectFileSlice = createSlice({\r\n\tname: \"projectFiles\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\taddOrReplaceProjectFiles: (state, action: { payload: ProjectFile[] }) => {\r\n\t\t\tfor (let fileObj of action.payload) {\r\n\t\t\t\tlet file = fileObj.file\r\n\t\t\t\tif (file.includes(\"+\")) {\r\n\t\t\t\t\tconsole.warn(\"Attempting to apply fix for image URL with '+' character:\", file)\r\n\t\t\t\t\t// We have a src such as this:\r\n\t\t\t\t\t// https://example.com/my-svg.svg+xml\r\n\t\t\t\t\t// Or:\r\n\t\t\t\t\t// blob://.../my-svg.svg+xml\r\n\t\t\t\t\t// We want just the `my-svg.svg+xml` part.\r\n\t\t\t\t\tconst parts = file.split(\"/\")\r\n\t\t\t\t\tif (parts.length < 2) {\r\n\t\t\t\t\t\tthrow new Error(\"Invalid URL: \" + file)\r\n\t\t\t\t\t}\r\n\t\t\t\t\tconst lastPart = encodeURIComponent(parts[parts.length - 1]!)\r\n\t\t\t\t\t// Reconstruct the URL with the fixed last part.\r\n\t\t\t\t\tfile = parts.slice(0, -1).join(\"/\") + \"/\" + lastPart\r\n\t\t\t\t\tconsole.warn(\"Fixed URL:\", file)\r\n\t\t\t\t\tfileObj = { ...fileObj, file }\r\n\t\t\t\t}\r\n\t\t\t\tstate.projectFiles[fileObj.offline_id] = fileObj\r\n\t\t\t}\r\n\t\t},\r\n\t\taddOrReplaceProjectFile: (state, action: { payload: ProjectFile }) => {\r\n\t\t\tif (!action.payload.project) {\r\n\t\t\t\tthrow new Error(\"ProjectFile has no project. A project must be set before storing.\")\r\n\t\t\t}\r\n\t\t\tstate.projectFiles[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\tsetProjectFileVisible: (state, action: { payload: { fileId: string; visible: boolean } }) => {\r\n\t\t\tstate.enabledProjectFiles[action.payload.fileId] = action.payload.visible\r\n\t\t},\r\n\t\tsetIsImportingProjectFile: (state, action: { payload: boolean }) => {\r\n\t\t\tstate.isImportingProjectFile = action.payload\r\n\t\t},\r\n\t\tsaveActiveProjectFileBounds: (state, action: { payload: [L.LatLngTuple, L.LatLngTuple] }) => {\r\n\t\t\tconst activeProjectFileId = state.activeProjectFileId\r\n\t\t\tif (!activeProjectFileId) {\r\n\t\t\t\tthrow new Error(\"Tried to save bounds for active project file, but no active project file was set.\")\r\n\t\t\t}\r\n\t\t\tif (!state.projectFiles[activeProjectFileId]) {\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Tried to save bounds for active project file, but project file with ID ${activeProjectFileId} \r\n\t\t\t\t\tdoesn't exist.`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t\tstate.projectFiles[activeProjectFileId]!.bounds = action.payload\r\n\t\t},\r\n\t\t// TODO: Move to MapContext. Should not be persisted.\r\n\t\tsetActiveProjectFileId: (state, action: { payload: string | null }) => {\r\n\t\t\tstate.activeProjectFileId = action.payload\r\n\t\t\tif (action.payload) {\r\n\t\t\t\tstate.enabledProjectFiles[action.payload] = true\r\n\t\t\t}\r\n\t\t},\r\n\t\tremoveProjectFile: (state, action: { payload: string }) => {\r\n\t\t\tdelete state.projectFiles[action.payload]\r\n\t\t\tdelete state.enabledProjectFiles[action.payload]\r\n\t\t},\r\n\t\tremoveProjectFilesOfProject: (state, action: { payload: number }) => {\r\n\t\t\tconst filesToDelete = Object.values(state.projectFiles).filter((file) => file.project === action.payload)\r\n\t\t\tfor (const file of filesToDelete) {\r\n\t\t\t\tdelete state.projectFiles[file.offline_id]\r\n\t\t\t\tdelete state.enabledProjectFiles[file.offline_id]\r\n\t\t\t}\r\n\t\t},\r\n\t\tresetProjectFileObjectUrls: (state, ..._args: []) => {\r\n\t\t\tfor (const key in state.projectFiles) {\r\n\t\t\t\tdelete state.projectFiles[key]!.objectURL\r\n\t\t\t}\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\taddOrReplaceProjectFiles,\r\n\taddOrReplaceProjectFile,\r\n\tsetProjectFileVisible,\r\n\tsetIsImportingProjectFile,\r\n\tsetActiveProjectFileId,\r\n\tsaveActiveProjectFileBounds,\r\n\tremoveProjectFile,\r\n\tremoveProjectFilesOfProject,\r\n\tresetProjectFileObjectUrls,\r\n} = projectFileSlice.actions\r\n\r\nexport const selectEnabledProjectFiles = (state: RootState) => state.projectFileReducer.enabledProjectFiles\r\n\r\nexport const selectProjectFileVisibility: Selector<Record<string, boolean>> = createSelector(\r\n\t[selectEnabledProjectFiles],\r\n\t(enabledProjectFiles) => {\r\n\t\tconst ret: Record<string, boolean> = {}\r\n\t\tfor (const [fileId, enabled] of Object.entries(enabledProjectFiles)) {\r\n\t\t\tret[fileId] = enabled === true || enabled === undefined\r\n\t\t}\r\n\t\treturn ret\r\n\t},\r\n)\r\n\r\nexport const selectEnabledProjectFileMapping = (state: RootState) => state.projectFileReducer.projectFiles\r\n\r\nexport const selectProjectFiles = createSelector(\r\n\t[selectEnabledProjectFileMapping, selectActiveProjectId],\r\n\t(mapping, activeProjectId) => {\r\n\t\treturn Object.values(mapping)\r\n\t\t\t.filter((file) => file.project === activeProjectId)\r\n\t\t\t.sort((a, b) => a.z_index - b.z_index)\r\n\t},\r\n)\r\n\r\nexport const selectActiveProjectFileId: Selector<string | null> = (state: RootState) =>\r\n\tstate.projectFileReducer.activeProjectFileId\r\n\r\nexport const selectIsImportingProjectFile: Selector<boolean> = (state: RootState) =>\r\n\tstate.projectFileReducer.isImportingProjectFile\r\n\r\nexport const projectFileReducer: Reducer<ProjectFileState> = projectFileSlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport interface RehydratedState {\r\n\tisRehydrated: boolean\r\n}\r\n\r\nconst initialState: RehydratedState = {\r\n\tisRehydrated: false,\r\n}\r\n\r\n// rehydratedSlice is used to indicate when the Redux store has finished rehydrating its state from localForage\r\n// Once finished, the app renders, which prevents the annoying login screen flickering issue\r\nexport const rehydratedSlice = createSlice({\r\n\tname: \"rehydrated\",\r\n\tinitialState,\r\n\t// The `reducers` field lets us define reducers and generate associated actions\r\n\treducers: {\r\n\t\tsetRehydrated: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.isRehydrated = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\n// export const { setRehydrated } = rehydratedSlice.actions\r\n\r\n// The function below is called a selector and allows us to select a value from\r\n// the state. Selectors can also be defined inline where they're used instead of\r\n// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`\r\nexport const selectRehydrated = (state: RootState) => state.rehydratedReducer.isRehydrated\r\n\r\nexport const rehydratedReducer: Reducer<RehydratedState> = rehydratedSlice.reducer\r\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\nimport { Appearance, RootState } from \"../../typings\"\r\n\r\nexport interface SettingState {\r\n\tuseIssueTemplate: boolean\r\n\tplacementMode: boolean\r\n\tenableClustering: boolean\r\n\tsvgLayout: boolean\r\n\texpandedSections: Record<string, boolean>\r\n\tappearance: Appearance\r\n}\r\n\r\nconst initialState: SettingState = {\r\n\tuseIssueTemplate: false,\r\n\tplacementMode: false,\r\n\tenableClustering: true,\r\n\tsvgLayout: false,\r\n\texpandedSections: {\r\n\t\tIssues: true,\r\n\t\t\"Map Layers\": false,\r\n\t\tComponents: false,\r\n\t\tExperimental: false,\r\n\t},\r\n\tappearance: \"dark\",\r\n}\r\n\r\nexport const settingSlice = createSlice({\r\n\tname: \"settings\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetEnableDuplicateIssues: (state, action: PayloadAction<boolean>) => {\r\n\t\t\t// The logic here is the same as in workspaceSlice.ts. I want to create\r\n\t\t\t// a way for the store to know the state of a clicked button, and\r\n\t\t\t// in the future maybe other features of the application.\r\n\t\t\tstate.useIssueTemplate = action.payload\r\n\t\t},\r\n\t\tsetEnablePlacementMode: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.placementMode = action.payload\r\n\t\t},\r\n\t\tsetEnableSvgLayout: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.svgLayout = action.payload\r\n\t\t},\r\n\t\tsetSectionExpanded: (state, action: PayloadAction<Record<string, boolean>>) => {\r\n\t\t\tObject.assign(state.expandedSections, action.payload)\r\n\t\t},\r\n\t\tsetEnableClustering: (state, action: PayloadAction<boolean>) => {\r\n\t\t\tstate.enableClustering = action.payload\r\n\t\t},\r\n\t\tsetAppearance: (state, action: PayloadAction<\"dark\" | \"light\">) => {\r\n\t\t\tstate.appearance = action.payload\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\tsetEnableDuplicateIssues,\r\n\tsetEnablePlacementMode,\r\n\tsetSectionExpanded,\r\n\tsetEnableClustering,\r\n\tsetAppearance,\r\n} = settingSlice.actions\r\n\r\nexport const selectEnablePlacementMode = (state: RootState) => state.settingReducer.placementMode\r\nexport const selectEnableDuplicateIssues = (state: RootState) => state.settingReducer.useIssueTemplate\r\nexport const selectEnableSvgLayout = (state: RootState) => state.settingReducer.svgLayout\r\nexport const selectExpandedSections = (state: RootState) => state.settingReducer.expandedSections\r\nexport const selectEnableClustering = (state: RootState) => state.settingReducer.enableClustering\r\nexport const selectAppearance = (state: RootState) => state.settingReducer.appearance\r\nexport const settingReducer: Reducer<SettingState> = settingSlice.reducer\r\n","import { createSelector, createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\r\n\r\nimport {\r\n\tCachedUserForm,\r\n\tUserForm,\r\n\tUserFormRevision,\r\n\tUserFormSubmission,\r\n\tUserFormSubmissionAttachment,\r\n} from \"typings/models/forms\"\r\nimport { SearchArgs } from \"typings/search\"\r\nimport { Selector, SelectorWithArgs } from \"typings/store\"\r\nimport { shallowEqual } from \"react-redux\"\r\nimport { restructureCreateSelectorWithArgs } from \"utils/utils\"\r\nimport { RootState, Stored, Submitted } from \"../../typings\"\r\n\r\nconst LATEST_REVISION_CACHE: Record<string, UserFormRevision | null> = {}\r\n\r\nfunction considerCachingRevision(revision?: UserFormRevision | null, formId?: string, preferPending = false) {\r\n\tif (!revision) {\r\n\t\tif (!formId) {\r\n\t\t\tthrow new Error(\"If revision is null, formId is required.\")\r\n\t\t}\r\n\t\tconst currentLatestRevision = getLatestRevisionFromCache(formId)\r\n\t\tif (currentLatestRevision) return\r\n\t\tLATEST_REVISION_CACHE[formId] = null\r\n\t\treturn\r\n\t}\r\n\tif (revision.revision === \"Pending\") {\r\n\t\tif (preferPending) {\r\n\t\t\tLATEST_REVISION_CACHE[revision.form] = revision\r\n\t\t}\r\n\t\treturn\r\n\t}\r\n\tconst cachedRevision = LATEST_REVISION_CACHE[revision.form]?.revision\r\n\tif (revision.revision > (typeof cachedRevision === \"number\" ? cachedRevision : -1)) {\r\n\t\tLATEST_REVISION_CACHE[revision.form] = revision\r\n\t}\r\n}\r\n\r\nfunction getLatestRevisionFromCache(formId: string): UserFormRevision | null | undefined {\r\n\treturn LATEST_REVISION_CACHE[formId]\r\n}\r\n\r\nexport interface UserFormState {\r\n\tuserForms: Record<string, Stored<UserForm>>\r\n\tsubmissions: Record<string, UserFormSubmission>\r\n\tsubmissionAttachments: Record<UserFormSubmission[\"offline_id\"], UserFormSubmissionAttachment[]>\r\n\trevisions: Record<string, UserFormRevision>\r\n}\r\n\r\nconst initialState: UserFormState = {\r\n\tuserForms: {},\r\n\trevisions: {},\r\n\tsubmissions: {},\r\n\tsubmissionAttachments: {},\r\n}\r\n\r\nexport const userFormSlice = createSlice({\r\n\tname: \"userForms\",\r\n\tinitialState,\r\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\r\n\treducers: {\r\n\t\tsetUserForms: (state, action: { payload: Submitted<UserForm>[] }) => {\r\n\t\t\tstate.userForms = {}\r\n\t\t\taction.payload.forEach((userForm) => {\r\n\t\t\t\tstate.userForms[userForm.offline_id] = userForm\r\n\t\t\t})\r\n\t\t},\r\n\t\taddUserForm: (state, action: { payload: Submitted<UserForm> }) => {\r\n\t\t\tstate.userForms[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\taddUserForms: (state, action: { payload: Submitted<UserForm>[] }) => {\r\n\t\t\taction.payload.forEach((userForm) => {\r\n\t\t\t\tstate.userForms[userForm.offline_id] = userForm\r\n\t\t\t})\r\n\t\t},\r\n\t\taddUserFormRevisions: (state, action: { payload: UserFormRevision[] }) => {\r\n\t\t\taction.payload.forEach((userFormRevision) => {\r\n\t\t\t\tstate.revisions[userFormRevision.offline_id] = userFormRevision\r\n\t\t\t\tconsiderCachingRevision(userFormRevision)\r\n\t\t\t})\r\n\t\t},\r\n\t\taddUserFormRevision: (state, action: PayloadAction<UserFormRevision>) => {\r\n\t\t\tstate.revisions[action.payload.offline_id] = action.payload\r\n\t\t\tconsiderCachingRevision(action.payload)\r\n\t\t},\r\n\t\tdeleteUserFormRevision: (state, action: PayloadAction<string>) => {\r\n\t\t\tdelete state.revisions[action.payload]\r\n\t\t\tdelete LATEST_REVISION_CACHE[action.payload]\r\n\t\t},\r\n\t\tdeleteUserFormRevisions: (state, action: { payload: UserFormRevision[] }) => {\r\n\t\t\tfor (const userFormRevision of action.payload) {\r\n\t\t\t\tdelete state.revisions[userFormRevision.offline_id]\r\n\t\t\t\tdelete LATEST_REVISION_CACHE[userFormRevision.offline_id]\r\n\t\t\t}\r\n\t\t},\r\n\t\taddUserFormSubmission: (state, action: { payload: UserFormSubmission }) => {\r\n\t\t\tstate.submissions[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\taddUserFormSubmissionAttachment: (state, action: { payload: UserFormSubmissionAttachment }) => {\r\n\t\t\tconst submissionId = action.payload.submission\r\n\t\t\tconst submissionAttachments = state.submissionAttachments[submissionId]\r\n\t\t\tif (submissionAttachments) {\r\n\t\t\t\tsubmissionAttachments.push(action.payload)\r\n\t\t\t} else {\r\n\t\t\t\tstate.submissionAttachments[submissionId] = [action.payload]\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetUserFormSubmissionAttachments: (state, action: { payload: UserFormSubmissionAttachment[] }) => {\r\n\t\t\tstate.submissionAttachments = {}\r\n\t\t\tfor (const attachment of action.payload) {\r\n\t\t\t\tconst submissionId = attachment.submission\r\n\t\t\t\tconst submissionAttachments = state.submissionAttachments[submissionId]\r\n\t\t\t\tif (submissionAttachments) {\r\n\t\t\t\t\tsubmissionAttachments.push(attachment)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstate.submissionAttachments[submissionId] = [attachment]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\tdeleteUserFormSubmission: (state, action: PayloadAction<string>) => {\r\n\t\t\tdelete state.submissions[action.payload]\r\n\t\t},\r\n\t\tdeleteUserFormSubmissions: (state, action: { payload: UserFormSubmission[] }) => {\r\n\t\t\tfor (const userFormSubmission of action.payload) {\r\n\t\t\t\tdelete state.submissions[userFormSubmission.offline_id]\r\n\t\t\t}\r\n\t\t},\r\n\t\taddUserFormSubmissions: (state, action: { payload: UserFormSubmission[] }) => {\r\n\t\t\tfor (const submission of action.payload) {\r\n\t\t\t\tstate.submissions[submission.offline_id] = submission\r\n\t\t\t}\r\n\t\t},\r\n\t\tsetUserFormSubmissions: (state, action: { payload: UserFormSubmission[] }) => {\r\n\t\t\tstate.submissions = {}\r\n\t\t\taction.payload.forEach((submission) => {\r\n\t\t\t\tstate.submissions[submission.offline_id] = submission\r\n\t\t\t})\r\n\t\t},\r\n\t\tfavoriteForm: (state, action: { payload: { formId: string } }) => {\r\n\t\t\tconst { formId } = action.payload\r\n\t\t\tconst form = state.userForms[formId]\r\n\t\t\tif (!form) {\r\n\t\t\t\tthrow new Error(\"No form exists with the id \" + formId)\r\n\t\t\t}\r\n\t\t\tform.favorite = true\r\n\t\t},\r\n\t\tunfavoriteForm: (state, action: { payload: { formId: string } }) => {\r\n\t\t\tconst { formId } = action.payload\r\n\t\t\tconst form = state.userForms[formId]\r\n\t\t\tif (!form) {\r\n\t\t\t\tthrow new Error(\"No form exists with the id \" + formId)\r\n\t\t\t}\r\n\t\t\tform.favorite = false\r\n\t\t},\r\n\t\tdeleteUserForm: (state, action: { payload: string }) => {\r\n\t\t\tdelete state.userForms[action.payload]\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const {\r\n\taddUserForm,\r\n\taddUserForms,\r\n\taddUserFormRevisions,\r\n\taddUserFormSubmission,\r\n\taddUserFormSubmissions,\r\n\tdeleteUserFormSubmission,\r\n\tdeleteUserFormSubmissions,\r\n\tfavoriteForm,\r\n\tunfavoriteForm,\r\n\tdeleteUserForm,\r\n\tdeleteUserFormRevision,\r\n\tdeleteUserFormRevisions,\r\n\tsetUserFormSubmissions,\r\n\taddUserFormRevision,\r\n\taddUserFormSubmissionAttachment,\r\n\tsetUserFormSubmissionAttachments,\r\n} = userFormSlice.actions\r\n\r\nexport type UserFormSearchArgs = SearchArgs<{\r\n\t/** `undefined` means don't filter by favorite. `boolean` filters forms. */\r\n\tfavorites?: boolean\r\n\t/** organization owner */\r\n\towner_organization?: number\r\n\t/** user owner */\r\n\towner_user?: number\r\n}>\r\n\r\nexport const selectSubmissionAttachments: SelectorWithArgs<string, UserFormSubmissionAttachment[]> =\r\n\t(submissionId: string) => (state: RootState) => {\r\n\t\treturn state.userFormReducer.submissionAttachments[submissionId] || []\r\n\t}\r\n\r\nexport const selectFilteredUserForms: SelectorWithArgs<UserFormSearchArgs, CachedUserForm[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[\r\n\t\t\t\t(state: RootState) => state.userFormReducer.userForms,\r\n\t\t\t\t(state: RootState) => state.userFormReducer.revisions,\r\n\t\t\t\t(_state: RootState, search: UserFormSearchArgs) => search,\r\n\t\t\t],\r\n\t\t\t(userForms, revisions, search) => {\r\n\t\t\t\tconst { searchTerm, maxResults, favorites, owner_organization, owner_user } = search\r\n\r\n\t\t\t\tconst favoriteMatches: CachedUserForm[] = []\r\n\t\t\t\tconst regularMatches: CachedUserForm[] = []\r\n\r\n\t\t\t\tfor (const [userFormId, userForm] of Object.entries(userForms)) {\r\n\t\t\t\t\t// if filtering by favorites, skip forms with the wrong favorite status\r\n\t\t\t\t\tif (favorites !== undefined && userForm.favorite != favorites) continue\r\n\r\n\t\t\t\t\t// if filtering by organizations, skip forms with the wrong organization\r\n\t\t\t\t\tif (Number.isInteger(owner_organization) && owner_organization !== userForm.owner_organization) {\r\n\t\t\t\t\t\tcontinue\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// if filtering by owners, skip forms with the wrong owner\r\n\t\t\t\t\tif (Number.isInteger(owner_user) && owner_user !== userForm.owner_user) continue\r\n\r\n\t\t\t\t\t// find the latest revision for this form (note: expensive)\r\n\t\t\t\t\tconst latestRevision = _selectLatestFormRevision(revisions, userFormId)\r\n\r\n\t\t\t\t\tif (latestRevision.title.toLowerCase().includes(searchTerm.toLowerCase())) {\r\n\t\t\t\t\t\tif (userForm.favorite) {\r\n\t\t\t\t\t\t\tfavoriteMatches.push({ ...userForm, latestRevision: latestRevision })\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tregularMatches.push({ ...userForm, latestRevision: latestRevision })\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// if we've found enough matches, stop searching\r\n\t\t\t\t\t// only count favorites as favorites are displayed first\r\n\t\t\t\t\tif (favoriteMatches.length >= maxResults) {\r\n\t\t\t\t\t\tbreak\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst maxRegularMatches = maxResults - favoriteMatches.length\r\n\r\n\t\t\t\treturn [...favoriteMatches, ...regularMatches.slice(0, maxRegularMatches)]\r\n\t\t\t},\r\n\t\t\t// as the argument is an object, we check the first level of properties for equality\r\n\t\t\t{ memoizeOptions: { equalityCheck: shallowEqual } },\r\n\t\t),\r\n\t)\r\n\r\nexport const selectFormRevision: SelectorWithArgs<string, UserFormRevision> =\r\n\t(revisionId: string) => (state: RootState) => {\r\n\t\treturn state.userFormReducer.revisions[revisionId]\r\n\t}\r\n\r\n// takes user form state revisions instead of the whole state as an argument\r\nconst _selectLatestFormRevision = (revisions: UserFormState[\"revisions\"], formId: string): UserFormRevision => {\r\n\tlet ret: UserFormRevision | null = null\r\n\r\n\tfor (const candidate of Object.values(revisions)) {\r\n\t\tif (candidate.form === formId && (!ret || ret.revision < candidate.revision)) {\r\n\t\t\tret = candidate\r\n\t\t}\r\n\t}\r\n\r\n\tif (!ret) {\r\n\t\tthrow new Error(\"No revision found for form \" + formId)\r\n\t}\r\n\r\n\treturn ret\r\n}\r\n\r\nexport const selectLatestFormRevision: SelectorWithArgs<string, UserFormRevision> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector(\r\n\t\t[(state: RootState) => state.userFormReducer.revisions, (_state: RootState, formId: string) => formId],\r\n\t\t(revisions, formId) => {\r\n\t\t\tif (!formId) {\r\n\t\t\t\tthrow new Error(\"formId is required\")\r\n\t\t\t}\r\n\r\n\t\t\treturn _selectLatestFormRevision(revisions, formId)\r\n\t\t},\r\n\t),\r\n)\r\n\r\nexport const selectUserForm: SelectorWithArgs<string, Stored<UserForm>> = (formId: string) => (state: RootState) => {\r\n\treturn state.userFormReducer.userForms[formId]\r\n}\r\n\r\nconst selectSubmissionMapping = (state: RootState) => state.userFormReducer.submissions\r\nconst selectSubmissions = createSelector([selectSubmissionMapping], (submissions) => Object.values(submissions))\r\nconst selectRevisionMapping = (state: RootState) => state.userFormReducer.revisions\r\n\r\nconst selectRevisions = createSelector([selectRevisionMapping], (revisions) => Object.values(revisions))\r\n\r\nexport const selectRevisionsForForm: SelectorWithArgs<string, UserFormRevision[]> = restructureCreateSelectorWithArgs(\r\n\tcreateSelector([selectRevisions, (_state: RootState, formId: string) => formId], (revisions, formId) => {\r\n\t\treturn revisions.filter((revision) => {\r\n\t\t\treturn revision.form === formId\r\n\t\t})\r\n\t}),\r\n)\r\n\r\nexport const selectSubmissionsForForm: SelectorWithArgs<string, UserFormSubmission[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[selectSubmissions, selectRevisionMapping, (_state: RootState, formId: string) => formId],\r\n\t\t\t(submissions, revisionMapping, formId) => {\r\n\t\t\t\treturn Object.values(submissions).filter((submission) => {\r\n\t\t\t\t\tconst revision = revisionMapping[submission.form_revision]\r\n\t\t\t\t\treturn revision?.form === formId\r\n\t\t\t\t})\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectSubmissionsForIssue: SelectorWithArgs<string, UserFormSubmission[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[(state: RootState) => state.userFormReducer.submissions, (_state: RootState, issueId: string) => issueId],\r\n\t\t\t(submissions, issueId) => {\r\n\t\t\t\treturn Object.values(submissions).filter((submission) => {\r\n\t\t\t\t\treturn submission.issue === issueId\r\n\t\t\t\t})\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectSubmissionsForComponent: SelectorWithArgs<string, UserFormSubmission[]> =\r\n\trestructureCreateSelectorWithArgs(\r\n\t\tcreateSelector(\r\n\t\t\t[selectSubmissions, (_state: RootState, componentId: string) => componentId],\r\n\t\t\t(submissions, componentId) => {\r\n\t\t\t\treturn submissions.filter((submission) => {\r\n\t\t\t\t\treturn submission.component === componentId\r\n\t\t\t\t})\r\n\t\t\t},\r\n\t\t),\r\n\t)\r\n\r\nexport const selectUserFormMapping: Selector<Record<Stored<UserForm>[\"offline_id\"], UserForm>> = (state: RootState) => {\r\n\treturn state.userFormReducer.userForms\r\n}\r\n\r\nexport const selectLatestRevisionByFormId: Selector<Record<Stored<UserForm>[\"offline_id\"], UserFormRevision>> =\r\n\tcreateSelector([selectRevisionMapping], (revisions) => {\r\n\t\tconst latestRevisions: Record<string, UserFormRevision> = {}\r\n\t\tfor (const revision of Object.values(revisions)) {\r\n\t\t\tconst formId = revision.form\r\n\t\t\tconst currentLatestRevision = latestRevisions[formId]\r\n\t\t\tif (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {\r\n\t\t\t\tlatestRevisions[formId] = revision\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn latestRevisions\r\n\t})\r\n\r\nexport const selectNumberOfUserForms: Selector<number> = createSelector([selectUserFormMapping], (userForms) => {\r\n\treturn Object.keys(userForms).length\r\n})\r\n\r\nexport const userFormReducer: Reducer<UserFormState> = userFormSlice.reducer\r\n","import { EmailDomain, Selector, RootState } from \"../../typings\"\r\nimport { createSlice, Reducer } from \"@reduxjs/toolkit\"\r\n\r\nexport interface EmailDomainState {\r\n\temailDomains: Record<string, EmailDomain>\r\n}\r\n\r\nconst initialState: EmailDomainState = {\r\n\temailDomains: {},\r\n}\r\n\r\nexport const emailDomainsSlice = createSlice({\r\n\tname: \"emailDomains\",\r\n\tinitialState,\r\n\treducers: {\r\n\t\tsetEmailDomains: (state, action: { payload: EmailDomain[] }) => {\r\n\t\t\tconst emailDomains: Record<string, EmailDomain> = {}\r\n\t\t\taction.payload.forEach((emailDomain) => {\r\n\t\t\t\temailDomains[emailDomain.offline_id] = emailDomain\r\n\t\t\t})\r\n\t\t\tstate.emailDomains = emailDomains\r\n\t\t},\r\n\t\taddEmailDomain: (state, action: { payload: EmailDomain }) => {\r\n\t\t\tstate.emailDomains[action.payload.offline_id] = action.payload\r\n\t\t},\r\n\t\tremoveEmailDomain: (state, action: { payload: EmailDomain }) => {\r\n\t\t\tif (action.payload.offline_id in state.emailDomains) {\r\n\t\t\t\tdelete state.emailDomains[action.payload.offline_id]\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error(`Tried to remove email domain with ID that doesn't exist: ${action.payload.offline_id}`)\r\n\t\t\t}\r\n\t\t},\r\n\t},\r\n})\r\n\r\nexport const { setEmailDomains, addEmailDomain, removeEmailDomain } = emailDomainsSlice.actions\r\n\r\nexport const selectEmailDomainsAsMapping: Selector<Record<number, EmailDomain>> = (state: RootState) =>\r\n\tstate.emailDomainsReducer.emailDomains\r\n\r\nexport const selectSortedEmailDomains: Selector<EmailDomain[]> = (state: RootState) =>\r\n\tObject.values(state.emailDomainsReducer.emailDomains).sort((ed1: EmailDomain, ed2: EmailDomain) =>\r\n\t\ted1.domain.localeCompare(ed2.domain),\r\n\t)\r\n\r\nexport const emailDomainsReducer: Reducer<EmailDomainState> = emailDomainsSlice.reducer\r\n","import { createSlice, Reducer } from \"@reduxjs/toolkit\"\r\n\r\nexport interface VersioningState {\r\n\tversion: number\r\n}\r\n\r\nconst initialState: VersioningState = {\r\n\tversion: 0,\r\n}\r\n\r\n/**\r\n * Version of the offline redux store\r\n */\r\nexport const versioningSlice = createSlice({\r\n\tname: \"versioning\",\r\n\tinitialState,\r\n\treducers: {},\r\n})\r\n\r\nexport const versioningReducer: Reducer<VersioningState> = versioningSlice.reducer\r\n","// NOTE: Also update $full-component-marker-size in src/theme/_variables.sass\r\nexport const fullComponentMarkerSize = 45 // px\r\n","import { IssuePriority, IssueStatus } from \"../enums\"\r\n\r\nexport const DEFAULT_ISSUE_STATUS = IssueStatus.BACKLOG\r\nexport const DEFAULT_ISSUE_PRIORITY = IssuePriority.MEDIUM\r\n","export const OUTBOX_RETRY_DELAY = 5000 // milliseconds\r\n","import { AnyAction, applyMiddleware, compose, Reducer } from \"redux\"\r\nimport { offline } from \"@redux-offline/redux-offline\"\r\nimport offlineConfig from \"@redux-offline/redux-offline/lib/defaults\"\r\nimport localforage from \"localforage\"\r\nimport createMigration from \"redux-persist-migrate\"\r\nimport { combineReducers, configureStore, createNextState } from \"@reduxjs/toolkit\"\r\nimport {\r\n\tConfig,\r\n\tOfflineAction,\r\n\tOfflineMetadata,\r\n\tOfflineState,\r\n\tResultAction,\r\n} from \"@redux-offline/redux-offline/lib/types\"\r\nimport request from \"superagent\"\r\nimport { HttpMethod } from \"../enums\"\r\nimport { manifest } from \"./migrations\"\r\n\r\n// There are two \"blobs\": The Blob type from the \"buffer\" package (part of node),\r\n// and the Blob type from the browser. For some reason, superagent uses the \"buffer\"\r\n// version after moving code from hemora-web to overmap-core. This overwrites the name\r\n// \"Blob\". There are minor differences between the two interfaces (remove the type casting\r\n// of the `file` argument to `req.field()` in performRequest() to see the error), but it's\r\n// unlikely that we'll run into any problems.\r\nimport { Blob } from \"buffer\"\r\nimport {\r\n\tAPIError,\r\n\tmakeClient,\r\n\ttype OfflineMetaEffect,\r\n\tOutboxCoordinator,\r\n\ttype OvermapSDK,\r\n\tRequestDetails,\r\n} from \"../sdk\"\r\nimport { ToastProps, unsafeShowToast } from \"@overmap-ai/blocks\"\r\nimport {\r\n\t_setLatestRetryTime,\r\n\tauthReducer,\r\n\tcategoryReducer,\r\n\tcomponentReducer,\r\n\tcomponentStageCompletionReducer,\r\n\tcomponentStageReducer,\r\n\tcomponentTypeReducer,\r\n\tfileReducer,\r\n\tissueReducer,\r\n\tmapReducer,\r\n\tmarkAsDeleted,\r\n\torganizationAccessReducer,\r\n\torganizationReducer,\r\n\toutboxReducer,\r\n\tprojectAccessReducer,\r\n\tprojectFileReducer,\r\n\tprojectReducer,\r\n\trehydratedReducer,\r\n\tselectAccessToken,\r\n\tselectCategoriesOfWorkspace,\r\n\tselectMainWorkspace,\r\n\tsettingReducer,\r\n\tuserFormReducer,\r\n\tuserReducer,\r\n\tworkspaceReducer,\r\n\temailDomainsReducer,\r\n} from \"./slices\"\r\nimport { versioningReducer } from \"./slices/versioningSlice\"\r\nimport { clientStore } from \"contexts\"\r\nimport { OUTBOX_RETRY_DELAY } from \"../constants\"\r\nimport { RootState } from \"../typings\"\r\n\r\n// NOTE: If changing, also change it in migrations.ts (avoid circular imports)\r\nconst VERSION_REDUCER_KEY = \"versioning\"\r\n\r\nexport const overmapReducers = {\r\n\t// TODO: attachmentReducer,\r\n\t[VERSION_REDUCER_KEY]: versioningReducer,\r\n\tfileReducer,\r\n\tauthReducer,\r\n\tcategoryReducer,\r\n\tcomponentReducer,\r\n\tcomponentStageCompletionReducer,\r\n\tcomponentStageReducer,\r\n\tcomponentTypeReducer,\r\n\tissueReducer,\r\n\tmapReducer,\r\n\torganizationReducer,\r\n\toutboxReducer,\r\n\tprojectReducer,\r\n\tprojectAccessReducer,\r\n\torganizationAccessReducer,\r\n\tprojectFileReducer,\r\n\trehydratedReducer,\r\n\tsettingReducer,\r\n\tuserFormReducer,\r\n\tuserReducer,\r\n\tworkspaceReducer,\r\n\temailDomainsReducer,\r\n} as const\r\n\r\nexport const overmapReducer = combineReducers(overmapReducers)\r\n\r\n// Special action to revert all slices to their initial state. A reducer for this is added to each slice using\r\n// `extraReducers` in the slice definition.\r\nexport const resetStore = \"RESET\"\r\n\r\nfunction handleWorkspaceRemoval(draft: RootState, action: AnyAction): void {\r\n\tconst workspaceId = (action as AnyAction & { payload: string }).payload\r\n\tconst issuesVisibleInWorkspace = Object.values(draft.issueReducer.issues).filter((issue) =>\r\n\t\tissue.visible_in_workspaces.includes(workspaceId),\r\n\t)\r\n\r\n\tconst mainWorkspace = selectMainWorkspace(draft)\r\n\tif (!mainWorkspace) {\r\n\t\tthrow new Error(\"Main workspace not found\")\r\n\t}\r\n\tif (action.payload === mainWorkspace.offline_id) {\r\n\t\tthrow new Error(\"Tried to delete main workspace\")\r\n\t}\r\n\r\n\t// Find categories about to be deleted. If the issue has this category, we will have to remove it.\r\n\tconst categoriesInThisWorkspace = new Set<string>(\r\n\t\t(selectCategoriesOfWorkspace(workspaceId)(draft) ?? []).map((category) => category.offline_id),\r\n\t)\r\n\tfor (const issue of issuesVisibleInWorkspace) {\r\n\t\tif (issue.category && categoriesInThisWorkspace.has(issue.category)) {\r\n\t\t\tissue.category = null\r\n\t\t}\r\n\t}\r\n\r\n\t// If the deleted workspace was the index_workspace, we need to update the index_workspace to be the\r\n\t// main workspace.\r\n\t// NOTE: Issues are always visible in the index_workspace, so we can expect to find the index_workspace\r\n\t// in visible_in_workspaces.\r\n\tconst issuesWithThisWorkspaceIndex = issuesVisibleInWorkspace.filter(\r\n\t\t(issue) => issue.index_workspace === action.payload,\r\n\t)\r\n\r\n\tfor (const issue of issuesWithThisWorkspaceIndex) {\r\n\t\t// NOTE: Indexes of WorkspaceIndexedModels are updated after a reload in the workspace service. For now,\r\n\t\t// we'll just update the index_workspace of indexed models (currently issues and forms).\r\n\t\tissue.index_workspace = mainWorkspace.offline_id\r\n\t\tif (!issue.visible_in_workspaces.includes(mainWorkspace.offline_id)) {\r\n\t\t\tissue.visible_in_workspaces.push(mainWorkspace.offline_id)\r\n\t\t}\r\n\t}\r\n\r\n\t// Remove the workspace from the visible_in_workspaces of all issues\r\n\tfor (const issue of issuesVisibleInWorkspace) {\r\n\t\tconst indexOfWorkspace = issue.visible_in_workspaces.indexOf(workspaceId)\r\n\t\tif (indexOfWorkspace === -1) {\r\n\t\t\t// This is unexpected because we already filtered by visible_in_workspaces.\r\n\t\t\tthrow new Error(\"Workspace not found in issue's visible_in_workspaces\")\r\n\t\t}\r\n\t\tissue.visible_in_workspaces.splice(indexOfWorkspace, 1)\r\n\t}\r\n\r\n\t// Lastly, some sanity checks to make sure we didn't miss anything.\r\n\tfor (const issue of issuesVisibleInWorkspace) {\r\n\t\tif (issue.visible_in_workspaces.length === 0) {\r\n\t\t\tthrow new Error(`Unexpected error: Issue ${issue.offline_id} has no visible_in_workspaces`)\r\n\t\t}\r\n\t\tif (issue.index_workspace === action.payload || !issue.index_workspace) {\r\n\t\t\tthrow new Error(`Failed to update index_workspace of issue ${issue.offline_id} to main workspace`)\r\n\t\t}\r\n\t}\r\n\r\n\tconst indexedForms = Object.values(draft.userFormReducer.userForms).filter(\r\n\t\t(form) => form.index_workspace === workspaceId,\r\n\t)\r\n\t// Update the index_workspace of all forms that are indexed by the workspace being removed\r\n\tfor (const form of indexedForms) {\r\n\t\tform.index_workspace = mainWorkspace.offline_id\r\n\t}\r\n}\r\n\r\n// Clear the store and reset all reducers on logout\r\nexport const rootReducer: Reducer<RootState> = (state, action): RootState => {\r\n\tif (action.type === \"auth/setLoggedIn\" && !action.payload) {\r\n\t\treturn overmapReducer(undefined, action) as RootState\r\n\t}\r\n\r\n\tlet mutatedState = state\r\n\r\n\tif (state && action.type === \"workspace/removeWorkspace\") {\r\n\t\tmutatedState = createNextState(state, (draft) => {\r\n\t\t\thandleWorkspaceRemoval(draft, action)\r\n\t\t})\r\n\t}\r\n\r\n\treturn overmapReducer(mutatedState, action) as RootState\r\n}\r\n\r\nexport interface FullOfflineMetadata extends OfflineMetadata {\r\n\teffect: OfflineMetaEffect\r\n}\r\n\r\nexport interface FullOfflineAction extends OfflineAction {\r\n\tmeta: { offline: FullOfflineMetadata }\r\n\t// Redundantly store request details in the unused `payload` property to make TypeScript happy\r\n\tpayload: RequestDetails\r\n}\r\n\r\nlet __OUTBOX_COORDINATOR: OutboxCoordinator | null = null\r\n\r\nfunction _getOutboxCoordinator(): OutboxCoordinator {\r\n\tif (!__OUTBOX_COORDINATOR) {\r\n\t\t__OUTBOX_COORDINATOR = new OutboxCoordinator()\r\n\t}\r\n\treturn __OUTBOX_COORDINATOR\r\n}\r\n\r\n// This callback is run when the Redux store has finished rehydrating itself from localForage\r\n// We signal to the rest of the app that hydration has finished\r\nconst persistCallback = (err: null | Error) => {\r\n\tif (err) throw err\r\n\tif (clientStore) {\r\n\t\tclientStore.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\r\n\t} else {\r\n\t\tconsole.error(\"Client store not set\")\r\n\t}\r\n}\r\n\r\nexport const enqueue: Config[\"queue\"][\"enqueue\"] = (_array, item, _context) => {\r\n\tconst coordinator = _getOutboxCoordinator()\r\n\tcoordinator.addRequest(item as FullOfflineAction)\r\n\treturn coordinator.getQueue()\r\n}\r\n\r\nexport const dequeue: Config[\"queue\"][\"dequeue\"] = (_array, item, _context) => {\r\n\tconst coordinator = _getOutboxCoordinator()\r\n\t// The redux-offline type leaves out the \"offlineAction\" property\r\n\ttype BadMetaType = ResultAction[\"meta\"]\r\n\ttype CorrectedMetaType = BadMetaType & { offlineAction: FullOfflineAction }\r\n\tconst meta = item.meta as CorrectedMetaType\r\n\tconst uuid = meta.offlineAction.payload.uuid\r\n\tcoordinator.remove(uuid)\r\n\treturn coordinator.getQueue()\r\n}\r\n\r\n// This is called an \"effect reconciler\", and it turns an offline action into a real API request\r\nasync function effect(_effect: OfflineMetaEffect, action: FullOfflineAction) {\r\n\t// REASON: Handling of unexpected case\r\n\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\r\n\tif (!action.payload) {\r\n\t\tthrow new Error(\"Received empty payload\")\r\n\t}\r\n\r\n\t// We pass the action through a chain of middleware, which can do some useful things and then perform the action.\r\n\t// `runMiddleware` returns a Promise<Response> if everything goes well.\r\n\treturn runMiddleware(action)\r\n}\r\n\r\nconst customConfig: Partial<Config> = {\r\n\t...offlineConfig,\r\n\teffect: effect as Config[\"effect\"],\r\n\t// Casting needed because we are saving FullOfflineAction objects, not just OfflineAction objects,\r\n\t// but redux-offline does not know this.\r\n\tdiscard: discard as Config[\"discard\"],\r\n\treturnPromises: true,\r\n\tpersistCallback,\r\n\tretry: retry as Config[\"retry\"],\r\n\t// Modify the configuration of the offline store to use localforage\r\n\t// which uses IndexedDB by default (persists even on mobile when installed as a PWA, unlike localStorage)\r\n\tpersistOptions: { storage: localforage },\r\n\t// TODO: custom enqueue implementation to take care of intelligently cancelling \"create/delete same issue\",\r\n\t// and custom dequeue for e.g. if user insists on removing a failed a \"create issue\", then remove the \"edit\r\n\t// that same issue\"\r\n\tqueue: {\r\n\t\t...offlineConfig.queue,\r\n\t\tenqueue,\r\n\t\tdequeue,\r\n\t\t// Bad typing, undefined is actually fine, and the action is a FullOfflineAction, not just an OfflineAction.\r\n\t\tpeek: (...args) => peek(...(args as Parameters<typeof peek>))!,\r\n\t} satisfies Config[\"queue\"],\r\n}\r\n\r\n// migration to compose into store\r\nconst migration = createMigration(manifest, VERSION_REDUCER_KEY) as (_: unknown) => unknown\r\n\r\n/**\r\n * Enhancer for the Redux store that adds offline support and needed middleware for overmap.\r\n * Add to your store's `enhancers` array.\r\n */\r\nexport const overmapEnhancer = compose(offline(customConfig), migration)\r\n\r\nexport const defaultStore = configureStore({\r\n\treducer: rootReducer,\r\n\tenhancers: [compose(applyMiddleware(), overmapEnhancer)],\r\n\tmiddleware: (getDefaultMiddleware) => {\r\n\t\treturn getDefaultMiddleware({\r\n\t\t\t// TODO: Enable periodically to find problems\r\n\t\t\tserializableCheck: false,\r\n\t\t\timmutableCheck: false,\r\n\t\t})\r\n\t},\r\n})\r\n\r\n/**\r\n * Makes a best-effort attempt to extract a request.Response from an error object.\r\n * @param error The error object\r\n */\r\nfunction extractResponseFromError(error: unknown): request.Response | undefined {\r\n\tfunction isResponse(response: unknown): response is request.Response {\r\n\t\t// Just some keys we know are on a request.Response\r\n\t\tconst knownKeys = [\"ok\", \"redirect\", \"clientError\", \"serverError\", \"error\"]\r\n\t\treturn typeof response === \"object\" && response !== null && knownKeys.every((key) => key in response)\r\n\t}\r\n\r\n\tif (isResponse(error)) return error\r\n\tif (typeof error === \"object\" && error !== null) {\r\n\t\tconst typedError = error as { response?: { response?: request.Response } }\r\n\t\tif (isResponse(typedError.response)) return typedError.response\r\n\t\tif (typedError.response && isResponse(typedError.response.response)) return typedError.response.response\r\n\t}\r\n\treturn undefined\r\n}\r\n\r\n/**\r\n * Makes a best-effort attempt to extract an error message from a request.Response or an error object.\r\n * @param errorRes The response object from a request, if available\r\n * @param err The error object, if available\r\n */\r\nfunction extractErrorMessage(errorRes: request.Response | undefined, err: unknown): string | undefined {\r\n\tif (errorRes?.body) {\r\n\t\tif (typeof errorRes.body === \"object\") {\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\r\n\t\t\tif (typeof errorRes.body.error === \"string\") return errorRes.body.error as string\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\r\n\t\t\tif (typeof errorRes.body.message === \"string\") return errorRes.body.message as string\r\n\t\t} else if (typeof errorRes.body === \"string\") return errorRes.body\r\n\t} else if (errorRes?.text) {\r\n\t\treturn errorRes.text\r\n\t} else if (err instanceof Error) {\r\n\t\treturn err.message\r\n\t}\r\n\treturn undefined\r\n}\r\n\r\n// Executes an offline action by making the API request specified in the action's offline metadata\r\nexport async function performRequest(action: FullOfflineAction, client: OvermapSDK): Promise<request.Response> {\r\n\t// Checks access token, renews if expiring soon\r\n\tasync function checkToken() {\r\n\t\t// TODO: If another check is already in progress, skip this check.\r\n\t\t// TODO: Enqueue\r\n\t\tif (client.auth.tokenIsExpiringSoon()) {\r\n\t\t\tawait client.auth.renewTokens()\r\n\t\t}\r\n\t}\r\n\r\n\tconst state: RootState = client.store.getState()\r\n\tif (state.outboxReducer.deletedRequests.includes(action.payload.uuid)) {\r\n\t\t// The request has been marked for deletion, so we don't want to perform it.\r\n\t\t// Instead, throw an error, so it will be retried and discarded in the `discard` function.\r\n\t\tthrow new Error(\"Request was marked for deletion\")\r\n\t}\r\n\r\n\tif (action.payload.checkAuth !== false) {\r\n\t\ttry {\r\n\t\t\tawait checkToken()\r\n\t\t} catch (e) {\r\n\t\t\tif (e instanceof APIError) {\r\n\t\t\t\t// Renewing tokens has failed; we should sign out the user.\r\n\t\t\t\tawait client.auth.logout()\r\n\t\t\t\treturn Promise.reject(e)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tconsole.debug(\"Done checking tokens\")\r\n\r\n\tconst defaultSettings = {\r\n\t\tqueryParams: \"\",\r\n\t\tisAuthNeeded: true,\r\n\t}\r\n\r\n\tconst offlineEffect = action.meta.offline.effect\r\n\tconst { payload, headers, method, queryParams, attachmentHash, isExternalUrl, isAuthNeeded, isResponseBlob } = {\r\n\t\t...defaultSettings,\r\n\t\t...offlineEffect.request,\r\n\t}\r\n\tconst requestDetails = offlineEffect.request\r\n\tlet url = requestDetails.url\r\n\tconst file = attachmentHash ? await client.files.fetchCache(attachmentHash) : undefined\r\n\tconst accessToken = selectAccessToken(state)\r\n\r\n\tif (attachmentHash && !file) {\r\n\t\tthrow new Error(`Cannot upload file ${attachmentHash} because it's not cached.`)\r\n\t}\r\n\r\n\tif ((!isExternalUrl || import.meta.env.DEV) && !url.startsWith(\"http\")) {\r\n\t\tif (!url.startsWith(\"/\") && !url.startsWith(\"blob:\")) {\r\n\t\t\turl = \"/\" + url\r\n\t\t\tif (import.meta.env.DEV) {\r\n\t\t\t\tconsole.trace(`You have passed a host-relative URL: ${url}`)\r\n\t\t\t}\r\n\t\t}\r\n\t\turl = client.API_URL + url\r\n\t}\r\n\r\n\tconst addPayload = (req: request.SuperAgentRequest) => {\r\n\t\tif (attachmentHash) {\r\n\t\t\tconst s3url = requestDetails.s3url\r\n\t\t\tif (!s3url) throw new Error(`No S3 URL for file ${attachmentHash}`)\r\n\t\t\tif (\"warning\" in s3url) throw new Error(`S3 URL warning for file ${attachmentHash}`)\r\n\t\t\tif (!file) throw new Error(`No file for file ${attachmentHash}`)\r\n\t\t\tconst s3Sha1Checksum = s3url.fields[\"x-amz-checksum-sha1\"]\r\n\t\t\tif (!s3Sha1Checksum) throw new Error(`No checksum for file ${attachmentHash}`)\r\n\t\t\treturn req\r\n\t\t\t\t.set(\"x-amz-checksum-sha1\", s3Sha1Checksum)\r\n\t\t\t\t.field({ ...payload, ...s3url.fields })\r\n\t\t\t\t.attach(\"file\", file as unknown as Blob)\r\n\t\t}\r\n\t\treturn req.send(payload)\r\n\t}\r\n\r\n\tconst methodRequestMapping: Record<HttpMethod, () => request.SuperAgentRequest> = {\r\n\t\t[HttpMethod.GET]: () => {\r\n\t\t\tif (isResponseBlob) {\r\n\t\t\t\treturn request.get(url.toString()).responseType(\"blob\")\r\n\t\t\t}\r\n\t\t\treturn request.get(url.toString())\r\n\t\t},\r\n\t\t[HttpMethod.POST]: () => {\r\n\t\t\tconst ret = request.post(url.toString())\r\n\t\t\treturn addPayload(ret)\r\n\t\t},\r\n\t\t[HttpMethod.PATCH]: () => {\r\n\t\t\tconst ret = request.patch(url.toString())\r\n\t\t\treturn addPayload(ret)\r\n\t\t},\r\n\t\t[HttpMethod.PUT]: () => {\r\n\t\t\tconst ret = request.put(url.toString())\r\n\t\t\treturn addPayload(ret)\r\n\t\t},\r\n\t\t[HttpMethod.DELETE]: () => {\r\n\t\t\tconst ret = request.delete(url.toString())\r\n\t\t\treturn addPayload(ret)\r\n\t\t},\r\n\t}\r\n\r\n\tconst selectedRequest = methodRequestMapping[method]\r\n\r\n\tlet requestToSend = selectedRequest()\r\n\tif (isAuthNeeded) {\r\n\t\trequestToSend = requestToSend.set(\"Authorization\", `Bearer ${accessToken}`)\r\n\t}\r\n\tif (headers) {\r\n\t\trequestToSend = requestToSend.set(headers)\r\n\t}\r\n\r\n\ttry {\r\n\t\treturn await requestToSend.query(queryParams)\r\n\t} catch (error) {\r\n\t\t// Observed error types: Error, request.Response\r\n\t\t// If it's an Error, it has a `response.response` property that is a request.Response.\r\n\t\tconst errorResponse = extractResponseFromError(error)\r\n\t\tconst status: number | undefined = errorResponse?.status\r\n\r\n\t\tif (status === 401) {\r\n\t\t\tconsole.debug(\"Forbidden; renewing tokens and retrying.\")\r\n\t\t\ttry {\r\n\t\t\t\tawait client.auth.renewTokens()\r\n\t\t\t\tconsole.debug(\"Successfully renewed tokens; retrying request.\")\r\n\t\t\t\treturn await requestToSend.query(queryParams)\r\n\t\t\t} catch (error) {\r\n\t\t\t\tconsole.warn(\"Failed to renew tokens.\", error)\r\n\t\t\t\tconst loggedIn = state.authReducer.isLoggedIn\r\n\t\t\t\tif (loggedIn) {\r\n\t\t\t\t\tconsole.warn(\"Signing out already signed-in user.\")\r\n\t\t\t\t\tawait client.auth.logout()\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// This is only expected when signing in for the first time with invalid credentials.\r\n\t\t\t\t\tconsole.warn(\"No signed-in user to sign out.\")\r\n\t\t\t\t}\r\n\t\t\t\tthrow new APIError(\"You have been signed out due to inactivity.\", errorResponse, {\r\n\t\t\t\t\tdiscard: true,\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// TODO: Error codes for all APIErrors.\r\n\t\t// TODO: Constant for all messages.\r\n\t\tconst apiErrorMessage = extractErrorMessage(errorResponse, error) || \"An unexpected error occurred.\"\r\n\r\n\t\tthrow new APIError(apiErrorMessage, errorResponse, {\r\n\t\t\tdiscard: discardStatuses.includes(status!),\r\n\t\t})\r\n\t}\r\n}\r\n\r\ninterface MiddlewareChainer {\r\n\tthen: (next: OfflineMiddleware) => MiddlewareChainer\r\n\tcompile: () => OfflineMiddleware[]\r\n}\r\n\r\nclass MiddlewareChainerPrivate {\r\n\t_all: OfflineMiddleware[]\r\n\t_previous?: OfflineMiddleware\r\n\r\n\tconstructor(current: OfflineMiddleware) {\r\n\t\tthis._all = [current]\r\n\t\tthis._previous = current\r\n\t\tthis.then = this.then.bind(this)\r\n\t\tthis.compile = this.compile.bind(this)\r\n\t}\r\n\r\n\tthen(next: OfflineMiddleware): MiddlewareChainer {\r\n\t\tif (this._previous) this._previous.next = next // \"next\" is now \"current\"\r\n\t\tthis._all.push(next)\r\n\t\tthis._previous = next // \"next\" is now \"previous\"\r\n\r\n\t\treturn {\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/unbound-method\r\n\t\t\tthen: this.then,\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/unbound-method\r\n\t\t\tcompile: this.compile,\r\n\t\t}\r\n\t}\r\n\r\n\tcompile() {\r\n\t\treturn this._all\r\n\t}\r\n}\r\n\r\nabstract class OfflineMiddleware {\r\n\tnext: OfflineMiddleware | null\r\n\r\n\tconstructor() {\r\n\t\tthis.next = null\r\n\t}\r\n\r\n\tthen(next: OfflineMiddleware): MiddlewareChainer {\r\n\t\treturn new MiddlewareChainerPrivate(this).then(next)\r\n\t}\r\n\r\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\r\n\t\tif (this.next) {\r\n\t\t\treturn this.next.run(action)\r\n\t\t} else {\r\n\t\t\tconsole.debug(`All middleware finished with ${this.constructor.name}, performing request:`, action)\r\n\t\t\tconst baseUrl = action.meta.offline.effect.BASE_URL\r\n\t\t\tif (!clientStore) throw new Error(\"Client store not set\")\r\n\t\t\t// At the end of the middleware chain, we want to perform the action\r\n\t\t\treturn performRequest(action, makeClient(baseUrl, clientStore))\r\n\t\t}\r\n\t}\r\n}\r\n\r\nclass OfflineAnalyticsMiddleware extends OfflineMiddleware {\r\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\r\n\t\t// TODO: Store some statistics on which actions are called and enqueue reports periodically\r\n\t\treturn super.run(action)\r\n\t}\r\n}\r\n\r\nclass RateLimitingMiddleware extends OfflineMiddleware {\r\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\r\n\t\t// TODO: Consider rate limits (enable offline mode programmatically to reduce rate)\r\n\t\treturn super.run(action)\r\n\t}\r\n}\r\n\r\nconst allMiddleware = new OfflineAnalyticsMiddleware().then(new RateLimitingMiddleware()).compile()\r\n\r\nfunction runMiddleware(action: FullOfflineAction) {\r\n\treturn allMiddleware[0]?.run(action)\r\n}\r\n\r\n// These status codes are due to a fundamental problem that can never be corrected except by manual intervention.\r\n// TODO: 400 (Bad Request) should result in the user being given a chance to amend their request to be valid.\r\nconst discardStatuses = [400, 409, 403, 404]\r\nconst statusMessages: Record<number, ToastProps | undefined> = {\r\n\t403: { title: \"Forbidden\", description: \"You are not authorized to perform this action.\", severity: \"danger\" },\r\n\t404: { title: \"Not found\", description: \"The requested resource was not found.\", severity: \"danger\" },\r\n}\r\n\r\n// TODO:\r\n/*\r\nconst statusHandlers: Record<number, SimpleToastMessage> = {\r\n\t401: { title: \"You have been logged out\", description: \"Please log in again to continue using the app.\", element: <FormRenderer ...> },\r\n}\r\n */\r\n\r\n// Discard function is used by Redux Offline to decide whether to discard an action or not, based on the error\r\n// that the effect reconciler threw and/or the action\r\nexport function discard(reason: unknown, action: FullOfflineAction, retries = 0): boolean {\r\n\t// TODO: If 401, renew auth and return false\r\n\t// TODO: If 400, set state to rescue mode, allowing the user to fix the request and retry (or discard)\r\n\r\n\tconsole.debug(\r\n\t\t\"Considering discarding request due to error:\",\r\n\t\treason,\r\n\t\t`(${typeof reason})`,\r\n\t\t\"\\nAction:\",\r\n\t\taction,\r\n\t\t\"\\nRetries:\",\r\n\t\tretries,\r\n\t)\r\n\r\n\tif (!(reason instanceof Error)) {\r\n\t\tconsole.error(\r\n\t\t\t\"ENCOUNTERED NON-ERROR ERROR:\",\r\n\t\t\treason,\r\n\t\t\t\"(throwing immediately, which may lead to unexpected behavior)\",\r\n\t\t)\r\n\t\tthrow reason\r\n\t}\r\n\r\n\tconst state = clientStore!.getState()\r\n\tconst deletedRequests = state.outboxReducer.deletedRequests\r\n\tconst uuid = action.payload.uuid\r\n\r\n\t// NOTE: Doesn't really return true, but TypeScript doesn't need to know that.\r\n\t// Adding a `return true` would be meaningless since we are throwing the passed error.\r\n\tfunction rollbackAndThrow(): true {\r\n\t\tclientStore!.dispatch(markAsDeleted(uuid))\r\n\t\t_getOutboxCoordinator().remove(action.payload.uuid)\r\n\t\tconst rollbackAction = action.meta.offline.rollback\r\n\t\tif (rollbackAction) {\r\n\t\t\tconsole.warn(\"Rolling back request due to SDK error:\", action)\r\n\t\t\tclientStore!.dispatch(rollbackAction)\r\n\t\t}\r\n\t\tthrow reason\r\n\t}\r\n\r\n\tif (reason instanceof APIError && reason.options.discard) {\r\n\t\tconsole.debug(\"Discarding request due to explicit discard:\", action)\r\n\t\treturn rollbackAndThrow()\r\n\t}\r\n\r\n\tif (deletedRequests.includes(uuid)) {\r\n\t\tconsole.debug(\"Discarding request due to deletion:\", action)\r\n\t\treturn rollbackAndThrow()\r\n\t}\r\n\r\n\tif (reason instanceof APIError) {\r\n\t\tconst status: number | undefined = reason.status || reason.response?.status\r\n\t\tif (!status) {\r\n\t\t\tconsole.warn(\"Error has no status code:\", reason)\r\n\t\t}\r\n\t\tif (status !== undefined && discardStatuses.includes(status)) {\r\n\t\t\tconsole.warn(\"Discarding request due to error:\", reason, \"\\nAction:\", action)\r\n\t\t\tconst message = statusMessages[status]\r\n\t\t\tif (message) {\r\n\t\t\t\tif (unsafeShowToast) {\r\n\t\t\t\t\tunsafeShowToast(message)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconsole.error(`Could not display toast for status ${status} because there is no toast handle.`)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t_getOutboxCoordinator().remove(action.payload.uuid)\r\n\t\t\treason.options.discard = true\r\n\t\t\trollbackAndThrow()\r\n\t\t}\r\n\t}\r\n\r\n\tconsole.debug(\"Registering a retry for request:\", action.payload.uuid)\r\n\t// All failures due to any other reason should be retried indefinitely. It will not block the outbox thanks to\r\n\t// OutboxCoordinator.\r\n\t_getOutboxCoordinator().registerRetry(action.payload.uuid)\r\n\treturn false\r\n}\r\n\r\n// Peek function is used by Redux Offline to determine the next action of the outbox to execute.\r\n// We are overriding the default implementation (return array[0]) with our own to support our graph-based outbox.\r\nfunction peek(\r\n\t_array: FullOfflineAction[],\r\n\t_item: unknown,\r\n\t_context: { offline: OfflineState },\r\n): OfflineAction | undefined {\r\n\treturn _getOutboxCoordinator().peek()\r\n}\r\n\r\n// Retry function is used by Redux Offline to determine how long to retry an action, given number of retries\r\nfunction retry(_action: FullOfflineAction, _retries: number): number | undefined {\r\n\t// Always retry, but wait a few seconds after a failed request. We have our own custom discard/retry logic.\r\n\tclientStore!.dispatch(_setLatestRetryTime(new Date().getTime()))\r\n\treturn OUTBOX_RETRY_DELAY\r\n}\r\n\r\n// export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, RootState, unknown, Action<string>>\r\n","import { TypedUseSelectorHook, useDispatch, useSelector } from \"react-redux\"\r\nimport { AppDispatch, RootState } from \"../typings\"\r\n\r\n// Use throughout the app instead of plain `useDispatch` and `useSelector`\r\nexport const useAppDispatch = () => useDispatch<AppDispatch>()\r\n\r\nexport const useAppSelector: TypedUseSelectorHook<RootState> = useSelector\r\n","import request from \"superagent\"\r\nimport { DeferredPromise } from \"../../utils/async/DeferredPromise\"\r\nimport type { OvermapSDK } from \"../sdk\"\r\nimport { OfflineMetaEffect, SDKRequest } from \"../typings\"\r\nimport { discard, enqueueRequest, FullOfflineAction, performRequest } from \"../../store\"\r\nimport { APIError } from \"../errors.ts\"\r\nimport { v4 as uuidv4 } from \"uuid\"\r\n\r\n/**\r\n * Abstract base class for building a service that can enqueue API requests\r\n */\r\nexport abstract class BaseApiService {\r\n\tprotected readonly client: OvermapSDK\r\n\r\n\tconstructor(sdk: OvermapSDK) {\r\n\t\tthis.client = sdk\r\n\t}\r\n\r\n\t/**\r\n\t * Enqueues an API request to the offline outbox.\r\n\t * @param requestDetails An SDKRequest object containing the details of the request.\r\n\t * @protected\r\n\t */\r\n\tprotected async enqueueRequest<TResult>(requestDetails: SDKRequest): Promise<TResult> {\r\n\t\t// enqueueRequest is a wrapper for _enqueueRequest that ensures the result is not an APIError unless\r\n\t\t// `.catch()` is triggered.\r\n\t\treturn this._enqueueRequest<TResult>(requestDetails).then((result) => {\r\n\t\t\tif (result instanceof APIError) {\r\n\t\t\t\tthrow result\r\n\t\t\t}\r\n\t\t\treturn result\r\n\t\t})\r\n\t}\r\n\r\n\t/**\r\n\t * Enqueues an API request to the Redux Offline outbox\r\n\t * @protected\r\n\t */\r\n\tprivate _enqueueRequest<TResult>(requestDetails: SDKRequest): DeferredPromise<TResult | APIError> {\r\n\t\t// We'll receive a Response object, but we want to return just the body of the response. This means\r\n\t\t// that we must inject a callback in the middle. We will use two promises:\r\n\t\tconst promise = new DeferredPromise<TResult | APIError>()\r\n\r\n\t\t// We dispatch an action that will eventually result in a request.\r\n\t\tconst requestDetailsWithBaseUrl = { ...requestDetails, BASE_URL: this.client.API_URL }\r\n\t\tconst { store } = this.client\r\n\r\n\t\tif (requestDetails.immediate) {\r\n\t\t\tconst requestWithUuid = {\r\n\t\t\t\t...requestDetailsWithBaseUrl,\r\n\t\t\t\tuuid: requestDetails.uuid ?? uuidv4(),\r\n\t\t\t}\r\n\t\t\t// TODO: Does this result in sending the request multiple times?\r\n\t\t\t// Should performRequest accept pure requestDetails?\r\n\t\t\t// (It shouldn't result in dupes because we're not dispatching an action.)\r\n\t\t\tconst fullOfflineAction: FullOfflineAction = {\r\n\t\t\t\tpayload: requestWithUuid,\r\n\t\t\t\ttype: \"\",\r\n\t\t\t\tmeta: {\r\n\t\t\t\t\toffline: {\r\n\t\t\t\t\t\teffect: {\r\n\t\t\t\t\t\t\ttimestamp: new Date().toISOString(),\r\n\t\t\t\t\t\t\trequest: requestWithUuid,\r\n\t\t\t\t\t\t\tBASE_URL: this.client.API_URL,\r\n\t\t\t\t\t\t} satisfies OfflineMetaEffect,\r\n\t\t\t\t\t},\r\n\t\t\t\t},\r\n\t\t\t}\r\n\t\t\tperformRequest(fullOfflineAction, this.client)\r\n\t\t\t\t.then((result) => {\r\n\t\t\t\t\tpromise.resolve(result.body as TResult)\r\n\t\t\t\t})\r\n\t\t\t\t.catch((error) => {\r\n\t\t\t\t\tdiscard(error, fullOfflineAction)\r\n\t\t\t\t\tpromise.reject(error)\r\n\t\t\t\t})\r\n\t\t} else {\r\n\t\t\tconst innerPromise: Promise<request.Response> = store.dispatch(\r\n\t\t\t\tenqueueRequest(requestDetailsWithBaseUrl),\r\n\t\t\t) as unknown as Promise<request.Response>\r\n\r\n\t\t\tconst successOrUndefinedHandler = (response: request.Response | undefined) => {\r\n\t\t\t\tif (response) {\r\n\t\t\t\t\tpromise.resolve(response.body as TResult)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconst error = new APIError(\r\n\t\t\t\t\t\t\"Could not get a response from the server.\",\r\n\t\t\t\t\t\tresponse satisfies undefined,\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tdiscard: true,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t)\r\n\t\t\t\t\tpromise.reject(error)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Handles errors from the inner promise (which performs the request) and rejects the outer promise, which has\r\n\t\t\t * been returned to the caller by the time this is triggered. This handler is only expected to be triggered if\r\n\t\t\t * the request has been discarded from the outbox.\r\n\t\t\t * @param error The error that caused the request to be discarded. Expected to be an APIError instance.\r\n\t\t\t */\r\n\t\t\tconst errorHandler = (error: APIError) => {\r\n\t\t\t\terror.options.discard = true\r\n\t\t\t\tpromise.reject(error)\r\n\t\t\t}\r\n\r\n\t\t\tinnerPromise.then(successOrUndefinedHandler, errorHandler)\r\n\t\t}\r\n\r\n\t\treturn promise\r\n\t}\r\n}\r\n\r\n// TODO: Make abstract class for fetching all, updating one, deleting one, etc., of TModel.\r\n","import { BaseApiService } from \"./BaseApiService\"\r\n\r\nimport type { OptimisticGenericResult, OptimisticModelResult, OptimisticMultipleModelResult } from \"../typings\"\r\nimport { Created, IssueAttachment, MaybeObjectURL, PhotoAttachmentPayload } from \"../../typings\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { hashFile, offline } from \"../../utils\"\r\nimport { addAttachment, removeAttachment, updateAttachment } from \"../../store\"\r\n\r\n// TODO: Use FileService\r\n/**\r\n * Handles creation and caching of attachments\r\n */\r\nexport class AttachmentService extends BaseApiService {\r\n\tfetchAll(projectId: number): OptimisticMultipleModelResult<IssueAttachment> {\r\n\t\tconst promise = this.enqueueRequest<IssueAttachment[]>({\r\n\t\t\tdescription: \"Fetch attachments\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/attachments/${projectId}/`,\r\n\t\t\tblocks: [],\r\n\t\t\tblockers: [],\r\n\t\t})\r\n\t\tconst allAttachments: IssueAttachment[] = Object.values(this.client.store.getState().issueReducer.attachments)\r\n\t\treturn [allAttachments, promise]\r\n\t}\r\n\t// Attachments aren't models, so we use the OptimisticGenericResult type instead\r\n\tasync add(attachmentPayload: PhotoAttachmentPayload): Promise<OptimisticModelResult<IssueAttachment>> {\r\n\t\tconst { description, issue_id, file_sha1, offline_id } = attachmentPayload\r\n\r\n\t\tif (!attachmentPayload.file.objectURL) {\r\n\t\t\tthrow new Error(\"Expected attachmentPayload.file.objectURL to be defined.\")\r\n\t\t}\r\n\r\n\t\t// We don't have a public URL yet, but we have a local objectURL. We'll use that as the file location for now.\r\n\t\t// It will be replaced by a real, online S3 URL once the attachment is created and loaded from the server on the\r\n\t\t// next login.\r\n\t\tconst offlineAttachment: IssueAttachment = {\r\n\t\t\t...attachmentPayload,\r\n\t\t\tfile: attachmentPayload.file.objectURL,\r\n\t\t\tfile_name: attachmentPayload.file.name,\r\n\t\t\tfile_type: attachmentPayload.file.type,\r\n\t\t}\r\n\r\n\t\tawait this.client.files.addCache(attachmentPayload.file, file_sha1)\r\n\r\n\t\tthis.client.store.dispatch(addAttachment(offlineAttachment))\r\n\r\n\t\tconst [fileProps] = await this.client.files.uploadFileToS3(file_sha1)\r\n\t\t// TODO: Handle response from server and verify tentative URL\r\n\t\tconst promise = this.enqueueRequest<Created<IssueAttachment>>({\r\n\t\t\tdescription: \"Create attachment\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/issues/${issue_id}/attach/`,\r\n\t\t\tblocks: [offline_id, issue_id],\r\n\t\t\tblockers: [file_sha1],\r\n\t\t\tpayload: {\r\n\t\t\t\toffline_id,\r\n\t\t\t\tissue: issue_id,\r\n\t\t\t\tdescription: description ?? \"\",\r\n\t\t\t\tsubmitted_at: new Date().getTime() / 1000,\r\n\t\t\t\t...fileProps,\r\n\t\t\t},\r\n\t\t})\r\n\r\n\t\treturn [offlineAttachment, promise]\r\n\t}\r\n\r\n\tasync attachFilesToIssue(\r\n\t\tfilesToSubmit: File[],\r\n\t\tissueId: string,\r\n\t): Promise<PromiseSettledResult<OptimisticGenericResult<IssueAttachment>>[]> {\r\n\t\treturn Promise.allSettled<OptimisticModelResult<IssueAttachment>>(\r\n\t\t\tfilesToSubmit.map((file) => {\r\n\t\t\t\tif (!(file instanceof File)) {\r\n\t\t\t\t\tthrow new Error(\"Expected a File instance.\")\r\n\t\t\t\t}\r\n\t\t\t\tconst photoAttachmentPromise = async (file: File) => {\r\n\t\t\t\t\tconst hash = await hashFile(file)\r\n\t\t\t\t\tconst attachment: PhotoAttachmentPayload = offline({\r\n\t\t\t\t\t\tfile,\r\n\t\t\t\t\t\t// No description for now\r\n\t\t\t\t\t\tissue_id: issueId,\r\n\t\t\t\t\t\tfile_sha1: hash,\r\n\t\t\t\t\t})\r\n\t\t\t\t\treturn await this.add(attachment)\r\n\t\t\t\t}\r\n\t\t\t\treturn photoAttachmentPromise(file)\r\n\t\t\t}),\r\n\t\t)\r\n\t}\r\n\r\n\tasync replaceFile(\r\n\t\tattachmentId: string,\r\n\t\tnewFile: MaybeObjectURL<File>,\r\n\t): Promise<OptimisticModelResult<IssueAttachment>> {\r\n\t\tconst { store } = this.client\r\n\t\tconst attachment: IssueAttachment | undefined = store.getState().issueReducer.attachments[attachmentId]\r\n\t\tif (!attachment) throw new Error(`Attachment ${attachmentId} not found`)\r\n\t\tlet oldFile: File | undefined = undefined\r\n\t\tconst newSha1 = await hashFile(newFile)\r\n\r\n\t\tconst performRequest: () => Promise<IssueAttachment> = async () => {\r\n\t\t\toldFile = await this.client.files.fetchCache(attachment.file_sha1)\r\n\t\t\tif (!oldFile) {\r\n\t\t\t\tconsole.error(`Failed to fetch old file from cache for sha1 ${attachment.file_sha1}.`)\r\n\t\t\t}\r\n\t\t\tif (!newFile.objectURL) {\r\n\t\t\t\tthrow new Error(`newFile[\"objectURL\"] is unexpectedly ${newFile.objectURL}`)\r\n\t\t\t}\r\n\t\t\tstore.dispatch(updateAttachment({ ...attachment, file_sha1: newSha1, file: URL.createObjectURL(newFile) }))\r\n\t\t\tawait this.client.files.addCache(newFile, newSha1)\r\n\r\n\t\t\tconst [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {\r\n\t\t\t\t// Revert to the old attachment details (which were gotten from the store before the request was sent)\r\n\t\t\t\tstore.dispatch(updateAttachment(attachment))\r\n\t\t\t\tthrow e\r\n\t\t\t})\r\n\r\n\t\t\tconst promise = this.enqueueRequest<Created<IssueAttachment>>({\r\n\t\t\t\tdescription: \"Edit attachment\",\r\n\t\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\t\turl: `/attachments/${attachment.offline_id}/`,\r\n\t\t\t\tisResponseBlob: false,\r\n\t\t\t\tpayload: fileProps,\r\n\t\t\t\tblockers: [attachmentId, newSha1],\r\n\t\t\t\tblocks: [attachmentId, newSha1],\r\n\t\t\t})\r\n\r\n\t\t\ttry {\r\n\t\t\t\tconst result = await promise\r\n\t\t\t\tvoid this.client.files.removeCache(attachment.file_sha1)\r\n\t\t\t\treturn result\r\n\t\t\t} catch (e) {\r\n\t\t\t\tif (oldFile) {\r\n\t\t\t\t\tstore.dispatch(\r\n\t\t\t\t\t\tupdateAttachment({\r\n\t\t\t\t\t\t\t...attachment,\r\n\t\t\t\t\t\t\tfile_sha1: attachment.file_sha1,\r\n\t\t\t\t\t\t\tfile: URL.createObjectURL(oldFile),\r\n\t\t\t\t\t\t}),\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t\tthrow e\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst offlineAttachment = {\r\n\t\t\t...attachment,\r\n\t\t\tfile_sha1: newSha1,\r\n\t\t\tfile: URL.createObjectURL(newFile),\r\n\t\t}\r\n\t\tconst promise = performRequest()\r\n\t\treturn [offlineAttachment, promise]\r\n\t}\r\n\r\n\t/**\r\n\t * Deletes an attachment and associated data in the cloud, in the Redux store and the cache.\r\n\t * @param attachmentId\r\n\t */\r\n\tdelete(attachmentId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst storeStateIssueReducer = store.getState().issueReducer\r\n\t\tconst attachment = storeStateIssueReducer.attachments[attachmentId]\r\n\t\tif (!attachment) {\r\n\t\t\tthrow new Error(`Attachment ${attachmentId} not found`)\r\n\t\t}\r\n\t\tstore.dispatch(removeAttachment(attachmentId))\r\n\t\tvoid this.client.files.removeCache(attachment.file_sha1)\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete attachment\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/attachments/${attachmentId}/`,\r\n\t\t\tblockers: [attachmentId],\r\n\t\t\tblocks: [attachmentId],\r\n\t\t})\r\n\t}\r\n}\r\n","import { Credentials, TokenPair } from \"../typings\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { hashFile } from \"utils/file\"\r\nimport {\r\n\taddFavouriteProjectId,\r\n\tclearTokens,\r\n\tmarkForDeletion,\r\n\tremoveFavouriteProjectId,\r\n\tresetStore,\r\n\tsetActiveOrganizationAccessId,\r\n\tsetActiveProjectId,\r\n\tsetActiveWorkspaceId,\r\n\tsetLoggedIn,\r\n\tsetProfilePicture,\r\n\tsetTokens,\r\n\tsetTourStep,\r\n} from \"../../store\"\r\nimport { RegistrationPayload, RegistrationReturn } from \"../../typings\"\r\nimport jwtDecode, { JwtPayload } from \"jwt-decode\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { RESET_STATE } from \"@redux-offline/redux-offline/lib/constants\"\r\nimport { v4 as uuidv4 } from \"uuid\"\r\nimport localforage from \"localforage\"\r\n\r\n// Number of seconds until expiry that we consider as \"expiring soon\"\r\nconst EXPIRING_SOON_THRESHOLD = 1800\r\n\r\n// TODO: Rename `accessToken` and `refreshToken` to `access` and `refresh` respectively, then remove this function and\r\n// just return the response directly.\r\nfunction parseTokens(response: { access: string; refresh: string }): TokenPair {\r\n\tif (!response.access) throw new Error(\"Missing access token\")\r\n\tif (!response.refresh) throw new Error(\"Missing refresh token\")\r\n\treturn { accessToken: response.access, refreshToken: response.refresh }\r\n}\r\n\r\n/**\r\n * Handles login, logout and renewing tokens\r\n */\r\nexport class AuthService extends BaseApiService {\r\n\tprivate _getAccessToken = () => this.client.store.getState().authReducer.accessToken\r\n\tprivate _getRefreshToken = () => this.client.store.getState().authReducer.refreshToken\r\n\r\n\t// _getTokenPair and _getRenewedTokens don't need to use enqueueRequest from the BaseApiService because\r\n\t// they are very simple. However, if we need robust error handling or want these operations to queue in the Outbox,\r\n\t// we will use enqueueRequest.\r\n\r\n\t/**\r\n\t * Takes credentials and gets a token pair\r\n\t * @async\r\n\t * @param credentials The username and password for obtaining a token pair\r\n\t * @param logoutOnFailure Whether to log out if the request fails\r\n\t * @returns An array containing two elements: 1) a Promise for the access and refresh tokens, and 2) the UUID of the\r\n\t * request, so the request can be cancelled if necessary.\r\n\t */\r\n\tprivate _getTokenPair = (credentials: Credentials, logoutOnFailure = true): [Promise<TokenPair>, string] => {\r\n\t\t// Used to cancel after a timeout\r\n\t\tconst uuid = uuidv4()\r\n\t\ttry {\r\n\t\t\tconst responsePromise = this.enqueueRequest<{ access: string; refresh: string }>({\r\n\t\t\t\tuuid,\r\n\t\t\t\tdescription: \"Get token pair\",\r\n\t\t\t\tmethod: HttpMethod.POST,\r\n\t\t\t\turl: \"/api/token/\",\r\n\t\t\t\tpayload: credentials,\r\n\t\t\t\tisAuthNeeded: false,\r\n\t\t\t\tblockers: [],\r\n\t\t\t\tblocks: [],\r\n\t\t\t})\r\n\t\t\treturn [responsePromise.then(parseTokens), uuid]\r\n\t\t} catch (e) {\r\n\t\t\tif (logoutOnFailure) {\r\n\t\t\t\tvoid this.logout().then()\r\n\t\t\t}\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Takes refresh token and gets a new token pair\r\n\t * @async\r\n\t * @param {string} refreshToken The refresh token used to get new tokens\r\n\t * @returns {Promise<TokenPair>} The new access and refresh tokens\r\n\t */\r\n\tprivate _getRenewedTokens = async (refreshToken: string): Promise<TokenPair> => {\r\n\t\tinterface MaybeTokenPair {\r\n\t\t\taccess?: string\r\n\t\t\trefresh?: string\r\n\t\t}\r\n\r\n\t\tconst response = await this.enqueueRequest<MaybeTokenPair>({\r\n\t\t\tdescription: \"Get renewed tokens\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: \"/api/token/refresh/\",\r\n\t\t\tpayload: { refresh: refreshToken },\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t\t// Don't wait for an auth check since this is a refresh token request.\r\n\t\t\tcheckAuth: false,\r\n\t\t\t// Don't wait for other requests to finish, or we might end up in a deadlock.\r\n\t\t\timmediate: true,\r\n\t\t})\r\n\t\tif (!response.access) throw new Error(\"Missing access token\")\r\n\t\tif (!response.refresh) throw new Error(\"Missing refresh token\")\r\n\t\treturn { accessToken: response.access, refreshToken: response.refresh }\r\n\t}\r\n\r\n\t/**\r\n\t * Attempts to log into Hemora using given credentials\r\n\t * @param {string} username\r\n\t * @param {string} password\r\n\t */\r\n\tasync login(username: string, password: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\t// false: Don't log out on failure because we're not currently logged in. Instead, throw and show an error.\r\n\t\tconst [promise, uuid] = this._getTokenPair({ username, password }, false)\r\n\t\tconst initialDataUuid = uuidv4()\r\n\r\n\t\t// The goal: Cancel the request if it takes too long\r\n\t\tconst timeout = 5 // seconds\r\n\t\tlet timedOut = false\r\n\t\tlet initialDataRequestFinished = false\r\n\r\n\t\tconst timeoutPromise = new Promise<undefined>((_, reject) => {\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\tif (initialDataRequestFinished) {\r\n\t\t\t\t\treturn undefined\r\n\t\t\t\t}\r\n\t\t\t\ttimedOut = true\r\n\t\t\t\tstore.dispatch(markForDeletion(uuid))\r\n\t\t\t\tstore.dispatch(markForDeletion(initialDataUuid))\r\n\t\t\t\treject(new Error(`Request timed out after ${timeout} seconds`))\r\n\t\t\t}, timeout * 1000)\r\n\t\t})\r\n\t\tconst successPromise: Promise<undefined> = promise.then((tokens) => {\r\n\t\t\tif (timedOut) {\r\n\t\t\t\treturn undefined\r\n\t\t\t}\r\n\t\t\tstore.dispatch(setTokens(tokens))\r\n\r\n\t\t\t// fetchInitialData returns necessary app information and initializes the store with values\r\n\t\t\t// according to what the logged user has access to. Overwrites information on login.\r\n\t\t\treturn this.client.main.fetchInitialData(true, initialDataUuid).then(() => {\r\n\t\t\t\tif (timedOut) {\r\n\t\t\t\t\treturn undefined\r\n\t\t\t\t}\r\n\t\t\t\tinitialDataRequestFinished = true\r\n\t\t\t\tstore.dispatch(setLoggedIn(true))\r\n\t\t\t\tstore.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\r\n\t\t\t\treturn undefined\r\n\t\t\t})\r\n\t\t})\r\n\r\n\t\treturn Promise.race([timeoutPromise, successPromise])\r\n\t}\r\n\r\n\t/**\r\n\t * Logs the user out\r\n\t */\r\n\tasync logout() {\r\n\t\tconst { store } = this.client\r\n\t\t// This also sends an action to the store.ts rootReducer function, allowing\r\n\t\t// the store to be reset upon sending an undefined state to the other\r\n\t\t// reducers.\r\n\t\tstore.dispatch(setLoggedIn(false))\r\n\t\tstore.dispatch(clearTokens())\r\n\t\tstore.dispatch(setActiveProjectId(null))\r\n\t\tstore.dispatch(setActiveOrganizationAccessId(null))\r\n\t\tstore.dispatch(setActiveWorkspaceId(null))\r\n\t\t// Clear the outbox\r\n\t\tstore.dispatch({ type: RESET_STATE })\r\n\t\t// TODO: Consider using only one of the two approaches\r\n\t\t// For good measure:\r\n\t\tstore.dispatch({ type: resetStore })\r\n\t\t// Clear localforage\r\n\t\tawait localforage.clear()\r\n\t\twindow.location.reload()\r\n\t}\r\n\r\n\t/**\r\n\t * Attempts to renew tokens\r\n\t */\r\n\tasync renewTokens() {\r\n\t\tconst { store } = this.client\r\n\t\tconst dyingRefreshToken = this._getRefreshToken()\r\n\t\tif (!dyingRefreshToken) {\r\n\t\t\tthrow new Error(\"No refresh token found\")\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\tconst { accessToken, refreshToken } = await this._getRenewedTokens(dyingRefreshToken)\r\n\t\t\tconsole.log(\"Got renewed tokens\")\r\n\t\t\tstore.dispatch(setTokens({ accessToken, refreshToken }))\r\n\t\t} catch (e) {\r\n\t\t\t// TODO: This is temporary behaviour, replace it with login button on outbox failed requests\r\n\t\t\t// that failed because of a 401 Unauthorized\r\n\t\t\tconsole.error(\"Could not renew tokens; logging out.\")\r\n\t\t\tawait this.logout()\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Register a new user\r\n\t */\r\n\tregister(payload: RegistrationPayload): Promise<RegistrationReturn> {\r\n\t\treturn this.enqueueRequest<RegistrationReturn>({\r\n\t\t\tdescription: \"Register\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: \"/authentication/users/register/\",\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tpayload,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync resetPassword(email: string): Promise<undefined> {\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Reset password\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: \"/authentication/users/reset-password/\",\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tpayload: {\r\n\t\t\t\temail: email,\r\n\t\t\t},\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\t/**\r\n\t * Checks whether the tokens will be expiring soon\r\n\t * @returns {boolean}\r\n\t */\r\n\ttokenIsExpiringSoon(): boolean {\r\n\t\tconst accessToken = this._getAccessToken()\r\n\t\tif (!accessToken) {\r\n\t\t\t// If the access token doesn't exist, it's not expiring.\r\n\t\t\treturn false\r\n\t\t}\r\n\t\t// Convert the current date from milliseconds to seconds (divide by 1000)\r\n\t\tconst currentDate = Date.now() / 1000\r\n\t\t// Find the expiration date of access token (in seconds)\r\n\t\tlet expiryDate: number\r\n\t\t// jwtDecode may throw an error if the access token is an empty string (logged out)\r\n\t\ttry {\r\n\t\t\t// REASON: Bad types\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error,@typescript-eslint/ban-ts-comment\r\n\t\t\t// @ts-ignore\r\n\r\n\t\t\texpiryDate = jwtDecode<JwtPayload>(accessToken).exp ?? currentDate\r\n\t\t} catch {\r\n\t\t\t// Enforce expiration if unable to decode token\r\n\t\t\texpiryDate = currentDate\r\n\t\t}\r\n\t\tconst secondsUntilExpiry = expiryDate - currentDate\r\n\t\treturn secondsUntilExpiry < EXPIRING_SOON_THRESHOLD\r\n\t}\r\n\r\n\tasync replaceProfilePicture(file: File): Promise<undefined> {\r\n\t\tconst hash = await hashFile(file)\r\n\r\n\t\tawait this.client.files.addCache(file, hash)\r\n\t\tconst { store } = this.client\r\n\r\n\t\tconst [fileProps] = await this.client.files.uploadFileToS3(hash)\r\n\r\n\t\tstore.dispatch(setProfilePicture({ file: `/files/${fileProps.file}`, file_sha1: hash }))\r\n\r\n\t\t// TODO: Handle response from server and verify tentative URL\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Replace profile picture\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: \"/authentication/users/profile-details/\",\r\n\t\t\tpayload: fileProps,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync addFavouriteProjectId(projectId: number): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(addFavouriteProjectId(projectId))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Add favourite project\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/authentication/users/favourite-project/${projectId}/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync removeFavouriteProjectId(projectId: number): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(removeFavouriteProjectId(projectId))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Add favourite project\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/authentication/users/unfavourite-project/${projectId}/`,\r\n\t\t\tblockers: [`favorite-project-${projectId}`],\r\n\t\t\tblocks: [`favorite-project-${projectId}`],\r\n\t\t})\r\n\t}\r\n\r\n\tasync setTourStep(stepIndex: number): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(setTourStep(stepIndex))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Set tour step\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: \"/authentication/users/profile-details/\",\r\n\t\t\tpayload: {\r\n\t\t\t\ttour_step: stepIndex,\r\n\t\t\t},\r\n\t\t\tblockers: [\"set-tour-step\"],\r\n\t\t\tblocks: [\"set-tour-step\"],\r\n\t\t})\r\n\t}\r\n\r\n\tasync joinApplication(\r\n\t\tprojectInviteId: string,\r\n\t\tverification_code: string,\r\n\t\tusername: string,\r\n\t\tpassword: string,\r\n\t): Promise<undefined> {\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Join application\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/authentication/join-app/${projectInviteId}/${verification_code}/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tusername,\r\n\t\t\t\tpassword,\r\n\t\t\t},\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { Category, Created, Offline, Payload, Stored } from \"../../typings\"\r\nimport { OptimisticEmptyResult, OptimisticGenericResult, OptimisticModelResult } from \"../typings\"\r\nimport { offline } from \"../../utils\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { addCategory, patchCategory, removeCategory, setCategories } from \"../../store\"\r\n\r\n/**\r\n * Handles the creation of Category Service\r\n * TODO: Support editing and deleting categories\r\n */\r\nexport class CategoryService extends BaseApiService {\r\n\tadd(category: Omit<Payload<Category>, \"workspace\">, workspaceId: string): OptimisticModelResult<Category> {\r\n\t\tconst offlineCategory = offline(category)\r\n\t\tconst categoryWithWorkspace = { ...offlineCategory, workspace: workspaceId }\r\n\t\tthis.client.store.dispatch(addCategory(categoryWithWorkspace))\r\n\r\n\t\tconst promise = this.enqueueRequest<Category>({\r\n\t\t\tdescription: \"Create Category\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: \"/categories/\",\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tpayload: offlineCategory,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offlineCategory.offline_id],\r\n\t\t})\r\n\t\treturn [categoryWithWorkspace, promise]\r\n\t}\r\n\tfetchAll(projectId: number): OptimisticGenericResult<Category[]> {\r\n\t\tconst promise = this.enqueueRequest<Category[]>({\r\n\t\t\tdescription: \"Get categories\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${projectId}/categories/`,\r\n\t\t\tblocks: [],\r\n\t\t\tblockers: [],\r\n\t\t})\r\n\r\n\t\t// Right now we are assuming that categories are generic and not a Model\r\n\t\t// Make fetchAll return OptimisticMultipleModelResult<Category>\r\n\t\tconst offlineCategories = Object.values(this.client.store.getState().categoryReducer.categories)\r\n\t\treturn [offlineCategories, promise]\r\n\t}\r\n\r\n\tupdate(category: Offline<Partial<Category>>, workspaceId: string): OptimisticModelResult<Category> {\r\n\t\tconst existingCategory = this.client.store.getState().categoryReducer.categories[category.offline_id]\r\n\r\n\t\tif (!existingCategory) {\r\n\t\t\tthrow new Error(`Expected an existing category with offline_id ${category.offline_id}`)\r\n\t\t}\r\n\r\n\t\tthis.client.store.dispatch(patchCategory(category))\r\n\t\tconst optimisticCategory: Stored<Category> = { ...existingCategory, ...category }\r\n\r\n\t\tconst promise = this.enqueueRequest<Created<Category>>({\r\n\t\t\tdescription: \"Edit Category\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/categories/${category.offline_id}/`,\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tpayload: category,\r\n\t\t\tblockers: [category.offline_id],\r\n\t\t\tblocks: [category.offline_id],\r\n\t\t})\r\n\t\treturn [optimisticCategory, promise]\r\n\t}\r\n\tremove(category: Category, workspaceId: string): OptimisticEmptyResult {\r\n\t\tthis.client.store.dispatch(removeCategory(category.offline_id))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete Category\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/categories/${category.offline_id}/`,\r\n\t\t\t// TODO: Shouldn't be necessary to specify workspace_id here\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tblockers: [category.offline_id],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\t/**\r\n\t * Overwrites the store with whatever categories are on the server.\r\n\t * @returns A promise that resolves to an empty result.\r\n\t * @throws An APIError if the request fails.\r\n\t * @throws An Error if there is no active project, or for any other unexpected error.\r\n\t * @example\r\n\t * ```typescript\r\n\t * try {\r\n\t * \t await sdk.category.refreshStore()\r\n\t * } catch (e) {\r\n\t * \t if (e instanceof APIError) {\r\n\t * \t // handle error\r\n\t * \t return\r\n\t * \t }\r\n\t * \t throw e\r\n\t * }\r\n\t * ```\r\n\t */\r\n\tasync refreshStore(): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst projectId = store.getState().projectReducer.activeProjectId\r\n\t\tif (!projectId) {\r\n\t\t\tthrow new Error(\"No active project\")\r\n\t\t}\r\n\t\tconst [_offlineCategories, promise] = this.fetchAll(projectId)\r\n\t\tconst result = await promise\r\n\t\t// temporary error handling\r\n\t\tstore.dispatch(setCategories(result))\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { Component, Payload, RootState, Submitted } from \"../../typings\"\r\nimport { ApiResult, OptimisticEmptyResult, OptimisticModelResult } from \"../typings\"\r\nimport { offline } from \"../../utils\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport {\r\n\taddComponent,\r\n\taddComponentsInBatches,\r\n\tremoveAllComponentsOfType,\r\n\tremoveComponent,\r\n\tselectComponentsByType,\r\n\tselectComponentsFromComponentType,\r\n\tsetComponents,\r\n\tupdateComponent,\r\n} from \"../../store\"\r\nimport { clientStore } from \"../../contexts\"\r\n\r\nexport class ComponentService extends BaseApiService {\r\n\t// Basic CRUD functions\r\n\tadd(component: Payload<Component>, workspaceId: string): OptimisticModelResult<Component> {\r\n\t\tconst offlineComponent = offline(component)\r\n\t\tthis.client.store.dispatch(addComponent(offlineComponent))\r\n\t\tconst promise = this.enqueueRequest<Component>({\r\n\t\t\tdescription: \"Create Component\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/components/types/${offlineComponent.component_type}/add-components/`,\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tpayload: { components: [offlineComponent] },\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offlineComponent.offline_id],\r\n\t\t})\r\n\t\treturn [offlineComponent, promise]\r\n\t}\r\n\tupdate(component: Component, workspaceId: string): OptimisticModelResult<Component> {\r\n\t\tthis.client.store.dispatch(updateComponent(component))\r\n\t\tconst promise = this.enqueueRequest<Component>({\r\n\t\t\tdescription: \"Edit component\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/components/${component.offline_id}/`,\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tpayload: component,\r\n\t\t\tblockers: [component.offline_id],\r\n\t\t\tblocks: [component.offline_id],\r\n\t\t})\r\n\t\treturn [component, promise]\r\n\t}\r\n\tremove(id: string): OptimisticEmptyResult {\r\n\t\tthis.client.store.dispatch(removeComponent(id))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete issue\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/components/${id}/`,\r\n\t\t\tblockers: [id],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\tdeleteAllByComponentType(componentTypeId: string): Promise<ApiResult<undefined>> {\r\n\t\tif (!clientStore) throw new Error(\"Client store not initialized\")\r\n\t\tconst allComponentsOfType = selectComponentsFromComponentType(componentTypeId)(clientStore.getState())\r\n\t\tconst affectedComponentIds = (allComponentsOfType || []).map((c) => c.offline_id)\r\n\t\tconst affectedOfflineIds = [componentTypeId, ...affectedComponentIds]\r\n\t\tconst { store } = this.client\r\n\t\tconst state: RootState = store.getState()\r\n\t\tconst componentsOfThisType: Component[] | undefined = selectComponentsByType(componentTypeId)(state)\r\n\t\tstore.dispatch(removeAllComponentsOfType(componentTypeId))\r\n\t\tconst promise = this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Batch delete components by component type\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/components/types/${componentTypeId}/delete-all-of-type/`,\r\n\t\t\tblockers: affectedOfflineIds,\r\n\t\t\tblocks: affectedOfflineIds,\r\n\t\t})\r\n\t\tpromise.catch((err) => {\r\n\t\t\t// If the request fails, we need to add the components back to the store\r\n\t\t\tif (componentsOfThisType) {\r\n\t\t\t\tstore.dispatch(addComponentsInBatches(componentsOfThisType))\r\n\t\t\t}\r\n\t\t\tthrow err\r\n\t\t})\r\n\t\treturn promise\r\n\t}\r\n\taddBatch(\r\n\t\tcomponentsToCreate: Payload<Component>[],\r\n\t\tworkspaceId: string,\r\n\t\tcomponentTypeId: string,\r\n\t): Promise<ApiResult<Record<string, Component>>> {\r\n\t\tconst fullComponents: Submitted<Component>[] = componentsToCreate.map((component) => {\r\n\t\t\treturn { ...offline(component), submitted_at: new Date().toISOString() }\r\n\t\t})\r\n\t\tconst { store } = this.client\r\n\t\tstore.dispatch(addComponentsInBatches(fullComponents))\r\n\t\tconst promise = this.enqueueRequest<Record<string, Component>>({\r\n\t\t\tdescription: \"Batch create components\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/components/types/${componentTypeId}/add-components/`,\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tpayload: {\r\n\t\t\t\tcomponents: fullComponents,\r\n\t\t\t},\r\n\t\t\tblockers: [componentTypeId],\r\n\t\t\tblocks: fullComponents.map((c) => c.offline_id),\r\n\t\t})\r\n\t\tvoid promise\r\n\t\t\t.then((result) => {\r\n\t\t\t\tfor (const component of Object.values(result)) {\r\n\t\t\t\t\tstore.dispatch(updateComponent(component))\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t.catch((e) => {\r\n\t\t\t\tfor (const component of fullComponents) {\r\n\t\t\t\t\tstore.dispatch(removeComponent(component.offline_id))\r\n\t\t\t\t}\r\n\t\t\t\tthrow e\r\n\t\t\t})\r\n\t\treturn promise\r\n\t}\r\n\r\n\tasync refreshStore(replace: boolean): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<Component[]>({\r\n\t\t\tdescription: \"Get components\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/components/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tif (replace) {\r\n\t\t\tstore.dispatch(setComponents(result))\r\n\t\t} else {\r\n\t\t\tstore.dispatch(addComponentsInBatches(result))\r\n\t\t}\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { addStageCompletion, addStageCompletions, ComponentStageCompletion, removeStageCompletions } from \"../../store\"\r\nimport { OptimisticEmptyResult, OptimisticModelResult } from \"../typings\"\r\nimport { offline } from \"../../utils\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { CompletedStagesMapping, Created, Payload } from \"../../typings\"\r\n\r\nexport class ComponentStageCompletionService extends BaseApiService {\r\n\tadd(componentId: string, stageId: string): OptimisticModelResult<ComponentStageCompletion> {\r\n\t\tconst { store } = this.client\r\n\t\tconst componentType = store.getState().componentReducer.components[componentId]?.component_type\r\n\t\tif (!componentType) {\r\n\t\t\tthrow new Error(`Component ${componentId} not found`)\r\n\t\t}\r\n\t\tconst offlineCompletion = offline({\r\n\t\t\tcomponent: componentId,\r\n\t\t\tstage: stageId,\r\n\t\t})\r\n\r\n\t\tstore.dispatch(addStageCompletion(offlineCompletion))\r\n\t\tconst promise = this.enqueueRequest<Created<ComponentStageCompletion>>({\r\n\t\t\tdescription: \"Mark stage as completed\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/components/types/${componentType}/complete-stages/`,\r\n\t\t\t// TODO: Add submitted_at to model\r\n\t\t\tpayload: { completions: [{ ...offlineCompletion, submitted_at: new Date().getTime() / 1000 }] },\r\n\t\t\tblockers: [componentId, stageId],\r\n\t\t\tblocks: [offlineCompletion.offline_id],\r\n\t\t})\r\n\t\treturn [offlineCompletion, promise]\r\n\t}\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<CompletedStagesMapping>({\r\n\t\t\tdescription: \"Get completed stages\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/component-stage-completions/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tstore.dispatch(addStageCompletions(result))\r\n\t}\r\n\r\n\t/**\r\n\t * Creates a collection of ComponentStageCompletions, marking the referenced stages as completed for the referenced\r\n\t * components. It's REQUIRED that all components referenced all have the SAME component type.\r\n\t * @param componentTypeId The ID of the component type for which we are completing stages (we can only complete\r\n\t * stages for one component type at a time)\r\n\t * @param stageCompletions\r\n\t */\r\n\tasync bulkAdd(componentTypeId: string, stageCompletions: Payload<ComponentStageCompletion>[]) {\r\n\t\tconst offlineStagesCompletions = stageCompletions.map((completion) => {\r\n\t\t\treturn offline(completion)\r\n\t\t})\r\n\t\tconst asMapping: CompletedStagesMapping = {}\r\n\t\tfor (const completion of stageCompletions) {\r\n\t\t\tconst stageToCompletionDateMapping = asMapping[completion.component] || {}\r\n\t\t\tstageToCompletionDateMapping[completion.stage] = new Date().toISOString()\r\n\t\t\tasMapping[completion.component] = stageToCompletionDateMapping\r\n\t\t}\r\n\t\tthis.client.store.dispatch(addStageCompletions(asMapping))\r\n\t\tawait this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Mark multiple stage as completed\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/components/types/${componentTypeId}/complete-stages/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tcompletions: offlineStagesCompletions,\r\n\t\t\t},\r\n\t\t\tblockers: [\r\n\t\t\t\tcomponentTypeId,\r\n\t\t\t\t...stageCompletions.map((c) => c.component),\r\n\t\t\t\t...stageCompletions.map((c) => c.stage),\r\n\t\t\t],\r\n\t\t\tblocks: offlineStagesCompletions.map((c) => c.offline_id),\r\n\t\t})\r\n\t}\r\n\tbulkDelete(stageId: string, componentIds: string[]): OptimisticEmptyResult {\r\n\t\tconst completionsToRemove: ComponentStageCompletion[] = componentIds.map((componentId) => {\r\n\t\t\treturn {\r\n\t\t\t\tcomponent: componentId,\r\n\t\t\t\tstage: stageId,\r\n\t\t\t}\r\n\t\t})\r\n\t\tthis.client.store.dispatch(removeStageCompletions(completionsToRemove))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: `Undo stage for ${componentIds.length} component(s)`,\r\n\t\t\t// TODO: Rename to setCompletedStages\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/components/stages/${stageId}/undo-stages/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tcomponents: componentIds,\r\n\t\t\t},\r\n\t\t\tblockers: [stageId, ...componentIds],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { ComponentStage, ComponentStagePayload, Payload } from \"../../typings\"\r\nimport { offline } from \"../../utils\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { addStages, removeStages, selectStagesFromStageIds, updateStages } from \"../../store\"\r\n\r\nexport class ComponentStageService extends BaseApiService {\r\n\tasync bulkCreateStages(\r\n\t\tstagesToSubmit: Payload<ComponentStagePayload>[],\r\n\t\tcomponentTypeId: string,\r\n\t\tworkspaceId: string,\r\n\t): Promise<ComponentStage[]> {\r\n\t\tconst payload: ComponentStagePayload[] = stagesToSubmit.map((stage) => {\r\n\t\t\treturn offline(stage)\r\n\t\t})\r\n\t\tconst fullStages = payload.map((stage) => {\r\n\t\t\treturn { ...stage, component_type: componentTypeId }\r\n\t\t})\r\n\t\tthis.client.store.dispatch(addStages(fullStages))\r\n\t\treturn this.enqueueRequest<ComponentStage[]>({\r\n\t\t\tdescription: \"Add component stages\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/components/types/${componentTypeId}/add-stages/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tstages: payload,\r\n\t\t\t},\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId.toString(),\r\n\t\t\t},\r\n\t\t\tblockers: [componentTypeId, workspaceId],\r\n\t\t\tblocks: payload.map(({ offline_id }) => offline_id),\r\n\t\t})\r\n\t}\r\n\r\n\tasync bulkUpdateStages(stagesToUpdate: ComponentStage[], componentTypeId: string): Promise<ComponentStage[]> {\r\n\t\tconst store = this.client.store\r\n\t\tconst state = store.getState()\r\n\t\tconst prevStages: ComponentStage[] | undefined = selectStagesFromStageIds(\r\n\t\t\tstagesToUpdate.map(({ offline_id }) => offline_id),\r\n\t\t)(state)\r\n\r\n\t\tif (!prevStages) {\r\n\t\t\tthrow new Error(\"Could not find the desired stages to update within the store\")\r\n\t\t}\r\n\r\n\t\tstore.dispatch(updateStages(stagesToUpdate))\r\n\t\treturn this.enqueueRequest<ComponentStage[]>({\r\n\t\t\tdescription: \"Edit component stages\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/components/types/${componentTypeId}/bulk-update-stages/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tstages: stagesToUpdate,\r\n\t\t\t},\r\n\t\t\tblockers: [componentTypeId],\r\n\t\t\tblocks: stagesToUpdate.map(({ offline_id }) => offline_id),\r\n\t\t}).catch((e) => {\r\n\t\t\t// restore stages in store if request fails\r\n\t\t\tstore.dispatch(updateStages(prevStages))\r\n\t\t\tthrow e\r\n\t\t})\r\n\t}\r\n\r\n\tasync bulkDelete(idsToDelete: string[]): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(removeStages(idsToDelete))\r\n\t\treturn this.enqueueRequest({\r\n\t\t\tdescription: \"Delete component stages\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: \"/components/stages/bulk-delete/\",\r\n\t\t\tpayload: {\r\n\t\t\t\tstage_ids: idsToDelete,\r\n\t\t\t},\r\n\t\t\tblockers: idsToDelete,\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync update(componentStage: ComponentStage): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(addStages([componentStage]))\r\n\t\treturn this.enqueueRequest({\r\n\t\t\tdescription: \"Update component stage\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/components/stages/${componentStage.offline_id}/`,\r\n\t\t\tpayload: componentStage,\r\n\t\t\tblockers: [componentStage.offline_id],\r\n\t\t\tblocks: [componentStage.offline_id],\r\n\t\t})\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<ComponentStage[]>({\r\n\t\t\tdescription: \"Get component stages\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/component-stages/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tstore.dispatch(addStages(result))\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { offline } from \"../../utils\"\r\nimport {\r\n\taddComponentType,\r\n\taddStages,\r\n\tdeleteComponentType,\r\n\tremoveStages,\r\n\tselectComponentType,\r\n\tselectStagesFromComponentType,\r\n\tsetComponentTypes,\r\n} from \"../../store\"\r\nimport { ComponentStage, ComponentType, Payload } from \"../../typings\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { OptimisticModelResult } from \"../typings\"\r\n\r\nexport class ComponentTypeService extends BaseApiService {\r\n\tadd(componentType: Payload<ComponentType>): OptimisticModelResult<ComponentType> {\r\n\t\tconst offlineComponentType = offline(componentType)\r\n\t\tconst { store } = this.client\r\n\t\tconst activeProjectId = store.getState().projectReducer.activeProjectId\r\n\r\n\t\tstore.dispatch(addComponentType(offlineComponentType))\r\n\t\tconst promise = this.enqueueRequest<ComponentType>({\r\n\t\t\tdescription: \"Create ComponentType\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/projects/${activeProjectId}/component-types/`,\r\n\t\t\tpayload: { ...offlineComponentType },\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offlineComponentType.offline_id],\r\n\t\t})\r\n\t\treturn [offlineComponentType, promise]\r\n\t}\r\n\r\n\tupdate(componentType: ComponentType): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(addComponentType(componentType))\r\n\t\treturn this.enqueueRequest({\r\n\t\t\tdescription: \"Update ComponentType\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/components/types/${componentType.offline_id}/`,\r\n\t\t\tpayload: componentType,\r\n\t\t\tblockers: [componentType.offline_id],\r\n\t\t\tblocks: [componentType.offline_id],\r\n\t\t})\r\n\t}\r\n\tasync delete(componentTypeId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\t// Get Component Stages in state associated with Component Type to be deleted\r\n\t\tconst componentType = selectComponentType(componentTypeId)(state)\r\n\t\tif (!componentType) {\r\n\t\t\tthrow new Error(\"Expected componentType to exist\")\r\n\t\t}\r\n\t\tconst componentTypeStages = selectStagesFromComponentType(componentTypeId)(state) ?? []\r\n\t\tstore.dispatch(\r\n\t\t\tremoveStages(\r\n\t\t\t\tcomponentTypeStages.map((componentTypeStage: ComponentStage) => componentTypeStage.offline_id),\r\n\t\t\t),\r\n\t\t)\r\n\t\tstore.dispatch(deleteComponentType(componentTypeId))\r\n\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete ComponentType\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/components/types/${componentTypeId}/`,\r\n\t\t\tblockers: [componentTypeId],\r\n\t\t\tblocks: [],\r\n\t\t}).catch((e) => {\r\n\t\t\tstore.dispatch(addComponentType(componentType))\r\n\t\t\tstore.dispatch(addStages(componentTypeStages))\r\n\t\t\tthrow e\r\n\t\t})\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<ComponentType[]>({\r\n\t\t\tdescription: \"Get component types\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/component-types/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tstore.dispatch(setComponentTypes(result))\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { Created, IssueComment, Payload, Submitted } from \"../../typings\"\r\nimport { offline, onlyUniqueOfflineIds, truncate } from \"../../utils\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { addOrReplaceIssueComment, removeIssueComment, setIssueComments } from \"../../store\"\r\nimport { OptimisticModelResult } from \"../typings.ts\"\r\n\r\nexport class IssueCommentService extends BaseApiService {\r\n\tadd(comment: Omit<Payload<IssueComment>, \"author\">): OptimisticModelResult<IssueComment> {\r\n\t\tconst offlinePayload: Omit<IssueComment, \"author\" | \"created_at\"> = offline(comment)\r\n\t\tconst submittedAt = new Date().toISOString()\r\n\t\tconst { store } = this.client\r\n\t\tconst offlineComment: Submitted<IssueComment> = {\r\n\t\t\t...offlinePayload,\r\n\t\t\tauthor: store.getState().userReducer.currentUser.id,\r\n\t\t\tcreated_at: submittedAt,\r\n\t\t}\r\n\t\tstore.dispatch(addOrReplaceIssueComment(offlineComment))\r\n\t\tconst promise = this.enqueueRequest<Created<IssueComment>>({\r\n\t\t\tdescription: `${truncate(comment.content, 80)}`,\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/issues/${comment.issue}/comment/`,\r\n\t\t\tpayload: { ...offlinePayload, submitted_at: submittedAt },\r\n\t\t\tblockers: [comment.issue],\r\n\t\t\tblocks: [offlinePayload.offline_id],\r\n\t\t})\r\n\t\treturn [offlineComment, promise]\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<Created<IssueComment>[]>({\r\n\t\t\tdescription: \"Get comments\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\t// TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\r\n\t\tlet filteredResult = result.filter(onlyUniqueOfflineIds)\r\n\t\tfilteredResult = filteredResult.map((comment) => {\r\n\t\t\treturn { ...comment }\r\n\t\t})\r\n\t\tif (result.length !== filteredResult.length) {\r\n\t\t\tconsole.error(\r\n\t\t\t\t`Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`,\r\n\t\t\t)\r\n\t\t}\r\n\t\tstore.dispatch(setIssueComments(filteredResult))\r\n\t}\r\n\r\n\tupdate(comment: Submitted<IssueComment>): OptimisticModelResult<IssueComment> {\r\n\t\tthis.client.store.dispatch(addOrReplaceIssueComment(comment))\r\n\t\tconst promise = this.enqueueRequest<Created<IssueComment>>({\r\n\t\t\tdescription: `Edit comment: ${truncate(comment.content, 80)}`,\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/issues/comments/${comment.offline_id}/`,\r\n\t\t\tpayload: comment,\r\n\t\t\tblockers: [comment.issue],\r\n\t\t\tblocks: [comment.offline_id],\r\n\t\t})\r\n\t\treturn [comment, promise]\r\n\t}\r\n\r\n\tremove(offline_id: string): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(removeIssueComment(offline_id))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete comment\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/issues/comments/${offline_id}/`,\r\n\t\t\tblockers: [offline_id],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { OptimisticModelResult, OptimisticMultipleModelResult } from \"../typings\"\r\nimport { Created, Issue, Submitted } from \"../../typings\"\r\nimport { offline, onlyUniqueOfflineIds } from \"../../utils\"\r\nimport {\r\n\taddAttachments,\r\n\taddIssue,\r\n\taddToRecentIssues,\r\n\tremoveAttachmentsOfIssue,\r\n\tremoveIssue,\r\n\tselectPhotoAttachmentsOfIssue,\r\n\tsetIssues,\r\n\tupdateIssue,\r\n} from \"../../store\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { DEFAULT_ISSUE_PRIORITY, DEFAULT_ISSUE_STATUS } from \"../../constants\"\r\nimport { unsafeShowToast } from \"@overmap-ai/blocks\"\r\nimport { APIError } from \"../errors.ts\"\r\n\r\n/**\r\n * Handles CRUD operations on issues\r\n */\r\nexport class IssueService extends BaseApiService {\r\n\t// Basic CRUD functions\r\n\t// TODO: Once all models are represented in `Created<TModel>`, use `Created` in `OptimisticModelResult`, so we don't\r\n\t// have to repeat it for all optimistic model results (all optimistic results are created).\r\n\tadd(issue: Issue): OptimisticModelResult<Issue> {\r\n\t\tconst { store } = this.client\r\n\t\tconst dateWithoutMilliseconds = new Date()\r\n\t\tconst state = store.getState()\r\n\t\tconst workspaceId = state.workspaceReducer.activeWorkspaceId\r\n\t\tconst currentUserId = state.userReducer.currentUser.id\r\n\t\tdateWithoutMilliseconds.setMilliseconds(0)\r\n\r\n\t\tif (!workspaceId) {\r\n\t\t\tthrow new Error(\"No active workspace ID while creating issue.\")\r\n\t\t}\r\n\r\n\t\tconst issuePayload: Submitted<Issue> = offline({\r\n\t\t\t...issue,\r\n\t\t\tsubmitted_at: dateWithoutMilliseconds.toISOString(),\r\n\t\t\tindex_workspace: workspaceId,\r\n\t\t\tcreated_by: currentUserId,\r\n\t\t\tstatus: issue.status ?? DEFAULT_ISSUE_STATUS,\r\n\t\t\tpriority: issue.priority ?? DEFAULT_ISSUE_PRIORITY,\r\n\t\t})\r\n\r\n\t\tstore.dispatch(addIssue(issuePayload))\r\n\t\tstore.dispatch(addToRecentIssues(issuePayload.offline_id))\r\n\r\n\t\tconst promise = this.enqueueRequest<Created<Issue>>({\r\n\t\t\tdescription: \"Create issue\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: \"/issues/\",\r\n\t\t\tqueryParams: {\r\n\t\t\t\tworkspace_id: workspaceId,\r\n\t\t\t},\r\n\t\t\tpayload: issuePayload,\r\n\t\t\tblockers: [\r\n\t\t\t\t...(issuePayload.index_workspace ? [issuePayload.index_workspace] : []),\r\n\t\t\t\t...issuePayload.visible_in_workspaces,\r\n\t\t\t],\r\n\t\t\tblocks: [issuePayload.offline_id],\r\n\t\t})\r\n\t\tvoid promise\r\n\t\t\t.then((result: Created<Issue>) => {\r\n\t\t\t\tstore.dispatch(updateIssue(result)) // Updates the index in the store\r\n\t\t\t})\r\n\t\t\t.catch((error) => {\r\n\t\t\t\tconsole.error(error)\r\n\t\t\t\tif (error instanceof APIError) {\r\n\t\t\t\t\tunsafeShowToast?.({\r\n\t\t\t\t\t\ttitle: \"Could not create issue\",\r\n\t\t\t\t\t\tdescription: \"An unexpected error occurred while creating the issue.\",\r\n\t\t\t\t\t})\r\n\t\t\t\t}\r\n\t\t\t\tstore.dispatch(removeIssue(issuePayload.offline_id))\r\n\t\t\t\tthrow error\r\n\t\t\t})\r\n\t\treturn [issuePayload, promise]\r\n\t}\r\n\r\n\tfetchAll(projectId: number): OptimisticMultipleModelResult<Issue> {\r\n\t\tconst promise: Promise<Created<Issue>[]> = this.enqueueRequest<Created<Issue>[]>({\r\n\t\t\tdescription: \"Get issues\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${projectId}/issues/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t}).then((result) => {\r\n\t\t\tconst filteredResult = result.filter(onlyUniqueOfflineIds)\r\n\t\t\tif (result.length !== filteredResult.length) {\r\n\t\t\t\tconsole.error(\r\n\t\t\t\t\t`Received duplicate issues from the API (new length ${filteredResult.length});\r\n\t\t\t\t\t\t filtered in browser.`,\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t\treturn filteredResult\r\n\t\t})\r\n\r\n\t\tconst offlineIssues = Object.values(this.client.store.getState().issueReducer.issues)\r\n\t\treturn [offlineIssues, promise]\r\n\t}\r\n\r\n\tupdate(issue: Submitted<Partial<Issue>>): OptimisticModelResult<Issue> {\r\n\t\tthis.client.store.dispatch(updateIssue(issue))\r\n\t\tconst promise = this.enqueueRequest<Created<Issue>>({\r\n\t\t\tdescription: \"Edit issue\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/issues/${issue.offline_id}/`,\r\n\t\t\tpayload: issue,\r\n\t\t\tblockers: [issue.offline_id],\r\n\t\t\tblocks: [issue.offline_id],\r\n\t\t})\r\n\t\tconst fullIssue = this.client.store.getState().issueReducer.issues[issue.offline_id]!\r\n\t\treturn [fullIssue, promise]\r\n\t}\r\n\r\n\tasync remove(id: string): Promise<undefined> {\r\n\t\tconst state = this.client.store.getState()\r\n\t\tconst backup = state.issueReducer.issues[id]\r\n\t\tif (!backup) {\r\n\t\t\tthrow new Error(`No issue with id ${id} found in the store`)\r\n\t\t}\r\n\t\tconst attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue_id === id)\r\n\t\tconst attachmentsOfIssue = selectPhotoAttachmentsOfIssue(id)(state)\r\n\t\tthis.client.store.dispatch(removeIssue(id))\r\n\t\tif (attachmentsOfIssue) {\r\n\t\t\tthis.client.store.dispatch(removeAttachmentsOfIssue(id))\r\n\t\t}\r\n\t\ttry {\r\n\t\t\t// REASON: Need to await to trigger the catch block.\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\r\n\t\t\treturn await this.enqueueRequest<undefined>({\r\n\t\t\t\tdescription: \"Delete issue\",\r\n\t\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\t\turl: `/issues/${id}/`,\r\n\t\t\t\tblockers: [id],\r\n\t\t\t\tblocks: [],\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\tthis.client.store.dispatch(addIssue(backup))\r\n\t\t\tthis.client.store.dispatch(addAttachments(attachments))\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\t// Special functions\r\n\tasync refreshStore(): Promise<undefined> {\r\n\t\t// TODO: This is called far too often.\r\n\t\tconst { store } = this.client\r\n\t\tconst projectId = store.getState().projectReducer.activeProjectId\r\n\t\tif (!projectId) {\r\n\t\t\tthrow new Error(\"No active project\")\r\n\t\t}\r\n\t\tconst [_offlineIssues, promise] = this.fetchAll(projectId)\r\n\t\tconst result = await promise\r\n\t\tstore.dispatch(setIssues(result))\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { Category, Organization, Project, User, Workspace } from \"../../typings\"\r\nimport {\r\n\taddOrReplaceCategories,\r\n\taddOrReplaceProjects,\r\n\taddOrReplaceWorkspaces,\r\n\tresetRecentIssues,\r\n\tsetActiveOrganizationId,\r\n\tsetActiveProjectId,\r\n\tsetActiveWorkspaceId,\r\n\tsetAttachments,\r\n\tsetCategories,\r\n\tsetCurrentUser,\r\n\tsetIsFetchingInitialData,\r\n\tsetOrganizations,\r\n\tsetProjects,\r\n\taddUsers,\r\n\tsetWorkspaces,\r\n} from \"../../store\"\r\nimport { HttpMethod } from \"../../enums\"\r\n\r\nexport interface InitialAPIData {\r\n\tprojects: (Project & {\r\n\t\tworkspaces: {\r\n\t\t\tcategories?: Category[]\r\n\t\t\toffline_id: string\r\n\t\t\tname: string\r\n\t\t\tabbreviation: string\r\n\t\t\tpermitted: boolean\r\n\t\t}[]\r\n\t})[]\r\n\torganizations: Organization[]\r\n\tuser: User\r\n}\r\n\r\nexport class MainService extends BaseApiService {\r\n\tasync fetchInitialData(replaceExisting: boolean, uuid?: string): Promise<InitialAPIData> {\r\n\t\tif (replaceExisting) {\r\n\t\t\tthis.client.store.dispatch(setIsFetchingInitialData(true))\r\n\t\t}\r\n\t\treturn this.enqueueRequest<InitialAPIData>({\r\n\t\t\tuuid,\r\n\t\t\tdescription: \"Get initial data\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: \"/main/initial-data/\",\r\n\t\t\tpayload: {},\r\n\t\t\tisAuthNeeded: true,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t}).then((result) => {\r\n\t\t\tvoid this._processInitialData(result, replaceExisting)\r\n\t\t\treturn result\r\n\t\t})\r\n\t}\r\n\r\n\tasync fetchProjectUsers(projectId: number): Promise<User[]> {\r\n\t\treturn this.enqueueRequest({\r\n\t\t\tdescription: \"Fetch users\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${projectId}/users/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync fetchOrganizationUsers(orgId: number): Promise<User[]> {\r\n\t\treturn this.enqueueRequest({\r\n\t\t\tdescription: \"Fetch organization users\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/organizations/${orgId}/users/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\t// TODO:\r\n\t// Don't accept updateStore in ComponentService.list. Just return the offline objects and promise. Here, if\r\n\t// overwrite, use setComponents. Otherwise, use bulkAddComponents.\r\n\r\n\tasync _processInitialData(data: InitialAPIData, overwrite: boolean) {\r\n\t\tconst workspaces: Record<string, Workspace> = {}\r\n\t\tconst projects: Project[] = []\r\n\t\tconst categories: Category[] = []\r\n\t\tconst projectsData = data.projects\r\n\r\n\t\tconst { store } = this.client\r\n\t\tconst oldProjectId = store.getState().projectReducer.activeProjectId\r\n\t\tlet currentProjectId: number | undefined | null = oldProjectId ?? projectsData[0]?.id\r\n\t\tstore.dispatch(setActiveProjectId(currentProjectId ?? null))\r\n\t\tlet isProjectIdValid = false\r\n\r\n\t\t// TODO: Backend returns x_owner, but frontend here uses owner_x. We need to establish a convention for\r\n\t\t// which to use\r\n\t\tfor (const projectData of projectsData as unknown as (Project & {\r\n\t\t\tworkspaces: {\r\n\t\t\t\tcategories?: Category[]\r\n\t\t\t\toffline_id: string\r\n\t\t\t\tname: string\r\n\t\t\t\tabbreviation: string\r\n\t\t\t\tpermitted: boolean\r\n\t\t\t}[]\r\n\t\t} & {\r\n\t\t\torganization_owner: number\r\n\t\t\tuser_owner: number\r\n\t\t})[]) {\r\n\t\t\tprojects.push({\r\n\t\t\t\tid: projectData.id,\r\n\t\t\t\tname: projectData.name,\r\n\t\t\t\towner_organization: projectData.organization_owner,\r\n\t\t\t\towner_user: projectData.user_owner,\r\n\t\t\t\tbounds: projectData.bounds,\r\n\t\t\t})\r\n\t\t\tif (currentProjectId === projectData.id) {\r\n\t\t\t\tisProjectIdValid = true\r\n\t\t\t\tfor (const workspaceData of projectData.workspaces) {\r\n\t\t\t\t\tconst workspace = { ...workspaceData, project: projectData.id }\r\n\t\t\t\t\tif (workspace.categories) {\r\n\t\t\t\t\t\tfor (const category of workspace.categories) {\r\n\t\t\t\t\t\t\tcategories.push(category)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdelete workspace.categories\r\n\t\t\t\t\tworkspaces[workspace.offline_id] = workspace\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tstore.dispatch(setCurrentUser(data.user))\r\n\t\tconst organizationsData = data.organizations\r\n\t\tstore.dispatch(setOrganizations(organizationsData))\r\n\r\n\t\t// TODO: Add ability to select if there are multiple\r\n\t\tconst firstOrg = organizationsData[0]\r\n\t\tconst currProjObj = projects.find((project) => project.id === currentProjectId)\r\n\t\tconst isOrgProject = !!currProjObj?.owner_organization\r\n\t\tlet currentOrgId = -1\r\n\t\tif (isOrgProject && currProjObj.owner_organization) {\r\n\t\t\tcurrentOrgId = currProjObj.owner_organization\r\n\t\t} else if (firstOrg) {\r\n\t\t\tconsole.warn(\r\n\t\t\t\t\"No active organization; using the first available one. TODO: No active organization in personal projects.\",\r\n\t\t\t)\r\n\t\t\t// TODO: Should not set an active organization in a personal project\r\n\t\t\tcurrentOrgId = firstOrg.id\r\n\t\t}\r\n\r\n\t\tif (currentOrgId !== -1) {\r\n\t\t\tstore.dispatch(setActiveOrganizationId(currentOrgId))\r\n\r\n\t\t\tconst orgUsersResultPromise = this.fetchOrganizationUsers(currentOrgId)\r\n\t\t\tconst organizationAccessRefreshPromise = this.client.organizationAccess.refreshStore()\r\n\t\t\tconst orgUsersResult = await orgUsersResultPromise\r\n\t\t\tawait organizationAccessRefreshPromise\r\n\t\t\tstore.dispatch(addUsers(orgUsersResult))\r\n\t\t}\r\n\r\n\t\tif (!isProjectIdValid) {\r\n\t\t\tif (projects.length !== 0) {\r\n\t\t\t\tcurrentProjectId = projects[0]!.id\r\n\t\t\t\tstore.dispatch(setActiveProjectId(currentProjectId))\r\n\t\t\t\t// If `projects` has a length, so does `projectsData`\r\n\t\t\t\tconst projectData = projectsData[0]!\r\n\t\t\t\tfor (const workspaceData of projectData.workspaces) {\r\n\t\t\t\t\tconst workspace = { ...workspaceData, project: projectData.id }\r\n\t\t\t\t\tif (workspace.categories) {\r\n\t\t\t\t\t\tfor (const category of workspace.categories) {\r\n\t\t\t\t\t\t\tcategories.push(category)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tdelete workspace.categories\r\n\t\t\t\t\tworkspaces[workspace.offline_id] = workspace\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tcurrentProjectId = null\r\n\t\t\t\tstore.dispatch(setActiveProjectId(currentProjectId))\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (currentProjectId) {\r\n\t\t\tconst usersResultPromise = this.fetchProjectUsers(currentProjectId)\r\n\t\t\tconst projectAccessRefreshPromise = this.client.projectAccesses.refreshStore()\r\n\t\t\tconst usersResult = await usersResultPromise\r\n\t\t\tawait projectAccessRefreshPromise\r\n\t\t\tstore.dispatch(addUsers(usersResult))\r\n\t\t}\r\n\r\n\t\tlet currentWorkspaceId: string | undefined\r\n\t\tconst oldWorkspaceId = this.client.store.getState().workspaceReducer.activeWorkspaceId\r\n\t\tif (overwrite || !oldWorkspaceId) {\r\n\t\t\tcurrentWorkspaceId = Object.values(workspaces).at(0)?.offline_id\r\n\t\t} else {\r\n\t\t\tcurrentWorkspaceId = oldWorkspaceId\r\n\t\t}\r\n\r\n\t\tif (currentWorkspaceId && currentProjectId) {\r\n\t\t\tstore.dispatch(setActiveWorkspaceId(currentWorkspaceId))\r\n\r\n\t\t\t// TODO: Request all requests at once, then write to the store in the correct order.\r\n\t\t\t// We can even return a `initial_color` for components as a backup before stages and types are loaded.\r\n\t\t\t// At least use `blocks` and `blockers` instead of chaining.\r\n\t\t\t// TODO: Only overwrite if `overwrite === true`\r\n\t\t\tvoid this.client.categories.refreshStore().then(() => {\r\n\t\t\t\tvoid this.client.issues.refreshStore().then(() => {\r\n\t\t\t\t\tvoid this.client.issueComments.refreshStore().then()\r\n\t\t\t\t})\r\n\t\t\t})\r\n\t\t\tvoid this.client.projectFiles.refreshStore().then()\r\n\t\t\tvoid this.client.componentTypes.refreshStore().then(() => {\r\n\t\t\t\tvoid this.client.componentStages.refreshStore().then(() => {\r\n\t\t\t\t\tvoid this.client.components.refreshStore(overwrite).then()\r\n\t\t\t\t})\r\n\t\t\t\tvoid this.client.componentStageCompletions.refreshStore().then()\r\n\t\t\t})\r\n\t\t\tvoid this.client.userForms.refreshStore().then(() => {\r\n\t\t\t\tvoid this.client.userFormSubmissions.refreshStore().then()\r\n\t\t\t})\r\n\r\n\t\t\tvoid this.client.emailDomains.refreshStore().then()\r\n\t\t}\r\n\r\n\t\t// TODO: Everything in the `if (currentWorkspace)` block above should go in here:\r\n\t\tif (currentProjectId) {\r\n\t\t\tconst [_offlineAttachments, promise] = this.client.attachments.fetchAll(currentProjectId)\r\n\t\t\tvoid promise.then((result) => {\r\n\t\t\t\tstore.dispatch(setAttachments(result))\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\tstore.dispatch(setIsFetchingInitialData(false))\r\n\r\n\t\t// TODO: Follow same pattern as above (refreshStore)\r\n\t\tif (overwrite) {\r\n\t\t\tconsole.log(\"Overwriting data\")\r\n\t\t\tstore.dispatch(setProjects(projects))\r\n\t\t\tstore.dispatch(setWorkspaces(workspaces))\r\n\t\t\tstore.dispatch(setCategories(categories))\r\n\t\t\tstore.dispatch(resetRecentIssues())\r\n\t\t} else {\r\n\t\t\tconsole.log(\"Updating data (collisions will be replaced)\")\r\n\t\t\tstore.dispatch(addOrReplaceProjects(projects))\r\n\t\t\tstore.dispatch(addOrReplaceWorkspaces(workspaces))\r\n\t\t\tstore.dispatch(addOrReplaceCategories(categories))\r\n\t\t}\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { removeProjectAccess, removeUser, setProjectAccesses, updateProjectAccess } from \"../../store\"\r\nimport { ProjectAccess } from \"../../typings\"\r\n\r\n/**\r\n * Handles the creation of ProjectAccess Service\r\n */\r\nexport class ProjectAccessService extends BaseApiService {\r\n\tasync fetchAll(projectId: number): Promise<ProjectAccess[]> {\r\n\t\treturn this.enqueueRequest<ProjectAccess[]>({\r\n\t\t\tdescription: \"Get project accesses\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${projectId}/access/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync update(projectAccess: ProjectAccess): Promise<ProjectAccess> {\r\n\t\tthis.client.store.dispatch(updateProjectAccess(projectAccess))\r\n\t\treturn this.enqueueRequest<ProjectAccess>({\r\n\t\t\tdescription: \"Edit project access\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/access/${projectAccess.offline_id}/`,\r\n\t\t\tpayload: projectAccess,\r\n\t\t\tblockers: [projectAccess.offline_id],\r\n\t\t\tblocks: [projectAccess.offline_id],\r\n\t\t})\r\n\t}\r\n\t// TODO: Re-add user to project if removal fails\r\n\tasync remove(projectAccess: ProjectAccess): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\r\n\t\tstore.dispatch(removeProjectAccess(projectAccess))\r\n\t\tstore.dispatch(removeUser(projectAccess.user))\r\n\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete project access\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/access/${projectAccess.offline_id}/`,\r\n\t\t\tblockers: [projectAccess.offline_id],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst projectId = state.projectReducer.activeProjectId\r\n\t\tconst currentUser = state.userReducer.currentUser\r\n\t\tif (!projectId) {\r\n\t\t\tthrow new Error(\"No active project\")\r\n\t\t}\r\n\t\tconst promise = this.fetchAll(projectId)\r\n\t\tconst result: ProjectAccess[] = await promise\r\n\t\tconst activeProjectAccess = result.find((projectAccess) => projectAccess.user === currentUser.id)\r\n\t\tif (!activeProjectAccess) {\r\n\t\t\tthrow new Error(\"Current user does not have a project access instance\")\r\n\t\t}\r\n\t\tstore.dispatch(setProjectAccesses(result))\r\n\t}\r\n}\r\n","import { HttpMethod } from \"enums/api\"\r\nimport { ProjectFile } from \"typings/models/projects\"\r\nimport { OptimisticGenericResult, SDKRequest } from \"../typings\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport {\r\n\taddOrReplaceProjectFile,\r\n\taddOrReplaceProjectFiles,\r\n\tremoveProjectFile,\r\n\tsaveActiveProjectFileBounds,\r\n\tsetActiveProjectFileId,\r\n\tsetIsImportingProjectFile,\r\n} from \"store/slices/projectFileSlice\"\r\n\r\n/**\r\n * Handles creation and caching of ProjectFiles\r\n */\r\nexport class ProjectFileService extends BaseApiService {\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<ProjectFile[]>({\r\n\t\t\tdescription: \"Get project files\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/files/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tstore.dispatch(addOrReplaceProjectFiles(result))\r\n\t}\r\n\r\n\tasync saveExisting(file: ProjectFile): Promise<ProjectFile> {\r\n\t\tif (!file.offline_id) {\r\n\t\t\tthrow new Error(\r\n\t\t\t\t\"You can only use this method to save existing project files. The one provided has no offline_id.\",\r\n\t\t\t)\r\n\t\t}\r\n\t\tconst editableData: { file?: unknown } = { ...file }\r\n\t\tdelete editableData.file\r\n\t\tconst promise = this.enqueueRequest<ProjectFile>({\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/projects/files/${file.offline_id}/`,\r\n\t\t\tpayload: editableData,\r\n\t\t\tblockers: [file.offline_id],\r\n\t\t\tblocks: [file.offline_id],\r\n\t\t})\r\n\t\tvoid promise.then((result) => {\r\n\t\t\tthis.client.store.dispatch(addOrReplaceProjectFile(result))\r\n\t\t})\r\n\t\treturn promise\r\n\t}\r\n\tsaveActive(): OptimisticGenericResult<ProjectFile> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst activeProjectFileId = state.projectFileReducer.activeProjectFileId\r\n\t\tconst activeProjectId = state.projectReducer.activeProjectId\r\n\t\tif (!activeProjectFileId) {\r\n\t\t\tthrow new Error(\"No active project file\")\r\n\t\t}\r\n\t\tif (!activeProjectId) {\r\n\t\t\tthrow new Error(\"No active project\")\r\n\t\t}\r\n\t\tconst activeProjectFile = state.projectFileReducer.projectFiles[activeProjectFileId]\r\n\t\tif (!activeProjectFile) {\r\n\t\t\tthrow new Error(\"No active project file\")\r\n\t\t}\r\n\r\n\t\tlet requestDetails: SDKRequest | Promise<SDKRequest>\r\n\t\tconst existing = typeof activeProjectFile.file === \"string\" && !activeProjectFile.file.startsWith(\"blob:\")\r\n\t\tif (existing) {\r\n\t\t\tconst editableData: { file?: unknown } = { ...activeProjectFile }\r\n\t\t\tdelete editableData.file\r\n\t\t\trequestDetails = {\r\n\t\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\t\turl: `/projects/files/${activeProjectFileId}/`,\r\n\t\t\t\tpayload: editableData,\r\n\t\t\t\tblockers: [activeProjectFileId],\r\n\t\t\t\tblocks: [activeProjectFileId],\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\trequestDetails = new Promise<SDKRequest>((resolve, reject) => {\r\n\t\t\t\tthis.client.files\r\n\t\t\t\t\t.uploadFileToS3(activeProjectFile.file_sha1)\r\n\t\t\t\t\t.then(([fileProps]) => {\r\n\t\t\t\t\t\tresolve({\r\n\t\t\t\t\t\t\tmethod: HttpMethod.POST,\r\n\t\t\t\t\t\t\turl: `/projects/${activeProjectId}/files/`,\r\n\t\t\t\t\t\t\tpayload: {\r\n\t\t\t\t\t\t\t\t...activeProjectFile,\r\n\t\t\t\t\t\t\t\tbounds: JSON.stringify(activeProjectFile.bounds),\r\n\t\t\t\t\t\t\t\t...fileProps,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tblockers: [activeProjectFileId],\r\n\t\t\t\t\t\t\tblocks: [activeProjectFileId],\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t})\r\n\t\t\t\t\t.catch(reject)\r\n\t\t\t})\r\n\t\t}\r\n\t\tconst promise = Promise.resolve(requestDetails).then((requestDetails) => {\r\n\t\t\treturn this.enqueueRequest<ProjectFile>(requestDetails)\r\n\t\t})\r\n\t\tvoid promise.then((result) => {\r\n\t\t\tstore.dispatch(addOrReplaceProjectFile(result))\r\n\t\t})\r\n\t\tstore.dispatch(saveActiveProjectFileBounds)\r\n\t\tstore.dispatch(setActiveProjectFileId(null))\r\n\t\tstore.dispatch(setIsImportingProjectFile(false))\r\n\t\treturn [activeProjectFile, promise]\r\n\t}\r\n\r\n\tdelete(projectFileId: string): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(removeProjectFile(projectFileId))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/projects/files/${projectFileId}`,\r\n\t\t\tblockers: [projectFileId],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","import { HttpMethod } from \"enums/api\"\r\nimport { Project } from \"typings/models/projects\"\r\nimport type { ApiSuccessResult } from \"../typings\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { v4 as uuidv4 } from \"uuid\"\r\nimport { Created, Payload } from \"../../typings\"\r\nimport {\r\n\taddOrReplaceProjectFiles,\r\n\tdeleteProject,\r\n\tremoveProjectAccessesOfProject,\r\n\tremoveProjectFilesOfProject,\r\n\tselectProjectAccesses,\r\n\tselectProjectFiles,\r\n\tselectProjects,\r\n\tsetActiveProjectId,\r\n\tsetProjectAccesses,\r\n\tsetProjects,\r\n\tupdateOrCreateProject,\r\n} from \"../../store\"\r\n\r\ninterface JoinProjectResponse {\r\n\tusername: string\r\n}\r\n\r\nexport class ProjectService extends BaseApiService {\r\n\t/**\r\n\t * Creates a new project. Due to the nature of project creation,\r\n\t * @param project A Payload<Project> object containing project attributes.\r\n\t * @returns A promise that resolves to a Project.\r\n\t * @throws An APIError if the server returns an error, or any other error that may occur.\r\n\t */\r\n\tasync add(project: Payload<Project>): Promise<Project> {\r\n\t\tif (!project.bounds) {\r\n\t\t\tthrow new Error(\"Project bounds were not set before trying to create a project\")\r\n\t\t}\r\n\t\tif (!project.owner_organization && !project.owner_user) {\r\n\t\t\tthrow new Error(\"Project type was not chosen when trying to create a project\")\r\n\t\t}\r\n\t\tconst isOrganizationProject = !!project.owner_organization\r\n\t\tconst activeOrganization = this.client.store.getState().organizationReducer.activeOrganizationId\r\n\t\tif (isOrganizationProject && (!activeOrganization || project.owner_organization !== activeOrganization)) {\r\n\t\t\tthrow new Error(\"User tried creating organization project for organization they do not belong to.\")\r\n\t\t}\r\n\t\tconst url = isOrganizationProject ? `/organizations/${project.owner_organization}/projects/` : \"/projects/\"\r\n\t\tconst projectType = isOrganizationProject\r\n\t\t\t? { organization_owner: project.owner_organization }\r\n\t\t\t: { user_owner: project.owner_user }\r\n\t\tconst result = await this.enqueueRequest<Created<Project>>({\r\n\t\t\tdescription: \"Create project\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl,\r\n\t\t\tpayload: {\r\n\t\t\t\tname: project.name,\r\n\t\t\t\tbounds: {\r\n\t\t\t\t\ttype: \"MultiPoint\",\r\n\t\t\t\t\tcoordinates: [project.bounds[0], project.bounds[1]],\r\n\t\t\t\t},\r\n\t\t\t\t...projectType,\r\n\t\t\t},\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tawait this.client.main.fetchInitialData(true)\r\n\t\treturn result\r\n\t}\r\n\r\n\tasync update(project: Project): Promise<Project> {\r\n\t\tconst { store } = this.client\r\n\t\tif (!project.bounds) {\r\n\t\t\tthrow new Error(\"Project bounds were not set before trying to create a project\")\r\n\t\t}\r\n\r\n\t\tstore.dispatch(updateOrCreateProject(project))\r\n\t\treturn await this.enqueueRequest<Project>({\r\n\t\t\tdescription: \"Update project\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/projects/${project.id}/`,\r\n\t\t\tpayload: {\r\n\t\t\t\tname: project.name,\r\n\t\t\t\tbounds: {\r\n\t\t\t\t\ttype: \"MultiPoint\",\r\n\t\t\t\t\tcoordinates: [project.bounds[0], project.bounds[1]],\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t\tblockers: [project.id.toString()],\r\n\t\t\tblocks: [project.id.toString()],\r\n\t\t})\r\n\t}\r\n\r\n\tasync delete(projectId: number): Promise<ApiSuccessResult<undefined>> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst projects = selectProjects(state)\r\n\t\tconst project = projects[projectId]\r\n\t\tif (!project) {\r\n\t\t\tthrow new Error(\"Expected project to exist\")\r\n\t\t}\r\n\r\n\t\tconst activeProjectId = state.projectReducer.activeProjectId\r\n\t\tif (activeProjectId === projectId) {\r\n\t\t\tstore.dispatch({ type: \"project/setActiveProjectId\", payload: null })\r\n\t\t}\r\n\r\n\t\t// Selector needed to restore if the request fails\r\n\t\tconst filesToDelete = selectProjectFiles(state).filter((file) => file.project === projectId)\r\n\t\tstore.dispatch(removeProjectFilesOfProject(project.id))\r\n\r\n\t\t// Selector needed to restore if the request fails\r\n\t\tconst projectAccesses = selectProjectAccesses(state)\r\n\t\tstore.dispatch(removeProjectAccessesOfProject(project.id))\r\n\r\n\t\t// Necessary to prevent no projects view from showing when project is deleted\r\n\t\tstore.dispatch({ type: \"rehydrated/setRehydrated\", payload: false })\r\n\t\tstore.dispatch(deleteProject(project))\r\n\r\n\t\ttry {\r\n\t\t\tawait this.enqueueRequest<undefined>({\r\n\t\t\t\tdescription: \"Delete project\",\r\n\t\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\t\turl: `/projects/${projectId}/`,\r\n\t\t\t\tblockers: [projectId.toString()],\r\n\t\t\t\tblocks: [],\r\n\t\t\t})\r\n\t\t\tstore.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\r\n\t\t} catch (e) {\r\n\t\t\tstore.dispatch(setProjects(Object.values(projects)))\r\n\t\t\tstore.dispatch(setProjectAccesses(Object.values(projectAccesses)))\r\n\t\t\tstore.dispatch(addOrReplaceProjectFiles(filesToDelete))\r\n\t\t\tstore.dispatch(setActiveProjectId(activeProjectId))\r\n\t\t\tstore.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\tinvite(projectId: number, email: string): Promise<undefined> {\r\n\t\tconst offline_id: string = uuidv4()\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Invite user to project\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/projects/${projectId}/invite/${email}/`,\r\n\t\t\tpayload: {\r\n\t\t\t\toffline_id,\r\n\t\t\t},\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offline_id],\r\n\t\t})\r\n\t}\r\n\r\n\tjoinProject(projectId: number, userId: number, inviteCode: string): Promise<ApiSuccessResult<JoinProjectResponse>> {\r\n\t\treturn this.enqueueRequest<JoinProjectResponse>({\r\n\t\t\tdescription: \"Join project\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/projects/${projectId}/join-project/${userId}/${inviteCode}/`,\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","import { HttpMethod } from \"enums/api\"\r\nimport {\r\n\taddUserForm,\r\n\taddUserFormRevision,\r\n\taddUserFormRevisions,\r\n\taddUserForms,\r\n\taddUserFormSubmissions,\r\n\tdeleteUserForm,\r\n\tdeleteUserFormRevision,\r\n\tdeleteUserFormRevisions,\r\n\tdeleteUserFormSubmissions,\r\n\tfavoriteForm,\r\n\tselectRevisionsForForm,\r\n\tselectSubmissionsForForm,\r\n\tselectUserForm,\r\n\tunfavoriteForm,\r\n} from \"store/slices/userFormSlice\"\r\nimport { SubmittedUserForm, UserForm, UserFormRevision, UserFormRevisionPayload } from \"typings/models/forms\"\r\nimport { OptimisticModelResult } from \"../typings\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { offline } from \"utils/offline\"\r\nimport { Created, RootState } from \"../../typings\"\r\n\r\nexport class UserFormService extends BaseApiService {\r\n\tprivate add(\r\n\t\tstate: RootState,\r\n\t\tinitialRevision: UserFormRevisionPayload,\r\n\t\turl: string,\r\n\t\townerUser: number | undefined,\r\n\t\townerOrganization?: number,\r\n\t): [UserForm, UserFormRevision, Promise<UserFormRevision>] {\r\n\t\tif (!!ownerUser === !!ownerOrganization) {\r\n\t\t\tthrow new Error(\"Exactly one of ownerUser and ownerOrganization must be defined.\")\r\n\t\t}\r\n\r\n\t\tconst ownerAttrs = {\r\n\t\t\towner_user: ownerUser,\r\n\t\t\towner_organization: ownerOrganization,\r\n\t\t} as\r\n\t\t\t| {\r\n\t\t\t\t\towner_user: number\r\n\t\t\t\t\towner_organization: undefined\r\n\t\t\t }\r\n\t\t\t| {\r\n\t\t\t\t\towner_user: undefined\r\n\t\t\t\t\towner_organization: number\r\n\t\t\t }\r\n\r\n\t\tconst currentUser = state.userReducer.currentUser\r\n\t\tconst activeWorkspaceId = state.workspaceReducer.activeWorkspaceId\r\n\t\t// NOTE: Creating forms only requires an offline ID, nothing else (except for the initial revision).\r\n\t\tconst offlineFormPayload = offline({})\r\n\t\tconst offlineRevisionPayload = offline(initialRevision)\r\n\t\tconst retForm: SubmittedUserForm = {\r\n\t\t\t...offlineFormPayload,\r\n\t\t\tindex_workspace: activeWorkspaceId,\r\n\t\t\tfavorite: true,\r\n\t\t\tsubmitted_at: new Date().toISOString(),\r\n\t\t\tcreated_by: currentUser.id,\r\n\t\t\t...ownerAttrs,\r\n\t\t}\r\n\t\tconst retRevision: UserFormRevision = {\r\n\t\t\t...offlineRevisionPayload,\r\n\t\t\tcreated_by: currentUser.id,\r\n\t\t\tform: retForm.offline_id,\r\n\t\t\trevision: 0,\r\n\t\t}\r\n\t\tconst { store } = this.client\r\n\t\tstore.dispatch(addUserForm(retForm))\r\n\t\tstore.dispatch(addUserFormRevision(retRevision))\r\n\r\n\t\tconst formPromise = this.enqueueRequest<UserFormRevision>({\r\n\t\t\tdescription: \"Create form\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl,\r\n\t\t\tqueryParams: activeWorkspaceId\r\n\t\t\t\t? {\r\n\t\t\t\t\t\tworkspace_id: activeWorkspaceId,\r\n\t\t\t\t }\r\n\t\t\t\t: undefined,\r\n\t\t\tpayload: { ...offlineFormPayload, initial_revision: offlineRevisionPayload },\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offlineFormPayload.offline_id, offlineRevisionPayload.offline_id],\r\n\t\t})\r\n\r\n\t\tvoid formPromise.catch((e) => {\r\n\t\t\tstore.dispatch(deleteUserForm(retForm.offline_id))\r\n\t\t\tstore.dispatch(deleteUserFormRevision(retRevision.offline_id))\r\n\t\t\tthrow e\r\n\t\t})\r\n\r\n\t\treturn [retForm, retRevision, formPromise]\r\n\t}\r\n\taddForOrganization(\r\n\t\tinitialRevision: UserFormRevisionPayload,\r\n\t): [UserForm, UserFormRevision, Promise<UserFormRevision>] {\r\n\t\tconst state: RootState = this.client.store.getState()\r\n\t\tconst activeOrganizationId = state.organizationReducer.activeOrganizationId\r\n\r\n\t\tif (!activeOrganizationId) {\r\n\t\t\tthrow new Error(\"Cannot add forms for organization when there is no active organization.\")\r\n\t\t}\r\n\t\treturn this.add(\r\n\t\t\tstate,\r\n\t\t\tinitialRevision,\r\n\t\t\t`/forms/in-organization/${activeOrganizationId}/`,\r\n\t\t\tundefined,\r\n\t\t\tactiveOrganizationId,\r\n\t\t)\r\n\t}\r\n\r\n\taddForCurrentUser(initialRevision: UserFormRevision): [UserForm, UserFormRevision, Promise<UserFormRevision>] {\r\n\t\tconst state: RootState = this.client.store.getState()\r\n\t\tconst currentUser = state.userReducer.currentUser\r\n\t\treturn this.add(state, initialRevision, \"/forms/my-forms/\", currentUser.id)\r\n\t}\r\n\tcreateRevision(formId: string, revision: UserFormRevisionPayload): OptimisticModelResult<UserFormRevision> {\r\n\t\tconst offlineRevision = offline(revision)\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst activeProjectId = state.projectReducer.activeProjectId\r\n\t\tif (!activeProjectId) {\r\n\t\t\tthrow new Error(\"Cannot create form revision when there is no active project.\")\r\n\t\t}\r\n\t\tconst currentUserId = state.userReducer.currentUser.id\r\n\t\tconst fullRevision: UserFormRevision = {\r\n\t\t\t...offlineRevision,\r\n\t\t\tcreated_by: currentUserId,\r\n\t\t\trevision: \"Pending\",\r\n\t\t\tform: formId,\r\n\t\t}\r\n\t\t// TODO: Rename to addOrReplaceUserFormRevision or make two separate methods. Standardize across services.\r\n\t\tstore.dispatch(addUserFormRevision(fullRevision))\r\n\t\tconst promise = this.enqueueRequest<UserFormRevision>({\r\n\t\t\tdescription: \"Create form revision\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/forms/${formId}/`,\r\n\t\t\tpayload: { initial_revision: offlineRevision },\r\n\t\t\tqueryParams: {\r\n\t\t\t\tproject_id: activeProjectId.toString(),\r\n\t\t\t},\r\n\t\t\tblockers: [formId],\r\n\t\t\tblocks: [offlineRevision.offline_id],\r\n\t\t})\r\n\t\tvoid promise\r\n\t\t\t.then((result) => {\r\n\t\t\t\tstore.dispatch(addUserFormRevision(result))\r\n\t\t\t})\r\n\t\t\t.catch(() => {\r\n\t\t\t\tstore.dispatch(deleteUserFormRevision(fullRevision.offline_id))\r\n\t\t\t})\r\n\t\treturn [fullRevision, promise]\r\n\t}\r\n\r\n\tasync favorite(formId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst activeProjectId = store.getState().projectReducer.activeProjectId\r\n\t\tstore.dispatch(favoriteForm({ formId }))\r\n\t\ttry {\r\n\t\t\tawait this.enqueueRequest({\r\n\t\t\t\tdescription: \"Favorite form\",\r\n\t\t\t\tmethod: HttpMethod.POST,\r\n\t\t\t\turl: `/forms/${formId}/favorite/${activeProjectId}/`,\r\n\t\t\t\tblockers: [formId, `favorite-${formId}`],\r\n\t\t\t\tblocks: [`favorite-${formId}`],\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\tstore.dispatch(unfavoriteForm({ formId }))\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\tasync unfavorite(formId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst activeProjectId = store.getState().projectReducer.activeProjectId\r\n\t\tstore.dispatch(unfavoriteForm({ formId }))\r\n\t\ttry {\r\n\t\t\t// REASON: Need to await to trigger the catch block.\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\r\n\t\t\treturn await this.enqueueRequest<undefined>({\r\n\t\t\t\tdescription: \"Unfavorite form\",\r\n\t\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\t\turl: `/forms/${formId}/unfavorite/${activeProjectId}/`,\r\n\t\t\t\tblockers: [formId, `favorite-${formId}`],\r\n\t\t\t\tblocks: [`favorite-${formId}`],\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\tstore.dispatch(favoriteForm({ formId }))\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\tasync delete(formId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst userForm = selectUserForm(formId)(state)\r\n\t\tif (!userForm) {\r\n\t\t\tthrow new Error(\"Expected userForm to exist\")\r\n\t\t}\r\n\t\t// Delete all submissions for this form\r\n\t\tconst userFormSubmissions = selectSubmissionsForForm(formId)(state)\r\n\t\tif (userFormSubmissions && userFormSubmissions.length > 0) {\r\n\t\t\tstore.dispatch(deleteUserFormSubmissions(userFormSubmissions))\r\n\t\t}\r\n\r\n\t\t// Delete all revisions for this form\r\n\t\tconst userFormRevisions = selectRevisionsForForm(formId)(state)\r\n\t\tif (userFormRevisions && userFormRevisions.length > 0) {\r\n\t\t\tstore.dispatch(deleteUserFormRevisions(userFormRevisions))\r\n\t\t}\r\n\r\n\t\t// Delete the form itself\r\n\t\tstore.dispatch(deleteUserForm(formId))\r\n\r\n\t\ttry {\r\n\t\t\t// REASON: Need to await to trigger the catch block.\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\r\n\t\t\treturn await this.enqueueRequest<undefined>({\r\n\t\t\t\tdescription: \"Delete form\",\r\n\t\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\t\turl: `/forms/${formId}/`,\r\n\t\t\t\tblockers: [formId],\r\n\t\t\t\tblocks: [],\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\tstore.dispatch(addUserForm(userForm))\r\n\t\t\tif (userFormRevisions && userFormRevisions.length > 0) {\r\n\t\t\t\tstore.dispatch(addUserFormRevisions(userFormRevisions))\r\n\t\t\t}\r\n\t\t\tif (userFormSubmissions && userFormSubmissions.length > 0) {\r\n\t\t\t\tstore.dispatch(addUserFormSubmissions(userFormSubmissions))\r\n\t\t\t}\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst result = await this.enqueueRequest<{ forms: Created<UserForm>[]; revisions: UserFormRevision[] }>({\r\n\t\t\tdescription: \"Fetch user forms\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/forms/in-project/${store.getState().projectReducer.activeProjectId}/forms/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tstore.dispatch(addUserForms(Object.values(result.forms)))\r\n\t\tstore.dispatch(addUserFormRevisions(Object.values(result.revisions)))\r\n\t}\r\n}\r\n","import { Offline } from \"typings/models/base\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { UserFormSubmission, UserFormSubmissionAttachment, UserFormSubmissionPayload } from \"typings/models/forms\"\r\nimport { OptimisticModelResult } from \"../typings\"\r\nimport { HttpMethod } from \"enums/api\"\r\nimport {\r\n\taddUserFormSubmission,\r\n\taddUserFormSubmissionAttachment,\r\n\tdeleteUserFormSubmission,\r\n\tsetUserFormSubmissionAttachments,\r\n\tsetUserFormSubmissions,\r\n} from \"store/slices/userFormSlice\"\r\nimport { FieldValue } from \"forms\"\r\nimport { hashFile, offline } from \"utils\"\r\n\r\nconst isArrayOfFiles = (value: unknown): value is File[] => {\r\n\treturn Array.isArray(value) && value[0] instanceof File\r\n}\r\n\r\nconst separateFilesFromValues = (payload: Offline<UserFormSubmissionPayload>) => {\r\n\tconst { values } = payload\r\n\tconst files: Record<string, File[]> = {}\r\n\tconst newValues: Record<string, FieldValue> = {}\r\n\tfor (const key in values) {\r\n\t\tconst value = values[key]\r\n\r\n\t\tif (value === undefined) throw new Error(\"Expected value to be defined\")\r\n\r\n\t\tif (value instanceof File) {\r\n\t\t\tfiles[key] = [value]\r\n\t\t} else if (isArrayOfFiles(value)) {\r\n\t\t\tfiles[key] = value\r\n\t\t} else {\r\n\t\t\tnewValues[key] = value\r\n\t\t}\r\n\t}\r\n\r\n\tconst payloadWithoutFiles = {\r\n\t\t...payload,\r\n\t\tvalues: newValues,\r\n\t}\r\n\r\n\treturn { payloadWithoutFiles, files }\r\n}\r\n\r\nexport class UserFormSubmissionService extends BaseApiService {\r\n\tadd(payload: Offline<UserFormSubmissionPayload>): OptimisticModelResult<UserFormSubmission> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst activeProjectId = state.projectReducer.activeProjectId\r\n\r\n\t\tif (!activeProjectId) {\r\n\t\t\tthrow new Error(\"Expected an active project\")\r\n\t\t}\r\n\r\n\t\tconst { payloadWithoutFiles, files } = separateFilesFromValues(payload)\r\n\t\tconst promise = this.enqueueRequest<UserFormSubmission>({\r\n\t\t\tdescription: \"Respond to form\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/forms/revisions/${payload.form_revision}/respond/`,\r\n\t\t\tpayload: { ...payloadWithoutFiles, project: activeProjectId },\r\n\t\t\tblockers: [payload.issue, payload.component].filter((x) => x !== undefined) as string[],\r\n\t\t\tblocks: [payload.offline_id],\r\n\t\t})\r\n\r\n\t\t// attach files to submission, after uploading them to S3\r\n\t\tconst attachFilesPromises = Object.entries(files).map(async ([key, fileArray]) => {\r\n\t\t\tconst attachResults: UserFormSubmissionAttachment[] = []\r\n\t\t\tfor (const file of fileArray) {\r\n\t\t\t\tconst sha1 = await hashFile(file)\r\n\t\t\t\tawait this.client.files.addCache(file, sha1)\r\n\t\t\t\tconst [fileProps] = await this.client.files.uploadFileToS3(sha1)\r\n\t\t\t\tconst submissionAttachmentPayload: UserFormSubmissionAttachment = offline({\r\n\t\t\t\t\t...fileProps,\r\n\t\t\t\t\tsubmission: payload.offline_id,\r\n\t\t\t\t\tfield_identifier: key,\r\n\t\t\t\t})\r\n\t\t\t\tconst attach = await this.enqueueRequest<UserFormSubmissionAttachment>({\r\n\t\t\t\t\tdescription: \"Attach file to form submission\",\r\n\t\t\t\t\tmethod: HttpMethod.POST,\r\n\t\t\t\t\turl: `/forms/submission/${payload.offline_id}/attachments/`,\r\n\t\t\t\t\tpayload: submissionAttachmentPayload,\r\n\t\t\t\t\tblockers: [payload.component, payload.issue, payload.form_revision].filter(\r\n\t\t\t\t\t\t(x) => x !== undefined,\r\n\t\t\t\t\t) as string[],\r\n\t\t\t\t\tblocks: [submissionAttachmentPayload.offline_id],\r\n\t\t\t\t})\r\n\t\t\t\tconst offlinePayload = {\r\n\t\t\t\t\t...submissionAttachmentPayload,\r\n\t\t\t\t\tfile: URL.createObjectURL(file),\r\n\t\t\t\t}\r\n\t\t\t\tstore.dispatch(addUserFormSubmissionAttachment(offlinePayload))\r\n\r\n\t\t\t\tattachResults.push(attach)\r\n\t\t\t}\r\n\r\n\t\t\treturn attachResults\r\n\t\t})\r\n\r\n\t\tconst fullOfflineResult: UserFormSubmission = {\r\n\t\t\t...payload,\r\n\t\t\tcreated_by: state.userReducer.currentUser.id,\r\n\t\t\tcreated_at: new Date().toISOString(),\r\n\t\t}\r\n\t\tconst offlineResultWithoutFiles = {\r\n\t\t\t...fullOfflineResult,\r\n\t\t\t...payloadWithoutFiles,\r\n\t\t}\r\n\t\tstore.dispatch(addUserFormSubmission(offlineResultWithoutFiles))\r\n\t\tvoid promise\r\n\t\t\t.then((result) => {\r\n\t\t\t\tstore.dispatch(addUserFormSubmission(result))\r\n\t\t\t\treturn result\r\n\t\t\t})\r\n\t\t\t.catch(() => {\r\n\t\t\t\tstore.dispatch(deleteUserFormSubmission(payload.offline_id))\r\n\t\t\t})\r\n\r\n\t\tconst settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise)\r\n\r\n\t\treturn [fullOfflineResult, settledPromise]\r\n\t}\r\n\r\n\tasync delete(submissionId: string): Promise<undefined> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst submission = state.userFormReducer.submissions[submissionId]\r\n\t\tstore.dispatch(deleteUserFormSubmission(submissionId))\r\n\t\ttry {\r\n\t\t\t// REASON: Need to await to trigger the catch block.\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\r\n\t\t\treturn await this.enqueueRequest<undefined>({\r\n\t\t\t\tdescription: \"Delete user form submissions\",\r\n\t\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\t\turl: `/forms/submissions/${submissionId}/`,\r\n\t\t\t\tblockers: [submissionId],\r\n\t\t\t\tblocks: [],\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\tif (submission) {\r\n\t\t\t\tstore.dispatch(addUserFormSubmission(submission))\r\n\t\t\t}\r\n\t\t\tthrow e\r\n\t\t}\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst projectId = store.getState().projectReducer.activeProjectId\r\n\t\tconst submissions = await this.enqueueRequest<UserFormSubmission[]>({\r\n\t\t\tdescription: \"Fetch form submissions\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/forms/in-project/${projectId}/submissions/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\r\n\t\tstore.dispatch(setUserFormSubmissions(submissions))\r\n\r\n\t\tconst attachments = await this.enqueueRequest<UserFormSubmissionAttachment[]>({\r\n\t\t\tdescription: \"Fetch form attachments\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/forms/in-project/${projectId}/attachments/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\r\n\t\tstore.dispatch(setUserFormSubmissionAttachments(attachments))\r\n\t}\r\n}\r\n","import { HttpMethod } from \"enums/api\"\r\nimport { addOrReplaceWorkspaces, addWorkspace, removeWorkspace } from \"store/slices/workspaceSlice\"\r\nimport { Payload } from \"typings/models/base\"\r\nimport { Workspace } from \"typings/models/workspace\"\r\nimport { ApiResult, OptimisticModelResult } from \"../typings\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { offline } from \"utils/offline\"\r\n\r\nexport class WorkspaceService extends BaseApiService {\r\n\tadd(workspace: Payload<Workspace>): OptimisticModelResult<Workspace> {\r\n\t\tconst { store } = this.client\r\n\t\tconst offlineWorkspace = offline(workspace)\r\n\t\tstore.dispatch(addWorkspace(offlineWorkspace))\r\n\t\tconst promise = this.enqueueRequest<Workspace>({\r\n\t\t\tdescription: \"Create Workspace\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/projects/${store.getState().projectReducer.activeProjectId}/workspaces/`,\r\n\t\t\tpayload: offlineWorkspace,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [offlineWorkspace.offline_id],\r\n\t\t})\r\n\t\tvoid promise\r\n\t\t\t.then((result) => {\r\n\t\t\t\tstore.dispatch(addOrReplaceWorkspaces({ [offlineWorkspace.offline_id]: result }))\r\n\t\t\t})\r\n\t\t\t.catch(() => {\r\n\t\t\t\tstore.dispatch(removeWorkspace(offlineWorkspace.offline_id))\r\n\t\t\t})\r\n\r\n\t\treturn [offlineWorkspace, promise]\r\n\t}\r\n\r\n\tupdate(workspace: Workspace): OptimisticModelResult<Workspace> {\r\n\t\tconst { store } = this.client\r\n\t\tstore.dispatch(addOrReplaceWorkspaces({ [workspace.offline_id]: workspace }))\r\n\t\tconst promise = this.enqueueRequest<Workspace>({\r\n\t\t\tdescription: \"Update Workspace\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/workspaces/${workspace.offline_id}/`,\r\n\t\t\tpayload: workspace,\r\n\t\t\tblockers: [workspace.offline_id],\r\n\t\t\tblocks: [workspace.offline_id],\r\n\t\t})\r\n\r\n\t\treturn [workspace, promise]\r\n\t}\r\n\r\n\tdelete(workspaceId: string): Promise<ApiResult<undefined>> {\r\n\t\tconst { store } = this.client\r\n\t\tconst promise = this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Delete Workspace\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/workspaces/${workspaceId}/`,\r\n\t\t\tblockers: [workspaceId],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tconst originalWorkspace = store.getState().workspaceReducer.workspaces[workspaceId]\r\n\t\tstore.dispatch(removeWorkspace(workspaceId))\r\n\t\tvoid promise\r\n\t\t\t.then(() => {\r\n\t\t\t\t// After deleting a workspace, we need to fetch the initial data again because workspace indexes will have\r\n\t\t\t\t// changed.\r\n\t\t\t\tvoid this.client.main.fetchInitialData(true).then()\r\n\t\t\t})\r\n\t\t\t.catch((reason) => {\r\n\t\t\t\tif (originalWorkspace) {\r\n\t\t\t\t\tstore.dispatch(addWorkspace(originalWorkspace))\r\n\t\t\t\t}\r\n\t\t\t\tthrow reason\r\n\t\t\t})\r\n\t\treturn promise\r\n\t}\r\n}\r\n","import { HttpMethod } from \"../../enums\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { OrganizationAccess, Created } from \"../../typings\"\r\nimport {\r\n\tsetActiveOrganizationAccessId,\r\n\tsetOrganizationAccesses,\r\n\tremoveOrganizationAccess,\r\n\tremoveUser,\r\n\tupdateOrganizationAccess,\r\n} from \"../../store\"\r\n\r\n/**\r\n * Handles the creation of OrganizationAccess Service\r\n */\r\nexport class OrganizationAccessService extends BaseApiService {\r\n\tasync update(organizationAccess: OrganizationAccess): Promise<OrganizationAccess> {\r\n\t\tconst promise = this.enqueueRequest<Created<OrganizationAccess>>({\r\n\t\t\tdescription: \"Edit organization access\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/organizations/${organizationAccess.organization}/access/${organizationAccess.offline_id}/`,\r\n\t\t\tpayload: organizationAccess,\r\n\t\t\tblockers: [organizationAccess.offline_id],\r\n\t\t\tblocks: [organizationAccess.offline_id],\r\n\t\t})\r\n\r\n\t\tvoid promise.then(() => {\r\n\t\t\tthis.client.store.dispatch(updateOrganizationAccess(organizationAccess))\r\n\t\t})\r\n\r\n\t\treturn promise\r\n\t}\r\n\r\n\tasync remove(organizationAccess: OrganizationAccess): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(removeOrganizationAccess(organizationAccess))\r\n\t\tthis.client.store.dispatch(removeUser(organizationAccess.user))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Remove organization access\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/organizations/${organizationAccess.organization}/access/${organizationAccess.offline_id}/`,\r\n\t\t\tblockers: [organizationAccess.offline_id],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<void> {\r\n\t\tconst { store } = this.client\r\n\t\tconst state = store.getState()\r\n\t\tconst organizationId = state.organizationReducer.activeOrganizationId\r\n\t\tif (!organizationId) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tconst result = await this.enqueueRequest<OrganizationAccess[]>({\r\n\t\t\tdescription: \"Get organization accesses\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/organizations/${organizationId}/access/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t\tconst currentUser = state.userReducer.currentUser\r\n\t\tconst organizationAccesses = result\r\n\t\tconst activeOrganizationAccess = organizationAccesses.find(\r\n\t\t\t(organizationAccess) => organizationAccess.user === currentUser.id,\r\n\t\t)\r\n\t\tif (!activeOrganizationAccess) {\r\n\t\t\tthrow new Error(\"Current user does not have an organization access instance\")\r\n\t\t}\r\n\t\tstore.dispatch(setOrganizationAccesses(organizationAccesses))\r\n\t\tstore.dispatch(setActiveOrganizationAccessId(activeOrganizationAccess.offline_id))\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\n\r\n// TODO: add more methods, add error handling, add quota management etc, make it work for any Attachment\r\n// Goal is to not use more than 80% of quota, as full utilization would stop the Redux offline store from\r\n// functioning properly as well\r\nimport { DBSchema, IDBPDatabase, openDB } from \"idb\"\r\nimport { HttpMethod } from \"enums\"\r\nimport { fileToBlob, getFileS3Key, getRenamedFile, hashFile } from \"utils\"\r\nimport { selectUploadUrl, setUploadUrl } from \"store/slices/fileSlice\"\r\nimport { RootState } from \"../../typings\"\r\nimport { APIError } from \"../errors.ts\"\r\nimport { SDKRequest } from \"../typings.ts\"\r\n\r\nexport interface GetS3UrlSuccessResponse {\r\n\turl: string\r\n\tfields: Record<string, string>\r\n}\r\n\r\ninterface GetS3UrlWarningResponse {\r\n\twarning: string\r\n}\r\n\r\nexport type GetS3UrlResponse = GetS3UrlSuccessResponse | GetS3UrlWarningResponse\r\n\r\ninterface DatabaseFileProperties {\r\n\tfile_name: string\r\n\tfile_sha1: string\r\n\t/** When uploading, this is the s3 key of the file.\r\n\t * When downloading, this is the s3 public url.\r\n\t */\r\n\tfile: string\r\n}\r\n\r\ninterface FileCacheDB extends DBSchema {\r\n\tfiles: {\r\n\t\tvalue: File\r\n\t\tkey: string\r\n\t}\r\n}\r\n\r\nconst cachedRequestPromises: Record<string, Promise<File> | undefined> = {}\r\n// Used to minimize writing to the cache.\r\nconst _cachedKeys = new Set<string>()\r\n\r\n// <ANALYTICS>\r\nlet _filePutCacheHits = 0\r\nlet _filePutCacheMisses = 0\r\nlet _totalCount = 0\r\nconst summarizeEvery = 20\r\n// </ANALYTICS>\r\n\r\nexport class FileService extends BaseApiService {\r\n\t// NOTE: If you alter the schema (of the IndexedDB database) in any way, you must increment the version in order to\r\n\t// migrate the store. This allows idb to automatically migrate the user's existing data to the new schema.\r\n\tprivate _dbPromise = openDB<FileCacheDB>(\"fileCache\", 1, {\r\n\t\tupgrade(db) {\r\n\t\t\tdb.createObjectStore(\"files\")\r\n\t\t},\r\n\t})\r\n\r\n\tprivate async renewUploadUrl(sha1: string): Promise<GetS3UrlResponse> {\r\n\t\tconst file = await this.fetchCache(sha1)\r\n\t\tif (!file) throw new Error(`File with sha1 ${sha1} not found in cache`)\r\n\t\tconst key = await getFileS3Key(file, sha1)\r\n\r\n\t\tconst s3UploadUrl = await this.enqueueRequest<GetS3UrlResponse>({\r\n\t\t\tdescription: \"Get S3 URL\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: \"/authentication/files/presigned-upload-url/\",\r\n\t\t\tqueryParams: { key, type: file.type },\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [`s3-${key}`],\r\n\t\t})\r\n\r\n\t\tif (\"url\" in s3UploadUrl) {\r\n\t\t\t// TODO: Why save it to the store?\r\n\t\t\tthis.client.store.dispatch(setUploadUrl({ sha1, ...s3UploadUrl }))\r\n\t\t}\r\n\t\treturn s3UploadUrl\r\n\t}\r\n\r\n\t/**\r\n\t * Adds a file to the cache using the sha1 hash as the key and returns the sha1 hash.\r\n\t * @param file The file to add to the cache\r\n\t * TODO: This should be removed once the bug described in [1] is fixed.\r\n\t * @param sha1 The sha1 hash of the file to cache.\r\n\t */\r\n\tasync addCache(file: File, sha1: string): Promise<void> {\r\n\t\tif (_cachedKeys.has(sha1)) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\t// TODO: Check\r\n\t\tif (!file.type) {\r\n\t\t\tconst parts = file.name.split(\".\")\r\n\t\t\tconst extension = parts[parts.length - 1]\r\n\t\t\tfile = new File([file], file.name, { type: extension })\r\n\t\t}\r\n\t\tif (!file.name || !file.size || !file.type) {\r\n\t\t\tthrow new Error(\"Cannot add files to cache that do not have a name, size and type.\")\r\n\t\t}\r\n\t\tconst fileStorage: IDBPDatabase<FileCacheDB> = await this._dbPromise\r\n\t\t// TODO: Is this an improvement or not?\r\n\t\tconst alreadyCached = !!(await fileStorage.get(\"files\", sha1))\r\n\t\tif (!alreadyCached) {\r\n\t\t\tawait fileStorage.put(\"files\", file, sha1)\r\n\t\t\t_filePutCacheMisses++\r\n\t\t} else {\r\n\t\t\tconsole.error(\"File already cached (this is unexpected at this point):\", file.name, sha1)\r\n\t\t\t_filePutCacheHits++\r\n\t\t}\r\n\t\t_cachedKeys.add(sha1)\r\n\t\t_totalCount++\r\n\t\tif (_totalCount % summarizeEvery === 0) {\r\n\t\t\t// TODO: If this ends up hitting the console more often than not, they `alreadyCached` check might be more\r\n\t\t\t// performant than overwriting the identical file in the database. Because all file names saved are based\r\n\t\t\t// on the sha1 hash, we can guarantee that the files are identical, so there is no point in overwriting.\r\n\t\t\tconsole.debug(\r\n\t\t\t\t\"File cache summary: \" +\r\n\t\t\t\t\t`${_filePutCacheHits} hits and ${_filePutCacheMisses} misses, ` +\r\n\t\t\t\t\t`${(_filePutCacheHits / (_filePutCacheHits + _filePutCacheMisses)) * 100}% hit rate over ` +\r\n\t\t\t\t\t`${_totalCount} calls to addCache.`,\r\n\t\t\t)\r\n\t\t}\r\n\t}\r\n\r\n\tasync removeCache(sha1: string): Promise<void> {\r\n\t\tawait (await this._dbPromise).delete(\"files\", sha1)\r\n\t\t_cachedKeys.delete(sha1)\r\n\t}\r\n\r\n\tasync fetchCache(sha1: string): Promise<File | undefined> {\r\n\t\treturn (await this._dbPromise).get(\"files\", sha1)\r\n\t}\r\n\r\n\tasync getOrRenewUploadUrl(sha1: string): Promise<GetS3UrlResponse> {\r\n\t\tconst state: RootState = this.client.store.getState()\r\n\t\tconst uploadUrl = selectUploadUrl(sha1)(state)\r\n\r\n\t\treturn uploadUrl ?? (await this.renewUploadUrl(sha1))\r\n\t}\r\n\r\n\t/** Ensure the file has been added to the file cache before calling `uploadFileToS3()` */\r\n\tasync uploadFileToS3(sha1: string): Promise<[DatabaseFileProperties, Promise<undefined>]> {\r\n\t\tconst file = await this.fetchCache(sha1)\r\n\r\n\t\tif (!file) throw new Error(`File with sha1 ${sha1} not found in cache`)\r\n\r\n\t\tconst key = await getFileS3Key(file, sha1)\r\n\t\tconst dbFileProperties: DatabaseFileProperties = {\r\n\t\t\tfile_name: file.name,\r\n\t\t\tfile_sha1: sha1,\r\n\t\t\tfile: key,\r\n\t\t}\r\n\t\tconst fileUploadUrlResponse: GetS3UrlResponse = await this.getOrRenewUploadUrl(sha1)\r\n\r\n\t\tif (\"warning\" in fileUploadUrlResponse) {\r\n\t\t\tif (fileUploadUrlResponse.warning === \"already_uploaded\") {\r\n\t\t\t\treturn [dbFileProperties, Promise.resolve(undefined).then()]\r\n\t\t\t}\r\n\t\t\tthrow new Error(fileUploadUrlResponse.warning)\r\n\t\t}\r\n\r\n\t\tconst url = fileUploadUrlResponse.url\r\n\t\tconst promise = this.enqueueRequest<undefined>({\r\n\t\t\turl,\r\n\t\t\tdescription: \"Upload file\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\tisExternalUrl: true,\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tattachmentHash: sha1,\r\n\t\t\tblockers: [`s3-${key}`],\r\n\t\t\tblocks: [sha1],\r\n\t\t\ts3url: fileUploadUrlResponse,\r\n\t\t} satisfies SDKRequest)\r\n\r\n\t\treturn [dbFileProperties, promise]\r\n\t}\r\n\r\n\t/**\r\n\t * Fetches a file based on its URL and SHA1. SHA1 values should be known ahead of time because the SHA1 and URL of\r\n\t * any file is stored in a FileModelMixin (see backend). If the expected SHA1 doesn't match the actual SHA1 of the\r\n\t * file, an error will be thrown.\r\n\t * @param url The URL from which to get the file.\r\n\t * @param expectedSha1 The expected SHA1 of the file. If this doesn't match the actual SHA1 of the file, an error\r\n\t * will be thrown.\r\n\t * @param downloadedName (Optional) The name to give the file after download. Set to the name of an attachment, for\r\n\t * example.\r\n\t */\r\n\tasync fetchFileFromUrl(url: string, expectedSha1: string, downloadedName?: string | undefined): Promise<File> {\r\n\t\tconst requestCacheKey: string = url.split(\"?\")[0] ?? url\r\n\r\n\t\tconst cachedResult = await this.fetchCache(expectedSha1)\r\n\r\n\t\tif (cachedResult) {\r\n\t\t\tif (!cachedResult.name) {\r\n\t\t\t\tthrow new Error(\"Cached file unexpectedly has no name.\")\r\n\t\t\t}\r\n\t\t\treturn cachedResult\r\n\t\t}\r\n\r\n\t\tif (url.startsWith(\"blob:\")) {\r\n\t\t\tconst blob = await fileToBlob(url)\r\n\t\t\tconst file = new File([blob], downloadedName ?? expectedSha1, { type: blob.type })\r\n\t\t\tawait this.addCache(file, expectedSha1)\r\n\t\t\treturn file\r\n\t\t}\r\n\r\n\t\tlet promise = cachedRequestPromises[requestCacheKey]\r\n\t\tlet isFirstRequest = true\r\n\r\n\t\tif (!promise) {\r\n\t\t\tpromise = this.enqueueRequest<File>({\r\n\t\t\t\tdescription: \"Download file\",\r\n\t\t\t\tmethod: HttpMethod.GET,\r\n\t\t\t\turl,\r\n\t\t\t\t// If in development, we should assume the files are saved at localhost by the Django development server.\r\n\t\t\t\t// Setting this to true will lead to localhost:8000 being prepended to the URL.\r\n\t\t\t\tisExternalUrl: import.meta.env.PROD || url.startsWith(\"https://\"),\r\n\t\t\t\tisResponseBlob: true,\r\n\t\t\t\tisAuthNeeded: false,\r\n\t\t\t\tblockers: [expectedSha1],\r\n\t\t\t\tblocks: [expectedSha1],\r\n\t\t\t})\r\n\t\t\tcachedRequestPromises[requestCacheKey] = promise\r\n\t\t} else {\r\n\t\t\tisFirstRequest = false\r\n\t\t}\r\n\r\n\t\tlet file: File\r\n\r\n\t\ttry {\r\n\t\t\tfile = await promise\r\n\t\t} catch (e) {\r\n\t\t\tif (isFirstRequest && e instanceof APIError) {\r\n\t\t\t\t// Don't cache failed promises\r\n\t\t\t\tdelete cachedRequestPromises[requestCacheKey]\r\n\t\t\t}\r\n\t\t\tthrow e\r\n\t\t}\r\n\r\n\t\tif (isFirstRequest) {\r\n\t\t\t// The first request for this image (in case there are concurrent ones) has the responsibility to cache the\r\n\t\t\t// file itself.\r\n\t\t\tconst actualSha1 = await hashFile(file)\r\n\t\t\tif (actualSha1 !== expectedSha1) {\r\n\t\t\t\tconst message = `The hash of the file returned from the server (${actualSha1}) does not match the \r\n\t\t\t\t\texpected hash (${expectedSha1}). This can happen if you're using a local development server and the \r\n\t\t\t\t\tisExternalUrl flag in the request details is set to true, because instead of requesting the local\r\n\t\t\t\t\tREST API, you will be requesting localhost:80 (where this app runs), resulting in a transformed blob\r\n\t\t\t\t\t(with an offline_id attached) being returned. Alternatively, you may be running with \r\n\t\t\t\t\timport.meta.env.PROD, which will result in some file requests being treated as\r\n\t\t\t\t\texternal URLs and therefore not prepended with VITE_API_URL.`\r\n\r\n\t\t\t\tthrow new Error(message)\r\n\t\t\t}\r\n\t\t\t// All files need a name. Otherwise, they might end up with duplicated keys in the PrimeReact FileUpload\r\n\t\t\t// component (it uses the name, size and type as the key).\r\n\t\t\tconst extension = file.type.split(\"/\")[1]\r\n\t\t\tif (!extension) {\r\n\t\t\t\tthrow new Error(\"File has no extension\")\r\n\t\t\t}\r\n\t\t\tconst fileName = downloadedName ?? actualSha1 + \".\" + extension\r\n\r\n\t\t\tfile = getRenamedFile(file, fileName)\r\n\r\n\t\t\tif (!file.name) {\r\n\t\t\t\tthrow new Error(\"Failed to set file's name\")\r\n\t\t\t}\r\n\r\n\t\t\tawait this.addCache(file, actualSha1)\r\n\r\n\t\t\t// Overwrite the cached promise, so it returns the renamed file\r\n\t\t\tcachedRequestPromises[requestCacheKey] = new Promise((resolve) => {\r\n\t\t\t\tresolve(file)\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\treturn file\r\n\t}\r\n}\r\n","import { BaseApiService } from \"./BaseApiService\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { SDKRequest } from \"../../sdk\"\r\nimport { EmailVerificationPayload, EmailVerificationReturn, VerificationCode } from \"../../typings\"\r\n\r\nexport class EmailVerificationService extends BaseApiService {\r\n\tasync getVerificationCode(verificationCode: string): Promise<VerificationCode> {\r\n\t\tconst requestDetails: SDKRequest = {\r\n\t\t\tdescription: \"Get verification code\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/verification/email-verification/${verificationCode}/`,\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t}\r\n\t\treturn this.enqueueRequest<VerificationCode>(requestDetails)\r\n\t}\r\n\r\n\tvalidateVerificationCode(\r\n\t\tverificationCode: string,\r\n\t\tpayload: EmailVerificationPayload | undefined = undefined,\r\n\t): Promise<EmailVerificationReturn> {\r\n\t\tconst requestDetails: SDKRequest = {\r\n\t\t\tdescription: \"Validate verification code\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/verification/email-verification/${verificationCode}/`,\r\n\t\t\tisAuthNeeded: false,\r\n\t\t\tpayload,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t}\r\n\t\treturn this.enqueueRequest<EmailVerificationReturn>(requestDetails)\r\n\t}\r\n}\r\n","import { HttpMethod } from \"../../enums\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { setEmailDomains, removeEmailDomain, addEmailDomain } from \"../../store\"\r\nimport { EmailDomain } from \"../../typings\"\r\n\r\nexport class EmailDomainsService extends BaseApiService {\r\n\tasync fetchAll(orgId: number): Promise<EmailDomain[]> {\r\n\t\treturn this.enqueueRequest<EmailDomain[]>({\r\n\t\t\tdescription: \"Fetch email domains for organization\",\r\n\t\t\tmethod: HttpMethod.GET,\r\n\t\t\turl: `/organizations/${orgId}/email-domains/`,\r\n\t\t\tblockers: [orgId.toString()],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync add(orgId: number, email: string): Promise<undefined> {\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Add email domain to organization\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/organizations/${orgId}/email-domains/`,\r\n\t\t\tpayload: { email },\r\n\t\t\tblockers: [orgId.toString(), \"create-org\"],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n\r\n\tasync remove(emailDomain: EmailDomain): Promise<undefined> {\r\n\t\tthis.client.store.dispatch(removeEmailDomain(emailDomain))\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Remove email domain from organization\",\r\n\t\t\tmethod: HttpMethod.DELETE,\r\n\t\t\turl: `/organizations/${emailDomain.organization}/email-domains/${emailDomain.offline_id}/`,\r\n\t\t\tblockers: [emailDomain.domain],\r\n\t\t\tblocks: [],\r\n\t\t}).catch((e) => {\r\n\t\t\tthis.client.store.dispatch(addEmailDomain(emailDomain))\r\n\t\t\tthrow e\r\n\t\t})\r\n\t}\r\n\r\n\tasync refreshStore(): Promise<undefined> {\r\n\t\tconst organizationId = this.client.store.getState().organizationReducer.activeOrganizationId\r\n\t\tif (!organizationId) {\r\n\t\t\tthrow new Error(\"No active organization\")\r\n\t\t}\r\n\t\tconst promise = this.fetchAll(organizationId)\r\n\t\tconst result = await promise\r\n\t\tthis.client.store.dispatch(setEmailDomains(result))\r\n\t}\r\n}\r\n","import { Organization } from \"../../typings\"\r\nimport { HttpMethod } from \"../../enums\"\r\nimport { BaseApiService } from \"./BaseApiService\"\r\nimport { updateActiveOrganization } from \"../../store\"\r\n\r\nexport class OrganizationService extends BaseApiService {\r\n\tasync create(name: string): Promise<Organization> {\r\n\t\tconst result = await this.enqueueRequest<Organization>({\r\n\t\t\tdescription: \"Create organization\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: \"/organizations/\",\r\n\t\t\tpayload: { name },\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [`add-org-${name}`, \"create-org\"],\r\n\t\t})\r\n\t\tawait this.client.main.fetchInitialData(true)\r\n\t\treturn result\r\n\t}\r\n\tasync update(organization: Organization): Promise<Organization> {\r\n\t\tconst promise = this.enqueueRequest<Organization>({\r\n\t\t\tdescription: \"Edit organization\",\r\n\t\t\tmethod: HttpMethod.PATCH,\r\n\t\t\turl: `/organizations/${organization.id}/`,\r\n\t\t\tpayload: organization,\r\n\t\t\tblockers: [`add-org-${organization.name}`, organization.id.toString()],\r\n\t\t\tblocks: [organization.id.toString()],\r\n\t\t})\r\n\r\n\t\treturn promise.then((result) => {\r\n\t\t\tthis.client.store.dispatch(updateActiveOrganization(organization))\r\n\t\t\treturn result\r\n\t\t})\r\n\t}\r\n\r\n\tasync invite(organizationId: number, email: string): Promise<undefined> {\r\n\t\treturn this.enqueueRequest<undefined>({\r\n\t\t\tdescription: \"Invite user to organization\",\r\n\t\t\tmethod: HttpMethod.POST,\r\n\t\t\turl: `/organizations/${organizationId}/invite/${email}/`,\r\n\t\t\tblockers: [],\r\n\t\t\tblocks: [],\r\n\t\t})\r\n\t}\r\n}\r\n","// The shape of an object that describes the details of an API request\r\nimport {\r\n\tAttachmentService,\r\n\tAuthService,\r\n\tCategoryService,\r\n\tComponentService,\r\n\tComponentStageCompletionService,\r\n\tComponentStageService,\r\n\tComponentTypeService,\r\n\tEmailVerificationService,\r\n\tFileService,\r\n\tIssueCommentService,\r\n\tIssueService,\r\n\tMainService,\r\n\tOrganizationAccessService,\r\n\tProjectAccessService,\r\n\tProjectFileService,\r\n\tProjectService,\r\n\tUserFormService,\r\n\tUserFormSubmissionService,\r\n\tWorkspaceService,\r\n\tOrganizationService,\r\n\tEmailDomainsService,\r\n} from \"./services\"\r\nimport { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore.js\"\r\nimport { RootState } from \"../typings\"\r\n\r\n// This is a bundle of the services that our app uses. These can be used in tandem with the types\r\n// declared above in order to execute requests to the backend (queued or otherwise). To use it,\r\n// you can declare a \"PlaceholderName-Service.ts\" and have CRUD methods to send to the backend,\r\n// and call it by using `sdk.PlaceHolderName.CRUD_METHOD`\r\nexport class OvermapSDK {\r\n\treadonly API_URL: string\r\n\treadonly store: ToolkitStore<RootState>\r\n\r\n\tconstructor(apiUrl: string, store: ToolkitStore<RootState>) {\r\n\t\tthis.API_URL = apiUrl\r\n\t\tthis.store = store\r\n\t}\r\n\r\n\tfiles = new FileService(this)\r\n\tattachments = new AttachmentService(this)\r\n\tauth = new AuthService(this)\r\n\tcategories = new CategoryService(this)\r\n\tprojectAccesses = new ProjectAccessService(this)\r\n\torganizations = new OrganizationService(this)\r\n\torganizationAccess = new OrganizationAccessService(this)\r\n\tissues = new IssueService(this)\r\n\tissueComments = new IssueCommentService(this)\r\n\tworkspaces = new WorkspaceService(this)\r\n\tmain = new MainService(this)\r\n\tcomponents = new ComponentService(this)\r\n\tcomponentTypes = new ComponentTypeService(this)\r\n\tcomponentStages = new ComponentStageService(this)\r\n\tcomponentStageCompletions = new ComponentStageCompletionService(this)\r\n\tuserForms = new UserFormService(this)\r\n\tuserFormSubmissions = new UserFormSubmissionService(this)\r\n\tprojects = new ProjectService(this)\r\n\tprojectFiles = new ProjectFileService(this)\r\n\temailVerification = new EmailVerificationService(this)\r\n\temailDomains = new EmailDomainsService(this)\r\n}\r\n\r\n// Instance of the API that the whole app uses\r\nexport const makeClient = (apiUrl: string, store: ToolkitStore<RootState>) => new OvermapSDK(apiUrl, store)\r\n","import React, { useEffect, useMemo } from \"react\"\r\nimport { makeClient, OvermapSDK } from \"../../sdk\"\r\nimport { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore\"\r\nimport { RootState } from \"../../typings\"\r\n\r\nexport interface ISDKContext {\r\n\tsdk: OvermapSDK\r\n}\r\n\r\n/** The client store is the store passed to the SDKProvider\r\n * and is used where the SDKProvider is not available.\r\n */\r\nexport let clientStore: ToolkitStore<RootState> | undefined\r\n\r\ninterface SDKProviderProps {\r\n\tchildren: React.ReactNode\r\n\tAPI_URL: string\r\n\tstore: ToolkitStore<RootState>\r\n}\r\n\r\nconst SDKContext = React.createContext<ISDKContext>({} as ISDKContext)\r\n\r\nconst SDKProvider = ({ children, API_URL, store }: SDKProviderProps) => {\r\n\tconst client = useMemo(() => makeClient(API_URL, store), [API_URL, store])\r\n\r\n\tuseEffect(() => {\r\n\t\tclientStore = store\r\n\t}, [store])\r\n\r\n\t// TODO: Implement dependency graphs in the outbox\r\n\treturn <SDKContext.Provider value={{ sdk: client }}>{children}</SDKContext.Provider>\r\n}\r\n\r\nexport { SDKProvider, SDKContext }\r\n","import React from \"react\"\r\nimport { SDKContext } from \"./sdk\"\r\n\r\n/**\r\n * useSDK\r\n */\r\n\r\nexport const useSDK = () => {\r\n\treturn React.useContext(SDKContext)\r\n}\r\n","// Combines all the contexts into one context for the convenience of the user of the overmap-ui library.\r\n\r\nimport React from \"react\"\r\nimport { AlertDialogProvider, DefaultTheme, ToastProvider } from \"@overmap-ai/blocks\"\r\nimport { SDKProvider } from \"./sdk\"\r\n\r\nimport { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore\"\r\nimport { RootState } from \"../typings\"\r\n\r\ninterface OvermapProviderProps {\r\n\tchildren: React.ReactNode\r\n\tproduction?: boolean\r\n\tdisableDefaultTheme?: boolean\r\n\tstore: ToolkitStore<RootState>\r\n}\r\n\r\nconst OvermapContext = React.createContext(null)\r\n\r\nconst PRODUCTION_URL = \"https://api.wordn.io\"\r\nconst STAGING_URL = \"https://test-api.hemora.ca\"\r\n\r\nconst OvermapProvider = (props: OvermapProviderProps) => {\r\n\tconst { children, production, disableDefaultTheme = false, store } = props\r\n\r\n\tlet ret = (\r\n\t\t<AlertDialogProvider>\r\n\t\t\t<ToastProvider>\r\n\t\t\t\t<SDKProvider API_URL={production ? PRODUCTION_URL : STAGING_URL} store={store}>\r\n\t\t\t\t\t{children}\r\n\t\t\t\t</SDKProvider>\r\n\t\t\t</ToastProvider>\r\n\t\t</AlertDialogProvider>\r\n\t)\r\n\r\n\tif (!disableDefaultTheme) {\r\n\t\tret = <DefaultTheme>{ret}</DefaultTheme>\r\n\t}\r\n\treturn <OvermapContext.Provider value={null}>{ret}</OvermapContext.Provider>\r\n}\r\n\r\nexport { OvermapProvider, OvermapContext }\r\n"],"names":["DepGraph","request","uuid","o","toPrimitive","toPropertyKey","r","defineProperty","randomString","process","_objectSpread","HttpMethod","IssuePriority","IssueStatus","MapStyle","VERSION_REDUCER_KEY","_a","migration","initialState","createSlice","useState","useEffect","file","uuidv4","self","useRef","createSelector","today","ProjectAccessLevel","OrganizationAccessLevel","ProjectType","VerificationCodeType","shallowEqual","combineReducers","createNextState","clientStore","offline","configureStore","error","unsafeShowToast","useDispatch","useSelector","performRequest","promise","RESET_STATE","requestDetails","openDB","exports","useMemo","jsx","AlertDialogProvider","ToastProvider","DefaultTheme"],"mappings":"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","x_google_ignoreList":[3,4,5,6,7,8,23]}
|