/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/basic-features/typescript for more information.
+// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
+++ /dev/null
-{
- "name": "neoboard-exporter",
- "version": "0.1.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "neoboard-exporter",
- "version": "0.1.0",
- "license": "MIT",
- "dependencies": {
- "@mirohq/miro-api": "^2.0.0",
- "cookie": "^0.5.0",
- "dotenv": "^16.0.3",
- "mirotone": "5",
- "next": "14.0.1",
- "react": "^18.2.0",
- "react-dom": "^18.2.0"
- },
- "devDependencies": {
- "@mirohq/websdk-types": "latest",
- "@types/cookie": "^0.5.1",
- "@types/node": "^18.8.2",
- "@types/react": "^18.0.24",
- "typescript": "4.9.5"
- }
- },
- "node_modules/@mirohq/design-tokens": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@mirohq/design-tokens/-/design-tokens-5.1.1.tgz",
- "integrity": "sha512-PcCA7HlumSSaRkAIlrB4+CKhFyF+w93q1SnbIL6zPM69hzN9kJD7zNUk2ngGJpDcQseRyoE+uJkN8f+WRvp0Lg=="
- },
- "node_modules/@mirohq/miro-api": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/@mirohq/miro-api/-/miro-api-2.2.2.tgz",
- "integrity": "sha512-KoBjjMv8rXXSQtvAamT1YQ94vZ+Lofw/Gp4hvHYHzlHtc4A3UHkUl6vgBh2O+eHf5j/sUCJ+xe7JbQsyHoZVng==",
- "license": "MIT",
- "dependencies": {
- "form-data": "^4.0.0",
- "node-fetch": "^2.7.0"
- }
- },
- "node_modules/@mirohq/websdk-types": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/@mirohq/websdk-types/-/websdk-types-2.16.1.tgz",
- "integrity": "sha512-dv3RX+aP7QvmXXpishm72BeWR/iDxwXdnLufLO5glgOTKIBGiRHuju2WL7tSOOmuttw2LjVc03zSBDYK692o0Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "typescript": ">=4.6.3 || ~5"
- },
- "peerDependencies": {
- "@mirohq/prettier-config": "*",
- "@typescript-eslint/eslint-plugin": "*",
- "@typescript-eslint/parser": "*",
- "eslint": "*",
- "eslint-config-airbnb-typescript": "*",
- "eslint-plugin-import": "*",
- "husky": "*",
- "lint-staged": "*",
- "prettier": "*"
- },
- "peerDependenciesMeta": {
- "@mirohq/prettier-config": {
- "optional": true
- },
- "@typescript-eslint/eslint-plugin": {
- "optional": true
- },
- "@typescript-eslint/parser": {
- "optional": true
- },
- "eslint": {
- "optional": true
- },
- "eslint-config-airbnb-typescript": {
- "optional": true
- },
- "eslint-plugin-import": {
- "optional": true
- },
- "husky": {
- "optional": true
- },
- "lint-staged": {
- "optional": true
- },
- "prettier": {
- "optional": true
- }
- }
- },
- "node_modules/@next/env": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-14.0.1.tgz",
- "integrity": "sha512-Ms8ZswqY65/YfcjrlcIwMPD7Rg/dVjdLapMcSHG26W6O67EJDF435ShW4H4LXi1xKO1oRc97tLXUpx8jpLe86A==",
- "license": "MIT"
- },
- "node_modules/@next/swc-darwin-arm64": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.1.tgz",
- "integrity": "sha512-JyxnGCS4qT67hdOKQ0CkgFTp+PXub5W1wsGvIq98TNbF3YEIN7iDekYhYsZzc8Ov0pWEsghQt+tANdidITCLaw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-darwin-x64": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.1.tgz",
- "integrity": "sha512-625Z7bb5AyIzswF9hvfZWa+HTwFZw+Jn3lOBNZB87lUS0iuCYDHqk3ujuHCkiyPtSC0xFBtYDLcrZ11mF/ap3w==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-arm64-gnu": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.1.tgz",
- "integrity": "sha512-iVpn3KG3DprFXzVHM09kvb//4CNNXBQ9NB/pTm8LO+vnnnaObnzFdS5KM+w1okwa32xH0g8EvZIhoB3fI3mS1g==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-arm64-musl": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.1.tgz",
- "integrity": "sha512-mVsGyMxTLWZXyD5sen6kGOTYVOO67lZjLApIj/JsTEEohDDt1im2nkspzfV5MvhfS7diDw6Rp/xvAQaWZTv1Ww==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-x64-gnu": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.1.tgz",
- "integrity": "sha512-wMqf90uDWN001NqCM/auRl3+qVVeKfjJdT9XW+RMIOf+rhUzadmYJu++tp2y+hUbb6GTRhT+VjQzcgg/QTD9NQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-x64-musl": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.1.tgz",
- "integrity": "sha512-ol1X1e24w4j4QwdeNjfX0f+Nza25n+ymY0T2frTyalVczUmzkVD7QGgPTZMHfR1aLrO69hBs0G3QBYaj22J5GQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-win32-arm64-msvc": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.1.tgz",
- "integrity": "sha512-WEmTEeWs6yRUEnUlahTgvZteh5RJc4sEjCQIodJlZZ5/VJwVP8p2L7l6VhzQhT4h7KvLx/Ed4UViBdne6zpIsw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-win32-ia32-msvc": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.1.tgz",
- "integrity": "sha512-oFpHphN4ygAgZUKjzga7SoH2VGbEJXZa/KL8bHCAwCjDWle6R1SpiGOdUdA8EJ9YsG1TYWpzY6FTbUA+iAJeww==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-win32-x64-msvc": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.1.tgz",
- "integrity": "sha512-FFp3nOJ/5qSpeWT0BZQ+YE1pSMk4IMpkME/1DwKBwhg4mJLB9L+6EXuJi4JEwaJdl5iN+UUlmUD3IsR1kx5fAg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@swc/helpers": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz",
- "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==",
- "license": "Apache-2.0",
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@types/cookie": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.4.tgz",
- "integrity": "sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "18.19.70",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.70.tgz",
- "integrity": "sha512-RE+K0+KZoEpDUbGGctnGdkrLFwi1eYKTlIHNl2Um98mUkGsm1u2Ff6Ltd0e8DktTtC98uy7rSj+hO8t/QuLoVQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~5.26.4"
- }
- },
- "node_modules/@types/prop-types": {
- "version": "15.7.14",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
- "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/react": {
- "version": "18.3.18",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz",
- "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/prop-types": "*",
- "csstype": "^3.0.2"
- }
- },
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "license": "MIT"
- },
- "node_modules/busboy": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
- "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
- "dependencies": {
- "streamsearch": "^1.1.0"
- },
- "engines": {
- "node": ">=10.16.0"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001692",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz",
- "integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
- "node_modules/client-only": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
- "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
- "license": "MIT"
- },
- "node_modules/clone": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
- "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
- "license": "MIT",
- "engines": {
- "node": ">=0.8"
- }
- },
- "node_modules/clone-buffer": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
- "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/clone-stats": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
- "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==",
- "license": "MIT"
- },
- "node_modules/cloneable-readable": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
- "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.1",
- "process-nextick-args": "^2.0.0",
- "readable-stream": "^2.3.5"
- }
- },
- "node_modules/cloneable-readable/node_modules/isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
- "license": "MIT"
- },
- "node_modules/cloneable-readable/node_modules/readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "license": "MIT",
- "dependencies": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "node_modules/cloneable-readable/node_modules/string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.1.0"
- }
- },
- "node_modules/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "license": "MIT",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/core-util-is": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
- "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
- "license": "MIT"
- },
- "node_modules/csstype": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
- "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/dotenv": {
- "version": "16.4.7",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
- "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://dotenvx.com"
- }
- },
- "node_modules/form-data": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
- "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/glob-to-regexp": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
- "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
- "license": "BSD-2-Clause"
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "license": "ISC"
- },
- "node_modules/gulp-file": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/gulp-file/-/gulp-file-0.4.0.tgz",
- "integrity": "sha512-3NPCJpAPpbNoV2aml8T96OK3Aof4pm4PMOIa1jSQbMNSNUUXdZ5QjVgLXLStjv0gg9URcETc7kvYnzXdYXUWug==",
- "license": "BSD",
- "dependencies": {
- "through2": "^0.4.1",
- "vinyl": "^2.1.0"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
- "license": "MIT"
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "license": "MIT"
- },
- "node_modules/loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "license": "MIT",
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mirotone": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/mirotone/-/mirotone-5.3.0.tgz",
- "integrity": "sha512-PsAMyy48OwGleHWtOCGscjcqt2U5tFbFvTKdUeamv9+bGvt7lQHHkpccQLCqdKfMJeAIySRAJggMDmm7fls+kQ==",
- "license": "MIT",
- "dependencies": {
- "@mirohq/design-tokens": "5.1.1",
- "gulp-file": "^0.4.0"
- }
- },
- "node_modules/nanoid": {
- "version": "3.3.8",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
- "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/next": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/next/-/next-14.0.1.tgz",
- "integrity": "sha512-s4YaLpE4b0gmb3ggtmpmV+wt+lPRuGtANzojMQ2+gmBpgX9w5fTbjsy6dXByBuENsdCX5pukZH/GxdFgO62+pA==",
- "license": "MIT",
- "dependencies": {
- "@next/env": "14.0.1",
- "@swc/helpers": "0.5.2",
- "busboy": "1.6.0",
- "caniuse-lite": "^1.0.30001406",
- "postcss": "8.4.31",
- "styled-jsx": "5.1.1",
- "watchpack": "2.4.0"
- },
- "bin": {
- "next": "dist/bin/next"
- },
- "engines": {
- "node": ">=18.17.0"
- },
- "optionalDependencies": {
- "@next/swc-darwin-arm64": "14.0.1",
- "@next/swc-darwin-x64": "14.0.1",
- "@next/swc-linux-arm64-gnu": "14.0.1",
- "@next/swc-linux-arm64-musl": "14.0.1",
- "@next/swc-linux-x64-gnu": "14.0.1",
- "@next/swc-linux-x64-musl": "14.0.1",
- "@next/swc-win32-arm64-msvc": "14.0.1",
- "@next/swc-win32-ia32-msvc": "14.0.1",
- "@next/swc-win32-x64-msvc": "14.0.1"
- },
- "peerDependencies": {
- "@opentelemetry/api": "^1.1.0",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
- "sass": "^1.3.0"
- },
- "peerDependenciesMeta": {
- "@opentelemetry/api": {
- "optional": true
- },
- "sass": {
- "optional": true
- }
- }
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/object-keys": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
- "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==",
- "license": "MIT"
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/postcss": {
- "version": "8.4.31",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
- "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.6",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/process-nextick-args": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
- "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
- "license": "MIT"
- },
- "node_modules/react": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
- "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-dom": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
- "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "scheduler": "^0.23.2"
- },
- "peerDependencies": {
- "react": "^18.3.1"
- }
- },
- "node_modules/readable-stream": {
- "version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
- "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
- "license": "MIT",
- "dependencies": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
- }
- },
- "node_modules/remove-trailing-separator": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
- "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
- "license": "ISC"
- },
- "node_modules/replace-ext": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
- "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "license": "MIT"
- },
- "node_modules/scheduler": {
- "version": "0.23.2",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
- "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/streamsearch": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
- "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
- "license": "MIT"
- },
- "node_modules/styled-jsx": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
- "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
- "license": "MIT",
- "dependencies": {
- "client-only": "0.0.1"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "peerDependencies": {
- "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
- },
- "peerDependenciesMeta": {
- "@babel/core": {
- "optional": true
- },
- "babel-plugin-macros": {
- "optional": true
- }
- }
- },
- "node_modules/through2": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz",
- "integrity": "sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==",
- "license": "MIT",
- "dependencies": {
- "readable-stream": "~1.0.17",
- "xtend": "~2.1.1"
- }
- },
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "license": "MIT"
- },
- "node_modules/tslib": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "license": "0BSD"
- },
- "node_modules/typescript": {
- "version": "4.9.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
- "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- },
- "node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "license": "MIT"
- },
- "node_modules/vinyl": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz",
- "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==",
- "license": "MIT",
- "dependencies": {
- "clone": "^2.1.1",
- "clone-buffer": "^1.0.0",
- "clone-stats": "^1.0.0",
- "cloneable-readable": "^1.0.0",
- "remove-trailing-separator": "^1.0.1",
- "replace-ext": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/watchpack": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
- "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
- "license": "MIT",
- "dependencies": {
- "glob-to-regexp": "^0.4.1",
- "graceful-fs": "^4.1.2"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "license": "BSD-2-Clause"
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "license": "MIT",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/xtend": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
- "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==",
- "dependencies": {
- "object-keys": "~0.4.0"
- },
- "engines": {
- "node": ">=0.4"
- }
- }
- }
-}
"lint": "next lint"
},
"dependencies": {
- "next": "14.0.1",
- "@mirohq/miro-api": "^2.0.0",
- "mirotone": "5",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
- "dotenv": "^16.0.3",
- "cookie": "^0.5.0"
+ "@mirohq/miro-api": "^2.2.2",
+ "cookie": "^0.5.0",
+ "dotenv": "^16.4.7",
+ "mirotone": "^5.3.0",
+ "next": "15.1.4",
+ "react": "19.0.0",
+ "react-dom": "19.0.0",
+ "sass": "^1.83.1",
+ "string-strip-html": "^13.4.8",
+ "zod": "^3.24.1"
},
"devDependencies": {
"@mirohq/websdk-types": "latest",
- "typescript": "4.9.5",
- "@types/node": "^18.8.2",
- "@types/react": "^18.0.24",
- "@types/cookie": "^0.5.1"
+ "@types/cookie": "^0.5.4",
+ "@types/node": "^18.19.70",
+ "@types/react": "19.0.4",
+ "@types/react-dom": "19.0.2",
+ "typescript": "4.9.5"
}
-}
+}
\ No newline at end of file
--- /dev/null
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+overrides:
+ '@types/react': 19.0.4
+ '@types/react-dom': 19.0.2
+
+importers:
+
+ .:
+ dependencies:
+ '@mirohq/miro-api':
+ specifier: ^2.2.2
+ version: 2.2.2
+ cookie:
+ specifier: ^0.5.0
+ version: 0.5.0
+ dotenv:
+ specifier: ^16.4.7
+ version: 16.4.7
+ mirotone:
+ specifier: ^5.3.0
+ version: 5.3.0
+ next:
+ specifier: 15.1.4
+ version: 15.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.1)
+ react:
+ specifier: 19.0.0
+ version: 19.0.0
+ react-dom:
+ specifier: 19.0.0
+ version: 19.0.0(react@19.0.0)
+ sass:
+ specifier: ^1.83.1
+ version: 1.83.1
+ string-strip-html:
+ specifier: ^13.4.8
+ version: 13.4.8
+ zod:
+ specifier: ^3.24.1
+ version: 3.24.1
+ devDependencies:
+ '@mirohq/websdk-types':
+ specifier: latest
+ version: 2.16.1
+ '@types/cookie':
+ specifier: ^0.5.4
+ version: 0.5.4
+ '@types/node':
+ specifier: ^18.19.70
+ version: 18.19.70
+ '@types/react':
+ specifier: 19.0.4
+ version: 19.0.4
+ '@types/react-dom':
+ specifier: 19.0.2
+ version: 19.0.2(@types/react@19.0.4)
+ typescript:
+ specifier: 4.9.5
+ version: 4.9.5
+
+packages:
+
+ '@emnapi/runtime@1.3.1':
+ resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==}
+
+ '@img/sharp-darwin-arm64@0.33.5':
+ resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.33.5':
+ resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.0.4':
+ resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.0.4':
+ resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.0.4':
+ resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-arm@1.0.5':
+ resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-s390x@1.0.4':
+ resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-x64@1.0.4':
+ resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
+ resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.0.4':
+ resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linux-arm64@0.33.5':
+ resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linux-arm@0.33.5':
+ resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-linux-s390x@0.33.5':
+ resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-linux-x64@0.33.5':
+ resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-arm64@0.33.5':
+ resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-x64@0.33.5':
+ resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-wasm32@0.33.5':
+ resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-ia32@0.33.5':
+ resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.33.5':
+ resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@mirohq/design-tokens@5.1.1':
+ resolution: {integrity: sha512-PcCA7HlumSSaRkAIlrB4+CKhFyF+w93q1SnbIL6zPM69hzN9kJD7zNUk2ngGJpDcQseRyoE+uJkN8f+WRvp0Lg==}
+
+ '@mirohq/miro-api@2.2.2':
+ resolution: {integrity: sha512-KoBjjMv8rXXSQtvAamT1YQ94vZ+Lofw/Gp4hvHYHzlHtc4A3UHkUl6vgBh2O+eHf5j/sUCJ+xe7JbQsyHoZVng==}
+
+ '@mirohq/websdk-types@2.16.1':
+ resolution: {integrity: sha512-dv3RX+aP7QvmXXpishm72BeWR/iDxwXdnLufLO5glgOTKIBGiRHuju2WL7tSOOmuttw2LjVc03zSBDYK692o0Q==}
+ peerDependencies:
+ '@mirohq/prettier-config': '*'
+ '@typescript-eslint/eslint-plugin': '*'
+ '@typescript-eslint/parser': '*'
+ eslint: '*'
+ eslint-config-airbnb-typescript: '*'
+ eslint-plugin-import: '*'
+ husky: '*'
+ lint-staged: '*'
+ prettier: '*'
+ peerDependenciesMeta:
+ '@mirohq/prettier-config':
+ optional: true
+ '@typescript-eslint/eslint-plugin':
+ optional: true
+ '@typescript-eslint/parser':
+ optional: true
+ eslint:
+ optional: true
+ eslint-config-airbnb-typescript:
+ optional: true
+ eslint-plugin-import:
+ optional: true
+ husky:
+ optional: true
+ lint-staged:
+ optional: true
+ prettier:
+ optional: true
+
+ '@next/env@15.1.4':
+ resolution: {integrity: sha512-2fZ5YZjedi5AGaeoaC0B20zGntEHRhi2SdWcu61i48BllODcAmmtj8n7YarSPt4DaTsJaBFdxQAVEVzgmx2Zpw==}
+
+ '@next/swc-darwin-arm64@15.1.4':
+ resolution: {integrity: sha512-wBEMBs+np+R5ozN1F8Y8d/Dycns2COhRnkxRc+rvnbXke5uZBHkUGFgWxfTXn5rx7OLijuUhyfB+gC/ap58dDw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@next/swc-darwin-x64@15.1.4':
+ resolution: {integrity: sha512-7sgf5rM7Z81V9w48F02Zz6DgEJulavC0jadab4ZsJ+K2sxMNK0/BtF8J8J3CxnsJN3DGcIdC260wEKssKTukUw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@next/swc-linux-arm64-gnu@15.1.4':
+ resolution: {integrity: sha512-JaZlIMNaJenfd55kjaLWMfok+vWBlcRxqnRoZrhFQrhM1uAehP3R0+Aoe+bZOogqlZvAz53nY/k3ZyuKDtT2zQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@next/swc-linux-arm64-musl@15.1.4':
+ resolution: {integrity: sha512-7EBBjNoyTO2ipMDgCiORpwwOf5tIueFntKjcN3NK+GAQD7OzFJe84p7a2eQUeWdpzZvhVXuAtIen8QcH71ZCOQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@next/swc-linux-x64-gnu@15.1.4':
+ resolution: {integrity: sha512-9TGEgOycqZFuADyFqwmK/9g6S0FYZ3tphR4ebcmCwhL8Y12FW8pIBKJvSwV+UBjMkokstGNH+9F8F031JZKpHw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@next/swc-linux-x64-musl@15.1.4':
+ resolution: {integrity: sha512-0578bLRVDJOh+LdIoKvgNDz77+Bd85c5JrFgnlbI1SM3WmEQvsjxTA8ATu9Z9FCiIS/AliVAW2DV/BDwpXbtiQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@next/swc-win32-arm64-msvc@15.1.4':
+ resolution: {integrity: sha512-JgFCiV4libQavwII+kncMCl30st0JVxpPOtzWcAI2jtum4HjYaclobKhj+JsRu5tFqMtA5CJIa0MvYyuu9xjjQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@next/swc-win32-x64-msvc@15.1.4':
+ resolution: {integrity: sha512-xxsJy9wzq7FR5SqPCUqdgSXiNXrMuidgckBa8nH9HtjjxsilgcN6VgXF6tZ3uEWuVEadotQJI8/9EQ6guTC4Yw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@parcel/watcher-android-arm64@2.5.0':
+ resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ '@parcel/watcher-darwin-arm64@2.5.0':
+ resolution: {integrity: sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@parcel/watcher-darwin-x64@2.5.0':
+ resolution: {integrity: sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@parcel/watcher-freebsd-x64@2.5.0':
+ resolution: {integrity: sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@parcel/watcher-linux-arm-glibc@2.5.0':
+ resolution: {integrity: sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ '@parcel/watcher-linux-arm-musl@2.5.0':
+ resolution: {integrity: sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ '@parcel/watcher-linux-arm64-glibc@2.5.0':
+ resolution: {integrity: sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@parcel/watcher-linux-arm64-musl@2.5.0':
+ resolution: {integrity: sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@parcel/watcher-linux-x64-glibc@2.5.0':
+ resolution: {integrity: sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ '@parcel/watcher-linux-x64-musl@2.5.0':
+ resolution: {integrity: sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ '@parcel/watcher-win32-arm64@2.5.0':
+ resolution: {integrity: sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@parcel/watcher-win32-ia32@2.5.0':
+ resolution: {integrity: sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@parcel/watcher-win32-x64@2.5.0':
+ resolution: {integrity: sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ '@parcel/watcher@2.5.0':
+ resolution: {integrity: sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==}
+ engines: {node: '>= 10.0.0'}
+
+ '@swc/counter@0.1.3':
+ resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
+
+ '@swc/helpers@0.5.15':
+ resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
+
+ '@types/cookie@0.5.4':
+ resolution: {integrity: sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA==}
+
+ '@types/lodash-es@4.17.12':
+ resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==}
+
+ '@types/lodash@4.17.14':
+ resolution: {integrity: sha512-jsxagdikDiDBeIRaPYtArcT8my4tN1og7MtMRquFT3XNA6axxyHDRUemqDz/taRDdOUn0GnGHRCuff4q48sW9A==}
+
+ '@types/node@18.19.70':
+ resolution: {integrity: sha512-RE+K0+KZoEpDUbGGctnGdkrLFwi1eYKTlIHNl2Um98mUkGsm1u2Ff6Ltd0e8DktTtC98uy7rSj+hO8t/QuLoVQ==}
+
+ '@types/react-dom@19.0.2':
+ resolution: {integrity: sha512-c1s+7TKFaDRRxr1TxccIX2u7sfCnc3RxkVyBIUA2lCpyqCF+QoAwQ/CBg7bsMdVwP120HEH143VQezKtef5nCg==}
+ peerDependencies:
+ '@types/react': 19.0.4
+
+ '@types/react@19.0.4':
+ resolution: {integrity: sha512-3O4QisJDYr1uTUMZHA2YswiQZRq+Pd8D+GdVFYikTutYsTz+QZgWkAPnP7rx9txoI6EXKcPiluMqWPFV3tT9Wg==}
+
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ busboy@1.6.0:
+ resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
+ engines: {node: '>=10.16.0'}
+
+ caniuse-lite@1.0.30001692:
+ resolution: {integrity: sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==}
+
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
+ client-only@0.0.1:
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+
+ clone-buffer@1.0.0:
+ resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==}
+ engines: {node: '>= 0.10'}
+
+ clone-stats@1.0.0:
+ resolution: {integrity: sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==}
+
+ clone@2.1.2:
+ resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
+ engines: {node: '>=0.8'}
+
+ cloneable-readable@1.1.3:
+ resolution: {integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==}
+
+ codsen-utils@1.6.4:
+ resolution: {integrity: sha512-PDyvQ5f2PValmqZZIJATimcokDt4JjIev8cKbZgEOoZm+U1IJDYuLeTcxZPQdep99R/X0RIlQ6ReQgPOVnPbNw==}
+ engines: {node: '>=14.18.0'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ color-string@1.9.1:
+ resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
+
+ color@4.2.3:
+ resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
+ engines: {node: '>=12.5.0'}
+
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
+ cookie@0.5.0:
+ resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
+ engines: {node: '>= 0.6'}
+
+ core-util-is@1.0.3:
+ resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
+ detect-libc@1.0.3:
+ resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==}
+ engines: {node: '>=0.10'}
+ hasBin: true
+
+ detect-libc@2.0.3:
+ resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
+ engines: {node: '>=8'}
+
+ dotenv@16.4.7:
+ resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
+ engines: {node: '>=12'}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ form-data@4.0.1:
+ resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
+ engines: {node: '>= 6'}
+
+ gulp-file@0.4.0:
+ resolution: {integrity: sha512-3NPCJpAPpbNoV2aml8T96OK3Aof4pm4PMOIa1jSQbMNSNUUXdZ5QjVgLXLStjv0gg9URcETc7kvYnzXdYXUWug==}
+
+ html-entities@2.5.2:
+ resolution: {integrity: sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==}
+
+ immutable@5.0.3:
+ resolution: {integrity: sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==}
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ is-arrayish@0.3.2:
+ resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ isarray@0.0.1:
+ resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==}
+
+ isarray@1.0.0:
+ resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
+
+ lodash-es@4.17.21:
+ resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ mirotone@5.3.0:
+ resolution: {integrity: sha512-PsAMyy48OwGleHWtOCGscjcqt2U5tFbFvTKdUeamv9+bGvt7lQHHkpccQLCqdKfMJeAIySRAJggMDmm7fls+kQ==}
+
+ nanoid@3.3.8:
+ resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ next@15.1.4:
+ resolution: {integrity: sha512-mTaq9dwaSuwwOrcu3ebjDYObekkxRnXpuVL21zotM8qE2W0HBOdVIdg2Li9QjMEZrj73LN96LcWcz62V19FjAg==}
+ engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ '@playwright/test': ^1.41.2
+ babel-plugin-react-compiler: '*'
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ '@playwright/test':
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+
+ node-addon-api@7.1.1:
+ resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
+
+ node-fetch@2.7.0:
+ resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
+ engines: {node: 4.x || >=6.0.0}
+ peerDependencies:
+ encoding: ^0.1.0
+ peerDependenciesMeta:
+ encoding:
+ optional: true
+
+ object-keys@0.4.0:
+ resolution: {integrity: sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ process-nextick-args@2.0.1:
+ resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
+
+ ranges-apply@7.0.16:
+ resolution: {integrity: sha512-4rGJHOyA7qatiMDg3vcETkc/TVBPU86/xZRTXff6o7a2neYLmj0EXUUAlhLVuiWAzTPHDPHOQxtk8EDrIF4ohg==}
+ engines: {node: '>=14.18.0'}
+
+ ranges-merge@9.0.15:
+ resolution: {integrity: sha512-hvt4hx0FKIaVfjd1oKx0poL57ljxdL2KHC6bXBrAdsx2iCsH+x7nO/5J0k2veM/isnOcFZKp0ZKkiCjCtzy74Q==}
+ engines: {node: '>=14.18.0'}
+
+ ranges-push@7.0.15:
+ resolution: {integrity: sha512-gXpBYQ5Umf3uG6jkJnw5ddok2Xfo5p22rAJBLrqzNKa7qkj3q5AOCoxfRPXEHUVaJutfXc9K9eGXdIzdyQKPkw==}
+ engines: {node: '>=14.18.0'}
+
+ ranges-sort@6.0.11:
+ resolution: {integrity: sha512-fhNEG0vGi7bESitNNqNBAfYPdl2efB+1paFlI8BQDCNkruERKuuhG8LkQClDIVqUJLkrmKuOSPQ3xZHqVnVo3Q==}
+ engines: {node: '>=14.18.0'}
+
+ react-dom@19.0.0:
+ resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
+ peerDependencies:
+ react: ^19.0.0
+
+ react@19.0.0:
+ resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
+ engines: {node: '>=0.10.0'}
+
+ readable-stream@1.0.34:
+ resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==}
+
+ readable-stream@2.3.8:
+ resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
+
+ readdirp@4.0.2:
+ resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==}
+ engines: {node: '>= 14.16.0'}
+
+ remove-trailing-separator@1.1.0:
+ resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==}
+
+ replace-ext@1.0.1:
+ resolution: {integrity: sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==}
+ engines: {node: '>= 0.10'}
+
+ rfdc@1.4.1:
+ resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
+
+ safe-buffer@5.1.2:
+ resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+
+ sass@1.83.1:
+ resolution: {integrity: sha512-EVJbDaEs4Rr3F0glJzFSOvtg2/oy2V/YrGFPqPY24UqcLDWcI9ZY5sN+qyO3c/QCZwzgfirvhXvINiJCE/OLcA==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ scheduler@0.25.0:
+ resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
+
+ semver@7.6.3:
+ resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ sharp@0.33.5:
+ resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
+ simple-swizzle@0.2.2:
+ resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ streamsearch@1.1.0:
+ resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
+ engines: {node: '>=10.0.0'}
+
+ string-collapse-leading-whitespace@7.0.7:
+ resolution: {integrity: sha512-jF9eynJoE6ezTCdYI8Qb02/ij/DlU9ItG93Dty4SWfJeLFrotOr+wH9IRiWHTqO3mjCyqBWEiU3uSTIbxYbAEQ==}
+ engines: {node: '>=14.18.0'}
+
+ string-left-right@6.0.17:
+ resolution: {integrity: sha512-nuyIV4D4ivnwT64E0TudmCRg52NfkumuEUilyoOrHb/Z2wEOF5I+9SI6P+veFKqWKZfGpAs6OqKe4nAjujARyw==}
+ engines: {node: '>=14.18.0'}
+
+ string-strip-html@13.4.8:
+ resolution: {integrity: sha512-vlcRAtx5DN6zXGUx3EYGFg0/JOQWM65mqLgDaBHviQPP+ovUFzqZ30iQ+674JHWr9wNgnzFGxx9TGipPZMnZXg==}
+ engines: {node: '>=14.18.0'}
+
+ string-trim-spaces-only@5.0.10:
+ resolution: {integrity: sha512-MhmjE5jNqb1Ylo+BARPRlsdChGLrnPpAUWrT1VOxo9WhWwKVUU6CbZTfjwKaQPYTGS/wsX/4Zek88FM2rEb5iA==}
+ engines: {node: '>=14.18.0'}
+
+ string_decoder@0.10.31:
+ resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==}
+
+ string_decoder@1.1.1:
+ resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
+
+ styled-jsx@5.1.6:
+ resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+
+ through2@0.4.2:
+ resolution: {integrity: sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==}
+
+ tiny-invariant@1.3.3:
+ resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ tr46@0.0.3:
+ resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ typescript@4.9.5:
+ resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
+ engines: {node: '>=4.2.0'}
+ hasBin: true
+
+ undici-types@5.26.5:
+ resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ vinyl@2.2.1:
+ resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==}
+ engines: {node: '>= 0.10'}
+
+ webidl-conversions@3.0.1:
+ resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
+
+ whatwg-url@5.0.0:
+ resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
+
+ xtend@2.1.2:
+ resolution: {integrity: sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==}
+ engines: {node: '>=0.4'}
+
+ zod@3.24.1:
+ resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==}
+
+snapshots:
+
+ '@emnapi/runtime@1.3.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@img/sharp-darwin-arm64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.0.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.0.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.0.5':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.0.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.0.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.0.5
+ optional: true
+
+ '@img/sharp-linux-s390x@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.0.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.0.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.0.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.0.4
+ optional: true
+
+ '@img/sharp-wasm32@0.33.5':
+ dependencies:
+ '@emnapi/runtime': 1.3.1
+ optional: true
+
+ '@img/sharp-win32-ia32@0.33.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.33.5':
+ optional: true
+
+ '@mirohq/design-tokens@5.1.1': {}
+
+ '@mirohq/miro-api@2.2.2':
+ dependencies:
+ form-data: 4.0.1
+ node-fetch: 2.7.0
+ transitivePeerDependencies:
+ - encoding
+
+ '@mirohq/websdk-types@2.16.1':
+ dependencies:
+ typescript: 4.9.5
+
+ '@next/env@15.1.4': {}
+
+ '@next/swc-darwin-arm64@15.1.4':
+ optional: true
+
+ '@next/swc-darwin-x64@15.1.4':
+ optional: true
+
+ '@next/swc-linux-arm64-gnu@15.1.4':
+ optional: true
+
+ '@next/swc-linux-arm64-musl@15.1.4':
+ optional: true
+
+ '@next/swc-linux-x64-gnu@15.1.4':
+ optional: true
+
+ '@next/swc-linux-x64-musl@15.1.4':
+ optional: true
+
+ '@next/swc-win32-arm64-msvc@15.1.4':
+ optional: true
+
+ '@next/swc-win32-x64-msvc@15.1.4':
+ optional: true
+
+ '@parcel/watcher-android-arm64@2.5.0':
+ optional: true
+
+ '@parcel/watcher-darwin-arm64@2.5.0':
+ optional: true
+
+ '@parcel/watcher-darwin-x64@2.5.0':
+ optional: true
+
+ '@parcel/watcher-freebsd-x64@2.5.0':
+ optional: true
+
+ '@parcel/watcher-linux-arm-glibc@2.5.0':
+ optional: true
+
+ '@parcel/watcher-linux-arm-musl@2.5.0':
+ optional: true
+
+ '@parcel/watcher-linux-arm64-glibc@2.5.0':
+ optional: true
+
+ '@parcel/watcher-linux-arm64-musl@2.5.0':
+ optional: true
+
+ '@parcel/watcher-linux-x64-glibc@2.5.0':
+ optional: true
+
+ '@parcel/watcher-linux-x64-musl@2.5.0':
+ optional: true
+
+ '@parcel/watcher-win32-arm64@2.5.0':
+ optional: true
+
+ '@parcel/watcher-win32-ia32@2.5.0':
+ optional: true
+
+ '@parcel/watcher-win32-x64@2.5.0':
+ optional: true
+
+ '@parcel/watcher@2.5.0':
+ dependencies:
+ detect-libc: 1.0.3
+ is-glob: 4.0.3
+ micromatch: 4.0.8
+ node-addon-api: 7.1.1
+ optionalDependencies:
+ '@parcel/watcher-android-arm64': 2.5.0
+ '@parcel/watcher-darwin-arm64': 2.5.0
+ '@parcel/watcher-darwin-x64': 2.5.0
+ '@parcel/watcher-freebsd-x64': 2.5.0
+ '@parcel/watcher-linux-arm-glibc': 2.5.0
+ '@parcel/watcher-linux-arm-musl': 2.5.0
+ '@parcel/watcher-linux-arm64-glibc': 2.5.0
+ '@parcel/watcher-linux-arm64-musl': 2.5.0
+ '@parcel/watcher-linux-x64-glibc': 2.5.0
+ '@parcel/watcher-linux-x64-musl': 2.5.0
+ '@parcel/watcher-win32-arm64': 2.5.0
+ '@parcel/watcher-win32-ia32': 2.5.0
+ '@parcel/watcher-win32-x64': 2.5.0
+ optional: true
+
+ '@swc/counter@0.1.3': {}
+
+ '@swc/helpers@0.5.15':
+ dependencies:
+ tslib: 2.8.1
+
+ '@types/cookie@0.5.4': {}
+
+ '@types/lodash-es@4.17.12':
+ dependencies:
+ '@types/lodash': 4.17.14
+
+ '@types/lodash@4.17.14': {}
+
+ '@types/node@18.19.70':
+ dependencies:
+ undici-types: 5.26.5
+
+ '@types/react-dom@19.0.2(@types/react@19.0.4)':
+ dependencies:
+ '@types/react': 19.0.4
+
+ '@types/react@19.0.4':
+ dependencies:
+ csstype: 3.1.3
+
+ asynckit@0.4.0: {}
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+ optional: true
+
+ busboy@1.6.0:
+ dependencies:
+ streamsearch: 1.1.0
+
+ caniuse-lite@1.0.30001692: {}
+
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.0.2
+
+ client-only@0.0.1: {}
+
+ clone-buffer@1.0.0: {}
+
+ clone-stats@1.0.0: {}
+
+ clone@2.1.2: {}
+
+ cloneable-readable@1.1.3:
+ dependencies:
+ inherits: 2.0.4
+ process-nextick-args: 2.0.1
+ readable-stream: 2.3.8
+
+ codsen-utils@1.6.4:
+ dependencies:
+ rfdc: 1.4.1
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+ optional: true
+
+ color-name@1.1.4:
+ optional: true
+
+ color-string@1.9.1:
+ dependencies:
+ color-name: 1.1.4
+ simple-swizzle: 0.2.2
+ optional: true
+
+ color@4.2.3:
+ dependencies:
+ color-convert: 2.0.1
+ color-string: 1.9.1
+ optional: true
+
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
+ cookie@0.5.0: {}
+
+ core-util-is@1.0.3: {}
+
+ csstype@3.1.3: {}
+
+ delayed-stream@1.0.0: {}
+
+ detect-libc@1.0.3:
+ optional: true
+
+ detect-libc@2.0.3:
+ optional: true
+
+ dotenv@16.4.7: {}
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+ optional: true
+
+ form-data@4.0.1:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ mime-types: 2.1.35
+
+ gulp-file@0.4.0:
+ dependencies:
+ through2: 0.4.2
+ vinyl: 2.2.1
+
+ html-entities@2.5.2: {}
+
+ immutable@5.0.3: {}
+
+ inherits@2.0.4: {}
+
+ is-arrayish@0.3.2:
+ optional: true
+
+ is-extglob@2.1.1:
+ optional: true
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+ optional: true
+
+ is-number@7.0.0:
+ optional: true
+
+ isarray@0.0.1: {}
+
+ isarray@1.0.0: {}
+
+ lodash-es@4.17.21: {}
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+ optional: true
+
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ mirotone@5.3.0:
+ dependencies:
+ '@mirohq/design-tokens': 5.1.1
+ gulp-file: 0.4.0
+
+ nanoid@3.3.8: {}
+
+ next@15.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.1):
+ dependencies:
+ '@next/env': 15.1.4
+ '@swc/counter': 0.1.3
+ '@swc/helpers': 0.5.15
+ busboy: 1.6.0
+ caniuse-lite: 1.0.30001692
+ postcss: 8.4.31
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ styled-jsx: 5.1.6(react@19.0.0)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 15.1.4
+ '@next/swc-darwin-x64': 15.1.4
+ '@next/swc-linux-arm64-gnu': 15.1.4
+ '@next/swc-linux-arm64-musl': 15.1.4
+ '@next/swc-linux-x64-gnu': 15.1.4
+ '@next/swc-linux-x64-musl': 15.1.4
+ '@next/swc-win32-arm64-msvc': 15.1.4
+ '@next/swc-win32-x64-msvc': 15.1.4
+ sass: 1.83.1
+ sharp: 0.33.5
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+
+ node-addon-api@7.1.1:
+ optional: true
+
+ node-fetch@2.7.0:
+ dependencies:
+ whatwg-url: 5.0.0
+
+ object-keys@0.4.0: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.1:
+ optional: true
+
+ postcss@8.4.31:
+ dependencies:
+ nanoid: 3.3.8
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ process-nextick-args@2.0.1: {}
+
+ ranges-apply@7.0.16:
+ dependencies:
+ ranges-merge: 9.0.15
+ tiny-invariant: 1.3.3
+
+ ranges-merge@9.0.15:
+ dependencies:
+ ranges-push: 7.0.15
+ ranges-sort: 6.0.11
+
+ ranges-push@7.0.15:
+ dependencies:
+ codsen-utils: 1.6.4
+ ranges-sort: 6.0.11
+ string-collapse-leading-whitespace: 7.0.7
+ string-trim-spaces-only: 5.0.10
+
+ ranges-sort@6.0.11: {}
+
+ react-dom@19.0.0(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+ scheduler: 0.25.0
+
+ react@19.0.0: {}
+
+ readable-stream@1.0.34:
+ dependencies:
+ core-util-is: 1.0.3
+ inherits: 2.0.4
+ isarray: 0.0.1
+ string_decoder: 0.10.31
+
+ readable-stream@2.3.8:
+ dependencies:
+ core-util-is: 1.0.3
+ inherits: 2.0.4
+ isarray: 1.0.0
+ process-nextick-args: 2.0.1
+ safe-buffer: 5.1.2
+ string_decoder: 1.1.1
+ util-deprecate: 1.0.2
+
+ readdirp@4.0.2: {}
+
+ remove-trailing-separator@1.1.0: {}
+
+ replace-ext@1.0.1: {}
+
+ rfdc@1.4.1: {}
+
+ safe-buffer@5.1.2: {}
+
+ sass@1.83.1:
+ dependencies:
+ chokidar: 4.0.3
+ immutable: 5.0.3
+ source-map-js: 1.2.1
+ optionalDependencies:
+ '@parcel/watcher': 2.5.0
+
+ scheduler@0.25.0: {}
+
+ semver@7.6.3:
+ optional: true
+
+ sharp@0.33.5:
+ dependencies:
+ color: 4.2.3
+ detect-libc: 2.0.3
+ semver: 7.6.3
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.33.5
+ '@img/sharp-darwin-x64': 0.33.5
+ '@img/sharp-libvips-darwin-arm64': 1.0.4
+ '@img/sharp-libvips-darwin-x64': 1.0.4
+ '@img/sharp-libvips-linux-arm': 1.0.5
+ '@img/sharp-libvips-linux-arm64': 1.0.4
+ '@img/sharp-libvips-linux-s390x': 1.0.4
+ '@img/sharp-libvips-linux-x64': 1.0.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.0.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.0.4
+ '@img/sharp-linux-arm': 0.33.5
+ '@img/sharp-linux-arm64': 0.33.5
+ '@img/sharp-linux-s390x': 0.33.5
+ '@img/sharp-linux-x64': 0.33.5
+ '@img/sharp-linuxmusl-arm64': 0.33.5
+ '@img/sharp-linuxmusl-x64': 0.33.5
+ '@img/sharp-wasm32': 0.33.5
+ '@img/sharp-win32-ia32': 0.33.5
+ '@img/sharp-win32-x64': 0.33.5
+ optional: true
+
+ simple-swizzle@0.2.2:
+ dependencies:
+ is-arrayish: 0.3.2
+ optional: true
+
+ source-map-js@1.2.1: {}
+
+ streamsearch@1.1.0: {}
+
+ string-collapse-leading-whitespace@7.0.7: {}
+
+ string-left-right@6.0.17:
+ dependencies:
+ codsen-utils: 1.6.4
+ rfdc: 1.4.1
+
+ string-strip-html@13.4.8:
+ dependencies:
+ '@types/lodash-es': 4.17.12
+ codsen-utils: 1.6.4
+ html-entities: 2.5.2
+ lodash-es: 4.17.21
+ ranges-apply: 7.0.16
+ ranges-push: 7.0.15
+ string-left-right: 6.0.17
+
+ string-trim-spaces-only@5.0.10: {}
+
+ string_decoder@0.10.31: {}
+
+ string_decoder@1.1.1:
+ dependencies:
+ safe-buffer: 5.1.2
+
+ styled-jsx@5.1.6(react@19.0.0):
+ dependencies:
+ client-only: 0.0.1
+ react: 19.0.0
+
+ through2@0.4.2:
+ dependencies:
+ readable-stream: 1.0.34
+ xtend: 2.1.2
+
+ tiny-invariant@1.3.3: {}
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+ optional: true
+
+ tr46@0.0.3: {}
+
+ tslib@2.8.1: {}
+
+ typescript@4.9.5: {}
+
+ undici-types@5.26.5: {}
+
+ util-deprecate@1.0.2: {}
+
+ vinyl@2.2.1:
+ dependencies:
+ clone: 2.1.2
+ clone-buffer: 1.0.0
+ clone-stats: 1.0.0
+ cloneable-readable: 1.1.3
+ remove-trailing-separator: 1.1.0
+ replace-ext: 1.0.1
+
+ webidl-conversions@3.0.1: {}
+
+ whatwg-url@5.0.0:
+ dependencies:
+ tr46: 0.0.3
+ webidl-conversions: 3.0.1
+
+ xtend@2.1.2:
+ dependencies:
+ object-keys: 0.4.0
+
+ zod@3.24.1: {}
--- /dev/null
+'use server';
+
+import { AppCardItem, CardItem, DocumentItem, EmbedItem, FrameItem, ImageItem, Item, ShapeItem, StickyNoteItem, TextItem } from '@mirohq/miro-api';
+import initMiroAPI from '../utils/initMiroAPI';
+import { Path, Shape, Slide, Whiteboard, Image, neoboardWhiteboardWidth, neoboardWhiteboardHeight } from './neoboardTypes';
+import { stripHtml } from 'string-strip-html';
+
+export type FormState = {
+ neoboards: {
+ id: string;
+ neoboard: Whiteboard;
+ }[];
+ message: string;
+}
+
+export async function importBoard(prevState: FormState, formData: FormData): Promise<FormState> {
+ const boardIdsRaw = formData.get('board');
+ if (!boardIdsRaw) {
+ return prevState;
+ }
+ const boardIds: string[] = Array.isArray(boardIdsRaw) ? boardIdsRaw : [boardIdsRaw] as string[];
+
+ // Get board from Miro API
+ const { miro, userId } = initMiroAPI();
+
+ const userIdAwaited = await userId();
+
+ // redirect to auth url if user has not authorized the app
+ if (!userIdAwaited || !(await miro.isAuthorized(userIdAwaited))) {
+ return {
+ neoboards: prevState.neoboards,
+ message: 'User has not authorized the app',
+ };
+ }
+ const api = miro.as(userIdAwaited);
+
+ const resultingBoards: {
+ id: string;
+ neoboard: Whiteboard;
+ }[] = [];
+ for (const boardId of boardIds) {
+ const neoboard: Whiteboard = {
+ version: 'net.nordeck.whiteboard@v1',
+ whiteboard: {
+ slides: [],
+ }
+ }
+
+ const board = await api.getBoard(boardId as string);
+
+ // Get board items and split them into frames and other items
+ const framesGenerator = await board.getAllItems({ type: 'frame' });
+ const frames: (FrameItem | Item)[] = [];
+
+ for await (const frame of framesGenerator) {
+ frames.push(frame as FrameItem);
+ }
+
+ const contentGenerator = await board.getAllItems()
+ const items: (Item | AppCardItem | CardItem | DocumentItem | EmbedItem | ImageItem | ShapeItem | StickyNoteItem | TextItem)[] = [];
+
+ for await (const item of contentGenerator) {
+ if (item.type !== 'frame') {
+ // @ts-ignore
+ items.push(item);
+ }
+ }
+
+ // Create slides from frames
+ for (const frame of frames) {
+ // Find items which are within the geometry of the frame. Keep in mind the position of the frame as well.
+ const slide: Slide = {
+ elements: [],
+ };
+
+ const frameId = frame.id;
+ for (const item of items) {
+ if (!item.parent) {
+ continue;
+ }
+ if (item.parent.id === frameId) {
+ switch (item.type) {
+ case 'shape':
+ const shape = convertShape(item as ShapeItem);
+ if (shape) {
+ slide.elements.push(shape);
+ }
+ break;
+ case 'path':
+ slide.elements.push(convertPath(item));
+ break;
+ case 'image':
+ const image = await convertImage(item as ImageItem);
+ if (image) {
+ slide.elements.push(image.imageElement);
+ if (!neoboard.whiteboard.files) {
+ neoboard.whiteboard.files = [];
+ }
+ neoboard.whiteboard.files.push(image.file);
+ }
+ break;
+ case 'text':
+ slide.elements.push(convertText(item as TextItem));
+ break;
+ case 'sticky_note':
+ slide.elements.push(convertStickyNote(item as StickyNoteItem));
+ break;
+ default:
+ console.log('unknown item type', item.type);
+ }
+ }
+ }
+
+ neoboard.whiteboard.slides.push(slide);
+ }
+
+ // Transform the board into neoboard coordinates
+ const transformedNeoboard = transformBoardIntoNeoboardCoordinates(neoboard);
+
+ resultingBoards.push({ id: boardId, neoboard: transformedNeoboard });
+ }
+
+ return {
+ neoboards: [...prevState.neoboards, ...resultingBoards],
+ message: ''
+ }
+}
+
+function transformBoardIntoNeoboardCoordinates(board: Whiteboard): Whiteboard {
+ // The coordinate system in Miro is different from the coordinate system in Neoboard.
+ // In Neoboard the frames are only neoboardWhiteboardWidth wide and whiteboardHeight tall.
+
+ // The first step is to find the bounding box of all the slides.
+ let minX = Number.MAX_SAFE_INTEGER;
+ let minY = Number.MAX_SAFE_INTEGER;
+ let maxX = Number.MIN_SAFE_INTEGER;
+ let maxY = Number.MIN_SAFE_INTEGER;
+
+ for (const slide of board.whiteboard.slides) {
+ for (const element of slide.elements) {
+ if (element.type === 'shape' || element.type === 'image') {
+ const x = element.position.x;
+ const y = element.position.y;
+ const width = element.width;
+ const height = element.height;
+
+ minX = Math.min(minX, x);
+ minY = Math.min(minY, y);
+ maxX = Math.max(maxX, x + width);
+ maxY = Math.max(maxY, y + height);
+ }
+ }
+ }
+
+ // The second step is to scale all the elements to fit within the bounding box.
+ const width = maxX - minX;
+ const height = maxY - minY;
+ const scale = Math.min(neoboardWhiteboardWidth / width, neoboardWhiteboardHeight / height);
+
+ const transformedBoard: Whiteboard = {
+ version: board.version,
+ whiteboard: {
+ slides: [],
+ }
+ };
+
+ for (const slide of board.whiteboard.slides) {
+ const transformedSlide: Slide = {
+ elements: [],
+ };
+
+ for (const element of slide.elements) {
+ if (element.type === 'shape' || element.type === 'image') {
+ const x = (element.position.x - minX) * scale;
+ const y = (element.position.y - minY) * scale;
+ const width = element.width * scale;
+ const height = element.height * scale;
+
+ transformedSlide.elements.push({
+ ...element,
+ position: {
+ x,
+ y,
+ },
+ width,
+ height,
+ });
+ } else {
+ transformedSlide.elements.push(element);
+ }
+ }
+
+ transformedBoard.whiteboard.slides.push(transformedSlide);
+ }
+
+ return transformedBoard;
+}
+
+function convertShape(item: ShapeItem): Shape | undefined {
+ let shapeType = item.data?.shape;
+ let borderRadius = 0;
+ if (shapeType !== 'rectangle' && shapeType !== 'circle' && shapeType !== 'ellipse' && shapeType !== 'triangle' && shapeType !== 'round_rectangle') {
+ console.log('unknown shape type', shapeType);
+ return undefined;
+ }
+ if (shapeType === 'round_rectangle') {
+ shapeType = 'rectangle';
+ borderRadius = 10;
+ }
+
+ const opacity = item.style?.fillOpacity ?? (item.style?.fillColor ? "1.0" : "0.0");
+ const borderColorOpacity = item.style?.borderOpacity ?? "1.0";
+
+ return {
+ type: 'shape',
+ kind: shapeType as "rectangle" | "circle" | "ellipse" | "triangle",
+ position: {
+ x: item.position?.x ?? 0,
+ y: item.position?.y ?? 0,
+ },
+ width: item.geometry?.width ?? 1,
+ height: item.geometry?.height ?? 1,
+ fillColor: opacity === "1.0" ? (item.style?.fillColor ?? "#ffffff") : "transparent",
+ strokeColor: borderColorOpacity === "1.0" ? (item.style?.borderColor ?? "#1a1a1a") : "transparent",
+ strokeWidth: parseFloat(item.style?.borderWidth ?? "2.0"),
+ borderRadius: borderRadius,
+ text: stripHtml(item.data?.content ?? "").result,
+ textAlignment: (item.style?.textAlign ?? "left") as "left" | "center" | "right",
+ textColor: item.style?.color,
+ // TODO: Revisit this when neoboard can do html or inline styles
+ textBold: false,
+ textItalic: false,
+ };
+}
+
+// TODO: Is this the right way to handle paths?
+function convertPath(item: Item): Path {
+ return {
+ type: 'path',
+ kind: 'line',
+ position: {
+ x: item.position?.x ?? 0,
+ y: item.position?.y ?? 0,
+ },
+ points: [],
+ strokeColor: "#000000",
+ endMarker: 'arrow-head-line',
+ };
+}
+
+async function convertImage(item: ImageItem): Promise<{
+ imageElement: Image; file: {
+ mxc: string;
+ data: string;
+ };
+} | undefined> {
+ const uuid = item.id;
+
+ if (!item.data?.imageUrl) {
+ return undefined;
+ }
+
+ // Download the image and convert it to base64
+ const file = await fetch(item.data?.imageUrl);
+ if (!file.ok) {
+ return undefined
+ };
+
+ const fileBuffer = await file.arrayBuffer();
+ const fileBase64 = Buffer.from(fileBuffer).toString('base64');
+
+ return {
+ imageElement: {
+ type: 'image',
+ mxc: `mxc://example.com/${uuid}`,
+ fileName: item.data?.title ?? uuid,
+ position: {
+ x: item.position?.x ?? 0,
+ y: item.position?.y ?? 0,
+ },
+ width: item.geometry?.width ?? 1,
+ height: item.geometry?.height ?? 1,
+ },
+ file: {
+ mxc: `mxc://example.com/${uuid}`,
+ data: fileBase64,
+ }
+ };
+}
+
+function convertText(item: TextItem): Shape {
+ return {
+ type: 'shape',
+ kind: 'rectangle',
+ position: {
+ x: item.position?.x ?? 0,
+ y: item.position?.y ?? 0,
+ },
+ width: item.geometry?.width ?? 1,
+ height: item.geometry?.height ?? 1,
+ fillColor: "transparent",
+ strokeColor: "transparent",
+ strokeWidth: 0,
+ borderRadius: 0,
+ text: stripHtml(item.data?.content ?? "").result,
+ textAlignment: (item.style?.textAlign ?? "left") as "left" | "center" | "right",
+ textColor: item.style?.color,
+ // TODO: Revisit this when neoboard can do html or inline styles
+ textBold: false,
+ textItalic: false,
+ };
+}
+
+// Make sticky notes a rounded rectangle
+function convertStickyNote(item: StickyNoteItem): Shape {
+ return {
+ type: 'shape',
+ kind: 'rectangle',
+ position: {
+ x: item.position?.x ?? 0,
+ y: item.position?.y ?? 0,
+ },
+ width: item.geometry?.width ?? 1,
+ height: item.geometry?.height ?? 1,
+ fillColor: item.style?.fillColor ?? "#ffffff",
+ strokeColor: 'transparent',
+ strokeWidth: 0,
+ borderRadius: 10,
+ text: stripHtml(item.data?.content ?? "").result,
+ textAlignment: (item.style?.textAlign ?? "left") as "left" | "center" | "right",
+ textColor: 'black',
+ }
+}
\ No newline at end of file
-import React, {PropsWithChildren} from 'react';
+import React, { PropsWithChildren } from 'react';
import Image from 'next/image';
-import Script from 'next/script';
import congratulations from '../assets/congratulations.png';
-import {SDKUsageDemo} from '../components/SDKUsageDemo';
-import {MiroSDKInit} from '../components/SDKInit';
-export default function RootLayout({children}: PropsWithChildren) {
+export default function RootLayout({ children }: PropsWithChildren) {
return (
<html>
<body>
- <Script
- src="https://miro.com/app/static/sdk/v2/miro.js"
- strategy="beforeInteractive"
- />
- <MiroSDKInit />
<div id="root">
<div className="grid">
<div className="cs1 ce12">
- <Image src={congratulations} alt="" />
- <h1>Congratulations!</h1>
- <p>You've just created your first Miro app!</p>
- </div>
- <div className="cs1 ce12">
- <SDKUsageDemo />
+ <Image src={congratulations} alt="" priority />
+ <h1>Welcome!</h1>
+ <p>Thank you for wanting to move your board to the Neoboard software!</p>
</div>
<hr className="cs1 ce12" />
<div className="cs1 ce12">{children}</div>
- <hr className="cs1 ce12" />
- <div className="cs1 ce12">
- <p>
- To explore more and build your own app, see the Miro Developer
- Platform documentation.
- </p>
- <a
- className="button button-secondary"
- target="_blank"
- href="https://developers.miro.com"
- >
- Read the documentation
- </a>
- </div>
</div>
</div>
</body>
--- /dev/null
+import z from 'zod';
+
+export const zPoint = z.object({
+ x: z.number(),
+ y: z.number(),
+});
+
+export const zShape = z.object({
+ type: z.literal('shape'),
+ kind: z.enum(['rectangle', 'circle', 'ellipse', 'triangle']),
+ position: zPoint,
+ width: z.number(),
+ height: z.number(),
+ fillColor: z.string(),
+ strokeColor: z.string().optional(),
+ strokeWidth: z.number().min(0).optional(),
+ borderRadius: z.number().optional(),
+ text: z.string(),
+ textAlignment: z.enum(['left', 'center', 'right']).optional(),
+ textColor: z.string().optional(),
+ textBold: z.boolean().optional(),
+ textItalic: z.boolean().optional(),
+});
+
+export type Shape = z.infer<typeof zShape>;
+
+export const zImage = z.object({
+ type: z.literal('image'),
+ mxc: z.string(),
+ fileName: z.string(),
+ mimeType: z.enum(['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml']).optional(),
+ position: zPoint,
+ width: z.number().min(0),
+ height: z.number().min(0),
+});
+
+export type Image = z.infer<typeof zImage>;
+
+export const zPath = z.object({
+ type: z.literal('path'),
+ kind: z.enum(['line', 'polyline']),
+ position: zPoint,
+ points: z.array(zPoint),
+ strokeColor: z.string(),
+ endMarker: z.enum(['arrow-head-line']).optional(),
+});
+
+export type Path = z.infer<typeof zPath>;
+
+export const zSlide = z.object({
+ elements: z.array(z.discriminatedUnion('type', [
+ zShape,
+ zPath,
+ zImage,
+ ])),
+});
+
+export type Slide = z.infer<typeof zSlide>;
+
+export const zWhiteboard = z.object({
+ version: z.literal('net.nordeck.whiteboard@v1'),
+ whiteboard: z.object({
+ files: z.array(z.object({
+ mxc: z.string(),
+ data: z.string(),
+ })).optional(),
+ slides: z.array(zSlide),
+ }),
+});
+
+export type Whiteboard = z.infer<typeof zWhiteboard>;
+
+export const neoboardWhiteboardWidth = 1920;
+export const neoboardWhiteboardHeight = 1080;
\ No newline at end of file
+"use server";
import React from 'react';
-import {Board} from '@mirohq/miro-api';
+import { Board } from '@mirohq/miro-api';
import initMiroAPI from '../utils/initMiroAPI';
-import '../assets/style.css';
+import '../assets/style.scss';
+import SelectionFormComponent from './selectionFormComponent';
const getBoards = async () => {
- const {miro, userId} = initMiroAPI();
+ const { miro, userId } = initMiroAPI();
+ const userIdAwaited = await userId();
// redirect to auth url if user has not authorized the app
- if (!userId || !(await miro.isAuthorized(userId))) {
+ if (!userIdAwaited || !(await miro.isAuthorized(userIdAwaited))) {
return {
authUrl: miro.getAuthUrl(),
};
}
- const api = miro.as(userId);
+ const api = miro.as(userIdAwaited);
const boards: Board[] = [];
for await (const board of api.getAllBoards()) {
};
export default async function Page() {
- const {boards, authUrl} = await getBoards();
-
- return (
- <div>
- <h3>API usage demo</h3>
- <p className="p-small">API Calls need to be authenticated</p>
- <p>
- Apps that use the API usually would run on your own domain. During
- development, test on http://localhost:3000
- </p>
- {authUrl ? (
+ const { boards, authUrl } = await getBoards();
+
+ const safeBoards = boards?.map((board) => ({
+ id: board.id,
+ name: board.name,
+ }));
+
+ if (authUrl) {
+ return (
+ <div>
+ <h3>Login</h3>
<a className="button button-primary" href={authUrl} target="_blank">
Login
</a>
- ) : (
- <>
- <p>This is a list of all the boards that your user has access to:</p>
-
- <ul>
- {boards?.map((board) => (
- <li key={board.name}>{board.name}</li>
- ))}
- </ul>
- </>
- )}
- </div>
- );
+ </div>
+ );
+ }
+
+ if (!safeBoards) {
+ return <div>Loading...</div>;
+ }
+
+ return (<><SelectionFormComponent boards={safeBoards} /></>);
}
--- /dev/null
+"use client";
+
+import { FormState, importBoard } from "./importActions";
+import { startTransition, useActionState } from "react";
+
+export type SelectionFormProps = {
+ boards: {
+ id: string;
+ name: string;
+ }[];
+};
+
+export default function SelectionFormComponent({ boards }: SelectionFormProps) {
+ // Filter duplicate boards
+ const uniqueBoards = boards.filter((board, index, self) => self.findIndex((t) => t.id === board.id) === index);
+
+ const [state, action, isPending] = useActionState(async (state: FormState, payload: FormData) => {
+ if (payload === null) {
+ return {
+ neoboards: [],
+ message: '',
+ } as FormState;
+ }
+
+ return await importBoard(state, payload);
+ }, {
+ neoboards: [],
+ message: '',
+ } as FormState);
+
+ if (isPending) {
+ return <div>Loading...</div>;
+ }
+
+ if (state.neoboards.length > 0) {
+ const neoboardBlobs = state.neoboards.map((neoboard) => new Blob([JSON.stringify(neoboard.neoboard)], { type: 'application/json' }));
+ return (
+ <div>
+ <h3>Converting Boards</h3>
+ {state.message && <p>{state.message}</p>}
+ <p>Download the Neoboards below</p>
+ {neoboardBlobs.map((blob, index) => (
+ <a key={index} href={URL.createObjectURL(blob)} download={`${uniqueBoards.find(x => state.neoboards[index].id === x.id)?.name}.nwb`} className="button button-primary">
+ Download Neoboard "{uniqueBoards.find(x => state.neoboards[index].id === x.id)?.name}"
+ </a>
+ ))}
+ {/* Start over button which resets state */}
+ <button onClick={() => {
+ startTransition(() => {
+ // @ts-ignore
+ action(null)
+ });
+ }} className="button button-danger" type="button">
+ Start Over
+ </button>
+ </div>
+ );
+ }
+
+ return (
+ <div>
+ <h3>Available Boards</h3>
+ <p><i>Due to limitations of the Miro API we can not correctly export boards which used templates</i></p>
+ <form action={action}>
+ <p>This is a list of all the boards you have access to. Please select a board to import</p>
+
+ {uniqueBoards?.map((board) => (
+ <label className="checkbox" key={board.id}>
+ <input tabIndex={0} type="checkbox" name="board" value={board.id} />
+ <span>{board.name}</span>
+ </label>
+ ))}
+
+ <button type="submit" className="button button-primary">
+ Import
+ </button>
+ </form>
+ </div>
+ );
+}
\ No newline at end of file
+++ /dev/null
-@import 'mirotone/dist/styles.css';
-
-*,
-*:before,
-*:after {
- box-sizing: border-box;
-}
-
-body {
- display: flex;
-}
-
-#root {
- width: 100%;
- overflow: auto;
- padding: var(--space-medium);
-}
-
-img {
- max-width: 100%;
- height: auto;
-}
--- /dev/null
+@import 'mirotone/dist/styles.css';
+
+*,
+*:before,
+*:after {
+ box-sizing: border-box;
+}
+
+body {
+ display: flex;
+ // Center the content
+ justify-content: center;
+}
+
+#root {
+ width: 100%;
+ overflow: auto;
+ padding: var(--space-medium);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+img {
+ max-width: 100%;
+ width: auto;
+ height: auto;
+ max-height: 30vh;
+}
+
+// Add some space between checkboxes
+form div {
+ margin-bottom: var(--space-small);
+}
\ No newline at end of file
+++ /dev/null
-'use client';
-
-import {useEffect} from 'react';
-
-export const MiroSDKInit = () => {
- useEffect(() => {
- miro.board.ui.on('icon:click', async () => {
- await miro.board.ui.openPanel({url: '/'});
- });
- });
-
- return null;
-};
+++ /dev/null
-'use client';
-import {FC} from 'react';
-
-async function addSticky() {
- const stickyNote = await miro.board.createStickyNote({
- content: 'Hello, World!',
- });
- await miro.board.viewport.zoomTo(stickyNote);
-}
-
-export const SDKUsageDemo: FC = () => {
- return (
- <div>
- <h3>SDK Usage Demo</h3>
- <p className="p-small">SDK doesnt need to be authenticated.</p>
- <p>
- Apps that use the SDK should run inside a Miro board. During
- development, you can open this app inside a{' '}
- <a href="https://developers.miro.com/docs/build-your-first-hello-world-app#step-2-try-out-your-app-in-miro">
- Miro board
- </a>
- .
- </p>
- <button
- type="button"
- onClick={addSticky}
- className="button button-primary"
- >
- Add a sticky
- </button>
- </div>
- );
-};
-import {Miro} from '@mirohq/miro-api';
-import {cookies} from 'next/headers';
-import {State} from '@mirohq/miro-api/dist/storage';
+import { Miro } from '@mirohq/miro-api';
+import { cookies } from 'next/headers';
+import { State } from '@mirohq/miro-api/dist/storage';
const tokensCookie = 'miro_tokens';
export default function initMiroAPI() {
const cookieInstance = cookies();
- const getCookieValue = (key: string = tokensCookie) => {
+ const getCookieValue = async (key: string = tokensCookie) => {
+ const awaitedCookieInstance = await cookieInstance;
// Load state (tokens) from a cookie if it's set
try {
- return JSON.parse(cookieInstance.get(key)?.value!) as State;
+ return JSON.parse(awaitedCookieInstance.get(key)?.value!) as State;
} catch (err) {
- return null;
+ return undefined;
}
};
get: () => {
return getCookieValue();
},
- set: (_, state) => {
- cookieInstance.set(tokensCookie, JSON.stringify(state), {
+ set: async (_, state) => {
+ const awaitedCookieInstance = await cookieInstance;
+ awaitedCookieInstance.set(tokensCookie, JSON.stringify(state), {
path: '/',
httpOnly: true,
sameSite: 'none',
},
}),
// User id might be undefined if the user is not logged in yet, we will know it after the redirect happened
- userId: getCookieValue()?.userId || '',
+ userId: async () => {
+ const state = await getCookieValue();
+ return state?.userId || '';
+ },
};
}