mgacn-commonsdk 1.0.6 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,10 +28,10 @@ npm install mgacn-commonsdk
28
28
  ## 使用
29
29
 
30
30
  ```js
31
+ // 顺序不能乱:先 EP 默认,再品牌主题(主题不要被 JS 副作用提前加载)
31
32
  import 'element-plus/dist/index.css';
32
- import MgacnCommonSdk from 'mgacn-commonsdk';
33
- // 含全局主题:element-variables / common / reset-element
34
33
  import 'mgacn-commonsdk/style.css';
34
+ import MgacnCommonSdk from 'mgacn-commonsdk';
35
35
 
36
36
  app.use(MgacnCommonSdk, {
37
37
  tokenKey: 'your_token_key',
@@ -40,7 +40,7 @@ app.use(MgacnCommonSdk, {
40
40
  });
41
41
  ```
42
42
 
43
- `style.css` 已包含门户与子系统共用的主题样式(须放在 `element-plus` 样式之后):
43
+ `style.css` 已包含门户与子系统共用的主题样式(**必须**放在 `element-plus` 样式之后;SDK 的 JS 入口不再副作用引入主题,避免被 Vite CSS 去重后排到 EP 前面):
44
44
 
45
45
  - `element-variables.scss` — 品牌色与 EP 变量
46
46
  - `common.scss` — 通用工具类
@@ -90,6 +90,42 @@ checkPermission(['menu:add'], 'menu:add'); // 纯函数,不依赖 getter
90
90
 
91
91
  未传入 `getPermissions` / `setPermissionGetter` 时,`hasPermission` 不拦截(恒为 `true`)。
92
92
 
93
+ ### 子系统壳层(`mgacn-commonsdk/admin`)
94
+
95
+ 门户**不要**引入;仅各业务子系统使用。仍是**同一个 npm 包**,通过子路径导出,无需发第二个包。
96
+
97
+ 包含:顶栏、侧栏、布局、user/system/menu store、动态路由、菜单管理、角色管理。
98
+
99
+ ```js
100
+ import { bootstrapAdminApp } from 'mgacn-commonsdk/admin';
101
+ import 'element-plus/dist/index.css';
102
+ import 'mgacn-commonsdk/style.css';
103
+ import App from './App.vue';
104
+ import Homepage from './views/homepage/index.vue';
105
+
106
+ bootstrapAdminApp({
107
+ App,
108
+ homepageComponent: Homepage,
109
+ deployKey: 'account_cms', // 部署目录名,匹配当前系统
110
+ appTitle: '芒果ACN账号库',
111
+ portalUrl: import.meta.env.VITE_PORTAL_URL, // 如 /portal_cms#
112
+ ossDomain: import.meta.env.VITE_OSS_URL,
113
+ viewModules: import.meta.glob('./views/**/*.vue'),
114
+ isDev: import.meta.env.DEV,
115
+ setupIcons: (app) => { /* 注册图标 */ },
116
+ });
117
+ ```
118
+
119
+ 菜单 `pathComponent` 为 `system/menu`、`system/role` 时走壳内页面;其它业务页由宿主 `viewModules` 解析。
120
+
121
+ 本地 monorepo 可在 Vite 中 alias:
122
+
123
+ ```js
124
+ 'mgacn-commonsdk/admin' → '../mgacn-commonsdk/src/admin/index.js'
125
+ ```
126
+
127
+ peer 依赖需宿主已安装:`vue`、`vue-router`、`pinia`、`element-plus`、`@element-plus/icons-vue`。
128
+
93
129
  ### 网络请求(宿主使用 .GET / .POST)
94
130
 
95
131
  先 `app.use` 后,页面里这样调:
@@ -113,6 +149,7 @@ await request.POST('/path', { foo: 1 });
113
149
  ```js
114
150
  import { getApi } from 'mgacn-commonsdk';
115
151
  await getApi().getUserInfo(userId);
152
+ await getApi().listUserForSelect({ realName: '张三', status: 0 });
116
153
  await getApi().logout(username);
117
154
  await getApi().getOssSts(dir);
118
155
  ```
