dirk-cfx-react 1.1.92 → 1.1.93

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/useAudio/store.ts","../../src/utils/misc.ts","../../src/hooks/useNuiEvent.ts","../../src/hooks/useForm.tsx","../../src/types/theme.ts","../../src/utils/useSettings.ts","../../src/hooks/useTornEdges.tsx","../../src/utils/fetchNui.ts","../../src/hooks/useScriptConfig.ts","../../src/hooks/useValidModels.ts","../../src/hooks/useAdminState.ts","../../src/hooks/usePlayers.ts"],"names":["useRef","store","create","jsx","useMemo","useEffect","useState"],"mappings":"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","file":"index.js","sourcesContent":["import { create } from 'zustand';\r\n\r\n// Import sounds as URLs (TypeScript-safe)\r\nimport clickSoundUrl from './click_sound.mp3';\r\nimport hoverSoundUrl from './hover_sound.mp3';\r\n\r\n// Define a type for the store state and actions\r\ntype AudioPlayerStore = {\r\n play: (sound: string) => void;\r\n stop: (sound: string) => void;\r\n};\r\n\r\n// Create the store using Zustand\r\nexport const useAudio = create<AudioPlayerStore>(() => {\r\n const audioRefs: Record<string, HTMLAudioElement> = {};\r\n\r\n // Predefined sounds\r\n const sounds: Record<string, string> = {\r\n click: clickSoundUrl,\r\n hover: hoverSoundUrl,\r\n };\r\n\r\n // Initialize audio elements for each sound\r\n for (const [key, src] of Object.entries(sounds)) {\r\n audioRefs[key] = new Audio(src);\r\n }\r\n\r\n return {\r\n play: (sound) => {\r\n const audio = audioRefs[sound];\r\n if (!audio) return console.warn(`Sound '${sound}' not found.`);\r\n audio.currentTime = 0;\r\n audio.volume = 0.1;\r\n audio.play();\r\n },\r\n stop: (sound) => {\r\n const audio = audioRefs[sound];\r\n if (!audio) return console.warn(`Sound '${sound}' not found.`);\r\n audio.pause();\r\n audio.currentTime = 0;\r\n },\r\n };\r\n});\r\n","export const isEnvBrowser = (): boolean => !(window as any).invokeNative;\r\n\r\n// Basic no operation function\r\nexport const noop = () => {};\r\n\r\nexport const splitFAString = (faString:string) => {\r\n const [prefix, newIcon] = faString.split('-');\r\n if (!prefix || !newIcon) return {prefix: 'fas', newIcon: 'question'};\r\n return {prefix, newIcon};\r\n}\r\n\r\nexport const numberToRoman = (num:number) => {\r\n const romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX'] \r\n return romanNumerals[num]\r\n}\r\n\r\nexport const copyToClipboard = (text:string) => {\r\n const el = document.createElement('textarea');\r\n el.value = text;\r\n document.body.appendChild(el);\r\n el.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(el);\r\n}\r\n\r\nexport const openLink = (url:string) => {\r\n if (isEnvBrowser()) {\r\n window.open(url, '_blank');\r\n } else {\r\n // @ts-expect-error -- invokeNative exists in NUI\r\n window.invokeNative('openLink', url);\r\n } \r\n}","import { MutableRefObject, useEffect, useRef } from \"react\";\r\nimport { noop } from \"../utils/misc\";\r\n\r\nexport interface NuiMessageData<T = unknown> {\r\n action: string;\r\n data: T;\r\n}\r\n\r\nexport type NuiHandlerSignature<T> = ( data: T) => void;\r\n\r\n/**\r\n * A hook that manage events listeners for receiving data from the client scripts\r\n * @param action The specific `action` that should be listened for.\r\n * @param handler The callback function that will handle data relayed by this hook\r\n *\r\n * @example\r\n * useNuiEvent<{visibility: true, wasVisible: 'something'}>('setVisible', (data) => {\r\n * // whatever logic you want\r\n * })\r\n *\r\n **/\r\n\r\nexport const useNuiEvent = <T = unknown>(\r\n action: string,\r\n handler: ( data: T) => void,\r\n) => {\r\n const savedHandler: MutableRefObject<NuiHandlerSignature<T>> = useRef(noop);\r\n\r\n // Make sure we handle for a reactive handler\r\n useEffect(() => {\r\n savedHandler.current = handler;\r\n }, [handler]);\r\n\r\n useEffect(() => {\r\n const eventListener = (event: MessageEvent<NuiMessageData<T>>) => {\r\n const { action: eventAction, data } = event.data;\r\n\r\n if (savedHandler.current) {\r\n if (eventAction === action) {\r\n savedHandler.current( data);\r\n }\r\n }\r\n };\r\n\r\n window.addEventListener(\"message\", eventListener);\r\n // Remove Event Listener on component dirkup\r\n return () => window.removeEventListener(\"message\", eventListener);\r\n }, [action]);\r\n};\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\n\r\nimport React, { createContext, useContext, useMemo, useRef } from \"react\";\r\nimport { createStore, StoreApi, useStore } from \"zustand\";\r\n\r\n/* ======================================================\r\n Type Utilities\r\n====================================================== */\r\n\r\ntype PathValue<T, P extends string> = P extends keyof T\r\n ? T[P]\r\n : P extends `${infer K}.${infer R}`\r\n ? K extends keyof T\r\n ? PathValue<T[K], R>\r\n : never\r\n : never;\r\n\r\ntype Paths<T> = T extends object\r\n ? {\r\n [K in keyof T]: K extends string\r\n ? T[K] extends object\r\n ? T[K] extends any[] | Date | Function\r\n ? K\r\n : K | `${K}.${Paths<T[K]>}`\r\n : K\r\n : never;\r\n }[keyof T]\r\n : never;\r\n\r\ntype LoosePaths<T> = Paths<T> | (string & {});\r\n\r\n/* ======================================================\r\n Utilities\r\n====================================================== */\r\n\r\nfunction getNested(obj: any, path: string): any {\r\n return path.split(\".\").reduce((acc, key) => (acc ? acc[key] : undefined), obj);\r\n}\r\n\r\nfunction setNested(obj: any, path: string, value: any): any {\r\n const keys = path.split(\".\");\r\n const root = Array.isArray(obj) ? [...obj] : { ...obj };\r\n let current = root;\r\n\r\n for (let i = 0; i < keys.length - 1; i++) {\r\n const key = keys[i];\r\n const nextKey = keys[i + 1];\r\n const isIndex = !isNaN(Number(nextKey));\r\n\r\n const existing = current[key];\r\n\r\n current[key] =\r\n existing != null\r\n ? Array.isArray(existing)\r\n ? [...existing]\r\n : { ...existing }\r\n : isIndex\r\n ? []\r\n : {};\r\n\r\n current = current[key];\r\n }\r\n\r\n current[keys[keys.length - 1]] = value;\r\n return root;\r\n}\r\n\r\nfunction deleteNested(obj: any, path: string): any {\r\n const keys = path.split(\".\");\r\n const newObj = { ...obj };\r\n let current = newObj;\r\n\r\n for (let i = 0; i < keys.length - 1; i++) {\r\n const key = keys[i];\r\n if (!current[key]) return obj;\r\n current[key] = { ...current[key] };\r\n current = current[key];\r\n }\r\n\r\n delete current[keys[keys.length - 1]];\r\n return newObj;\r\n}\r\n\r\nfunction isPlainObject(value: any): value is Record<string, any> {\r\n return (\r\n value !== null &&\r\n typeof value === \"object\" &&\r\n !Array.isArray(value) &&\r\n !(value instanceof Date)\r\n );\r\n}\r\n\r\nfunction collectChangedPaths(values: any, initial: any, prefix = \"\"): string[] {\r\n if (Object.is(values, initial)) return [];\r\n\r\n const valuesIsObj = isPlainObject(values);\r\n const initialIsObj = isPlainObject(initial);\r\n const valuesIsArr = Array.isArray(values);\r\n const initialIsArr = Array.isArray(initial);\r\n\r\n if (valuesIsArr || initialIsArr) {\r\n const maxLen = Math.max(values?.length ?? 0, initial?.length ?? 0);\r\n const fields: string[] = [];\r\n for (let i = 0; i < maxLen; i++) {\r\n const nextPrefix = prefix ? `${prefix}.${i}` : `${i}`;\r\n fields.push(...collectChangedPaths(values?.[i], initial?.[i], nextPrefix));\r\n }\r\n return fields;\r\n }\r\n\r\n if (valuesIsObj || initialIsObj) {\r\n const keys = new Set([\r\n ...Object.keys(values ?? {}),\r\n ...Object.keys(initial ?? {}),\r\n ]);\r\n const fields: string[] = [];\r\n for (const key of keys) {\r\n const nextPrefix = prefix ? `${prefix}.${key}` : key;\r\n fields.push(...collectChangedPaths(values?.[key], initial?.[key], nextPrefix));\r\n }\r\n return fields;\r\n }\r\n\r\n return prefix ? [prefix] : [];\r\n}\r\n\r\nfunction computeChangedState<T>(\r\n values: Partial<T>,\r\n initialVals: Partial<T>\r\n): { fields: string[]; partial: Partial<T> } {\r\n const fields = collectChangedPaths(values, initialVals);\r\n let partial: Partial<T> = {};\r\n\r\n for (const path of fields) {\r\n partial = setNested(partial, path, getNested(values, path));\r\n }\r\n\r\n return { fields, partial };\r\n}\r\n\r\nfunction flattenRules(\r\n rules: any,\r\n prefix = \"\"\r\n): Record<string, ValidatorFn> {\r\n const result: Record<string, ValidatorFn> = {};\r\n\r\n for (const key in rules) {\r\n const fullPath = prefix ? `${prefix}.${key}` : key;\r\n const val = rules[key];\r\n\r\n if (typeof val === \"function\") result[fullPath] = val;\r\n else if (typeof val === \"object\")\r\n Object.assign(result, flattenRules(val, fullPath));\r\n }\r\n\r\n return result;\r\n}\r\n\r\nasync function runRule(\r\n rule: ValidatorFn,\r\n value: any,\r\n values: any\r\n): Promise<string | null> {\r\n const result = rule(value, values);\r\n return result instanceof Promise ? await result : result;\r\n}\r\n\r\n/* ======================================================\r\n Types\r\n====================================================== */\r\n\r\nexport type ValidatorFn<T = any> =\r\n | ((value: any, values: Partial<T>) => string | null)\r\n | ((value: any, values: Partial<T>) => Promise<string | null>);\r\n\r\nexport type ValidationRules<T> = {\r\n [K in keyof T]?: T[K] extends object\r\n ? ValidationRules<T[K]>\r\n : ValidatorFn<T>;\r\n};\r\n\r\nexport type FormState<T> = {\r\n values: Partial<T>;\r\n initialValues: Partial<T>;\r\n errors: Record<string, string>;\r\n\r\n partialChanged: Partial<T>;\r\n\r\n getInputProps: (path: string) => {\r\n value: any;\r\n error?: string;\r\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n };\r\n\r\n setValue: (path: string, value: any, options?: { validate?: boolean }) => void;\r\n setInitialValues: (newInitialValues: Partial<T>) => void;\r\n\r\n setError: (path: string, message: string) => void;\r\n clearError: (path: string) => void;\r\n\r\n validate: () => Promise<boolean>;\r\n validateField: (path: string) => Promise<boolean>;\r\n\r\n reset: () => void;\r\n reinitialize: (newValues: Partial<T>) => void;\r\n\r\n back: () => void;\r\n forward: () => void;\r\n canBack: boolean;\r\n canForward: boolean;\r\n\r\n changedFields: string[];\r\n changedCount: number;\r\n resetChangeCount: () => void;\r\n\r\n onSubmit?: (form: FormState<T>) => void;\r\n submit: () => Promise<void>;\r\n};\r\n\r\n/* ======================================================\r\n Store\r\n====================================================== */\r\n\r\nexport function createFormStore<T>(\r\n initialValues: Partial<T>,\r\n validationRules?: ValidationRules<T>,\r\n onSubmit?: (form: FormState<T>) => void\r\n) {\r\n const flatRules = validationRules ? flattenRules(validationRules) : {};\r\n\r\n const history: Partial<T>[] = [];\r\n const future: Partial<T>[] = [];\r\n const changed = new Set<string>();\r\n\r\n return createStore<FormState<T>>((set, get) => ({\r\n initialValues,\r\n values: initialValues,\r\n errors: {},\r\n partialChanged: {},\r\n canBack: false,\r\n canForward: false,\r\n changedFields: [],\r\n changedCount: 0,\r\n onSubmit,\r\n\r\n submit: async () => {\r\n const state = get();\r\n const isValid = await state.validate();\r\n if (isValid && state.onSubmit) {\r\n state.onSubmit(get());\r\n }\r\n },\r\n\r\n getInputProps: (path: string) => {\r\n return {\r\n value: getNested(get().values, path) ?? \"\",\r\n error: get().errors[path],\r\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\r\n get().setValue(path, e.target.value, { validate: true });\r\n },\r\n };\r\n },\r\n\r\n resetChangeCount: () => {\r\n changed.clear();\r\n set({ changedFields: [], changedCount: 0, partialChanged: {} });\r\n },\r\n\r\n setInitialValues: (newInitialValues) =>\r\n set({ initialValues: newInitialValues }),\r\n\r\n setValue: (path, value, options) => {\r\n const state = get();\r\n const currentValues = state.values;\r\n const newValues = setNested(currentValues, path, value);\r\n\r\n const oldValue = getNested(state.initialValues, path);\r\n const hasChanged = value !== oldValue;\r\n\r\n history.push(currentValues);\r\n future.length = 0;\r\n\r\n let newPartial = state.partialChanged;\r\n\r\n if (hasChanged) {\r\n changed.add(path);\r\n newPartial = setNested(newPartial, path, value);\r\n } else {\r\n changed.delete(path);\r\n newPartial = deleteNested(newPartial, path);\r\n }\r\n\r\n set({\r\n values: newValues,\r\n partialChanged: newPartial,\r\n canBack: history.length > 0,\r\n canForward: false,\r\n changedFields: Array.from(changed),\r\n changedCount: changed.size,\r\n });\r\n\r\n if (!options?.validate) return;\r\n\r\n const rule = flatRules[path];\r\n if (!rule) return;\r\n\r\n Promise.resolve(runRule(rule, value, newValues)).then((error) => {\r\n if (error)\r\n set((s) => ({ errors: setNested(s.errors, path, error) }));\r\n else\r\n set((s) => ({ errors: deleteNested(s.errors, path) }));\r\n });\r\n },\r\n\r\n setError: (path, message) =>\r\n set((s) => ({ errors: setNested(s.errors, path, message) })),\r\n\r\n clearError: (path) =>\r\n set((s) => ({ errors: deleteNested(s.errors, path) })),\r\n\r\n validateField: async (path) => {\r\n const state = get();\r\n const rule = flatRules[path];\r\n if (!rule) return true;\r\n\r\n const value = getNested(state.values, path);\r\n const error = await runRule(rule, value, state.values);\r\n\r\n if (error) {\r\n set((s) => ({ errors: setNested(s.errors, path, error) }));\r\n return false;\r\n }\r\n\r\n set((s) => ({ errors: deleteNested(s.errors, path) }));\r\n return true;\r\n },\r\n\r\n validate: async () => {\r\n const state = get();\r\n let isValid = true;\r\n let newErrors: Record<string, string> = {};\r\n\r\n for (const path in flatRules) {\r\n const rule = flatRules[path];\r\n const value = getNested(state.values, path);\r\n const error = await runRule(rule, value, state.values);\r\n\r\n if (error) {\r\n isValid = false;\r\n newErrors = setNested(newErrors, path, error);\r\n }\r\n }\r\n\r\n set({ errors: newErrors });\r\n return isValid;\r\n },\r\n\r\n reset: () => {\r\n history.length = 0;\r\n future.length = 0;\r\n changed.clear();\r\n\r\n set({\r\n values: get().initialValues,\r\n errors: {},\r\n partialChanged: {},\r\n canBack: false,\r\n canForward: false,\r\n changedFields: [],\r\n changedCount: 0,\r\n });\r\n },\r\n\r\n reinitialize: (newValues) => {\r\n history.length = 0;\r\n future.length = 0;\r\n changed.clear();\r\n\r\n set({\r\n values: newValues,\r\n initialValues: newValues,\r\n errors: {},\r\n partialChanged: {},\r\n canBack: false,\r\n canForward: false,\r\n changedFields: [],\r\n changedCount: 0,\r\n });\r\n },\r\n\r\n back: () => {\r\n if (!history.length) return;\r\n\r\n const prev = history.pop()!;\r\n future.push(get().values);\r\n\r\n const { fields, partial } = computeChangedState(prev, get().initialValues);\r\n\r\n set({\r\n values: prev,\r\n partialChanged: partial,\r\n canBack: history.length > 0,\r\n canForward: true,\r\n changedFields: fields,\r\n changedCount: fields.length,\r\n });\r\n },\r\n\r\n forward: () => {\r\n if (!future.length) return;\r\n\r\n const next = future.pop()!;\r\n history.push(get().values);\r\n\r\n const { fields, partial } = computeChangedState(next, get().initialValues);\r\n\r\n set({\r\n values: next,\r\n partialChanged: partial,\r\n canBack: true,\r\n canForward: future.length > 0,\r\n changedFields: fields,\r\n changedCount: fields.length,\r\n });\r\n },\r\n }));\r\n}\r\n\r\n/* ======================================================\r\n Context + Hook\r\n====================================================== */\r\n\r\nconst FormContext = createContext<StoreApi<FormState<any>> | null>(null);\r\n\r\nexport function FormProvider<T>({\r\n initialValues,\r\n validate,\r\n onSubmit,\r\n children,\r\n}: {\r\n initialValues: Partial<T>;\r\n validate?: ValidationRules<T>;\r\n onSubmit?: (form: FormState<T>) => void;\r\n children: React.ReactNode;\r\n}) {\r\n const storeRef = useRef(\r\n createFormStore<T>(initialValues, validate, onSubmit)\r\n );\r\n\r\n return (\r\n <FormContext.Provider value={storeRef.current}>\r\n {children}\r\n </FormContext.Provider>\r\n );\r\n}\r\n\r\nexport function useForm<T>() {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useForm must be used inside <FormProvider>\");\r\n }\r\n const state = useStore(store) as FormState<T>;\r\n\r\n const changedFields = useMemo(() => {\r\n return collectChangedPaths(state.values, state.initialValues);\r\n }, [state.values, state.initialValues]);\r\n\r\n return { ...state, changedFields, changedCount: changedFields.length } as FormState<T>;\r\n}\r\n\r\nexport function useFormField<T, P extends LoosePaths<T> = LoosePaths<T>>(\r\n path: P\r\n): P extends Paths<T> ? PathValue<T, P> | undefined : any {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useFormField must be used inside <FormProvider>\");\r\n }\r\n return useStore(store, (s) => getNested(s.values, path));\r\n}\r\n\r\nexport function useFormFields<T, P extends LoosePaths<T> = LoosePaths<T>>(\r\n ...paths: P[]\r\n): { [K in P]: K extends Paths<T> ? PathValue<T, K> | undefined : any } {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useFormFields must be used inside <FormProvider>\");\r\n }\r\n \r\n return useStore(store, (s) => {\r\n const result = {} as { [K in P]: K extends Paths<T> ? PathValue<T, K> | undefined : any };\r\n for (const path of paths) {\r\n result[path] = getNested(s.values, path);\r\n }\r\n return result;\r\n });\r\n}\r\n\r\nexport function useFormError(path: string) {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useFormError must be used inside <FormProvider>\");\r\n }\r\n return useStore(store, (s) => s.errors[path]);\r\n}\r\n\r\nexport function useFormErrors(...paths: string[]) {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useFormErrors must be used inside <FormProvider>\");\r\n }\r\n return useStore(store, (s) => {\r\n const result: Record<string, string | undefined> = {};\r\n for (const path of paths) {\r\n result[path] = s.errors[path];\r\n }\r\n return result;\r\n });\r\n}\r\n\r\nexport function useFormActions<T>() {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useFormActions must be used inside <FormProvider>\");\r\n }\r\n return store.getState() as Pick<\r\n FormState<T>,\r\n | \"setValue\"\r\n | \"setError\"\r\n | \"clearError\"\r\n | \"validate\"\r\n | \"validateField\"\r\n | \"reset\"\r\n | \"reinitialize\"\r\n | \"back\"\r\n | \"forward\"\r\n | \"canBack\"\r\n | \"canForward\"\r\n | \"submit\"\r\n >;\r\n}","import { z } from \"zod\";\n\n/**\n * Per-resource theme override block.\n *\n * Single source of truth for the shape + defaults that were previously\n * duplicated across `components/ThemeOverrideSection.tsx` and\n * `utils/useSettings.ts`. Both now import from here.\n *\n * Data shape (driven by a schema block on the consumer side):\n * theme: {\n * useOverride: boolean,\n * primaryColor: string, // \"dirk\" | \"custom\" | mantine palette name\n * primaryShade: 0..9,\n * customTheme: string[10], // hex stops\n * }\n */\n\n/**\n * The 10-stop hex palette used as the fallback custom theme. This exact tuple\n * was duplicated in ThemeOverrideSection (DEFAULT_PALETTE) and useSettings\n * (customTheme). Keep it as a 10-tuple — Mantine `MantineColorsTuple` expects\n * exactly ten stops.\n */\nexport const DEFAULT_PALETTE: string[] = [\n \"#f0f4ff\",\n \"#d9e3ff\",\n \"#bfcfff\",\n \"#a6bbff\",\n \"#8ca7ff\",\n \"#7393ff\",\n \"#5a7fff\",\n \"#406bff\",\n \"#2547ff\",\n \"#0b33ff\",\n];\n\n/**\n * Zod schema for the theme override block. `customTheme` is validated as an\n * array of strings (the editor enforces the 10-length shape at the UI layer\n * by falling back to DEFAULT_PALETTE when the count is wrong).\n */\nexport const ThemeOverrideSchema = z.object({\n useOverride: z.boolean(),\n primaryColor: z.string(),\n primaryShade: z.number(),\n customTheme: z.array(z.string()),\n});\n\nexport type ThemeOverrideValue = z.infer<typeof ThemeOverrideSchema>;\n\n/**\n * Canonical default theme override block. Used as the merge fallback in\n * ThemeOverrideSection and (the palette portion) as the default custom theme\n * in useSettings.\n */\nexport const defaultThemeOverride: ThemeOverrideValue = {\n useOverride: false,\n primaryColor: \"dirk\",\n primaryShade: 5,\n customTheme: DEFAULT_PALETTE,\n};\n","import { MantineColorsTuple } from \"@mantine/core\";\r\nimport { create } from \"zustand\";\r\nimport { DEFAULT_PALETTE } from \"../types/theme\";\r\n\r\nexport type SettingsState = {\r\n game: \"fivem\" | \"rdr3\";\r\n currency: string;\r\n primaryColor: string;\r\n primaryShade: number;\r\n itemImgPath: string;\r\n resourceVersion?: string;\r\n customTheme?: MantineColorsTuple;\r\n overideResourceName?: string;\r\n serverName?: string;\r\n logo?: string;\r\n language?: string;\r\n};\r\n\r\nexport const useSettings = create<SettingsState>(() => ({\r\n currency: \"$\",\r\n game: \"fivem\",\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n itemImgPath: \"\",\r\n resourceVersion: \"dev\",\r\n customTheme: DEFAULT_PALETTE as unknown as MantineColorsTuple,\r\n}));\r\n\r\n// registerInitialFetch<Partial<SettingsState>>('GET_SETTINGS', undefined).then((data) => {\r\n// if (!data) {\r\n// console.warn('No settings data received from GET_SETTINGS fetch.');\r\n// return;\r\n// }\r\n// useSettings.setState({\r\n// ...data,\r\n// });\r\n// })\r\n","import { useSettings } from \"@/utils/useSettings\";\r\nexport function useTornEdges() {\r\n const game = useSettings((state) => state.game);\r\n return game === \"rdr3\" ? \"torn-edge-wrapper\" : \"\";\r\n}\r\n\r\n// Add this SVG to your layout/root component:\r\nexport function TornEdgeSVGFilter() {\r\n return (\r\n <svg\r\n style={{ position: \"absolute\", width: 0, height: 0, pointerEvents: \"none\" }}\r\n aria-hidden=\"true\"\r\n >\r\n <defs>\r\n <filter id=\"torn-edge-filter\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\r\n {/* Base fractal noise for tearing */}\r\n <feTurbulence\r\n type=\"fractalNoise\"\r\n baseFrequency=\"0.018 0.022\"\r\n numOctaves=\"5\"\r\n seed=\"9\"\r\n result=\"noise1\"\r\n />\r\n {/* Second noise layer for micro detail */}\r\n <feTurbulence\r\n type=\"fractalNoise\"\r\n baseFrequency=\"0.08 0.12\"\r\n numOctaves=\"2\"\r\n seed=\"3\"\r\n result=\"noise2\"\r\n />\r\n\r\n {/* Blend both noise layers */}\r\n <feBlend in=\"noise1\" in2=\"noise2\" mode=\"multiply\" result=\"combinedNoise\" />\r\n\r\n {/* Primary displacement */}\r\n <feDisplacementMap\r\n in=\"SourceGraphic\"\r\n in2=\"combinedNoise\"\r\n scale=\"52\"\r\n xChannelSelector=\"R\"\r\n yChannelSelector=\"G\"\r\n result=\"displaced\"\r\n />\r\n\r\n {/* Alpha fade toward edges */}\r\n <feGaussianBlur stdDeviation=\"0.8\" in=\"displaced\" result=\"blurred\" />\r\n <feComponentTransfer in=\"blurred\" result=\"alphaFade\">\r\n <feFuncA type=\"gamma\" amplitude=\"1\" exponent=\"1.3\" offset=\"-0.05\" />\r\n </feComponentTransfer>\r\n\r\n {/* Sharpen a bit after fade */}\r\n <feMorphology operator=\"erode\" radius=\"0.4\" in=\"alphaFade\" result=\"eroded\" />\r\n\r\n {/* Merge final */}\r\n <feMerge>\r\n <feMergeNode in=\"eroded\" />\r\n </feMerge>\r\n </filter>\r\n </defs>\r\n </svg>\r\n );\r\n}\r\n\r\n","import { useEffect } from \"react\";\r\nimport { isEnvBrowser } from \"./misc\";\r\nimport { useSettings } from \"./useSettings\";\r\n\r\n/**\r\n * Simple wrapper around fetch API tailored for CEF/NUI use.\r\n */\r\nexport async function fetchNui<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const options = {\r\n method: \"post\",\r\n headers: {\r\n \"Content-Type\": \"application/json; charset=UTF-8\",\r\n },\r\n body: JSON.stringify(data),\r\n };\r\n\r\n if (isEnvBrowser() && mockData !== undefined) return mockData;\r\n if (isEnvBrowser() && mockData === undefined) {\r\n console.warn(\r\n `[fetchNui] Called fetchNui for event \"${eventName}\" in browser environment without mockData. Returning empty object.`,\r\n );\r\n return {} as T;\r\n }\r\n\r\n const overrideResourceName = useSettings.getState().overideResourceName;\r\n\r\n // Resource-name resolution:\r\n // 1. NUI iframes expose `window.GetParentResourceName` — use that.\r\n // 2. DUIs don't have it, but DirkProvider sets `overideResourceName`\r\n // once it mounts, so consumer DUIs that wait until then resolve fine.\r\n // 3. If NEITHER is available (e.g. a DUI before its DirkProvider has\r\n // mounted, which happens for module-level `registerInitialFetch`\r\n // calls in `locales.ts`), there's no valid resource to call. Skip\r\n // the fetch entirely — firing it against a placeholder URL just\r\n // produces a doomed network request + an \"Uncaught (in promise)\r\n // TypeError: Failed to fetch\" in older consumer builds that\r\n // lacked the try/catch fallback below. Caller can rely on the\r\n // mockData return or refetch once context is established.\r\n const hasResourceContext =\r\n typeof (window as any).GetParentResourceName === \"function\" ||\r\n !!overrideResourceName;\r\n\r\n if (!hasResourceContext) {\r\n return (mockData ?? ({} as T));\r\n }\r\n\r\n const resourceName = (window as any).GetParentResourceName\r\n ? (window as any).GetParentResourceName()\r\n : overrideResourceName as string;\r\n\r\n try {\r\n const resp = await fetch(`https://${resourceName}/${eventName}`, options);\r\n return await resp.json();\r\n } catch {\r\n return (mockData ?? ({} as T));\r\n }\r\n}\r\n\r\n// -----------------------------\r\n// Initial fetch registration\r\n// -----------------------------\r\nexport type InitialFetch<T> = () => Promise<T>;\r\nexport const initialFetches: Record<string, InitialFetch<unknown>> = {};\r\n\r\n/**\r\n * Registers an initial fetch that automatically uses fetchNui.\r\n * Works like:\r\n * ```ts\r\n * registerInitialFetch<{ name: string }>(\"MY_EVENT_NAME\", undefined, { name: \"Mocky\" });\r\n * ```\r\n * and returns a Promise resolving to the same type as fetchNui.\r\n */\r\nexport async function registerInitialFetch<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const fetcher = () => fetchNui<T>(eventName, data, mockData);\r\n initialFetches[eventName] = fetcher;\r\n return fetcher(); // run immediately if needed\r\n}\r\n\r\n/**\r\n * Runs all registered initial fetches in parallel.\r\n */\r\nexport async function runFetches() {\r\n return Promise.all(\r\n Object.entries(initialFetches).map(async ([eventName, fetcher]) => {\r\n const data = await fetcher();\r\n return { eventName, data };\r\n }),\r\n );\r\n}\r\n\r\n/**\r\n * React hook to automatically run all registered fetches on mount.\r\n */\r\nexport const useAutoFetcher = () => {\r\n useEffect(() => {\r\n if (isEnvBrowser()) return;\r\n runFetches().catch(() => {});\r\n }, []);\r\n};\r\n\r\n\r\nexport const fetchLuaTable = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return fetchNui<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\nexport const registerInitialLuaTableFetch = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return registerInitialFetch<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\n\r\n\r\n// useage example:\r\n// registerInitialLuaTableFetch<{ [key: string]: string }>('my_lua_table', { key1: 'value1', key2: 'value2' }); \r\n","import { fetchNui } from \"@/utils\";\r\nimport { useNuiEvent } from \"@/hooks/useNuiEvent\";\r\nimport { create } from \"zustand\";\r\n\r\ntype ScriptConfigUpdateMeta<T> = {\r\n client_version?: number;\r\n latestVersion?: number;\r\n latestData?: Partial<T>;\r\n changed_paths?: Array<{ path: string; old: unknown; new: unknown }>;\r\n lastEditor?: { source?: number; name?: string; identifier?: string };\r\n};\r\n\r\nexport type ScriptConfigHistoryChange = {\r\n path: string;\r\n old: unknown;\r\n new: unknown;\r\n};\r\n\r\nexport type ScriptConfigHistoryEntry = {\r\n at_unix: number;\r\n at_utc: string;\r\n script: string;\r\n admin?: { source?: number; name?: string; identifier?: string };\r\n expected_version?: number;\r\n applied_version?: number;\r\n changes: ScriptConfigHistoryChange[];\r\n};\r\n\r\nexport type ScriptConfigHistoryRequest = {\r\n offset?: number;\r\n limit?: number;\r\n query?: string;\r\n path?: string;\r\n admin?: string;\r\n fromUnix?: number;\r\n toUnix?: number;\r\n};\r\n\r\nexport type ScriptConfigHistoryResponse = {\r\n success: boolean;\r\n _error?: string;\r\n data?: {\r\n items: ScriptConfigHistoryEntry[];\r\n total: number;\r\n limit: number;\r\n offset: number;\r\n nextOffset?: number;\r\n };\r\n};\r\n\r\ntype NuiResponse<T> = {\r\n success: boolean;\r\n message?: string;\r\n _error?: string;\r\n meta?: ScriptConfigUpdateMeta<T>;\r\n};\r\n\r\n// Derive the set of changed TOP-LEVEL section keys from a useForm changed-set\r\n// of dotted paths (e.g. [\"stores.0.name\", \"basic.weightUnit\"] → {\"stores\",\"basic\"}).\r\n// CONSERVATIVE by design: any changed path under section X marks the WHOLE\r\n// section X as changed, so the caller sends its full current value. This is what\r\n// lets deletions inside a section (a removed array element) propagate, because\r\n// the server/client overwrite the section wholesale rather than deep-merging.\r\nfunction changedTopLevelSections(changedFields?: readonly string[]): string[] {\r\n if (!changedFields || changedFields.length === 0) return [];\r\n const sections = new Set<string>();\r\n for (const path of changedFields) {\r\n if (typeof path !== \"string\" || path.length === 0) continue;\r\n const dot = path.indexOf(\".\");\r\n sections.add(dot === -1 ? path : path.slice(0, dot));\r\n }\r\n return Array.from(sections);\r\n}\r\n\r\n// ── Singleton registry ────────────────────────────────────────────────────────\r\n\r\nexport interface ScriptConfigInstance<T = any> {\r\n store: { getState: () => T; setState: (partial: Partial<T> | ((prev: T) => T)) => void };\r\n updateConfig: (newConfig: Partial<T>, changedFields?: readonly string[]) => Promise<NuiResponse<T>>;\r\n resetConfig: () => Promise<{ success: boolean; _error?: string }>;\r\n getHistory: (params?: ScriptConfigHistoryRequest) => Promise<ScriptConfigHistoryResponse>;\r\n fetchConfig: () => Promise<T | null>;\r\n}\r\n\r\nlet _instance: ScriptConfigInstance | null = null;\r\n\r\nexport function getScriptConfigInstance<T = any>(): ScriptConfigInstance<T> {\r\n if (!_instance) throw new Error(\"[dirk-cfx-react] createScriptConfig must be called before using ConfigPanel\");\r\n return _instance as ScriptConfigInstance<T>;\r\n}\r\n\r\nexport function createScriptConfig<T>(defaultValue: T) {\r\n const store = create<T>(() => defaultValue);\r\n let clientVersion = 0;\r\n\r\n const useScriptConfigHooks = () => {\r\n useNuiEvent<{ config?: Partial<T>; clientVersion?: number; sectionReplace?: boolean }>(\r\n \"UPDATE_SCRIPT_CONFIG\",\r\n (data) => {\r\n if (!data) return;\r\n\r\n if (typeof data.clientVersion === \"number\") {\r\n clientVersion = data.clientVersion as number;\r\n }\r\n\r\n if (data.config && typeof data.config === \"object\") {\r\n // Both apply modes use the same top-level merge-by-replace:\r\n // - sectionReplace: `config` holds only the changed sections; spreading\r\n // them over `prev` wholesale-overwrites those keys and leaves every\r\n // other (unsent) section exactly as-is. We MUST NOT full-replace here\r\n // or the unsent sections would vanish from the UI.\r\n // - fullReplace / merge / initial: `config` holds the FULL config, so\r\n // the same spread effectively replaces every key.\r\n store.setState((prev) => ({ ...prev, ...(data.config as Partial<T>) }));\r\n }\r\n }\r\n );\r\n };\r\n\r\n const fetchScriptConfig = async (): Promise<T | null> => {\r\n try {\r\n const response = await fetchNui<{\r\n success: boolean;\r\n data?: { config: T; clientVersion: number };\r\n }>(\"GET_FULL_SCRIPT_CONFIG\");\r\n\r\n if (response?.success && response.data?.config) {\r\n store.setState(() => response.data!.config as T);\r\n if (typeof response.data.clientVersion === \"number\") {\r\n clientVersion = response.data.clientVersion;\r\n }\r\n return response.data.config;\r\n }\r\n } catch { /* fallback to current store state */ }\r\n return null;\r\n };\r\n\r\n // `changedFields` is the useForm tracked changed-set (dotted paths). When\r\n // supplied AND it resolves to ≥1 top-level section, we send a SECTION-DELTA:\r\n // only the changed sections, each as its WHOLE current value, with\r\n // sectionReplace:true. The server/client then overwrite those keys wholesale\r\n // (which is what lets deletions inside a section propagate). When omitted or\r\n // empty, we fall back to the legacy full-send (server defaults to\r\n // fullReplace=true when no `sectionReplace` flag is present).\r\n const updateScriptConfig = async (\r\n newConfig: Partial<T>,\r\n changedFields?: readonly string[]\r\n ): Promise<NuiResponse<T>> => {\r\n store.setState((prev) => ({ ...prev, ...newConfig }));\r\n\r\n const sections = changedTopLevelSections(changedFields);\r\n\r\n let payload: { data: Partial<T>; expectedVersion: number; sectionReplace?: boolean };\r\n if (sections.length > 0) {\r\n // Section-delta: flat object keyed by top-level section name → whole\r\n // current section value (pulled from the just-applied store state so it\r\n // reflects the user's edits, including deletions).\r\n const current = store.getState() as Record<string, unknown>;\r\n const delta: Record<string, unknown> = {};\r\n for (const key of sections) delta[key] = current[key];\r\n payload = { data: delta as Partial<T>, expectedVersion: clientVersion, sectionReplace: true };\r\n } else {\r\n // No changed-set provided (or nothing resolved) but the user explicitly\r\n // saved → legacy full-send. No sectionReplace flag ⇒ server fullReplace.\r\n payload = { data: newConfig, expectedVersion: clientVersion };\r\n }\r\n\r\n const response = await fetchNui<NuiResponse<T>>(\"UPDATE_SCRIPT_CONFIG\", payload);\r\n\r\n if (response?.meta?.client_version != null) {\r\n clientVersion = response.meta.client_version as number;\r\n }\r\n\r\n if (response?.success === false && response?.meta?.latestData) {\r\n store.setState((prev) => ({ ...prev, ...(response.meta!.latestData as Partial<T>) }));\r\n }\r\n\r\n return response;\r\n };\r\n\r\n const getScriptConfigHistory = async (\r\n params: ScriptConfigHistoryRequest = {}\r\n ): Promise<ScriptConfigHistoryResponse> => {\r\n return fetchNui<ScriptConfigHistoryResponse>('GET_SCRIPT_CONFIG_HISTORY', params);\r\n };\r\n\r\n const resetConfig = async (): Promise<{ success: boolean; _error?: string }> => {\r\n const response = await fetchNui<{ success: boolean; _error?: string }>('RESET_SCRIPT_CONFIG');\r\n if (response?.success) {\r\n const fresh = await fetchScriptConfig();\r\n if (fresh) {\r\n store.setState(() => fresh);\r\n }\r\n }\r\n return response;\r\n };\r\n\r\n _instance = {\r\n store,\r\n updateConfig: updateScriptConfig,\r\n resetConfig,\r\n getHistory: getScriptConfigHistory,\r\n fetchConfig: fetchScriptConfig,\r\n };\r\n\r\n return {store, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig}\r\n}\r\n","// Validates a list of GTA / RDR model names against the client's CD-image\r\n// via dirk_lib's adminTool.validateModels Lua tool. Returns a Set of names\r\n// that DO resolve to a streamable model — useful for greying out admin-\r\n// panel rows that reference props/shells/peds that aren't installed.\r\n//\r\n// Batches: pass the full list each render; the hook diffs against what's\r\n// already been resolved and only asks Lua for the new names. Once a name\r\n// has been checked, subsequent renders with the same name return the\r\n// cached result instantly.\r\n//\r\n// Result is a stable Set reference per resolution wave so callers can use\r\n// it as a useMemo / useEffect dep without thrashing.\r\n//\r\n// Usage:\r\n// const valid = useValidModels(shells.map(s => s.model));\r\n// shells.map(s => <Row dimmed={!valid.has(s.model)} ... />)\r\n//\r\n// Only meaningful inside an open admin panel (the underlying NUI callback\r\n// is gated on scriptConfig being open). Outside that window the hook just\r\n// returns an empty Set.\r\nimport { useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { fetchNui } from \"../utils/fetchNui\";\r\n\r\nconst moduleCache = new Map<string, boolean>();\r\n\r\nexport function useValidModels(names: string[]): Set<string> {\r\n // Stable string key for the input list so the effect doesn't re-fire on\r\n // every render. Sort + join keeps the dep change-detection cheap.\r\n const cacheKey = useMemo(() => {\r\n const unique = Array.from(new Set(names.filter(n => typeof n === \"string\" && n.length > 0)));\r\n unique.sort();\r\n return unique.join(\"|\");\r\n }, [names]);\r\n\r\n // Bump on every new validation result so memoised consumers re-derive.\r\n const [version, setVersion] = useState(0);\r\n const inflight = useRef<Set<string>>(new Set());\r\n\r\n useEffect(() => {\r\n if (!cacheKey) return;\r\n const all = cacheKey.split(\"|\").filter(Boolean);\r\n const missing = all.filter(n => !moduleCache.has(n) && !inflight.current.has(n));\r\n if (missing.length === 0) return;\r\n\r\n missing.forEach(n => inflight.current.add(n));\r\n let cancelled = false;\r\n\r\n fetchNui<Record<string, boolean> | null>(\r\n \"ADMIN_TOOL_QUERY\",\r\n { id: \"validateModels\", value: missing },\r\n // Fallback when running outside FiveM (browser dev) — assume valid so the\r\n // dev shell doesn't grey out every row.\r\n Object.fromEntries(missing.map(n => [n, true])),\r\n )\r\n .then(result => {\r\n if (cancelled) return;\r\n const map = result && typeof result === \"object\" ? result : {};\r\n missing.forEach(n => {\r\n moduleCache.set(n, !!map[n]);\r\n inflight.current.delete(n);\r\n });\r\n setVersion(v => v + 1);\r\n })\r\n .catch(() => {\r\n if (cancelled) return;\r\n // On failure, mark them as valid by default so a transient NUI hiccup\r\n // doesn't dim every row of the panel. Lua side will be re-asked next\r\n // time the deps change.\r\n missing.forEach(n => {\r\n inflight.current.delete(n);\r\n });\r\n });\r\n\r\n return () => {\r\n cancelled = true;\r\n };\r\n }, [cacheKey]);\r\n\r\n return useMemo(() => {\r\n const out = new Set<string>();\r\n if (!cacheKey) return out;\r\n for (const n of cacheKey.split(\"|\")) {\r\n if (n && moduleCache.get(n) === true) out.add(n);\r\n }\r\n return out;\r\n // version bumps cause re-derivation once the async cache fills in.\r\n }, [cacheKey, version]);\r\n}\r\n","// Drop-in replacement for React's useState that survives unmount/remount.\r\n//\r\n// Why: ConfigPanel returns null when closed, which tears down the entire\r\n// React tree under it. Local component state (active tab, current edit\r\n// target, search text, view-mode toggles, etc.) is lost. Admins who close\r\n// and reopen the panel land back at the default state every time.\r\n//\r\n// useAdminState writes to a module-scope store keyed by an arbitrary\r\n// string. The store survives close/reopen because the NUI iframe stays\r\n// alive across SetNuiFocus toggles — only React unmounts.\r\n//\r\n// Reset scope: keys live for the lifetime of the iframe (= until the\r\n// resource restarts or the player reloads the NUI). That's exactly what\r\n// admins want — \"remember where I was in this session, but don't carry\r\n// over after a restart\".\r\n//\r\n// Usage:\r\n// const [activeTab, setActiveTab] = useAdminState(\"labs:viewMode\", \"list\");\r\n//\r\n// Key collisions: state is scoped per dirk-cfx-react module-scope, which\r\n// is per-iframe — so two different consumer resources can both use the key\r\n// \"viewMode\" without colliding. Within a single consumer, keep keys unique\r\n// (prefix with section name: \"labs:viewMode\", \"shells:editingId\" etc).\r\n\r\nimport { useEffect, useState } from \"react\";\r\n\r\ntype Listener = () => void;\r\n\r\nconst store: Map<string, unknown> = new Map();\r\nconst listeners: Map<string, Set<Listener>> = new Map();\r\n\r\nfunction notify(key: string) {\r\n const ls = listeners.get(key);\r\n if (!ls) return;\r\n ls.forEach((fn) => fn());\r\n}\r\n\r\n/**\r\n * Like `useState` but the value persists in a module-scope store across\r\n * unmount/remount cycles. Identical API otherwise.\r\n *\r\n * @param key Stable string identifying this slot. Must be unique per\r\n * intended slot within the consumer's iframe.\r\n * @param initial Initial value if no value has been stored under `key` yet.\r\n */\r\nexport function useAdminState<T>(key: string, initial: T): [T, (v: T | ((prev: T) => T)) => void] {\r\n // useState here is just for triggering re-renders on cross-component\r\n // updates. The real value lives in the module-scope `store`.\r\n const [, setTick] = useState(0);\r\n\r\n useEffect(() => {\r\n const set = listeners.get(key) ?? new Set<Listener>();\r\n listeners.set(key, set);\r\n const handler = () => setTick((t) => t + 1);\r\n set.add(handler);\r\n return () => {\r\n set.delete(handler);\r\n if (set.size === 0) listeners.delete(key);\r\n };\r\n }, [key]);\r\n\r\n const value = (store.has(key) ? store.get(key) : initial) as T;\r\n\r\n const setValue = (v: T | ((prev: T) => T)) => {\r\n const next = typeof v === \"function\" ? (v as (p: T) => T)(value) : v;\r\n store.set(key, next);\r\n notify(key);\r\n };\r\n\r\n return [value, setValue];\r\n}\r\n\r\n/** Imperative clear — useful for \"reset everything\" admin actions. */\r\nexport function clearAdminState(key?: string) {\r\n if (key) {\r\n store.delete(key);\r\n notify(key);\r\n } else {\r\n const keys = Array.from(store.keys());\r\n store.clear();\r\n keys.forEach(notify);\r\n }\r\n}\r\n","// Fetches normalised player lists from dirk_lib's admin tool subsystem.\r\n//\r\n// Two modes, controlled by `includeOffline`:\r\n// • false (default) → online-only. Fast, cheap, refreshed every ~5s.\r\n// • true → DB-backed search across online + offline players.\r\n// Filtered server-side by `search`. Cap of 50.\r\n//\r\n// Caching: react-query handles dedupe + stale-while-revalidate, keyed on\r\n// (mode, search, limit). Multiple <PlayerSelect>s on screen share one\r\n// fetch. Typing \"j\" → \"jo\" → \"joh\" creates separate cache entries — each\r\n// stays cached for 5 minutes (gcTime) so re-typing reuses instantly.\r\n//\r\n// Admin gating: lives behind the ADMIN_TOOL_QUERY perm check on the\r\n// server. Outside an open admin panel, fetches return empty arrays.\r\n\r\nimport { useQuery, keepPreviousData } from \"@tanstack/react-query\";\r\nimport { fetchNui } from \"../utils/fetchNui\";\r\n\r\nexport type Player = {\r\n /** Server id when online, null when offline. */\r\n id: number | null;\r\n /** Persistent identifier — citizenid (qb/qbx) or license (esx). */\r\n citizenId: string;\r\n /** Steam/Discord display name from GetPlayerName(src). Blank for some\r\n * framework + offline combos (ESX users table doesn't store it). */\r\n name: string;\r\n /** First name + last name from the framework's character data. */\r\n charName: string;\r\n online: boolean;\r\n};\r\n\r\nexport type UsePlayersOptions = {\r\n /** When true, hits the DB and returns offline + online matches.\r\n * When false (default), returns only currently-connected players. */\r\n includeOffline?: boolean;\r\n /** Required when includeOffline=true; ignored otherwise. Server-side\r\n * filtered (LIKE) across char name, citizenId, account name. */\r\n search?: string;\r\n /** Default 50, max 50 (capped server-side). */\r\n limit?: number;\r\n /** Override staleTime — how long the cache stays fresh before background\r\n * refetch. Default 5s for online, 30s for search. */\r\n staleTimeMs?: number;\r\n /** Set to e.g. 10000 to auto-refresh every 10s. Off by default. */\r\n refetchIntervalMs?: number;\r\n};\r\n\r\nexport type UsePlayersResult = {\r\n players: Player[];\r\n isLoading: boolean;\r\n isFetching: boolean;\r\n error: Error | null;\r\n refresh: () => void;\r\n};\r\n\r\nexport function usePlayers(opts: UsePlayersOptions = {}): UsePlayersResult {\r\n const {\r\n includeOffline = false,\r\n search = \"\",\r\n limit = 50,\r\n staleTimeMs,\r\n refetchIntervalMs,\r\n } = opts;\r\n\r\n const query = useQuery<Player[]>({\r\n queryKey: includeOffline\r\n ? [\"dirk:players\", \"search\", search.trim().toLowerCase(), limit]\r\n : [\"dirk:players\", \"online\"],\r\n queryFn: async () => {\r\n const toolId = includeOffline ? \"searchPlayers\" : \"getOnlinePlayers\";\r\n const payload = includeOffline\r\n ? { id: toolId, value: { search: search.trim(), limit } }\r\n : { id: toolId };\r\n const result = await fetchNui<Player[] | null>(\r\n \"ADMIN_TOOL_QUERY\",\r\n payload,\r\n // Browser-dev fallback. Returns a couple of mock players so the\r\n // dev shell isn't blank.\r\n includeOffline\r\n ? [\r\n { id: 1, citizenId: \"ABC12345\", name: \"Dev User\", charName: \"John Doe\", online: true },\r\n { id: null, citizenId: \"DEF67890\", name: \"\", charName: \"Jane Offline\", online: false },\r\n ]\r\n : [\r\n { id: 1, citizenId: \"ABC12345\", name: \"Dev User\", charName: \"John Doe\", online: true },\r\n ],\r\n );\r\n return Array.isArray(result) ? result : [];\r\n },\r\n staleTime: staleTimeMs ?? (includeOffline ? 30_000 : 5_000),\r\n gcTime: 5 * 60_000,\r\n refetchInterval: refetchIntervalMs ?? false,\r\n refetchOnWindowFocus: false,\r\n placeholderData: includeOffline ? keepPreviousData : undefined,\r\n });\r\n\r\n return {\r\n players: query.data ?? [],\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: (query.error as Error | null) ?? null,\r\n refresh: () => query.refetch(),\r\n };\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/hooks/useAudio/store.ts","../../src/utils/misc.ts","../../src/hooks/useNuiEvent.ts","../../src/hooks/useForm.tsx","../../src/types/theme.ts","../../src/utils/useSettings.ts","../../src/hooks/useTornEdges.tsx","../../src/utils/fetchNui.ts","../../src/hooks/useScriptConfig.ts","../../src/hooks/useValidModels.ts","../../src/hooks/useAdminState.ts","../../src/hooks/usePlayers.ts"],"names":["useRef","store","create","jsx","isPlainObject","useMemo","useEffect","useState"],"mappings":"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","file":"index.js","sourcesContent":["import { create } from 'zustand';\r\n\r\n// Import sounds as URLs (TypeScript-safe)\r\nimport clickSoundUrl from './click_sound.mp3';\r\nimport hoverSoundUrl from './hover_sound.mp3';\r\n\r\n// Define a type for the store state and actions\r\ntype AudioPlayerStore = {\r\n play: (sound: string) => void;\r\n stop: (sound: string) => void;\r\n};\r\n\r\n// Create the store using Zustand\r\nexport const useAudio = create<AudioPlayerStore>(() => {\r\n const audioRefs: Record<string, HTMLAudioElement> = {};\r\n\r\n // Predefined sounds\r\n const sounds: Record<string, string> = {\r\n click: clickSoundUrl,\r\n hover: hoverSoundUrl,\r\n };\r\n\r\n // Initialize audio elements for each sound\r\n for (const [key, src] of Object.entries(sounds)) {\r\n audioRefs[key] = new Audio(src);\r\n }\r\n\r\n return {\r\n play: (sound) => {\r\n const audio = audioRefs[sound];\r\n if (!audio) return console.warn(`Sound '${sound}' not found.`);\r\n audio.currentTime = 0;\r\n audio.volume = 0.1;\r\n audio.play();\r\n },\r\n stop: (sound) => {\r\n const audio = audioRefs[sound];\r\n if (!audio) return console.warn(`Sound '${sound}' not found.`);\r\n audio.pause();\r\n audio.currentTime = 0;\r\n },\r\n };\r\n});\r\n","export const isEnvBrowser = (): boolean => !(window as any).invokeNative;\r\n\r\n// Basic no operation function\r\nexport const noop = () => {};\r\n\r\nexport const splitFAString = (faString:string) => {\r\n const [prefix, newIcon] = faString.split('-');\r\n if (!prefix || !newIcon) return {prefix: 'fas', newIcon: 'question'};\r\n return {prefix, newIcon};\r\n}\r\n\r\nexport const numberToRoman = (num:number) => {\r\n const romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX'] \r\n return romanNumerals[num]\r\n}\r\n\r\nexport const copyToClipboard = (text:string) => {\r\n const el = document.createElement('textarea');\r\n el.value = text;\r\n document.body.appendChild(el);\r\n el.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(el);\r\n}\r\n\r\nexport const openLink = (url:string) => {\r\n if (isEnvBrowser()) {\r\n window.open(url, '_blank');\r\n } else {\r\n // @ts-expect-error -- invokeNative exists in NUI\r\n window.invokeNative('openLink', url);\r\n } \r\n}","import { MutableRefObject, useEffect, useRef } from \"react\";\r\nimport { noop } from \"../utils/misc\";\r\n\r\nexport interface NuiMessageData<T = unknown> {\r\n action: string;\r\n data: T;\r\n}\r\n\r\nexport type NuiHandlerSignature<T> = ( data: T) => void;\r\n\r\n/**\r\n * A hook that manage events listeners for receiving data from the client scripts\r\n * @param action The specific `action` that should be listened for.\r\n * @param handler The callback function that will handle data relayed by this hook\r\n *\r\n * @example\r\n * useNuiEvent<{visibility: true, wasVisible: 'something'}>('setVisible', (data) => {\r\n * // whatever logic you want\r\n * })\r\n *\r\n **/\r\n\r\nexport const useNuiEvent = <T = unknown>(\r\n action: string,\r\n handler: ( data: T) => void,\r\n) => {\r\n const savedHandler: MutableRefObject<NuiHandlerSignature<T>> = useRef(noop);\r\n\r\n // Make sure we handle for a reactive handler\r\n useEffect(() => {\r\n savedHandler.current = handler;\r\n }, [handler]);\r\n\r\n useEffect(() => {\r\n const eventListener = (event: MessageEvent<NuiMessageData<T>>) => {\r\n const { action: eventAction, data } = event.data;\r\n\r\n if (savedHandler.current) {\r\n if (eventAction === action) {\r\n savedHandler.current( data);\r\n }\r\n }\r\n };\r\n\r\n window.addEventListener(\"message\", eventListener);\r\n // Remove Event Listener on component dirkup\r\n return () => window.removeEventListener(\"message\", eventListener);\r\n }, [action]);\r\n};\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\n\r\nimport React, { createContext, useContext, useMemo, useRef } from \"react\";\r\nimport { createStore, StoreApi, useStore } from \"zustand\";\r\n\r\n/* ======================================================\r\n Type Utilities\r\n====================================================== */\r\n\r\ntype PathValue<T, P extends string> = P extends keyof T\r\n ? T[P]\r\n : P extends `${infer K}.${infer R}`\r\n ? K extends keyof T\r\n ? PathValue<T[K], R>\r\n : never\r\n : never;\r\n\r\ntype Paths<T> = T extends object\r\n ? {\r\n [K in keyof T]: K extends string\r\n ? T[K] extends object\r\n ? T[K] extends any[] | Date | Function\r\n ? K\r\n : K | `${K}.${Paths<T[K]>}`\r\n : K\r\n : never;\r\n }[keyof T]\r\n : never;\r\n\r\ntype LoosePaths<T> = Paths<T> | (string & {});\r\n\r\n/* ======================================================\r\n Utilities\r\n====================================================== */\r\n\r\nfunction getNested(obj: any, path: string): any {\r\n return path.split(\".\").reduce((acc, key) => (acc ? acc[key] : undefined), obj);\r\n}\r\n\r\nfunction setNested(obj: any, path: string, value: any): any {\r\n const keys = path.split(\".\");\r\n const root = Array.isArray(obj) ? [...obj] : { ...obj };\r\n let current = root;\r\n\r\n for (let i = 0; i < keys.length - 1; i++) {\r\n const key = keys[i];\r\n const nextKey = keys[i + 1];\r\n const isIndex = !isNaN(Number(nextKey));\r\n\r\n const existing = current[key];\r\n\r\n current[key] =\r\n existing != null\r\n ? Array.isArray(existing)\r\n ? [...existing]\r\n : { ...existing }\r\n : isIndex\r\n ? []\r\n : {};\r\n\r\n current = current[key];\r\n }\r\n\r\n current[keys[keys.length - 1]] = value;\r\n return root;\r\n}\r\n\r\nfunction deleteNested(obj: any, path: string): any {\r\n const keys = path.split(\".\");\r\n const newObj = { ...obj };\r\n let current = newObj;\r\n\r\n for (let i = 0; i < keys.length - 1; i++) {\r\n const key = keys[i];\r\n if (!current[key]) return obj;\r\n current[key] = { ...current[key] };\r\n current = current[key];\r\n }\r\n\r\n delete current[keys[keys.length - 1]];\r\n return newObj;\r\n}\r\n\r\nfunction isPlainObject(value: any): value is Record<string, any> {\r\n return (\r\n value !== null &&\r\n typeof value === \"object\" &&\r\n !Array.isArray(value) &&\r\n !(value instanceof Date)\r\n );\r\n}\r\n\r\nfunction collectChangedPaths(values: any, initial: any, prefix = \"\"): string[] {\r\n if (Object.is(values, initial)) return [];\r\n\r\n const valuesIsObj = isPlainObject(values);\r\n const initialIsObj = isPlainObject(initial);\r\n const valuesIsArr = Array.isArray(values);\r\n const initialIsArr = Array.isArray(initial);\r\n\r\n if (valuesIsArr || initialIsArr) {\r\n const maxLen = Math.max(values?.length ?? 0, initial?.length ?? 0);\r\n const fields: string[] = [];\r\n for (let i = 0; i < maxLen; i++) {\r\n const nextPrefix = prefix ? `${prefix}.${i}` : `${i}`;\r\n fields.push(...collectChangedPaths(values?.[i], initial?.[i], nextPrefix));\r\n }\r\n return fields;\r\n }\r\n\r\n if (valuesIsObj || initialIsObj) {\r\n const keys = new Set([\r\n ...Object.keys(values ?? {}),\r\n ...Object.keys(initial ?? {}),\r\n ]);\r\n const fields: string[] = [];\r\n for (const key of keys) {\r\n const nextPrefix = prefix ? `${prefix}.${key}` : key;\r\n fields.push(...collectChangedPaths(values?.[key], initial?.[key], nextPrefix));\r\n }\r\n return fields;\r\n }\r\n\r\n return prefix ? [prefix] : [];\r\n}\r\n\r\nfunction computeChangedState<T>(\r\n values: Partial<T>,\r\n initialVals: Partial<T>\r\n): { fields: string[]; partial: Partial<T> } {\r\n const fields = collectChangedPaths(values, initialVals);\r\n let partial: Partial<T> = {};\r\n\r\n for (const path of fields) {\r\n partial = setNested(partial, path, getNested(values, path));\r\n }\r\n\r\n return { fields, partial };\r\n}\r\n\r\nfunction flattenRules(\r\n rules: any,\r\n prefix = \"\"\r\n): Record<string, ValidatorFn> {\r\n const result: Record<string, ValidatorFn> = {};\r\n\r\n for (const key in rules) {\r\n const fullPath = prefix ? `${prefix}.${key}` : key;\r\n const val = rules[key];\r\n\r\n if (typeof val === \"function\") result[fullPath] = val;\r\n else if (typeof val === \"object\")\r\n Object.assign(result, flattenRules(val, fullPath));\r\n }\r\n\r\n return result;\r\n}\r\n\r\nasync function runRule(\r\n rule: ValidatorFn,\r\n value: any,\r\n values: any\r\n): Promise<string | null> {\r\n const result = rule(value, values);\r\n return result instanceof Promise ? await result : result;\r\n}\r\n\r\n/* ======================================================\r\n Types\r\n====================================================== */\r\n\r\nexport type ValidatorFn<T = any> =\r\n | ((value: any, values: Partial<T>) => string | null)\r\n | ((value: any, values: Partial<T>) => Promise<string | null>);\r\n\r\nexport type ValidationRules<T> = {\r\n [K in keyof T]?: T[K] extends object\r\n ? ValidationRules<T[K]>\r\n : ValidatorFn<T>;\r\n};\r\n\r\nexport type FormState<T> = {\r\n values: Partial<T>;\r\n initialValues: Partial<T>;\r\n errors: Record<string, string>;\r\n\r\n partialChanged: Partial<T>;\r\n\r\n getInputProps: (path: string) => {\r\n value: any;\r\n error?: string;\r\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n };\r\n\r\n setValue: (path: string, value: any, options?: { validate?: boolean }) => void;\r\n setInitialValues: (newInitialValues: Partial<T>) => void;\r\n\r\n setError: (path: string, message: string) => void;\r\n clearError: (path: string) => void;\r\n\r\n validate: () => Promise<boolean>;\r\n validateField: (path: string) => Promise<boolean>;\r\n\r\n reset: () => void;\r\n reinitialize: (newValues: Partial<T>) => void;\r\n\r\n back: () => void;\r\n forward: () => void;\r\n canBack: boolean;\r\n canForward: boolean;\r\n\r\n changedFields: string[];\r\n changedCount: number;\r\n resetChangeCount: () => void;\r\n\r\n onSubmit?: (form: FormState<T>) => void;\r\n submit: () => Promise<void>;\r\n};\r\n\r\n/* ======================================================\r\n Store\r\n====================================================== */\r\n\r\nexport function createFormStore<T>(\r\n initialValues: Partial<T>,\r\n validationRules?: ValidationRules<T>,\r\n onSubmit?: (form: FormState<T>) => void\r\n) {\r\n const flatRules = validationRules ? flattenRules(validationRules) : {};\r\n\r\n const history: Partial<T>[] = [];\r\n const future: Partial<T>[] = [];\r\n const changed = new Set<string>();\r\n\r\n return createStore<FormState<T>>((set, get) => ({\r\n initialValues,\r\n values: initialValues,\r\n errors: {},\r\n partialChanged: {},\r\n canBack: false,\r\n canForward: false,\r\n changedFields: [],\r\n changedCount: 0,\r\n onSubmit,\r\n\r\n submit: async () => {\r\n const state = get();\r\n const isValid = await state.validate();\r\n if (isValid && state.onSubmit) {\r\n state.onSubmit(get());\r\n }\r\n },\r\n\r\n getInputProps: (path: string) => {\r\n return {\r\n value: getNested(get().values, path) ?? \"\",\r\n error: get().errors[path],\r\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\r\n get().setValue(path, e.target.value, { validate: true });\r\n },\r\n };\r\n },\r\n\r\n resetChangeCount: () => {\r\n changed.clear();\r\n set({ changedFields: [], changedCount: 0, partialChanged: {} });\r\n },\r\n\r\n setInitialValues: (newInitialValues) =>\r\n set({ initialValues: newInitialValues }),\r\n\r\n setValue: (path, value, options) => {\r\n const state = get();\r\n const currentValues = state.values;\r\n const newValues = setNested(currentValues, path, value);\r\n\r\n const oldValue = getNested(state.initialValues, path);\r\n const hasChanged = value !== oldValue;\r\n\r\n history.push(currentValues);\r\n future.length = 0;\r\n\r\n let newPartial = state.partialChanged;\r\n\r\n if (hasChanged) {\r\n changed.add(path);\r\n newPartial = setNested(newPartial, path, value);\r\n } else {\r\n changed.delete(path);\r\n newPartial = deleteNested(newPartial, path);\r\n }\r\n\r\n set({\r\n values: newValues,\r\n partialChanged: newPartial,\r\n canBack: history.length > 0,\r\n canForward: false,\r\n changedFields: Array.from(changed),\r\n changedCount: changed.size,\r\n });\r\n\r\n if (!options?.validate) return;\r\n\r\n const rule = flatRules[path];\r\n if (!rule) return;\r\n\r\n Promise.resolve(runRule(rule, value, newValues)).then((error) => {\r\n if (error)\r\n set((s) => ({ errors: setNested(s.errors, path, error) }));\r\n else\r\n set((s) => ({ errors: deleteNested(s.errors, path) }));\r\n });\r\n },\r\n\r\n setError: (path, message) =>\r\n set((s) => ({ errors: setNested(s.errors, path, message) })),\r\n\r\n clearError: (path) =>\r\n set((s) => ({ errors: deleteNested(s.errors, path) })),\r\n\r\n validateField: async (path) => {\r\n const state = get();\r\n const rule = flatRules[path];\r\n if (!rule) return true;\r\n\r\n const value = getNested(state.values, path);\r\n const error = await runRule(rule, value, state.values);\r\n\r\n if (error) {\r\n set((s) => ({ errors: setNested(s.errors, path, error) }));\r\n return false;\r\n }\r\n\r\n set((s) => ({ errors: deleteNested(s.errors, path) }));\r\n return true;\r\n },\r\n\r\n validate: async () => {\r\n const state = get();\r\n let isValid = true;\r\n let newErrors: Record<string, string> = {};\r\n\r\n for (const path in flatRules) {\r\n const rule = flatRules[path];\r\n const value = getNested(state.values, path);\r\n const error = await runRule(rule, value, state.values);\r\n\r\n if (error) {\r\n isValid = false;\r\n newErrors = setNested(newErrors, path, error);\r\n }\r\n }\r\n\r\n set({ errors: newErrors });\r\n return isValid;\r\n },\r\n\r\n reset: () => {\r\n history.length = 0;\r\n future.length = 0;\r\n changed.clear();\r\n\r\n set({\r\n values: get().initialValues,\r\n errors: {},\r\n partialChanged: {},\r\n canBack: false,\r\n canForward: false,\r\n changedFields: [],\r\n changedCount: 0,\r\n });\r\n },\r\n\r\n reinitialize: (newValues) => {\r\n history.length = 0;\r\n future.length = 0;\r\n changed.clear();\r\n\r\n set({\r\n values: newValues,\r\n initialValues: newValues,\r\n errors: {},\r\n partialChanged: {},\r\n canBack: false,\r\n canForward: false,\r\n changedFields: [],\r\n changedCount: 0,\r\n });\r\n },\r\n\r\n back: () => {\r\n if (!history.length) return;\r\n\r\n const prev = history.pop()!;\r\n future.push(get().values);\r\n\r\n const { fields, partial } = computeChangedState(prev, get().initialValues);\r\n\r\n set({\r\n values: prev,\r\n partialChanged: partial,\r\n canBack: history.length > 0,\r\n canForward: true,\r\n changedFields: fields,\r\n changedCount: fields.length,\r\n });\r\n },\r\n\r\n forward: () => {\r\n if (!future.length) return;\r\n\r\n const next = future.pop()!;\r\n history.push(get().values);\r\n\r\n const { fields, partial } = computeChangedState(next, get().initialValues);\r\n\r\n set({\r\n values: next,\r\n partialChanged: partial,\r\n canBack: true,\r\n canForward: future.length > 0,\r\n changedFields: fields,\r\n changedCount: fields.length,\r\n });\r\n },\r\n }));\r\n}\r\n\r\n/* ======================================================\r\n Context + Hook\r\n====================================================== */\r\n\r\nconst FormContext = createContext<StoreApi<FormState<any>> | null>(null);\r\n\r\nexport function FormProvider<T>({\r\n initialValues,\r\n validate,\r\n onSubmit,\r\n children,\r\n}: {\r\n initialValues: Partial<T>;\r\n validate?: ValidationRules<T>;\r\n onSubmit?: (form: FormState<T>) => void;\r\n children: React.ReactNode;\r\n}) {\r\n const storeRef = useRef(\r\n createFormStore<T>(initialValues, validate, onSubmit)\r\n );\r\n\r\n return (\r\n <FormContext.Provider value={storeRef.current}>\r\n {children}\r\n </FormContext.Provider>\r\n );\r\n}\r\n\r\nexport function useForm<T>() {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useForm must be used inside <FormProvider>\");\r\n }\r\n const state = useStore(store) as FormState<T>;\r\n\r\n const changedFields = useMemo(() => {\r\n return collectChangedPaths(state.values, state.initialValues);\r\n }, [state.values, state.initialValues]);\r\n\r\n return { ...state, changedFields, changedCount: changedFields.length } as FormState<T>;\r\n}\r\n\r\nexport function useFormField<T, P extends LoosePaths<T> = LoosePaths<T>>(\r\n path: P\r\n): P extends Paths<T> ? PathValue<T, P> | undefined : any {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useFormField must be used inside <FormProvider>\");\r\n }\r\n return useStore(store, (s) => getNested(s.values, path));\r\n}\r\n\r\nexport function useFormFields<T, P extends LoosePaths<T> = LoosePaths<T>>(\r\n ...paths: P[]\r\n): { [K in P]: K extends Paths<T> ? PathValue<T, K> | undefined : any } {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useFormFields must be used inside <FormProvider>\");\r\n }\r\n \r\n return useStore(store, (s) => {\r\n const result = {} as { [K in P]: K extends Paths<T> ? PathValue<T, K> | undefined : any };\r\n for (const path of paths) {\r\n result[path] = getNested(s.values, path);\r\n }\r\n return result;\r\n });\r\n}\r\n\r\nexport function useFormError(path: string) {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useFormError must be used inside <FormProvider>\");\r\n }\r\n return useStore(store, (s) => s.errors[path]);\r\n}\r\n\r\nexport function useFormErrors(...paths: string[]) {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useFormErrors must be used inside <FormProvider>\");\r\n }\r\n return useStore(store, (s) => {\r\n const result: Record<string, string | undefined> = {};\r\n for (const path of paths) {\r\n result[path] = s.errors[path];\r\n }\r\n return result;\r\n });\r\n}\r\n\r\nexport function useFormActions<T>() {\r\n const store = useContext(FormContext);\r\n if (!store) {\r\n throw new Error(\"useFormActions must be used inside <FormProvider>\");\r\n }\r\n return store.getState() as Pick<\r\n FormState<T>,\r\n | \"setValue\"\r\n | \"setError\"\r\n | \"clearError\"\r\n | \"validate\"\r\n | \"validateField\"\r\n | \"reset\"\r\n | \"reinitialize\"\r\n | \"back\"\r\n | \"forward\"\r\n | \"canBack\"\r\n | \"canForward\"\r\n | \"submit\"\r\n >;\r\n}","import { z } from \"zod\";\n\n/**\n * Per-resource theme override block.\n *\n * Single source of truth for the shape + defaults that were previously\n * duplicated across `components/ThemeOverrideSection.tsx` and\n * `utils/useSettings.ts`. Both now import from here.\n *\n * Data shape (driven by a schema block on the consumer side):\n * theme: {\n * useOverride: boolean,\n * primaryColor: string, // \"dirk\" | \"custom\" | mantine palette name\n * primaryShade: 0..9,\n * customTheme: string[10], // hex stops\n * }\n */\n\n/**\n * The 10-stop hex palette used as the fallback custom theme. This exact tuple\n * was duplicated in ThemeOverrideSection (DEFAULT_PALETTE) and useSettings\n * (customTheme). Keep it as a 10-tuple — Mantine `MantineColorsTuple` expects\n * exactly ten stops.\n */\nexport const DEFAULT_PALETTE: string[] = [\n \"#f0f4ff\",\n \"#d9e3ff\",\n \"#bfcfff\",\n \"#a6bbff\",\n \"#8ca7ff\",\n \"#7393ff\",\n \"#5a7fff\",\n \"#406bff\",\n \"#2547ff\",\n \"#0b33ff\",\n];\n\n/**\n * Zod schema for the theme override block. `customTheme` is validated as an\n * array of strings (the editor enforces the 10-length shape at the UI layer\n * by falling back to DEFAULT_PALETTE when the count is wrong).\n */\nexport const ThemeOverrideSchema = z.object({\n useOverride: z.boolean(),\n primaryColor: z.string(),\n primaryShade: z.number(),\n customTheme: z.array(z.string()),\n});\n\nexport type ThemeOverrideValue = z.infer<typeof ThemeOverrideSchema>;\n\n/**\n * Canonical default theme override block. Used as the merge fallback in\n * ThemeOverrideSection and (the palette portion) as the default custom theme\n * in useSettings.\n */\nexport const defaultThemeOverride: ThemeOverrideValue = {\n useOverride: false,\n primaryColor: \"dirk\",\n primaryShade: 5,\n customTheme: DEFAULT_PALETTE,\n};\n","import { MantineColorsTuple } from \"@mantine/core\";\r\nimport { create } from \"zustand\";\r\nimport { DEFAULT_PALETTE } from \"../types/theme\";\r\n\r\nexport type SettingsState = {\r\n game: \"fivem\" | \"rdr3\";\r\n currency: string;\r\n primaryColor: string;\r\n primaryShade: number;\r\n itemImgPath: string;\r\n resourceVersion?: string;\r\n customTheme?: MantineColorsTuple;\r\n overideResourceName?: string;\r\n serverName?: string;\r\n logo?: string;\r\n language?: string;\r\n};\r\n\r\nexport const useSettings = create<SettingsState>(() => ({\r\n currency: \"$\",\r\n game: \"fivem\",\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n itemImgPath: \"\",\r\n resourceVersion: \"dev\",\r\n customTheme: DEFAULT_PALETTE as unknown as MantineColorsTuple,\r\n}));\r\n\r\n// registerInitialFetch<Partial<SettingsState>>('GET_SETTINGS', undefined).then((data) => {\r\n// if (!data) {\r\n// console.warn('No settings data received from GET_SETTINGS fetch.');\r\n// return;\r\n// }\r\n// useSettings.setState({\r\n// ...data,\r\n// });\r\n// })\r\n","import { useSettings } from \"@/utils/useSettings\";\r\nexport function useTornEdges() {\r\n const game = useSettings((state) => state.game);\r\n return game === \"rdr3\" ? \"torn-edge-wrapper\" : \"\";\r\n}\r\n\r\n// Add this SVG to your layout/root component:\r\nexport function TornEdgeSVGFilter() {\r\n return (\r\n <svg\r\n style={{ position: \"absolute\", width: 0, height: 0, pointerEvents: \"none\" }}\r\n aria-hidden=\"true\"\r\n >\r\n <defs>\r\n <filter id=\"torn-edge-filter\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\r\n {/* Base fractal noise for tearing */}\r\n <feTurbulence\r\n type=\"fractalNoise\"\r\n baseFrequency=\"0.018 0.022\"\r\n numOctaves=\"5\"\r\n seed=\"9\"\r\n result=\"noise1\"\r\n />\r\n {/* Second noise layer for micro detail */}\r\n <feTurbulence\r\n type=\"fractalNoise\"\r\n baseFrequency=\"0.08 0.12\"\r\n numOctaves=\"2\"\r\n seed=\"3\"\r\n result=\"noise2\"\r\n />\r\n\r\n {/* Blend both noise layers */}\r\n <feBlend in=\"noise1\" in2=\"noise2\" mode=\"multiply\" result=\"combinedNoise\" />\r\n\r\n {/* Primary displacement */}\r\n <feDisplacementMap\r\n in=\"SourceGraphic\"\r\n in2=\"combinedNoise\"\r\n scale=\"52\"\r\n xChannelSelector=\"R\"\r\n yChannelSelector=\"G\"\r\n result=\"displaced\"\r\n />\r\n\r\n {/* Alpha fade toward edges */}\r\n <feGaussianBlur stdDeviation=\"0.8\" in=\"displaced\" result=\"blurred\" />\r\n <feComponentTransfer in=\"blurred\" result=\"alphaFade\">\r\n <feFuncA type=\"gamma\" amplitude=\"1\" exponent=\"1.3\" offset=\"-0.05\" />\r\n </feComponentTransfer>\r\n\r\n {/* Sharpen a bit after fade */}\r\n <feMorphology operator=\"erode\" radius=\"0.4\" in=\"alphaFade\" result=\"eroded\" />\r\n\r\n {/* Merge final */}\r\n <feMerge>\r\n <feMergeNode in=\"eroded\" />\r\n </feMerge>\r\n </filter>\r\n </defs>\r\n </svg>\r\n );\r\n}\r\n\r\n","import { useEffect } from \"react\";\r\nimport { isEnvBrowser } from \"./misc\";\r\nimport { useSettings } from \"./useSettings\";\r\n\r\n/**\r\n * Simple wrapper around fetch API tailored for CEF/NUI use.\r\n */\r\nexport async function fetchNui<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const options = {\r\n method: \"post\",\r\n headers: {\r\n \"Content-Type\": \"application/json; charset=UTF-8\",\r\n },\r\n body: JSON.stringify(data),\r\n };\r\n\r\n if (isEnvBrowser() && mockData !== undefined) return mockData;\r\n if (isEnvBrowser() && mockData === undefined) {\r\n console.warn(\r\n `[fetchNui] Called fetchNui for event \"${eventName}\" in browser environment without mockData. Returning empty object.`,\r\n );\r\n return {} as T;\r\n }\r\n\r\n const overrideResourceName = useSettings.getState().overideResourceName;\r\n\r\n // Resource-name resolution:\r\n // 1. NUI iframes expose `window.GetParentResourceName` — use that.\r\n // 2. DUIs don't have it, but DirkProvider sets `overideResourceName`\r\n // once it mounts, so consumer DUIs that wait until then resolve fine.\r\n // 3. If NEITHER is available (e.g. a DUI before its DirkProvider has\r\n // mounted, which happens for module-level `registerInitialFetch`\r\n // calls in `locales.ts`), there's no valid resource to call. Skip\r\n // the fetch entirely — firing it against a placeholder URL just\r\n // produces a doomed network request + an \"Uncaught (in promise)\r\n // TypeError: Failed to fetch\" in older consumer builds that\r\n // lacked the try/catch fallback below. Caller can rely on the\r\n // mockData return or refetch once context is established.\r\n const hasResourceContext =\r\n typeof (window as any).GetParentResourceName === \"function\" ||\r\n !!overrideResourceName;\r\n\r\n if (!hasResourceContext) {\r\n return (mockData ?? ({} as T));\r\n }\r\n\r\n const resourceName = (window as any).GetParentResourceName\r\n ? (window as any).GetParentResourceName()\r\n : overrideResourceName as string;\r\n\r\n try {\r\n const resp = await fetch(`https://${resourceName}/${eventName}`, options);\r\n return await resp.json();\r\n } catch {\r\n return (mockData ?? ({} as T));\r\n }\r\n}\r\n\r\n// -----------------------------\r\n// Initial fetch registration\r\n// -----------------------------\r\nexport type InitialFetch<T> = () => Promise<T>;\r\nexport const initialFetches: Record<string, InitialFetch<unknown>> = {};\r\n\r\n/**\r\n * Registers an initial fetch that automatically uses fetchNui.\r\n * Works like:\r\n * ```ts\r\n * registerInitialFetch<{ name: string }>(\"MY_EVENT_NAME\", undefined, { name: \"Mocky\" });\r\n * ```\r\n * and returns a Promise resolving to the same type as fetchNui.\r\n */\r\nexport async function registerInitialFetch<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const fetcher = () => fetchNui<T>(eventName, data, mockData);\r\n initialFetches[eventName] = fetcher;\r\n return fetcher(); // run immediately if needed\r\n}\r\n\r\n/**\r\n * Runs all registered initial fetches in parallel.\r\n */\r\nexport async function runFetches() {\r\n return Promise.all(\r\n Object.entries(initialFetches).map(async ([eventName, fetcher]) => {\r\n const data = await fetcher();\r\n return { eventName, data };\r\n }),\r\n );\r\n}\r\n\r\n/**\r\n * React hook to automatically run all registered fetches on mount.\r\n */\r\nexport const useAutoFetcher = () => {\r\n useEffect(() => {\r\n if (isEnvBrowser()) return;\r\n runFetches().catch(() => {});\r\n }, []);\r\n};\r\n\r\n\r\nexport const fetchLuaTable = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return fetchNui<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\nexport const registerInitialLuaTableFetch = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return registerInitialFetch<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\n\r\n\r\n// useage example:\r\n// registerInitialLuaTableFetch<{ [key: string]: string }>('my_lua_table', { key1: 'value1', key2: 'value2' }); \r\n","import { fetchNui } from \"@/utils\";\r\nimport { useNuiEvent } from \"@/hooks/useNuiEvent\";\r\nimport { create } from \"zustand\";\r\n\r\ntype ScriptConfigUpdateMeta<T> = {\r\n client_version?: number;\r\n latestVersion?: number;\r\n latestData?: Partial<T>;\r\n changed_paths?: Array<{ path: string; old: unknown; new: unknown }>;\r\n lastEditor?: { source?: number; name?: string; identifier?: string };\r\n};\r\n\r\nexport type ScriptConfigHistoryChange = {\r\n path: string;\r\n old: unknown;\r\n new: unknown;\r\n};\r\n\r\nexport type ScriptConfigHistoryEntry = {\r\n at_unix: number;\r\n at_utc: string;\r\n script: string;\r\n admin?: { source?: number; name?: string; identifier?: string };\r\n expected_version?: number;\r\n applied_version?: number;\r\n changes: ScriptConfigHistoryChange[];\r\n};\r\n\r\nexport type ScriptConfigHistoryRequest = {\r\n offset?: number;\r\n limit?: number;\r\n query?: string;\r\n path?: string;\r\n admin?: string;\r\n fromUnix?: number;\r\n toUnix?: number;\r\n};\r\n\r\nexport type ScriptConfigHistoryResponse = {\r\n success: boolean;\r\n _error?: string;\r\n data?: {\r\n items: ScriptConfigHistoryEntry[];\r\n total: number;\r\n limit: number;\r\n offset: number;\r\n nextOffset?: number;\r\n };\r\n};\r\n\r\ntype NuiResponse<T> = {\r\n success: boolean;\r\n message?: string;\r\n _error?: string;\r\n meta?: ScriptConfigUpdateMeta<T>;\r\n};\r\n\r\n// Server-only \"sliver\" response (GET_SERVER_ONLY_SCRIPT_CONFIG). Identical\r\n// envelope to GET_FULL_SCRIPT_CONFIG — only the inner key differs (`serverOnly`\r\n// instead of `config`). `serverOnly` is the x-serverOnly subtree in the SAME\r\n// nested shape/paths as `config` (a deep object, NOT flat dot-paths); `{}` when\r\n// the schema declares no server-only fields.\r\nexport type ServerOnlyScriptConfigResponse<T> = {\r\n success: boolean;\r\n _error?: string;\r\n data?: { serverOnly: Partial<T>; clientVersion: number };\r\n};\r\n\r\n// Recursive deep-merge: returns a new object where `patch`'s plain-object\r\n// branches are merged INTO `base`'s, and non-object values (scalars, arrays)\r\n// from `patch` replace `base`. Used to top up the server-only sliver onto the\r\n// already-cached client-visible config WITHOUT the top-level spread-replace\r\n// `fetchScriptConfig` uses — a shallow spread would clobber sibling\r\n// client-visible keys that live under a shared parent section. By construction\r\n// the two views are disjoint (serverOnly is the set-complement of the\r\n// client-visible view), but we still deep-merge so a shared parent section keeps\r\n// both its client-visible and server-only children.\r\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\r\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\r\n}\r\n\r\nfunction deepMerge<T>(base: T, patch: Partial<T>): T {\r\n if (!isPlainObject(base) || !isPlainObject(patch)) {\r\n // patch wins for non-object values (arrays/scalars are replaced wholesale).\r\n return (patch as unknown as T) ?? base;\r\n }\r\n const out: Record<string, unknown> = { ...(base as Record<string, unknown>) };\r\n for (const key of Object.keys(patch as Record<string, unknown>)) {\r\n const patchVal = (patch as Record<string, unknown>)[key];\r\n const baseVal = out[key];\r\n out[key] = isPlainObject(baseVal) && isPlainObject(patchVal)\r\n ? deepMerge(baseVal, patchVal as Record<string, unknown>)\r\n : patchVal;\r\n }\r\n return out as T;\r\n}\r\n\r\n// Derive the set of changed TOP-LEVEL section keys from a useForm changed-set\r\n// of dotted paths (e.g. [\"stores.0.name\", \"basic.weightUnit\"] → {\"stores\",\"basic\"}).\r\n// CONSERVATIVE by design: any changed path under section X marks the WHOLE\r\n// section X as changed, so the caller sends its full current value. This is what\r\n// lets deletions inside a section (a removed array element) propagate, because\r\n// the server/client overwrite the section wholesale rather than deep-merging.\r\nfunction changedTopLevelSections(changedFields?: readonly string[]): string[] {\r\n if (!changedFields || changedFields.length === 0) return [];\r\n const sections = new Set<string>();\r\n for (const path of changedFields) {\r\n if (typeof path !== \"string\" || path.length === 0) continue;\r\n const dot = path.indexOf(\".\");\r\n sections.add(dot === -1 ? path : path.slice(0, dot));\r\n }\r\n return Array.from(sections);\r\n}\r\n\r\n// ── Singleton registry ────────────────────────────────────────────────────────\r\n\r\nexport interface ScriptConfigInstance<T = any> {\r\n store: { getState: () => T; setState: (partial: Partial<T> | ((prev: T) => T)) => void };\r\n updateConfig: (newConfig: Partial<T>, changedFields?: readonly string[]) => Promise<NuiResponse<T>>;\r\n resetConfig: () => Promise<{ success: boolean; _error?: string }>;\r\n getHistory: (params?: ScriptConfigHistoryRequest) => Promise<ScriptConfigHistoryResponse>;\r\n fetchConfig: () => Promise<T | null>;\r\n // Admin-only top-up: fetches the server-only sliver and DEEP-MERGES it onto\r\n // the already-cached client-visible store state. Returns the merged full\r\n // config, or null on failure / no-permission. The sliver is in-memory only —\r\n // it is NEVER persisted to KVP or any cache (KVP holds client-visible only).\r\n fetchServerOnly: () => Promise<T | null>;\r\n}\r\n\r\nlet _instance: ScriptConfigInstance | null = null;\r\n\r\nexport function getScriptConfigInstance<T = any>(): ScriptConfigInstance<T> {\r\n if (!_instance) throw new Error(\"[dirk-cfx-react] createScriptConfig must be called before using ConfigPanel\");\r\n return _instance as ScriptConfigInstance<T>;\r\n}\r\n\r\nexport function createScriptConfig<T>(defaultValue: T) {\r\n const store = create<T>(() => defaultValue);\r\n let clientVersion = 0;\r\n\r\n const useScriptConfigHooks = () => {\r\n useNuiEvent<{ config?: Partial<T>; clientVersion?: number; sectionReplace?: boolean }>(\r\n \"UPDATE_SCRIPT_CONFIG\",\r\n (data) => {\r\n if (!data) return;\r\n\r\n if (typeof data.clientVersion === \"number\") {\r\n clientVersion = data.clientVersion as number;\r\n }\r\n\r\n if (data.config && typeof data.config === \"object\") {\r\n // Both apply modes use the same top-level merge-by-replace:\r\n // - sectionReplace: `config` holds only the changed sections; spreading\r\n // them over `prev` wholesale-overwrites those keys and leaves every\r\n // other (unsent) section exactly as-is. We MUST NOT full-replace here\r\n // or the unsent sections would vanish from the UI.\r\n // - fullReplace / merge / initial: `config` holds the FULL config, so\r\n // the same spread effectively replaces every key.\r\n store.setState((prev) => ({ ...prev, ...(data.config as Partial<T>) }));\r\n }\r\n }\r\n );\r\n };\r\n\r\n const fetchScriptConfig = async (): Promise<T | null> => {\r\n try {\r\n const response = await fetchNui<{\r\n success: boolean;\r\n data?: { config: T; clientVersion: number };\r\n }>(\"GET_FULL_SCRIPT_CONFIG\");\r\n\r\n if (response?.success && response.data?.config) {\r\n store.setState(() => response.data!.config as T);\r\n if (typeof response.data.clientVersion === \"number\") {\r\n clientVersion = response.data.clientVersion;\r\n }\r\n return response.data.config;\r\n }\r\n } catch { /* fallback to current store state */ }\r\n return null;\r\n };\r\n\r\n // Option B top-up. Called ONLY by the admin editor on panel open. The\r\n // baseline (client-visible config) is already in the store — pushed by Lua\r\n // via UPDATE_SCRIPT_CONFIG (handled in useScriptConfigHooks above) and cached\r\n // in KVP on the Lua side. Here we fetch ONLY the server-only sliver\r\n // (permission-gated server-side on canEditScript) and DEEP-MERGE it onto that\r\n // baseline to form the full editor view. We deliberately do NOT spread-replace\r\n // (as fetchScriptConfig does) — that would clobber sibling client-visible keys\r\n // under a shared parent section.\r\n //\r\n // SECURITY: this sliver is admin-only and in-memory only. It is NEVER written\r\n // to KVP or any cache; it is re-fetched fresh on every panel open.\r\n const fetchServerOnlyScriptConfig = async (): Promise<T | null> => {\r\n try {\r\n const response = await fetchNui<ServerOnlyScriptConfigResponse<T>>(\r\n \"GET_SERVER_ONLY_SCRIPT_CONFIG\"\r\n );\r\n\r\n if (response?.success && response.data) {\r\n // clientVersion here matches the value already in the store from the\r\n // Lua push; keep it in sync (safe no-op if identical).\r\n if (typeof response.data.clientVersion === \"number\") {\r\n clientVersion = response.data.clientVersion;\r\n }\r\n const sliver = response.data.serverOnly;\r\n // An empty sliver ({} — schema declares no server-only paths) is a valid\r\n // no-op merge: deepMerge returns the baseline unchanged.\r\n const merged = deepMerge(store.getState() as T, (sliver ?? {}) as Partial<T>);\r\n store.setState(() => merged as T);\r\n return merged;\r\n }\r\n } catch { /* fall back to the client-visible baseline already in the store */ }\r\n return null;\r\n };\r\n\r\n // `changedFields` is the useForm tracked changed-set (dotted paths). When\r\n // supplied AND it resolves to ≥1 top-level section, we send a SECTION-DELTA:\r\n // only the changed sections, each as its WHOLE current value, with\r\n // sectionReplace:true. The server/client then overwrite those keys wholesale\r\n // (which is what lets deletions inside a section propagate). When omitted or\r\n // empty, we fall back to the legacy full-send (server defaults to\r\n // fullReplace=true when no `sectionReplace` flag is present).\r\n const updateScriptConfig = async (\r\n newConfig: Partial<T>,\r\n changedFields?: readonly string[]\r\n ): Promise<NuiResponse<T>> => {\r\n store.setState((prev) => ({ ...prev, ...newConfig }));\r\n\r\n const sections = changedTopLevelSections(changedFields);\r\n\r\n let payload: { data: Partial<T>; expectedVersion: number; sectionReplace?: boolean };\r\n if (sections.length > 0) {\r\n // Section-delta: flat object keyed by top-level section name → whole\r\n // current section value (pulled from the just-applied store state so it\r\n // reflects the user's edits, including deletions).\r\n const current = store.getState() as Record<string, unknown>;\r\n const delta: Record<string, unknown> = {};\r\n for (const key of sections) delta[key] = current[key];\r\n payload = { data: delta as Partial<T>, expectedVersion: clientVersion, sectionReplace: true };\r\n } else {\r\n // No changed-set provided (or nothing resolved) but the user explicitly\r\n // saved → legacy full-send. No sectionReplace flag ⇒ server fullReplace.\r\n payload = { data: newConfig, expectedVersion: clientVersion };\r\n }\r\n\r\n const response = await fetchNui<NuiResponse<T>>(\"UPDATE_SCRIPT_CONFIG\", payload);\r\n\r\n if (response?.meta?.client_version != null) {\r\n clientVersion = response.meta.client_version as number;\r\n }\r\n\r\n if (response?.success === false && response?.meta?.latestData) {\r\n store.setState((prev) => ({ ...prev, ...(response.meta!.latestData as Partial<T>) }));\r\n }\r\n\r\n return response;\r\n };\r\n\r\n const getScriptConfigHistory = async (\r\n params: ScriptConfigHistoryRequest = {}\r\n ): Promise<ScriptConfigHistoryResponse> => {\r\n return fetchNui<ScriptConfigHistoryResponse>('GET_SCRIPT_CONFIG_HISTORY', params);\r\n };\r\n\r\n const resetConfig = async (): Promise<{ success: boolean; _error?: string }> => {\r\n const response = await fetchNui<{ success: boolean; _error?: string }>('RESET_SCRIPT_CONFIG');\r\n if (response?.success) {\r\n // Option B: after a reset the server restores defaults and broadcasts a\r\n // fresh client-visible UPDATE_SCRIPT_CONFIG push (handled in\r\n // useScriptConfigHooks → store baseline). We only need to re-merge the\r\n // server-only sliver onto that refreshed baseline to rebuild the full\r\n // editor view — no GET_FULL_SCRIPT_CONFIG round-trip. fetchServerOnly\r\n // merges onto whatever client-visible baseline is currently in the store,\r\n // so it's safe regardless of broadcast/callback ordering.\r\n await fetchServerOnlyScriptConfig();\r\n }\r\n return response;\r\n };\r\n\r\n _instance = {\r\n store,\r\n updateConfig: updateScriptConfig,\r\n resetConfig,\r\n getHistory: getScriptConfigHistory,\r\n fetchConfig: fetchScriptConfig,\r\n fetchServerOnly: fetchServerOnlyScriptConfig,\r\n };\r\n\r\n return {store, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig, fetchServerOnlyScriptConfig}\r\n}\r\n","// Validates a list of GTA / RDR model names against the client's CD-image\r\n// via dirk_lib's adminTool.validateModels Lua tool. Returns a Set of names\r\n// that DO resolve to a streamable model — useful for greying out admin-\r\n// panel rows that reference props/shells/peds that aren't installed.\r\n//\r\n// Batches: pass the full list each render; the hook diffs against what's\r\n// already been resolved and only asks Lua for the new names. Once a name\r\n// has been checked, subsequent renders with the same name return the\r\n// cached result instantly.\r\n//\r\n// Result is a stable Set reference per resolution wave so callers can use\r\n// it as a useMemo / useEffect dep without thrashing.\r\n//\r\n// Usage:\r\n// const valid = useValidModels(shells.map(s => s.model));\r\n// shells.map(s => <Row dimmed={!valid.has(s.model)} ... />)\r\n//\r\n// Only meaningful inside an open admin panel (the underlying NUI callback\r\n// is gated on scriptConfig being open). Outside that window the hook just\r\n// returns an empty Set.\r\nimport { useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { fetchNui } from \"../utils/fetchNui\";\r\n\r\nconst moduleCache = new Map<string, boolean>();\r\n\r\nexport function useValidModels(names: string[]): Set<string> {\r\n // Stable string key for the input list so the effect doesn't re-fire on\r\n // every render. Sort + join keeps the dep change-detection cheap.\r\n const cacheKey = useMemo(() => {\r\n const unique = Array.from(new Set(names.filter(n => typeof n === \"string\" && n.length > 0)));\r\n unique.sort();\r\n return unique.join(\"|\");\r\n }, [names]);\r\n\r\n // Bump on every new validation result so memoised consumers re-derive.\r\n const [version, setVersion] = useState(0);\r\n const inflight = useRef<Set<string>>(new Set());\r\n\r\n useEffect(() => {\r\n if (!cacheKey) return;\r\n const all = cacheKey.split(\"|\").filter(Boolean);\r\n const missing = all.filter(n => !moduleCache.has(n) && !inflight.current.has(n));\r\n if (missing.length === 0) return;\r\n\r\n missing.forEach(n => inflight.current.add(n));\r\n let cancelled = false;\r\n\r\n fetchNui<Record<string, boolean> | null>(\r\n \"ADMIN_TOOL_QUERY\",\r\n { id: \"validateModels\", value: missing },\r\n // Fallback when running outside FiveM (browser dev) — assume valid so the\r\n // dev shell doesn't grey out every row.\r\n Object.fromEntries(missing.map(n => [n, true])),\r\n )\r\n .then(result => {\r\n if (cancelled) return;\r\n const map = result && typeof result === \"object\" ? result : {};\r\n missing.forEach(n => {\r\n moduleCache.set(n, !!map[n]);\r\n inflight.current.delete(n);\r\n });\r\n setVersion(v => v + 1);\r\n })\r\n .catch(() => {\r\n if (cancelled) return;\r\n // On failure, mark them as valid by default so a transient NUI hiccup\r\n // doesn't dim every row of the panel. Lua side will be re-asked next\r\n // time the deps change.\r\n missing.forEach(n => {\r\n inflight.current.delete(n);\r\n });\r\n });\r\n\r\n return () => {\r\n cancelled = true;\r\n };\r\n }, [cacheKey]);\r\n\r\n return useMemo(() => {\r\n const out = new Set<string>();\r\n if (!cacheKey) return out;\r\n for (const n of cacheKey.split(\"|\")) {\r\n if (n && moduleCache.get(n) === true) out.add(n);\r\n }\r\n return out;\r\n // version bumps cause re-derivation once the async cache fills in.\r\n }, [cacheKey, version]);\r\n}\r\n","// Drop-in replacement for React's useState that survives unmount/remount.\r\n//\r\n// Why: ConfigPanel returns null when closed, which tears down the entire\r\n// React tree under it. Local component state (active tab, current edit\r\n// target, search text, view-mode toggles, etc.) is lost. Admins who close\r\n// and reopen the panel land back at the default state every time.\r\n//\r\n// useAdminState writes to a module-scope store keyed by an arbitrary\r\n// string. The store survives close/reopen because the NUI iframe stays\r\n// alive across SetNuiFocus toggles — only React unmounts.\r\n//\r\n// Reset scope: keys live for the lifetime of the iframe (= until the\r\n// resource restarts or the player reloads the NUI). That's exactly what\r\n// admins want — \"remember where I was in this session, but don't carry\r\n// over after a restart\".\r\n//\r\n// Usage:\r\n// const [activeTab, setActiveTab] = useAdminState(\"labs:viewMode\", \"list\");\r\n//\r\n// Key collisions: state is scoped per dirk-cfx-react module-scope, which\r\n// is per-iframe — so two different consumer resources can both use the key\r\n// \"viewMode\" without colliding. Within a single consumer, keep keys unique\r\n// (prefix with section name: \"labs:viewMode\", \"shells:editingId\" etc).\r\n\r\nimport { useEffect, useState } from \"react\";\r\n\r\ntype Listener = () => void;\r\n\r\nconst store: Map<string, unknown> = new Map();\r\nconst listeners: Map<string, Set<Listener>> = new Map();\r\n\r\nfunction notify(key: string) {\r\n const ls = listeners.get(key);\r\n if (!ls) return;\r\n ls.forEach((fn) => fn());\r\n}\r\n\r\n/**\r\n * Like `useState` but the value persists in a module-scope store across\r\n * unmount/remount cycles. Identical API otherwise.\r\n *\r\n * @param key Stable string identifying this slot. Must be unique per\r\n * intended slot within the consumer's iframe.\r\n * @param initial Initial value if no value has been stored under `key` yet.\r\n */\r\nexport function useAdminState<T>(key: string, initial: T): [T, (v: T | ((prev: T) => T)) => void] {\r\n // useState here is just for triggering re-renders on cross-component\r\n // updates. The real value lives in the module-scope `store`.\r\n const [, setTick] = useState(0);\r\n\r\n useEffect(() => {\r\n const set = listeners.get(key) ?? new Set<Listener>();\r\n listeners.set(key, set);\r\n const handler = () => setTick((t) => t + 1);\r\n set.add(handler);\r\n return () => {\r\n set.delete(handler);\r\n if (set.size === 0) listeners.delete(key);\r\n };\r\n }, [key]);\r\n\r\n const value = (store.has(key) ? store.get(key) : initial) as T;\r\n\r\n const setValue = (v: T | ((prev: T) => T)) => {\r\n const next = typeof v === \"function\" ? (v as (p: T) => T)(value) : v;\r\n store.set(key, next);\r\n notify(key);\r\n };\r\n\r\n return [value, setValue];\r\n}\r\n\r\n/** Imperative clear — useful for \"reset everything\" admin actions. */\r\nexport function clearAdminState(key?: string) {\r\n if (key) {\r\n store.delete(key);\r\n notify(key);\r\n } else {\r\n const keys = Array.from(store.keys());\r\n store.clear();\r\n keys.forEach(notify);\r\n }\r\n}\r\n","// Fetches normalised player lists from dirk_lib's admin tool subsystem.\r\n//\r\n// Two modes, controlled by `includeOffline`:\r\n// • false (default) → online-only. Fast, cheap, refreshed every ~5s.\r\n// • true → DB-backed search across online + offline players.\r\n// Filtered server-side by `search`. Cap of 50.\r\n//\r\n// Caching: react-query handles dedupe + stale-while-revalidate, keyed on\r\n// (mode, search, limit). Multiple <PlayerSelect>s on screen share one\r\n// fetch. Typing \"j\" → \"jo\" → \"joh\" creates separate cache entries — each\r\n// stays cached for 5 minutes (gcTime) so re-typing reuses instantly.\r\n//\r\n// Admin gating: lives behind the ADMIN_TOOL_QUERY perm check on the\r\n// server. Outside an open admin panel, fetches return empty arrays.\r\n\r\nimport { useQuery, keepPreviousData } from \"@tanstack/react-query\";\r\nimport { fetchNui } from \"../utils/fetchNui\";\r\n\r\nexport type Player = {\r\n /** Server id when online, null when offline. */\r\n id: number | null;\r\n /** Persistent identifier — citizenid (qb/qbx) or license (esx). */\r\n citizenId: string;\r\n /** Steam/Discord display name from GetPlayerName(src). Blank for some\r\n * framework + offline combos (ESX users table doesn't store it). */\r\n name: string;\r\n /** First name + last name from the framework's character data. */\r\n charName: string;\r\n online: boolean;\r\n};\r\n\r\nexport type UsePlayersOptions = {\r\n /** When true, hits the DB and returns offline + online matches.\r\n * When false (default), returns only currently-connected players. */\r\n includeOffline?: boolean;\r\n /** Required when includeOffline=true; ignored otherwise. Server-side\r\n * filtered (LIKE) across char name, citizenId, account name. */\r\n search?: string;\r\n /** Default 50, max 50 (capped server-side). */\r\n limit?: number;\r\n /** Override staleTime — how long the cache stays fresh before background\r\n * refetch. Default 5s for online, 30s for search. */\r\n staleTimeMs?: number;\r\n /** Set to e.g. 10000 to auto-refresh every 10s. Off by default. */\r\n refetchIntervalMs?: number;\r\n};\r\n\r\nexport type UsePlayersResult = {\r\n players: Player[];\r\n isLoading: boolean;\r\n isFetching: boolean;\r\n error: Error | null;\r\n refresh: () => void;\r\n};\r\n\r\nexport function usePlayers(opts: UsePlayersOptions = {}): UsePlayersResult {\r\n const {\r\n includeOffline = false,\r\n search = \"\",\r\n limit = 50,\r\n staleTimeMs,\r\n refetchIntervalMs,\r\n } = opts;\r\n\r\n const query = useQuery<Player[]>({\r\n queryKey: includeOffline\r\n ? [\"dirk:players\", \"search\", search.trim().toLowerCase(), limit]\r\n : [\"dirk:players\", \"online\"],\r\n queryFn: async () => {\r\n const toolId = includeOffline ? \"searchPlayers\" : \"getOnlinePlayers\";\r\n const payload = includeOffline\r\n ? { id: toolId, value: { search: search.trim(), limit } }\r\n : { id: toolId };\r\n const result = await fetchNui<Player[] | null>(\r\n \"ADMIN_TOOL_QUERY\",\r\n payload,\r\n // Browser-dev fallback. Returns a couple of mock players so the\r\n // dev shell isn't blank.\r\n includeOffline\r\n ? [\r\n { id: 1, citizenId: \"ABC12345\", name: \"Dev User\", charName: \"John Doe\", online: true },\r\n { id: null, citizenId: \"DEF67890\", name: \"\", charName: \"Jane Offline\", online: false },\r\n ]\r\n : [\r\n { id: 1, citizenId: \"ABC12345\", name: \"Dev User\", charName: \"John Doe\", online: true },\r\n ],\r\n );\r\n return Array.isArray(result) ? result : [];\r\n },\r\n staleTime: staleTimeMs ?? (includeOffline ? 30_000 : 5_000),\r\n gcTime: 5 * 60_000,\r\n refetchInterval: refetchIntervalMs ?? false,\r\n refetchOnWindowFocus: false,\r\n placeholderData: includeOffline ? keepPreviousData : undefined,\r\n });\r\n\r\n return {\r\n players: query.data ?? [],\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: (query.error as Error | null) ?? null,\r\n refresh: () => query.refetch(),\r\n };\r\n}\r\n"]}
package/dist/index.cjs CHANGED
@@ -4687,6 +4687,21 @@ function mergeMantineThemeSafe(base, custom, override) {
4687
4687
  }
