@inpageedit/core 0.9.3 → 0.11.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.
Files changed (73) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +62 -55
  3. package/dist/ActionButton-BgbTKTg7.js.map +1 -1
  4. package/dist/CheckBox-D3rHnX7I.js.map +1 -1
  5. package/dist/IconQuickEdit-CAL1HXIb.js.map +1 -1
  6. package/dist/InputBox-BV4m05Xs.js.map +1 -1
  7. package/dist/PluginPrefSync-PIoKRRu2.js +254 -0
  8. package/dist/PluginPrefSync-PIoKRRu2.js.map +1 -0
  9. package/dist/Preferences-DS4-CFWe.js.map +1 -1
  10. package/dist/RadioBox-nJqWsxW2.js.map +1 -1
  11. package/dist/__test__/utils/constants.d.ts +3 -2
  12. package/dist/components/index.js.map +1 -1
  13. package/dist/constants/endpoints.d.ts +1 -1
  14. package/dist/{index-D968kDLW.js → index-B5vDBMEh.js} +44 -38
  15. package/dist/index-B5vDBMEh.js.map +1 -0
  16. package/dist/{index-DRaYlg2d.js → index-BP-e8PeH.js} +2 -2
  17. package/dist/{index-DRaYlg2d.js.map → index-BP-e8PeH.js.map} +1 -1
  18. package/dist/{index-D8zKl2eU.js → index-BVkdBJNf.js} +6 -2
  19. package/dist/index-BVkdBJNf.js.map +1 -0
  20. package/dist/index-Bh70Udzi.js.map +1 -1
  21. package/dist/{index-BJ2aqva1.js → index-BjwVNZ_h.js} +46 -35
  22. package/dist/index-BjwVNZ_h.js.map +1 -0
  23. package/dist/{index-CMuITxgX.js → index-BzCqww16.js} +22 -21
  24. package/dist/index-BzCqww16.js.map +1 -0
  25. package/dist/index-CFb1PSJg.js +185 -0
  26. package/dist/index-CFb1PSJg.js.map +1 -0
  27. package/dist/index-CvhkVj_L.js.map +1 -1
  28. package/dist/{index-CNsfHvio.js → index-D7NpqwUe.js} +148 -110
  29. package/dist/index-D7NpqwUe.js.map +1 -0
  30. package/dist/{index-BKxuoVoX.js → index-DFPN4uYd.js} +771 -683
  31. package/dist/index-DFPN4uYd.js.map +1 -0
  32. package/dist/index-DGOY4X1J.js +4912 -0
  33. package/dist/{index-DtLiqtR8.js.map → index-DGOY4X1J.js.map} +1 -1
  34. package/dist/{index-CiceXP5j.js → index-DKDtc9IF.js} +42 -42
  35. package/dist/index-DKDtc9IF.js.map +1 -0
  36. package/dist/index-DkQLtTG0.js +211 -0
  37. package/dist/index-DkQLtTG0.js.map +1 -0
  38. package/dist/index-lZkYoUca.js.map +1 -1
  39. package/dist/index.js +1 -1
  40. package/dist/makeCallable-LDU0xZMJ.js.map +1 -1
  41. package/dist/models/WikiTitle/index.d.ts +2 -2
  42. package/dist/noop-ClDc6zv4.js.map +1 -1
  43. package/dist/plugins/analytics/index.d.ts +41 -0
  44. package/dist/plugins/in-article-links/index.d.ts +14 -0
  45. package/dist/plugins/preferences-ui/PluginPrefSync.d.ts +27 -0
  46. package/dist/plugins/preferences-ui/index.d.ts +7 -1
  47. package/dist/plugins/quick-delete/index.d.ts +3 -0
  48. package/dist/plugins/quick-diff/index.d.ts +17 -0
  49. package/dist/plugins/quick-edit/index.d.ts +8 -0
  50. package/dist/plugins/quick-move/index.d.ts +16 -0
  51. package/dist/plugins/quick-redirect/index.d.ts +15 -0
  52. package/dist/plugins/toolbox/index.d.ts +9 -0
  53. package/dist/services/PreferencesService.d.ts +14 -0
  54. package/dist/services/WikiMetadataService.d.ts +23 -23
  55. package/dist/services/storage/IPEStorageManager.d.ts +25 -0
  56. package/dist/services/storage/index.d.ts +3 -26
  57. package/dist/style.css +1 -1
  58. package/dist/types/WikiMetadata.d.ts +6 -8
  59. package/lib/index.umd.js +27 -20
  60. package/lib/index.umd.js.map +1 -1
  61. package/lib/style.css +1 -1
  62. package/package.json +2 -1
  63. package/dist/index-BJ2aqva1.js.map +0 -1
  64. package/dist/index-BKxuoVoX.js.map +0 -1
  65. package/dist/index-CA_JNRF8.js +0 -193
  66. package/dist/index-CA_JNRF8.js.map +0 -1
  67. package/dist/index-CMuITxgX.js.map +0 -1
  68. package/dist/index-CNsfHvio.js.map +0 -1
  69. package/dist/index-CiceXP5j.js.map +0 -1
  70. package/dist/index-D8zKl2eU.js.map +0 -1
  71. package/dist/index-D968kDLW.js.map +0 -1
  72. package/dist/index-DtLiqtR8.js +0 -4853
  73. package/dist/services/storage/IDBStorage.d.ts +0 -90
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 dragon-fish
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1
+ MIT License
2
+
3
+ Copyright (c) 2025 dragon-fish
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
package/README.md CHANGED
@@ -1,55 +1,62 @@
1
- <div align="center">
2
-
3
- [<img src="/docs/.vitepress/public/images/logo/ipe-next-uwu.png" width="280" alt="InPageEdit Logo">](https://www.ipe.wiki)
4
-
5
- # InPageEdit NEXT
6
-
7
- 🚀 MediaWiki 的模块化、可扩展超级增强插件
8
-
9
- **InPageEdit NEXT**是由机智的小鱼君开发的一款 MediaWiki 多功能插件。主要功能旨在使许多 MediaWiki 的功能在不打开新标签页的情况下完成(包括但不限于编辑),极大加快维护 wiki 的速度。模块化设计、类型定义清晰完整,插件可自由热插拔。
10
-
11
- </div>
12
-
13
- ## 快速上手 / Quick Start
14
-
15
- [![](https://data.jsdelivr.com/v1/package/npm/@inpageedit/core/badge)](https://www.jsdelivr.com/package/npm/@inpageedit/core)
16
-
17
- 在*个人 JS 页*添加以下代码:
18
-
19
- <!-- prettier-ignore -->
20
- ```javascript
21
- // InPageEdit NEXT
22
- $('<script src="https://unpkg.com/@inpageedit/core" type="module"></script>').appendTo('body')
23
- ```
24
-
25
- ## 特色功能 / Features
26
-
27
- **编辑者视角 / For wiki editors**
28
-
29
- - 快速编辑 / Quick Edit
30
- - 快速移动 / Quick Move
31
- - 快速重定向 / Quick Redirect
32
- - 快速差异 / Quick Diff
33
- - 快速预览 / Quick Preview
34
-
35
- **开发者视角 / For developers**
36
-
37
- - 可热插拔的模块化设计
38
- - 完全使用 TypeScript 编写
39
- - 超简单的扩展能力,示例插件:[hello-world](./docs/.templates/examples/plugins/hello-world.js)
40
-
41
- ## Supported languages
42
-
43
- > [!NOTE]
44
- >
45
- > Currently only English is supported. We're working on i18n support.
46
-
47
- ---
48
-
49
- 🚀 Modular, Extensible Supercharged Plugin for MediaWiki.
50
-
51
- > [MIT License](https://opensource.org/licenses/MIT)
52
- >
53
- > InPageEdit-NEXT Copyright © 2025-present dragon-fish
54
-
55
- See more: [GitHub](https://github.com/inpageedit/inpageedit-next) | [Change Logs](https://www.ipe.wiki/changelogs/) | [File Issues](https://github.com/inpageedit/inpageedit-next/issues)
1
+ <div align="center">
2
+
3
+ [<img src="https://www.ipe.wiki/images/logo/ipe-next-uwu.png" width="280" alt="InPageEdit Logo">](https://www.ipe.wiki)
4
+
5
+ # InPageEdit NEXT
6
+
7
+ 🚀 MediaWiki 的模块化、可扩展超级增强插件
8
+
9
+ **InPageEdit NEXT**是由机智的小鱼君开发的一款 MediaWiki 多功能插件。主要功能旨在使许多 MediaWiki 的功能在不打开新标签页的情况下完成(包括但不限于编辑),极大加快维护 wiki 的速度。模块化设计、类型定义清晰完整,插件可自由热插拔。
10
+
11
+ → <https://www.ipe.wiki>
12
+
13
+ </div>
14
+
15
+ ## 快速上手 / Quick Start
16
+
17
+ [![](https://data.jsdelivr.com/v1/package/npm/@inpageedit/core/badge)](https://www.jsdelivr.com/package/npm/@inpageedit/core)
18
+
19
+ 在*个人 JS 页*添加以下代码:
20
+
21
+ <!-- prettier-ignore -->
22
+ ```javascript
23
+ // InPageEdit NEXT
24
+ document.body.append(
25
+ Object.assign(document.createElement('script'), {
26
+ src: 'https://cdn.jsdelivr.net/npm/@inpageedit/core/dist/index.js',
27
+ type: 'module',
28
+ })
29
+ )
30
+ ```
31
+
32
+ ## 特色功能 / Features
33
+
34
+ **编辑者视角 / For wiki editors**
35
+
36
+ - 快速编辑 / Quick Edit
37
+ - 快速移动 / Quick Move
38
+ - 快速重定向 / Quick Redirect
39
+ - 快速差异 / Quick Diff
40
+ - 快速预览 / Quick Preview
41
+
42
+ **开发者视角 / For developers**
43
+
44
+ - 可热插拔的模块化设计
45
+ - 完全使用 TypeScript 编写
46
+ - 超简单的扩展能力,示例插件:[hello-world](./docs/.templates/examples/plugins/hello-world.js)
47
+
48
+ ## Supported languages
49
+
50
+ > [!NOTE]
51
+ >
52
+ > Currently only English is supported. We're working on i18n support.
53
+
54
+ ---
55
+
56
+ 🚀 Modular, Extensible Supercharged Plugin for MediaWiki.
57
+
58
+ > [MIT License](https://opensource.org/licenses/MIT)
59
+ >
60
+ > InPageEdit-NEXT Copyright © 2025-present dragon-fish
61
+
62
+ See more: [GitHub](https://github.com/inpageedit/inpageedit-next) | [Change Logs](https://www.ipe.wiki/changelogs/) | [File Issues](https://github.com/inpageedit/inpageedit-next/issues)
@@ -1 +1 @@
1
- {"version":3,"file":"ActionButton-BgbTKTg7.js","sources":["../src/components/ActionButton.tsx"],"sourcesContent":["import { h, JSX, ReactNode } from 'jsx-dom'\r\n\r\nexport interface ActionButtonProps {\r\n type?: 'primary' | 'secondary' | 'danger' | 'default'\r\n tag?: 'a' | 'button' | 'div'\r\n}\r\n\r\nconst origin = window?.location?.origin\r\n\r\nexport const ActionButton = ({\r\n type,\r\n tag,\r\n href,\r\n target,\r\n children,\r\n ...rest\r\n}: ActionButtonProps &\r\n Omit<JSX.IntrinsicElements['button'], 'type'> &\r\n JSX.IntrinsicElements['a']) => {\r\n tag = tag || (href ? 'a' : 'button')\r\n if (\r\n typeof target === 'undefined' &&\r\n href &&\r\n href.startsWith('http') &&\r\n !href.startsWith(origin)\r\n ) {\r\n target = '_blank'\r\n }\r\n return h(\r\n tag,\r\n {\r\n className: `theme-ipe ipe-action-button ipe-modal-btn is-${type || 'default'}`,\r\n // @ts-ignore\r\n href: tag === 'a' ? href : undefined,\r\n target: tag === 'a' ? target : undefined,\r\n 'data-href': tag !== 'a' ? href : undefined,\r\n ...rest,\r\n },\r\n children\r\n )\r\n}\r\n"],"names":["origin","ActionButton","type","tag","href","target","children","rest","h"],"mappings":";AAOA,MAAMA,IAAS,QAAQ,UAAU,QAEpBC,IAAe,CAAC;AAAA,EAC3B,MAAAC;AAAA,EACA,KAAAC;AAAA,EACA,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,OAGEJ,IAAMA,MAAQC,IAAO,MAAM,WAEzB,OAAOC,IAAW,OAClBD,KACAA,EAAK,WAAW,MAAM,KACtB,CAACA,EAAK,WAAWJ,CAAM,MAEvBK,IAAS,WAEJG;AAAAA,EACLL;AAAA,EACA;AAAA,IACE,WAAW,gDAAgDD,KAAQ,SAAS;AAAA;AAAA,IAE5E,MAAMC,MAAQ,MAAMC,IAAO;AAAA,IAC3B,QAAQD,MAAQ,MAAME,IAAS;AAAA,IAC/B,aAAaF,MAAQ,MAAMC,IAAO;AAAA,IAClC,GAAGG;AAAA,EAAA;AAAA,EAELD;AAAA;"}
1
+ {"version":3,"file":"ActionButton-BgbTKTg7.js","sources":["../src/components/ActionButton.tsx"],"sourcesContent":["import { h, JSX } from 'jsx-dom'\n\nexport interface ActionButtonProps {\n type?: 'primary' | 'secondary' | 'danger' | 'default'\n tag?: 'a' | 'button' | 'div'\n}\n\nconst origin = window?.location?.origin\n\nexport const ActionButton = ({\n type,\n tag,\n href,\n target,\n children,\n ...rest\n}: ActionButtonProps &\n Omit<JSX.IntrinsicElements['button'], 'type'> &\n JSX.IntrinsicElements['a']) => {\n tag = tag || (href ? 'a' : 'button')\n if (\n typeof target === 'undefined' &&\n href &&\n href.startsWith('http') &&\n !href.startsWith(origin)\n ) {\n target = '_blank'\n }\n return h(\n tag,\n {\n className: `theme-ipe ipe-action-button ipe-modal-btn is-${type || 'default'}`,\n // @ts-ignore\n href: tag === 'a' ? href : undefined,\n target: tag === 'a' ? target : undefined,\n 'data-href': tag !== 'a' ? href : undefined,\n ...rest,\n },\n children\n )\n}\n"],"names":["origin","ActionButton","type","tag","href","target","children","rest","h"],"mappings":";AAOA,MAAMA,IAAS,QAAQ,UAAU,QAEpBC,IAAe,CAAC;AAAA,EAC3B,MAAAC;AAAA,EACA,KAAAC;AAAA,EACA,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,OAGEJ,IAAMA,MAAQC,IAAO,MAAM,WAEzB,OAAOC,IAAW,OAClBD,KACAA,EAAK,WAAW,MAAM,KACtB,CAACA,EAAK,WAAWJ,CAAM,MAEvBK,IAAS,WAEJG;AAAAA,EACLL;AAAA,EACA;AAAA,IACE,WAAW,gDAAgDD,KAAQ,SAAS;AAAA;AAAA,IAE5E,MAAMC,MAAQ,MAAMC,IAAO;AAAA,IAC3B,QAAQD,MAAQ,MAAME,IAAS;AAAA,IAC/B,aAAaF,MAAQ,MAAMC,IAAO;AAAA,IAClC,GAAGG;AAAA,EAAA;AAAA,EAELD;AAAA;"}
@@ -1 +1 @@
1
- {"version":3,"file":"CheckBox-D3rHnX7I.js","sources":["../src/components/CheckBox.tsx"],"sourcesContent":["import { JSX, ReactNode } from 'jsx-dom'\r\n\r\nexport type CheckBoxProps = {\r\n id?: string\r\n name: string\r\n label?: string | HTMLElement\r\n checked?: boolean\r\n inputProps?: JSX.IntrinsicElements['input']\r\n labelProps?: JSX.IntrinsicElements['span']\r\n} & JSX.IntrinsicElements['label']\r\n\r\nexport const CheckBox = (props: CheckBoxProps) => {\r\n const { id, name, label, checked, inputProps, labelProps, children, ...rest } = props\r\n return (\r\n <label className=\"theme-ipe ipe-checkbox\" {...rest}>\r\n <input type=\"checkbox\" id={id} name={name} checked={checked} {...inputProps} />\r\n <span className=\"ipe-checkbox-box\"></span>\r\n <span {...labelProps}>{label || children}</span>\r\n </label>\r\n )\r\n}\r\n"],"names":["CheckBox","props","id","name","label","checked","inputProps","labelProps","children","rest","jsxs","jsx"],"mappings":";AAWO,MAAMA,IAAW,CAACC,MAAyB;AAChD,QAAM,EAAE,IAAAC,GAAI,MAAAC,GAAM,OAAAC,GAAO,SAAAC,GAAS,YAAAC,GAAY,YAAAC,GAAY,UAAAC,GAAU,GAAGC,EAAA,IAASR;AAChF,SACES,gBAAAA,EAAC,SAAA,EAAM,WAAU,0BAA0B,GAAGD,GAC5C,UAAA;AAAA,IAAA,gBAAAE,EAAC,WAAM,MAAK,YAAW,IAAAT,GAAQ,MAAAC,GAAY,SAAAE,GAAmB,GAAGC,GAAY;AAAA,IAC7E,gBAAAK,EAAC,QAAA,EAAK,WAAU,mBAAA,CAAmB;AAAA,IACnC,gBAAAA,EAAC,QAAA,EAAM,GAAGJ,GAAa,eAASC,EAAA,CAAS;AAAA,EAAA,GAC3C;AAEJ;"}
1
+ {"version":3,"file":"CheckBox-D3rHnX7I.js","sources":["../src/components/CheckBox.tsx"],"sourcesContent":["import { JSX } from 'jsx-dom'\n\nexport type CheckBoxProps = {\n id?: string\n name: string\n label?: string | HTMLElement\n checked?: boolean\n inputProps?: JSX.IntrinsicElements['input']\n labelProps?: JSX.IntrinsicElements['span']\n} & JSX.IntrinsicElements['label']\n\nexport const CheckBox = (props: CheckBoxProps) => {\n const { id, name, label, checked, inputProps, labelProps, children, ...rest } = props\n return (\n <label className=\"theme-ipe ipe-checkbox\" {...rest}>\n <input type=\"checkbox\" id={id} name={name} checked={checked} {...inputProps} />\n <span className=\"ipe-checkbox-box\"></span>\n <span {...labelProps}>{label || children}</span>\n </label>\n )\n}\n"],"names":["CheckBox","props","id","name","label","checked","inputProps","labelProps","children","rest","jsxs","jsx"],"mappings":";AAWO,MAAMA,IAAW,CAACC,MAAyB;AAChD,QAAM,EAAE,IAAAC,GAAI,MAAAC,GAAM,OAAAC,GAAO,SAAAC,GAAS,YAAAC,GAAY,YAAAC,GAAY,UAAAC,GAAU,GAAGC,EAAA,IAASR;AAChF,SACES,gBAAAA,EAAC,SAAA,EAAM,WAAU,0BAA0B,GAAGD,GAC5C,UAAA;AAAA,IAAA,gBAAAE,EAAC,WAAM,MAAK,YAAW,IAAAT,GAAQ,MAAAC,GAAY,SAAAE,GAAmB,GAAGC,GAAY;AAAA,IAC7E,gBAAAK,EAAC,QAAA,EAAK,WAAU,mBAAA,CAAmB;AAAA,IACnC,gBAAAA,EAAC,QAAA,EAAM,GAAGJ,GAAa,eAASC,EAAA,CAAS;AAAA,EAAA,GAC3C;AAEJ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"IconQuickEdit-CAL1HXIb.js","sources":["../src/components/Icon/IconQuickEdit.tsx"],"sourcesContent":["import { SVGProps } from 'jsx-dom'\r\n\r\nexport const IconQuickEdit = (props: SVGProps<SVGSVGElement>) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n {...props}\r\n class={`icon icon-tabler icons-tabler-outline icon-tabler-pencil-bolt ${props.className || ''}`}\r\n >\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\r\n <path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\" />\r\n <path d=\"M13.5 6.5l4 4\" />\r\n <path d=\"M19 16l-2 3h4l-2 3\" />\r\n </svg>\r\n)\r\n"],"names":["IconQuickEdit","props","jsxs","jsx"],"mappings":";AAEO,MAAMA,IAAgB,CAACC,MAC5BC,gBAAAA;AAAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,gBAAa;AAAA,IACb,kBAAe;AAAA,IACf,mBAAgB;AAAA,IACf,GAAGD;AAAA,IACJ,OAAO,iEAAiEA,EAAM,aAAa,EAAE;AAAA,IAE7F,UAAA;AAAA,MAAA,gBAAAE,EAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,MAClD,gBAAAA,EAAC,QAAA,EAAK,GAAE,0DAAA,CAA0D;AAAA,MAClE,gBAAAA,EAAC,QAAA,EAAK,GAAE,gBAAA,CAAgB;AAAA,MACxB,gBAAAA,EAAC,QAAA,EAAK,GAAE,qBAAA,CAAqB;AAAA,IAAA;AAAA,EAAA;AAC/B;"}
1
+ {"version":3,"file":"IconQuickEdit-CAL1HXIb.js","sources":["../src/components/Icon/IconQuickEdit.tsx"],"sourcesContent":["import { SVGProps } from 'jsx-dom'\n\nexport const IconQuickEdit = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n {...props}\n class={`icon icon-tabler icons-tabler-outline icon-tabler-pencil-bolt ${props.className || ''}`}\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\" />\n <path d=\"M13.5 6.5l4 4\" />\n <path d=\"M19 16l-2 3h4l-2 3\" />\n </svg>\n)\n"],"names":["IconQuickEdit","props","jsxs","jsx"],"mappings":";AAEO,MAAMA,IAAgB,CAACC,MAC5BC,gBAAAA;AAAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,gBAAa;AAAA,IACb,kBAAe;AAAA,IACf,mBAAgB;AAAA,IACf,GAAGD;AAAA,IACJ,OAAO,iEAAiEA,EAAM,aAAa,EAAE;AAAA,IAE7F,UAAA;AAAA,MAAA,gBAAAE,EAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,MAClD,gBAAAA,EAAC,QAAA,EAAK,GAAE,0DAAA,CAA0D;AAAA,MAClE,gBAAAA,EAAC,QAAA,EAAK,GAAE,gBAAA,CAAgB;AAAA,MACxB,gBAAAA,EAAC,QAAA,EAAK,GAAE,qBAAA,CAAqB;AAAA,IAAA;AAAA,EAAA;AAC/B;"}
@@ -1 +1 @@
1
- {"version":3,"file":"InputBox-BV4m05Xs.js","sources":["../src/components/InputBox.tsx"],"sourcesContent":["import { JSX } from 'jsx-dom'\r\n\r\nexport type InputBoxProps = {\r\n label: string\r\n id?: string\r\n name: string\r\n value?: string\r\n disabled?: boolean\r\n labelProps?: JSX.IntrinsicElements['label']\r\n inputProps?: JSX.IntrinsicElements['input']\r\n} & JSX.IntrinsicElements['div']\r\n\r\nexport const InputBox = (props: InputBoxProps) => {\r\n const { label, id, name, value, disabled, labelProps, inputProps, ...rest } = props\r\n return (\r\n <div className=\"theme-ipe ipe-input-box\" {...rest}>\r\n <label htmlFor={id} style={{ display: 'block' }} {...labelProps}>\r\n {label}\r\n </label>\r\n <input\r\n id={id}\r\n name={name}\r\n value={value}\r\n disabled={disabled}\r\n style={{ width: '100%' }}\r\n {...inputProps}\r\n />\r\n </div>\r\n )\r\n}\r\n"],"names":["InputBox","props","label","id","name","value","disabled","labelProps","inputProps","rest","jsxs","jsx"],"mappings":";AAYO,MAAMA,IAAW,CAACC,MAAyB;AAChD,QAAM,EAAE,OAAAC,GAAO,IAAAC,GAAI,MAAAC,GAAM,OAAAC,GAAO,UAAAC,GAAU,YAAAC,GAAY,YAAAC,GAAY,GAAGC,EAAA,IAASR;AAC9E,SACES,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BAA2B,GAAGD,GAC3C,UAAA;AAAA,IAAA,gBAAAE,EAAC,SAAA,EAAM,SAASR,GAAI,OAAO,EAAE,SAAS,QAAA,GAAY,GAAGI,GAClD,UAAAL,EAAA,CACH;AAAA,IACA,gBAAAS;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAAR;AAAA,QACA,MAAAC;AAAA,QACA,OAAAC;AAAA,QACA,UAAAC;AAAA,QACA,OAAO,EAAE,OAAO,OAAA;AAAA,QACf,GAAGE;AAAA,MAAA;AAAA,IAAA;AAAA,EACN,GACF;AAEJ;"}
1
+ {"version":3,"file":"InputBox-BV4m05Xs.js","sources":["../src/components/InputBox.tsx"],"sourcesContent":["import { JSX } from 'jsx-dom'\n\nexport type InputBoxProps = {\n label: string\n id?: string\n name: string\n value?: string\n disabled?: boolean\n labelProps?: JSX.IntrinsicElements['label']\n inputProps?: JSX.IntrinsicElements['input']\n} & JSX.IntrinsicElements['div']\n\nexport const InputBox = (props: InputBoxProps) => {\n const { label, id, name, value, disabled, labelProps, inputProps, ...rest } = props\n return (\n <div className=\"theme-ipe ipe-input-box\" {...rest}>\n <label htmlFor={id} style={{ display: 'block' }} {...labelProps}>\n {label}\n </label>\n <input\n id={id}\n name={name}\n value={value}\n disabled={disabled}\n style={{ width: '100%' }}\n {...inputProps}\n />\n </div>\n )\n}\n"],"names":["InputBox","props","label","id","name","value","disabled","labelProps","inputProps","rest","jsxs","jsx"],"mappings":";AAYO,MAAMA,IAAW,CAACC,MAAyB;AAChD,QAAM,EAAE,OAAAC,GAAO,IAAAC,GAAI,MAAAC,GAAM,OAAAC,GAAO,UAAAC,GAAU,YAAAC,GAAY,YAAAC,GAAY,GAAGC,EAAA,IAASR;AAC9E,SACES,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BAA2B,GAAGD,GAC3C,UAAA;AAAA,IAAA,gBAAAE,EAAC,SAAA,EAAM,SAASR,GAAI,OAAO,EAAE,SAAS,QAAA,GAAY,GAAGI,GAClD,UAAAL,EAAA,CACH;AAAA,IACA,gBAAAS;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAAR;AAAA,QACA,MAAAC;AAAA,QACA,OAAAC;AAAA,QACA,UAAAC;AAAA,QACA,OAAO,EAAE,OAAO,OAAA;AAAA,QACf,GAAGE;AAAA,MAAA;AAAA,IAAA;AAAA,EACN,GACF;AAEJ;"}
@@ -0,0 +1,254 @@
1
+ import { j as s } from "./index-CvhkVj_L.js";
2
+ import { B as I, S as d, W as E, I as k } from "./index-DFPN4uYd.js";
3
+ var U = Object.create, u = Object.defineProperty, j = Object.getOwnPropertyDescriptor, b = (o, e) => (e = Symbol[o]) ? e : Symbol.for("Symbol." + o), w = (o) => {
4
+ throw TypeError(o);
5
+ }, C = (o, e, r) => e in o ? u(o, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : o[e] = r, T = (o, e) => u(o, "name", { value: e, configurable: !0 }), F = (o) => [, , , U(o?.[b("metadata")] ?? null)], L = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], v = (o) => o !== void 0 && typeof o != "function" ? w("Function expected") : o, O = (o, e, r, n, t) => ({ kind: L[o], name: e, metadata: n, addInitializer: (a) => r._ ? w("Already initialized") : t.push(v(a || null)) }), D = (o, e) => C(e, b("metadata"), o[3]), B = (o, e, r, n) => {
6
+ for (var t = 0, a = o[e >> 1], i = a && a.length; t < i; t++) a[t].call(r);
7
+ return n;
8
+ }, M = (o, e, r, n, t, a) => {
9
+ var i, l, m, c = e & 7, y = !1, x = 0, P = o[x] || (o[x] = []), p = c && (t = t.prototype, c < 5 && (c > 3 || !y) && j(t, r));
10
+ T(t, r);
11
+ for (var f = n.length - 1; f >= 0; f--)
12
+ m = O(c, r, l = {}, o[3], P), i = (0, n[f])(t, m), l._ = 1, v(i) && (t = i);
13
+ return D(o, t), p && u(t, r, p), y ? c ^ 4 ? a : p : t;
14
+ }, S, h, _;
15
+ S = [k(["preferences", "wikiPage", "wikiTitle", "modal", "preferencesUI"])];
16
+ class g extends (_ = I) {
17
+ constructor(e) {
18
+ super(e, {}, "pref-sync"), this.ctx = e, e.set("prefSync", this);
19
+ }
20
+ start() {
21
+ const e = this.ctx;
22
+ e.preferences.defineCategory({
23
+ name: "pref-sync",
24
+ label: "Sync",
25
+ description: "Import and export preferences",
26
+ index: 98
27
+ }), e.preferences.registerCustomConfig(
28
+ "pref-sync-user-page",
29
+ d.object({
30
+ "pref-sync-user-page": d.const(
31
+ /* @__PURE__ */ s("section", { children: /* @__PURE__ */ s("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
32
+ /* @__PURE__ */ s(
33
+ "button",
34
+ {
35
+ onClick: (r) => {
36
+ r.preventDefault();
37
+ const n = e.preferencesUI.getExistingModal(), t = r.target;
38
+ t.disabled = !0, n?.setLoadingState(!0), this.importFromUserPage().then((a) => {
39
+ this.notifyImportSuccess(a), n?.close?.();
40
+ }).finally(() => {
41
+ t.disabled = !1, n?.setLoadingState(!1);
42
+ });
43
+ },
44
+ children: "Import"
45
+ }
46
+ ),
47
+ /* @__PURE__ */ s(
48
+ "button",
49
+ {
50
+ onClick: (r) => {
51
+ r.preventDefault();
52
+ const n = r.target;
53
+ n.disabled = !0;
54
+ const t = e.preferencesUI.getExistingModal();
55
+ t?.setLoadingState(!0), this.exportToUserPage().then((a) => {
56
+ e.modal.notify("success", {
57
+ title: "Preferences Exported",
58
+ content: /* @__PURE__ */ s("p", { children: [
59
+ "Your preferences have been exported to",
60
+ " ",
61
+ /* @__PURE__ */ s("a", { href: a.getURL().toString(), target: "_blank", children: a.getPrefixedText() }),
62
+ "."
63
+ ] })
64
+ }), t?.close?.();
65
+ }).finally(() => {
66
+ n.disabled = !1, t?.setLoadingState(!1);
67
+ });
68
+ },
69
+ children: "Export"
70
+ }
71
+ )
72
+ ] }) })
73
+ ).role("raw-html")
74
+ }).description("Backup your preferences via user page"),
75
+ "pref-sync"
76
+ ), e.preferences.registerCustomConfig(
77
+ "pref-sync-manual",
78
+ d.object({
79
+ "pref-sync-manual": d.const(
80
+ /* @__PURE__ */ s("section", { children: /* @__PURE__ */ s("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
81
+ /* @__PURE__ */ s(
82
+ "button",
83
+ {
84
+ onClick: (r) => {
85
+ r.preventDefault();
86
+ const n = e.preferencesUI.getExistingModal();
87
+ n?.setLoadingState(!0);
88
+ const t = document.createElement("input");
89
+ t.type = "file", t.accept = "application/json", t.addEventListener("change", async (a) => {
90
+ try {
91
+ const i = a.target.files?.[0];
92
+ if (!i)
93
+ return;
94
+ const l = await this.importFromFile(i);
95
+ this.notifyImportSuccess(l), n?.close?.();
96
+ } catch (i) {
97
+ e.modal.notify("error", {
98
+ title: "Import failed",
99
+ content: i instanceof Error ? i.message : String(i)
100
+ });
101
+ } finally {
102
+ n?.setLoadingState(!1);
103
+ }
104
+ }), t.addEventListener("cancel", () => {
105
+ n?.setLoadingState(!1);
106
+ }), t.click();
107
+ },
108
+ children: "Import from file"
109
+ }
110
+ ),
111
+ /* @__PURE__ */ s(
112
+ "button",
113
+ {
114
+ onClick: async (r) => {
115
+ r.preventDefault();
116
+ const n = await e.preferences.getExportableRecord(), t = JSON.stringify(n, null, 2);
117
+ e.modal.dialog(
118
+ {
119
+ title: "Save to file",
120
+ content: /* @__PURE__ */ s("div", { children: [
121
+ /* @__PURE__ */ s("label", { htmlFor: "data", children: "Your InPageEdit preferences:" }),
122
+ /* @__PURE__ */ s(
123
+ "textarea",
124
+ {
125
+ name: "data",
126
+ id: "data",
127
+ rows: 10,
128
+ value: t,
129
+ readOnly: !0,
130
+ style: { width: "100%" }
131
+ }
132
+ )
133
+ ] }),
134
+ buttons: [
135
+ {
136
+ label: "Copy",
137
+ method: () => {
138
+ navigator.clipboard.writeText(t), e.modal.notify("success", {
139
+ content: "Copied to clipboard"
140
+ });
141
+ }
142
+ },
143
+ {
144
+ label: "Download",
145
+ method: () => {
146
+ const a = document.createElement("a");
147
+ a.href = `data:text/json;charset=utf-8,${encodeURIComponent(t)}`, a.download = `ipe-prefs-${(/* @__PURE__ */ new Date()).toISOString()}.json`, a.click();
148
+ }
149
+ }
150
+ ]
151
+ },
152
+ () => {
153
+ }
154
+ );
155
+ },
156
+ children: "Save to file"
157
+ }
158
+ )
159
+ ] }) })
160
+ ).role("raw-html")
161
+ }).description("Backup your preferences to file"),
162
+ "pref-sync"
163
+ );
164
+ }
165
+ stop() {
166
+ }
167
+ /**
168
+ * 获取用户页配置文件的标题
169
+ */
170
+ getUserPrefsPageTitle() {
171
+ try {
172
+ const e = this.ctx.wiki?.userInfo?.name;
173
+ return e ? this.ctx.wikiTitle.newTitle(`User:${e}/ipe-prefs.json`, 2) : null;
174
+ } catch {
175
+ return null;
176
+ }
177
+ }
178
+ /**
179
+ * 从用户页加载配置
180
+ */
181
+ async importFromUserPage() {
182
+ const e = this.getUserPrefsPageTitle();
183
+ if (!e)
184
+ return this.logger.debug("Cannot get user page title, skipping load"), {};
185
+ try {
186
+ const r = e.getURL({ action: "raw", ctype: "application/json" });
187
+ let n;
188
+ try {
189
+ if (n = await fetch(r.toString()), !n.ok) {
190
+ if (n.status === 404)
191
+ return this.logger.debug("User preferences page does not exist"), {};
192
+ throw new Error(`HTTP ${n.status}: ${n.statusText}`);
193
+ }
194
+ } catch (i) {
195
+ if (i instanceof TypeError && i.message.includes("Failed to fetch"))
196
+ return this.logger.debug("User preferences page does not exist or network error"), {};
197
+ throw i;
198
+ }
199
+ const t = await n.blob(), a = await this.importFromFile(t);
200
+ return this.logger.info("Loaded preferences from user page:", e), a;
201
+ } catch (r) {
202
+ return this.logger.error("Failed to load preferences from user page:", r), {};
203
+ }
204
+ }
205
+ /**
206
+ * 导出配置到用户页
207
+ */
208
+ async exportToUserPage() {
209
+ const e = this.ctx, r = this.getUserPrefsPageTitle();
210
+ if (!r)
211
+ throw new Error("Cannot get user page title");
212
+ const n = await e.preferences.getExportableRecord(), t = JSON.stringify(n, null, 2);
213
+ try {
214
+ return await this.ctx.wikiPage.newBlankPage({
215
+ title: r.toString(),
216
+ ns: 2
217
+ // User namespace
218
+ }).edit({
219
+ text: t,
220
+ summary: "Update InPageEdit preferences",
221
+ watchlist: E.nochange
222
+ }), this.logger.info("Exported preferences to user page:", r), r;
223
+ } catch (a) {
224
+ throw this.logger.error("Failed to export preferences to user page:", a), a;
225
+ }
226
+ }
227
+ async importFromFile(e) {
228
+ const r = await e.text(), n = JSON.parse(r);
229
+ return await this.ctx.preferences.setMany(n);
230
+ }
231
+ notifyImportSuccess(e) {
232
+ const r = Object.keys(e ?? {}), n = r.length;
233
+ return this.ctx.modal.notify("success", {
234
+ title: "Preferences Imported",
235
+ content: /* @__PURE__ */ s("section", { children: [
236
+ /* @__PURE__ */ s("p", { children: [
237
+ "Successfully imported ",
238
+ n || "",
239
+ " ",
240
+ n !== 1 ? "settings" : "setting",
241
+ ":"
242
+ ] }),
243
+ /* @__PURE__ */ s("ol", { style: { listStyle: "auto", paddingLeft: "1em" }, children: r.map((t) => /* @__PURE__ */ s("li", { children: t }, t)) })
244
+ ] })
245
+ });
246
+ }
247
+ }
248
+ h = F(_);
249
+ g = M(h, 0, "PluginPrefSync", S, g);
250
+ B(h, 1, g);
251
+ export {
252
+ g as PluginPrefSync
253
+ };
254
+ //# sourceMappingURL=PluginPrefSync-PIoKRRu2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginPrefSync-PIoKRRu2.js","sources":["../src/plugins/preferences-ui/PluginPrefSync.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema } from '@/InPageEdit.js'\nimport { WatchlistAction } from '@/models/WikiPage/types/WatchlistAction.js'\nimport { IWikiTitle } from '@/models/WikiTitle/index.js'\n\ndeclare module '@/InPageEdit' {\n export interface InPageEdit {\n prefSync: PluginPrefSync\n }\n}\n\n@Inject(['preferences', 'wikiPage', 'wikiTitle', 'modal', 'preferencesUI'])\nexport class PluginPrefSync extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'pref-sync')\n ctx.set('prefSync', this)\n }\n\n protected start(): Promise<void> | void {\n const ctx = this.ctx\n ctx.preferences.defineCategory({\n name: 'pref-sync',\n label: 'Sync',\n description: 'Import and export preferences',\n index: 98,\n })\n ctx.preferences.registerCustomConfig(\n 'pref-sync-user-page',\n Schema.object({\n 'pref-sync-user-page': Schema.const(\n <section>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <button\n onClick={(e) => {\n e.preventDefault()\n const modal = ctx.preferencesUI.getExistingModal()\n const btn = e.target as HTMLButtonElement\n btn.disabled = true\n modal?.setLoadingState(true)\n this.importFromUserPage()\n .then((record) => {\n this.notifyImportSuccess(record)\n modal?.close?.()\n })\n .finally(() => {\n btn.disabled = false\n modal?.setLoadingState(false)\n })\n }}\n >\n Import\n </button>\n <button\n onClick={(e) => {\n e.preventDefault()\n const btn = e.target as HTMLButtonElement\n btn.disabled = true\n const modal = ctx.preferencesUI.getExistingModal()\n modal?.setLoadingState(true)\n this.exportToUserPage()\n .then((title) => {\n ctx.modal.notify('success', {\n title: 'Preferences Exported',\n content: (\n <p>\n Your preferences have been exported to{' '}\n <a href={title.getURL().toString()} target=\"_blank\">\n {title.getPrefixedText()}\n </a>\n .\n </p>\n ),\n })\n modal?.close?.()\n })\n .finally(() => {\n btn.disabled = false\n modal?.setLoadingState(false)\n })\n }}\n >\n Export\n </button>\n </div>\n </section>\n ).role('raw-html'),\n }).description('Backup your preferences via user page'),\n 'pref-sync'\n )\n ctx.preferences.registerCustomConfig(\n 'pref-sync-manual',\n Schema.object({\n 'pref-sync-manual': Schema.const(\n <section>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <button\n onClick={(e) => {\n e.preventDefault()\n const modal = ctx.preferencesUI.getExistingModal()\n modal?.setLoadingState(true)\n const input = document.createElement('input')\n input.type = 'file'\n input.accept = 'application/json'\n input.addEventListener('change', async (e) => {\n try {\n const file = (e.target as HTMLInputElement).files?.[0]\n if (!file) {\n return\n }\n const record = await this.importFromFile(file)\n this.notifyImportSuccess(record)\n modal?.close?.()\n } catch (e) {\n ctx.modal.notify('error', {\n title: 'Import failed',\n content: e instanceof Error ? e.message : String(e),\n })\n } finally {\n modal?.setLoadingState(false)\n }\n })\n input.addEventListener('cancel', () => {\n modal?.setLoadingState(false)\n })\n input.click()\n }}\n >\n Import from file\n </button>\n <button\n onClick={async (e) => {\n e.preventDefault()\n const data = await ctx.preferences.getExportableRecord()\n const json = JSON.stringify(data, null, 2)\n ctx.modal.dialog(\n {\n title: 'Save to file',\n content: (\n <div>\n <label htmlFor=\"data\">Your InPageEdit preferences:</label>\n <textarea\n name=\"data\"\n id=\"data\"\n rows={10}\n value={json}\n readOnly\n style={{ width: '100%' }}\n ></textarea>\n </div>\n ),\n buttons: [\n {\n label: 'Copy',\n method: () => {\n navigator.clipboard.writeText(json)\n ctx.modal.notify('success', {\n content: 'Copied to clipboard',\n })\n },\n },\n {\n label: 'Download',\n method: () => {\n const a = document.createElement('a')\n a.href = `data:text/json;charset=utf-8,${encodeURIComponent(json)}`\n a.download = `ipe-prefs-${new Date().toISOString()}.json`\n a.click()\n },\n },\n ],\n },\n () => {}\n )\n }}\n >\n Save to file\n </button>\n </div>\n </section>\n ).role('raw-html'),\n }).description('Backup your preferences to file'),\n 'pref-sync'\n )\n }\n\n protected stop(): Promise<void> | void {}\n\n /**\n * 获取用户页配置文件的标题\n */\n private getUserPrefsPageTitle(): IWikiTitle | null {\n try {\n const userName = this.ctx.wiki?.userInfo?.name\n if (!userName) {\n return null\n }\n // 使用 User: 命名空间\n return this.ctx.wikiTitle.newTitle(`User:${userName}/ipe-prefs.json`, 2)\n } catch {\n return null\n }\n }\n\n /**\n * 从用户页加载配置\n */\n async importFromUserPage(): Promise<Record<string, unknown>> {\n const title = this.getUserPrefsPageTitle()\n if (!title) {\n this.logger.debug('Cannot get user page title, skipping load')\n return {}\n }\n\n try {\n // 使用 raw action 获取 JSON 内容\n const rawUrl = title.getURL({ action: 'raw', ctype: 'application/json' })\n\n let response: Response\n try {\n response = await fetch(rawUrl.toString())\n if (!response.ok) {\n if (response.status === 404) {\n this.logger.debug('User preferences page does not exist')\n return {}\n }\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n } catch (error) {\n if (error instanceof TypeError && error.message.includes('Failed to fetch')) {\n this.logger.debug('User preferences page does not exist or network error')\n return {}\n }\n throw error\n }\n\n const blob = await response.blob()\n const changed = await this.importFromFile(blob)\n this.logger.info('Loaded preferences from user page:', title)\n return changed\n } catch (error) {\n this.logger.error('Failed to load preferences from user page:', error)\n return {}\n }\n }\n\n /**\n * 导出配置到用户页\n */\n async exportToUserPage(): Promise<IWikiTitle> {\n const ctx = this.ctx\n const title = this.getUserPrefsPageTitle()\n if (!title) {\n throw new Error('Cannot get user page title')\n }\n\n const json = await ctx.preferences.getExportableRecord()\n const text = JSON.stringify(json, null, 2)\n\n try {\n const page = this.ctx.wikiPage.newBlankPage({\n title: title.toString(),\n ns: 2, // User namespace\n })\n await page.edit({\n text,\n summary: 'Update InPageEdit preferences',\n watchlist: WatchlistAction.nochange,\n })\n\n this.logger.info('Exported preferences to user page:', title)\n return title\n } catch (error) {\n this.logger.error('Failed to export preferences to user page:', error)\n throw error\n }\n }\n\n async importFromFile(input: Blob): Promise<Record<string, unknown>> {\n const text = await input.text()\n const data = JSON.parse(text)\n const changed = await this.ctx.preferences.setMany(data)\n return changed\n }\n\n private notifyImportSuccess(configs?: Record<string, unknown>) {\n const keys = Object.keys(configs ?? {})\n const count = keys.length\n return this.ctx.modal.notify('success', {\n title: 'Preferences Imported',\n content: (\n <section>\n <p>\n Successfully imported {count || ''} {count !== 1 ? 'settings' : 'setting'}:\n </p>\n <ol style={{ listStyle: 'auto', paddingLeft: '1em' }}>\n {keys.map((key) => (\n <li key={key}>{key}</li>\n ))}\n </ol>\n </section>\n ),\n })\n }\n}\n"],"names":["_PluginPrefSync_decorators","_init","_a","Inject","PluginPrefSync","BasePlugin","ctx","Schema","jsx","jsxs","e","modal","btn","record","title","input","file","data","json","userName","rawUrl","response","error","blob","changed","text","WatchlistAction","configs","keys","count","key","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Preferences-DS4-CFWe.js","sources":["../src/decorators/Preferences.ts"],"sourcesContent":["import type Schema from 'schemastery'\r\n\r\ntype AnyConstructor<T = any> = new (...args: any[]) => T\r\n\r\nexport type PreferenceAugmented<D, C extends AnyConstructor> = C & {\r\n PreferencesSchema: Schema<D>\r\n}\r\n\r\n/**\r\n * Decorator for registering preferences\r\n *\r\n * ```ts\r\n * @RegisterPreferences(\r\n * Schema.object({\r\n * foo: Schema.string().description('Foo description'),\r\n * }),\r\n * {\r\n * foo: 'default foo value',\r\n * }\r\n * )\r\n * class Foo {}\r\n * ```\r\n *\r\n * same as:\r\n *\r\n * ```ts\r\n * class Foo {\r\n * static ConfigSchema = Schema.object({\r\n * foo: Schema.string().description('Foo description')\r\n * })\r\n * static ConfigDefaults = {\r\n * foo: 'default foo value'\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function RegisterPreferences<D extends Record<string, any>>(schema: Schema<D>) {\r\n return function <T extends AnyConstructor>(target: T): PreferenceAugmented<D, T> {\r\n ;(target as any).PreferencesSchema = schema\r\n return target as PreferenceAugmented<D, T>\r\n }\r\n}\r\n"],"names":["RegisterPreferences","schema","target"],"mappings":"AAoCO,SAASA,EAAmDC,GAAmB;AACpF,SAAO,SAAoCC,GAAsC;AAC7E,WAAAA,EAAe,oBAAoBD,GAC9BC;AAAA,EACT;AACF;"}
1
+ {"version":3,"file":"Preferences-DS4-CFWe.js","sources":["../src/decorators/Preferences.ts"],"sourcesContent":["import type Schema from 'schemastery'\n\ntype AnyConstructor<T = any> = new (...args: any[]) => T\n\nexport type PreferenceAugmented<D, C extends AnyConstructor> = C & {\n PreferencesSchema: Schema<D>\n}\n\n/**\n * Decorator for registering preferences\n *\n * ```ts\n * @RegisterPreferences(\n * Schema.object({\n * foo: Schema.string().description('Foo description'),\n * }),\n * {\n * foo: 'default foo value',\n * }\n * )\n * class Foo {}\n * ```\n *\n * same as:\n *\n * ```ts\n * class Foo {\n * static ConfigSchema = Schema.object({\n * foo: Schema.string().description('Foo description')\n * })\n * static ConfigDefaults = {\n * foo: 'default foo value'\n * }\n * }\n * ```\n */\nexport function RegisterPreferences<D extends Record<string, any>>(schema: Schema<D>) {\n return function <T extends AnyConstructor>(target: T): PreferenceAugmented<D, T> {\n ;(target as any).PreferencesSchema = schema\n return target as PreferenceAugmented<D, T>\n }\n}\n"],"names":["RegisterPreferences","schema","target"],"mappings":"AAoCO,SAASA,EAAmDC,GAAmB;AACpF,SAAO,SAAoCC,GAAsC;AAC7E,WAAAA,EAAe,oBAAoBD,GAC9BC;AAAA,EACT;AACF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"RadioBox-nJqWsxW2.js","sources":["../src/components/RadioBox.tsx"],"sourcesContent":["import { JSX, ReactNode } from 'jsx-dom'\r\n\r\nexport type RadioBoxProps = {\r\n id?: string\r\n name: string\r\n value: string\r\n label?: string | HTMLElement\r\n inputProps?: JSX.IntrinsicElements['input']\r\n labelProps?: JSX.IntrinsicElements['span']\r\n} & JSX.IntrinsicElements['label']\r\n\r\nexport const RadioBox = (props: RadioBoxProps) => {\r\n const { id, name, value, label, inputProps, labelProps, children, ...rest } = props\r\n return (\r\n <label className=\"theme-ipe ipe-radio-box\" {...rest}>\r\n <input type=\"radio\" id={id} name={name} value={value} {...inputProps} />\r\n <span className=\"ipe-checkbox-box\"></span>\r\n <span {...labelProps}>{label || children}</span>\r\n </label>\r\n )\r\n}\r\n"],"names":["RadioBox","props","id","name","value","label","inputProps","labelProps","children","rest","jsxs","jsx"],"mappings":";AAWO,MAAMA,IAAW,CAACC,MAAyB;AAChD,QAAM,EAAE,IAAAC,GAAI,MAAAC,GAAM,OAAAC,GAAO,OAAAC,GAAO,YAAAC,GAAY,YAAAC,GAAY,UAAAC,GAAU,GAAGC,EAAA,IAASR;AAC9E,SACES,gBAAAA,EAAC,SAAA,EAAM,WAAU,2BAA2B,GAAGD,GAC7C,UAAA;AAAA,IAAA,gBAAAE,EAAC,WAAM,MAAK,SAAQ,IAAAT,GAAQ,MAAAC,GAAY,OAAAC,GAAe,GAAGE,GAAY;AAAA,IACtE,gBAAAK,EAAC,QAAA,EAAK,WAAU,mBAAA,CAAmB;AAAA,IACnC,gBAAAA,EAAC,QAAA,EAAM,GAAGJ,GAAa,eAASC,EAAA,CAAS;AAAA,EAAA,GAC3C;AAEJ;"}
1
+ {"version":3,"file":"RadioBox-nJqWsxW2.js","sources":["../src/components/RadioBox.tsx"],"sourcesContent":["import { JSX } from 'jsx-dom'\n\nexport type RadioBoxProps = {\n id?: string\n name: string\n value: string\n label?: string | HTMLElement\n inputProps?: JSX.IntrinsicElements['input']\n labelProps?: JSX.IntrinsicElements['span']\n} & JSX.IntrinsicElements['label']\n\nexport const RadioBox = (props: RadioBoxProps) => {\n const { id, name, value, label, inputProps, labelProps, children, ...rest } = props\n return (\n <label className=\"theme-ipe ipe-radio-box\" {...rest}>\n <input type=\"radio\" id={id} name={name} value={value} {...inputProps} />\n <span className=\"ipe-checkbox-box\"></span>\n <span {...labelProps}>{label || children}</span>\n </label>\n )\n}\n"],"names":["RadioBox","props","id","name","value","label","inputProps","labelProps","children","rest","jsxs","jsx"],"mappings":";AAWO,MAAMA,IAAW,CAACC,MAAyB;AAChD,QAAM,EAAE,IAAAC,GAAI,MAAAC,GAAM,OAAAC,GAAO,OAAAC,GAAO,YAAAC,GAAY,YAAAC,GAAY,UAAAC,GAAU,GAAGC,EAAA,IAASR;AAC9E,SACES,gBAAAA,EAAC,SAAA,EAAM,WAAU,2BAA2B,GAAGD,GAC7C,UAAA;AAAA,IAAA,gBAAAE,EAAC,WAAM,MAAK,SAAQ,IAAAT,GAAQ,MAAAC,GAAY,OAAAC,GAAe,GAAGE,GAAY;AAAA,IACtE,gBAAAK,EAAC,QAAA,EAAK,WAAU,mBAAA,CAAmB;AAAA,IACnC,gBAAAA,EAAC,QAAA,EAAM,GAAGJ,GAAa,eAASC,EAAA,CAAS;AAAA,EAAA,GAC3C;AAEJ;"}
@@ -1,2 +1,3 @@
1
- import { WikiMetadata } from '../../types/WikiMetadata.js';
2
- export declare const MOCK_SITE_METADATA: WikiMetadata;
1
+ import { WikiSiteInfo, WikiUserInfo } from '../../types/WikiMetadata.js';
2
+ export declare const MOCK_SITE_INFO: WikiSiteInfo;
3
+ export declare const MOCK_USER_INFO: WikiUserInfo;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/components/TabView/index.tsx"],"sourcesContent":["import { ReactNode } from 'jsx-dom'\r\nimport styles from './styles.module.sass'\r\n\r\nexport interface TabViewLabelOptions {\r\n name: string\r\n children: ReactNode\r\n}\r\n\r\nconsole.log(styles)\r\n\r\nexport function TabView({\r\n tabs = [],\r\n defaultActiveIndex = 0,\r\n}: {\r\n tabs: (TabViewLabelOptions & { content: ReactNode })[]\r\n defaultActiveIndex?: number\r\n}) {\r\n const el = (\r\n <div className={`ipe-tabView ${styles.tabview}`}>\r\n <ul className={`ipe-tabView__labels-container ${styles.labels_container}`}>\r\n {tabs.map((tab) => (\r\n <TabLabel key={tab.name} name={tab.name}>\r\n {tab.children}\r\n </TabLabel>\r\n ))}\r\n </ul>\r\n <div className={`ipe-tabView__contents ${styles.contents_container}`}>\r\n {tabs.map((tab) => (\r\n <TabContent key={tab.name} name={tab.name}>\r\n {tab.content}\r\n </TabContent>\r\n ))}\r\n </div>\r\n </div>\r\n )\r\n\r\n const defaultActiveLabel = el.querySelector<HTMLAnchorElement>(\r\n `.ipe-tabView__labels-container > .ipe-tabView__label:nth-child(${defaultActiveIndex + 1})`\r\n )\r\n if (defaultActiveLabel) {\r\n defaultActiveLabel.click()\r\n }\r\n\r\n return el\r\n}\r\n\r\nexport function TabLabel({ name, children }: { name: string; children: ReactNode }) {\r\n return (\r\n <li\r\n data-tab-name={name}\r\n className={`ipe-tabView__label ${styles.label}`}\r\n onClick={function (e) {\r\n e.preventDefault()\r\n const container = this.closest('.ipe-tabView')\r\n if (!container) return\r\n const labels = Array.from(container.children).find((el) =>\r\n el.classList.contains('ipe-tabView__labels')\r\n )?.children\r\n if (labels) {\r\n Array.from(labels).forEach((label) => {\r\n label.classList.remove(styles.active)\r\n })\r\n }\r\n this.classList.add(styles.active)\r\n const contents = Array.from(container.children).find((el) =>\r\n el.classList.contains('ipe-tabView__contents')\r\n )?.children\r\n if (contents) {\r\n Array.from(contents).forEach((content) => {\r\n if (content instanceof HTMLElement) {\r\n if (content.dataset.tabName === name) {\r\n content.style.display = ''\r\n content.classList.add(styles.active)\r\n } else {\r\n content.style.display = 'none'\r\n content.classList.remove(styles.active)\r\n }\r\n }\r\n })\r\n }\r\n }}\r\n >\r\n <a>{children || name}</a>\r\n </li>\r\n )\r\n}\r\n\r\nexport function TabContent({ name, children }: { name: string; children: ReactNode }) {\r\n return (\r\n <div\r\n data-tab-name={name}\r\n className=\"ipe-tabView__content-body\"\r\n style={{\r\n display: 'none',\r\n }}\r\n >\r\n {children}\r\n </div>\r\n )\r\n}\r\n"],"names":["TabView","tabs","defaultActiveIndex","el","jsxs","styles","jsx","tab","TabLabel","TabContent","defaultActiveLabel","name","children","e","container","labels","label","contents","content"],"mappings":";;;;;;;;;;;;;;;AAUO,SAASA,EAAQ;AAAA,EACtB,MAAAC,IAAO,CAAA;AAAA,EACP,oBAAAC,IAAqB;AACvB,GAGG;AACD,QAAMC,IACJC,gBAAAA,EAAC,OAAA,EAAI,WAAW,eAAeC,EAAO,OAAO,IAC3C,UAAA;AAAA,IAAA,gBAAAC,EAAC,MAAA,EAAG,WAAW,iCAAiCD,EAAO,gBAAgB,IACpE,UAAAJ,EAAK,IAAI,CAACM,wBACRC,GAAA,EAAwB,MAAMD,EAAI,MAChC,UAAAA,EAAI,YADQA,EAAI,IAEnB,CACD,EAAA,CACH;AAAA,IACA,gBAAAD,EAAC,SAAI,WAAW,yBAAyBD,EAAO,kBAAkB,IAC/D,YAAK,IAAI,CAACE,MACT,gBAAAD,EAACG,GAAA,EAA0B,MAAMF,EAAI,MAClC,YAAI,QAAA,GADUA,EAAI,IAErB,CACD,EAAA,CACH;AAAA,EAAA,GACF,GAGIG,IAAqBP,EAAG;AAAA,IAC5B,kEAAkED,IAAqB,CAAC;AAAA,EAAA;AAE1F,SAAIQ,KACFA,EAAmB,MAAA,GAGdP;AACT;AAEO,SAASK,EAAS,EAAE,MAAAG,GAAM,UAAAC,KAAmD;AAClF,SACE,gBAAAN;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,iBAAeK;AAAA,MACf,WAAW,sBAAsBN,EAAO,KAAK;AAAA,MAC7C,SAAS,SAAUQ,GAAG;AACpB,QAAAA,EAAE,eAAA;AACF,cAAMC,IAAY,KAAK,QAAQ,cAAc;AAC7C,YAAI,CAACA,EAAW;AAChB,cAAMC,IAAS,MAAM,KAAKD,EAAU,QAAQ,EAAE;AAAA,UAAK,CAACX,MAClDA,EAAG,UAAU,SAAS,qBAAqB;AAAA,QAAA,GAC1C;AACH,QAAIY,KACF,MAAM,KAAKA,CAAM,EAAE,QAAQ,CAACC,MAAU;AACpC,UAAAA,EAAM,UAAU,OAAOX,EAAO,MAAM;AAAA,QACtC,CAAC,GAEH,KAAK,UAAU,IAAIA,EAAO,MAAM;AAChC,cAAMY,IAAW,MAAM,KAAKH,EAAU,QAAQ,EAAE;AAAA,UAAK,CAACX,MACpDA,EAAG,UAAU,SAAS,uBAAuB;AAAA,QAAA,GAC5C;AACH,QAAIc,KACF,MAAM,KAAKA,CAAQ,EAAE,QAAQ,CAACC,MAAY;AACxC,UAAIA,aAAmB,gBACjBA,EAAQ,QAAQ,YAAYP,KAC9BO,EAAQ,MAAM,UAAU,IACxBA,EAAQ,UAAU,IAAIb,EAAO,MAAM,MAEnCa,EAAQ,MAAM,UAAU,QACxBA,EAAQ,UAAU,OAAOb,EAAO,MAAM;AAAA,QAG5C,CAAC;AAAA,MAEL;AAAA,MAEA,UAAA,gBAAAC,EAAC,KAAA,EAAG,UAAAM,KAAYD,EAAA,CAAK;AAAA,IAAA;AAAA,EAAA;AAG3B;AAEO,SAASF,EAAW,EAAE,MAAAE,GAAM,UAAAC,KAAmD;AACpF,SACE,gBAAAN;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,iBAAeK;AAAA,MACf,WAAU;AAAA,MACV,OAAO;AAAA,QACL,SAAS;AAAA,MAAA;AAAA,MAGV,UAAAC;AAAA,IAAA;AAAA,EAAA;AAGP;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/components/TabView/index.tsx"],"sourcesContent":["import { ReactNode } from 'jsx-dom'\nimport styles from './styles.module.sass'\n\nexport interface TabViewLabelOptions {\n name: string\n children: ReactNode\n}\n\nconsole.log(styles)\n\nexport function TabView({\n tabs = [],\n defaultActiveIndex = 0,\n}: {\n tabs: (TabViewLabelOptions & { content: ReactNode })[]\n defaultActiveIndex?: number\n}) {\n const el = (\n <div className={`ipe-tabView ${styles.tabview}`}>\n <ul className={`ipe-tabView__labels-container ${styles.labels_container}`}>\n {tabs.map((tab) => (\n <TabLabel key={tab.name} name={tab.name}>\n {tab.children}\n </TabLabel>\n ))}\n </ul>\n <div className={`ipe-tabView__contents ${styles.contents_container}`}>\n {tabs.map((tab) => (\n <TabContent key={tab.name} name={tab.name}>\n {tab.content}\n </TabContent>\n ))}\n </div>\n </div>\n )\n\n const defaultActiveLabel = el.querySelector<HTMLAnchorElement>(\n `.ipe-tabView__labels-container > .ipe-tabView__label:nth-child(${defaultActiveIndex + 1})`\n )\n if (defaultActiveLabel) {\n defaultActiveLabel.click()\n }\n\n return el\n}\n\nexport function TabLabel({ name, children }: { name: string; children: ReactNode }) {\n return (\n <li\n data-tab-name={name}\n className={`ipe-tabView__label ${styles.label}`}\n onClick={function (e) {\n e.preventDefault()\n const container = this.closest('.ipe-tabView')\n if (!container) return\n const labels = Array.from(container.children).find((el) =>\n el.classList.contains('ipe-tabView__labels')\n )?.children\n if (labels) {\n Array.from(labels).forEach((label) => {\n label.classList.remove(styles.active)\n })\n }\n this.classList.add(styles.active)\n const contents = Array.from(container.children).find((el) =>\n el.classList.contains('ipe-tabView__contents')\n )?.children\n if (contents) {\n Array.from(contents).forEach((content) => {\n if (content instanceof HTMLElement) {\n if (content.dataset.tabName === name) {\n content.style.display = ''\n content.classList.add(styles.active)\n } else {\n content.style.display = 'none'\n content.classList.remove(styles.active)\n }\n }\n })\n }\n }}\n >\n <a>{children || name}</a>\n </li>\n )\n}\n\nexport function TabContent({ name, children }: { name: string; children: ReactNode }) {\n return (\n <div\n data-tab-name={name}\n className=\"ipe-tabView__content-body\"\n style={{\n display: 'none',\n }}\n >\n {children}\n </div>\n )\n}\n"],"names":["TabView","tabs","defaultActiveIndex","el","jsxs","styles","jsx","tab","TabLabel","TabContent","defaultActiveLabel","name","children","e","container","labels","label","contents","content"],"mappings":";;;;;;;;;;;;;;;AAUO,SAASA,EAAQ;AAAA,EACtB,MAAAC,IAAO,CAAA;AAAA,EACP,oBAAAC,IAAqB;AACvB,GAGG;AACD,QAAMC,IACJC,gBAAAA,EAAC,OAAA,EAAI,WAAW,eAAeC,EAAO,OAAO,IAC3C,UAAA;AAAA,IAAA,gBAAAC,EAAC,MAAA,EAAG,WAAW,iCAAiCD,EAAO,gBAAgB,IACpE,UAAAJ,EAAK,IAAI,CAACM,wBACRC,GAAA,EAAwB,MAAMD,EAAI,MAChC,UAAAA,EAAI,YADQA,EAAI,IAEnB,CACD,EAAA,CACH;AAAA,IACA,gBAAAD,EAAC,SAAI,WAAW,yBAAyBD,EAAO,kBAAkB,IAC/D,YAAK,IAAI,CAACE,MACT,gBAAAD,EAACG,GAAA,EAA0B,MAAMF,EAAI,MAClC,YAAI,QAAA,GADUA,EAAI,IAErB,CACD,EAAA,CACH;AAAA,EAAA,GACF,GAGIG,IAAqBP,EAAG;AAAA,IAC5B,kEAAkED,IAAqB,CAAC;AAAA,EAAA;AAE1F,SAAIQ,KACFA,EAAmB,MAAA,GAGdP;AACT;AAEO,SAASK,EAAS,EAAE,MAAAG,GAAM,UAAAC,KAAmD;AAClF,SACE,gBAAAN;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,iBAAeK;AAAA,MACf,WAAW,sBAAsBN,EAAO,KAAK;AAAA,MAC7C,SAAS,SAAUQ,GAAG;AACpB,QAAAA,EAAE,eAAA;AACF,cAAMC,IAAY,KAAK,QAAQ,cAAc;AAC7C,YAAI,CAACA,EAAW;AAChB,cAAMC,IAAS,MAAM,KAAKD,EAAU,QAAQ,EAAE;AAAA,UAAK,CAACX,MAClDA,EAAG,UAAU,SAAS,qBAAqB;AAAA,QAAA,GAC1C;AACH,QAAIY,KACF,MAAM,KAAKA,CAAM,EAAE,QAAQ,CAACC,MAAU;AACpC,UAAAA,EAAM,UAAU,OAAOX,EAAO,MAAM;AAAA,QACtC,CAAC,GAEH,KAAK,UAAU,IAAIA,EAAO,MAAM;AAChC,cAAMY,IAAW,MAAM,KAAKH,EAAU,QAAQ,EAAE;AAAA,UAAK,CAACX,MACpDA,EAAG,UAAU,SAAS,uBAAuB;AAAA,QAAA,GAC5C;AACH,QAAIc,KACF,MAAM,KAAKA,CAAQ,EAAE,QAAQ,CAACC,MAAY;AACxC,UAAIA,aAAmB,gBACjBA,EAAQ,QAAQ,YAAYP,KAC9BO,EAAQ,MAAM,UAAU,IACxBA,EAAQ,UAAU,IAAIb,EAAO,MAAM,MAEnCa,EAAQ,MAAM,UAAU,QACxBA,EAAQ,UAAU,OAAOb,EAAO,MAAM;AAAA,QAG5C,CAAC;AAAA,MAEL;AAAA,MAEA,UAAA,gBAAAC,EAAC,KAAA,EAAG,UAAAM,KAAYD,EAAA,CAAK;AAAA,IAAA;AAAA,EAAA;AAG3B;AAEO,SAASF,EAAW,EAAE,MAAAE,GAAM,UAAAC,KAAmD;AACpF,SACE,gBAAAN;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,iBAAeK;AAAA,MACf,WAAU;AAAA,MACV,OAAO;AAAA,QACL,SAAS;AAAA,MAAA;AAAA,MAGV,UAAAC;AAAA,IAAA;AAAA,EAAA;AAGP;"}
@@ -1,5 +1,5 @@
1
1
  export declare enum Endpoints {
2
- ANALYTICS_API_BASE = "https://analytics.ipe.wiki/api",
2
+ ANALYTICS_API_BASE = "https://analytics.ipe.wiki/api/v6",
3
3
  ANALYTICS_DASH_URL = "https://analytics.ipe.wiki",
4
4
  GITHUB_URL = "https://github.com/inpageedit/inpageedit-next",
5
5
  HOME_URL = "https://www.ipe.wiki/",