dirk-cfx-react 1.1.89 → 1.1.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/index.cjs +499 -247
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +39 -9
- package/dist/components/index.d.ts +39 -9
- package/dist/components/index.js +500 -249
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.cjs +22 -12
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js +22 -12
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +502 -248
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -2
- package/dist/index.d.ts +43 -2
- package/dist/index.js +500 -250
- package/dist/index.js.map +1 -1
- package/dist/providers/index.cjs +51 -17
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.js +51 -17
- package/dist/providers/index.js.map +1 -1
- package/dist/utils/index.cjs +51 -17
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js +51 -17
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
package/dist/components/index.js
CHANGED
|
@@ -2,9 +2,10 @@ import { Flex, Text, Image, TextInput, Select, Box, useMantineTheme, Tooltip, al
|
|
|
2
2
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import { createContext, memo, useRef, useEffect, useContext, useState, useCallback, useMemo } from 'react';
|
|
4
4
|
import { create, useStore, createStore } from 'zustand';
|
|
5
|
+
import { z } from 'zod';
|
|
5
6
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
6
7
|
import { motion, AnimatePresence, useMotionValue } from 'framer-motion';
|
|
7
|
-
import { Info, X, AlertTriangle, Trash2, RefreshCw, ChevronDown, Check, Copy, MapPin, Crosshair, EyeOff, Eye, RotateCcw, FlaskConical, ChevronUp, Palette,
|
|
8
|
+
import { Info, X, AlertTriangle, Trash2, RefreshCw, ChevronDown, Check, Copy, MapPin, Crosshair, EyeOff, Eye, RotateCcw, FlaskConical, ChevronUp, Palette, ShieldCheck, Users, UserRound, Plus, DoorOpen, Minus, ArrowLeft, Undo2, Redo2, Save, History, XCircle, Code2, Search, Filter, User } from 'lucide-react';
|
|
8
9
|
import clickSoundUrl from '../click_sound-PNCRRTM4.mp3';
|
|
9
10
|
import hoverSoundUrl from '../hover_sound-NBUA222C.mp3';
|
|
10
11
|
import { notifications } from '@mantine/notifications';
|
|
@@ -1282,6 +1283,32 @@ function colorWithAlpha(color, alpha17) {
|
|
|
1282
1283
|
|
|
1283
1284
|
// src/utils/misc.ts
|
|
1284
1285
|
var isEnvBrowser = () => !window.invokeNative;
|
|
1286
|
+
var DEFAULT_PALETTE = [
|
|
1287
|
+
"#f0f4ff",
|
|
1288
|
+
"#d9e3ff",
|
|
1289
|
+
"#bfcfff",
|
|
1290
|
+
"#a6bbff",
|
|
1291
|
+
"#8ca7ff",
|
|
1292
|
+
"#7393ff",
|
|
1293
|
+
"#5a7fff",
|
|
1294
|
+
"#406bff",
|
|
1295
|
+
"#2547ff",
|
|
1296
|
+
"#0b33ff"
|
|
1297
|
+
];
|
|
1298
|
+
z.object({
|
|
1299
|
+
useOverride: z.boolean(),
|
|
1300
|
+
primaryColor: z.string(),
|
|
1301
|
+
primaryShade: z.number(),
|
|
1302
|
+
customTheme: z.array(z.string())
|
|
1303
|
+
});
|
|
1304
|
+
var defaultThemeOverride = {
|
|
1305
|
+
useOverride: false,
|
|
1306
|
+
primaryColor: "dirk",
|
|
1307
|
+
primaryShade: 5,
|
|
1308
|
+
customTheme: DEFAULT_PALETTE
|
|
1309
|
+
};
|
|
1310
|
+
|
|
1311
|
+
// src/utils/useSettings.ts
|
|
1285
1312
|
var useSettings = create(() => ({
|
|
1286
1313
|
currency: "$",
|
|
1287
1314
|
game: "fivem",
|
|
@@ -1289,18 +1316,7 @@ var useSettings = create(() => ({
|
|
|
1289
1316
|
primaryShade: 9,
|
|
1290
1317
|
itemImgPath: "",
|
|
1291
1318
|
resourceVersion: "dev",
|
|
1292
|
-
customTheme:
|
|
1293
|
-
"#f0f4ff",
|
|
1294
|
-
"#d9e3ff",
|
|
1295
|
-
"#bfcfff",
|
|
1296
|
-
"#a6bbff",
|
|
1297
|
-
"#8ca7ff",
|
|
1298
|
-
"#7393ff",
|
|
1299
|
-
"#5a7fff",
|
|
1300
|
-
"#406bff",
|
|
1301
|
-
"#2547ff",
|
|
1302
|
-
"#0b33ff"
|
|
1303
|
-
]
|
|
1319
|
+
customTheme: DEFAULT_PALETTE
|
|
1304
1320
|
}));
|
|
1305
1321
|
|
|
1306
1322
|
// src/utils/fetchNui.ts
|
|
@@ -1343,11 +1359,35 @@ function reportMissingLocale(key) {
|
|
|
1343
1359
|
fetchNui("REPORT_MISSING_LOCALE", { key }).catch(() => {
|
|
1344
1360
|
});
|
|
1345
1361
|
}
|
|
1362
|
+
var PACKAGE_DEFAULTS = {
|
|
1363
|
+
"OccupantsDesc": "Here you can view and manage the occupants of your traphouse. These occupants can be used mainly for selling drugs to the NPCs surrounding your traphouse. However they have other uses to so be careful who you add as an occupant.",
|
|
1364
|
+
"cfgpanel_discard": "Discard",
|
|
1365
|
+
"cfgpanel_manual_edit": "Manual Edit",
|
|
1366
|
+
"cfgpanel_reset_defaults": "Reset Defaults",
|
|
1367
|
+
"cfgpanel_version": "Version",
|
|
1368
|
+
"cfgpanel_back_title": "Back to script list",
|
|
1369
|
+
"cfgpanel_undo": "Undo",
|
|
1370
|
+
"cfgpanel_redo": "Redo",
|
|
1371
|
+
"cfgpanel_save": "Save",
|
|
1372
|
+
"cfgpanel_saving": "Saving...",
|
|
1373
|
+
"cfgpanel_history": "History",
|
|
1374
|
+
"cfgpanel_reset_title": "Reset to Defaults",
|
|
1375
|
+
"cfgpanel_reset_desc": "This will permanently reset ALL config back to the defaults. Every value you have configured will be overwritten. This cannot be undone.",
|
|
1376
|
+
"cfgpanel_reset_confirm": "Reset Config",
|
|
1377
|
+
"cfgpanel_discard_title": "Discard Unsaved Changes?",
|
|
1378
|
+
"cfgpanel_discard_desc_back": "You have unsaved changes. Going back now will discard them.",
|
|
1379
|
+
"cfgpanel_discard_desc_close": "You have unsaved changes. Closing now will discard them.",
|
|
1380
|
+
"cfgpanel_discard_confirm_back": "Go Back Without Saving",
|
|
1381
|
+
"cfgpanel_discard_confirm_close": "Close Without Saving",
|
|
1382
|
+
"cfgpanel_json_title": "Config JSON",
|
|
1383
|
+
"cfgpanel_cancel": "Cancel",
|
|
1384
|
+
"cfgpanel_apply": "Apply",
|
|
1385
|
+
"cfgpanel_history_title": "Config History",
|
|
1386
|
+
"cfgpanel_close": "Close"
|
|
1387
|
+
};
|
|
1346
1388
|
var localeStore = create((set, get) => {
|
|
1347
1389
|
return {
|
|
1348
|
-
locales: {
|
|
1349
|
-
"OccupantsDesc": "Here you can view and manage the occupants of your traphouse. These occupants can be used mainly for selling drugs to the NPCs surrounding your traphouse. However they have other uses to so be careful who you add as an occupant."
|
|
1350
|
-
},
|
|
1390
|
+
locales: { ...PACKAGE_DEFAULTS },
|
|
1351
1391
|
locale: (key, ...args) => {
|
|
1352
1392
|
const exists = get().locales[key];
|
|
1353
1393
|
if (!exists) reportMissingLocale(key);
|
|
@@ -1361,7 +1401,7 @@ var localeStore = create((set, get) => {
|
|
|
1361
1401
|
});
|
|
1362
1402
|
var locale = localeStore.getState().locale;
|
|
1363
1403
|
registerInitialFetch("GET_LOCALES", void 0).then((data) => {
|
|
1364
|
-
localeStore.setState({ locales: data });
|
|
1404
|
+
localeStore.setState({ locales: { ...PACKAGE_DEFAULTS, ...data } });
|
|
1365
1405
|
}).catch(() => {
|
|
1366
1406
|
});
|
|
1367
1407
|
if (typeof window !== "undefined") {
|
|
@@ -1370,7 +1410,7 @@ if (typeof window !== "undefined") {
|
|
|
1370
1410
|
if (!msg || msg.action !== "UPDATE_DIRK_LIB_LOCALES") return;
|
|
1371
1411
|
if (!msg.data || typeof msg.data !== "object") return;
|
|
1372
1412
|
if (Object.keys(msg.data).length === 0) return;
|
|
1373
|
-
localeStore.setState({ locales: msg.data });
|
|
1413
|
+
localeStore.setState({ locales: { ...PACKAGE_DEFAULTS, ...msg.data } });
|
|
1374
1414
|
});
|
|
1375
1415
|
}
|
|
1376
1416
|
|
|
@@ -3130,11 +3170,11 @@ function ConfirmModal({
|
|
|
3130
3170
|
placeholder: confirmText,
|
|
3131
3171
|
value: typed,
|
|
3132
3172
|
onChange: (e) => setTyped(e.currentTarget.value),
|
|
3133
|
-
styles: (
|
|
3173
|
+
styles: (t4) => ({
|
|
3134
3174
|
input: {
|
|
3135
|
-
backgroundColor: alpha(
|
|
3175
|
+
backgroundColor: alpha(t4.colors.dark[7], 0.5),
|
|
3136
3176
|
border: `0.1vh solid ${alpha(
|
|
3137
|
-
typed === confirmText ? "#ef4444" :
|
|
3177
|
+
typed === confirmText ? "#ef4444" : t4.colors.dark[5],
|
|
3138
3178
|
0.5
|
|
3139
3179
|
)}`,
|
|
3140
3180
|
color: "rgba(255,255,255,0.85)",
|
|
@@ -3779,7 +3819,7 @@ function useAdminState(key, initial) {
|
|
|
3779
3819
|
useEffect(() => {
|
|
3780
3820
|
const set = listeners.get(key) ?? /* @__PURE__ */ new Set();
|
|
3781
3821
|
listeners.set(key, set);
|
|
3782
|
-
const handler = () => setTick((
|
|
3822
|
+
const handler = () => setTick((t4) => t4 + 1);
|
|
3783
3823
|
set.add(handler);
|
|
3784
3824
|
return () => {
|
|
3785
3825
|
set.delete(handler);
|
|
@@ -3899,7 +3939,7 @@ function ConfigJsonModal({
|
|
|
3899
3939
|
setError(e.message);
|
|
3900
3940
|
}
|
|
3901
3941
|
};
|
|
3902
|
-
return /* @__PURE__ */ jsxs(Modal, { title: "
|
|
3942
|
+
return /* @__PURE__ */ jsxs(Modal, { title: locale("cfgpanel_json_title"), icon: Code2, iconColor: color, onClose, width: "60vh", maxHeight: "80vh", zIndex: 200, children: [
|
|
3903
3943
|
/* @__PURE__ */ jsxs(Box, { flex: 1, p: "0.8vh", style: { overflowY: "auto" }, children: [
|
|
3904
3944
|
/* @__PURE__ */ jsx(
|
|
3905
3945
|
JsonInput,
|
|
@@ -3927,7 +3967,7 @@ function ConfigJsonModal({
|
|
|
3927
3967
|
style: { background: "transparent", border: `0.1vh solid ${theme.colors.dark[6]}`, borderRadius: theme.radius.xs, padding: `${theme.spacing.xxs} ${theme.spacing.xs}`, cursor: "pointer", display: "flex", alignItems: "center", gap: theme.spacing.xxs },
|
|
3928
3968
|
children: [
|
|
3929
3969
|
/* @__PURE__ */ jsx(X, { color: "rgba(255,255,255,0.4)" }),
|
|
3930
|
-
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.05em", c: "rgba(255,255,255,0.4)", children: "
|
|
3970
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.05em", c: "rgba(255,255,255,0.4)", children: locale("cfgpanel_cancel") })
|
|
3931
3971
|
]
|
|
3932
3972
|
}
|
|
3933
3973
|
),
|
|
@@ -3940,7 +3980,7 @@ function ConfigJsonModal({
|
|
|
3940
3980
|
style: { background: alpha(color, 0.14), border: `0.1vh solid ${alpha(color, 0.4)}`, borderRadius: theme.radius.xs, padding: `${theme.spacing.xxs} ${theme.spacing.xs}`, cursor: "pointer", display: "flex", alignItems: "center", gap: theme.spacing.xxs },
|
|
3941
3981
|
children: [
|
|
3942
3982
|
/* @__PURE__ */ jsx(Check, { color }),
|
|
3943
|
-
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.05em", c: color, children: "
|
|
3983
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.05em", c: color, children: locale("cfgpanel_apply") })
|
|
3944
3984
|
]
|
|
3945
3985
|
}
|
|
3946
3986
|
)
|
|
@@ -4081,7 +4121,7 @@ function ConfigHistoryModal({
|
|
|
4081
4121
|
historyQuery.fetchNextPage();
|
|
4082
4122
|
}
|
|
4083
4123
|
};
|
|
4084
|
-
return /* @__PURE__ */ jsxs(Modal, { title: "
|
|
4124
|
+
return /* @__PURE__ */ jsxs(Modal, { title: locale("cfgpanel_history_title"), icon: History, iconColor: color, onClose, width: "88vh", maxHeight: "82vh", zIndex: 260, children: [
|
|
4085
4125
|
/* @__PURE__ */ jsxs(Flex, { direction: "column", style: { flex: 1, minHeight: 0 }, children: [
|
|
4086
4126
|
/* @__PURE__ */ jsxs(Flex, { gap: "xs", p: "sm", style: { borderBottom: `0.1vh solid ${alpha(theme.colors.dark[7], 0.8)}` }, children: [
|
|
4087
4127
|
/* @__PURE__ */ jsx(TextInput, { leftSection: /* @__PURE__ */ jsx(Search, { size: "1.4vh" }), placeholder: "Search path/admin/value", value: queryInput, onChange: (e) => setQueryInput(e.currentTarget.value), size: "xs", style: { flex: 1 } }),
|
|
@@ -4124,7 +4164,7 @@ function ConfigHistoryModal({
|
|
|
4124
4164
|
style: { background: "transparent", border: `0.1vh solid ${theme.colors.dark[6]}`, borderRadius: theme.radius.xs, padding: `${theme.spacing.xxs} ${theme.spacing.xs}`, cursor: "pointer", display: "flex", alignItems: "center", gap: theme.spacing.xxs },
|
|
4125
4165
|
children: [
|
|
4126
4166
|
/* @__PURE__ */ jsx(X, { color: "rgba(255,255,255,0.4)", size: "1.5vh" }),
|
|
4127
|
-
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.05em", c: "rgba(255,255,255,0.4)", children: "
|
|
4167
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.05em", c: "rgba(255,255,255,0.4)", children: locale("cfgpanel_close") })
|
|
4128
4168
|
]
|
|
4129
4169
|
}
|
|
4130
4170
|
) })
|
|
@@ -4184,9 +4224,9 @@ function ConfigPanelInner({
|
|
|
4184
4224
|
/* @__PURE__ */ jsx(AnimatePresence, { children: resetOpen && /* @__PURE__ */ jsx(
|
|
4185
4225
|
ConfirmModal,
|
|
4186
4226
|
{
|
|
4187
|
-
title: "
|
|
4188
|
-
description: "
|
|
4189
|
-
confirmLabel: "
|
|
4227
|
+
title: locale("cfgpanel_reset_title"),
|
|
4228
|
+
description: locale("cfgpanel_reset_desc"),
|
|
4229
|
+
confirmLabel: locale("cfgpanel_reset_confirm"),
|
|
4190
4230
|
confirmText: resetConfirmText,
|
|
4191
4231
|
onConfirm: async () => {
|
|
4192
4232
|
setResetOpen(false);
|
|
@@ -4218,9 +4258,9 @@ function ConfigPanelInner({
|
|
|
4218
4258
|
/* @__PURE__ */ jsx(AnimatePresence, { children: pendingAction !== null && /* @__PURE__ */ jsx(
|
|
4219
4259
|
ConfirmModal,
|
|
4220
4260
|
{
|
|
4221
|
-
title: "
|
|
4222
|
-
description: pendingAction === "back" ? "
|
|
4223
|
-
confirmLabel: pendingAction === "back" ? "
|
|
4261
|
+
title: locale("cfgpanel_discard_title"),
|
|
4262
|
+
description: pendingAction === "back" ? locale("cfgpanel_discard_desc_back") : locale("cfgpanel_discard_desc_close"),
|
|
4263
|
+
confirmLabel: pendingAction === "back" ? locale("cfgpanel_discard_confirm_back") : locale("cfgpanel_discard_confirm_close"),
|
|
4224
4264
|
onConfirm: () => {
|
|
4225
4265
|
const action = pendingAction;
|
|
4226
4266
|
setPendingAction(null);
|
|
@@ -4258,7 +4298,7 @@ function ConfigPanelInner({
|
|
|
4258
4298
|
/* @__PURE__ */ jsx(
|
|
4259
4299
|
motion.button,
|
|
4260
4300
|
{
|
|
4261
|
-
title: "
|
|
4301
|
+
title: locale("cfgpanel_back_title"),
|
|
4262
4302
|
onClick: handleBack,
|
|
4263
4303
|
whileHover: { background: alpha(color, 0.16), borderColor: alpha(color, 0.45) },
|
|
4264
4304
|
whileTap: { scale: 0.95 },
|
|
@@ -4286,7 +4326,7 @@ function ConfigPanelInner({
|
|
|
4286
4326
|
/* @__PURE__ */ jsx(
|
|
4287
4327
|
motion.button,
|
|
4288
4328
|
{
|
|
4289
|
-
title: "
|
|
4329
|
+
title: locale("cfgpanel_undo"),
|
|
4290
4330
|
onClick: () => form.canBack && form.back(),
|
|
4291
4331
|
disabled: !form.canBack,
|
|
4292
4332
|
whileHover: form.canBack ? { background: "rgba(255,255,255,0.07)" } : void 0,
|
|
@@ -4298,7 +4338,7 @@ function ConfigPanelInner({
|
|
|
4298
4338
|
/* @__PURE__ */ jsx(
|
|
4299
4339
|
motion.button,
|
|
4300
4340
|
{
|
|
4301
|
-
title: "
|
|
4341
|
+
title: locale("cfgpanel_redo"),
|
|
4302
4342
|
onClick: () => form.canForward && form.forward(),
|
|
4303
4343
|
disabled: !form.canForward,
|
|
4304
4344
|
whileHover: form.canForward ? { background: "rgba(255,255,255,0.07)" } : void 0,
|
|
@@ -4310,7 +4350,7 @@ function ConfigPanelInner({
|
|
|
4310
4350
|
/* @__PURE__ */ jsx(
|
|
4311
4351
|
motion.button,
|
|
4312
4352
|
{
|
|
4313
|
-
title: isSaving ? "
|
|
4353
|
+
title: isSaving ? locale("cfgpanel_saving") : isDirty ? `${locale("cfgpanel_save")} (${changedCount})` : locale("cfgpanel_save"),
|
|
4314
4354
|
onClick: () => isDirty && !isSaving && form.submit(),
|
|
4315
4355
|
disabled: !isDirty || isSaving,
|
|
4316
4356
|
whileHover: isDirty && !isSaving ? { background: alpha(color, 0.25), borderColor: alpha(color, 0.5) } : void 0,
|
|
@@ -4322,7 +4362,7 @@ function ConfigPanelInner({
|
|
|
4322
4362
|
/* @__PURE__ */ jsx(
|
|
4323
4363
|
motion.button,
|
|
4324
4364
|
{
|
|
4325
|
-
title: "
|
|
4365
|
+
title: locale("cfgpanel_history"),
|
|
4326
4366
|
onClick: () => setHistoryOpen(true),
|
|
4327
4367
|
whileHover: { background: alpha("#22d3ee", 0.16), borderColor: alpha("#22d3ee", 0.5) },
|
|
4328
4368
|
whileTap: { scale: 0.97 },
|
|
@@ -4343,7 +4383,7 @@ function ConfigPanelInner({
|
|
|
4343
4383
|
style: { width: "100%", background: "transparent", border: `0.1vh solid ${isDirty ? alpha("#f97316", 0.35) : alpha(theme.colors.dark[5], 0.3)}`, borderRadius: theme.radius.xs, padding: "0.65vh 0.8vh", cursor: isDirty ? "pointer" : "default", display: "flex", alignItems: "center", gap: "0.55vh", opacity: isDirty ? 1 : 0.35, transition: "opacity 0.2s" },
|
|
4344
4384
|
children: [
|
|
4345
4385
|
/* @__PURE__ */ jsx(XCircle, { color: isDirty ? "#f97316" : "rgba(255,255,255,0.35)", size: "1.6vh" }),
|
|
4346
|
-
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: isDirty ? "#f97316" : "rgba(255,255,255,0.35)", children: "
|
|
4386
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: isDirty ? "#f97316" : "rgba(255,255,255,0.35)", children: locale("cfgpanel_discard") })
|
|
4347
4387
|
]
|
|
4348
4388
|
}
|
|
4349
4389
|
),
|
|
@@ -4357,7 +4397,7 @@ function ConfigPanelInner({
|
|
|
4357
4397
|
style: { width: "100%", background: alpha(color, 0.07), border: `0.1vh solid ${alpha(color, 0.28)}`, borderRadius: theme.radius.xs, padding: "0.65vh 0.8vh", cursor: "pointer", display: "flex", alignItems: "center", gap: "0.55vh" },
|
|
4358
4398
|
children: [
|
|
4359
4399
|
/* @__PURE__ */ jsx(Code2, { color, size: "1.6vh" }),
|
|
4360
|
-
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: "
|
|
4400
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: locale("cfgpanel_manual_edit") })
|
|
4361
4401
|
]
|
|
4362
4402
|
}
|
|
4363
4403
|
),
|
|
@@ -4370,12 +4410,13 @@ function ConfigPanelInner({
|
|
|
4370
4410
|
style: { width: "100%", background: alpha("#ef4444", 0.07), border: `0.1vh solid ${alpha("#ef4444", 0.25)}`, borderRadius: theme.radius.xs, padding: "0.65vh 0.8vh", cursor: "pointer", display: "flex", alignItems: "center", gap: "0.55vh" },
|
|
4371
4411
|
children: [
|
|
4372
4412
|
/* @__PURE__ */ jsx(RotateCcw, { color: "#ef4444", size: "1.6vh" }),
|
|
4373
|
-
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: "#ef4444", children: "
|
|
4413
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: "#ef4444", children: locale("cfgpanel_reset_defaults") })
|
|
4374
4414
|
]
|
|
4375
4415
|
}
|
|
4376
4416
|
),
|
|
4377
4417
|
version && /* @__PURE__ */ jsxs(Text, { size: "0.95vh", c: "dimmed", ta: "center", style: { letterSpacing: "0.04em", opacity: 0.8 }, children: [
|
|
4378
|
-
"
|
|
4418
|
+
locale("cfgpanel_version"),
|
|
4419
|
+
" ",
|
|
4379
4420
|
version
|
|
4380
4421
|
] })
|
|
4381
4422
|
] })
|
|
@@ -5466,24 +5507,6 @@ var MANTINE_COLOR_OPTIONS = [
|
|
|
5466
5507
|
"yellow",
|
|
5467
5508
|
"orange"
|
|
5468
5509
|
].map((value) => ({ value, label: value }));
|
|
5469
|
-
var DEFAULT_PALETTE = [
|
|
5470
|
-
"#f0f4ff",
|
|
5471
|
-
"#d9e3ff",
|
|
5472
|
-
"#bfcfff",
|
|
5473
|
-
"#a6bbff",
|
|
5474
|
-
"#8ca7ff",
|
|
5475
|
-
"#7393ff",
|
|
5476
|
-
"#5a7fff",
|
|
5477
|
-
"#406bff",
|
|
5478
|
-
"#2547ff",
|
|
5479
|
-
"#0b33ff"
|
|
5480
|
-
];
|
|
5481
|
-
var DEFAULT_VALUE = {
|
|
5482
|
-
useOverride: false,
|
|
5483
|
-
primaryColor: "dirk",
|
|
5484
|
-
primaryShade: 5,
|
|
5485
|
-
customTheme: DEFAULT_PALETTE
|
|
5486
|
-
};
|
|
5487
5510
|
function GroupLabel({ label }) {
|
|
5488
5511
|
return /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", mt: "xxs", children: [
|
|
5489
5512
|
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.07em", c: "rgba(255,255,255,0.2)", children: label }),
|
|
@@ -5498,10 +5521,10 @@ function ThemeOverrideSection({
|
|
|
5498
5521
|
const color = mantineTheme.colors[mantineTheme.primaryColor][5];
|
|
5499
5522
|
const raw = useFormField(schemaKey);
|
|
5500
5523
|
const value = {
|
|
5501
|
-
useOverride: raw?.useOverride ??
|
|
5502
|
-
primaryColor: raw?.primaryColor ??
|
|
5503
|
-
primaryShade: raw?.primaryShade ??
|
|
5504
|
-
customTheme: Array.isArray(raw?.customTheme) && raw.customTheme.length === 10 ? raw.customTheme :
|
|
5524
|
+
useOverride: raw?.useOverride ?? defaultThemeOverride.useOverride,
|
|
5525
|
+
primaryColor: raw?.primaryColor ?? defaultThemeOverride.primaryColor,
|
|
5526
|
+
primaryShade: raw?.primaryShade ?? defaultThemeOverride.primaryShade,
|
|
5527
|
+
customTheme: Array.isArray(raw?.customTheme) && raw.customTheme.length === 10 ? raw.customTheme : defaultThemeOverride.customTheme
|
|
5505
5528
|
};
|
|
5506
5529
|
const { setValue } = useFormActions();
|
|
5507
5530
|
const set = (key, val) => setValue(schemaKey, { ...value, [key]: val });
|
|
@@ -5708,6 +5731,403 @@ function SwatchTile({
|
|
|
5708
5731
|
) })
|
|
5709
5732
|
] });
|
|
5710
5733
|
}
|
|
5734
|
+
function usePlayers(opts = {}) {
|
|
5735
|
+
const {
|
|
5736
|
+
includeOffline = false,
|
|
5737
|
+
search = "",
|
|
5738
|
+
limit = 50,
|
|
5739
|
+
staleTimeMs,
|
|
5740
|
+
refetchIntervalMs
|
|
5741
|
+
} = opts;
|
|
5742
|
+
const query = useQuery({
|
|
5743
|
+
queryKey: includeOffline ? ["dirk:players", "search", search.trim().toLowerCase(), limit] : ["dirk:players", "online"],
|
|
5744
|
+
queryFn: async () => {
|
|
5745
|
+
const toolId = includeOffline ? "searchPlayers" : "getOnlinePlayers";
|
|
5746
|
+
const payload = includeOffline ? { id: toolId, value: { search: search.trim(), limit } } : { id: toolId };
|
|
5747
|
+
const result = await fetchNui(
|
|
5748
|
+
"ADMIN_TOOL_QUERY",
|
|
5749
|
+
payload,
|
|
5750
|
+
// Browser-dev fallback. Returns a couple of mock players so the
|
|
5751
|
+
// dev shell isn't blank.
|
|
5752
|
+
includeOffline ? [
|
|
5753
|
+
{ id: 1, citizenId: "ABC12345", name: "Dev User", charName: "John Doe", online: true },
|
|
5754
|
+
{ id: null, citizenId: "DEF67890", name: "", charName: "Jane Offline", online: false }
|
|
5755
|
+
] : [
|
|
5756
|
+
{ id: 1, citizenId: "ABC12345", name: "Dev User", charName: "John Doe", online: true }
|
|
5757
|
+
]
|
|
5758
|
+
);
|
|
5759
|
+
return Array.isArray(result) ? result : [];
|
|
5760
|
+
},
|
|
5761
|
+
staleTime: staleTimeMs ?? (includeOffline ? 3e4 : 5e3),
|
|
5762
|
+
gcTime: 5 * 6e4,
|
|
5763
|
+
refetchInterval: refetchIntervalMs ?? false,
|
|
5764
|
+
refetchOnWindowFocus: false,
|
|
5765
|
+
placeholderData: includeOffline ? keepPreviousData : void 0
|
|
5766
|
+
});
|
|
5767
|
+
return {
|
|
5768
|
+
players: query.data ?? [],
|
|
5769
|
+
isLoading: query.isLoading,
|
|
5770
|
+
isFetching: query.isFetching,
|
|
5771
|
+
error: query.error ?? null,
|
|
5772
|
+
refresh: () => query.refetch()
|
|
5773
|
+
};
|
|
5774
|
+
}
|
|
5775
|
+
var DEBOUNCE_MS = 300;
|
|
5776
|
+
var ONLINE_COLOR = "#3FA83F";
|
|
5777
|
+
var OFFLINE_COLOR = "#E54141";
|
|
5778
|
+
function PlayerSelect({
|
|
5779
|
+
value,
|
|
5780
|
+
onChange,
|
|
5781
|
+
includeOffline = false,
|
|
5782
|
+
limit = 50,
|
|
5783
|
+
searchable: searchableProp,
|
|
5784
|
+
placeholder,
|
|
5785
|
+
nothingFoundMessage: nothingFoundMessageProp,
|
|
5786
|
+
loadingLabel = "Loading\u2026",
|
|
5787
|
+
onlineLabel = "Online",
|
|
5788
|
+
offlineLabel = "Offline",
|
|
5789
|
+
refreshLabel = "Refresh player list",
|
|
5790
|
+
...rest
|
|
5791
|
+
}) {
|
|
5792
|
+
const theme = useMantineTheme();
|
|
5793
|
+
const color = theme.colors[theme.primaryColor][5];
|
|
5794
|
+
const [searchInput, setSearchInput] = useState("");
|
|
5795
|
+
const [debouncedSearch, setDebouncedSearch] = useState("");
|
|
5796
|
+
const { players, isFetching, refresh } = usePlayers({
|
|
5797
|
+
includeOffline,
|
|
5798
|
+
search: includeOffline ? debouncedSearch : void 0,
|
|
5799
|
+
limit
|
|
5800
|
+
});
|
|
5801
|
+
const sortedPlayers = useMemo(
|
|
5802
|
+
() => [...players].sort((a, b) => {
|
|
5803
|
+
if (a.online !== b.online) return a.online ? -1 : 1;
|
|
5804
|
+
return a.charName.localeCompare(b.charName);
|
|
5805
|
+
}),
|
|
5806
|
+
[players]
|
|
5807
|
+
);
|
|
5808
|
+
const playerByCitizen = useMemo(() => {
|
|
5809
|
+
const m = /* @__PURE__ */ new Map();
|
|
5810
|
+
for (const p of sortedPlayers) m.set(p.citizenId, p);
|
|
5811
|
+
return m;
|
|
5812
|
+
}, [sortedPlayers]);
|
|
5813
|
+
const data = useMemo(() => {
|
|
5814
|
+
const items = sortedPlayers.map((p) => ({
|
|
5815
|
+
value: p.citizenId,
|
|
5816
|
+
label: formatLabel(p)
|
|
5817
|
+
}));
|
|
5818
|
+
if (value && !items.some((i) => i.value === value)) {
|
|
5819
|
+
items.unshift({ value, label: value });
|
|
5820
|
+
}
|
|
5821
|
+
return items;
|
|
5822
|
+
}, [sortedPlayers, value]);
|
|
5823
|
+
const selectedPlayer = value ? playerByCitizen.get(value) ?? null : null;
|
|
5824
|
+
const selectedLabel = selectedPlayer ? formatLabel(selectedPlayer) : null;
|
|
5825
|
+
useEffect(() => {
|
|
5826
|
+
if (!includeOffline) return;
|
|
5827
|
+
if (selectedLabel && searchInput === selectedLabel) return;
|
|
5828
|
+
const t4 = setTimeout(() => setDebouncedSearch(searchInput), DEBOUNCE_MS);
|
|
5829
|
+
return () => clearTimeout(t4);
|
|
5830
|
+
}, [searchInput, includeOffline, selectedLabel]);
|
|
5831
|
+
const renderOption = ({ option }) => {
|
|
5832
|
+
const p = playerByCitizen.get(option.value);
|
|
5833
|
+
if (!p) return option.label;
|
|
5834
|
+
return /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", gap: "xs", style: { width: "100%" }, children: [
|
|
5835
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", truncate: true, style: { flex: 1 }, children: formatLabel(p) }),
|
|
5836
|
+
/* @__PURE__ */ jsx(StatusDot, { online: p.online, onlineLabel, offlineLabel })
|
|
5837
|
+
] });
|
|
5838
|
+
};
|
|
5839
|
+
return /* @__PURE__ */ jsx(
|
|
5840
|
+
Select,
|
|
5841
|
+
{
|
|
5842
|
+
...rest,
|
|
5843
|
+
data,
|
|
5844
|
+
value: value ?? null,
|
|
5845
|
+
onChange: (v) => {
|
|
5846
|
+
if (!v) return onChange(null);
|
|
5847
|
+
const player = playerByCitizen.get(v) ?? null;
|
|
5848
|
+
onChange(player);
|
|
5849
|
+
},
|
|
5850
|
+
searchable: searchableProp ?? true,
|
|
5851
|
+
searchValue: includeOffline ? searchInput : void 0,
|
|
5852
|
+
onSearchChange: includeOffline ? setSearchInput : void 0,
|
|
5853
|
+
placeholder,
|
|
5854
|
+
nothingFoundMessage: isFetching ? loadingLabel : nothingFoundMessageProp ?? "No players found",
|
|
5855
|
+
maxDropdownHeight: 300,
|
|
5856
|
+
renderOption,
|
|
5857
|
+
leftSection: selectedPlayer ? /* @__PURE__ */ jsx(StatusDot, { online: selectedPlayer.online, onlineLabel, offlineLabel }) : void 0,
|
|
5858
|
+
rightSectionWidth: "3.5vh",
|
|
5859
|
+
rightSectionPointerEvents: "all",
|
|
5860
|
+
rightSection: /* @__PURE__ */ jsx(
|
|
5861
|
+
ActionIcon,
|
|
5862
|
+
{
|
|
5863
|
+
variant: "subtle",
|
|
5864
|
+
size: "sm",
|
|
5865
|
+
onClick: (e) => {
|
|
5866
|
+
e.stopPropagation();
|
|
5867
|
+
refresh();
|
|
5868
|
+
},
|
|
5869
|
+
"aria-label": refreshLabel,
|
|
5870
|
+
title: refreshLabel,
|
|
5871
|
+
style: { marginRight: "0.6vh" },
|
|
5872
|
+
children: isFetching ? /* @__PURE__ */ jsx(Loader, { size: "1.2vh", color }) : /* @__PURE__ */ jsx(RefreshCw, { size: "1.4vh", color })
|
|
5873
|
+
}
|
|
5874
|
+
)
|
|
5875
|
+
}
|
|
5876
|
+
);
|
|
5877
|
+
}
|
|
5878
|
+
function StatusDot({ online, onlineLabel, offlineLabel }) {
|
|
5879
|
+
return /* @__PURE__ */ jsx(
|
|
5880
|
+
"span",
|
|
5881
|
+
{
|
|
5882
|
+
title: online ? onlineLabel : offlineLabel,
|
|
5883
|
+
style: {
|
|
5884
|
+
display: "inline-block",
|
|
5885
|
+
width: "0.9vh",
|
|
5886
|
+
height: "0.9vh",
|
|
5887
|
+
borderRadius: "50%",
|
|
5888
|
+
backgroundColor: online ? ONLINE_COLOR : OFFLINE_COLOR,
|
|
5889
|
+
boxShadow: `0 0 0.4vh ${online ? ONLINE_COLOR : OFFLINE_COLOR}`,
|
|
5890
|
+
flexShrink: 0
|
|
5891
|
+
}
|
|
5892
|
+
}
|
|
5893
|
+
);
|
|
5894
|
+
}
|
|
5895
|
+
function formatLabel(p) {
|
|
5896
|
+
const parts = [p.charName || p.citizenId];
|
|
5897
|
+
if (p.online) {
|
|
5898
|
+
if (p.name) parts.push(p.name);
|
|
5899
|
+
if (p.id != null) parts.push(`#${p.id}`);
|
|
5900
|
+
}
|
|
5901
|
+
return parts.join(" \xB7 ");
|
|
5902
|
+
}
|
|
5903
|
+
var t = (key, fallback) => {
|
|
5904
|
+
const v = locale(key);
|
|
5905
|
+
return v === key ? fallback : v;
|
|
5906
|
+
};
|
|
5907
|
+
var DEFAULT_VALUE = {
|
|
5908
|
+
groups: [],
|
|
5909
|
+
identifiers: []
|
|
5910
|
+
};
|
|
5911
|
+
function SectionLabel({ icon: Icon, label }) {
|
|
5912
|
+
return /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", mt: "xs", children: [
|
|
5913
|
+
/* @__PURE__ */ jsx(Icon, { size: "1.4vh", color: "rgba(255,255,255,0.3)" }),
|
|
5914
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.07em", c: "rgba(255,255,255,0.2)", children: label }),
|
|
5915
|
+
/* @__PURE__ */ jsx("div", { style: { flex: 1, height: "0.05vh", background: "rgba(255,255,255,0.06)" } })
|
|
5916
|
+
] });
|
|
5917
|
+
}
|
|
5918
|
+
function EmptyHint({ text }) {
|
|
5919
|
+
return /* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.25)", ta: "center", py: "xs", children: text });
|
|
5920
|
+
}
|
|
5921
|
+
function AccessOverrideSection({
|
|
5922
|
+
schemaKey = "access",
|
|
5923
|
+
title,
|
|
5924
|
+
description,
|
|
5925
|
+
groupType,
|
|
5926
|
+
includeOffline = true
|
|
5927
|
+
}) {
|
|
5928
|
+
const mantineTheme = useMantineTheme();
|
|
5929
|
+
const color = mantineTheme.colors[mantineTheme.primaryColor][5];
|
|
5930
|
+
const raw = useFormField(schemaKey);
|
|
5931
|
+
const value = {
|
|
5932
|
+
groups: Array.isArray(raw?.groups) ? raw.groups : DEFAULT_VALUE.groups,
|
|
5933
|
+
identifiers: Array.isArray(raw?.identifiers) ? raw.identifiers : DEFAULT_VALUE.identifiers
|
|
5934
|
+
};
|
|
5935
|
+
const { setValue } = useFormActions();
|
|
5936
|
+
const set = (key, val) => setValue(schemaKey, { ...value, [key]: val });
|
|
5937
|
+
const [addingGroup, setAddingGroup] = useState(false);
|
|
5938
|
+
const [addingPlayer, setAddingPlayer] = useState(false);
|
|
5939
|
+
const commitGroup = (name) => {
|
|
5940
|
+
if (!name) return;
|
|
5941
|
+
set("groups", [...value.groups, name]);
|
|
5942
|
+
setAddingGroup(false);
|
|
5943
|
+
};
|
|
5944
|
+
const setGroup = (index, name) => {
|
|
5945
|
+
const next = [...value.groups];
|
|
5946
|
+
next[index] = name;
|
|
5947
|
+
set("groups", next.filter((g) => g !== ""));
|
|
5948
|
+
};
|
|
5949
|
+
const removeGroup = (index) => set("groups", value.groups.filter((_, i) => i !== index));
|
|
5950
|
+
const commitIdentifier = (id) => {
|
|
5951
|
+
if (!id) return;
|
|
5952
|
+
set("identifiers", [...value.identifiers, id]);
|
|
5953
|
+
setAddingPlayer(false);
|
|
5954
|
+
};
|
|
5955
|
+
const setIdentifier = (index, id) => {
|
|
5956
|
+
const next = [...value.identifiers];
|
|
5957
|
+
next[index] = id;
|
|
5958
|
+
set("identifiers", next.filter((x) => x !== ""));
|
|
5959
|
+
};
|
|
5960
|
+
const removeIdentifier = (index) => set("identifiers", value.identifiers.filter((_, i) => i !== index));
|
|
5961
|
+
return /* @__PURE__ */ jsxs(
|
|
5962
|
+
Flex,
|
|
5963
|
+
{
|
|
5964
|
+
direction: "column",
|
|
5965
|
+
gap: "xs",
|
|
5966
|
+
p: "sm",
|
|
5967
|
+
style: { flex: 1, minHeight: 0, overflowY: "auto" },
|
|
5968
|
+
children: [
|
|
5969
|
+
/* @__PURE__ */ jsx(
|
|
5970
|
+
AdminPageTitle,
|
|
5971
|
+
{
|
|
5972
|
+
icon: ShieldCheck,
|
|
5973
|
+
title: title || t("Access", "Access"),
|
|
5974
|
+
color
|
|
5975
|
+
}
|
|
5976
|
+
),
|
|
5977
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.4)", children: description || t(
|
|
5978
|
+
"AccessOverrideDesc",
|
|
5979
|
+
"Grant access to this resource's admin panel to specific groups and players, in addition to your global dirk_lib admins. Enforcement is server-side."
|
|
5980
|
+
) }),
|
|
5981
|
+
/* @__PURE__ */ jsx(SectionLabel, { icon: Users, label: t("AccessGroups", "Groups") }),
|
|
5982
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "xxs", children: [
|
|
5983
|
+
value.groups.length === 0 && !addingGroup && /* @__PURE__ */ jsx(EmptyHint, { text: t("AccessNoGroups", "No groups added.") }),
|
|
5984
|
+
value.groups.map((name, i) => /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", children: [
|
|
5985
|
+
/* @__PURE__ */ jsx(
|
|
5986
|
+
GroupName,
|
|
5987
|
+
{
|
|
5988
|
+
value: name,
|
|
5989
|
+
onChange: (v) => setGroup(i, v),
|
|
5990
|
+
type: groupType,
|
|
5991
|
+
placeholder: t("AccessPickGroup", "Pick a group\u2026"),
|
|
5992
|
+
style: { flex: 1 }
|
|
5993
|
+
}
|
|
5994
|
+
),
|
|
5995
|
+
/* @__PURE__ */ jsx(
|
|
5996
|
+
ActionIcon,
|
|
5997
|
+
{
|
|
5998
|
+
variant: "subtle",
|
|
5999
|
+
color: "red",
|
|
6000
|
+
size: "md",
|
|
6001
|
+
onClick: () => removeGroup(i),
|
|
6002
|
+
title: t("Remove", "Remove"),
|
|
6003
|
+
"aria-label": t("Remove", "Remove"),
|
|
6004
|
+
children: /* @__PURE__ */ jsx(Trash2, { size: "1.4vh" })
|
|
6005
|
+
}
|
|
6006
|
+
)
|
|
6007
|
+
] }, i)),
|
|
6008
|
+
addingGroup && /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", children: [
|
|
6009
|
+
/* @__PURE__ */ jsx(
|
|
6010
|
+
GroupName,
|
|
6011
|
+
{
|
|
6012
|
+
value: "",
|
|
6013
|
+
onChange: (v) => commitGroup(v),
|
|
6014
|
+
type: groupType,
|
|
6015
|
+
placeholder: t("AccessPickGroup", "Pick a group\u2026"),
|
|
6016
|
+
style: { flex: 1 }
|
|
6017
|
+
}
|
|
6018
|
+
),
|
|
6019
|
+
/* @__PURE__ */ jsx(
|
|
6020
|
+
ActionIcon,
|
|
6021
|
+
{
|
|
6022
|
+
variant: "subtle",
|
|
6023
|
+
color: "red",
|
|
6024
|
+
size: "md",
|
|
6025
|
+
onClick: () => setAddingGroup(false),
|
|
6026
|
+
title: t("Remove", "Remove"),
|
|
6027
|
+
"aria-label": t("Remove", "Remove"),
|
|
6028
|
+
children: /* @__PURE__ */ jsx(Trash2, { size: "1.4vh" })
|
|
6029
|
+
}
|
|
6030
|
+
)
|
|
6031
|
+
] })
|
|
6032
|
+
] }),
|
|
6033
|
+
!addingGroup && /* @__PURE__ */ jsx(AddRowButton, { label: t("AccessAddGroup", "Add group"), onClick: () => setAddingGroup(true) }),
|
|
6034
|
+
/* @__PURE__ */ jsx(SectionLabel, { icon: UserRound, label: t("AccessPlayers", "Players") }),
|
|
6035
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "xxs", children: [
|
|
6036
|
+
value.identifiers.length === 0 && !addingPlayer && /* @__PURE__ */ jsx(EmptyHint, { text: t("AccessNoPlayers", "No players added.") }),
|
|
6037
|
+
value.identifiers.map((id, i) => /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", children: [
|
|
6038
|
+
/* @__PURE__ */ jsx(
|
|
6039
|
+
PlayerSelect,
|
|
6040
|
+
{
|
|
6041
|
+
value: id || null,
|
|
6042
|
+
onChange: (p) => setIdentifier(i, p?.citizenId ?? ""),
|
|
6043
|
+
includeOffline,
|
|
6044
|
+
placeholder: t("AccessPickPlayer", "Pick a player\u2026"),
|
|
6045
|
+
style: { flex: 1 },
|
|
6046
|
+
size: "xs"
|
|
6047
|
+
}
|
|
6048
|
+
),
|
|
6049
|
+
/* @__PURE__ */ jsx(
|
|
6050
|
+
ActionIcon,
|
|
6051
|
+
{
|
|
6052
|
+
variant: "subtle",
|
|
6053
|
+
color: "red",
|
|
6054
|
+
size: "md",
|
|
6055
|
+
onClick: () => removeIdentifier(i),
|
|
6056
|
+
title: t("Remove", "Remove"),
|
|
6057
|
+
"aria-label": t("Remove", "Remove"),
|
|
6058
|
+
children: /* @__PURE__ */ jsx(Trash2, { size: "1.4vh" })
|
|
6059
|
+
}
|
|
6060
|
+
)
|
|
6061
|
+
] }, i)),
|
|
6062
|
+
addingPlayer && /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", children: [
|
|
6063
|
+
/* @__PURE__ */ jsx(
|
|
6064
|
+
PlayerSelect,
|
|
6065
|
+
{
|
|
6066
|
+
value: null,
|
|
6067
|
+
onChange: (p) => commitIdentifier(p?.citizenId ?? ""),
|
|
6068
|
+
includeOffline,
|
|
6069
|
+
placeholder: t("AccessPickPlayer", "Pick a player\u2026"),
|
|
6070
|
+
style: { flex: 1 },
|
|
6071
|
+
size: "xs"
|
|
6072
|
+
}
|
|
6073
|
+
),
|
|
6074
|
+
/* @__PURE__ */ jsx(
|
|
6075
|
+
ActionIcon,
|
|
6076
|
+
{
|
|
6077
|
+
variant: "subtle",
|
|
6078
|
+
color: "red",
|
|
6079
|
+
size: "md",
|
|
6080
|
+
onClick: () => setAddingPlayer(false),
|
|
6081
|
+
title: t("Remove", "Remove"),
|
|
6082
|
+
"aria-label": t("Remove", "Remove"),
|
|
6083
|
+
children: /* @__PURE__ */ jsx(Trash2, { size: "1.4vh" })
|
|
6084
|
+
}
|
|
6085
|
+
)
|
|
6086
|
+
] })
|
|
6087
|
+
] }),
|
|
6088
|
+
!addingPlayer && /* @__PURE__ */ jsx(AddRowButton, { label: t("AccessAddPlayer", "Add player"), onClick: () => setAddingPlayer(true) })
|
|
6089
|
+
]
|
|
6090
|
+
}
|
|
6091
|
+
);
|
|
6092
|
+
}
|
|
6093
|
+
function AddRowButton({ label, onClick }) {
|
|
6094
|
+
return /* @__PURE__ */ jsxs(
|
|
6095
|
+
Flex,
|
|
6096
|
+
{
|
|
6097
|
+
align: "center",
|
|
6098
|
+
justify: "center",
|
|
6099
|
+
gap: "xs",
|
|
6100
|
+
onClick,
|
|
6101
|
+
role: "button",
|
|
6102
|
+
tabIndex: 0,
|
|
6103
|
+
onKeyDown: (e) => {
|
|
6104
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
6105
|
+
e.preventDefault();
|
|
6106
|
+
onClick();
|
|
6107
|
+
}
|
|
6108
|
+
},
|
|
6109
|
+
py: "xs",
|
|
6110
|
+
style: {
|
|
6111
|
+
cursor: "pointer",
|
|
6112
|
+
border: "0.1vh dashed rgba(255,255,255,0.12)",
|
|
6113
|
+
borderRadius: "0.4vh",
|
|
6114
|
+
transition: "background 0.15s, border-color 0.15s"
|
|
6115
|
+
},
|
|
6116
|
+
onMouseEnter: (e) => {
|
|
6117
|
+
e.currentTarget.style.background = "rgba(255,255,255,0.03)";
|
|
6118
|
+
e.currentTarget.style.borderColor = "rgba(255,255,255,0.2)";
|
|
6119
|
+
},
|
|
6120
|
+
onMouseLeave: (e) => {
|
|
6121
|
+
e.currentTarget.style.background = "transparent";
|
|
6122
|
+
e.currentTarget.style.borderColor = "rgba(255,255,255,0.12)";
|
|
6123
|
+
},
|
|
6124
|
+
children: [
|
|
6125
|
+
/* @__PURE__ */ jsx(Plus, { size: "1.4vh", color: "rgba(255,255,255,0.4)" }),
|
|
6126
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: "rgba(255,255,255,0.4)", children: label })
|
|
6127
|
+
]
|
|
6128
|
+
}
|
|
6129
|
+
);
|
|
6130
|
+
}
|
|
5711
6131
|
|
|
5712
6132
|
// src/utils/gtaAnimPostFx.ts
|
|
5713
6133
|
var GTA_ANIM_POST_FX_GROUP_ORDER = [
|
|
@@ -6297,7 +6717,7 @@ function ScenarioSelect({
|
|
|
6297
6717
|
}
|
|
6298
6718
|
);
|
|
6299
6719
|
}
|
|
6300
|
-
var
|
|
6720
|
+
var t2 = (key, fallback) => {
|
|
6301
6721
|
const v = locale(key);
|
|
6302
6722
|
return v === key ? fallback : v;
|
|
6303
6723
|
};
|
|
@@ -6365,7 +6785,7 @@ function DiscordRoleSelect(props) {
|
|
|
6365
6785
|
return map;
|
|
6366
6786
|
}, [roles]);
|
|
6367
6787
|
if (errorCode === "NotConfigured") {
|
|
6368
|
-
const notConfiguredPlaceholder =
|
|
6788
|
+
const notConfiguredPlaceholder = t2(
|
|
6369
6789
|
"DiscordNotConfigured",
|
|
6370
6790
|
"Not configured \u2014 set in /dirk_lib"
|
|
6371
6791
|
);
|
|
@@ -6433,9 +6853,9 @@ function DiscordRoleSelect(props) {
|
|
|
6433
6853
|
e.stopPropagation();
|
|
6434
6854
|
refresh();
|
|
6435
6855
|
},
|
|
6436
|
-
title:
|
|
6856
|
+
title: t2("Refresh", "Refresh"),
|
|
6437
6857
|
loading,
|
|
6438
|
-
"aria-label":
|
|
6858
|
+
"aria-label": t2("Refresh", "Refresh"),
|
|
6439
6859
|
children: /* @__PURE__ */ jsx(RefreshCw, { size: "1.2vh" })
|
|
6440
6860
|
}
|
|
6441
6861
|
);
|
|
@@ -6445,7 +6865,7 @@ function DiscordRoleSelect(props) {
|
|
|
6445
6865
|
{
|
|
6446
6866
|
label,
|
|
6447
6867
|
size,
|
|
6448
|
-
placeholder: placeholder ||
|
|
6868
|
+
placeholder: placeholder || t2("PickRoles", "Pick roles..."),
|
|
6449
6869
|
data,
|
|
6450
6870
|
value: props.value || [],
|
|
6451
6871
|
onChange: (ids) => props.onChange(ids),
|
|
@@ -6457,7 +6877,7 @@ function DiscordRoleSelect(props) {
|
|
|
6457
6877
|
rightSectionPointerEvents: "all",
|
|
6458
6878
|
style,
|
|
6459
6879
|
styles,
|
|
6460
|
-
nothingFoundMessage: errorCode ? `${
|
|
6880
|
+
nothingFoundMessage: errorCode ? `${t2("Error", "Error")} (${errorCode})` : t2("NoRoles", "No roles found")
|
|
6461
6881
|
}
|
|
6462
6882
|
);
|
|
6463
6883
|
}
|
|
@@ -6466,7 +6886,7 @@ function DiscordRoleSelect(props) {
|
|
|
6466
6886
|
{
|
|
6467
6887
|
label,
|
|
6468
6888
|
size,
|
|
6469
|
-
placeholder: placeholder ||
|
|
6889
|
+
placeholder: placeholder || t2("PickRole", "Pick a role..."),
|
|
6470
6890
|
data,
|
|
6471
6891
|
value: props.value || null,
|
|
6472
6892
|
onChange: (id) => props.onChange(id),
|
|
@@ -6478,11 +6898,11 @@ function DiscordRoleSelect(props) {
|
|
|
6478
6898
|
rightSectionPointerEvents: "all",
|
|
6479
6899
|
style,
|
|
6480
6900
|
styles,
|
|
6481
|
-
nothingFoundMessage: errorCode ? `${
|
|
6901
|
+
nothingFoundMessage: errorCode ? `${t2("Error", "Error")} (${errorCode})` : t2("NoRoles", "No roles found")
|
|
6482
6902
|
}
|
|
6483
6903
|
);
|
|
6484
6904
|
}
|
|
6485
|
-
var
|
|
6905
|
+
var t3 = (key, fallback) => {
|
|
6486
6906
|
const v = locale(key);
|
|
6487
6907
|
return v === key ? fallback : v;
|
|
6488
6908
|
};
|
|
@@ -6503,7 +6923,7 @@ function FrameworkHint({ framework }) {
|
|
|
6503
6923
|
const theme = useMantineTheme();
|
|
6504
6924
|
if (!framework) return null;
|
|
6505
6925
|
const hintKey = `AccountFrameworkHint_${framework}`;
|
|
6506
|
-
const text =
|
|
6926
|
+
const text = t3(hintKey, FRAMEWORK_HINTS[framework] || FRAMEWORK_HINTS.unknown);
|
|
6507
6927
|
return /* @__PURE__ */ jsxs(
|
|
6508
6928
|
Flex,
|
|
6509
6929
|
{
|
|
@@ -6587,9 +7007,9 @@ function AccountSelect(props) {
|
|
|
6587
7007
|
e.stopPropagation();
|
|
6588
7008
|
refresh();
|
|
6589
7009
|
},
|
|
6590
|
-
title:
|
|
7010
|
+
title: t3("Refresh", "Refresh"),
|
|
6591
7011
|
loading,
|
|
6592
|
-
"aria-label":
|
|
7012
|
+
"aria-label": t3("Refresh", "Refresh"),
|
|
6593
7013
|
children: /* @__PURE__ */ jsx(RefreshCw, { size: "1.2vh" })
|
|
6594
7014
|
}
|
|
6595
7015
|
);
|
|
@@ -6603,14 +7023,14 @@ function AccountSelect(props) {
|
|
|
6603
7023
|
rightSection: refreshButton,
|
|
6604
7024
|
rightSectionPointerEvents: "all",
|
|
6605
7025
|
style,
|
|
6606
|
-
nothingFoundMessage:
|
|
7026
|
+
nothingFoundMessage: t3("NoAccounts", "No accounts available")
|
|
6607
7027
|
};
|
|
6608
7028
|
return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "0.3vh", style, children: [
|
|
6609
7029
|
props.multi ? /* @__PURE__ */ jsx(
|
|
6610
7030
|
MultiSelect,
|
|
6611
7031
|
{
|
|
6612
7032
|
...sharedSelectProps,
|
|
6613
|
-
placeholder: placeholder ||
|
|
7033
|
+
placeholder: placeholder || t3("PickAccounts", "Pick accounts (or type custom)..."),
|
|
6614
7034
|
value: props.value || [],
|
|
6615
7035
|
onChange: (names) => props.onChange(names),
|
|
6616
7036
|
renderOption,
|
|
@@ -6622,7 +7042,7 @@ function AccountSelect(props) {
|
|
|
6622
7042
|
Select,
|
|
6623
7043
|
{
|
|
6624
7044
|
...sharedSelectProps,
|
|
6625
|
-
placeholder: placeholder ||
|
|
7045
|
+
placeholder: placeholder || t3("PickAccount", "Pick an account..."),
|
|
6626
7046
|
value: props.value || null,
|
|
6627
7047
|
onChange: (name) => props.onChange(name),
|
|
6628
7048
|
renderOption,
|
|
@@ -6914,175 +7334,6 @@ function WorldPositionGotoButton2({
|
|
|
6914
7334
|
}
|
|
6915
7335
|
) });
|
|
6916
7336
|
}
|
|
6917
|
-
function usePlayers(opts = {}) {
|
|
6918
|
-
const {
|
|
6919
|
-
includeOffline = false,
|
|
6920
|
-
search = "",
|
|
6921
|
-
limit = 50,
|
|
6922
|
-
staleTimeMs,
|
|
6923
|
-
refetchIntervalMs
|
|
6924
|
-
} = opts;
|
|
6925
|
-
const query = useQuery({
|
|
6926
|
-
queryKey: includeOffline ? ["dirk:players", "search", search.trim().toLowerCase(), limit] : ["dirk:players", "online"],
|
|
6927
|
-
queryFn: async () => {
|
|
6928
|
-
const toolId = includeOffline ? "searchPlayers" : "getOnlinePlayers";
|
|
6929
|
-
const payload = includeOffline ? { id: toolId, value: { search: search.trim(), limit } } : { id: toolId };
|
|
6930
|
-
const result = await fetchNui(
|
|
6931
|
-
"ADMIN_TOOL_QUERY",
|
|
6932
|
-
payload,
|
|
6933
|
-
// Browser-dev fallback. Returns a couple of mock players so the
|
|
6934
|
-
// dev shell isn't blank.
|
|
6935
|
-
includeOffline ? [
|
|
6936
|
-
{ id: 1, citizenId: "ABC12345", name: "Dev User", charName: "John Doe", online: true },
|
|
6937
|
-
{ id: null, citizenId: "DEF67890", name: "", charName: "Jane Offline", online: false }
|
|
6938
|
-
] : [
|
|
6939
|
-
{ id: 1, citizenId: "ABC12345", name: "Dev User", charName: "John Doe", online: true }
|
|
6940
|
-
]
|
|
6941
|
-
);
|
|
6942
|
-
return Array.isArray(result) ? result : [];
|
|
6943
|
-
},
|
|
6944
|
-
staleTime: staleTimeMs ?? (includeOffline ? 3e4 : 5e3),
|
|
6945
|
-
gcTime: 5 * 6e4,
|
|
6946
|
-
refetchInterval: refetchIntervalMs ?? false,
|
|
6947
|
-
refetchOnWindowFocus: false,
|
|
6948
|
-
placeholderData: includeOffline ? keepPreviousData : void 0
|
|
6949
|
-
});
|
|
6950
|
-
return {
|
|
6951
|
-
players: query.data ?? [],
|
|
6952
|
-
isLoading: query.isLoading,
|
|
6953
|
-
isFetching: query.isFetching,
|
|
6954
|
-
error: query.error ?? null,
|
|
6955
|
-
refresh: () => query.refetch()
|
|
6956
|
-
};
|
|
6957
|
-
}
|
|
6958
|
-
var DEBOUNCE_MS = 300;
|
|
6959
|
-
var ONLINE_COLOR = "#3FA83F";
|
|
6960
|
-
var OFFLINE_COLOR = "#E54141";
|
|
6961
|
-
function PlayerSelect({
|
|
6962
|
-
value,
|
|
6963
|
-
onChange,
|
|
6964
|
-
includeOffline = false,
|
|
6965
|
-
limit = 50,
|
|
6966
|
-
searchable: searchableProp,
|
|
6967
|
-
placeholder,
|
|
6968
|
-
nothingFoundMessage: nothingFoundMessageProp,
|
|
6969
|
-
loadingLabel = "Loading\u2026",
|
|
6970
|
-
onlineLabel = "Online",
|
|
6971
|
-
offlineLabel = "Offline",
|
|
6972
|
-
refreshLabel = "Refresh player list",
|
|
6973
|
-
...rest
|
|
6974
|
-
}) {
|
|
6975
|
-
const theme = useMantineTheme();
|
|
6976
|
-
const color = theme.colors[theme.primaryColor][5];
|
|
6977
|
-
const [searchInput, setSearchInput] = useState("");
|
|
6978
|
-
const [debouncedSearch, setDebouncedSearch] = useState("");
|
|
6979
|
-
const { players, isFetching, refresh } = usePlayers({
|
|
6980
|
-
includeOffline,
|
|
6981
|
-
search: includeOffline ? debouncedSearch : void 0,
|
|
6982
|
-
limit
|
|
6983
|
-
});
|
|
6984
|
-
const sortedPlayers = useMemo(
|
|
6985
|
-
() => [...players].sort((a, b) => {
|
|
6986
|
-
if (a.online !== b.online) return a.online ? -1 : 1;
|
|
6987
|
-
return a.charName.localeCompare(b.charName);
|
|
6988
|
-
}),
|
|
6989
|
-
[players]
|
|
6990
|
-
);
|
|
6991
|
-
const playerByCitizen = useMemo(() => {
|
|
6992
|
-
const m = /* @__PURE__ */ new Map();
|
|
6993
|
-
for (const p of sortedPlayers) m.set(p.citizenId, p);
|
|
6994
|
-
return m;
|
|
6995
|
-
}, [sortedPlayers]);
|
|
6996
|
-
const data = useMemo(() => {
|
|
6997
|
-
const items = sortedPlayers.map((p) => ({
|
|
6998
|
-
value: p.citizenId,
|
|
6999
|
-
label: formatLabel(p)
|
|
7000
|
-
}));
|
|
7001
|
-
if (value && !items.some((i) => i.value === value)) {
|
|
7002
|
-
items.unshift({ value, label: value });
|
|
7003
|
-
}
|
|
7004
|
-
return items;
|
|
7005
|
-
}, [sortedPlayers, value]);
|
|
7006
|
-
const selectedPlayer = value ? playerByCitizen.get(value) ?? null : null;
|
|
7007
|
-
const selectedLabel = selectedPlayer ? formatLabel(selectedPlayer) : null;
|
|
7008
|
-
useEffect(() => {
|
|
7009
|
-
if (!includeOffline) return;
|
|
7010
|
-
if (selectedLabel && searchInput === selectedLabel) return;
|
|
7011
|
-
const t3 = setTimeout(() => setDebouncedSearch(searchInput), DEBOUNCE_MS);
|
|
7012
|
-
return () => clearTimeout(t3);
|
|
7013
|
-
}, [searchInput, includeOffline, selectedLabel]);
|
|
7014
|
-
const renderOption = ({ option }) => {
|
|
7015
|
-
const p = playerByCitizen.get(option.value);
|
|
7016
|
-
if (!p) return option.label;
|
|
7017
|
-
return /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", gap: "xs", style: { width: "100%" }, children: [
|
|
7018
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", truncate: true, style: { flex: 1 }, children: formatLabel(p) }),
|
|
7019
|
-
/* @__PURE__ */ jsx(StatusDot, { online: p.online, onlineLabel, offlineLabel })
|
|
7020
|
-
] });
|
|
7021
|
-
};
|
|
7022
|
-
return /* @__PURE__ */ jsx(
|
|
7023
|
-
Select,
|
|
7024
|
-
{
|
|
7025
|
-
...rest,
|
|
7026
|
-
data,
|
|
7027
|
-
value: value ?? null,
|
|
7028
|
-
onChange: (v) => {
|
|
7029
|
-
if (!v) return onChange(null);
|
|
7030
|
-
const player = playerByCitizen.get(v) ?? null;
|
|
7031
|
-
onChange(player);
|
|
7032
|
-
},
|
|
7033
|
-
searchable: searchableProp ?? true,
|
|
7034
|
-
searchValue: includeOffline ? searchInput : void 0,
|
|
7035
|
-
onSearchChange: includeOffline ? setSearchInput : void 0,
|
|
7036
|
-
placeholder,
|
|
7037
|
-
nothingFoundMessage: isFetching ? loadingLabel : nothingFoundMessageProp ?? "No players found",
|
|
7038
|
-
maxDropdownHeight: 300,
|
|
7039
|
-
renderOption,
|
|
7040
|
-
leftSection: selectedPlayer ? /* @__PURE__ */ jsx(StatusDot, { online: selectedPlayer.online, onlineLabel, offlineLabel }) : void 0,
|
|
7041
|
-
rightSectionWidth: "3.5vh",
|
|
7042
|
-
rightSectionPointerEvents: "all",
|
|
7043
|
-
rightSection: /* @__PURE__ */ jsx(
|
|
7044
|
-
ActionIcon,
|
|
7045
|
-
{
|
|
7046
|
-
variant: "subtle",
|
|
7047
|
-
size: "sm",
|
|
7048
|
-
onClick: (e) => {
|
|
7049
|
-
e.stopPropagation();
|
|
7050
|
-
refresh();
|
|
7051
|
-
},
|
|
7052
|
-
"aria-label": refreshLabel,
|
|
7053
|
-
title: refreshLabel,
|
|
7054
|
-
style: { marginRight: "0.6vh" },
|
|
7055
|
-
children: isFetching ? /* @__PURE__ */ jsx(Loader, { size: "1.2vh", color }) : /* @__PURE__ */ jsx(RefreshCw, { size: "1.4vh", color })
|
|
7056
|
-
}
|
|
7057
|
-
)
|
|
7058
|
-
}
|
|
7059
|
-
);
|
|
7060
|
-
}
|
|
7061
|
-
function StatusDot({ online, onlineLabel, offlineLabel }) {
|
|
7062
|
-
return /* @__PURE__ */ jsx(
|
|
7063
|
-
"span",
|
|
7064
|
-
{
|
|
7065
|
-
title: online ? onlineLabel : offlineLabel,
|
|
7066
|
-
style: {
|
|
7067
|
-
display: "inline-block",
|
|
7068
|
-
width: "0.9vh",
|
|
7069
|
-
height: "0.9vh",
|
|
7070
|
-
borderRadius: "50%",
|
|
7071
|
-
backgroundColor: online ? ONLINE_COLOR : OFFLINE_COLOR,
|
|
7072
|
-
boxShadow: `0 0 0.4vh ${online ? ONLINE_COLOR : OFFLINE_COLOR}`,
|
|
7073
|
-
flexShrink: 0
|
|
7074
|
-
}
|
|
7075
|
-
}
|
|
7076
|
-
);
|
|
7077
|
-
}
|
|
7078
|
-
function formatLabel(p) {
|
|
7079
|
-
const parts = [p.charName || p.citizenId];
|
|
7080
|
-
if (p.online) {
|
|
7081
|
-
if (p.name) parts.push(p.name);
|
|
7082
|
-
if (p.id != null) parts.push(`#${p.id}`);
|
|
7083
|
-
}
|
|
7084
|
-
return parts.join(" \xB7 ");
|
|
7085
|
-
}
|
|
7086
7337
|
function usePickDoor() {
|
|
7087
7338
|
const begin = useAdminToolStore((s) => s.begin);
|
|
7088
7339
|
return async () => {
|
|
@@ -7359,6 +7610,6 @@ function BlipMarker({
|
|
|
7359
7610
|
);
|
|
7360
7611
|
}
|
|
7361
7612
|
|
|
7362
|
-
export { AccountSelect, AdminPageTitle, AnimPostFxSelect, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BlipMarker, BorderedIcon, ConfigPanel, ConfirmModal, ControlMultiSelect, ControlSelect, Counter, DiscordRoleSelect, DoorPickerButton, FiveMKeyBindInput, FloatingParticles, GroupName, GroupRank, GroupSelect, InfoBox, InputContainer, InstructionPanel, LevelBanner, LevelPanel, Map2 as Map, MapLayer, MissingItemsBanner, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PlayerSelect, PositionPicker, PromptModal, ScenarioSelect, SegmentedControl, SegmentedProgress, SelectItem, SwitchPanel, TestBed, ThemeOverrideSection, Title, Vector4DeleteButton, Vector4Display, WorldPositionGotoButton, WorldPositionPicker, WorldPositionSetButton, ZoomControls, blipUrl, blipUrlForSprite, getBlipColor, getBlipEntry, useAdminToolStore, useMissingItemsAudit, useModal, useModalActions, useNavigation, useNavigationStore, usePickDoor };
|
|
7613
|
+
export { AccessOverrideSection, AccountSelect, AdminPageTitle, AnimPostFxSelect, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BlipMarker, BorderedIcon, ConfigPanel, ConfirmModal, ControlMultiSelect, ControlSelect, Counter, DiscordRoleSelect, DoorPickerButton, FiveMKeyBindInput, FloatingParticles, GroupName, GroupRank, GroupSelect, InfoBox, InputContainer, InstructionPanel, LevelBanner, LevelPanel, Map2 as Map, MapLayer, MissingItemsBanner, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PlayerSelect, PositionPicker, PromptModal, ScenarioSelect, SegmentedControl, SegmentedProgress, SelectItem, SwitchPanel, TestBed, ThemeOverrideSection, Title, Vector4DeleteButton, Vector4Display, WorldPositionGotoButton, WorldPositionPicker, WorldPositionSetButton, ZoomControls, blipUrl, blipUrlForSprite, getBlipColor, getBlipEntry, useAdminToolStore, useMissingItemsAudit, useModal, useModalActions, useNavigation, useNavigationStore, usePickDoor };
|
|
7363
7614
|
//# sourceMappingURL=index.js.map
|
|
7364
7615
|
//# sourceMappingURL=index.js.map
|