4688
4688
  };
4689
4689
  }
4690
+ function isPlainObject2(v) {
4691
+ return typeof v === "object" && v !== null && !Array.isArray(v);
4692
+ }
4693
+ function deepMerge(base, patch) {
4694
+ if (!isPlainObject2(base) || !isPlainObject2(patch)) {
4695
+ return patch ?? base;
4696
+ }
4697
+ const out = { ...base };
4698
+ for (const key of Object.keys(patch)) {
4699
+ const patchVal = patch[key];
4700
+ const baseVal = out[key];
4701
+ out[key] = isPlainObject2(baseVal) && isPlainObject2(patchVal) ? deepMerge(baseVal, patchVal) : patchVal;
4702
+ }
4703
+ return out;
4704
+ }
4690
4705
  function changedTopLevelSections(changedFields) {
4691
4706
  if (!changedFields || changedFields.length === 0) return [];
4692
4707
  const sections = /* @__PURE__ */ new Set();
@@ -4733,6 +4748,24 @@ function createScriptConfig(defaultValue) {
4733
4748
  }
4734
4749
  return null;
4735
4750
  };
4751
+ const fetchServerOnlyScriptConfig = async () => {
4752
+ try {
4753
+ const response = await fetchNui(
4754
+ "GET_SERVER_ONLY_SCRIPT_CONFIG"
4755
+ );
4756
+ if (response?.success && response.data) {
4757
+ if (typeof response.data.clientVersion === "number") {
4758
+ clientVersion = response.data.clientVersion;
4759
+ }
4760
+ const sliver = response.data.serverOnly;
4761
+ const merged = deepMerge(store2.getState(), sliver ?? {});
4762
+ store2.setState(() => merged);
4763
+ return merged;
4764
+ }
4765
+ } catch {
4766
+ }
4767
+ return null;
4768
+ };
4736
4769
  const updateScriptConfig = async (newConfig, changedFields) => {
4737
4770
  store2.setState((prev) => ({ ...prev, ...newConfig }));
4738
4771
  const sections = changedTopLevelSections(changedFields);
@@ -4760,10 +4793,7 @@ function createScriptConfig(defaultValue) {
4760
4793
  const resetConfig = async () => {
4761
4794
  const response = await fetchNui("RESET_SCRIPT_CONFIG");
4762
4795
  if (response?.success) {
4763
- const fresh = await fetchScriptConfig();
4764
- if (fresh) {
4765
- store2.setState(() => fresh);
4766
- }
4796
+ await fetchServerOnlyScriptConfig();
4767
4797
  }
4768
4798
  return response;
4769
4799
  };
@@ -4772,9 +4802,10 @@ function createScriptConfig(defaultValue) {
4772
4802
  updateConfig: updateScriptConfig,
4773
4803
  resetConfig,
4774
4804
  getHistory: getScriptConfigHistory,
4775
- fetchConfig: fetchScriptConfig
4805
+ fetchConfig: fetchScriptConfig,
4806
+ fetchServerOnly: fetchServerOnlyScriptConfig
4776
4807
  };
4777
- return { store: store2, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig };
4808
+ return { store: store2, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig, fetchServerOnlyScriptConfig };
4778
4809
  }
4779
4810
  var DirkErrorBoundary = class extends React4__default.default.Component {
4780
4811
  constructor() {
@@ -4961,12 +4992,6 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
4961
4992
  setScTheme(s?.theme ?? null);
4962
4993
  });
4963
4994
  }
4964
- inst.fetchConfig?.().then((full) => {
4965
- if (full && typeof full === "object") {
4966
- setScTheme(full.theme ?? null);
4967
- }
4968
- }).catch(() => {
4969
- });
4970
4995
  } catch {
4971
4996
  }
4972
4997
  return () => {
@@ -5586,11 +5611,11 @@ function cloneConfig(value) {
5586
5611
  return JSON.parse(JSON.stringify(value));
5587
5612
  }
5588
5613
  function ServerOnlyFetcher() {
5589
- const { fetchConfig } = getScriptConfigInstance();
5614
+ const { fetchServerOnly } = getScriptConfigInstance();
5590
5615
  const { reinitialize } = useFormActions();
5591
5616
  React4.useEffect(() => {
5592
5617
  let cancelled = false;
5593
- fetchConfig().then((full) => {
5618
+ fetchServerOnly().then((full) => {
5594
5619
  if (!cancelled && full) reinitialize(full);
5595
5620
  }).catch(() => {
5596
5621
  });