@tagsamurai/gsts-api-services 1.0.1-alpha.9 → 1.0.2-alpha.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/api-services.es.js +123 -117
- package/index.html +172 -0
- package/main.d.ts +1 -0
- package/manifest.json +8 -0
- package/microtsm.config.d.ts +2 -0
- package/package.json +1 -1
- package/src/dto/tag.dto.d.ts +29 -1
- package/src/dto/tagEventlog.dto.d.ts +4 -13
- package/src/dto/user.dto.d.ts +1 -1
- package/src/services/auth.service.d.ts +5 -0
- package/src/services/globalTag.service.d.ts +11 -1
- package/src/types/changelog.type.d.ts +5 -5
- package/src/types/fetchResponse.type.d.ts +2 -2
- package/src/types/tag.type.d.ts +8 -1
- package/src/types/tagEventlog.type.d.ts +11 -0
- package/src/utils/getImageURL.util.d.ts +1 -1
- package/api-services.system.js +0 -1
package/api-services.es.js
CHANGED
|
@@ -1,25 +1,33 @@
|
|
|
1
|
-
import
|
|
2
|
-
const
|
|
1
|
+
import m from "axios";
|
|
2
|
+
const y = { BASE_URL: "/", DEV: !1, MODE: "production", PROD: !0, SSR: !1, VITE_APP_GLOBAL_SETTINGS_API: "https://dev-api.global-settings.tagsamurai.com", VITE_APP_LOGS_NOTIFICATION_API: "https://dev-api-logs-notification.tagsamurai.com", VITE_APP_TAGSAMURAI_API: "https://dev-api.tagsamurai.com" }, O = (t = "APP_TAGSAMURAI_API") => y["VITE_" + t], o = (t = {}, e = !1) => {
|
|
3
3
|
const {
|
|
4
4
|
env: r = "APP_GLOBAL_SETTINGS_API",
|
|
5
|
-
prefix:
|
|
6
|
-
headers:
|
|
7
|
-
...
|
|
8
|
-
} = t,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
headers: e ? c : {
|
|
5
|
+
prefix: c = "",
|
|
6
|
+
headers: a = {},
|
|
7
|
+
...l
|
|
8
|
+
} = t, g = "".concat(O(r)).concat(c), d = m.create({
|
|
9
|
+
...l,
|
|
10
|
+
baseURL: g,
|
|
11
|
+
headers: e ? a : {
|
|
13
12
|
"Content-Type": "application/json",
|
|
14
|
-
|
|
15
|
-
...c
|
|
13
|
+
...a
|
|
16
14
|
}
|
|
17
15
|
});
|
|
18
|
-
|
|
16
|
+
return d.interceptors.request.use((v) => {
|
|
17
|
+
var $, S, I;
|
|
18
|
+
const P = JSON.parse(($ = localStorage.getItem("user")) != null ? $ : "{}"), _ = (I = (S = P.jwt) != null ? S : P.token) != null ? I : "";
|
|
19
|
+
return v.headers.Authorization = "Bearer ".concat(_), v;
|
|
20
|
+
}), d;
|
|
21
|
+
}, D = (t, e, r) => {
|
|
22
|
+
var l;
|
|
19
23
|
if (!t) return;
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
const c = O("APP_UTILITY_API"), a = t.startsWith("http") ? t : "".concat(c, "/files/").concat(t.replace(/^\/+/, ""));
|
|
25
|
+
if (e || r) {
|
|
26
|
+
const g = new URLSearchParams();
|
|
27
|
+
return e && g.set("width", e.toString()), r && g.set("height", (l = r == null ? void 0 : r.toString()) != null ? l : e == null ? void 0 : e.toString()), "".concat(a, "?").concat(g.toString());
|
|
28
|
+
}
|
|
29
|
+
return a;
|
|
30
|
+
}, b = (t) => {
|
|
23
31
|
if (!t || typeof t == "string")
|
|
24
32
|
return;
|
|
25
33
|
const e = {};
|
|
@@ -30,143 +38,141 @@ const _ = { BASE_URL: "/", DEV: !1, MODE: "production", PROD: !0, SSR: !1, VITE_
|
|
|
30
38
|
[r]: t[r]
|
|
31
39
|
});
|
|
32
40
|
}), e;
|
|
33
|
-
},
|
|
41
|
+
}, E = o({
|
|
42
|
+
prefix: "/v1/global-settings/auth"
|
|
43
|
+
}), G = () => E.post("/logout"), x = { logout: G }, T = o({
|
|
34
44
|
prefix: "/v1/global-settings/change-log"
|
|
35
|
-
}),
|
|
36
|
-
getChangelogs: (t) =>
|
|
37
|
-
getChangelogOptions: (t) =>
|
|
38
|
-
},
|
|
45
|
+
}), C = {
|
|
46
|
+
getChangelogs: (t) => T.get("", { params: t }),
|
|
47
|
+
getChangelogOptions: (t) => T.get("/options", { params: t })
|
|
48
|
+
}, u = o({
|
|
39
49
|
prefix: "/v1/global-settings/division"
|
|
40
|
-
}),
|
|
41
|
-
getDivisions: (t) =>
|
|
42
|
-
getDivisionDetail: (t) =>
|
|
43
|
-
postCreateDivision: (t) =>
|
|
44
|
-
putEditDivision: (t, e) =>
|
|
50
|
+
}), h = {
|
|
51
|
+
getDivisions: (t) => u.get("", { params: t }),
|
|
52
|
+
getDivisionDetail: (t) => u.get("/".concat(t)),
|
|
53
|
+
postCreateDivision: (t) => u.post("/", t),
|
|
54
|
+
putEditDivision: (t, e) => u.put("/".concat(t), e),
|
|
45
55
|
deleteDivisions: (t) => {
|
|
46
56
|
const e = { id: JSON.stringify(t) };
|
|
47
|
-
return
|
|
57
|
+
return u.delete("", { params: e });
|
|
48
58
|
}
|
|
49
|
-
},
|
|
50
|
-
env: "APP_TAGSAMURAI_API",
|
|
59
|
+
}, i = o({
|
|
51
60
|
prefix: "/v1/global-settings"
|
|
52
|
-
}),
|
|
53
|
-
getTAGAllPaired: (t, e) =>
|
|
54
|
-
getTAGAllPairedOptions: (t, e) =>
|
|
55
|
-
getTAGNotPaired: (t, e) =>
|
|
56
|
-
getTAGNotPairedOptions: (t, e) =>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
putPingReaders: (t) => s().put("/iot-reader/ping", t),
|
|
74
|
-
putMarkIOTStatus: (t, e) => s().put(`/${e}/mark-status`, t),
|
|
75
|
-
putEditReaderGroup: (t, e, r) => s().put(
|
|
76
|
-
`/${t === "iot" ? "iot-" : ""}reader/${r}/set-group`,
|
|
61
|
+
}), N = {
|
|
62
|
+
getTAGAllPaired: (t, e) => i.get("/".concat(t), { params: e }),
|
|
63
|
+
getTAGAllPairedOptions: (t, e) => i.get("/".concat(t, "/options"), { params: e }),
|
|
64
|
+
getTAGNotPaired: (t, e) => i.get("/".concat(t, "/not-paired"), { params: e }),
|
|
65
|
+
getTAGNotPairedOptions: (t, e) => i.get("/".concat(t, "/not-paired/options"), { params: e }),
|
|
66
|
+
getScanTAG: (t, e) => i.get("/".concat(t, "/scan"), { params: e }),
|
|
67
|
+
putDetailAuditTAG: (t, e) => i.put("/".concat(t, "/audit-detail"), e),
|
|
68
|
+
putAuditTAG: (t, e) => i.put("/".concat(t, "/audit"), e),
|
|
69
|
+
putAllocateTAG: (t, e) => i.put("/".concat(t, "/allocate"), e),
|
|
70
|
+
putCombineTAG: (t) => i.put("/combine", t)
|
|
71
|
+
}, n = o({
|
|
72
|
+
prefix: "/v1/global-settings"
|
|
73
|
+
}), j = {
|
|
74
|
+
getHandheldReader: (t) => n.get("/reader", { params: t }),
|
|
75
|
+
getHandheldReaderDetail: (t) => n.get("/reader/".concat(t)),
|
|
76
|
+
getHandheldReaderOptions: (t) => n.get("/reader/options", { params: t }),
|
|
77
|
+
putMarkHandheldStatus: (t) => n.put("/reader/mark-status", t),
|
|
78
|
+
putPingReaders: (t) => n.put("/iot-reader/ping", t),
|
|
79
|
+
putMarkIOTStatus: (t, e) => n.put("/".concat(e, "/mark-status"), t),
|
|
80
|
+
putEditReaderGroup: (t, e, r) => n.put(
|
|
81
|
+
"/".concat(t === "iot" ? "iot-" : "", "reader/").concat(r, "/set-group"),
|
|
77
82
|
e
|
|
78
83
|
),
|
|
79
|
-
putEditAntennaGroup: (t, e) =>
|
|
80
|
-
putEditPortStatus: (t, e) =>
|
|
81
|
-
putEditAliasName: (t, e, r) =>
|
|
82
|
-
|
|
84
|
+
putEditAntennaGroup: (t, e) => n.put("/iot-reader/".concat(e, "/set-port-group"), t),
|
|
85
|
+
putEditPortStatus: (t, e) => n.put("/iot-reader/".concat(e, "/set-port-status"), t),
|
|
86
|
+
putEditAliasName: (t, e, r) => n.put(
|
|
87
|
+
"/".concat(t === "iot" ? "iot-" : "", "reader/").concat(r, "/set-alias-name"),
|
|
83
88
|
e
|
|
84
89
|
),
|
|
85
|
-
putAntennaPower: (t, e) =>
|
|
86
|
-
getIOTReaderOrAntenna: (t, e) =>
|
|
87
|
-
getIOTReaderDetail: (t) =>
|
|
88
|
-
getIOTReaderOrAntennaOptions: (t, e) =>
|
|
89
|
-
getActivityLog: (t) =>
|
|
90
|
-
getActivityLogOptions: (t) =>
|
|
91
|
-
getDetailActivityLog: (t) =>
|
|
92
|
-
getDetailActivityLogOptions: (t) =>
|
|
93
|
-
getExistingAliasNames: () =>
|
|
94
|
-
getIotReaderPort: (t, e) =>
|
|
95
|
-
},
|
|
90
|
+
putAntennaPower: (t, e) => n.put("/iot-reader/".concat(e, "/set-antenna-power"), t),
|
|
91
|
+
getIOTReaderOrAntenna: (t, e) => n.get("/".concat(t), { params: e }),
|
|
92
|
+
getIOTReaderDetail: (t) => n.get("/iot-reader/".concat(t)),
|
|
93
|
+
getIOTReaderOrAntennaOptions: (t, e) => n.get("/".concat(t, "/options"), { params: e }),
|
|
94
|
+
getActivityLog: (t) => n.get("/activity-log", { params: t }),
|
|
95
|
+
getActivityLogOptions: (t) => n.get("/activity-log/options", { params: t }),
|
|
96
|
+
getDetailActivityLog: (t) => n.get("/activity-log", { params: t }),
|
|
97
|
+
getDetailActivityLogOptions: (t) => n.get("/activity-log/options", { params: t }),
|
|
98
|
+
getExistingAliasNames: () => n.get("/reader/alias-names"),
|
|
99
|
+
getIotReaderPort: (t, e) => n.get("/iot-reader/".concat(t, "/ports"), { params: e })
|
|
100
|
+
}, L = o({
|
|
96
101
|
env: "APP_LOGS_NOTIFICATION_API",
|
|
97
102
|
prefix: "/v2"
|
|
98
|
-
}),
|
|
99
|
-
getSessionLogList: (t) =>
|
|
100
|
-
},
|
|
103
|
+
}), k = {
|
|
104
|
+
getSessionLogList: (t) => L.get("/session-log", { params: t })
|
|
105
|
+
}, f = o({
|
|
101
106
|
prefix: "/v1/global-settings/option"
|
|
102
|
-
}),
|
|
103
|
-
getPositions: () =>
|
|
104
|
-
getDivisions: () =>
|
|
105
|
-
},
|
|
107
|
+
}), B = {
|
|
108
|
+
getPositions: () => f.get("/position"),
|
|
109
|
+
getDivisions: () => f.get("/division")
|
|
110
|
+
}, p = o({
|
|
106
111
|
prefix: "/v1/global-settings/position"
|
|
107
|
-
}),
|
|
108
|
-
getPositions: (t) =>
|
|
109
|
-
getPositionDetail: (t) =>
|
|
110
|
-
postCreatePosition: (t) =>
|
|
111
|
-
putEditPosition: (t, e) =>
|
|
112
|
+
}), M = {
|
|
113
|
+
getPositions: (t) => p.get("", { params: t }),
|
|
114
|
+
getPositionDetail: (t) => p.get("/".concat(t)),
|
|
115
|
+
postCreatePosition: (t) => p.post("/", t),
|
|
116
|
+
putEditPosition: (t, e) => p.put("/".concat(t), e),
|
|
112
117
|
deletePositions: (t) => {
|
|
113
118
|
const e = { id: JSON.stringify(t) };
|
|
114
|
-
return
|
|
119
|
+
return p.delete("", { params: e });
|
|
115
120
|
}
|
|
116
|
-
},
|
|
121
|
+
}, R = o({
|
|
117
122
|
env: "APP_TAGSAMURAI_API",
|
|
118
123
|
prefix: "/tag/v2"
|
|
119
|
-
}),
|
|
120
|
-
getTagInfo: (t) =>
|
|
121
|
-
},
|
|
124
|
+
}), H = {
|
|
125
|
+
getTagInfo: (t) => R.get("/rfid-qr/scan", { params: t })
|
|
126
|
+
}, A = o({
|
|
122
127
|
prefix: "/v1/global-settings/change-log"
|
|
123
|
-
}),
|
|
124
|
-
getTAGEventlog: (t) =>
|
|
125
|
-
getTAGEventlogOptions: (t) =>
|
|
126
|
-
getDetailTAGEventlog: (t) =>
|
|
127
|
-
},
|
|
128
|
+
}), J = {
|
|
129
|
+
getTAGEventlog: (t) => A.get("/tag-event-log", { params: t }),
|
|
130
|
+
getTAGEventlogOptions: (t) => A.get("/tag-event-log/options", { params: t }),
|
|
131
|
+
getDetailTAGEventlog: (t) => A.get("/tag-event-log/".concat(t))
|
|
132
|
+
}, s = o({
|
|
128
133
|
prefix: "/v1/global-settings/user"
|
|
129
|
-
}),
|
|
130
|
-
getUsers: (t) =>
|
|
131
|
-
getUserDetail: (t) =>
|
|
132
|
-
getUserSystemLogs: (t, e) =>
|
|
134
|
+
}), V = {
|
|
135
|
+
getUsers: (t) => s.get("", { params: t }),
|
|
136
|
+
getUserDetail: (t) => s.get("/".concat(t)),
|
|
137
|
+
getUserSystemLogs: (t, e) => s.get("/".concat(t, "/system-logs"), { params: e }),
|
|
133
138
|
getUserSystemLogOptions: (t, e) => {
|
|
134
139
|
const r = {};
|
|
135
|
-
return r[e] = !0,
|
|
140
|
+
return r[e] = !0, s.get("/".concat(t, "/system-logs/options"), { params: r });
|
|
136
141
|
},
|
|
137
142
|
postCreateUser: (t) => {
|
|
138
143
|
const e = { "Content-Type": "multipart/form-data" };
|
|
139
|
-
return
|
|
144
|
+
return s.post("", t, { headers: e });
|
|
140
145
|
},
|
|
141
146
|
putEditUser: (t, e) => {
|
|
142
147
|
const r = { "Content-Type": "multipart/form-data" };
|
|
143
|
-
return
|
|
148
|
+
return s.put("/".concat(t), e, { headers: r });
|
|
144
149
|
},
|
|
145
150
|
deleteUsers: (t) => {
|
|
146
151
|
const e = { id: JSON.stringify(t) };
|
|
147
|
-
return
|
|
152
|
+
return s.delete("", { params: e });
|
|
148
153
|
},
|
|
149
|
-
putToggleStatusUsers: (t) =>
|
|
154
|
+
putToggleStatusUsers: (t) => s.put("/active-status", t),
|
|
150
155
|
getUserOptions: (t) => {
|
|
151
156
|
const e = {};
|
|
152
|
-
return e[t] = !0,
|
|
157
|
+
return e[t] = !0, s.get("/options", { params: e });
|
|
153
158
|
},
|
|
154
|
-
deleteCancelEmailChange: (t) =>
|
|
155
|
-
postResendEmail: (t) =>
|
|
156
|
-
putChangePassword: (t, e) =>
|
|
159
|
+
deleteCancelEmailChange: (t) => s.delete("/cancel-email-change/".concat(t)),
|
|
160
|
+
postResendEmail: (t) => s.post("/resend-email", t),
|
|
161
|
+
putChangePassword: (t, e) => s.put("/change-password/".concat(t), e)
|
|
157
162
|
};
|
|
158
163
|
export {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
164
|
+
x as AuthServices,
|
|
165
|
+
C as ChangelogServices,
|
|
166
|
+
h as DivisionServices,
|
|
167
|
+
N as GlobalTagServices,
|
|
168
|
+
j as HardwareServices,
|
|
169
|
+
k as LogServices,
|
|
170
|
+
B as OptionServices,
|
|
171
|
+
M as PositionServices,
|
|
172
|
+
J as TagEventlogServices,
|
|
173
|
+
H as TagServices,
|
|
174
|
+
V as UserServices,
|
|
175
|
+
O as getBaseURL,
|
|
176
|
+
D as getImageURL,
|
|
177
|
+
b as queryParamsStringfy
|
|
172
178
|
};
|
package/index.html
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8"/>
|
|
6
|
+
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
|
7
|
+
<title>MicroApp Integration Guide</title>
|
|
8
|
+
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"/>
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Material+Icons" rel="stylesheet"/>
|
|
10
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
|
|
11
|
+
rel="stylesheet"/>
|
|
12
|
+
<style>
|
|
13
|
+
body {
|
|
14
|
+
font-family: 'Inter', sans-serif;
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body class="bg-gray-100">
|
|
20
|
+
<header class="bg-white shadow-sm">
|
|
21
|
+
<div class="container mx-auto px-6 py-4 flex justify-between items-center">
|
|
22
|
+
<div class="flex items-center">
|
|
23
|
+
<span class="material-icons text-purple-600 text-3xl mr-2">widgets</span>
|
|
24
|
+
<h1 class="text-xl font-semibold text-gray-800">MicroApp Guide</h1>
|
|
25
|
+
</div>
|
|
26
|
+
<nav class="flex items-center space-x-6">
|
|
27
|
+
<a class="text-gray-600 hover:text-purple-600" href="#">Overview</a>
|
|
28
|
+
<a class="text-purple-600 font-medium border-b-2 border-purple-600 pb-1" href="#">Development</a>
|
|
29
|
+
<a class="text-gray-600 hover:text-purple-600" href="#">Deployment</a>
|
|
30
|
+
<a class="text-gray-600 hover:text-purple-600" href="#">Troubleshooting</a>
|
|
31
|
+
<a class="text-gray-600 hover:text-purple-600" href="#">
|
|
32
|
+
<span class="material-icons">help_outline</span>
|
|
33
|
+
</a>
|
|
34
|
+
<img alt="User avatar" class="rounded-full w-8 h-8"
|
|
35
|
+
src="https://lh3.googleusercontent.com/aida-public/AB6AXuBYomsI9qOSrR7mdND8D_9i1n-qfVQ929APFVQrN1jJ7nv9Pg2sh20GXu9OrHOXWKm2TGiBp24isi352RxMi-e4cf_8Ju180_J1C1B4uX6PjQKaglT2dh6xrx5CsdW1ByZtZGrj9qPVdGBMxU7_r8cqlAKacqx9XUmOvluxOQxfOwOXmqNdV0xtrtyYa1z9v6ITJLWUF4rnXCbLRIZ77KhDGUL6d9U-HCKFWZzl-4gY7Y7GiYPC7tNfPxjAbqvgcxbH7_NLhmpCdPg"/>
|
|
36
|
+
</nav>
|
|
37
|
+
</div>
|
|
38
|
+
</header>
|
|
39
|
+
<main class="container mx-auto px-6 py-12">
|
|
40
|
+
<div class="bg-white p-8 md:p-12 rounded-xl shadow-xl max-w-4xl mx-auto">
|
|
41
|
+
<section class="text-center mb-12">
|
|
42
|
+
<h2 class="text-3xl md:text-4xl font-bold text-gray-800 mb-4">MicroApp Integration Guide</h2>
|
|
43
|
+
<p class="text-gray-600 text-lg mb-8">
|
|
44
|
+
Welcome! This guide provides step-by-step instructions for integrating and developing
|
|
45
|
+
your @tagsamurai/gsts-api-services MicroApp within a single-spa application.
|
|
46
|
+
</p>
|
|
47
|
+
<button
|
|
48
|
+
class="bg-purple-600 hover:bg-purple-700 text-white font-medium py-3 px-6 rounded-lg inline-flex items-center text-lg transition duration-150 ease-in-out">
|
|
49
|
+
<span class="material-icons mr-2">play_arrow</span>
|
|
50
|
+
Start Here
|
|
51
|
+
</button>
|
|
52
|
+
</section>
|
|
53
|
+
<section class="mb-12">
|
|
54
|
+
<div class="flex items-center mb-6">
|
|
55
|
+
<span class="material-icons text-purple-600 text-3xl mr-3">settings_ethernet</span>
|
|
56
|
+
<h3 class="text-2xl font-semibold text-gray-800">Local Development</h3>
|
|
57
|
+
</div>
|
|
58
|
+
<p class="text-gray-600 mb-8">To develop your MicroApp locally, follow these steps:</p>
|
|
59
|
+
<div class="space-y-8">
|
|
60
|
+
<div class="bg-gray-50 p-6 rounded-lg">
|
|
61
|
+
<div class="flex items-start">
|
|
62
|
+
<div class="flex shrink-0 bg-purple-100 p-3 rounded-full mr-4">
|
|
63
|
+
<span class="material-icons text-purple-600">link</span>
|
|
64
|
+
</div>
|
|
65
|
+
<div>
|
|
66
|
+
<h4 class="font-semibold text-gray-700 text-lg mb-1">1. Copy MicroApp URL</h4>
|
|
67
|
+
<p class="text-gray-600 mb-2">
|
|
68
|
+
Copy the URL of your MicroApp's development server. This URL is crucial for
|
|
69
|
+
registering your MicroApp
|
|
70
|
+
with the main single-spa application.
|
|
71
|
+
</p>
|
|
72
|
+
<p class="text-gray-500 text-sm">Your local URL:
|
|
73
|
+
<code class="bg-gray-200 text-purple-700 px-2 py-1 rounded-md text-xs">
|
|
74
|
+
<a id="mfe-url" target="_blank"></a>
|
|
75
|
+
|
|
76
|
+
<script>
|
|
77
|
+
const mfeUrl = document.getElementById('mfe-url');
|
|
78
|
+
const entryUrl = window.location.origin + ('/' + 'api-services.es.js').replace(/\/+/g, '/');
|
|
79
|
+
mfeUrl.href = entryUrl;
|
|
80
|
+
mfeUrl.innerText = entryUrl;
|
|
81
|
+
</script>
|
|
82
|
+
</code>
|
|
83
|
+
</p>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
<div class="bg-gray-50 p-6 rounded-lg">
|
|
88
|
+
<div class="flex items-start">
|
|
89
|
+
<div class="flex shrink-0 bg-purple-100 p-3 rounded-full mr-4">
|
|
90
|
+
<span class="material-icons text-purple-600">open_in_browser</span>
|
|
91
|
+
</div>
|
|
92
|
+
<div>
|
|
93
|
+
<h4 class="font-semibold text-gray-700 text-lg mb-1">2. Open Single-Spa App</h4>
|
|
94
|
+
<p class="text-gray-600">
|
|
95
|
+
Open your single-spa application in a web browser. This is the primary application
|
|
96
|
+
that will host and
|
|
97
|
+
manage your MicroApp.
|
|
98
|
+
</p>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="bg-gray-50 p-6 rounded-lg">
|
|
103
|
+
<div class="flex items-start">
|
|
104
|
+
<div class="flex shrink-0 bg-purple-100 p-3 rounded-full mr-4">
|
|
105
|
+
<span class="material-icons text-purple-600">build</span>
|
|
106
|
+
</div>
|
|
107
|
+
<div>
|
|
108
|
+
<h4 class="font-semibold text-gray-700 text-lg mb-1">3. Enable Dev Tools</h4>
|
|
109
|
+
<p class="text-gray-600 mb-2">
|
|
110
|
+
Enable your browser's development tools. This will allow you to inspect elements,
|
|
111
|
+
debug JavaScript,
|
|
112
|
+
and monitor network requests for your MicroApp.
|
|
113
|
+
</p>
|
|
114
|
+
<code
|
|
115
|
+
class="bg-gray-200 text-gray-700 px-3 py-2 rounded-md text-sm block w-full overflow-x-auto">localStorage.setItem('devtools',
|
|
116
|
+
true);</code>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
<div class="bg-gray-50 p-6 rounded-lg">
|
|
121
|
+
<div class="flex items-start">
|
|
122
|
+
<div class="flex shrink-0 bg-purple-100 p-3 rounded-full mr-4">
|
|
123
|
+
<span class="material-icons text-purple-600">input</span>
|
|
124
|
+
</div>
|
|
125
|
+
<div>
|
|
126
|
+
<h4 class="font-semibold text-gray-700 text-lg mb-1">4. Activate Local Instance</h4>
|
|
127
|
+
<p class="text-gray-600">
|
|
128
|
+
Activate your local MicroApp instance by pasting the copied URL into the single-spa
|
|
129
|
+
application's
|
|
130
|
+
import map or configuration.
|
|
131
|
+
</p>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</section>
|
|
137
|
+
<section>
|
|
138
|
+
<div class="flex items-center mb-6">
|
|
139
|
+
<span class="material-icons text-purple-600 text-3xl mr-3">bolt</span>
|
|
140
|
+
<h3 class="text-2xl font-semibold text-gray-800">Standalone Mode with MicroTSM CLI</h3>
|
|
141
|
+
</div>
|
|
142
|
+
<p class="text-gray-600 mb-6">
|
|
143
|
+
To start developing your MicroApp locally, use the MicroTSM CLI which provides a streamlined development
|
|
144
|
+
experience powered by Vite. Run:
|
|
145
|
+
</p>
|
|
146
|
+
<div class="bg-gray-800 text-white rounded-lg p-4 mb-8 font-mono">
|
|
147
|
+
<span class="text-green-500">$</span><span class="text-green-300"> microtsm dev</span>
|
|
148
|
+
</div>
|
|
149
|
+
<p class="text-gray-600 mb-8">
|
|
150
|
+
This command will start the development server with hot module replacement (HMR) enabled, allowing you
|
|
151
|
+
to see your changes instantly.
|
|
152
|
+
</p>
|
|
153
|
+
<div class="flex space-x-4">
|
|
154
|
+
<button class="border border-purple-600 text-purple-600 hover:bg-purple-50 font-medium py-3 px-6 rounded-lg inline-flex items-center transition duration-150 ease-in-out">
|
|
155
|
+
<span class="material-icons mr-2">terminal</span>
|
|
156
|
+
View CLI Commands
|
|
157
|
+
</button>
|
|
158
|
+
<button class="border border-purple-600 text-purple-600 hover:bg-purple-50 font-medium py-3 px-6 rounded-lg inline-flex items-center transition duration-150 ease-in-out">
|
|
159
|
+
<span class="material-icons mr-2">description</span>
|
|
160
|
+
CLI Documentation
|
|
161
|
+
</button>
|
|
162
|
+
</div>
|
|
163
|
+
</section>
|
|
164
|
+
</div>
|
|
165
|
+
</main>
|
|
166
|
+
<footer class="text-center py-8 text-gray-500 text-sm">
|
|
167
|
+
© 2025 MicroTSM CLI. All rights reserved.
|
|
168
|
+
</footer>
|
|
169
|
+
|
|
170
|
+
</body>
|
|
171
|
+
|
|
172
|
+
</html>
|
package/main.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { default as AuthServices } from './src/services/auth.service';
|
|
1
2
|
export { default as ChangelogServices } from './src/services/changelog.service';
|
|
2
3
|
export { default as DivisionServices } from './src/services/division.service';
|
|
3
4
|
export { default as GlobalTagServices } from './src/services/globalTag.service';
|
package/manifest.json
ADDED
package/package.json
CHANGED
package/src/dto/tag.dto.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MultiSelectOption } from '../types/options.type';
|
|
2
|
-
import { TAGCountType, TAGDataType } from '../types/tag.type';
|
|
2
|
+
import { ApplicationModule, TAGCountType, TAGDataType } from '../types/tag.type';
|
|
3
|
+
import { TAGDetailCount } from '../types/tagEventlog.type';
|
|
3
4
|
export interface TAGFetchResponse<T = TAGDataType> {
|
|
4
5
|
message: string;
|
|
5
6
|
status: number;
|
|
@@ -9,6 +10,13 @@ export interface TAGFetchResponse<T = TAGDataType> {
|
|
|
9
10
|
} & TAGCountType;
|
|
10
11
|
}
|
|
11
12
|
export type TAGFetchOptionResponse<Opt = Record<string, boolean>> = Record<keyof Opt, MultiSelectOption[]>;
|
|
13
|
+
export type TAGDetailAuditResponse = {
|
|
14
|
+
status: number;
|
|
15
|
+
message: string;
|
|
16
|
+
data: {
|
|
17
|
+
detail: TAGDetailCount[];
|
|
18
|
+
};
|
|
19
|
+
};
|
|
12
20
|
export interface TAGFilterRaw {
|
|
13
21
|
rfidCode?: ('Yes' | 'No')[];
|
|
14
22
|
qrCode?: ('Yes' | 'No')[];
|
|
@@ -22,3 +30,23 @@ export interface TAGFilterRaw {
|
|
|
22
30
|
tag?: string[];
|
|
23
31
|
}
|
|
24
32
|
export type TAGFilterQuery = Partial<Record<keyof TAGFilterRaw, string>>;
|
|
33
|
+
export interface PUTAuditTAGBody {
|
|
34
|
+
ids: string[];
|
|
35
|
+
markNotFoundAsDamagedMissing: boolean;
|
|
36
|
+
moveFoundFixedAssetToPortal: boolean;
|
|
37
|
+
moveFoundSupplyAssetToPortal: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface PUTAllocateTAGBody {
|
|
40
|
+
ids: string[];
|
|
41
|
+
group?: number;
|
|
42
|
+
module?: ApplicationModule;
|
|
43
|
+
}
|
|
44
|
+
export type CombineSeparateActions = 'Combine RFID & QR' | 'Combine RFID & NFC' | 'Combine RFID & NFC & QR' | 'Combine NFC & QR' | 'Separate RFID & QR' | 'Separate RFID & NFC' | 'Separate RFID & NFC & QR' | 'Separate NFC & QR';
|
|
45
|
+
export interface PUTCombineTAGBody {
|
|
46
|
+
ids: {
|
|
47
|
+
rfid?: string;
|
|
48
|
+
nfc?: string;
|
|
49
|
+
qr?: string;
|
|
50
|
+
}[];
|
|
51
|
+
action: CombineSeparateActions;
|
|
52
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FetchListResponse, FetchOptionResponse } from '../types/fetchResponse.type';
|
|
2
2
|
import { MultiSelectOption } from '../types/options.type';
|
|
3
|
-
import { TAGType } from '../types/tag.type';
|
|
4
|
-
import { TAGEventlogData } from '../types/tagEventlog.type';
|
|
3
|
+
import { ApplicationModule, TAGType } from '../types/tag.type';
|
|
4
|
+
import { TAGDetailCount, TAGEventlogData } from '../types/tagEventlog.type';
|
|
5
5
|
export interface TAGEventlogFilterQuery {
|
|
6
6
|
status?: string[];
|
|
7
7
|
modifiedBy?: number[];
|
|
@@ -16,16 +16,7 @@ export type TAGEventlogDetailResponse = {
|
|
|
16
16
|
message: string;
|
|
17
17
|
data: {
|
|
18
18
|
type: 'Audit' | 'Allocation';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
isChecked?: boolean;
|
|
22
|
-
groupName?: string;
|
|
23
|
-
rfid?: number;
|
|
24
|
-
nfc?: number;
|
|
25
|
-
rfidQr?: number;
|
|
26
|
-
nfcQr?: number;
|
|
27
|
-
rfidNfc?: number;
|
|
28
|
-
rfidNfcQr?: number;
|
|
29
|
-
}[];
|
|
19
|
+
module?: ApplicationModule;
|
|
20
|
+
detail: TAGDetailCount[];
|
|
30
21
|
};
|
|
31
22
|
};
|
package/src/dto/user.dto.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { AxiosResponse } from 'axios';
|
|
2
2
|
import { BooleanOptions } from '../dto/dataTable.dto';
|
|
3
3
|
import { HardwareFilterQuery } from '../dto/hardware.dto';
|
|
4
|
-
import { TAGFetchOptionResponse, TAGFetchResponse } from '../dto/tag.dto';
|
|
4
|
+
import { PUTAllocateTAGBody, PUTAuditTAGBody, PUTCombineTAGBody, TAGDetailAuditResponse, TAGFetchOptionResponse, TAGFetchResponse } from '../dto/tag.dto';
|
|
5
|
+
import { FetchResponse } from '../types/fetchResponse.type';
|
|
5
6
|
import { TAGType } from '../types/tag.type';
|
|
6
7
|
declare const GlobalTagServices: {
|
|
7
8
|
getTAGAllPaired: (tagType: TAGType, params?: HardwareFilterQuery) => Promise<AxiosResponse<TAGFetchResponse>>;
|
|
@@ -12,5 +13,14 @@ declare const GlobalTagServices: {
|
|
|
12
13
|
getTAGNotPairedOptions: (tagType: TAGType, params?: BooleanOptions) => Promise<AxiosResponse<{
|
|
13
14
|
data: TAGFetchOptionResponse;
|
|
14
15
|
}>>;
|
|
16
|
+
getScanTAG: (tagType: TAGType, params?: {
|
|
17
|
+
tag: string;
|
|
18
|
+
}) => Promise<AxiosResponse>;
|
|
19
|
+
putDetailAuditTAG: (tagType: TAGType, body: {
|
|
20
|
+
ids: string[];
|
|
21
|
+
}) => Promise<AxiosResponse<TAGDetailAuditResponse>>;
|
|
22
|
+
putAuditTAG: (tagType: TAGType, body: PUTAuditTAGBody) => Promise<AxiosResponse<FetchResponse>>;
|
|
23
|
+
putAllocateTAG: (tagType: TAGType, body: PUTAllocateTAGBody) => Promise<AxiosResponse<FetchResponse>>;
|
|
24
|
+
putCombineTAG: (body: PUTCombineTAGBody) => Promise<AxiosResponse<FetchResponse>>;
|
|
15
25
|
};
|
|
16
26
|
export default GlobalTagServices;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Option } from '../../node_modules/@fewangsit/wangsvue-gsts/dropdown';
|
|
2
2
|
export type ChangelogType = {
|
|
3
3
|
_id: string;
|
|
4
4
|
action: string;
|
|
@@ -14,8 +14,8 @@ export type ChangelogType = {
|
|
|
14
14
|
updatedAt: string;
|
|
15
15
|
};
|
|
16
16
|
export type ChangelogOptionFilter = {
|
|
17
|
-
actionOptions?:
|
|
18
|
-
modifiedByOptions?:
|
|
19
|
-
fieldOptions?:
|
|
20
|
-
objectNameOptions?:
|
|
17
|
+
actionOptions?: Option[];
|
|
18
|
+
modifiedByOptions?: Option[];
|
|
19
|
+
fieldOptions?: Option[];
|
|
20
|
+
objectNameOptions?: Option[];
|
|
21
21
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { Option } from '../../node_modules/@fewangsit/wangsvue-gsts/dropdown';
|
|
1
2
|
import { Data } from './dataTable.type';
|
|
2
|
-
import { MultiSelectOption } from './options.type';
|
|
3
3
|
export type FetchListResponse<T = Data> = {
|
|
4
4
|
status: number;
|
|
5
5
|
message: string;
|
|
@@ -22,7 +22,7 @@ export type FetchResponse = {
|
|
|
22
22
|
status: number;
|
|
23
23
|
message: string;
|
|
24
24
|
};
|
|
25
|
-
export type FilterOptions<Opt = Record<string, boolean>> = Record<keyof Opt,
|
|
25
|
+
export type FilterOptions<Opt = Record<string, boolean>> = Record<keyof Opt, Option[]>;
|
|
26
26
|
export type FetchOptionResponse<Opt = Record<string, boolean>> = {
|
|
27
27
|
message: string;
|
|
28
28
|
data: FilterOptions<Opt>;
|
package/src/types/tag.type.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type TAGType = 'rfid' | 'nfc';
|
|
1
|
+
export type TAGType = 'rfid' | 'nfc' | 'qr';
|
|
2
2
|
export type TAGTabType = 'all' | 'paired' | 'not-paired' | 'combine-tag';
|
|
3
3
|
export type ApplicationModule = 'Settings Portal' | 'Fixed Asset' | 'Supply Asset';
|
|
4
4
|
export interface TAGCountType {
|
|
@@ -19,3 +19,10 @@ export interface TAGDataType {
|
|
|
19
19
|
status: 'Available' | 'Paired' | 'Damaged/Missing';
|
|
20
20
|
pairedIn: ApplicationModule;
|
|
21
21
|
}
|
|
22
|
+
export interface TAGInfomartion {
|
|
23
|
+
_id: '662f63b17adde9b58b0eb152';
|
|
24
|
+
rfidCode: 'E*40B105';
|
|
25
|
+
nfcCode: 'B*EASD';
|
|
26
|
+
qrCode: 'C*EASDF';
|
|
27
|
+
module: 'Fixed Asset';
|
|
28
|
+
}
|
|
@@ -6,3 +6,14 @@ export interface TAGEventlogData {
|
|
|
6
6
|
modifiedBy?: string;
|
|
7
7
|
createdAt: string;
|
|
8
8
|
}
|
|
9
|
+
export interface TAGDetailCount {
|
|
10
|
+
type: 'availableFound' | 'damagedMissingFound' | 'availableMarkDamagedMissing' | 'fixedAssetMoveToPortal' | 'supplyAssetMoveToPortal' | 'allocated';
|
|
11
|
+
isChecked?: boolean;
|
|
12
|
+
groupName?: string;
|
|
13
|
+
rfid?: number;
|
|
14
|
+
nfc?: number;
|
|
15
|
+
rfidQr?: number;
|
|
16
|
+
nfcQr?: number;
|
|
17
|
+
rfidNfc?: number;
|
|
18
|
+
rfidNfcQr?: number;
|
|
19
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const getImageURL: (name?: string | null) => string | undefined;
|
|
1
|
+
export declare const getImageURL: (name?: string | null, width?: number, height?: number) => string | undefined;
|
package/api-services.system.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
System.register(["axios"],function(s,m){"use strict";var l;return{setters:[c=>{l=c.default}],execute:function(){const c={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1,VITE_APP_GLOBAL_SETTINGS_API:"https://dev-api.global-settings.tagsamurai.com",VITE_APP_LOGS_NOTIFICATION_API:"https://dev-api-logs-notification.tagsamurai.com",VITE_APP_TAGSAMURAI_API:"https://dev-api.tagsamurai.com"},p=s("getBaseURL",(t="APP_TAGSAMURAI_API")=>c["VITE_"+t]),o=(t={},e=!1)=>{const{env:r="APP_GLOBAL_SETTINGS_API",prefix:d="",headers:S={},...f}=t,_=`${p(r)}${d}`,I=JSON.parse(localStorage.getItem("user")??"{}"),O=I.jwt??I.token??"";return l.create({...f,baseURL:_,headers:e?S:{"Content-Type":"application/json",Authorization:`Bearer ${O}`,...S}})},h=s("getImageURL",t=>{if(!t)return;const e=p("APP_TAGSAMURAI_API");return t.startsWith("http")?t:`${e}/file-manager/v2/files/${t}`}),y=s("queryParamsStringfy",t=>{if(!t||typeof t=="string")return;const e={};return Object.keys(t).forEach(r=>{Array.isArray(t[r])?t[r].length>0&&Object.assign(e,{[r]:JSON.stringify(t[r])}):t[r]!==void 0&&Object.assign(e,{[r]:t[r]})}),e}),v=o({prefix:"/v1/global-settings/change-log"}),E=s("ChangelogServices",{getChangelogs:t=>v.get("",{params:t}),getChangelogOptions:t=>v.get("/options",{params:t})}),a=o({prefix:"/v1/global-settings/division"}),L=s("DivisionServices",{getDivisions:t=>a.get("",{params:t}),getDivisionDetail:t=>a.get(`/${t}`),postCreateDivision:t=>a.post("/",t),putEditDivision:(t,e)=>a.put(`/${t}`,e),deleteDivisions:t=>{const e={id:JSON.stringify(t)};return a.delete("",{params:e})}}),u=o({env:"APP_TAGSAMURAI_API",prefix:"/v1/global-settings"}),R=s("GlobalTagServices",{getTAGAllPaired:(t,e)=>u.get(`/${t}`,{params:e}),getTAGAllPairedOptions:(t,e)=>u.get(`/${t}/options`,{params:e}),getTAGNotPaired:(t,e)=>u.get(`/${t}/not-paired`,{params:e}),getTAGNotPairedOptions:(t,e)=>u.get(`/${t}/not-paired/options`,{params:e})}),n=({headers:t={},params:e={}}={})=>{const r=p("APP_GLOBAL_SETTINGS_API"),d=JSON.parse(localStorage.getItem("user")??"{}");return l.create({baseURL:`${r}/v1/global-settings`,headers:{"Content-type":"application/json",Authorization:`Bearer ${d.token}`,...t},params:e})},G=s("HardwareServices",{getHandheldReader:t=>n({params:t}).get("/reader"),getHandheldReaderDetail:t=>n().get(`/reader/${t}`),getHandheldReaderOptions:t=>n({params:t}).get("/reader/options"),putMarkHandheldStatus:t=>n().put("/reader/mark-status",t),putPingReaders:t=>n().put("/iot-reader/ping",t),putMarkIOTStatus:(t,e)=>n().put(`/${e}/mark-status`,t),putEditReaderGroup:(t,e,r)=>n().put(`/${t==="iot"?"iot-":""}reader/${r}/set-group`,e),putEditAntennaGroup:(t,e)=>n().put(`/iot-reader/${e}/set-port-group`,t),putEditPortStatus:(t,e)=>n().put(`/iot-reader/${e}/set-port-status`,t),putEditAliasName:(t,e,r)=>n().put(`/${t==="iot"?"iot-":""}reader/${r}/set-alias-name`,e),putAntennaPower:(t,e)=>n().put(`/iot-reader/${e}/set-antenna-power`,t),getIOTReaderOrAntenna:(t,e)=>n({params:e}).get(`/${t}`),getIOTReaderDetail:t=>n().get(`/iot-reader/${t}`),getIOTReaderOrAntennaOptions:(t,e)=>n({params:e}).get(`/${t}/options`),getActivityLog:t=>n({params:t}).get("/activity-log"),getActivityLogOptions:t=>n({params:t}).get("/activity-log/options"),getDetailActivityLog:t=>n({params:t}).get("/activity-log"),getDetailActivityLogOptions:t=>n({params:t}).get("/activity-log/options"),getExistingAliasNames:()=>n().get("/reader/alias-names"),getIotReaderPort:(t,e)=>n({params:e}).get(`/iot-reader/${t}/ports`)}),$=o({env:"APP_LOGS_NOTIFICATION_API",prefix:"/v2"}),U=s("LogServices",{getSessionLogList:t=>$.get("/session-log",{params:t})}),P=o({prefix:"/v1/global-settings/option"}),D=s("OptionServices",{getPositions:()=>P.get("/position"),getDivisions:()=>P.get("/division")}),g=o({prefix:"/v1/global-settings/position"}),b=s("PositionServices",{getPositions:t=>g.get("",{params:t}),getPositionDetail:t=>g.get(`/${t}`),postCreatePosition:t=>g.post("/",t),putEditPosition:(t,e)=>g.put(`/${t}`,e),deletePositions:t=>{const e={id:JSON.stringify(t)};return g.delete("",{params:e})}}),T=o({env:"APP_TAGSAMURAI_API",prefix:"/tag/v2"}),C=s("TagServices",{getTagInfo:t=>T.get("/rfid-qr/scan",{params:t})}),A=o({prefix:"/v1/global-settings/change-log"}),N=s("TagEventlogServices",{getTAGEventlog:t=>A.get("/tag-event-log",{params:t}),getTAGEventlogOptions:t=>A.get("/tag-event-log/options",{params:t}),getDetailTAGEventlog:t=>A.get(`/tag-event-log/${t}`)}),i=o({prefix:"/v1/global-settings/user"}),B=s("UserServices",{getUsers:t=>i.get("",{params:t}),getUserDetail:t=>i.get(`/${t}`),getUserSystemLogs:(t,e)=>i.get(`/${t}/system-logs`,{params:e}),getUserSystemLogOptions:(t,e)=>{const r={};return r[e]=!0,i.get(`/${t}/system-logs/options`,{params:r})},postCreateUser:t=>{const e={"Content-Type":"multipart/form-data"};return i.post("",t,{headers:e})},putEditUser:(t,e)=>{const r={"Content-Type":"multipart/form-data"};return i.put(`/${t}`,e,{headers:r})},deleteUsers:t=>{const e={id:JSON.stringify(t)};return i.delete("",{params:e})},putToggleStatusUsers:t=>i.put("/active-status",t),getUserOptions:t=>{const e={};return e[t]=!0,i.get("/options",{params:e})},deleteCancelEmailChange:t=>i.delete(`/cancel-email-change/${t}`),postResendEmail:t=>i.post("/resend-email",t),putChangePassword:(t,e)=>i.put(`/change-password/${t}`,e)})}}});
|