@manifest-editor/projects 2.2.2-next.0.a82700e → 2.3.0
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/index.cjs +29 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -22
- package/dist/index.js.map +1 -1
- package/package.json +18 -11
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["randomId","slugify","slugify","slugify","shallowEqual","localforage","rawUseDropdownMenu"],"sources":["../../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js","../src/ProjectContext.tsx","../../../node_modules/.pnpm/shallowequal@1.1.0/node_modules/shallowequal/index.js","../../../node_modules/.pnpm/slugify@1.6.6/node_modules/slugify/slugify.js","../src/helpers/project-from-manifest.ts","../src/helpers/ensure-unique-filename.ts","../src/helpers/random-id.ts","../src/helpers/project-from-collection.ts","../src/ProjectContext.hooks.ts","../src/ProjectContext.reducer.ts","../src/backend/LocalStorageBackend.ts","../src/storage/AbstractVaultLoader.ts","../src/storage/LocalStorageLoader.ts","../src/ProjectContext.internal.tsx","../../ui/icons/MenuIcon.tsx","../../ui/atoms/Button.tsx","../../ui/atoms/Dropdown.tsx","../builtin:esm-external-require-react","../../../node_modules/.pnpm/react-accessible-dropdown-menu-hook@4.0.0/node_modules/react-accessible-dropdown-menu-hook/dist/use-dropdown-menu.js","../src/use-dropdown-menu.ts","../src/components/AppMenu.tsx","../src/components/DraftTitleEditor.tsx"],"sourcesContent":["var isProduction = process.env.NODE_ENV === 'production';\nvar prefix = 'Invariant failed';\nfunction invariant(condition, message) {\n if (condition) {\n return;\n }\n if (isProduction) {\n throw new Error(prefix);\n }\n var provided = typeof message === 'function' ? message() : message;\n var value = provided ? \"\".concat(prefix, \": \").concat(provided) : prefix;\n throw new Error(value);\n}\n\nexport { invariant as default };\n","import { createContext, useContext } from \"react\";\nimport { EditorProject, ProjectContext } from \"./ProjectContext.types\";\nimport invariant from \"tiny-invariant\";\n\nexport const ProjectReactContext = createContext<ProjectContext | null>(null);\nexport const ProjectLoadingReactContext = createContext<{ isLoading: boolean; isError: boolean; error?: string }>({\n error: undefined,\n isError: false,\n isLoading: false,\n});\n\nexport function useProjectLoading() {\n return useContext(ProjectLoadingReactContext);\n}\n\nexport function useProjectContext(): ProjectContext {\n const ctx = useContext(ProjectReactContext);\n\n invariant(ctx, \"useProjectContext can only be called from inside <ProjectProvider />\");\n\n return ctx;\n}\n\nexport function useCurrentProject(): EditorProject {\n const current = useProjectContext().current;\n\n invariant(current, \"No current project\");\n\n return current;\n}\n\nexport function useOptionalCurrentProject(): EditorProject | null {\n const current = useProjectContext().current;\n\n return current || null;\n}\n","//\n\nmodule.exports = function shallowEqual(objA, objB, compare, compareContext) {\n var ret = compare ? compare.call(compareContext, objA, objB) : void 0;\n\n if (ret !== void 0) {\n return !!ret;\n }\n\n if (objA === objB) {\n return true;\n }\n\n if (typeof objA !== \"object\" || !objA || typeof objB !== \"object\" || !objB) {\n return false;\n }\n\n var keysA = Object.keys(objA);\n var keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);\n\n // Test for A's keys different from B.\n for (var idx = 0; idx < keysA.length; idx++) {\n var key = keysA[idx];\n\n if (!bHasOwnProperty(key)) {\n return false;\n }\n\n var valueA = objA[key];\n var valueB = objB[key];\n\n ret = compare ? compare.call(compareContext, valueA, valueB, key) : void 0;\n\n if (ret === false || (ret === void 0 && valueA !== valueB)) {\n return false;\n }\n }\n\n return true;\n};\n","\n;(function (name, root, factory) {\n if (typeof exports === 'object') {\n module.exports = factory()\n module.exports['default'] = factory()\n }\n /* istanbul ignore next */\n else if (typeof define === 'function' && define.amd) {\n define(factory)\n }\n else {\n root[name] = factory()\n }\n}('slugify', this, function () {\n var charMap = JSON.parse('{\"$\":\"dollar\",\"%\":\"percent\",\"&\":\"and\",\"<\":\"less\",\">\":\"greater\",\"|\":\"or\",\"¢\":\"cent\",\"£\":\"pound\",\"¤\":\"currency\",\"¥\":\"yen\",\"©\":\"(c)\",\"ª\":\"a\",\"®\":\"(r)\",\"º\":\"o\",\"À\":\"A\",\"Á\":\"A\",\"Â\":\"A\",\"Ã\":\"A\",\"Ä\":\"A\",\"Å\":\"A\",\"Æ\":\"AE\",\"Ç\":\"C\",\"È\":\"E\",\"É\":\"E\",\"Ê\":\"E\",\"Ë\":\"E\",\"Ì\":\"I\",\"Í\":\"I\",\"Î\":\"I\",\"Ï\":\"I\",\"Ð\":\"D\",\"Ñ\":\"N\",\"Ò\":\"O\",\"Ó\":\"O\",\"Ô\":\"O\",\"Õ\":\"O\",\"Ö\":\"O\",\"Ø\":\"O\",\"Ù\":\"U\",\"Ú\":\"U\",\"Û\":\"U\",\"Ü\":\"U\",\"Ý\":\"Y\",\"Þ\":\"TH\",\"ß\":\"ss\",\"à\":\"a\",\"á\":\"a\",\"â\":\"a\",\"ã\":\"a\",\"ä\":\"a\",\"å\":\"a\",\"æ\":\"ae\",\"ç\":\"c\",\"è\":\"e\",\"é\":\"e\",\"ê\":\"e\",\"ë\":\"e\",\"ì\":\"i\",\"í\":\"i\",\"î\":\"i\",\"ï\":\"i\",\"ð\":\"d\",\"ñ\":\"n\",\"ò\":\"o\",\"ó\":\"o\",\"ô\":\"o\",\"õ\":\"o\",\"ö\":\"o\",\"ø\":\"o\",\"ù\":\"u\",\"ú\":\"u\",\"û\":\"u\",\"ü\":\"u\",\"ý\":\"y\",\"þ\":\"th\",\"ÿ\":\"y\",\"Ā\":\"A\",\"ā\":\"a\",\"Ă\":\"A\",\"ă\":\"a\",\"Ą\":\"A\",\"ą\":\"a\",\"Ć\":\"C\",\"ć\":\"c\",\"Č\":\"C\",\"č\":\"c\",\"Ď\":\"D\",\"ď\":\"d\",\"Đ\":\"DJ\",\"đ\":\"dj\",\"Ē\":\"E\",\"ē\":\"e\",\"Ė\":\"E\",\"ė\":\"e\",\"Ę\":\"e\",\"ę\":\"e\",\"Ě\":\"E\",\"ě\":\"e\",\"Ğ\":\"G\",\"ğ\":\"g\",\"Ģ\":\"G\",\"ģ\":\"g\",\"Ĩ\":\"I\",\"ĩ\":\"i\",\"Ī\":\"i\",\"ī\":\"i\",\"Į\":\"I\",\"į\":\"i\",\"İ\":\"I\",\"ı\":\"i\",\"Ķ\":\"k\",\"ķ\":\"k\",\"Ļ\":\"L\",\"ļ\":\"l\",\"Ľ\":\"L\",\"ľ\":\"l\",\"Ł\":\"L\",\"ł\":\"l\",\"Ń\":\"N\",\"ń\":\"n\",\"Ņ\":\"N\",\"ņ\":\"n\",\"Ň\":\"N\",\"ň\":\"n\",\"Ō\":\"O\",\"ō\":\"o\",\"Ő\":\"O\",\"ő\":\"o\",\"Œ\":\"OE\",\"œ\":\"oe\",\"Ŕ\":\"R\",\"ŕ\":\"r\",\"Ř\":\"R\",\"ř\":\"r\",\"Ś\":\"S\",\"ś\":\"s\",\"Ş\":\"S\",\"ş\":\"s\",\"Š\":\"S\",\"š\":\"s\",\"Ţ\":\"T\",\"ţ\":\"t\",\"Ť\":\"T\",\"ť\":\"t\",\"Ũ\":\"U\",\"ũ\":\"u\",\"Ū\":\"u\",\"ū\":\"u\",\"Ů\":\"U\",\"ů\":\"u\",\"Ű\":\"U\",\"ű\":\"u\",\"Ų\":\"U\",\"ų\":\"u\",\"Ŵ\":\"W\",\"ŵ\":\"w\",\"Ŷ\":\"Y\",\"ŷ\":\"y\",\"Ÿ\":\"Y\",\"Ź\":\"Z\",\"ź\":\"z\",\"Ż\":\"Z\",\"ż\":\"z\",\"Ž\":\"Z\",\"ž\":\"z\",\"Ə\":\"E\",\"ƒ\":\"f\",\"Ơ\":\"O\",\"ơ\":\"o\",\"Ư\":\"U\",\"ư\":\"u\",\"Lj\":\"LJ\",\"lj\":\"lj\",\"Nj\":\"NJ\",\"nj\":\"nj\",\"Ș\":\"S\",\"ș\":\"s\",\"Ț\":\"T\",\"ț\":\"t\",\"ə\":\"e\",\"˚\":\"o\",\"Ά\":\"A\",\"Έ\":\"E\",\"Ή\":\"H\",\"Ί\":\"I\",\"Ό\":\"O\",\"Ύ\":\"Y\",\"Ώ\":\"W\",\"ΐ\":\"i\",\"Α\":\"A\",\"Β\":\"B\",\"Γ\":\"G\",\"Δ\":\"D\",\"Ε\":\"E\",\"Ζ\":\"Z\",\"Η\":\"H\",\"Θ\":\"8\",\"Ι\":\"I\",\"Κ\":\"K\",\"Λ\":\"L\",\"Μ\":\"M\",\"Ν\":\"N\",\"Ξ\":\"3\",\"Ο\":\"O\",\"Π\":\"P\",\"Ρ\":\"R\",\"Σ\":\"S\",\"Τ\":\"T\",\"Υ\":\"Y\",\"Φ\":\"F\",\"Χ\":\"X\",\"Ψ\":\"PS\",\"Ω\":\"W\",\"Ϊ\":\"I\",\"Ϋ\":\"Y\",\"ά\":\"a\",\"έ\":\"e\",\"ή\":\"h\",\"ί\":\"i\",\"ΰ\":\"y\",\"α\":\"a\",\"β\":\"b\",\"γ\":\"g\",\"δ\":\"d\",\"ε\":\"e\",\"ζ\":\"z\",\"η\":\"h\",\"θ\":\"8\",\"ι\":\"i\",\"κ\":\"k\",\"λ\":\"l\",\"μ\":\"m\",\"ν\":\"n\",\"ξ\":\"3\",\"ο\":\"o\",\"π\":\"p\",\"ρ\":\"r\",\"ς\":\"s\",\"σ\":\"s\",\"τ\":\"t\",\"υ\":\"y\",\"φ\":\"f\",\"χ\":\"x\",\"ψ\":\"ps\",\"ω\":\"w\",\"ϊ\":\"i\",\"ϋ\":\"y\",\"ό\":\"o\",\"ύ\":\"y\",\"ώ\":\"w\",\"Ё\":\"Yo\",\"Ђ\":\"DJ\",\"Є\":\"Ye\",\"І\":\"I\",\"Ї\":\"Yi\",\"Ј\":\"J\",\"Љ\":\"LJ\",\"Њ\":\"NJ\",\"Ћ\":\"C\",\"Џ\":\"DZ\",\"А\":\"A\",\"Б\":\"B\",\"В\":\"V\",\"Г\":\"G\",\"Д\":\"D\",\"Е\":\"E\",\"Ж\":\"Zh\",\"З\":\"Z\",\"И\":\"I\",\"Й\":\"J\",\"К\":\"K\",\"Л\":\"L\",\"М\":\"M\",\"Н\":\"N\",\"О\":\"O\",\"П\":\"P\",\"Р\":\"R\",\"С\":\"S\",\"Т\":\"T\",\"У\":\"U\",\"Ф\":\"F\",\"Х\":\"H\",\"Ц\":\"C\",\"Ч\":\"Ch\",\"Ш\":\"Sh\",\"Щ\":\"Sh\",\"Ъ\":\"U\",\"Ы\":\"Y\",\"Ь\":\"\",\"Э\":\"E\",\"Ю\":\"Yu\",\"Я\":\"Ya\",\"а\":\"a\",\"б\":\"b\",\"в\":\"v\",\"г\":\"g\",\"д\":\"d\",\"е\":\"e\",\"ж\":\"zh\",\"з\":\"z\",\"и\":\"i\",\"й\":\"j\",\"к\":\"k\",\"л\":\"l\",\"м\":\"m\",\"н\":\"n\",\"о\":\"o\",\"п\":\"p\",\"р\":\"r\",\"с\":\"s\",\"т\":\"t\",\"у\":\"u\",\"ф\":\"f\",\"х\":\"h\",\"ц\":\"c\",\"ч\":\"ch\",\"ш\":\"sh\",\"щ\":\"sh\",\"ъ\":\"u\",\"ы\":\"y\",\"ь\":\"\",\"э\":\"e\",\"ю\":\"yu\",\"я\":\"ya\",\"ё\":\"yo\",\"ђ\":\"dj\",\"є\":\"ye\",\"і\":\"i\",\"ї\":\"yi\",\"ј\":\"j\",\"љ\":\"lj\",\"њ\":\"nj\",\"ћ\":\"c\",\"ѝ\":\"u\",\"џ\":\"dz\",\"Ґ\":\"G\",\"ґ\":\"g\",\"Ғ\":\"GH\",\"ғ\":\"gh\",\"Қ\":\"KH\",\"қ\":\"kh\",\"Ң\":\"NG\",\"ң\":\"ng\",\"Ү\":\"UE\",\"ү\":\"ue\",\"Ұ\":\"U\",\"ұ\":\"u\",\"Һ\":\"H\",\"һ\":\"h\",\"Ә\":\"AE\",\"ә\":\"ae\",\"Ө\":\"OE\",\"ө\":\"oe\",\"Ա\":\"A\",\"Բ\":\"B\",\"Գ\":\"G\",\"Դ\":\"D\",\"Ե\":\"E\",\"Զ\":\"Z\",\"Է\":\"E\\'\",\"Ը\":\"Y\\'\",\"Թ\":\"T\\'\",\"Ժ\":\"JH\",\"Ի\":\"I\",\"Լ\":\"L\",\"Խ\":\"X\",\"Ծ\":\"C\\'\",\"Կ\":\"K\",\"Հ\":\"H\",\"Ձ\":\"D\\'\",\"Ղ\":\"GH\",\"Ճ\":\"TW\",\"Մ\":\"M\",\"Յ\":\"Y\",\"Ն\":\"N\",\"Շ\":\"SH\",\"Չ\":\"CH\",\"Պ\":\"P\",\"Ջ\":\"J\",\"Ռ\":\"R\\'\",\"Ս\":\"S\",\"Վ\":\"V\",\"Տ\":\"T\",\"Ր\":\"R\",\"Ց\":\"C\",\"Փ\":\"P\\'\",\"Ք\":\"Q\\'\",\"Օ\":\"O\\'\\'\",\"Ֆ\":\"F\",\"և\":\"EV\",\"ء\":\"a\",\"آ\":\"aa\",\"أ\":\"a\",\"ؤ\":\"u\",\"إ\":\"i\",\"ئ\":\"e\",\"ا\":\"a\",\"ب\":\"b\",\"ة\":\"h\",\"ت\":\"t\",\"ث\":\"th\",\"ج\":\"j\",\"ح\":\"h\",\"خ\":\"kh\",\"د\":\"d\",\"ذ\":\"th\",\"ر\":\"r\",\"ز\":\"z\",\"س\":\"s\",\"ش\":\"sh\",\"ص\":\"s\",\"ض\":\"dh\",\"ط\":\"t\",\"ظ\":\"z\",\"ع\":\"a\",\"غ\":\"gh\",\"ف\":\"f\",\"ق\":\"q\",\"ك\":\"k\",\"ل\":\"l\",\"م\":\"m\",\"ن\":\"n\",\"ه\":\"h\",\"و\":\"w\",\"ى\":\"a\",\"ي\":\"y\",\"ً\":\"an\",\"ٌ\":\"on\",\"ٍ\":\"en\",\"َ\":\"a\",\"ُ\":\"u\",\"ِ\":\"e\",\"ْ\":\"\",\"٠\":\"0\",\"١\":\"1\",\"٢\":\"2\",\"٣\":\"3\",\"٤\":\"4\",\"٥\":\"5\",\"٦\":\"6\",\"٧\":\"7\",\"٨\":\"8\",\"٩\":\"9\",\"پ\":\"p\",\"چ\":\"ch\",\"ژ\":\"zh\",\"ک\":\"k\",\"گ\":\"g\",\"ی\":\"y\",\"۰\":\"0\",\"۱\":\"1\",\"۲\":\"2\",\"۳\":\"3\",\"۴\":\"4\",\"۵\":\"5\",\"۶\":\"6\",\"۷\":\"7\",\"۸\":\"8\",\"۹\":\"9\",\"฿\":\"baht\",\"ა\":\"a\",\"ბ\":\"b\",\"გ\":\"g\",\"დ\":\"d\",\"ე\":\"e\",\"ვ\":\"v\",\"ზ\":\"z\",\"თ\":\"t\",\"ი\":\"i\",\"კ\":\"k\",\"ლ\":\"l\",\"მ\":\"m\",\"ნ\":\"n\",\"ო\":\"o\",\"პ\":\"p\",\"ჟ\":\"zh\",\"რ\":\"r\",\"ს\":\"s\",\"ტ\":\"t\",\"უ\":\"u\",\"ფ\":\"f\",\"ქ\":\"k\",\"ღ\":\"gh\",\"ყ\":\"q\",\"შ\":\"sh\",\"ჩ\":\"ch\",\"ც\":\"ts\",\"ძ\":\"dz\",\"წ\":\"ts\",\"ჭ\":\"ch\",\"ხ\":\"kh\",\"ჯ\":\"j\",\"ჰ\":\"h\",\"Ṣ\":\"S\",\"ṣ\":\"s\",\"Ẁ\":\"W\",\"ẁ\":\"w\",\"Ẃ\":\"W\",\"ẃ\":\"w\",\"Ẅ\":\"W\",\"ẅ\":\"w\",\"ẞ\":\"SS\",\"Ạ\":\"A\",\"ạ\":\"a\",\"Ả\":\"A\",\"ả\":\"a\",\"Ấ\":\"A\",\"ấ\":\"a\",\"Ầ\":\"A\",\"ầ\":\"a\",\"Ẩ\":\"A\",\"ẩ\":\"a\",\"Ẫ\":\"A\",\"ẫ\":\"a\",\"Ậ\":\"A\",\"ậ\":\"a\",\"Ắ\":\"A\",\"ắ\":\"a\",\"Ằ\":\"A\",\"ằ\":\"a\",\"Ẳ\":\"A\",\"ẳ\":\"a\",\"Ẵ\":\"A\",\"ẵ\":\"a\",\"Ặ\":\"A\",\"ặ\":\"a\",\"Ẹ\":\"E\",\"ẹ\":\"e\",\"Ẻ\":\"E\",\"ẻ\":\"e\",\"Ẽ\":\"E\",\"ẽ\":\"e\",\"Ế\":\"E\",\"ế\":\"e\",\"Ề\":\"E\",\"ề\":\"e\",\"Ể\":\"E\",\"ể\":\"e\",\"Ễ\":\"E\",\"ễ\":\"e\",\"Ệ\":\"E\",\"ệ\":\"e\",\"Ỉ\":\"I\",\"ỉ\":\"i\",\"Ị\":\"I\",\"ị\":\"i\",\"Ọ\":\"O\",\"ọ\":\"o\",\"Ỏ\":\"O\",\"ỏ\":\"o\",\"Ố\":\"O\",\"ố\":\"o\",\"Ồ\":\"O\",\"ồ\":\"o\",\"Ổ\":\"O\",\"ổ\":\"o\",\"Ỗ\":\"O\",\"ỗ\":\"o\",\"Ộ\":\"O\",\"ộ\":\"o\",\"Ớ\":\"O\",\"ớ\":\"o\",\"Ờ\":\"O\",\"ờ\":\"o\",\"Ở\":\"O\",\"ở\":\"o\",\"Ỡ\":\"O\",\"ỡ\":\"o\",\"Ợ\":\"O\",\"ợ\":\"o\",\"Ụ\":\"U\",\"ụ\":\"u\",\"Ủ\":\"U\",\"ủ\":\"u\",\"Ứ\":\"U\",\"ứ\":\"u\",\"Ừ\":\"U\",\"ừ\":\"u\",\"Ử\":\"U\",\"ử\":\"u\",\"Ữ\":\"U\",\"ữ\":\"u\",\"Ự\":\"U\",\"ự\":\"u\",\"Ỳ\":\"Y\",\"ỳ\":\"y\",\"Ỵ\":\"Y\",\"ỵ\":\"y\",\"Ỷ\":\"Y\",\"ỷ\":\"y\",\"Ỹ\":\"Y\",\"ỹ\":\"y\",\"–\":\"-\",\"‘\":\"\\'\",\"’\":\"\\'\",\"“\":\"\\\\\\\"\",\"”\":\"\\\\\\\"\",\"„\":\"\\\\\\\"\",\"†\":\"+\",\"•\":\"*\",\"…\":\"...\",\"₠\":\"ecu\",\"₢\":\"cruzeiro\",\"₣\":\"french franc\",\"₤\":\"lira\",\"₥\":\"mill\",\"₦\":\"naira\",\"₧\":\"peseta\",\"₨\":\"rupee\",\"₩\":\"won\",\"₪\":\"new shequel\",\"₫\":\"dong\",\"€\":\"euro\",\"₭\":\"kip\",\"₮\":\"tugrik\",\"₯\":\"drachma\",\"₰\":\"penny\",\"₱\":\"peso\",\"₲\":\"guarani\",\"₳\":\"austral\",\"₴\":\"hryvnia\",\"₵\":\"cedi\",\"₸\":\"kazakhstani tenge\",\"₹\":\"indian rupee\",\"₺\":\"turkish lira\",\"₽\":\"russian ruble\",\"₿\":\"bitcoin\",\"℠\":\"sm\",\"™\":\"tm\",\"∂\":\"d\",\"∆\":\"delta\",\"∑\":\"sum\",\"∞\":\"infinity\",\"♥\":\"love\",\"元\":\"yuan\",\"円\":\"yen\",\"﷼\":\"rial\",\"ﻵ\":\"laa\",\"ﻷ\":\"laa\",\"ﻹ\":\"lai\",\"ﻻ\":\"la\"}')\n var locales = JSON.parse('{\"bg\":{\"Й\":\"Y\",\"Ц\":\"Ts\",\"Щ\":\"Sht\",\"Ъ\":\"A\",\"Ь\":\"Y\",\"й\":\"y\",\"ц\":\"ts\",\"щ\":\"sht\",\"ъ\":\"a\",\"ь\":\"y\"},\"de\":{\"Ä\":\"AE\",\"ä\":\"ae\",\"Ö\":\"OE\",\"ö\":\"oe\",\"Ü\":\"UE\",\"ü\":\"ue\",\"ß\":\"ss\",\"%\":\"prozent\",\"&\":\"und\",\"|\":\"oder\",\"∑\":\"summe\",\"∞\":\"unendlich\",\"♥\":\"liebe\"},\"es\":{\"%\":\"por ciento\",\"&\":\"y\",\"<\":\"menor que\",\">\":\"mayor que\",\"|\":\"o\",\"¢\":\"centavos\",\"£\":\"libras\",\"¤\":\"moneda\",\"₣\":\"francos\",\"∑\":\"suma\",\"∞\":\"infinito\",\"♥\":\"amor\"},\"fr\":{\"%\":\"pourcent\",\"&\":\"et\",\"<\":\"plus petit\",\">\":\"plus grand\",\"|\":\"ou\",\"¢\":\"centime\",\"£\":\"livre\",\"¤\":\"devise\",\"₣\":\"franc\",\"∑\":\"somme\",\"∞\":\"infini\",\"♥\":\"amour\"},\"pt\":{\"%\":\"porcento\",\"&\":\"e\",\"<\":\"menor\",\">\":\"maior\",\"|\":\"ou\",\"¢\":\"centavo\",\"∑\":\"soma\",\"£\":\"libra\",\"∞\":\"infinito\",\"♥\":\"amor\"},\"uk\":{\"И\":\"Y\",\"и\":\"y\",\"Й\":\"Y\",\"й\":\"y\",\"Ц\":\"Ts\",\"ц\":\"ts\",\"Х\":\"Kh\",\"х\":\"kh\",\"Щ\":\"Shch\",\"щ\":\"shch\",\"Г\":\"H\",\"г\":\"h\"},\"vi\":{\"Đ\":\"D\",\"đ\":\"d\"},\"da\":{\"Ø\":\"OE\",\"ø\":\"oe\",\"Å\":\"AA\",\"å\":\"aa\",\"%\":\"procent\",\"&\":\"og\",\"|\":\"eller\",\"$\":\"dollar\",\"<\":\"mindre end\",\">\":\"større end\"},\"nb\":{\"&\":\"og\",\"Å\":\"AA\",\"Æ\":\"AE\",\"Ø\":\"OE\",\"å\":\"aa\",\"æ\":\"ae\",\"ø\":\"oe\"},\"it\":{\"&\":\"e\"},\"nl\":{\"&\":\"en\"},\"sv\":{\"&\":\"och\",\"Å\":\"AA\",\"Ä\":\"AE\",\"Ö\":\"OE\",\"å\":\"aa\",\"ä\":\"ae\",\"ö\":\"oe\"}}')\n\n function replace (string, options) {\n if (typeof string !== 'string') {\n throw new Error('slugify: string argument expected')\n }\n\n options = (typeof options === 'string')\n ? {replacement: options}\n : options || {}\n\n var locale = locales[options.locale] || {}\n\n var replacement = options.replacement === undefined ? '-' : options.replacement\n\n var trim = options.trim === undefined ? true : options.trim\n\n var slug = string.normalize().split('')\n // replace characters based on charMap\n .reduce(function (result, ch) {\n var appendChar = locale[ch];\n if (appendChar === undefined) appendChar = charMap[ch];\n if (appendChar === undefined) appendChar = ch;\n if (appendChar === replacement) appendChar = ' ';\n return result + appendChar\n // remove not allowed characters\n .replace(options.remove || /[^\\w\\s$*_+~.()'\"!\\-:@]+/g, '')\n }, '');\n\n if (options.strict) {\n slug = slug.replace(/[^A-Za-z0-9\\s]/g, '');\n }\n\n if (trim) {\n slug = slug.trim()\n }\n\n // Replace spaces with replacement character, treating multiple consecutive\n // spaces as a single space.\n slug = slug.replace(/\\s+/g, replacement);\n\n if (options.lower) {\n slug = slug.toLowerCase()\n }\n\n return slug\n }\n\n replace.extend = function (customMap) {\n Object.assign(charMap, customMap)\n }\n\n return replace\n}))\n","import { Manifest } from \"@iiif/presentation-3\";\nimport { getValue } from \"@iiif/helpers\";\nimport slugify from \"slugify\";\nimport { EditorProject } from \"../ProjectContext.types\";\nimport { ManifestStorage } from \"../types/Storage\";\n\nfunction randomId() {\n return `${Math.random().toString(36).substr(2)}-${Date.now().toString(36)}`;\n}\n\nexport function projectFromManifest(manifest: Manifest, details: Partial<EditorProject> = {}): EditorProject {\n const name = getValue(manifest.label) || \"Untitled manifest\";\n\n return {\n id: `manifest-editor://project/${randomId()}`,\n filename: slugify(name, { lower: true }),\n name,\n metadata: {\n created: Date.now(),\n modified: Date.now(),\n },\n resource: {\n id: manifest.id,\n type: \"Manifest\",\n },\n publications: [],\n previews: [],\n settings: {},\n storage: {\n type: \"manifest-storage\",\n data: manifest,\n } as ManifestStorage,\n ...details,\n };\n}\n","import { EditorProject } from \"../ProjectContext.types\";\nimport slugify from \"slugify\";\n\nexport function ensureUniqueFilename(project: EditorProject, existing: EditorProject[]) {\n const filenames = existing.map((project) => project.filename);\n\n const name = (project.name || project.filename || \"Untitled project\").toLowerCase();\n\n if (project.filename && filenames.indexOf(project.filename) !== -1) {\n // duplicate.\n project.filename = undefined;\n }\n\n if (!project.filename) {\n let counter = 0;\n while (!project.filename) {\n // Create filename.\n const potentialFilename = `${slugify(name, { lower: true })}${counter ? ` (${counter})` : \"\"}`;\n if (filenames.indexOf(potentialFilename) === -1) {\n project.filename = potentialFilename;\n project.name = `${project.name} (${counter})`;\n break;\n }\n\n counter++;\n }\n }\n}\n","export function randomId() {\n return `${Math.random().toString(36).substr(2)}-${Date.now().toString(36)}`;\n}\n","import { Collection } from \"@iiif/presentation-3\";\nimport { EditorProject } from \"../ProjectContext.types\";\nimport { getValue } from \"@iiif/helpers\";\nimport slugify from \"slugify\";\nimport { CollectionStorage } from \"../types/Storage\";\nimport { randomId } from \"./random-id\";\n\nexport function projectFromCollection(collection: Collection, details: Partial<EditorProject> = {}): EditorProject {\n const name = getValue(collection.label) || \"Untitled collection\";\n\n return {\n id: `manifest-editor://project/${randomId()}`,\n filename: slugify(name, { lower: true }),\n name,\n metadata: {\n created: Date.now(),\n modified: Date.now(),\n },\n resource: {\n id: collection.id,\n type: \"Collection\",\n },\n publications: [],\n previews: [],\n settings: {},\n storage: {\n type: \"collection-storage\",\n data: collection,\n } as CollectionStorage,\n ...details,\n };\n}\n","import { Dispatch, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n EditorProject,\n ProjectActionsType,\n ProjectBackend,\n ProjectContext,\n ProjectsLoadingStatus,\n ProjectState,\n ProjectStorage,\n} from \"./ProjectContext.types\";\nimport { Publication } from \"./types/Publication\";\nimport { Storage } from \"./types/Storage\";\nimport shallowEqual from \"shallowequal\";\nimport { useDebounce } from \"tiny-use-debounce\";\nimport { projectFromManifest } from \"./helpers/project-from-manifest\";\nimport { convertPresentation2 } from \"@iiif/parser/presentation-2\";\nimport { useProjectContext } from \"./ProjectContext\";\nimport { ensureUniqueFilename } from \"./helpers/ensure-unique-filename\";\nimport { projectFromCollection } from \"./helpers/project-from-collection\";\nimport { ClientVault } from \"@manifest-editor/client-vault\";\nimport { randomId } from \"./helpers/random-id\";\nimport { Vault } from \"@iiif/helpers/vault\";\nimport { Preview, getManifestNomalized } from \"@manifest-editor/shell\";\n\nexport function useProjectActionsWithBackend(\n dispatch: Dispatch<ProjectActionsType>,\n backend: ProjectBackend,\n storage: ProjectStorage<any>\n) {\n async function createProject(payload: EditorProject) {\n const allProjects = await backend.getAllProjects(true);\n\n const project = { ...payload }; // avoid readonly payload.\n\n ensureUniqueFilename(project, allProjects);\n\n if (!storage.canCreate()) {\n throw new Error(\"Cannot create project with this storage backend\");\n }\n\n const backendStorage = await storage.create(project, project.storage.data);\n const createdProject = { ...project, storage: backendStorage };\n await backend.createProject(createdProject);\n\n dispatch({ type: \"createProject\", payload: createdProject });\n\n switchProject(project.id);\n }\n function deleteProject(payload: string) {\n if (backend.canDelete()) {\n dispatch({ type: \"deleteProject\", payload });\n\n backend.deleteProject(payload).then(() => {\n // @todo notification?\n console.log(\"Loader: project deleted\");\n });\n }\n }\n function switchProject(payload: string) {\n dispatch({ type: \"switchProject\", payload });\n backend.setLastProject(payload).then(() => {\n // probably nothing.\n });\n }\n function deselectProject(payload: string) {\n dispatch({ type: \"deselectProject\", payload });\n }\n function forkProject(payload: { id: string; name: string; filename?: string }) {\n dispatch({ type: \"forkProject\", payload });\n throw new Error(\"Not implemented yet\");\n }\n function setLoadingStatus(payload: ProjectsLoadingStatus) {\n dispatch({ type: \"setLoadingStatus\", payload });\n }\n function saveProject(project: EditorProject) {\n console.log(\"trying to save project...\");\n dispatch({ type: \"saveProject\", payload: project });\n\n Promise.all([\n //\n backend.updateProject(project),\n storage.saveStorage(project.storage),\n ]).then(() => {\n // @todo notification?\n console.log(\"Loader: project saved\");\n });\n }\n function updateDetails(payload: { name: string; filename?: string }) {\n dispatch({ type: \"updateDetails\", payload });\n }\n function createPublication(payload: Publication) {\n dispatch({ type: \"createPublication\", payload });\n }\n function updatePublication(payload: Publication) {\n dispatch({ type: \"updatePublication\", payload });\n }\n function removePublication(payload: string) {\n dispatch({ type: \"removePublication\", payload });\n }\n function updateSettings(payload: EditorProject[\"settings\"]) {\n dispatch({ type: \"updateSettings\", payload });\n }\n function updateThumbnail(payload: string) {\n dispatch({ type: \"updateThumbnail\", payload });\n }\n function updateStorage(payload: Storage) {\n dispatch({ type: \"updateStorage\", payload });\n }\n function load(payload: ProjectState) {\n dispatch({ type: \"load\", payload });\n }\n\n function setPreview(publication: Preview) {\n dispatch({ type: \"setPreview\", payload: publication });\n }\n function removePreview(id: string) {\n dispatch({ type: \"removePreview\", payload: id });\n }\n\n return useMemo(\n () => ({\n createProject,\n deleteProject,\n switchProject,\n deselectProject,\n forkProject,\n saveProject,\n setLoadingStatus,\n load,\n updateDetails,\n createPublication,\n updatePublication,\n removePublication,\n updateSettings,\n updateThumbnail,\n updateStorage,\n setPreview,\n removePreview,\n }),\n // Dispatch always stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n}\n\nexport function useProjectBackend({ actions, current }: ProjectContext, backend: ProjectBackend) {\n useEffect(() => {\n actions.setLoadingStatus({ loading: true, lastLoaded: 0, loaded: false });\n backend.getAllProjects().then(async (allProjects) => {\n const lastId = await backend.getLastProject();\n const lastValid = allProjects.find((s) => s.id === lastId);\n\n actions.load({\n allProjects: allProjects,\n current: lastValid || null,\n loadingStatus: {\n loaded: true,\n loading: false,\n lastLoaded: Date.now(),\n },\n });\n });\n // this is fine.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n}\n\nexport function useProjectLoader<T extends Storage = any>(\n { actions, current }: ProjectContext,\n storage: ProjectStorage<T>\n) {\n const currentRef = useRef<EditorProject | null>(null);\n const [ready, setIsReady] = useState(false);\n const [error, setError] = useState(\"\");\n const saveChanges = useCallback(() => {\n const project = currentRef.current;\n if (project) {\n storage.saveStorage(project.storage).then(() => {\n const newStorage = storage.getBackendStorage(project);\n if (!shallowEqual(newStorage, project.storage)) {\n actions.saveProject({\n ...project,\n storage: newStorage,\n });\n }\n });\n }\n }, [actions, storage]);\n const debounceSaveChanges = useDebounce(saveChanges, storage.saveInterval);\n const currentId = current?.id;\n\n useEffect(() => {\n currentRef.current = current;\n }, [current]);\n\n // The loader is responsible for creating Vault instances.\n // In the future this Vault instance could be remote and \"clever\"\n // Offering collaboration or similar features.\n const { vault, promise } = useMemo(() => {\n if (current) {\n const [vault, promise] = storage.createVaultInstance(current);\n return {\n vault,\n promise,\n };\n }\n\n return { vault: null, promise: null };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [storage, currentId]);\n\n useEffect(() => {\n const currentStorage = storage;\n const currentProject = current;\n const currentVault = vault;\n return () => {\n if (currentVault && currentProject) {\n currentStorage.closeVaultInstance(currentProject, currentVault);\n } else if (currentVault instanceof ClientVault) {\n (currentVault as ClientVault).ws.close();\n }\n };\n }, [storage, current, vault]);\n\n // If the vault takes some time to load from an external source we might have\n // some time to wait. This will listen to the \"Vault is ready\" promise.\n useEffect(() => {\n setIsReady(false);\n let cancelled = false;\n if (promise) {\n promise\n .then(() => {\n if (!cancelled) {\n setIsReady(true);\n }\n })\n .catch((e) => {\n setError(e.message);\n });\n }\n return () => {\n cancelled = true;\n };\n }, [promise]);\n\n // This will ensure that the changes are saved before reloading or navigating away.\n useEffect(() => {\n window.addEventListener(\"beforeunload\", saveChanges, false);\n\n return () => {\n window.removeEventListener(\"beforeunload\", saveChanges);\n };\n }, [saveChanges]);\n\n // When we unmount, or \"current\" is about to change, then\n // we call save once more.\n useEffect(() => {\n return () => {\n saveChanges();\n };\n }, [saveChanges, currentId]);\n\n // If the loader does not handle its own synchronisation through the Vault it provides, it can\n // let the application know and update the local copy instead. This callback is debounced\n // to ensure we don't call it too often.\n useEffect(() => {\n // @todo migrate this into the storage class.\n if (vault && storage.shouldUpdateWithVault()) {\n return vault.subscribe(debounceSaveChanges, true);\n }\n }, [debounceSaveChanges, storage, vault]);\n\n return {\n vault,\n ready,\n error,\n } as {\n vault: Vault | null;\n ready: boolean;\n error: string;\n };\n}\n\nexport function useProjectCreators() {\n const { actions } = useProjectContext();\n\n const createBlankManifest = useCallback(function createBlankManifest() {\n actions.createProject(\n projectFromManifest({\n \"@context\": \"http://iiif.io/api/presentation/3/context.json\",\n id: `https://example.org/${randomId()}`,\n type: \"Manifest\",\n label: {\n en: [\"Blank Manifest\"],\n },\n items: [],\n })\n );\n\n // Actions are stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const createProjectFromManifestId = useCallback(\n async function createProjectFromManifestId(id: string) {\n let full = await getManifestNomalized(id);\n if (full) {\n if ((full as any)[\"@id\"]) {\n full = convertPresentation2(full) as any;\n }\n if (full) {\n actions.createProject(projectFromManifest(full as any));\n }\n }\n },\n // Actions are stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n\n const createProjectFromCollectionId = useCallback(\n async function createProjectFromCollectionId(id: string) {\n let full = await getManifestNomalized(id);\n if (full) {\n if ((full as any)[\"@id\"]) {\n full = convertPresentation2(full) as any;\n }\n if (full) {\n actions.createProject(projectFromCollection(full as any));\n }\n }\n },\n // Actions are stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n\n const createProjectFromManifestJson = useCallback(\n async function createProjectFromManifestId(json: string) {\n let full = JSON.parse(json);\n if (full) {\n if ((full as any)[\"@id\"]) {\n full = convertPresentation2(full) as any;\n }\n if (full) {\n actions.createProject(projectFromManifest(full as any));\n }\n }\n },\n // Actions are stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n\n return {\n createProjectFromManifestJson,\n createProjectFromManifestId,\n createProjectFromCollectionId,\n createBlankManifest,\n };\n}\n","import { ProjectActionsType, ProjectsLoadingStatus, ProjectState } from \"./ProjectContext.types\";\nimport { produce } from \"immer\";\n\nexport const projectContextReducer = produce(function projectContextReducer(\n state: ProjectState,\n action: ProjectActionsType\n) {\n if (state.current) {\n switch (action.type) {\n // Single project actions\n case \"removePublication\":\n state.current.publications = state.current.publications.filter((p) => p.id !== action.payload);\n break;\n case \"saveProject\":\n state.current.metadata.modified = Date.now();\n break;\n case \"updateDetails\":\n state.current.name = action.payload.name;\n state.current.filename = action.payload.filename;\n break;\n case \"updateStorage\":\n state.current.storage = action.payload;\n break;\n case \"createPublication\": {\n if (!state.current.publications.find((s) => s.id === action.payload.id)) {\n state.current.publications.push(action.payload);\n }\n break;\n }\n case \"updateThumbnail\":\n state.current.thumbnail = action.payload;\n break;\n case \"updateSettings\":\n state.current.settings = action.payload;\n break;\n case \"updatePublication\": {\n const found = state.current.publications.find((s) => s.id === action.payload.id);\n if (found) {\n found.config = action.payload.config;\n }\n break;\n }\n case \"removePreview\": {\n const existing = state.current.previews?.findIndex((p) => p.id === action.payload);\n if (existing !== -1) {\n state.current.previews.splice(existing, 1);\n }\n break;\n }\n case \"setPreview\": {\n const existing = state.current.previews?.findIndex((p) => p.id === action.payload.id);\n if (existing !== -1) {\n state.current.previews.splice(existing, 1, action.payload);\n } else {\n state.current.previews.push(action.payload);\n }\n\n break;\n }\n }\n }\n switch (action.type) {\n case \"load\": {\n state.allProjects = action.payload.allProjects;\n state.current = action.payload.current;\n state.loadingStatus = action.payload.loadingStatus;\n break;\n }\n // Navigate project actions.\n case \"forkProject\":\n // This is probably all behind the scenes.\n break;\n case \"deleteProject\":\n state.allProjects = state.allProjects.filter((p) => p.id !== action.payload);\n if (state.current && state.current.id === action.payload) {\n state.current = null;\n }\n break;\n case \"deselectProject\":\n state.current = null;\n break;\n case \"createProject\":\n state.allProjects.push(action.payload);\n state.current = action.payload;\n break;\n case \"switchProject\":\n state.current = state.allProjects.find((p) => p.id === action.payload) || null;\n break;\n case \"setLoadingStatus\":\n state.loadingStatus = action.payload;\n break;\n }\n});\n\nexport function getDefaultProjectContextState(\n status: ProjectsLoadingStatus | null = {\n loading: false,\n loaded: true,\n lastLoaded: 0,\n }\n): ProjectState {\n return {\n allProjects: [],\n current: null,\n loadingStatus: status,\n };\n}\n","import { EditorProject, ProjectBackend } from \"../ProjectContext.types\";\nimport * as localforage from \"localforage\";\n\nexport class LocalStorageBackend implements ProjectBackend {\n namespace: string;\n saveInterval: number;\n storage: LocalForage;\n constructor(settings?: { namespace?: string }) {\n this.namespace = settings?.namespace || \"default-v1.1\";\n this.saveInterval = 5000;\n this.storage = localforage.createInstance({\n name: \"manifest-editor-projects\",\n });\n }\n\n async deleteProject(id: string): Promise<void> {\n await this.storage.removeItem(`${this.namespace}/projects/${id}`);\n }\n\n async createProject(project: EditorProject): Promise<void> {\n const index = await this.getProjectIndex();\n\n await this.storage.setItem(`${this.namespace}/projects/${project.id}`, JSON.stringify(project));\n\n if (index.indexOf(project.id) === -1) {\n index.push(project.id);\n await this.saveProjectIndex(index);\n }\n }\n\n canDelete() {\n return true;\n }\n\n async getAllProjects(): Promise<EditorProject[]> {\n try {\n const index = await this.getProjectIndex();\n const projects = [];\n for (const item of index) {\n if (item === \"_index\") {\n continue;\n }\n const loaded = await this.storage.getItem<any>(`${this.namespace}/projects/${item}`);\n if (loaded) {\n try {\n projects.push(JSON.parse(loaded));\n } catch (e) {\n // Silent on individual items?\n }\n }\n }\n\n return projects;\n } catch (e) {\n console.error(\"Error loading from localstorage\", e);\n return [];\n }\n }\n\n async getLastProject(): Promise<string | null> {\n return this.storage.getItem(`${this.namespace}/last`);\n }\n\n async setLastProject(id: string): Promise<void> {\n await this.storage.setItem(`${this.namespace}/last`, id);\n }\n\n async updateProject(project: EditorProject): Promise<void> {\n await this.storage.setItem(`${this.namespace}/projects/${project.id}`, JSON.stringify(project));\n }\n\n private async saveProjectIndex(index: string[]): Promise<void> {\n await this.storage.setItem(`${this.namespace}/_index`, JSON.stringify(index));\n }\n\n private async getProjectIndex(): Promise<string[]> {\n const json = await this.storage.getItem<string>(`${this.namespace}/_index`);\n if (!json) {\n return [];\n }\n const index = JSON.parse(json);\n\n if (!Array.isArray(index)) {\n return [];\n }\n\n return index;\n }\n}\n","import { Vault } from \"@iiif/helpers/vault\";\nimport { EditorProject, ProjectStorage } from \"../ProjectContext.types\";\nimport { Collection, Manifest, Reference } from \"@iiif/presentation-3\";\nimport { CollectionStorage, ManifestStorage, Storage } from \"../types/Storage\";\n\nexport abstract class AbstractVaultLoader<T extends Storage>\n implements ProjectStorage<ManifestStorage | CollectionStorage, Manifest | Collection, T>\n{\n abstract type: string;\n vaults: Record<string, Vault | null> = {};\n saveInterval: number;\n\n protected constructor(config: Partial<{ saveInterval: number }> = {}) {\n this.saveInterval = config.saveInterval || 5000;\n }\n\n shouldUpdateWithVault() {\n return true;\n }\n\n canCreate() {\n return true;\n }\n\n canDelete() {\n return true;\n }\n\n abstract create(project: EditorProject, data: Manifest | Collection): Promise<T>;\n\n createVaultInstance(project: EditorProject): [Vault, Promise<void>] {\n const foundVault = this.vaults[project.storage.data.key];\n if (foundVault) {\n return [foundVault, Promise.resolve()];\n }\n\n const vault = new Vault();\n\n const promise = async () => {\n const data = await this.getStorage(project.storage as any);\n await vault.loadManifest(project.resource.id, JSON.parse(JSON.stringify(data?.data)));\n this.vaults[project.storage.data.key] = vault;\n };\n\n return [vault, promise() as Promise<void>];\n }\n\n closeVaultInstance(project: EditorProject, vault: Vault): void {\n // No-op\n }\n\n async saveStorage(storage: T): Promise<void> {\n const vault = this.vaults[storage.data.key];\n const manifestRef: Reference<\"Manifest\" | \"Collection\"> = {\n id: storage.data.id,\n type: storage.data.type,\n };\n\n // There will only be something to save if there is active vault.\n if (vault) {\n const data = vault.toPresentation3<Manifest | Collection>(manifestRef);\n\n const stored: ManifestStorage | CollectionStorage =\n data.type === \"Collection\"\n ? ({\n type: \"collection-storage\",\n data,\n } as CollectionStorage)\n : ({\n type: \"manifest-storage\",\n data,\n } as ManifestStorage);\n\n await this.saveStorageData(stored, storage);\n }\n }\n\n abstract getStorage(storage: T): Promise<CollectionStorage | ManifestStorage | null>;\n\n abstract saveStorageData(manifest: CollectionStorage | ManifestStorage, storage: T): void | Promise<void>;\n\n abstract deleteStorage(storage: T): Promise<void>;\n\n abstract getBackendStorage(project: EditorProject): T;\n}\n","import { EditorProject } from \"../ProjectContext.types\";\nimport { Vault } from \"@iiif/helpers/vault\";\nimport { Collection, Manifest } from \"@iiif/presentation-3\";\nimport { ResourceKeyedStorage, ManifestStorage, CollectionStorage } from \"../types/Storage\";\nimport { AbstractVaultLoader } from \"./AbstractVaultLoader\";\nimport invariant from \"tiny-invariant\";\nimport localforage from \"localforage\";\nimport { randomId } from \"../helpers/random-id\";\n\nexport class LocalStorageLoader extends AbstractVaultLoader<ResourceKeyedStorage> {\n type = \"local-storage\";\n namespace: string;\n storage: LocalForage;\n\n vaults: Record<string, Vault | null> = {};\n\n constructor(settings?: { namespace?: string }) {\n super({ saveInterval: 5000 });\n this.namespace = settings?.namespace || \"default\";\n this.storage = localforage.createInstance({\n name: \"local-storage-resource-loader\",\n });\n }\n\n shouldUpdateWithVault() {\n return true;\n }\n\n async create(project: EditorProject, data: Manifest | Collection): Promise<ResourceKeyedStorage> {\n const key = randomId();\n\n await localStorage.setItem(`${this.namespace}/store/${key}`, JSON.stringify(data));\n\n return {\n type: \"resource-keyed-storage\",\n data: {\n id: data.id,\n type: data.type,\n key,\n },\n };\n }\n\n async getStorage(storage: ResourceKeyedStorage): Promise<CollectionStorage | ManifestStorage | null> {\n try {\n const item = await localStorage.getItem(`${this.namespace}/store/${storage.data.key}`);\n const manifest = item ? (JSON.parse(item) as any) : null;\n\n invariant(manifest, \"Resource not found\");\n\n if (manifest.type === \"Collection\") {\n return {\n type: \"collection-storage\",\n data: manifest,\n };\n }\n\n return {\n type: \"manifest-storage\",\n data: manifest,\n };\n } catch (e) {\n return null;\n }\n }\n\n async saveStorageData(\n manifestStorage: ManifestStorage | CollectionStorage,\n storage: ResourceKeyedStorage\n ): Promise<void> {\n await localStorage.setItem(`${this.namespace}/store/${storage.data.key}`, JSON.stringify(manifestStorage.data));\n }\n\n async deleteStorage(storage: ResourceKeyedStorage): Promise<void> {\n this.vaults[storage.data.key] = null;\n await localStorage.removeItem(`${this.namespace}/store/${storage.data.key}`);\n }\n\n getBackendStorage(project: EditorProject): ResourceKeyedStorage {\n // This will never change after creation, but other adapters might?\n return project.storage as ResourceKeyedStorage;\n }\n}\n","import { ReactNode, useEffect, useMemo, useReducer } from \"react\";\nimport { ProjectReactContext, ProjectLoadingReactContext } from \"./ProjectContext\";\nimport { useApps, AppResourceProvider, AppResourceInstanceProvider } from \"@manifest-editor/shell\";\nimport { useProjectActionsWithBackend, useProjectLoader, useProjectBackend } from \"./ProjectContext.hooks\";\nimport { projectContextReducer, getDefaultProjectContextState } from \"./ProjectContext.reducer\";\nimport { ProjectBackend, ProjectState, ProjectContext } from \"./ProjectContext.types\";\nimport { LocalStorageBackend } from \"./backend/LocalStorageBackend\";\nimport { AbstractVaultLoader } from \"./storage/AbstractVaultLoader\";\nimport { LocalStorageLoader } from \"./storage/LocalStorageLoader\";\nimport { VaultProvider } from \"react-iiif-vault\";\n\nexport interface ProjectProviderProps {\n children: ReactNode;\n defaultApp?: string;\n // Storage\n storage?: AbstractVaultLoader<any>;\n backend?: ProjectBackend;\n initialState?: () => ProjectState;\n}\n\nexport function ProjectProvider(props: ProjectProviderProps) {\n const { currentApp, changeApp } = useApps();\n // @todo this may be configuration or something else.\n // The interface for the loader will definitely change over time.\n const backend = useMemo(() => props.backend || new LocalStorageBackend(), []);\n const storage = useMemo(() => props.storage || new LocalStorageLoader(), []);\n const [state, dispatch] = useReducer(\n projectContextReducer,\n undefined,\n props.initialState || getDefaultProjectContextState\n );\n const actions = useProjectActionsWithBackend(dispatch, backend, storage);\n const context: ProjectContext = useMemo(\n () => ({ actions, canDelete: backend.canDelete(), ...state }),\n [actions, backend, state]\n );\n const { vault, ready, error } = useProjectLoader(context, storage);\n const manifestOrCollection = context.current?.resource;\n\n const loadingStatus = useMemo(() => {\n return { isLoading: !ready, isError: !!error, error };\n }, [ready, error]);\n\n useProjectBackend(context, backend);\n\n useEffect(() => {\n if (\n state.loadingStatus &&\n state.loadingStatus.loaded &&\n ready &&\n (!vault || !manifestOrCollection) &&\n currentApp?.id !== (props.defaultApp || \"splash\")\n ) {\n changeApp({ id: props.defaultApp || \"splash\" });\n }\n }, []);\n\n if ((state.loadingStatus && state.loadingStatus.loading) || (context.current && !manifestOrCollection)) {\n return <div>Loading...</div>;\n }\n\n return (\n <ProjectLoadingReactContext.Provider value={loadingStatus}>\n <ProjectReactContext.Provider value={context}>\n <VaultProvider vault={vault || undefined} key={state.current?.id}>\n <AppResourceInstanceProvider id={context.current?.id}>\n <AppResourceProvider resource={manifestOrCollection}>{props.children}</AppResourceProvider>\n </AppResourceInstanceProvider>\n </VaultProvider>\n </ProjectReactContext.Provider>\n </ProjectLoadingReactContext.Provider>\n );\n}\n","export const MenuIcon: React.FC = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1rem\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"#000000\">\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z\" />\n </svg>\n);\n","import styled from \"styled-components\";\n\nexport const ButtonReset = styled.button`\n border: none;\n outline: none;\n background-color: transparent;\n margin: 0;\n padding: 0;\n font-size: inherit;\n color: inherit;\n cursor: pointer;\n &:hover {\n color: inherit;\n }\n`;\n\nexport const Button = styled.button<{ $active?: boolean }>`\n padding: 0.5rem 1rem;\n color: ${(props: any) => props.theme.color.main || \"none\"};\n background-color: ${(props: any) => props.theme.color.white || \"white\"};\n border-radius: inherit;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n font-size: 0.85em;\n :disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n\n &:hover {\n background: #eee;\n }\n`;\n\nexport const SmallButton = styled(Button as any)`\n padding: 0.25em ${(props: any) => props.theme.padding.xs || \"0.4em\"};\n height: unset;\n background: none;\n`;\n\nexport const SecondaryButton = styled(Button as any)`\n {\n padding: 0 ${(props: any) => props.theme.padding.medium || \"1rem\"};\n color: ${(props: any) => props.theme.color.main || \"#B84C74;\"};\n background-color: ${(props: any) => props.theme.color.white || \"white\"};\n border: 1px solid ${(props: any) => props.theme.color.main || \"#B84C74;\"};\n border-radius: 0.25rem;\n cursor: pointer;\n height: 2rem;\n display: flex;\n align-items: center;\n white-space: nowrap;\n font-size: 0.75rem;\n\n :disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n }\n`;\n\nexport const CalltoButton = styled(Button as any)`\n padding: 0 ${(props: any) => props.theme.padding.medium || \"1rem\"};\n color: ${(props: any) => props.theme.color.white || \"white\"};\n background-color: ${(props: any) => props.theme.color.main || \"#B84C74;\"};\n border: 1px solid #eee;\n border-radius: 0.25rem;\n cursor: pointer;\n justify-content: center;\n display: flex;\n align-items: center;\n &:hover {\n background-color: ${(props: any) => props.theme.color.mainHover || \"#B84C74;\"};\n }\n`;\n\nexport const ButtonGroup = styled.div<{ $right?: boolean }>`\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: ${(props) => (props.$right ? \"flex-end\" : \"flex-start\")};\n`;\n","import styled, { css } from \"styled-components\";\nimport { Button } from \"./Button\";\n\nexport const Dropdown = styled.div`\n position: relative;\n display: inline-block;\n`;\n\nexport const DropdownContent = styled.div`\n display: flex;\n flex-direction: column;\n position: absolute;\n background-color: ${(props: any) => props.theme.color.white || \"white\"};\n color: ${(props: any) => props.theme.color.black || \" black\"};\n font-size: 0.75rem;\n min-width: 160px;\n box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);\n z-index: 150;\n button {\n &:hover {\n background-color: ${(props: any) => props.theme.color.lightgrey || \"lightgrey\"};\n }\n }\n`;\n\nexport const DropdownItem = styled.button<{ $active?: boolean }>`\n padding: 0 ${(props: any) => props.theme.padding.small || \"0.5rem\"};\n color: ${(props: any) => props.theme.color.main || \"none\"};\n background-color: ${(props: any) => props.theme.color.white || \"white\"};\n border-radius: 0;\n border: none;\n cursor: pointer;\n display: flex;\n padding: 0.65em 1em;\n align-items: center;\n :disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n\n &:hover {\n background-color: ${(props: any) => props.theme.color.lightgrey || \"lightgrey\"};\n }\n\n ${(props) =>\n props.$active &&\n css`\n background: #b84c74;\n color: #fff;\n &:hover {\n background: #b84c74;\n color: #fff;\n }\n `}\n`;\n\nexport const DropdownMenu = styled.div<{ $open?: boolean; $center?: boolean }>`\n display: none;\n flex-direction: column;\n position: absolute;\n background: #fff;\n color: ${(props: any) => props.theme.color.black || \" black\"};\n font-size: 0.75rem;\n min-width: 190px;\n top: calc(100% + 0.5em);\n box-shadow:\n 0 4px 15px 0 rgba(0, 0, 0, 0.18),\n 0 0px 0px 1px rgba(0, 0, 0, 0.15),\n inset 0 0 0 1px rgba(255, 255, 255, 0.2);\n border-radius: 3px;\n z-index: 150;\n overflow: hidden;\n padding-bottom: 3px;\n\n ${Button} {\n &:hover {\n background-color: ${(props: any) => props.theme.color.lightgrey || \"lightgrey\"};\n }\n }\n\n ${(props) =>\n props.$open &&\n css`\n display: flex;\n `}\n`;\n\nexport const DropdownLabel = styled.div`\n color: #999;\n text-transform: uppercase;\n font-weight: 600;\n padding: 0.7em;\n font-size: 0.875em;\n`;\n\nexport const DropdownDivider = styled.div`\n height: 1px;\n margin: 0 0.5em;\n background: #eee;\n`;\n","import * as m from 'react';module.exports = { ...m };","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst react_1 = require(\"react\");\nfunction useDropdownMenu(itemCount, options) {\n const [isOpen, setIsOpen] = (0, react_1.useState)(false);\n const currentFocusIndex = (0, react_1.useRef)(null);\n const firstRun = (0, react_1.useRef)(true);\n const clickedOpen = (0, react_1.useRef)(false);\n const buttonRef = (0, react_1.useRef)(null);\n const itemRefs = (0, react_1.useMemo)(() => Array.from({ length: itemCount }, () => (0, react_1.createRef)()), [itemCount]);\n const isKeyboardEvent = (e) => e.key !== undefined;\n const moveFocus = (itemIndex) => {\n var _a;\n currentFocusIndex.current = itemIndex;\n (_a = itemRefs[itemIndex].current) === null || _a === void 0 ? void 0 : _a.focus();\n };\n (0, react_1.useEffect)(() => {\n if (firstRun.current) {\n firstRun.current = false;\n return;\n }\n if (isOpen && (!clickedOpen.current || (options === null || options === void 0 ? void 0 : options.focusFirstItemOnClick))) {\n moveFocus(0);\n }\n else if (!isOpen) {\n clickedOpen.current = false;\n }\n }, [isOpen]);\n (0, react_1.useEffect)(() => {\n if (!isOpen) {\n return;\n }\n const removalTracker = {\n removed: false,\n };\n const handleEveryClick = (event) => {\n setTimeout(() => {\n if (!(event.target instanceof Element)) {\n return;\n }\n if (event.target.closest('[role=\"menu\"]') instanceof Element) {\n return;\n }\n setIsOpen(false);\n }, 10);\n };\n setTimeout(() => {\n if (removalTracker.removed) {\n return;\n }\n document.addEventListener('click', handleEveryClick);\n }, 1);\n return () => {\n removalTracker.removed = true;\n document.removeEventListener('click', handleEveryClick);\n };\n }, [isOpen]);\n (0, react_1.useEffect)(() => {\n const disableArrowScroll = (event) => {\n if (isOpen && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {\n event.preventDefault();\n }\n };\n document.addEventListener('keydown', disableArrowScroll);\n return () => document.removeEventListener('keydown', disableArrowScroll);\n }, [isOpen]);\n const buttonListener = (e) => {\n if (isKeyboardEvent(e)) {\n const { key } = e;\n if (!['Enter', ' ', 'Tab', 'ArrowDown', 'Escape'].includes(key)) {\n return;\n }\n if ((key === 'Tab' || key === 'ArrowDown') && clickedOpen.current && isOpen) {\n e.preventDefault();\n moveFocus(0);\n }\n if (key === 'Enter' || key === ' ') {\n e.preventDefault();\n setIsOpen(true);\n }\n if (key === 'Escape') {\n e.preventDefault();\n setIsOpen(false);\n }\n }\n else {\n if (!(options === null || options === void 0 ? void 0 : options.focusFirstItemOnClick)) {\n clickedOpen.current = !isOpen;\n }\n setIsOpen(!isOpen);\n }\n };\n const itemListener = (e) => {\n var _a;\n const { key } = e;\n if (['Tab', 'Shift', 'Enter', 'Escape', 'ArrowUp', 'ArrowDown', ' '].includes(key)) {\n let newFocusIndex = currentFocusIndex.current;\n if (key === 'Escape') {\n setIsOpen(false);\n (_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.focus();\n return;\n }\n else if (key === 'Tab') {\n setIsOpen(false);\n return;\n }\n else if (key === 'Enter' || key === ' ') {\n if (!e.currentTarget.href) {\n e.currentTarget.click();\n }\n setIsOpen(false);\n return;\n }\n if (newFocusIndex !== null) {\n if (key === 'ArrowUp') {\n newFocusIndex -= 1;\n }\n else if (key === 'ArrowDown') {\n newFocusIndex += 1;\n }\n if (newFocusIndex > itemRefs.length - 1) {\n newFocusIndex = 0;\n }\n else if (newFocusIndex < 0) {\n newFocusIndex = itemRefs.length - 1;\n }\n }\n if (newFocusIndex !== null) {\n moveFocus(newFocusIndex);\n }\n return;\n }\n if (/[a-zA-Z0-9./<>?;:\"'`!@#$%^&*()\\\\[\\]{}_+=|\\\\-~,]/.test(key)) {\n const index = itemRefs.findIndex((ref) => {\n var _a, _b, _c, _d, _e, _f;\n return ((_b = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.innerText) === null || _b === void 0 ? void 0 : _b.toLowerCase().startsWith(key.toLowerCase())) ||\n ((_d = (_c = ref.current) === null || _c === void 0 ? void 0 : _c.textContent) === null || _d === void 0 ? void 0 : _d.toLowerCase().startsWith(key.toLowerCase())) ||\n ((_f = (_e = ref.current) === null || _e === void 0 ? void 0 : _e.getAttribute('aria-label')) === null || _f === void 0 ? void 0 : _f.toLowerCase().startsWith(key.toLowerCase()));\n });\n if (index !== -1) {\n moveFocus(index);\n }\n }\n };\n const buttonProps = {\n onKeyDown: buttonListener,\n onClick: buttonListener,\n tabIndex: 0,\n ref: buttonRef,\n role: 'button',\n 'aria-haspopup': true,\n 'aria-expanded': isOpen,\n };\n const itemProps = Array.from({ length: itemCount }, (_ignore, index) => ({\n onKeyDown: itemListener,\n tabIndex: -1,\n role: 'menuitem',\n ref: itemRefs[index],\n }));\n return { buttonProps, itemProps, isOpen, setIsOpen, moveFocus };\n}\nexports.default = useDropdownMenu;\n","import rawUseDropdownMenu from \"react-accessible-dropdown-menu-hook\";\n\nconst useDropdownMenu = (\n typeof rawUseDropdownMenu === \"object\" && rawUseDropdownMenu !== null && \"default\" in rawUseDropdownMenu\n ? rawUseDropdownMenu.default\n : rawUseDropdownMenu\n) as typeof rawUseDropdownMenu;\n\nexport default useDropdownMenu;\n","import { MenuIcon } from \"@manifest-editor/ui/icons/MenuIcon\";\nimport { Dropdown, DropdownDivider, DropdownLabel, DropdownMenu } from \"@manifest-editor/ui/atoms/Dropdown\";\nimport { Button } from \"@manifest-editor/ui/atoms/Button\";\nimport { useLocalStorage } from \"@manifest-editor/shell\";\nimport useDropdownMenu from \"../use-dropdown-menu\";\nimport { useProjectContext } from \"../ProjectContext\";\nimport { MappedApp, useApps } from \"@manifest-editor/shell\";\nimport styled from \"styled-components\";\n\nexport const IconButton = styled.button`\n height: 1.75em;\n width: 1.75em;\n background: #e9e9e9;\n border-radius: 3px;\n display: flex;\n text-align: center;\n align-items: center;\n font-size: 1.1em;\n border: none;\n justify-content: center;\n\n &:focus {\n background: #e94581;\n color: #fff;\n svg {\n fill: #fff;\n }\n }\n`;\n\nexport function AppMenu(props: { hideMenu?: boolean }) {\n const { current: currentProject } = useProjectContext();\n const [isMenuHidden, setIsMenuHidden] = useLocalStorage(\"menu-hidden\");\n const { apps, changeApp } = useApps();\n const type = currentProject?.resource.type;\n const filteredApps = Object.values(apps).filter((app: MappedApp) => {\n if (app.metadata.project && app.metadata.projectType !== type) {\n return false;\n }\n\n if (!currentProject && app.metadata.project) {\n return false;\n }\n\n if (app.metadata.type === \"launcher\") {\n return false;\n }\n\n // @todo ignore\n // if (app.metadata.dev && import.meta.env.PROD) {\n // try {\n // if (import.meta.env.PULL_REQUEST === \"true\") {\n // return true;\n // }\n // } catch (e) {\n // return false;\n // }\n\n // return false;\n // }\n\n return true;\n });\n const { itemProps, buttonProps, isOpen, setIsOpen } = useDropdownMenu(filteredApps.length + 1);\n\n return (\n <Dropdown>\n <IconButton {...buttonProps}>\n <MenuIcon />\n </IconButton>\n <DropdownMenu $open={isOpen}>\n <DropdownLabel>Apps</DropdownLabel>\n <DropdownDivider />\n {filteredApps.map((app, key) => (\n <Button\n key={app.metadata.id}\n {...(itemProps[key] as any)}\n onClick={() => {\n changeApp({ id: app.metadata.id });\n setIsOpen(false);\n }}\n >\n {app.metadata.title}\n </Button>\n ))}\n {props.hideMenu ? null : (\n <>\n <DropdownLabel>Quick Settings</DropdownLabel>\n <DropdownDivider />\n <Button {...(itemProps[filteredApps.length + 0] as any)} onClick={() => setIsMenuHidden(!isMenuHidden)}>\n {isMenuHidden ? \"Show menu\" : \"Hide menu\"}\n </Button>\n </>\n )}\n </DropdownMenu>\n </Dropdown>\n );\n}\n","import { FormEvent, useState } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport styled from \"styled-components\";\nimport { useProjectContext } from \"../ProjectContext\";\nimport { SmallButton } from \"@manifest-editor/ui/atoms/Button\";\n\nexport const Draft = styled.div`\n display: flex;\n flex-direction: row;\n flex: 1;\n padding: 0.28em;\n padding-left: 0.5em;\n align-items: center;\n overflow: hidden;\n`;\n\nexport const DraftsText = styled.div`\n color: #828282;\n padding-right: 1em;\n`;\n\nexport const DraftTitleEdit = styled.form`\n margin: 0;\n padding: 0;\n display: flex;\n flex: 1;\n`;\n\nexport const DraftTitleEditInput = styled.input`\n font-size: 1em;\n flex: 1;\n border: 1px solid #999;\n padding: 0.2em;\n margin: -0.2em 0;\n`;\n\nexport const DraftTitleEditButton = styled(SmallButton as any)`\n font-size: 1em;\n display: inline-block;\n`;\n\nexport const DraftTitle = styled.div`\n color: #333;\n flex: 1;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n`;\n\nexport function DraftTitleEditor() {\n const { actions, current } = useProjectContext();\n const [editingTitle, setIsEditingTitle] = useState(false);\n\n return (\n <Draft>\n <DraftsText>Drafts</DraftsText>\n {current ? (\n <>\n {editingTitle ? (\n <DraftTitleEdit\n onSubmit={(e: FormEvent<HTMLFormElement>) => {\n const form = new FormData(e.target as any);\n const data = Object.fromEntries(form.entries());\n actions.updateDetails(data as any);\n setIsEditingTitle(false);\n }}\n >\n <DraftTitleEditInput id=\"project-title\" defaultValue={current.name} name=\"name\" />\n <DraftTitleEditButton>Save</DraftTitleEditButton>\n </DraftTitleEdit>\n ) : (\n <DraftTitle\n onClick={() => {\n flushSync(() => {\n setIsEditingTitle(true);\n });\n document.getElementById(\"project-title\")?.focus();\n }}\n >\n {current.name || \"Untitled project\"}\n </DraftTitle>\n )}\n </>\n ) : null}\n </Draft>\n );\n}\n"],"x_google_ignoreList":[0,2,3,18],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["randomId","slugify","slugify","slugify","shallowEqual","localforage","rawUseDropdownMenu"],"sources":["../../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js","../src/ProjectContext.tsx","../../../node_modules/.pnpm/shallowequal@1.1.0/node_modules/shallowequal/index.js","../../../node_modules/.pnpm/slugify@1.6.6/node_modules/slugify/slugify.js","../src/helpers/project-from-manifest.ts","../src/helpers/ensure-unique-filename.ts","../src/helpers/random-id.ts","../src/helpers/project-from-collection.ts","../src/ProjectContext.hooks.ts","../src/ProjectContext.reducer.ts","../src/backend/LocalStorageBackend.ts","../src/storage/AbstractVaultLoader.ts","../src/storage/LocalStorageLoader.ts","../src/ProjectContext.internal.tsx","../../ui/icons/MenuIcon.tsx","../../ui/atoms/Button.tsx","../../ui/atoms/Dropdown.tsx","../builtin:esm-external-require-react","../../../node_modules/.pnpm/react-accessible-dropdown-menu-hook@4.0.0/node_modules/react-accessible-dropdown-menu-hook/dist/use-dropdown-menu.js","../src/use-dropdown-menu.ts","../src/components/AppMenu.tsx","../src/components/DraftTitleEditor.tsx"],"sourcesContent":["var isProduction = process.env.NODE_ENV === 'production';\nvar prefix = 'Invariant failed';\nfunction invariant(condition, message) {\n if (condition) {\n return;\n }\n if (isProduction) {\n throw new Error(prefix);\n }\n var provided = typeof message === 'function' ? message() : message;\n var value = provided ? \"\".concat(prefix, \": \").concat(provided) : prefix;\n throw new Error(value);\n}\n\nexport { invariant as default };\n","import { createContext, useContext } from \"react\";\nimport { EditorProject, ProjectContext } from \"./ProjectContext.types\";\nimport invariant from \"tiny-invariant\";\n\nexport const ProjectReactContext = createContext<ProjectContext | null>(null);\nexport const ProjectLoadingReactContext = createContext<{ isLoading: boolean; isError: boolean; error?: string }>({\n error: undefined,\n isError: false,\n isLoading: false,\n});\n\nexport function useProjectLoading() {\n return useContext(ProjectLoadingReactContext);\n}\n\nexport function useProjectContext(): ProjectContext {\n const ctx = useContext(ProjectReactContext);\n\n invariant(ctx, \"useProjectContext can only be called from inside <ProjectProvider />\");\n\n return ctx;\n}\n\nexport function useCurrentProject(): EditorProject {\n const current = useProjectContext().current;\n\n invariant(current, \"No current project\");\n\n return current;\n}\n\nexport function useOptionalCurrentProject(): EditorProject | null {\n const current = useProjectContext().current;\n\n return current || null;\n}\n","//\n\nmodule.exports = function shallowEqual(objA, objB, compare, compareContext) {\n var ret = compare ? compare.call(compareContext, objA, objB) : void 0;\n\n if (ret !== void 0) {\n return !!ret;\n }\n\n if (objA === objB) {\n return true;\n }\n\n if (typeof objA !== \"object\" || !objA || typeof objB !== \"object\" || !objB) {\n return false;\n }\n\n var keysA = Object.keys(objA);\n var keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);\n\n // Test for A's keys different from B.\n for (var idx = 0; idx < keysA.length; idx++) {\n var key = keysA[idx];\n\n if (!bHasOwnProperty(key)) {\n return false;\n }\n\n var valueA = objA[key];\n var valueB = objB[key];\n\n ret = compare ? compare.call(compareContext, valueA, valueB, key) : void 0;\n\n if (ret === false || (ret === void 0 && valueA !== valueB)) {\n return false;\n }\n }\n\n return true;\n};\n","\n;(function (name, root, factory) {\n if (typeof exports === 'object') {\n module.exports = factory()\n module.exports['default'] = factory()\n }\n /* istanbul ignore next */\n else if (typeof define === 'function' && define.amd) {\n define(factory)\n }\n else {\n root[name] = factory()\n }\n}('slugify', this, function () {\n var charMap = JSON.parse('{\"$\":\"dollar\",\"%\":\"percent\",\"&\":\"and\",\"<\":\"less\",\">\":\"greater\",\"|\":\"or\",\"¢\":\"cent\",\"£\":\"pound\",\"¤\":\"currency\",\"¥\":\"yen\",\"©\":\"(c)\",\"ª\":\"a\",\"®\":\"(r)\",\"º\":\"o\",\"À\":\"A\",\"Á\":\"A\",\"Â\":\"A\",\"Ã\":\"A\",\"Ä\":\"A\",\"Å\":\"A\",\"Æ\":\"AE\",\"Ç\":\"C\",\"È\":\"E\",\"É\":\"E\",\"Ê\":\"E\",\"Ë\":\"E\",\"Ì\":\"I\",\"Í\":\"I\",\"Î\":\"I\",\"Ï\":\"I\",\"Ð\":\"D\",\"Ñ\":\"N\",\"Ò\":\"O\",\"Ó\":\"O\",\"Ô\":\"O\",\"Õ\":\"O\",\"Ö\":\"O\",\"Ø\":\"O\",\"Ù\":\"U\",\"Ú\":\"U\",\"Û\":\"U\",\"Ü\":\"U\",\"Ý\":\"Y\",\"Þ\":\"TH\",\"ß\":\"ss\",\"à\":\"a\",\"á\":\"a\",\"â\":\"a\",\"ã\":\"a\",\"ä\":\"a\",\"å\":\"a\",\"æ\":\"ae\",\"ç\":\"c\",\"è\":\"e\",\"é\":\"e\",\"ê\":\"e\",\"ë\":\"e\",\"ì\":\"i\",\"í\":\"i\",\"î\":\"i\",\"ï\":\"i\",\"ð\":\"d\",\"ñ\":\"n\",\"ò\":\"o\",\"ó\":\"o\",\"ô\":\"o\",\"õ\":\"o\",\"ö\":\"o\",\"ø\":\"o\",\"ù\":\"u\",\"ú\":\"u\",\"û\":\"u\",\"ü\":\"u\",\"ý\":\"y\",\"þ\":\"th\",\"ÿ\":\"y\",\"Ā\":\"A\",\"ā\":\"a\",\"Ă\":\"A\",\"ă\":\"a\",\"Ą\":\"A\",\"ą\":\"a\",\"Ć\":\"C\",\"ć\":\"c\",\"Č\":\"C\",\"č\":\"c\",\"Ď\":\"D\",\"ď\":\"d\",\"Đ\":\"DJ\",\"đ\":\"dj\",\"Ē\":\"E\",\"ē\":\"e\",\"Ė\":\"E\",\"ė\":\"e\",\"Ę\":\"e\",\"ę\":\"e\",\"Ě\":\"E\",\"ě\":\"e\",\"Ğ\":\"G\",\"ğ\":\"g\",\"Ģ\":\"G\",\"ģ\":\"g\",\"Ĩ\":\"I\",\"ĩ\":\"i\",\"Ī\":\"i\",\"ī\":\"i\",\"Į\":\"I\",\"į\":\"i\",\"İ\":\"I\",\"ı\":\"i\",\"Ķ\":\"k\",\"ķ\":\"k\",\"Ļ\":\"L\",\"ļ\":\"l\",\"Ľ\":\"L\",\"ľ\":\"l\",\"Ł\":\"L\",\"ł\":\"l\",\"Ń\":\"N\",\"ń\":\"n\",\"Ņ\":\"N\",\"ņ\":\"n\",\"Ň\":\"N\",\"ň\":\"n\",\"Ō\":\"O\",\"ō\":\"o\",\"Ő\":\"O\",\"ő\":\"o\",\"Œ\":\"OE\",\"œ\":\"oe\",\"Ŕ\":\"R\",\"ŕ\":\"r\",\"Ř\":\"R\",\"ř\":\"r\",\"Ś\":\"S\",\"ś\":\"s\",\"Ş\":\"S\",\"ş\":\"s\",\"Š\":\"S\",\"š\":\"s\",\"Ţ\":\"T\",\"ţ\":\"t\",\"Ť\":\"T\",\"ť\":\"t\",\"Ũ\":\"U\",\"ũ\":\"u\",\"Ū\":\"u\",\"ū\":\"u\",\"Ů\":\"U\",\"ů\":\"u\",\"Ű\":\"U\",\"ű\":\"u\",\"Ų\":\"U\",\"ų\":\"u\",\"Ŵ\":\"W\",\"ŵ\":\"w\",\"Ŷ\":\"Y\",\"ŷ\":\"y\",\"Ÿ\":\"Y\",\"Ź\":\"Z\",\"ź\":\"z\",\"Ż\":\"Z\",\"ż\":\"z\",\"Ž\":\"Z\",\"ž\":\"z\",\"Ə\":\"E\",\"ƒ\":\"f\",\"Ơ\":\"O\",\"ơ\":\"o\",\"Ư\":\"U\",\"ư\":\"u\",\"Lj\":\"LJ\",\"lj\":\"lj\",\"Nj\":\"NJ\",\"nj\":\"nj\",\"Ș\":\"S\",\"ș\":\"s\",\"Ț\":\"T\",\"ț\":\"t\",\"ə\":\"e\",\"˚\":\"o\",\"Ά\":\"A\",\"Έ\":\"E\",\"Ή\":\"H\",\"Ί\":\"I\",\"Ό\":\"O\",\"Ύ\":\"Y\",\"Ώ\":\"W\",\"ΐ\":\"i\",\"Α\":\"A\",\"Β\":\"B\",\"Γ\":\"G\",\"Δ\":\"D\",\"Ε\":\"E\",\"Ζ\":\"Z\",\"Η\":\"H\",\"Θ\":\"8\",\"Ι\":\"I\",\"Κ\":\"K\",\"Λ\":\"L\",\"Μ\":\"M\",\"Ν\":\"N\",\"Ξ\":\"3\",\"Ο\":\"O\",\"Π\":\"P\",\"Ρ\":\"R\",\"Σ\":\"S\",\"Τ\":\"T\",\"Υ\":\"Y\",\"Φ\":\"F\",\"Χ\":\"X\",\"Ψ\":\"PS\",\"Ω\":\"W\",\"Ϊ\":\"I\",\"Ϋ\":\"Y\",\"ά\":\"a\",\"έ\":\"e\",\"ή\":\"h\",\"ί\":\"i\",\"ΰ\":\"y\",\"α\":\"a\",\"β\":\"b\",\"γ\":\"g\",\"δ\":\"d\",\"ε\":\"e\",\"ζ\":\"z\",\"η\":\"h\",\"θ\":\"8\",\"ι\":\"i\",\"κ\":\"k\",\"λ\":\"l\",\"μ\":\"m\",\"ν\":\"n\",\"ξ\":\"3\",\"ο\":\"o\",\"π\":\"p\",\"ρ\":\"r\",\"ς\":\"s\",\"σ\":\"s\",\"τ\":\"t\",\"υ\":\"y\",\"φ\":\"f\",\"χ\":\"x\",\"ψ\":\"ps\",\"ω\":\"w\",\"ϊ\":\"i\",\"ϋ\":\"y\",\"ό\":\"o\",\"ύ\":\"y\",\"ώ\":\"w\",\"Ё\":\"Yo\",\"Ђ\":\"DJ\",\"Є\":\"Ye\",\"І\":\"I\",\"Ї\":\"Yi\",\"Ј\":\"J\",\"Љ\":\"LJ\",\"Њ\":\"NJ\",\"Ћ\":\"C\",\"Џ\":\"DZ\",\"А\":\"A\",\"Б\":\"B\",\"В\":\"V\",\"Г\":\"G\",\"Д\":\"D\",\"Е\":\"E\",\"Ж\":\"Zh\",\"З\":\"Z\",\"И\":\"I\",\"Й\":\"J\",\"К\":\"K\",\"Л\":\"L\",\"М\":\"M\",\"Н\":\"N\",\"О\":\"O\",\"П\":\"P\",\"Р\":\"R\",\"С\":\"S\",\"Т\":\"T\",\"У\":\"U\",\"Ф\":\"F\",\"Х\":\"H\",\"Ц\":\"C\",\"Ч\":\"Ch\",\"Ш\":\"Sh\",\"Щ\":\"Sh\",\"Ъ\":\"U\",\"Ы\":\"Y\",\"Ь\":\"\",\"Э\":\"E\",\"Ю\":\"Yu\",\"Я\":\"Ya\",\"а\":\"a\",\"б\":\"b\",\"в\":\"v\",\"г\":\"g\",\"д\":\"d\",\"е\":\"e\",\"ж\":\"zh\",\"з\":\"z\",\"и\":\"i\",\"й\":\"j\",\"к\":\"k\",\"л\":\"l\",\"м\":\"m\",\"н\":\"n\",\"о\":\"o\",\"п\":\"p\",\"р\":\"r\",\"с\":\"s\",\"т\":\"t\",\"у\":\"u\",\"ф\":\"f\",\"х\":\"h\",\"ц\":\"c\",\"ч\":\"ch\",\"ш\":\"sh\",\"щ\":\"sh\",\"ъ\":\"u\",\"ы\":\"y\",\"ь\":\"\",\"э\":\"e\",\"ю\":\"yu\",\"я\":\"ya\",\"ё\":\"yo\",\"ђ\":\"dj\",\"є\":\"ye\",\"і\":\"i\",\"ї\":\"yi\",\"ј\":\"j\",\"љ\":\"lj\",\"њ\":\"nj\",\"ћ\":\"c\",\"ѝ\":\"u\",\"џ\":\"dz\",\"Ґ\":\"G\",\"ґ\":\"g\",\"Ғ\":\"GH\",\"ғ\":\"gh\",\"Қ\":\"KH\",\"қ\":\"kh\",\"Ң\":\"NG\",\"ң\":\"ng\",\"Ү\":\"UE\",\"ү\":\"ue\",\"Ұ\":\"U\",\"ұ\":\"u\",\"Һ\":\"H\",\"һ\":\"h\",\"Ә\":\"AE\",\"ә\":\"ae\",\"Ө\":\"OE\",\"ө\":\"oe\",\"Ա\":\"A\",\"Բ\":\"B\",\"Գ\":\"G\",\"Դ\":\"D\",\"Ե\":\"E\",\"Զ\":\"Z\",\"Է\":\"E\\'\",\"Ը\":\"Y\\'\",\"Թ\":\"T\\'\",\"Ժ\":\"JH\",\"Ի\":\"I\",\"Լ\":\"L\",\"Խ\":\"X\",\"Ծ\":\"C\\'\",\"Կ\":\"K\",\"Հ\":\"H\",\"Ձ\":\"D\\'\",\"Ղ\":\"GH\",\"Ճ\":\"TW\",\"Մ\":\"M\",\"Յ\":\"Y\",\"Ն\":\"N\",\"Շ\":\"SH\",\"Չ\":\"CH\",\"Պ\":\"P\",\"Ջ\":\"J\",\"Ռ\":\"R\\'\",\"Ս\":\"S\",\"Վ\":\"V\",\"Տ\":\"T\",\"Ր\":\"R\",\"Ց\":\"C\",\"Փ\":\"P\\'\",\"Ք\":\"Q\\'\",\"Օ\":\"O\\'\\'\",\"Ֆ\":\"F\",\"և\":\"EV\",\"ء\":\"a\",\"آ\":\"aa\",\"أ\":\"a\",\"ؤ\":\"u\",\"إ\":\"i\",\"ئ\":\"e\",\"ا\":\"a\",\"ب\":\"b\",\"ة\":\"h\",\"ت\":\"t\",\"ث\":\"th\",\"ج\":\"j\",\"ح\":\"h\",\"خ\":\"kh\",\"د\":\"d\",\"ذ\":\"th\",\"ر\":\"r\",\"ز\":\"z\",\"س\":\"s\",\"ش\":\"sh\",\"ص\":\"s\",\"ض\":\"dh\",\"ط\":\"t\",\"ظ\":\"z\",\"ع\":\"a\",\"غ\":\"gh\",\"ف\":\"f\",\"ق\":\"q\",\"ك\":\"k\",\"ل\":\"l\",\"م\":\"m\",\"ن\":\"n\",\"ه\":\"h\",\"و\":\"w\",\"ى\":\"a\",\"ي\":\"y\",\"ً\":\"an\",\"ٌ\":\"on\",\"ٍ\":\"en\",\"َ\":\"a\",\"ُ\":\"u\",\"ِ\":\"e\",\"ْ\":\"\",\"٠\":\"0\",\"١\":\"1\",\"٢\":\"2\",\"٣\":\"3\",\"٤\":\"4\",\"٥\":\"5\",\"٦\":\"6\",\"٧\":\"7\",\"٨\":\"8\",\"٩\":\"9\",\"پ\":\"p\",\"چ\":\"ch\",\"ژ\":\"zh\",\"ک\":\"k\",\"گ\":\"g\",\"ی\":\"y\",\"۰\":\"0\",\"۱\":\"1\",\"۲\":\"2\",\"۳\":\"3\",\"۴\":\"4\",\"۵\":\"5\",\"۶\":\"6\",\"۷\":\"7\",\"۸\":\"8\",\"۹\":\"9\",\"฿\":\"baht\",\"ა\":\"a\",\"ბ\":\"b\",\"გ\":\"g\",\"დ\":\"d\",\"ე\":\"e\",\"ვ\":\"v\",\"ზ\":\"z\",\"თ\":\"t\",\"ი\":\"i\",\"კ\":\"k\",\"ლ\":\"l\",\"მ\":\"m\",\"ნ\":\"n\",\"ო\":\"o\",\"პ\":\"p\",\"ჟ\":\"zh\",\"რ\":\"r\",\"ს\":\"s\",\"ტ\":\"t\",\"უ\":\"u\",\"ფ\":\"f\",\"ქ\":\"k\",\"ღ\":\"gh\",\"ყ\":\"q\",\"შ\":\"sh\",\"ჩ\":\"ch\",\"ც\":\"ts\",\"ძ\":\"dz\",\"წ\":\"ts\",\"ჭ\":\"ch\",\"ხ\":\"kh\",\"ჯ\":\"j\",\"ჰ\":\"h\",\"Ṣ\":\"S\",\"ṣ\":\"s\",\"Ẁ\":\"W\",\"ẁ\":\"w\",\"Ẃ\":\"W\",\"ẃ\":\"w\",\"Ẅ\":\"W\",\"ẅ\":\"w\",\"ẞ\":\"SS\",\"Ạ\":\"A\",\"ạ\":\"a\",\"Ả\":\"A\",\"ả\":\"a\",\"Ấ\":\"A\",\"ấ\":\"a\",\"Ầ\":\"A\",\"ầ\":\"a\",\"Ẩ\":\"A\",\"ẩ\":\"a\",\"Ẫ\":\"A\",\"ẫ\":\"a\",\"Ậ\":\"A\",\"ậ\":\"a\",\"Ắ\":\"A\",\"ắ\":\"a\",\"Ằ\":\"A\",\"ằ\":\"a\",\"Ẳ\":\"A\",\"ẳ\":\"a\",\"Ẵ\":\"A\",\"ẵ\":\"a\",\"Ặ\":\"A\",\"ặ\":\"a\",\"Ẹ\":\"E\",\"ẹ\":\"e\",\"Ẻ\":\"E\",\"ẻ\":\"e\",\"Ẽ\":\"E\",\"ẽ\":\"e\",\"Ế\":\"E\",\"ế\":\"e\",\"Ề\":\"E\",\"ề\":\"e\",\"Ể\":\"E\",\"ể\":\"e\",\"Ễ\":\"E\",\"ễ\":\"e\",\"Ệ\":\"E\",\"ệ\":\"e\",\"Ỉ\":\"I\",\"ỉ\":\"i\",\"Ị\":\"I\",\"ị\":\"i\",\"Ọ\":\"O\",\"ọ\":\"o\",\"Ỏ\":\"O\",\"ỏ\":\"o\",\"Ố\":\"O\",\"ố\":\"o\",\"Ồ\":\"O\",\"ồ\":\"o\",\"Ổ\":\"O\",\"ổ\":\"o\",\"Ỗ\":\"O\",\"ỗ\":\"o\",\"Ộ\":\"O\",\"ộ\":\"o\",\"Ớ\":\"O\",\"ớ\":\"o\",\"Ờ\":\"O\",\"ờ\":\"o\",\"Ở\":\"O\",\"ở\":\"o\",\"Ỡ\":\"O\",\"ỡ\":\"o\",\"Ợ\":\"O\",\"ợ\":\"o\",\"Ụ\":\"U\",\"ụ\":\"u\",\"Ủ\":\"U\",\"ủ\":\"u\",\"Ứ\":\"U\",\"ứ\":\"u\",\"Ừ\":\"U\",\"ừ\":\"u\",\"Ử\":\"U\",\"ử\":\"u\",\"Ữ\":\"U\",\"ữ\":\"u\",\"Ự\":\"U\",\"ự\":\"u\",\"Ỳ\":\"Y\",\"ỳ\":\"y\",\"Ỵ\":\"Y\",\"ỵ\":\"y\",\"Ỷ\":\"Y\",\"ỷ\":\"y\",\"Ỹ\":\"Y\",\"ỹ\":\"y\",\"–\":\"-\",\"‘\":\"\\'\",\"’\":\"\\'\",\"“\":\"\\\\\\\"\",\"”\":\"\\\\\\\"\",\"„\":\"\\\\\\\"\",\"†\":\"+\",\"•\":\"*\",\"…\":\"...\",\"₠\":\"ecu\",\"₢\":\"cruzeiro\",\"₣\":\"french franc\",\"₤\":\"lira\",\"₥\":\"mill\",\"₦\":\"naira\",\"₧\":\"peseta\",\"₨\":\"rupee\",\"₩\":\"won\",\"₪\":\"new shequel\",\"₫\":\"dong\",\"€\":\"euro\",\"₭\":\"kip\",\"₮\":\"tugrik\",\"₯\":\"drachma\",\"₰\":\"penny\",\"₱\":\"peso\",\"₲\":\"guarani\",\"₳\":\"austral\",\"₴\":\"hryvnia\",\"₵\":\"cedi\",\"₸\":\"kazakhstani tenge\",\"₹\":\"indian rupee\",\"₺\":\"turkish lira\",\"₽\":\"russian ruble\",\"₿\":\"bitcoin\",\"℠\":\"sm\",\"™\":\"tm\",\"∂\":\"d\",\"∆\":\"delta\",\"∑\":\"sum\",\"∞\":\"infinity\",\"♥\":\"love\",\"元\":\"yuan\",\"円\":\"yen\",\"﷼\":\"rial\",\"ﻵ\":\"laa\",\"ﻷ\":\"laa\",\"ﻹ\":\"lai\",\"ﻻ\":\"la\"}')\n var locales = JSON.parse('{\"bg\":{\"Й\":\"Y\",\"Ц\":\"Ts\",\"Щ\":\"Sht\",\"Ъ\":\"A\",\"Ь\":\"Y\",\"й\":\"y\",\"ц\":\"ts\",\"щ\":\"sht\",\"ъ\":\"a\",\"ь\":\"y\"},\"de\":{\"Ä\":\"AE\",\"ä\":\"ae\",\"Ö\":\"OE\",\"ö\":\"oe\",\"Ü\":\"UE\",\"ü\":\"ue\",\"ß\":\"ss\",\"%\":\"prozent\",\"&\":\"und\",\"|\":\"oder\",\"∑\":\"summe\",\"∞\":\"unendlich\",\"♥\":\"liebe\"},\"es\":{\"%\":\"por ciento\",\"&\":\"y\",\"<\":\"menor que\",\">\":\"mayor que\",\"|\":\"o\",\"¢\":\"centavos\",\"£\":\"libras\",\"¤\":\"moneda\",\"₣\":\"francos\",\"∑\":\"suma\",\"∞\":\"infinito\",\"♥\":\"amor\"},\"fr\":{\"%\":\"pourcent\",\"&\":\"et\",\"<\":\"plus petit\",\">\":\"plus grand\",\"|\":\"ou\",\"¢\":\"centime\",\"£\":\"livre\",\"¤\":\"devise\",\"₣\":\"franc\",\"∑\":\"somme\",\"∞\":\"infini\",\"♥\":\"amour\"},\"pt\":{\"%\":\"porcento\",\"&\":\"e\",\"<\":\"menor\",\">\":\"maior\",\"|\":\"ou\",\"¢\":\"centavo\",\"∑\":\"soma\",\"£\":\"libra\",\"∞\":\"infinito\",\"♥\":\"amor\"},\"uk\":{\"И\":\"Y\",\"и\":\"y\",\"Й\":\"Y\",\"й\":\"y\",\"Ц\":\"Ts\",\"ц\":\"ts\",\"Х\":\"Kh\",\"х\":\"kh\",\"Щ\":\"Shch\",\"щ\":\"shch\",\"Г\":\"H\",\"г\":\"h\"},\"vi\":{\"Đ\":\"D\",\"đ\":\"d\"},\"da\":{\"Ø\":\"OE\",\"ø\":\"oe\",\"Å\":\"AA\",\"å\":\"aa\",\"%\":\"procent\",\"&\":\"og\",\"|\":\"eller\",\"$\":\"dollar\",\"<\":\"mindre end\",\">\":\"større end\"},\"nb\":{\"&\":\"og\",\"Å\":\"AA\",\"Æ\":\"AE\",\"Ø\":\"OE\",\"å\":\"aa\",\"æ\":\"ae\",\"ø\":\"oe\"},\"it\":{\"&\":\"e\"},\"nl\":{\"&\":\"en\"},\"sv\":{\"&\":\"och\",\"Å\":\"AA\",\"Ä\":\"AE\",\"Ö\":\"OE\",\"å\":\"aa\",\"ä\":\"ae\",\"ö\":\"oe\"}}')\n\n function replace (string, options) {\n if (typeof string !== 'string') {\n throw new Error('slugify: string argument expected')\n }\n\n options = (typeof options === 'string')\n ? {replacement: options}\n : options || {}\n\n var locale = locales[options.locale] || {}\n\n var replacement = options.replacement === undefined ? '-' : options.replacement\n\n var trim = options.trim === undefined ? true : options.trim\n\n var slug = string.normalize().split('')\n // replace characters based on charMap\n .reduce(function (result, ch) {\n var appendChar = locale[ch];\n if (appendChar === undefined) appendChar = charMap[ch];\n if (appendChar === undefined) appendChar = ch;\n if (appendChar === replacement) appendChar = ' ';\n return result + appendChar\n // remove not allowed characters\n .replace(options.remove || /[^\\w\\s$*_+~.()'\"!\\-:@]+/g, '')\n }, '');\n\n if (options.strict) {\n slug = slug.replace(/[^A-Za-z0-9\\s]/g, '');\n }\n\n if (trim) {\n slug = slug.trim()\n }\n\n // Replace spaces with replacement character, treating multiple consecutive\n // spaces as a single space.\n slug = slug.replace(/\\s+/g, replacement);\n\n if (options.lower) {\n slug = slug.toLowerCase()\n }\n\n return slug\n }\n\n replace.extend = function (customMap) {\n Object.assign(charMap, customMap)\n }\n\n return replace\n}))\n","import { Manifest } from \"@iiif/presentation-3\";\nimport { getValue } from \"@iiif/helpers\";\nimport slugify from \"slugify\";\nimport { EditorProject } from \"../ProjectContext.types\";\nimport { ManifestStorage } from \"../types/Storage\";\n\nfunction randomId() {\n return `${Math.random().toString(36).substr(2)}-${Date.now().toString(36)}`;\n}\n\nexport function projectFromManifest(manifest: Manifest, details: Partial<EditorProject> = {}): EditorProject {\n const name = getValue(manifest.label) || \"Untitled manifest\";\n\n return {\n id: `manifest-editor://project/${randomId()}`,\n filename: slugify(name, { lower: true }),\n name,\n metadata: {\n created: Date.now(),\n modified: Date.now(),\n },\n resource: {\n id: manifest.id,\n type: \"Manifest\",\n },\n publications: [],\n previews: [],\n settings: {},\n storage: {\n type: \"manifest-storage\",\n data: manifest,\n } as ManifestStorage,\n ...details,\n };\n}\n","import { EditorProject } from \"../ProjectContext.types\";\nimport slugify from \"slugify\";\n\nexport function ensureUniqueFilename(project: EditorProject, existing: EditorProject[]) {\n const filenames = existing.map((project) => project.filename);\n\n const name = (project.name || project.filename || \"Untitled project\").toLowerCase();\n\n if (project.filename && filenames.indexOf(project.filename) !== -1) {\n // duplicate.\n project.filename = undefined;\n }\n\n if (!project.filename) {\n let counter = 0;\n while (!project.filename) {\n // Create filename.\n const potentialFilename = `${slugify(name, { lower: true })}${counter ? ` (${counter})` : \"\"}`;\n if (filenames.indexOf(potentialFilename) === -1) {\n project.filename = potentialFilename;\n project.name = `${project.name} (${counter})`;\n break;\n }\n\n counter++;\n }\n }\n}\n","export function randomId() {\n return `${Math.random().toString(36).substr(2)}-${Date.now().toString(36)}`;\n}\n","import { Collection } from \"@iiif/presentation-3\";\nimport { EditorProject } from \"../ProjectContext.types\";\nimport { getValue } from \"@iiif/helpers\";\nimport slugify from \"slugify\";\nimport { CollectionStorage } from \"../types/Storage\";\nimport { randomId } from \"./random-id\";\n\nexport function projectFromCollection(collection: Collection, details: Partial<EditorProject> = {}): EditorProject {\n const name = getValue(collection.label) || \"Untitled collection\";\n\n return {\n id: `manifest-editor://project/${randomId()}`,\n filename: slugify(name, { lower: true }),\n name,\n metadata: {\n created: Date.now(),\n modified: Date.now(),\n },\n resource: {\n id: collection.id,\n type: \"Collection\",\n },\n publications: [],\n previews: [],\n settings: {},\n storage: {\n type: \"collection-storage\",\n data: collection,\n } as CollectionStorage,\n ...details,\n };\n}\n","import { Dispatch, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n EditorProject,\n ProjectActionsType,\n ProjectBackend,\n ProjectContext,\n ProjectsLoadingStatus,\n ProjectState,\n ProjectStorage,\n} from \"./ProjectContext.types\";\nimport { Publication } from \"./types/Publication\";\nimport { Storage } from \"./types/Storage\";\nimport shallowEqual from \"shallowequal\";\nimport { useDebounce } from \"tiny-use-debounce\";\nimport { projectFromManifest } from \"./helpers/project-from-manifest\";\nimport { convertPresentation2 } from \"@iiif/parser/presentation-2\";\nimport { useProjectContext } from \"./ProjectContext\";\nimport { ensureUniqueFilename } from \"./helpers/ensure-unique-filename\";\nimport { projectFromCollection } from \"./helpers/project-from-collection\";\nimport { ClientVault } from \"@manifest-editor/client-vault\";\nimport { randomId } from \"./helpers/random-id\";\nimport { Vault } from \"@iiif/helpers/vault\";\nimport { Preview, getManifestNomalized } from \"@manifest-editor/shell\";\n\nexport function useProjectActionsWithBackend(\n dispatch: Dispatch<ProjectActionsType>,\n backend: ProjectBackend,\n storage: ProjectStorage<any>\n) {\n async function createProject(payload: EditorProject) {\n const allProjects = await backend.getAllProjects(true);\n\n const project = { ...payload }; // avoid readonly payload.\n\n ensureUniqueFilename(project, allProjects);\n\n if (!storage.canCreate()) {\n throw new Error(\"Cannot create project with this storage backend\");\n }\n\n const backendStorage = await storage.create(project, project.storage.data);\n const createdProject = { ...project, storage: backendStorage };\n await backend.createProject(createdProject);\n\n dispatch({ type: \"createProject\", payload: createdProject });\n\n switchProject(project.id);\n }\n function deleteProject(payload: string) {\n if (backend.canDelete()) {\n dispatch({ type: \"deleteProject\", payload });\n\n backend.deleteProject(payload).then(() => {\n // @todo notification?\n console.log(\"Loader: project deleted\");\n });\n }\n }\n function switchProject(payload: string) {\n dispatch({ type: \"switchProject\", payload });\n backend.setLastProject(payload).then(() => {\n // probably nothing.\n });\n }\n function deselectProject(payload: string) {\n dispatch({ type: \"deselectProject\", payload });\n }\n function forkProject(payload: { id: string; name: string; filename?: string }) {\n dispatch({ type: \"forkProject\", payload });\n throw new Error(\"Not implemented yet\");\n }\n function setLoadingStatus(payload: ProjectsLoadingStatus) {\n dispatch({ type: \"setLoadingStatus\", payload });\n }\n function saveProject(project: EditorProject) {\n console.log(\"trying to save project...\");\n dispatch({ type: \"saveProject\", payload: project });\n\n Promise.all([\n //\n backend.updateProject(project),\n storage.saveStorage(project.storage),\n ]).then(() => {\n // @todo notification?\n console.log(\"Loader: project saved\");\n });\n }\n function updateDetails(payload: { name: string; filename?: string }) {\n dispatch({ type: \"updateDetails\", payload });\n }\n function createPublication(payload: Publication) {\n dispatch({ type: \"createPublication\", payload });\n }\n function updatePublication(payload: Publication) {\n dispatch({ type: \"updatePublication\", payload });\n }\n function removePublication(payload: string) {\n dispatch({ type: \"removePublication\", payload });\n }\n function updateSettings(payload: EditorProject[\"settings\"]) {\n dispatch({ type: \"updateSettings\", payload });\n }\n function updateThumbnail(payload: string) {\n dispatch({ type: \"updateThumbnail\", payload });\n }\n function updateStorage(payload: Storage) {\n dispatch({ type: \"updateStorage\", payload });\n }\n function load(payload: ProjectState) {\n dispatch({ type: \"load\", payload });\n }\n\n function setPreview(publication: Preview) {\n dispatch({ type: \"setPreview\", payload: publication });\n }\n function removePreview(id: string) {\n dispatch({ type: \"removePreview\", payload: id });\n }\n\n return useMemo(\n () => ({\n createProject,\n deleteProject,\n switchProject,\n deselectProject,\n forkProject,\n saveProject,\n setLoadingStatus,\n load,\n updateDetails,\n createPublication,\n updatePublication,\n removePublication,\n updateSettings,\n updateThumbnail,\n updateStorage,\n setPreview,\n removePreview,\n }),\n // Dispatch always stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n}\n\nexport function useProjectBackend({ actions, current }: ProjectContext, backend: ProjectBackend) {\n useEffect(() => {\n actions.setLoadingStatus({ loading: true, lastLoaded: 0, loaded: false });\n backend.getAllProjects().then(async (allProjects) => {\n const lastId = await backend.getLastProject();\n const lastValid = allProjects.find((s) => s.id === lastId);\n\n actions.load({\n allProjects: allProjects,\n current: lastValid || null,\n loadingStatus: {\n loaded: true,\n loading: false,\n lastLoaded: Date.now(),\n },\n });\n });\n // this is fine.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n}\n\nexport function useProjectLoader<T extends Storage = any>(\n { actions, current }: ProjectContext,\n storage: ProjectStorage<T>\n) {\n const currentRef = useRef<EditorProject | null>(null);\n const [ready, setIsReady] = useState(false);\n const [error, setError] = useState(\"\");\n const saveChanges = useCallback(() => {\n const project = currentRef.current;\n if (project) {\n storage.saveStorage(project.storage).then(() => {\n const newStorage = storage.getBackendStorage(project);\n if (!shallowEqual(newStorage, project.storage)) {\n actions.saveProject({\n ...project,\n storage: newStorage,\n });\n }\n });\n }\n }, [actions, storage]);\n const debounceSaveChanges = useDebounce(saveChanges, storage.saveInterval);\n const currentId = current?.id;\n\n useEffect(() => {\n currentRef.current = current;\n }, [current]);\n\n // The loader is responsible for creating Vault instances.\n // In the future this Vault instance could be remote and \"clever\"\n // Offering collaboration or similar features.\n const { vault, promise } = useMemo(() => {\n if (current) {\n const [vault, promise] = storage.createVaultInstance(current);\n return {\n vault,\n promise,\n };\n }\n\n return { vault: null, promise: null };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [storage, currentId]);\n\n useEffect(() => {\n const currentStorage = storage;\n const currentProject = current;\n const currentVault = vault;\n return () => {\n if (currentVault && currentProject) {\n currentStorage.closeVaultInstance(currentProject, currentVault);\n } else if (currentVault instanceof ClientVault) {\n (currentVault as ClientVault).ws.close();\n }\n };\n }, [storage, current, vault]);\n\n // If the vault takes some time to load from an external source we might have\n // some time to wait. This will listen to the \"Vault is ready\" promise.\n useEffect(() => {\n setIsReady(false);\n let cancelled = false;\n if (promise) {\n promise\n .then(() => {\n if (!cancelled) {\n setIsReady(true);\n }\n })\n .catch((e) => {\n setError(e.message);\n });\n }\n return () => {\n cancelled = true;\n };\n }, [promise]);\n\n // This will ensure that the changes are saved before reloading or navigating away.\n useEffect(() => {\n window.addEventListener(\"beforeunload\", saveChanges, false);\n\n return () => {\n window.removeEventListener(\"beforeunload\", saveChanges);\n };\n }, [saveChanges]);\n\n // When we unmount, or \"current\" is about to change, then\n // we call save once more.\n useEffect(() => {\n return () => {\n saveChanges();\n };\n }, [saveChanges, currentId]);\n\n // If the loader does not handle its own synchronisation through the Vault it provides, it can\n // let the application know and update the local copy instead. This callback is debounced\n // to ensure we don't call it too often.\n useEffect(() => {\n // @todo migrate this into the storage class.\n if (vault && storage.shouldUpdateWithVault()) {\n return vault.subscribe(debounceSaveChanges, true);\n }\n }, [debounceSaveChanges, storage, vault]);\n\n return {\n vault,\n ready,\n error,\n } as {\n vault: Vault | null;\n ready: boolean;\n error: string;\n };\n}\n\nexport function useProjectCreators() {\n const { actions } = useProjectContext();\n\n const createBlankManifest = useCallback(function createBlankManifest() {\n actions.createProject(\n projectFromManifest({\n \"@context\": \"http://iiif.io/api/presentation/3/context.json\",\n id: `https://example.org/${randomId()}`,\n type: \"Manifest\",\n label: {\n en: [\"Blank Manifest\"],\n },\n items: [],\n })\n );\n\n // Actions are stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const createProjectFromManifestId = useCallback(\n async function createProjectFromManifestId(id: string) {\n let full = await getManifestNomalized(id);\n if (full) {\n if ((full as any)[\"@id\"]) {\n full = convertPresentation2(full) as any;\n }\n if (full) {\n actions.createProject(projectFromManifest(full as any));\n }\n }\n },\n // Actions are stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n\n const createProjectFromCollectionId = useCallback(\n async function createProjectFromCollectionId(id: string) {\n let full = await getManifestNomalized(id);\n if (full) {\n if ((full as any)[\"@id\"]) {\n full = convertPresentation2(full) as any;\n }\n if (full) {\n actions.createProject(projectFromCollection(full as any));\n }\n }\n },\n // Actions are stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n\n const createProjectFromManifestJson = useCallback(\n async function createProjectFromManifestId(json: string) {\n let full = JSON.parse(json);\n if (full) {\n if ((full as any)[\"@id\"]) {\n full = convertPresentation2(full) as any;\n }\n if (full) {\n actions.createProject(projectFromManifest(full as any));\n }\n }\n },\n // Actions are stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n\n return {\n createProjectFromManifestJson,\n createProjectFromManifestId,\n createProjectFromCollectionId,\n createBlankManifest,\n };\n}\n","import { ProjectActionsType, ProjectsLoadingStatus, ProjectState } from \"./ProjectContext.types\";\nimport { produce } from \"immer\";\n\nexport const projectContextReducer = produce(function projectContextReducer(\n state: ProjectState,\n action: ProjectActionsType\n) {\n if (state.current) {\n switch (action.type) {\n // Single project actions\n case \"removePublication\":\n state.current.publications = state.current.publications.filter((p) => p.id !== action.payload);\n break;\n case \"saveProject\":\n state.current.metadata.modified = Date.now();\n break;\n case \"updateDetails\":\n state.current.name = action.payload.name;\n state.current.filename = action.payload.filename;\n break;\n case \"updateStorage\":\n state.current.storage = action.payload;\n break;\n case \"createPublication\": {\n if (!state.current.publications.find((s) => s.id === action.payload.id)) {\n state.current.publications.push(action.payload);\n }\n break;\n }\n case \"updateThumbnail\":\n state.current.thumbnail = action.payload;\n break;\n case \"updateSettings\":\n state.current.settings = action.payload;\n break;\n case \"updatePublication\": {\n const found = state.current.publications.find((s) => s.id === action.payload.id);\n if (found) {\n found.config = action.payload.config;\n }\n break;\n }\n case \"removePreview\": {\n const existing = state.current.previews?.findIndex((p) => p.id === action.payload);\n if (existing !== -1) {\n state.current.previews.splice(existing, 1);\n }\n break;\n }\n case \"setPreview\": {\n const existing = state.current.previews?.findIndex((p) => p.id === action.payload.id);\n if (existing !== -1) {\n state.current.previews.splice(existing, 1, action.payload);\n } else {\n state.current.previews.push(action.payload);\n }\n\n break;\n }\n }\n }\n switch (action.type) {\n case \"load\": {\n state.allProjects = action.payload.allProjects;\n state.current = action.payload.current;\n state.loadingStatus = action.payload.loadingStatus;\n break;\n }\n // Navigate project actions.\n case \"forkProject\":\n // This is probably all behind the scenes.\n break;\n case \"deleteProject\":\n state.allProjects = state.allProjects.filter((p) => p.id !== action.payload);\n if (state.current && state.current.id === action.payload) {\n state.current = null;\n }\n break;\n case \"deselectProject\":\n state.current = null;\n break;\n case \"createProject\":\n state.allProjects.push(action.payload);\n state.current = action.payload;\n break;\n case \"switchProject\":\n state.current = state.allProjects.find((p) => p.id === action.payload) || null;\n break;\n case \"setLoadingStatus\":\n state.loadingStatus = action.payload;\n break;\n }\n});\n\nexport function getDefaultProjectContextState(\n status: ProjectsLoadingStatus | null = {\n loading: false,\n loaded: true,\n lastLoaded: 0,\n }\n): ProjectState {\n return {\n allProjects: [],\n current: null,\n loadingStatus: status,\n };\n}\n","import { EditorProject, ProjectBackend } from \"../ProjectContext.types\";\nimport * as localforage from \"localforage\";\n\nexport class LocalStorageBackend implements ProjectBackend {\n namespace: string;\n saveInterval: number;\n storage: LocalForage;\n constructor(settings?: { namespace?: string }) {\n this.namespace = settings?.namespace || \"default-v1.1\";\n this.saveInterval = 5000;\n this.storage = localforage.createInstance({\n name: \"manifest-editor-projects\",\n });\n }\n\n async deleteProject(id: string): Promise<void> {\n await this.storage.removeItem(`${this.namespace}/projects/${id}`);\n }\n\n async createProject(project: EditorProject): Promise<void> {\n const index = await this.getProjectIndex();\n\n await this.storage.setItem(`${this.namespace}/projects/${project.id}`, JSON.stringify(project));\n\n if (index.indexOf(project.id) === -1) {\n index.push(project.id);\n await this.saveProjectIndex(index);\n }\n }\n\n canDelete() {\n return true;\n }\n\n async getAllProjects(): Promise<EditorProject[]> {\n try {\n const index = await this.getProjectIndex();\n const projects = [];\n for (const item of index) {\n if (item === \"_index\") {\n continue;\n }\n const loaded = await this.storage.getItem<any>(`${this.namespace}/projects/${item}`);\n if (loaded) {\n try {\n projects.push(JSON.parse(loaded));\n } catch (e) {\n // Silent on individual items?\n }\n }\n }\n\n return projects;\n } catch (e) {\n console.error(\"Error loading from localstorage\", e);\n return [];\n }\n }\n\n async getLastProject(): Promise<string | null> {\n return this.storage.getItem(`${this.namespace}/last`);\n }\n\n async setLastProject(id: string): Promise<void> {\n await this.storage.setItem(`${this.namespace}/last`, id);\n }\n\n async updateProject(project: EditorProject): Promise<void> {\n await this.storage.setItem(`${this.namespace}/projects/${project.id}`, JSON.stringify(project));\n }\n\n private async saveProjectIndex(index: string[]): Promise<void> {\n await this.storage.setItem(`${this.namespace}/_index`, JSON.stringify(index));\n }\n\n private async getProjectIndex(): Promise<string[]> {\n const json = await this.storage.getItem<string>(`${this.namespace}/_index`);\n if (!json) {\n return [];\n }\n const index = JSON.parse(json);\n\n if (!Array.isArray(index)) {\n return [];\n }\n\n return index;\n }\n}\n","import { Vault } from \"@iiif/helpers/vault\";\nimport { EditorProject, ProjectStorage } from \"../ProjectContext.types\";\nimport { Collection, Manifest, Reference } from \"@iiif/presentation-3\";\nimport { CollectionStorage, ManifestStorage, Storage } from \"../types/Storage\";\n\nexport abstract class AbstractVaultLoader<T extends Storage>\n implements ProjectStorage<ManifestStorage | CollectionStorage, Manifest | Collection, T>\n{\n abstract type: string;\n vaults: Record<string, Vault | null> = {};\n saveInterval: number;\n\n protected constructor(config: Partial<{ saveInterval: number }> = {}) {\n this.saveInterval = config.saveInterval || 5000;\n }\n\n shouldUpdateWithVault() {\n return true;\n }\n\n canCreate() {\n return true;\n }\n\n canDelete() {\n return true;\n }\n\n abstract create(project: EditorProject, data: Manifest | Collection): Promise<T>;\n\n createVaultInstance(project: EditorProject): [Vault, Promise<void>] {\n const foundVault = this.vaults[project.storage.data.key];\n if (foundVault) {\n return [foundVault, Promise.resolve()];\n }\n\n const vault = new Vault();\n\n const promise = async () => {\n const data = await this.getStorage(project.storage as any);\n await vault.loadManifest(project.resource.id, JSON.parse(JSON.stringify(data?.data)));\n this.vaults[project.storage.data.key] = vault;\n };\n\n return [vault, promise() as Promise<void>];\n }\n\n closeVaultInstance(project: EditorProject, vault: Vault): void {\n // No-op\n }\n\n async saveStorage(storage: T): Promise<void> {\n const vault = this.vaults[storage.data.key];\n const manifestRef: Reference<\"Manifest\" | \"Collection\"> = {\n id: storage.data.id,\n type: storage.data.type,\n };\n\n // There will only be something to save if there is active vault.\n if (vault) {\n const data = vault.toPresentation3<Manifest | Collection>(manifestRef);\n\n const stored: ManifestStorage | CollectionStorage =\n data.type === \"Collection\"\n ? ({\n type: \"collection-storage\",\n data,\n } as CollectionStorage)\n : ({\n type: \"manifest-storage\",\n data,\n } as ManifestStorage);\n\n await this.saveStorageData(stored, storage);\n }\n }\n\n abstract getStorage(storage: T): Promise<CollectionStorage | ManifestStorage | null>;\n\n abstract saveStorageData(manifest: CollectionStorage | ManifestStorage, storage: T): void | Promise<void>;\n\n abstract deleteStorage(storage: T): Promise<void>;\n\n abstract getBackendStorage(project: EditorProject): T;\n}\n","import { EditorProject } from \"../ProjectContext.types\";\nimport { Vault } from \"@iiif/helpers/vault\";\nimport { Collection, Manifest } from \"@iiif/presentation-3\";\nimport { ResourceKeyedStorage, ManifestStorage, CollectionStorage } from \"../types/Storage\";\nimport { AbstractVaultLoader } from \"./AbstractVaultLoader\";\nimport invariant from \"tiny-invariant\";\nimport localforage from \"localforage\";\nimport { randomId } from \"../helpers/random-id\";\n\nexport class LocalStorageLoader extends AbstractVaultLoader<ResourceKeyedStorage> {\n type = \"local-storage\";\n namespace: string;\n storage: LocalForage;\n\n vaults: Record<string, Vault | null> = {};\n\n constructor(settings?: { namespace?: string }) {\n super({ saveInterval: 5000 });\n this.namespace = settings?.namespace || \"default\";\n this.storage = localforage.createInstance({\n name: \"local-storage-resource-loader\",\n });\n }\n\n shouldUpdateWithVault() {\n return true;\n }\n\n async create(project: EditorProject, data: Manifest | Collection): Promise<ResourceKeyedStorage> {\n const key = randomId();\n\n await localStorage.setItem(`${this.namespace}/store/${key}`, JSON.stringify(data));\n\n return {\n type: \"resource-keyed-storage\",\n data: {\n id: data.id,\n type: data.type,\n key,\n },\n };\n }\n\n async getStorage(storage: ResourceKeyedStorage): Promise<CollectionStorage | ManifestStorage | null> {\n try {\n const item = await localStorage.getItem(`${this.namespace}/store/${storage.data.key}`);\n const manifest = item ? (JSON.parse(item) as any) : null;\n\n invariant(manifest, \"Resource not found\");\n\n if (manifest.type === \"Collection\") {\n return {\n type: \"collection-storage\",\n data: manifest,\n };\n }\n\n return {\n type: \"manifest-storage\",\n data: manifest,\n };\n } catch (e) {\n return null;\n }\n }\n\n async saveStorageData(\n manifestStorage: ManifestStorage | CollectionStorage,\n storage: ResourceKeyedStorage\n ): Promise<void> {\n await localStorage.setItem(`${this.namespace}/store/${storage.data.key}`, JSON.stringify(manifestStorage.data));\n }\n\n async deleteStorage(storage: ResourceKeyedStorage): Promise<void> {\n this.vaults[storage.data.key] = null;\n await localStorage.removeItem(`${this.namespace}/store/${storage.data.key}`);\n }\n\n getBackendStorage(project: EditorProject): ResourceKeyedStorage {\n // This will never change after creation, but other adapters might?\n return project.storage as ResourceKeyedStorage;\n }\n}\n","import { useTranslations } from \"@manifest-editor/i18n\";\nimport { ReactNode, useEffect, useMemo, useReducer } from \"react\";\nimport { ProjectReactContext, ProjectLoadingReactContext } from \"./ProjectContext\";\nimport { useApps, AppResourceProvider, AppResourceInstanceProvider } from \"@manifest-editor/shell\";\nimport { useProjectActionsWithBackend, useProjectLoader, useProjectBackend } from \"./ProjectContext.hooks\";\nimport { projectContextReducer, getDefaultProjectContextState } from \"./ProjectContext.reducer\";\nimport { ProjectBackend, ProjectState, ProjectContext } from \"./ProjectContext.types\";\nimport { LocalStorageBackend } from \"./backend/LocalStorageBackend\";\nimport { AbstractVaultLoader } from \"./storage/AbstractVaultLoader\";\nimport { LocalStorageLoader } from \"./storage/LocalStorageLoader\";\nimport { VaultProvider } from \"react-iiif-vault\";\n\nexport interface ProjectProviderProps {\n children: ReactNode;\n defaultApp?: string;\n // Storage\n storage?: AbstractVaultLoader<any>;\n backend?: ProjectBackend;\n initialState?: () => ProjectState;\n}\n\nexport function ProjectProvider(props: ProjectProviderProps) {\n const t = useTranslations(\"projects\");\n const { currentApp, changeApp } = useApps();\n // @todo this may be configuration or something else.\n // The interface for the loader will definitely change over time.\n const backend = useMemo(() => props.backend || new LocalStorageBackend(), []);\n const storage = useMemo(() => props.storage || new LocalStorageLoader(), []);\n const [state, dispatch] = useReducer(\n projectContextReducer,\n undefined,\n props.initialState || getDefaultProjectContextState\n );\n const actions = useProjectActionsWithBackend(dispatch, backend, storage);\n const context: ProjectContext = useMemo(\n () => ({ actions, canDelete: backend.canDelete(), ...state }),\n [actions, backend, state]\n );\n const { vault, ready, error } = useProjectLoader(context, storage);\n const manifestOrCollection = context.current?.resource;\n\n const loadingStatus = useMemo(() => {\n return { isLoading: !ready, isError: !!error, error };\n }, [ready, error]);\n\n useProjectBackend(context, backend);\n\n useEffect(() => {\n if (\n state.loadingStatus &&\n state.loadingStatus.loaded &&\n ready &&\n (!vault || !manifestOrCollection) &&\n currentApp?.id !== (props.defaultApp || \"splash\")\n ) {\n changeApp({ id: props.defaultApp || \"splash\" });\n }\n }, []);\n\n if ((state.loadingStatus && state.loadingStatus.loading) || (context.current && !manifestOrCollection)) {\n return <output style={{ display: \"block\" }}>{t(\"status.loading\")}</output>;\n }\n\n return (\n <ProjectLoadingReactContext.Provider value={loadingStatus}>\n <ProjectReactContext.Provider value={context}>\n <VaultProvider vault={vault || undefined} key={state.current?.id}>\n <AppResourceInstanceProvider id={context.current?.id}>\n <AppResourceProvider resource={manifestOrCollection}>{props.children}</AppResourceProvider>\n </AppResourceInstanceProvider>\n </VaultProvider>\n </ProjectReactContext.Provider>\n </ProjectLoadingReactContext.Provider>\n );\n}\n","export const MenuIcon: React.FC = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1rem\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"#000000\">\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z\" />\n </svg>\n);\n","import styled from \"styled-components\";\n\nexport const ButtonReset = styled.button`\n border: none;\n outline: none;\n background-color: transparent;\n margin: 0;\n padding: 0;\n font-size: inherit;\n color: inherit;\n cursor: pointer;\n &:hover {\n color: inherit;\n }\n`;\n\nexport const Button = styled.button<{ $active?: boolean }>`\n padding: 0.5rem 1rem;\n color: ${(props: any) => props.theme.color.main || \"none\"};\n background-color: ${(props: any) => props.theme.color.white || \"white\"};\n border-radius: inherit;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n font-size: 0.85em;\n :disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n\n &:hover {\n background: #eee;\n }\n`;\n\nexport const SmallButton = styled(Button as any)`\n padding: 0.25em ${(props: any) => props.theme.padding.xs || \"0.4em\"};\n height: unset;\n background: none;\n`;\n\nexport const SecondaryButton = styled(Button as any)`\n {\n padding: 0 ${(props: any) => props.theme.padding.medium || \"1rem\"};\n color: ${(props: any) => props.theme.color.main || \"#B84C74;\"};\n background-color: ${(props: any) => props.theme.color.white || \"white\"};\n border: 1px solid ${(props: any) => props.theme.color.main || \"#B84C74;\"};\n border-radius: 0.25rem;\n cursor: pointer;\n height: 2rem;\n display: flex;\n align-items: center;\n white-space: nowrap;\n font-size: 0.75rem;\n\n :disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n }\n`;\n\nexport const CalltoButton = styled(Button as any)`\n padding: 0 ${(props: any) => props.theme.padding.medium || \"1rem\"};\n color: ${(props: any) => props.theme.color.white || \"white\"};\n background-color: ${(props: any) => props.theme.color.main || \"#B84C74;\"};\n border: 1px solid #eee;\n border-radius: 0.25rem;\n cursor: pointer;\n justify-content: center;\n display: flex;\n align-items: center;\n &:hover {\n background-color: ${(props: any) => props.theme.color.mainHover || \"#B84C74;\"};\n }\n`;\n\nexport const ButtonGroup = styled.div<{ $right?: boolean }>`\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: ${(props) => (props.$right ? \"flex-end\" : \"flex-start\")};\n`;\n","import styled, { css } from \"styled-components\";\nimport { Button } from \"./Button\";\n\nexport const Dropdown = styled.div`\n position: relative;\n display: inline-block;\n`;\n\nexport const DropdownContent = styled.div`\n display: flex;\n flex-direction: column;\n position: absolute;\n background-color: ${(props: any) => props.theme.color.white || \"white\"};\n color: ${(props: any) => props.theme.color.black || \" black\"};\n font-size: 0.75rem;\n min-width: 160px;\n box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);\n z-index: 150;\n button {\n &:hover {\n background-color: ${(props: any) => props.theme.color.lightgrey || \"lightgrey\"};\n }\n }\n`;\n\nexport const DropdownItem = styled.button<{ $active?: boolean }>`\n padding: 0 ${(props: any) => props.theme.padding.small || \"0.5rem\"};\n color: ${(props: any) => props.theme.color.main || \"none\"};\n background-color: ${(props: any) => props.theme.color.white || \"white\"};\n border-radius: 0;\n border: none;\n cursor: pointer;\n display: flex;\n padding: 0.65em 1em;\n align-items: center;\n :disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n\n &:hover {\n background-color: ${(props: any) => props.theme.color.lightgrey || \"lightgrey\"};\n }\n\n ${(props) =>\n props.$active &&\n css`\n background: #b84c74;\n color: #fff;\n &:hover {\n background: #b84c74;\n color: #fff;\n }\n `}\n`;\n\nexport const DropdownMenu = styled.div<{ $open?: boolean; $center?: boolean }>`\n display: none;\n flex-direction: column;\n position: absolute;\n background: #fff;\n color: ${(props: any) => props.theme.color.black || \" black\"};\n font-size: 0.75rem;\n min-width: 190px;\n top: calc(100% + 0.5em);\n box-shadow:\n 0 4px 15px 0 rgba(0, 0, 0, 0.18),\n 0 0px 0px 1px rgba(0, 0, 0, 0.15),\n inset 0 0 0 1px rgba(255, 255, 255, 0.2);\n border-radius: 3px;\n z-index: 150;\n overflow: hidden;\n padding-bottom: 3px;\n\n ${Button} {\n &:hover {\n background-color: ${(props: any) => props.theme.color.lightgrey || \"lightgrey\"};\n }\n }\n\n ${(props) =>\n props.$open &&\n css`\n display: flex;\n `}\n`;\n\nexport const DropdownLabel = styled.div`\n color: #999;\n text-transform: uppercase;\n font-weight: 600;\n padding: 0.7em;\n font-size: 0.875em;\n`;\n\nexport const DropdownDivider = styled.div`\n height: 1px;\n margin: 0 0.5em;\n background: #eee;\n`;\n","import * as m from 'react';module.exports = { ...m };","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst react_1 = require(\"react\");\nfunction useDropdownMenu(itemCount, options) {\n const [isOpen, setIsOpen] = (0, react_1.useState)(false);\n const currentFocusIndex = (0, react_1.useRef)(null);\n const firstRun = (0, react_1.useRef)(true);\n const clickedOpen = (0, react_1.useRef)(false);\n const buttonRef = (0, react_1.useRef)(null);\n const itemRefs = (0, react_1.useMemo)(() => Array.from({ length: itemCount }, () => (0, react_1.createRef)()), [itemCount]);\n const isKeyboardEvent = (e) => e.key !== undefined;\n const moveFocus = (itemIndex) => {\n var _a;\n currentFocusIndex.current = itemIndex;\n (_a = itemRefs[itemIndex].current) === null || _a === void 0 ? void 0 : _a.focus();\n };\n (0, react_1.useEffect)(() => {\n if (firstRun.current) {\n firstRun.current = false;\n return;\n }\n if (isOpen && (!clickedOpen.current || (options === null || options === void 0 ? void 0 : options.focusFirstItemOnClick))) {\n moveFocus(0);\n }\n else if (!isOpen) {\n clickedOpen.current = false;\n }\n }, [isOpen]);\n (0, react_1.useEffect)(() => {\n if (!isOpen) {\n return;\n }\n const removalTracker = {\n removed: false,\n };\n const handleEveryClick = (event) => {\n setTimeout(() => {\n if (!(event.target instanceof Element)) {\n return;\n }\n if (event.target.closest('[role=\"menu\"]') instanceof Element) {\n return;\n }\n setIsOpen(false);\n }, 10);\n };\n setTimeout(() => {\n if (removalTracker.removed) {\n return;\n }\n document.addEventListener('click', handleEveryClick);\n }, 1);\n return () => {\n removalTracker.removed = true;\n document.removeEventListener('click', handleEveryClick);\n };\n }, [isOpen]);\n (0, react_1.useEffect)(() => {\n const disableArrowScroll = (event) => {\n if (isOpen && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {\n event.preventDefault();\n }\n };\n document.addEventListener('keydown', disableArrowScroll);\n return () => document.removeEventListener('keydown', disableArrowScroll);\n }, [isOpen]);\n const buttonListener = (e) => {\n if (isKeyboardEvent(e)) {\n const { key } = e;\n if (!['Enter', ' ', 'Tab', 'ArrowDown', 'Escape'].includes(key)) {\n return;\n }\n if ((key === 'Tab' || key === 'ArrowDown') && clickedOpen.current && isOpen) {\n e.preventDefault();\n moveFocus(0);\n }\n if (key === 'Enter' || key === ' ') {\n e.preventDefault();\n setIsOpen(true);\n }\n if (key === 'Escape') {\n e.preventDefault();\n setIsOpen(false);\n }\n }\n else {\n if (!(options === null || options === void 0 ? void 0 : options.focusFirstItemOnClick)) {\n clickedOpen.current = !isOpen;\n }\n setIsOpen(!isOpen);\n }\n };\n const itemListener = (e) => {\n var _a;\n const { key } = e;\n if (['Tab', 'Shift', 'Enter', 'Escape', 'ArrowUp', 'ArrowDown', ' '].includes(key)) {\n let newFocusIndex = currentFocusIndex.current;\n if (key === 'Escape') {\n setIsOpen(false);\n (_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.focus();\n return;\n }\n else if (key === 'Tab') {\n setIsOpen(false);\n return;\n }\n else if (key === 'Enter' || key === ' ') {\n if (!e.currentTarget.href) {\n e.currentTarget.click();\n }\n setIsOpen(false);\n return;\n }\n if (newFocusIndex !== null) {\n if (key === 'ArrowUp') {\n newFocusIndex -= 1;\n }\n else if (key === 'ArrowDown') {\n newFocusIndex += 1;\n }\n if (newFocusIndex > itemRefs.length - 1) {\n newFocusIndex = 0;\n }\n else if (newFocusIndex < 0) {\n newFocusIndex = itemRefs.length - 1;\n }\n }\n if (newFocusIndex !== null) {\n moveFocus(newFocusIndex);\n }\n return;\n }\n if (/[a-zA-Z0-9./<>?;:\"'`!@#$%^&*()\\\\[\\]{}_+=|\\\\-~,]/.test(key)) {\n const index = itemRefs.findIndex((ref) => {\n var _a, _b, _c, _d, _e, _f;\n return ((_b = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.innerText) === null || _b === void 0 ? void 0 : _b.toLowerCase().startsWith(key.toLowerCase())) ||\n ((_d = (_c = ref.current) === null || _c === void 0 ? void 0 : _c.textContent) === null || _d === void 0 ? void 0 : _d.toLowerCase().startsWith(key.toLowerCase())) ||\n ((_f = (_e = ref.current) === null || _e === void 0 ? void 0 : _e.getAttribute('aria-label')) === null || _f === void 0 ? void 0 : _f.toLowerCase().startsWith(key.toLowerCase()));\n });\n if (index !== -1) {\n moveFocus(index);\n }\n }\n };\n const buttonProps = {\n onKeyDown: buttonListener,\n onClick: buttonListener,\n tabIndex: 0,\n ref: buttonRef,\n role: 'button',\n 'aria-haspopup': true,\n 'aria-expanded': isOpen,\n };\n const itemProps = Array.from({ length: itemCount }, (_ignore, index) => ({\n onKeyDown: itemListener,\n tabIndex: -1,\n role: 'menuitem',\n ref: itemRefs[index],\n }));\n return { buttonProps, itemProps, isOpen, setIsOpen, moveFocus };\n}\nexports.default = useDropdownMenu;\n","import rawUseDropdownMenu from \"react-accessible-dropdown-menu-hook\";\n\nconst candidate: unknown = rawUseDropdownMenu;\n\nconst useDropdownMenu = (\n typeof candidate === \"object\" && candidate !== null && \"default\" in candidate ? candidate.default : rawUseDropdownMenu\n) as typeof rawUseDropdownMenu;\n\nexport default useDropdownMenu;\n","import { useEditorI18n, useTranslations, type MessageReference } from \"@manifest-editor/i18n\";\nimport { MenuIcon } from \"@manifest-editor/ui/icons/MenuIcon\";\nimport { Dropdown, DropdownDivider, DropdownLabel, DropdownMenu } from \"@manifest-editor/ui/atoms/Dropdown\";\nimport { Button } from \"@manifest-editor/ui/atoms/Button\";\nimport { useLocalStorage } from \"@manifest-editor/shell\";\nimport useDropdownMenu from \"../use-dropdown-menu\";\nimport { useProjectContext } from \"../ProjectContext\";\nimport { MappedApp, useApps } from \"@manifest-editor/shell\";\nimport styled from \"styled-components\";\n\nexport const IconButton = styled.button`\n height: 1.75em;\n width: 1.75em;\n background: #e9e9e9;\n border-radius: 3px;\n display: flex;\n text-align: center;\n align-items: center;\n font-size: 1.1em;\n border: none;\n justify-content: center;\n\n &:focus {\n background: #e94581;\n color: #fff;\n svg {\n fill: #fff;\n }\n }\n`;\n\nexport function AppMenu(props: { hideMenu?: boolean }) {\n const t = useTranslations(\"projects\");\n const { resolveMessage } = useEditorI18n();\n const { current: currentProject } = useProjectContext();\n const [isMenuHidden, setIsMenuHidden] = useLocalStorage(\"menu-hidden\");\n const { apps, changeApp } = useApps();\n const type = currentProject?.resource.type;\n const filteredApps = Object.values(apps).filter((app: MappedApp) => {\n if (app.metadata.project && app.metadata.projectType !== type) {\n return false;\n }\n\n if (!currentProject && app.metadata.project) {\n return false;\n }\n\n if (app.metadata.type === \"launcher\") {\n return false;\n }\n\n // @todo ignore\n // if (app.metadata.dev && import.meta.env.PROD) {\n // try {\n // if (import.meta.env.PULL_REQUEST === \"true\") {\n // return true;\n // }\n // } catch (e) {\n // return false;\n // }\n\n // return false;\n // }\n\n return true;\n });\n const { itemProps, buttonProps, isOpen, setIsOpen } = useDropdownMenu(filteredApps.length + 1);\n\n return (\n <Dropdown>\n <IconButton {...buttonProps} aria-label={t(\"menu.toggle\")}>\n <MenuIcon />\n </IconButton>\n <DropdownMenu $open={isOpen}>\n <DropdownLabel>{t(\"menu.apps\")}</DropdownLabel>\n <DropdownDivider />\n {filteredApps.map((app, key) => (\n <Button\n key={app.metadata.id}\n {...(itemProps[key] as any)}\n onClick={() => {\n changeApp({ id: app.metadata.id });\n setIsOpen(false);\n }}\n >\n {resolveMessage(\n (app.metadata as MappedApp[\"metadata\"] & { titleMessage?: MessageReference }).titleMessage,\n app.metadata.title\n )}\n </Button>\n ))}\n {props.hideMenu ? null : (\n <>\n <DropdownLabel>{t(\"menu.quickSettings\")}</DropdownLabel>\n <DropdownDivider />\n <Button {...(itemProps[filteredApps.length + 0] as any)} onClick={() => setIsMenuHidden(!isMenuHidden)}>\n {t(isMenuHidden ? \"menu.show\" : \"menu.hide\")}\n </Button>\n </>\n )}\n </DropdownMenu>\n </Dropdown>\n );\n}\n","import { useTranslations } from \"@manifest-editor/i18n\";\nimport { FormEvent, useRef, useState } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport styled from \"styled-components\";\nimport { useProjectContext } from \"../ProjectContext\";\nimport { SmallButton } from \"@manifest-editor/ui/atoms/Button\";\n\nexport const Draft = styled.div`\n display: flex;\n flex-direction: row;\n flex: 1;\n padding: 0.28em;\n padding-left: 0.5em;\n align-items: center;\n overflow: hidden;\n`;\n\nexport const DraftsText = styled.div`\n color: #828282;\n padding-right: 1em;\n`;\n\nexport const DraftTitleEdit = styled.form`\n margin: 0;\n padding: 0;\n display: flex;\n flex: 1;\n`;\n\nexport const DraftTitleEditInput = styled.input`\n font-size: 1em;\n flex: 1;\n border: 1px solid #999;\n padding: 0.2em;\n margin: -0.2em 0;\n`;\n\nexport const DraftTitleEditButton = styled(SmallButton as any)`\n font-size: 1em;\n display: inline-block;\n`;\n\nexport const DraftTitle = styled.div`\n border: 0;\n background: none;\n padding: 0;\n font: inherit;\n text-align: start;\n cursor: pointer;\n color: #333;\n flex: 1;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n`;\n\nexport function DraftTitleEditor() {\n const t = useTranslations(\"projects\");\n const common = useTranslations(\"common\");\n const input = useRef<HTMLInputElement>(null);\n const { actions, current } = useProjectContext();\n const [editingTitle, setIsEditingTitle] = useState(false);\n\n return (\n <Draft>\n <DraftsText>{t(\"draft.list\")}</DraftsText>\n {current ? (\n <>\n {editingTitle ? (\n <DraftTitleEdit\n onSubmit={(e: FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const form = new FormData(e.target as any);\n const data = Object.fromEntries(form.entries());\n actions.updateDetails(data as any);\n setIsEditingTitle(false);\n }}\n >\n <DraftTitleEditInput ref={input} aria-label={t(\"draft.title\")} defaultValue={current.name} name=\"name\" />\n <DraftTitleEditButton type=\"submit\">{common(\"actions.save\")}</DraftTitleEditButton>\n </DraftTitleEdit>\n ) : (\n <DraftTitle\n as=\"button\"\n type=\"button\"\n aria-label={t(\"draft.edit\", { name: current.name || t(\"draft.untitledProject\") })}\n onClick={() => {\n flushSync(() => {\n setIsEditingTitle(true);\n });\n input.current?.focus();\n }}\n >\n {current.name || t(\"draft.untitledProject\")}\n </DraftTitle>\n )}\n </>\n ) : null}\n </Draft>\n );\n}\n"],"x_google_ignoreList":[0,2,3,18],"mappings":"8+CACI,GAAS,mBACb,SAAS,EAAU,EAAW,EAAS,CAC/B,MAIA,MAAU,MAAM,EAAM,CAK9B,CCRA,MAAa,EAAsB,EAAqC,IAAI,EAC/D,EAA6B,EAAwE,CAChH,MAAO,IAAA,GACP,QAAS,GACT,UAAW,EACb,CAAC,EAED,SAAgB,IAAoB,CAClC,OAAO,EAAW,CAA0B,CAC9C,CAEA,SAAgB,GAAoC,CAClD,IAAM,EAAM,EAAW,CAAmB,EAI1C,OAFA,EAAU,EAAK,sEAAsE,EAE9E,CACT,CAEA,SAAgB,IAAmC,CACjD,IAAM,EAAU,EAAkB,CAAC,CAAC,QAIpC,OAFA,EAAU,EAAS,oBAAoB,EAEhC,CACT,CAEA,SAAgB,IAAkD,CAGhE,OAFgB,EAAkB,CAAC,CAAC,SAElB,IACpB,mBCjCA,EAAO,QAAU,SAAsB,EAAM,EAAM,EAAS,EAAgB,CAC1E,IAAI,EAAM,EAAU,EAAQ,KAAK,EAAgB,EAAM,CAAI,EAAI,IAAK,GAEpE,GAAI,IAAQ,IAAK,GACf,MAAO,CAAC,CAAC,EAGX,GAAI,IAAS,EACX,MAAO,GAGT,GAAI,OAAO,GAAS,UAAY,CAAC,GAAQ,OAAO,GAAS,UAAY,CAAC,EACpE,MAAO,GAGT,IAAI,EAAQ,OAAO,KAAK,CAAI,EACxB,EAAQ,OAAO,KAAK,CAAI,EAE5B,GAAI,EAAM,SAAW,EAAM,OACzB,MAAO,GAMT,IAAK,IAHD,EAAkB,OAAO,UAAU,eAAe,KAAK,CAAI,EAGtD,EAAM,EAAG,EAAM,EAAM,OAAQ,IAAO,CAC3C,IAAI,EAAM,EAAM,GAEhB,GAAI,CAAC,EAAgB,CAAG,EACtB,MAAO,GAGT,IAAI,EAAS,EAAK,GACd,EAAS,EAAK,GAIlB,GAFA,EAAM,EAAU,EAAQ,KAAK,EAAgB,EAAQ,EAAQ,CAAG,EAAI,IAAK,GAErE,IAAQ,IAAU,IAAQ,IAAK,IAAK,IAAW,EACjD,MAAO,EAEX,CAEA,MAAO,EACT,oBC5CE,SAAU,EAAM,EAAM,EAAS,CAC3B,OAAO,GAAY,UACrB,EAAO,QAAU,EAAQ,EACzB,EAAO,QAAQ,QAAa,EAAQ,GAG7B,OAAO,QAAW,YAAc,OAAO,IAC9C,OAAO,CAAO,EAGd,EAAK,GAAQ,EAAQ,CAEzB,EAAA,CAAE,UAAA,EAAiB,UAAY,CAC7B,IAAI,EAAU,KAAK,MAAM,o1KAAm2K,EACx3K,EAAU,KAAK,MAAM,smCAAsmC,EAE/nC,SAAS,EAAS,EAAQ,EAAS,CACjC,GAAI,OAAO,GAAW,SACpB,MAAU,MAAM,mCAAmC,EAGrD,EAAW,OAAO,GAAY,SAC1B,CAAC,YAAa,CAAO,EACrB,GAAW,CAAC,EAEhB,IAAI,EAAS,EAAQ,EAAQ,SAAW,CAAC,EAErC,EAAc,EAAQ,cAAgB,IAAA,GAAY,IAAM,EAAQ,YAEhE,EAAO,EAAQ,OAAS,IAAA,IAAmB,EAAQ,KAEnD,EAAO,EAAO,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC,CAEpC,OAAO,SAAU,EAAQ,EAAI,CAC5B,IAAI,EAAa,EAAO,GAIxB,OAHI,IAAe,IAAA,KAAW,EAAa,EAAQ,IAC/C,IAAe,IAAA,KAAW,EAAa,GACvC,IAAe,IAAa,EAAa,KACtC,EAAS,EAEb,QAAQ,EAAQ,QAAU,2BAA4B,EAAE,CAC7D,EAAG,EAAE,EAkBP,OAhBI,EAAQ,SACV,EAAO,EAAK,QAAQ,kBAAmB,EAAE,GAGvC,IACF,EAAO,EAAK,KAAK,GAKnB,EAAO,EAAK,QAAQ,OAAQ,CAAW,EAEnC,EAAQ,QACV,EAAO,EAAK,YAAY,GAGnB,CACT,CAMA,MAJA,GAAQ,OAAS,SAAU,EAAW,CACpC,OAAO,OAAO,EAAS,CAAS,CAClC,EAEO,CACT,CAAC,8BC9DD,SAASA,IAAW,CAClB,MAAO,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,GAC1E,CAEA,SAAgB,EAAoB,EAAoB,EAAkC,CAAC,EAAkB,CAC3G,IAAM,EAAO,EAAS,EAAS,KAAK,GAAK,oBAEzC,MAAO,CACL,GAAI,6BAA6BA,GAAS,IAC1C,UAAA,EAAUC,EAAAA,QAAAA,CAAQ,EAAM,CAAE,MAAO,EAAK,CAAC,EACvC,OACA,SAAU,CACR,QAAS,KAAK,IAAI,EAClB,SAAU,KAAK,IAAI,CACrB,EACA,SAAU,CACR,GAAI,EAAS,GACb,KAAM,UACR,EACA,aAAc,CAAC,EACf,SAAU,CAAC,EACX,SAAU,CAAC,EACX,QAAS,CACP,KAAM,mBACN,KAAM,CACR,EACA,GAAG,CACL,CACF,CC/BA,SAAgB,GAAqB,EAAwB,EAA2B,CACtF,IAAM,EAAY,EAAS,IAAK,GAAY,EAAQ,QAAQ,EAEtD,GAAQ,EAAQ,MAAQ,EAAQ,UAAY,mBAAA,CAAoB,YAAY,EAOlF,GALI,EAAQ,UAAY,EAAU,QAAQ,EAAQ,QAAQ,IAAM,KAE9D,EAAQ,SAAW,IAAA,IAGjB,CAAC,EAAQ,SAAU,CACrB,IAAI,EAAU,EACd,KAAO,CAAC,EAAQ,UAAU,CAExB,IAAM,EAAoB,IAAA,EAAGC,EAAAA,QAAAA,CAAQ,EAAM,CAAE,MAAO,EAAK,CAAC,IAAI,EAAU,KAAK,EAAQ,GAAK,KAC1F,GAAI,EAAU,QAAQ,CAAiB,IAAM,GAAI,CAC/C,EAAQ,SAAW,EACnB,EAAQ,KAAO,GAAG,EAAQ,KAAK,IAAI,EAAQ,GAC3C,KACF,CAEA,GACF,CACF,CACF,CC3BA,SAAgB,GAAW,CACzB,MAAO,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,GAC1E,CCKA,SAAgB,GAAsB,EAAwB,EAAkC,CAAC,EAAkB,CACjH,IAAM,EAAO,EAAS,EAAW,KAAK,GAAK,sBAE3C,MAAO,CACL,GAAI,6BAA6B,EAAS,IAC1C,UAAA,EAAUC,EAAAA,QAAAA,CAAQ,EAAM,CAAE,MAAO,EAAK,CAAC,EACvC,OACA,SAAU,CACR,QAAS,KAAK,IAAI,EAClB,SAAU,KAAK,IAAI,CACrB,EACA,SAAU,CACR,GAAI,EAAW,GACf,KAAM,YACR,EACA,aAAc,CAAC,EACf,SAAU,CAAC,EACX,SAAU,CAAC,EACX,QAAS,CACP,KAAM,qBACN,KAAM,CACR,EACA,GAAG,CACL,CACF,CCPA,SAAgB,EACd,EACA,EACA,EACA,CACA,eAAe,EAAc,EAAwB,CACnD,IAAM,EAAc,MAAM,EAAQ,eAAe,EAAI,EAE/C,EAAU,CAAE,GAAG,CAAQ,EAI7B,GAFA,GAAqB,EAAS,CAAW,EAErC,CAAC,EAAQ,UAAU,EACrB,MAAU,MAAM,iDAAiD,EAGnE,IAAM,EAAiB,MAAM,EAAQ,OAAO,EAAS,EAAQ,QAAQ,IAAI,EACnE,EAAiB,CAAE,GAAG,EAAS,QAAS,CAAe,EAC7D,MAAM,EAAQ,cAAc,CAAc,EAE1C,EAAS,CAAE,KAAM,gBAAiB,QAAS,CAAe,CAAC,EAE3D,EAAc,EAAQ,EAAE,CAC1B,CACA,SAAS,EAAc,EAAiB,CAClC,EAAQ,UAAU,IACpB,EAAS,CAAE,KAAM,gBAAiB,SAAQ,CAAC,EAE3C,EAAQ,cAAc,CAAO,CAAC,CAAC,SAAW,CAExC,QAAQ,IAAI,yBAAyB,CACvC,CAAC,EAEL,CACA,SAAS,EAAc,EAAiB,CACtC,EAAS,CAAE,KAAM,gBAAiB,SAAQ,CAAC,EAC3C,EAAQ,eAAe,CAAO,CAAC,CAAC,SAAW,CAE3C,CAAC,CACH,CACA,SAAS,EAAgB,EAAiB,CACxC,EAAS,CAAE,KAAM,kBAAmB,SAAQ,CAAC,CAC/C,CACA,SAAS,EAAY,EAA0D,CAE7E,MADA,EAAS,CAAE,KAAM,cAAe,SAAQ,CAAC,EAC/B,MAAM,qBAAqB,CACvC,CACA,SAAS,EAAiB,EAAgC,CACxD,EAAS,CAAE,KAAM,mBAAoB,SAAQ,CAAC,CAChD,CACA,SAAS,EAAY,EAAwB,CAC3C,QAAQ,IAAI,2BAA2B,EACvC,EAAS,CAAE,KAAM,cAAe,QAAS,CAAQ,CAAC,EAElD,QAAQ,IAAI,CAEV,EAAQ,cAAc,CAAO,EAC7B,EAAQ,YAAY,EAAQ,OAAO,CACrC,CAAC,CAAC,CAAC,SAAW,CAEZ,QAAQ,IAAI,uBAAuB,CACrC,CAAC,CACH,CACA,SAAS,EAAc,EAA8C,CACnE,EAAS,CAAE,KAAM,gBAAiB,SAAQ,CAAC,CAC7C,CACA,SAAS,EAAkB,EAAsB,CAC/C,EAAS,CAAE,KAAM,oBAAqB,SAAQ,CAAC,CACjD,CACA,SAAS,EAAkB,EAAsB,CAC/C,EAAS,CAAE,KAAM,oBAAqB,SAAQ,CAAC,CACjD,CACA,SAAS,EAAkB,EAAiB,CAC1C,EAAS,CAAE,KAAM,oBAAqB,SAAQ,CAAC,CACjD,CACA,SAAS,EAAe,EAAoC,CAC1D,EAAS,CAAE,KAAM,iBAAkB,SAAQ,CAAC,CAC9C,CACA,SAAS,EAAgB,EAAiB,CACxC,EAAS,CAAE,KAAM,kBAAmB,SAAQ,CAAC,CAC/C,CACA,SAAS,EAAc,EAAkB,CACvC,EAAS,CAAE,KAAM,gBAAiB,SAAQ,CAAC,CAC7C,CACA,SAAS,EAAK,EAAuB,CACnC,EAAS,CAAE,KAAM,OAAQ,SAAQ,CAAC,CACpC,CAEA,SAAS,EAAW,EAAsB,CACxC,EAAS,CAAE,KAAM,aAAc,QAAS,CAAY,CAAC,CACvD,CACA,SAAS,EAAc,EAAY,CACjC,EAAS,CAAE,KAAM,gBAAiB,QAAS,CAAG,CAAC,CACjD,CAEA,OAAO,OACE,CACL,gBACA,gBACA,gBACA,kBACA,cACA,cACA,mBACA,OACA,gBACA,oBACA,oBACA,oBACA,iBACA,kBACA,gBACA,aACA,eACF,GAGA,CAAC,CACH,CACF,CAEA,SAAgB,EAAkB,CAAE,UAAS,WAA2B,EAAyB,CAC/F,MAAgB,CACd,EAAQ,iBAAiB,CAAE,QAAS,GAAM,WAAY,EAAG,OAAQ,EAAM,CAAC,EACxE,EAAQ,eAAe,CAAC,CAAC,KAAK,KAAO,IAAgB,CACnD,IAAM,EAAS,MAAM,EAAQ,eAAe,EACtC,EAAY,EAAY,KAAM,GAAM,EAAE,KAAO,CAAM,EAEzD,EAAQ,KAAK,CACE,cACb,QAAS,GAAa,KACtB,cAAe,CACb,OAAQ,GACR,QAAS,GACT,WAAY,KAAK,IAAI,CACvB,CACF,CAAC,CACH,CAAC,CAGH,EAAG,CAAC,CAAC,CACP,CAEA,SAAgB,EACd,CAAE,UAAS,WACX,EACA,CACA,IAAM,EAAa,EAA6B,IAAI,EAC9C,CAAC,EAAO,GAAc,EAAS,EAAK,EACpC,CAAC,EAAO,GAAY,EAAS,EAAE,EAC/B,EAAc,MAAkB,CACpC,IAAM,EAAU,EAAW,QACvB,GACF,EAAQ,YAAY,EAAQ,OAAO,CAAC,CAAC,SAAW,CAC9C,IAAM,EAAa,EAAQ,kBAAkB,CAAO,GAChD,EAACC,GAAAA,QAAAA,CAAa,EAAY,EAAQ,OAAO,GAC3C,EAAQ,YAAY,CAClB,GAAG,EACH,QAAS,CACX,CAAC,CAEL,CAAC,CAEL,EAAG,CAAC,EAAS,CAAO,CAAC,EACf,EAAsB,EAAY,EAAa,EAAQ,YAAY,EACnE,EAAY,GAAS,GAE3B,MAAgB,CACd,EAAW,QAAU,CACvB,EAAG,CAAC,CAAO,CAAC,EAKZ,GAAM,CAAE,QAAO,WAAY,MAAc,CACvC,GAAI,EAAS,CACX,GAAM,CAAC,EAAO,GAAW,EAAQ,oBAAoB,CAAO,EAC5D,MAAO,CACL,QACA,SACF,CACF,CAEA,MAAO,CAAE,MAAO,KAAM,QAAS,IAAK,CAEtC,EAAG,CAAC,EAAS,CAAS,CAAC,EA+DvB,OA7DA,MAAgB,CACd,IAAM,EAAiB,EACjB,EAAiB,EACjB,EAAe,EACrB,UAAa,CACP,GAAgB,EAClB,EAAe,mBAAmB,EAAgB,CAAY,EACrD,aAAwB,GACjC,EAA8B,GAAG,MAAM,CAE3C,CACF,EAAG,CAAC,EAAS,EAAS,CAAK,CAAC,EAI5B,MAAgB,CACd,EAAW,EAAK,EAChB,IAAI,EAAY,GAYhB,OAXI,GACF,EACG,SAAW,CACL,GACH,EAAW,EAAI,CAEnB,CAAC,CAAC,CACD,MAAO,GAAM,CACZ,EAAS,EAAE,OAAO,CACpB,CAAC,MAEQ,CACX,EAAY,EACd,CACF,EAAG,CAAC,CAAO,CAAC,EAGZ,OACE,OAAO,iBAAiB,eAAgB,EAAa,EAAK,MAE7C,CACX,OAAO,oBAAoB,eAAgB,CAAW,CACxD,GACC,CAAC,CAAW,CAAC,EAIhB,UACe,CACX,EAAY,CACd,EACC,CAAC,EAAa,CAAS,CAAC,EAK3B,MAAgB,CAEd,GAAI,GAAS,EAAQ,sBAAsB,EACzC,OAAO,EAAM,UAAU,EAAqB,EAAI,CAEpD,EAAG,CAAC,EAAqB,EAAS,CAAK,CAAC,EAEjC,CACL,QACA,QACA,OACF,CAKF,CAEA,SAAgB,IAAqB,CACnC,GAAM,CAAE,WAAY,EAAkB,EAEhC,EAAsB,EAAY,UAA+B,CACrE,EAAQ,cACN,EAAoB,CAClB,WAAY,iDACZ,GAAI,uBAAuB,EAAS,IACpC,KAAM,WACN,MAAO,CACL,GAAI,CAAC,gBAAgB,CACvB,EACA,MAAO,CAAC,CACV,CAAC,CACH,CAIF,EAAG,CAAC,CAAC,EAEC,EAA8B,EAClC,eAA2C,EAAY,CACrD,IAAI,EAAO,MAAM,EAAqB,CAAE,EACpC,IACG,EAAa,SAChB,EAAO,EAAqB,CAAI,GAE9B,GACF,EAAQ,cAAc,EAAoB,CAAW,CAAC,EAG5D,EAGA,CAAC,CACH,EAEM,EAAgC,EACpC,eAA6C,EAAY,CACvD,IAAI,EAAO,MAAM,EAAqB,CAAE,EACpC,IACG,EAAa,SAChB,EAAO,EAAqB,CAAI,GAE9B,GACF,EAAQ,cAAc,GAAsB,CAAW,CAAC,EAG9D,EAGA,CAAC,CACH,EAmBA,MAAO,CACL,8BAlBoC,EACpC,eAA2C,EAAc,CACvD,IAAI,EAAO,KAAK,MAAM,CAAI,EACtB,IACG,EAAa,SAChB,EAAO,EAAqB,CAAI,GAE9B,GACF,EAAQ,cAAc,EAAoB,CAAW,CAAC,EAG5D,EAGA,CAAC,CAI2B,EAC5B,8BACA,gCACA,qBACF,CACF,CCrWA,MAAa,GAAwB,EAAQ,SAC3C,EACA,EACA,CACA,GAAI,EAAM,QACR,OAAQ,EAAO,KAAf,CAEE,IAAK,oBACH,EAAM,QAAQ,aAAe,EAAM,QAAQ,aAAa,OAAQ,GAAM,EAAE,KAAO,EAAO,OAAO,EAC7F,MACF,IAAK,cACH,EAAM,QAAQ,SAAS,SAAW,KAAK,IAAI,EAC3C,MACF,IAAK,gBACH,EAAM,QAAQ,KAAO,EAAO,QAAQ,KACpC,EAAM,QAAQ,SAAW,EAAO,QAAQ,SACxC,MACF,IAAK,gBACH,EAAM,QAAQ,QAAU,EAAO,QAC/B,MACF,IAAK,oBACE,EAAM,QAAQ,aAAa,KAAM,GAAM,EAAE,KAAO,EAAO,QAAQ,EAAE,GACpE,EAAM,QAAQ,aAAa,KAAK,EAAO,OAAO,EAEhD,MAEF,IAAK,kBACH,EAAM,QAAQ,UAAY,EAAO,QACjC,MACF,IAAK,iBACH,EAAM,QAAQ,SAAW,EAAO,QAChC,MACF,IAAK,oBAAqB,CACxB,IAAM,EAAQ,EAAM,QAAQ,aAAa,KAAM,GAAM,EAAE,KAAO,EAAO,QAAQ,EAAE,EAC3E,IACF,EAAM,OAAS,EAAO,QAAQ,QAEhC,KACF,CACA,IAAK,gBAAiB,CACpB,IAAM,EAAW,EAAM,QAAQ,UAAU,UAAW,GAAM,EAAE,KAAO,EAAO,OAAO,EAC7E,IAAa,IACf,EAAM,QAAQ,SAAS,OAAO,EAAU,CAAC,EAE3C,KACF,CACA,IAAK,aAAc,CACjB,IAAM,EAAW,EAAM,QAAQ,UAAU,UAAW,GAAM,EAAE,KAAO,EAAO,QAAQ,EAAE,EAChF,IAAa,GAGf,EAAM,QAAQ,SAAS,KAAK,EAAO,OAAO,EAF1C,EAAM,QAAQ,SAAS,OAAO,EAAU,EAAG,EAAO,OAAO,EAK3D,KACF,CACF,CAEF,OAAQ,EAAO,KAAf,CACE,IAAK,OACH,EAAM,YAAc,EAAO,QAAQ,YACnC,EAAM,QAAU,EAAO,QAAQ,QAC/B,EAAM,cAAgB,EAAO,QAAQ,cACrC,MAGF,IAAK,cAEH,MACF,IAAK,gBACH,EAAM,YAAc,EAAM,YAAY,OAAQ,GAAM,EAAE,KAAO,EAAO,OAAO,EACvE,EAAM,SAAW,EAAM,QAAQ,KAAO,EAAO,UAC/C,EAAM,QAAU,MAElB,MACF,IAAK,kBACH,EAAM,QAAU,KAChB,MACF,IAAK,gBACH,EAAM,YAAY,KAAK,EAAO,OAAO,EACrC,EAAM,QAAU,EAAO,QACvB,MACF,IAAK,gBACH,EAAM,QAAU,EAAM,YAAY,KAAM,GAAM,EAAE,KAAO,EAAO,OAAO,GAAK,KAC1E,MACF,IAAK,mBACH,EAAM,cAAgB,EAAO,OAEjC,CACF,CAAC,EAED,SAAgB,GACd,EAAuC,CACrC,QAAS,GACT,OAAQ,GACR,WAAY,CACd,EACc,CACd,MAAO,CACL,YAAa,CAAC,EACd,QAAS,KACT,cAAe,CACjB,CACF,yrBCvGA,IAAa,GAAb,KAA2D,CAIzD,YAAY,EAAmC,CAH/C,EAAA,KAAA,YAAA,IAAA,EAAA,EACA,EAAA,KAAA,eAAA,IAAA,EAAA,EACA,EAAA,KAAA,UAAA,IAAA,EAAA,EAEE,KAAK,UAAY,GAAU,WAAa,eACxC,KAAK,aAAe,IACpB,KAAK,QAAUC,EAAY,eAAe,CACxC,KAAM,0BACR,CAAC,CACH,CAEA,MAAM,cAAc,EAA2B,CAC7C,MAAM,KAAK,QAAQ,WAAW,GAAG,KAAK,UAAU,YAAY,GAAI,CAClE,CAEA,MAAM,cAAc,EAAuC,CACzD,IAAM,EAAQ,MAAM,KAAK,gBAAgB,EAEzC,MAAM,KAAK,QAAQ,QAAQ,GAAG,KAAK,UAAU,YAAY,EAAQ,KAAM,KAAK,UAAU,CAAO,CAAC,EAE1F,EAAM,QAAQ,EAAQ,EAAE,IAAM,KAChC,EAAM,KAAK,EAAQ,EAAE,EACrB,MAAM,KAAK,iBAAiB,CAAK,EAErC,CAEA,WAAY,CACV,MAAO,EACT,CAEA,MAAM,gBAA2C,CAC/C,GAAI,CACF,IAAM,EAAQ,MAAM,KAAK,gBAAgB,EACnC,EAAW,CAAC,EAClB,IAAK,IAAM,KAAQ,EAAO,CACxB,GAAI,IAAS,SACX,SAEF,IAAM,EAAS,MAAM,KAAK,QAAQ,QAAa,GAAG,KAAK,UAAU,YAAY,GAAM,EACnF,GAAI,EACF,GAAI,CACF,EAAS,KAAK,KAAK,MAAM,CAAM,CAAC,CAClC,MAAY,CAEZ,CAEJ,CAEA,OAAO,CACT,OAAS,EAAG,CAEV,OADA,QAAQ,MAAM,kCAAmC,CAAC,EAC3C,CAAC,CACV,CACF,CAEA,MAAM,gBAAyC,CAC7C,OAAO,KAAK,QAAQ,QAAQ,GAAG,KAAK,UAAU,MAAM,CACtD,CAEA,MAAM,eAAe,EAA2B,CAC9C,MAAM,KAAK,QAAQ,QAAQ,GAAG,KAAK,UAAU,OAAQ,CAAE,CACzD,CAEA,MAAM,cAAc,EAAuC,CACzD,MAAM,KAAK,QAAQ,QAAQ,GAAG,KAAK,UAAU,YAAY,EAAQ,KAAM,KAAK,UAAU,CAAO,CAAC,CAChG,CAEA,MAAc,iBAAiB,EAAgC,CAC7D,MAAM,KAAK,QAAQ,QAAQ,GAAG,KAAK,UAAU,SAAU,KAAK,UAAU,CAAK,CAAC,CAC9E,CAEA,MAAc,iBAAqC,CACjD,IAAM,EAAO,MAAM,KAAK,QAAQ,QAAgB,GAAG,KAAK,UAAU,QAAQ,EAC1E,GAAI,CAAC,EACH,MAAO,CAAC,EAEV,IAAM,EAAQ,KAAK,MAAM,CAAI,EAM7B,OAJK,MAAM,QAAQ,CAAK,EAIjB,EAHE,CAAC,CAIZ,CACF,ECnFsB,GAAtB,KAEA,CAKE,YAAsB,EAA4C,CAAC,EAAG,CAHtE,EAAA,KAAA,SAAuC,CAAC,CAAA,EACxC,EAAA,KAAA,eAAA,IAAA,EAAA,EAGE,KAAK,aAAe,EAAO,cAAgB,GAC7C,CAEA,uBAAwB,CACtB,MAAO,EACT,CAEA,WAAY,CACV,MAAO,EACT,CAEA,WAAY,CACV,MAAO,EACT,CAIA,oBAAoB,EAAgD,CAClE,IAAM,EAAa,KAAK,OAAO,EAAQ,QAAQ,KAAK,KACpD,GAAI,EACF,MAAO,CAAC,EAAY,QAAQ,QAAQ,CAAC,EAGvC,IAAM,EAAQ,IAAI,GAQlB,MAAO,CAAC,GAAO,SANa,CAC1B,IAAM,EAAO,MAAM,KAAK,WAAW,EAAQ,OAAc,EACzD,MAAM,EAAM,aAAa,EAAQ,SAAS,GAAI,KAAK,MAAM,KAAK,UAAU,GAAM,IAAI,CAAC,CAAC,EACpF,KAAK,OAAO,EAAQ,QAAQ,KAAK,KAAO,CAC1C,EAEe,CAAQ,CAAkB,CAC3C,CAEA,mBAAmB,EAAwB,EAAoB,CAE/D,CAEA,MAAM,YAAY,EAA2B,CAC3C,IAAM,EAAQ,KAAK,OAAO,EAAQ,KAAK,KACjC,EAAoD,CACxD,GAAI,EAAQ,KAAK,GACjB,KAAM,EAAQ,KAAK,IACrB,EAGA,GAAI,EAAO,CACT,IAAM,EAAO,EAAM,gBAAuC,CAAW,EAE/D,EACJ,EAAK,OAAS,aACT,CACC,KAAM,qBACN,MACF,EACC,CACC,KAAM,mBACN,MACF,EAEN,MAAM,KAAK,gBAAgB,EAAQ,CAAO,CAC5C,CACF,CASF,EC3Ea,GAAb,cAAwC,EAA0C,CAOhF,YAAY,EAAmC,CAC7C,MAAM,CAAE,aAAc,GAAK,CAAC,EAP9B,EAAA,KAAA,OAAO,eAAA,EACP,EAAA,KAAA,YAAA,IAAA,EAAA,EACA,EAAA,KAAA,UAAA,IAAA,EAAA,EAEA,EAAA,KAAA,SAAuC,CAAC,CAAA,EAItC,KAAK,UAAY,GAAU,WAAa,UACxC,KAAK,QAAU,GAAY,eAAe,CACxC,KAAM,+BACR,CAAC,CACH,CAEA,uBAAwB,CACtB,MAAO,EACT,CAEA,MAAM,OAAO,EAAwB,EAA4D,CAC/F,IAAM,EAAM,EAAS,EAIrB,OAFA,MAAM,aAAa,QAAQ,GAAG,KAAK,UAAU,SAAS,IAAO,KAAK,UAAU,CAAI,CAAC,EAE1E,CACL,KAAM,yBACN,KAAM,CACJ,GAAI,EAAK,GACT,KAAM,EAAK,KACX,KACF,CACF,CACF,CAEA,MAAM,WAAW,EAAoF,CACnG,GAAI,CACF,IAAM,EAAO,MAAM,aAAa,QAAQ,GAAG,KAAK,UAAU,SAAS,EAAQ,KAAK,KAAK,EAC/E,EAAW,EAAQ,KAAK,MAAM,CAAI,EAAY,KAWpD,OATA,EAAU,EAAU,oBAAoB,EAEpC,EAAS,OAAS,aACb,CACL,KAAM,qBACN,KAAM,CACR,EAGK,CACL,KAAM,mBACN,KAAM,CACR,CACF,MAAY,CACV,OAAO,IACT,CACF,CAEA,MAAM,gBACJ,EACA,EACe,CACf,MAAM,aAAa,QAAQ,GAAG,KAAK,UAAU,SAAS,EAAQ,KAAK,MAAO,KAAK,UAAU,EAAgB,IAAI,CAAC,CAChH,CAEA,MAAM,cAAc,EAA8C,CAChE,KAAK,OAAO,EAAQ,KAAK,KAAO,KAChC,MAAM,aAAa,WAAW,GAAG,KAAK,UAAU,SAAS,EAAQ,KAAK,KAAK,CAC7E,CAEA,kBAAkB,EAA8C,CAE9D,OAAO,EAAQ,OACjB,CACF,EC7DA,SAAgB,GAAgB,EAA6B,CAC3D,IAAM,EAAI,EAAgB,UAAU,EAC9B,CAAE,aAAY,aAAc,EAAQ,EAGpC,EAAU,MAAc,EAAM,SAAW,IAAI,GAAuB,CAAC,CAAC,EACtE,EAAU,MAAc,EAAM,SAAW,IAAI,GAAsB,CAAC,CAAC,EACrE,CAAC,EAAO,GAAY,EACxB,GACA,IAAA,GACA,EAAM,cAAgB,EACxB,EACM,EAAU,EAA6B,EAAU,EAAS,CAAO,EACjE,EAA0B,OACvB,CAAE,UAAS,UAAW,EAAQ,UAAU,EAAG,GAAG,CAAM,GAC3D,CAAC,EAAS,EAAS,CAAK,CAC1B,EACM,CAAE,QAAO,QAAO,SAAU,EAAiB,EAAS,CAAO,EAC3D,EAAuB,EAAQ,SAAS,SAExC,EAAgB,OACb,CAAE,UAAW,CAAC,EAAO,QAAS,CAAC,CAAC,EAAO,OAAM,GACnD,CAAC,EAAO,CAAK,CAAC,EAoBjB,OAlBA,EAAkB,EAAS,CAAO,EAElC,MAAgB,CAEZ,EAAM,eACN,EAAM,cAAc,QACpB,IACC,CAAC,GAAS,CAAC,IACZ,GAAY,MAAQ,EAAM,YAAc,WAExC,EAAU,CAAE,GAAI,EAAM,YAAc,QAAS,CAAC,CAElD,EAAG,CAAC,CAAC,EAEA,EAAM,eAAiB,EAAM,cAAc,SAAa,EAAQ,SAAW,CAAC,EACxE,EAAC,SAAD,CAAQ,MAAO,CAAE,QAAS,OAAQ,EAAI,SAAA,EAAE,gBAAgB,CAAU,CAAA,EAIzE,EAAC,EAA2B,SAA5B,CAAqC,MAAO,EAC1C,SAAA,EAAC,EAAoB,SAArB,CAA8B,MAAO,EACnC,SAAA,EAAC,GAAD,CAAe,MAAO,GAAS,IAAA,GAC7B,SAAA,EAAC,EAAD,CAA6B,GAAI,EAAQ,SAAS,GAChD,SAAA,EAAC,EAAD,CAAqB,SAAU,EAAuB,SAAA,EAAM,QAA8B,CAAA,CAC/D,CAAA,CAChB,EAJgC,EAAM,SAAS,EAI/C,CACa,CAAA,CACK,CAAA,CAEzC,CC1EA,MAAa,OACX,EAAC,MAAD,CAAK,MAAM,6BAA6B,OAAO,OAAO,QAAQ,YAAY,MAAM,OAAO,KAAK,UAA5F,SAAA,CACE,EAAC,OAAD,CAAM,EAAE,gBAAgB,KAAK,MAAQ,CAAA,EACrC,EAAC,OAAD,CAAM,EAAE,+CAAiD,CAAA,CACtD,ICFoB,EAAO,MAAM;;;;;;;;;;;;EAcxC,MAAa,EAAS,EAAO,MAA6B;;WAE9C,GAAe,EAAM,MAAM,MAAM,MAAQ,OAAO;sBACrC,GAAe,EAAM,MAAM,MAAM,OAAS,QAAQ;;;;;;;;;;;;;;;EAiB5D,GAAc,EAAO,CAAa,CAAC;oBAC3B,GAAe,EAAM,MAAM,QAAQ,IAAM,QAAQ;;;EAKvC,EAAO,CAAa,CAAC;;iBAElC,GAAe,EAAM,MAAM,QAAQ,QAAU,OAAO;aACxD,GAAe,EAAM,MAAM,MAAM,MAAQ,WAAW;wBACzC,GAAe,EAAM,MAAM,MAAM,OAAS,QAAQ;wBAClD,GAAe,EAAM,MAAM,MAAM,MAAQ,WAAW;;;;;;;;;;;;;;EAgBjD,EAAO,CAAa,CAAC;eACjC,GAAe,EAAM,MAAM,QAAQ,QAAU,OAAO;WACxD,GAAe,EAAM,MAAM,MAAM,OAAS,QAAQ;sBACvC,GAAe,EAAM,MAAM,MAAM,MAAQ,WAAW;;;;;;;;wBAQlD,GAAe,EAAM,MAAM,MAAM,WAAa,WAAW;;EAIvD,EAAO,GAAyB;;;;;qBAKrC,GAAW,EAAM,OAAS,WAAa,aAAc;EChF3E,MAAa,GAAW,EAAO,GAAG;;;EAKH,EAAO,GAAG;;;;sBAIlB,GAAe,EAAM,MAAM,MAAM,OAAS,QAAQ;WAC7D,GAAe,EAAM,MAAM,MAAM,OAAS,SAAS;;;;;;;0BAOpC,GAAe,EAAM,MAAM,MAAM,WAAa,YAAY;;;EAKzD,EAAO,MAA6B;eAChD,GAAe,EAAM,MAAM,QAAQ,OAAS,SAAS;WACzD,GAAe,EAAM,MAAM,MAAM,MAAQ,OAAO;sBACrC,GAAe,EAAM,MAAM,MAAM,OAAS,QAAQ;;;;;;;;;;;;;wBAahD,GAAe,EAAM,MAAM,MAAM,WAAa,YAAY;;;IAG9E,GACD,EAAM,SACN,CAAG;;;;;;;MAOD;EAGN,MAAa,GAAe,EAAO,GAA2C;;;;;WAKlE,GAAe,EAAM,MAAM,MAAM,OAAS,SAAS;;;;;;;;;;;;;IAa3D,EAAO;;0BAEgB,GAAe,EAAM,MAAM,MAAM,WAAa,YAAY;;;;IAIhF,GACD,EAAM,OACN,CAAG;;MAED;EAGO,EAAgB,EAAO,GAAG;;;;;;EAQ1B,EAAkB,EAAO,GAAG;;;;oBC/Fd,EAAO,QAAU,CAAE,GAAG,CAAE,gBCCnD,OAAO,eAAe,EAAS,aAAc,CAAE,MAAO,EAAK,CAAC,EAC5D,IAAM,EAAA,GAAA,EACN,SAAS,EAAgB,EAAW,EAAS,CACzC,GAAM,CAAC,EAAQ,IAAc,EAAG,EAAQ,SAAA,CAAU,EAAK,EACjD,GAAqB,EAAG,EAAQ,OAAA,CAAQ,IAAI,EAC5C,GAAY,EAAG,EAAQ,OAAA,CAAQ,EAAI,EACnC,GAAe,EAAG,EAAQ,OAAA,CAAQ,EAAK,EACvC,GAAa,EAAG,EAAQ,OAAA,CAAQ,IAAI,EACpC,GAAY,EAAG,EAAQ,QAAA,KAAe,MAAM,KAAK,CAAE,OAAQ,CAAU,OAAU,EAAG,EAAQ,UAAA,CAAW,CAAC,EAAG,CAAC,CAAS,CAAC,EACpH,EAAmB,GAAM,EAAE,MAAQ,IAAA,GACnC,EAAa,GAAc,CAC7B,IAAI,EACJ,EAAkB,QAAU,GAC3B,EAAK,EAAS,EAAU,CAAC,UAAa,MAAiC,EAAG,MAAM,CACrF,GACC,EAAG,EAAQ,UAAA,KAAiB,CACzB,GAAI,EAAS,QAAS,CAClB,EAAS,QAAU,GACnB,MACJ,CACI,IAAW,CAAC,EAAY,SAAY,GAA0D,uBAC9F,EAAU,CAAC,EAEL,IACN,EAAY,QAAU,GAE9B,EAAG,CAAC,CAAM,CAAC,GACV,EAAG,EAAQ,UAAA,KAAiB,CACzB,GAAI,CAAC,EACD,OAEJ,IAAM,EAAiB,CACnB,QAAS,EACb,EACM,EAAoB,GAAU,CAChC,eAAiB,CACP,EAAM,kBAAkB,UAG1B,EAAM,OAAO,QAAQ,eAAe,YAAa,SAGrD,EAAU,EAAK,EACnB,EAAG,EAAE,CACT,EAOA,OANA,eAAiB,CACT,EAAe,SAGnB,SAAS,iBAAiB,QAAS,CAAgB,CACvD,EAAG,CAAC,MACS,CACT,EAAe,QAAU,GACzB,SAAS,oBAAoB,QAAS,CAAgB,CAC1D,CACJ,EAAG,CAAC,CAAM,CAAC,GACV,EAAG,EAAQ,UAAA,KAAiB,CACzB,IAAM,EAAsB,GAAU,CAC9B,IAAW,EAAM,MAAQ,aAAe,EAAM,MAAQ,YACtD,EAAM,eAAe,CAE7B,EAEA,OADA,SAAS,iBAAiB,UAAW,CAAkB,MAC1C,SAAS,oBAAoB,UAAW,CAAkB,CAC3E,EAAG,CAAC,CAAM,CAAC,EACX,IAAM,EAAkB,GAAM,CAC1B,GAAI,EAAgB,CAAC,EAAG,CACpB,GAAM,CAAE,OAAQ,EAChB,GAAI,CAAC,CAAC,QAAS,IAAK,MAAO,YAAa,QAAQ,CAAC,CAAC,SAAS,CAAG,EAC1D,QAEC,IAAQ,OAAS,IAAQ,cAAgB,EAAY,SAAW,IACjE,EAAE,eAAe,EACjB,EAAU,CAAC,IAEX,IAAQ,SAAW,IAAQ,OAC3B,EAAE,eAAe,EACjB,EAAU,EAAI,GAEd,IAAQ,WACR,EAAE,eAAe,EACjB,EAAU,EAAK,EAEvB,MAEU,GAA0D,wBAC5D,EAAY,QAAU,CAAC,GAE3B,EAAU,CAAC,CAAM,CAEzB,EACM,EAAgB,GAAM,CACxB,IAAI,EACJ,GAAM,CAAE,OAAQ,EAChB,GAAI,CAAC,MAAO,QAAS,QAAS,SAAU,UAAW,YAAa,GAAG,CAAC,CAAC,SAAS,CAAG,EAAG,CAChF,IAAI,EAAgB,EAAkB,QACtC,GAAI,IAAQ,SAAU,CAClB,EAAU,EAAK,GACd,EAAK,EAAU,UAAa,MAAiC,EAAG,MAAM,EACvE,MACJ,CACK,GAAI,IAAQ,MAAO,CACpB,EAAU,EAAK,EACf,MACJ,CACK,GAAI,IAAQ,SAAW,IAAQ,IAAK,CAChC,EAAE,cAAc,MACjB,EAAE,cAAc,MAAM,EAE1B,EAAU,EAAK,EACf,MACJ,CACI,IAAkB,OACd,IAAQ,UACR,IAEK,IAAQ,cACb,GAAiB,GAEjB,EAAgB,EAAS,OAAS,EAClC,EAAgB,EAEX,EAAgB,IACrB,EAAgB,EAAS,OAAS,IAGtC,IAAkB,MAClB,EAAU,CAAa,EAE3B,MACJ,CACA,GAAI,kDAAkD,KAAK,CAAG,EAAG,CAC7D,IAAM,EAAQ,EAAS,UAAW,IAEV,EAAI,SAAiD,UAAA,EAAmD,YAAY,CAAC,CAAC,WAAW,EAAI,YAAY,CAAC,IACrJ,EAAI,SAAiD,YAAA,EAAqD,YAAY,CAAC,CAAC,WAAW,EAAI,YAAY,CAAC,IACpJ,EAAI,SAAiD,aAAa,YAAY,EAAA,EAA2C,YAAY,CAAC,CAAC,WAAW,EAAI,YAAY,CAAC,CACvL,EACG,IAAU,IACV,EAAU,CAAK,CAEvB,CACJ,EAgBA,MAAO,CAAE,YAAA,CAdL,UAAW,EACX,QAAS,EACT,SAAU,EACV,IAAK,EACL,KAAM,SACN,gBAAiB,GACjB,gBAAiB,CAQF,EAAG,UANJ,MAAM,KAAK,CAAE,OAAQ,CAAU,GAAI,EAAS,KAAW,CACrE,UAAW,EACX,SAAU,GACV,KAAM,WACN,IAAK,EAAS,EAClB,EAC8B,EAAG,SAAQ,YAAW,WAAU,CAClE,CACA,EAAQ,QAAU,UC/JlB,MAAM,EAAqBC,EAAAA,QAErB,GACJ,OAAO,GAAc,UAAY,GAAsB,YAAa,EAAY,EAAU,QAAUA,EAAAA,QCKzF,EAAa,EAAO,MAAM;;;;;;;;;;;;;;;;;;;EAqBvC,SAAgB,GAAQ,EAA+B,CACrD,IAAM,EAAI,EAAgB,UAAU,EAC9B,CAAE,kBAAmB,EAAc,EACnC,CAAE,QAAS,GAAmB,EAAkB,EAChD,CAAC,EAAc,GAAmB,EAAgB,aAAa,EAC/D,CAAE,OAAM,aAAc,EAAQ,EAC9B,EAAO,GAAgB,SAAS,KAChC,EAAe,OAAO,OAAO,CAAI,CAAC,CAAC,OAAQ,GAS/C,EARI,EAAI,SAAS,SAAW,EAAI,SAAS,cAAgB,GAIrD,CAAC,GAAkB,EAAI,SAAS,SAIhC,EAAI,SAAS,OAAS,WAkB3B,EACK,CAAE,YAAW,cAAa,SAAQ,aAAc,GAAgB,EAAa,OAAS,CAAC,EAE7F,OACE,EAAC,GAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAY,GAAI,EAAa,aAAY,EAAE,aAAa,EACtD,SAAA,EAAC,GAAD,CAAW,CAAA,CACD,CAAA,EACZ,EAAC,GAAD,CAAc,MAAO,EAArB,SAAA,CACE,EAAC,EAAD,CAAA,SAAgB,EAAE,WAAW,CAAiB,CAAA,EAC9C,EAAC,EAAD,CAAkB,CAAA,EACjB,EAAa,KAAK,EAAK,IACtB,EAAC,EAAD,CAEE,GAAK,EAAU,GACf,YAAe,CACb,EAAU,CAAE,GAAI,EAAI,SAAS,EAAG,CAAC,EACjC,EAAU,EAAK,CACjB,EAEC,SAAA,EACE,EAAI,SAAyE,aAC9E,EAAI,SAAS,KACf,CACM,EAXD,EAAI,SAAS,EAWZ,CACT,EACA,EAAM,SAAW,KAChB,EAAA,EAAA,CAAA,SAAA,CACE,EAAC,EAAD,CAAA,SAAgB,EAAE,oBAAoB,CAAiB,CAAA,EACvD,EAAC,EAAD,CAAkB,CAAA,EAClB,EAAC,EAAD,CAAQ,GAAK,EAAU,EAAa,OAAS,GAAY,YAAe,EAAgB,CAAC,CAAY,EAClG,SAAA,EAAE,EAAe,YAAc,WAAW,CACrC,CAAA,CACR,CAAA,CAAA,CAEQ,CACN,CAAA,CAAA,CAAA,CAAA,CAEd,CChGA,MAAa,EAAQ,EAAO,GAAG;;;;;;;;EAUlB,EAAa,EAAO,GAAG;;;EAKvB,EAAiB,EAAO,IAAI;;;;;EAO5B,EAAsB,EAAO,KAAK;;;;;;EAQlC,EAAuB,EAAO,EAAkB,CAAC;;;EAKjD,GAAa,EAAO,GAAG;;;;;;;;;;;;EAcpC,SAAgB,IAAmB,CACjC,IAAM,EAAI,EAAgB,UAAU,EAC9B,EAAS,EAAgB,QAAQ,EACjC,EAAQ,EAAyB,IAAI,EACrC,CAAE,UAAS,WAAY,EAAkB,EACzC,CAAC,EAAc,GAAqB,EAAS,EAAK,EAExD,OACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAA,SAAa,EAAE,YAAY,CAAc,CAAA,EACxC,EACC,EAAA,EAAA,CAAA,SACG,EACC,EAAC,EAAD,CACE,SAAW,GAAkC,CAC3C,EAAE,eAAe,EACjB,IAAM,EAAO,IAAI,SAAS,EAAE,MAAa,EACnC,EAAO,OAAO,YAAY,EAAK,QAAQ,CAAC,EAC9C,EAAQ,cAAc,CAAW,EACjC,EAAkB,EAAK,CACzB,EAPF,SAAA,CASE,EAAC,EAAD,CAAqB,IAAK,EAAO,aAAY,EAAE,aAAa,EAAG,aAAc,EAAQ,KAAM,KAAK,MAAQ,CAAA,EACxG,EAAC,EAAD,CAAsB,KAAK,SAAU,SAAA,EAAO,cAAc,CAAwB,CAAA,CACpE,CAEhB,CAAA,EAAA,EAAC,GAAD,CACE,GAAG,SACH,KAAK,SACL,aAAY,EAAE,aAAc,CAAE,KAAM,EAAQ,MAAQ,EAAE,uBAAuB,CAAE,CAAC,EAChF,YAAe,CACb,OAAgB,CACd,EAAkB,EAAI,CACxB,CAAC,EACD,EAAM,SAAS,MAAM,CACvB,EAEC,SAAA,EAAQ,MAAQ,EAAE,uBAAuB,CAChC,CAAA,CAEd,CAAA,EACA,IACC,CAAA,CAAA,CAEX"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manifest-editor/projects",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bugs": "https://github.com/digirati-co-uk/iiif-manifest-editor/issues",
|
|
6
6
|
"repository": {
|
|
@@ -34,39 +34,46 @@
|
|
|
34
34
|
"dev": "tsdown src/index.ts --watch",
|
|
35
35
|
"lint": "publint",
|
|
36
36
|
"typecheck": "tsc --noEmit",
|
|
37
|
-
"prepack": "tsdown src/index.ts"
|
|
37
|
+
"prepack": "tsdown src/index.ts",
|
|
38
|
+
"test": "vitest run --config vitest.config.ts",
|
|
39
|
+
"typecheck:i18n": "tsc --noEmit -p tsconfig.i18n.json",
|
|
40
|
+
"lint:i18n": "oxlint src test"
|
|
38
41
|
},
|
|
39
42
|
"dependencies": {
|
|
40
|
-
"@atlas-viewer/atlas": "3.3.
|
|
41
|
-
"@iiif/helpers": "4.0.
|
|
42
|
-
"@iiif/parser": "4.0.
|
|
43
|
+
"@atlas-viewer/atlas": "3.3.6",
|
|
44
|
+
"@iiif/helpers": "4.0.5",
|
|
45
|
+
"@iiif/parser": "4.0.7",
|
|
43
46
|
"@iiif/presentation-3": "^2.2.3",
|
|
44
47
|
"@iiif/presentation-3-normalized": "^0.9.7",
|
|
45
|
-
"@manifest-editor/client-vault": "2.
|
|
46
|
-
"@manifest-editor/
|
|
48
|
+
"@manifest-editor/client-vault": "2.3.0",
|
|
49
|
+
"@manifest-editor/i18n": "2.3.0",
|
|
50
|
+
"@manifest-editor/shell": "2.3.0",
|
|
47
51
|
"immer": "^10.0.4",
|
|
48
52
|
"localforage": "^1.10.0",
|
|
49
53
|
"react": "19.2.8",
|
|
50
54
|
"react-accessible-dropdown-menu-hook": "4.0.0",
|
|
51
55
|
"react-dom": "19.2.8",
|
|
52
|
-
"react-iiif-vault": "4.
|
|
56
|
+
"react-iiif-vault": "4.1.0",
|
|
53
57
|
"styled-components": "6.1.8",
|
|
54
58
|
"tiny-use-debounce": "^1.0.4"
|
|
55
59
|
},
|
|
56
60
|
"devDependencies": {
|
|
57
|
-
"@manifest-editor/ui": "2.
|
|
61
|
+
"@manifest-editor/ui": "2.3.0",
|
|
58
62
|
"@types/react": "19.2.18",
|
|
59
63
|
"@types/react-dom": "19.2.4",
|
|
60
64
|
"@types/shallowequal": "^1.1.5",
|
|
65
|
+
"jsdom": "26.1.0",
|
|
61
66
|
"shallowequal": "^1.1.0",
|
|
62
67
|
"slugify": "^1.6.6",
|
|
63
68
|
"tiny-invariant": "^1.3.3",
|
|
64
|
-
"tsdown": "0.22.14"
|
|
69
|
+
"tsdown": "0.22.14",
|
|
70
|
+
"typescript": "7.0.2",
|
|
71
|
+
"vitest": "4.1.10"
|
|
65
72
|
},
|
|
66
73
|
"publishConfig": {
|
|
67
74
|
"access": "public"
|
|
68
75
|
},
|
|
69
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "34c06c440b1788a470f3da536169560ab1c0d3a3",
|
|
70
77
|
"inlinedDependencies": {
|
|
71
78
|
"react-accessible-dropdown-menu-hook": "4.0.0",
|
|
72
79
|
"shallowequal": "1.1.0",
|