@@ -0,0 +1,473 @@
1
+ import x from "axios";
2
+ const T = "__MGACN_COMMONSDK_SYSTEM_ID__";
3
+ function P(t) {
4
+ globalThis[T] = t == null ? "" : String(t);
5
+ }
6
+ function R() {
7
+ return globalThis[T] || "";
8
+ }
9
+ function I(t = {}) {
10
+ const {
11
+ baseURL: e = "",
12
+ timeout: n = 6e4,
13
+ tokenKey: r,
14
+ systemId: i,
15
+ loginUrl: s = "/login"
16
+ } = t;
17
+ i != null && i !== "" && P(i);
18
+ const c = x.create({ baseURL: e, timeout: n });
19
+ let l = !1;
20
+ function f() {
21
+ typeof localStorage < "u" && localStorage.clear(), !l && (l = !0, setTimeout(() => {
22
+ typeof window < "u" && window.location.replace(s);
23
+ }, 1500));
24
+ }
25
+ return c.interceptors.request.use(
26
+ (o) => {
27
+ if (o.headers["Content-Type"] = "application/json;charset=UTF-8", typeof localStorage < "u" && r) {
28
+ const a = localStorage.getItem(r);
29
+ a && (o.headers.Authorization = a);
30
+ }
31
+ const u = R();
32
+ return u && (o.headers.systemId = u), o;
33
+ },
34
+ (o) => Promise.reject(o)
35
+ ), c.interceptors.response.use(
36
+ (o) => {
37
+ if (o.status !== 200)
38
+ return Promise.reject(new Error(`请求发生错误,状态码 ${o.status}`));
39
+ const { data: u, config: a } = o;
40
+ if (a.responseType === "arraybuffer" || a.responseType === "blob")
41
+ return u;
42
+ if (u && u.code === 0) return u.data;
43
+ const m = Number(u == null ? void 0 : u.code);
44
+ if (m === 401 || m === 403)
45
+ return f(), Promise.reject(new Error("登录失效,请重新登录"));
46
+ const p = w(u) || "请求失败", d = new Error(p);
47
+ return d.code = m, d.data = u == null ? void 0 : u.data, d.biz = u, Promise.reject(d);
48
+ },
49
+ (o) => {
50
+ var p, d;
51
+ const u = (p = o == null ? void 0 : o.response) == null ? void 0 : p.status;
52
+ if (u === 401 || u === 403)
53
+ return f(), Promise.reject(new Error("登录失效,请重新登录"));
54
+ const a = (d = o == null ? void 0 : o.response) == null ? void 0 : d.data, m = w(a) || (o == null ? void 0 : o.message) || "请求失败";
55
+ return Promise.reject(new Error(String(m)));
56
+ }
57
+ ), c;
58
+ }
59
+ function w(t) {
60
+ if (t == null) return "";
61
+ if (typeof t == "string") {
62
+ const n = t.trim();
63
+ return n ? /^<!DOCTYPE html>/i.test(n) || /^<html[\s>]/i.test(n) ? "接口地址无效或未配置代理" : n.length > 200 ? `${n.slice(0, 200)}…` : n : "";
64
+ }
65
+ if (typeof t != "object") return String(t);
66
+ const e = [t.message, t.msg, t.data, t.error];
67
+ for (const n of e)
68
+ if (!(n == null || n === "") && (typeof n == "string" || typeof n == "number")) {
69
+ const r = String(n).trim();
70
+ return /^<!DOCTYPE html>/i.test(r) || /^<html[\s>]/i.test(r) ? "接口地址无效或未配置代理" : r.length > 200 ? `${r.slice(0, 200)}…` : r;
71
+ }
72
+ return "";
73
+ }
74
+ function et(t = {}) {
75
+ const e = I(t);
76
+ return {
77
+ GET(n, r = {}) {
78
+ return e({ method: "get", url: n, ...r });
79
+ },
80
+ POST(n, r, i = {}) {
81
+ return e({ method: "post", url: n, data: r, ...i });
82
+ },
83
+ DELETE(n, r = {}) {
84
+ return e({ method: "delete", url: n, ...r });
85
+ }
86
+ };
87
+ }
88
+ const E = "__MGACN_COMMONSDK_REQUEST__";
89
+ function nt(t) {
90
+ globalThis[E] = t;
91
+ }
92
+ function G() {
93
+ const t = globalThis[E];
94
+ if (!t)
95
+ throw new Error("[mgacn-commonsdk] 请先 app.use(MgacnCommonSdk, { tokenKey, baseURL })");
96
+ return t;
97
+ }
98
+ function M(t, e, n = "application/vnd.ms-excel") {
99
+ if (t == null || typeof window > "u") return;
100
+ const r = t instanceof Blob ? t : new Blob([t], { type: n }), i = window.URL.createObjectURL(r), s = document.createElement("a");
101
+ s.href = i, s.download = e || "download", s.style.display = "none", document.body.appendChild(s), s.click(), document.body.removeChild(s), window.URL.revokeObjectURL(i);
102
+ }
103
+ function g(t) {
104
+ return String(t).padStart(2, "0");
105
+ }
106
+ function j(t = /* @__PURE__ */ new Date()) {
107
+ return `${t.getFullYear()}${g(t.getMonth() + 1)}${g(t.getDate())}${g(t.getHours())}${g(t.getMinutes())}${g(t.getSeconds())}`;
108
+ }
109
+ async function F(t) {
110
+ if (!(t instanceof Blob) || !t.type || !/json/i.test(t.type)) return;
111
+ const e = await t.text();
112
+ let n = "导出失败";
113
+ try {
114
+ const r = JSON.parse(e);
115
+ n = (r == null ? void 0 : r.message) || (r == null ? void 0 : r.msg) || n;
116
+ } catch {
117
+ }
118
+ throw new Error(n);
119
+ }
120
+ async function H(t = {}) {
121
+ const {
122
+ url: e,
123
+ data: n,
124
+ params: r,
125
+ method: i = "POST",
126
+ filename: s,
127
+ ext: c = "xlsx"
128
+ } = t;
129
+ if (!e) throw new Error("导出地址不能为空");
130
+ if (!s) throw new Error("导出文件名不能为空");
131
+ const l = G(), f = String(i).toUpperCase();
132
+ let o;
133
+ f === "GET" ? o = await l.GET(e, { params: r, responseType: "blob" }) : o = await l.POST(e, n, { responseType: "blob" }), await F(o);
134
+ const a = /\.[a-z0-9]+$/i.test(s) ? s : `${s}_${j()}.${c}`;
135
+ return M(o, a), a;
136
+ }
137
+ function D(t) {
138
+ const e = String(t || "").trim().toUpperCase();
139
+ if (/^\d{15}$/.test(e)) {
140
+ const o = +`19${e.slice(6, 8)}`, u = Number(e.slice(8, 10)), a = Number(e.slice(10, 12)), m = new Date(o, u - 1, a);
141
+ return m.getFullYear() === o && m.getMonth() + 1 === u && m.getDate() === a;
142
+ }
143
+ if (!/^\d{17}[\dX]$/.test(e)) return !1;
144
+ const n = Number(e.slice(6, 10)), r = Number(e.slice(10, 12)), i = Number(e.slice(12, 14)), s = new Date(n, r - 1, i);
145
+ if (s.getFullYear() !== n || s.getMonth() + 1 !== r || s.getDate() !== i) return !1;
146
+ const c = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2], l = "10X98765432";
147
+ let f = 0;
148
+ for (let o = 0; o < 17; o++) f += Number(e[o]) * c[o];
149
+ return l[f % 11] === e[17];
150
+ }
151
+ function _(t) {
152
+ const e = String(t || "").trim().replace(/\s+/g, "");
153
+ return e ? /^1\d{10}$/.test(e) || /^\+[1-9]\d{6,14}$/.test(e) : !1;
154
+ }
155
+ function A(t) {
156
+ const e = String(t || "").trim();
157
+ return e ? /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e) : !1;
158
+ }
159
+ function S(t) {
160
+ return t == null || t === "";
161
+ }
162
+ function U(t, e, n) {
163
+ if (S(e)) {
164
+ n();
165
+ return;
166
+ }
167
+ if (!D(e)) {
168
+ n(new Error("请输入正确的身份证号(15/18位)"));
169
+ return;
170
+ }
171
+ n();
172
+ }
173
+ function k(t, e, n) {
174
+ if (S(e)) {
175
+ n();
176
+ return;
177
+ }
178
+ if (!_(e)) {
179
+ n(new Error("请输入正确的国内或海外手机号"));
180
+ return;
181
+ }
182
+ n();
183
+ }
184
+ function K(t, e, n) {
185
+ if (S(e)) {
186
+ n();
187
+ return;
188
+ }
189
+ if (!A(e)) {
190
+ n(new Error("请输入正确的邮箱"));
191
+ return;
192
+ }
193
+ n();
194
+ }
195
+ function L(t) {
196
+ return !!(t == null || typeof t == "string" && t.trim() === "" || Array.isArray(t) && t.length === 0 || typeof t == "object" && !Array.isArray(t) && Object.keys(t).length === 0);
197
+ }
198
+ function y(t) {
199
+ if (t === null || typeof t != "object") return t;
200
+ if (t instanceof Date) return new Date(t.getTime());
201
+ if (Array.isArray(t)) return t.map((n) => y(n));
202
+ const e = {};
203
+ return Object.keys(t).forEach((n) => {
204
+ e[n] = y(t[n]);
205
+ }), e;
206
+ }
207
+ function B(t, e = 300) {
208
+ let n = null;
209
+ return function(...i) {
210
+ n && clearTimeout(n), n = setTimeout(() => {
211
+ t.apply(this, i);
212
+ }, e);
213
+ };
214
+ }
215
+ function q(t, e = 300) {
216
+ let n = 0;
217
+ return function(...i) {
218
+ const s = Date.now();
219
+ s - n >= e && (n = s, t.apply(this, i));
220
+ };
221
+ }
222
+ function $(t) {
223
+ if (t == null || t === "") return null;
224
+ if (t instanceof Date)
225
+ return Number.isNaN(t.getTime()) ? null : t;
226
+ if (typeof t == "number") {
227
+ const i = new Date(t);
228
+ return Number.isNaN(i.getTime()) ? null : i;
229
+ }
230
+ const e = String(t).trim();
231
+ if (!e) return null;
232
+ if (/^\d{10,13}$/.test(e)) {
233
+ const i = e.length === 10 ? Number(e) * 1e3 : Number(e), s = new Date(i);
234
+ return Number.isNaN(s.getTime()) ? null : s;
235
+ }
236
+ if (/[Zz]$|[+-]\d{2}:?\d{2}$/.test(e)) {
237
+ const i = new Date(e);
238
+ return Number.isNaN(i.getTime()) ? null : i;
239
+ }
240
+ const n = e.match(
241
+ /^(\d{4})[-/.年](\d{1,2})[-/.月](\d{1,2})日?(?:[\sT]+(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?(?:\.(\d{1,3}))?)?/
242
+ );
243
+ if (n) {
244
+ const [, i, s, c, l = "0", f = "0", o = "0", u = "0"] = n, a = new Date(
245
+ Number(i),
246
+ Number(s) - 1,
247
+ Number(c),
248
+ Number(l),
249
+ Number(f),
250
+ Number(o),
251
+ Number(String(u).padEnd(3, "0"))
252
+ );
253
+ return Number.isNaN(a.getTime()) ? null : a;
254
+ }
255
+ const r = new Date(e);
256
+ return Number.isNaN(r.getTime()) ? null : r;
257
+ }
258
+ function b(t, e = "YYYY-MM-DD HH:mm:ss") {
259
+ const n = $(t);
260
+ if (!n) return "";
261
+ const r = n.getFullYear(), i = n.getMonth() + 1, s = n.getDate(), c = n.getHours(), l = n.getMinutes(), f = n.getSeconds(), o = {
262
+ YYYY: String(r),
263
+ MM: String(i).padStart(2, "0"),
264
+ DD: String(s).padStart(2, "0"),
265
+ HH: String(c).padStart(2, "0"),
266
+ mm: String(l).padStart(2, "0"),
267
+ ss: String(f).padStart(2, "0"),
268
+ M: String(i),
269
+ D: String(s),
270
+ H: String(c),
271
+ m: String(l),
272
+ s: String(f)
273
+ };
274
+ return e.replace(/YYYY|MM|DD|HH|mm|ss|M|D|H|m|s/g, (u) => o[u]);
275
+ }
276
+ function z() {
277
+ const t = /* @__PURE__ */ new Date();
278
+ t.setHours(23, 59, 59, 0);
279
+ const e = /* @__PURE__ */ new Date();
280
+ return e.setDate(e.getDate() - 30), e.setHours(0, 0, 0, 0), {
281
+ start: b(e, "YYYY-MM-DD HH:mm:ss"),
282
+ end: b(t, "YYYY-MM-DD HH:mm:ss")
283
+ };
284
+ }
285
+ function h(t) {
286
+ const e = {};
287
+ return Object.keys(t || {}).forEach((n) => {
288
+ const r = t[n];
289
+ r == null || r === "" || Array.isArray(r) && r.length === 0 || (e[n] = r);
290
+ }), e;
291
+ }
292
+ function N(t, e = 2) {
293
+ if (t == null || t === "") return t;
294
+ const n = Number(t);
295
+ if (Number.isNaN(n)) return t;
296
+ const r = n.toFixed(e), [i, s] = r.split("."), c = i.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
297
+ if (s == null) return c;
298
+ const l = s.replace(/0+$/, "");
299
+ return l ? `${c}.${l}` : c;
300
+ }
301
+ function Q(t) {
302
+ if (t == null || t === "") return "-";
303
+ const e = Number(t);
304
+ return Number.isNaN(e) ? "-" : Math.abs(e) > 1e4 ? `${N(e / 1e4, 2)}w` : String(N(e, 0));
305
+ }
306
+ function Y(t) {
307
+ if (t == null || t === "") return t;
308
+ const e = Number(t);
309
+ return !Number.isFinite(e) || Number.isNaN(e) ? t : e === 0 ? 0 : Number(String((e * 100).toFixed(2)).replace(/(?:\.0*|(\.\d+?)0+)$/, "$1"));
310
+ }
311
+ function X(t) {
312
+ if (t == null || t === "") return "-";
313
+ const e = Y(t);
314
+ return e == null || e === "" || Number.isNaN(Number(e)) ? "-" : `${e}%`;
315
+ }
316
+ function J(t, e = 4) {
317
+ if (t === "" || t == null) return;
318
+ const n = Number(t);
319
+ if (Number.isFinite(n))
320
+ return Number((n / 100).toFixed(e));
321
+ }
322
+ function Z(t, e = 2) {
323
+ if (t === 0 || t === "0") return 0;
324
+ if (t == null || t === "") return "";
325
+ const n = Number(t);
326
+ return Number.isFinite(n) ? Math.abs(n) >= 1e9 ? 0 : Number.isInteger(n) ? n : Number(n.toFixed(e)) : "";
327
+ }
328
+ function V(t = "id") {
329
+ return `${t}_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
330
+ }
331
+ const rt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
332
+ __proto__: null,
333
+ cleanNumber: Z,
334
+ cleanParams: h,
335
+ debounce: B,
336
+ deepClone: y,
337
+ downloadBlob: M,
338
+ exportFile: H,
339
+ formatDate: b,
340
+ formatFansCount: Q,
341
+ formatNum: N,
342
+ getRecentMonthRange: z,
343
+ isEmail: A,
344
+ isEmpty: L,
345
+ isMainlandIdCard: D,
346
+ isMobile: _,
347
+ numberRatio: Y,
348
+ numberRatioText: X,
349
+ parseDate: $,
350
+ throttle: q,
351
+ toRebateRatio: J,
352
+ uniqueId: V,
353
+ validateEmail: K,
354
+ validateIdCardNo: U,
355
+ validateMobile: k
356
+ }, Symbol.toStringTag, { value: "Module" }));
357
+ function it(t) {
358
+ if (!t)
359
+ throw new Error("[mgacn-commonsdk] createApi 需要传入 request 实例");
360
+ return {
361
+ // ---------- 注销登录 ----------
362
+ logout(e) {
363
+ return t.GET(`/yhAdmin/login/exit/${e}`);
364
+ },
365
+ // ---------- 用户 ----------
366
+ getUserInfo(e) {
367
+ return t.GET(`/yhAdmin/user/queryUser/${e}`);
368
+ },
369
+ /**
370
+ * 用户下拉选择列表
371
+ * POST /yhAdmin/user/listForSelect
372
+ * @param {object} [params]
373
+ * @param {0|1} [params.status] 0 正常/有效,1 禁用/锁定;不传查全部
374
+ * @param {0|1} [params.isDelete] 0 否,1 是;不传默认查未删除
375
+ * @param {string} [params.realName] 真实姓名,模糊
376
+ * @param {string} [params.username] 登录账号/工号,模糊
377
+ * @param {string} [params.mobile] 手机号,模糊
378
+ * @param {string} [params.openId] 第三方 openId,模糊
379
+ * @param {string} [params.createTimeStart]
380
+ * @param {string} [params.createTimeEnd]
381
+ * @param {string} [params.updateTimeStart]
382
+ * @param {string} [params.updateTimeEnd]
383
+ * @returns {Promise<Array>} 用户列表(兼容 result / list / 直接数组)
384
+ */
385
+ async listUserForSelect(e = {}) {
386
+ const n = await t.POST("/yhAdmin/user/listForSelect", h(e));
387
+ return Array.isArray(n) ? n : Array.isArray(n == null ? void 0 : n.result) ? n.result : Array.isArray(n == null ? void 0 : n.list) ? n.list : [];
388
+ },
389
+ /**
390
+ * 媒介供应商全量列表(下拉)
391
+ * GET /yhAccount/mediaSupplier/listAll
392
+ */
393
+ listMediaSupplierAll() {
394
+ return t.GET("/yhAccount/mediaSupplier/listAll");
395
+ },
396
+ /**
397
+ * 账号库平台配置全量列表(下拉)
398
+ * GET /yhAccount/platformInfo/listAll
399
+ */
400
+ listPlatformInfoAll() {
401
+ return t.GET("/yhAccount/platformInfo/listAll");
402
+ },
403
+ /**
404
+ * 标签配置全量列表
405
+ * GET /yhShared/tagConfig/queryAllTagConfigs
406
+ * @param {object} [params]
407
+ * @param {string} [params.businessKey]
408
+ */
409
+ queryAllTagConfigs(e = {}) {
410
+ return t.GET("/yhShared/tagConfig/queryAllTagConfigs", {
411
+ params: h(e)
412
+ });
413
+ },
414
+ // ---------- OSS ----------
415
+ getOssSts(e) {
416
+ return t.GET("/yhAdmin/oss/getStsToken", { params: { dir: e } });
417
+ }
418
+ };
419
+ }
420
+ const O = "__MGACN_COMMONSDK_API__";
421
+ function st(t) {
422
+ globalThis[O] = t;
423
+ }
424
+ function ot() {
425
+ const t = globalThis[O];
426
+ if (!t)
427
+ throw new Error("[mgacn-commonsdk] 请先 app.use(MgacnCommonSdk, { tokenKey, baseURL })");
428
+ return t;
429
+ }
430
+ const C = "__MGACN_COMMONSDK_PERMISSION_GETTER__";
431
+ function ut(t) {
432
+ globalThis[C] = typeof t == "function" ? t : null;
433
+ }
434
+ function W() {
435
+ return globalThis[C] || null;
436
+ }
437
+ function v(t, e, n = "and") {
438
+ const r = (Array.isArray(e) ? e : [e]).map((s) => String(s ?? "").trim()).filter(Boolean);
439
+ if (!r.length) return !0;
440
+ const i = new Set((t || []).map(String));
441
+ return n === "or" ? r.some((s) => i.has(s)) : r.every((s) => i.has(s));
442
+ }
443
+ function ct(t, e = "and") {
444
+ const n = W();
445
+ return typeof n != "function" ? !0 : v(n(), t, e);
446
+ }
447
+ const at = (t, e) => {
448
+ const n = t.__vccOpts || t;
449
+ for (const [r, i] of e)
450
+ n[r] = i;
451
+ return n;
452
+ };
453
+ export {
454
+ at as _,
455
+ G as a,
456
+ h as b,
457
+ v as c,
458
+ y as d,
459
+ B as e,
460
+ N as f,
461
+ ot as g,
462
+ ct as h,
463
+ ut as i,
464
+ et as j,
465
+ it as k,
466
+ nt as l,
467
+ st as m,
468
+ I as n,
469
+ W as o,
470
+ R as p,
471
+ rt as q,
472
+ P as s
473
+ };