From 538714acdb95965f9cf6ae9dc30d46761a11f690 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Tue, 19 May 2026 22:23:30 +0100 Subject: [PATCH 01/12] Remove existing plugin --- exp_groups/controller.ts | 282 ---------------------- exp_groups/index.ts | 84 ------- exp_groups/instance.ts | 129 ---------- exp_groups/messages.ts | 239 ------------------ exp_groups/module/control.lua | 127 ---------- exp_groups/module/module.json | 12 - exp_groups/module/module_exports.lua | 306 ------------------------ exp_groups/package.json | 41 ---- exp_groups/tsconfig.browser.json | 4 - exp_groups/tsconfig.json | 7 - exp_groups/tsconfig.node.json | 5 - exp_groups/web/components/groupTree.tsx | 129 ---------- exp_groups/web/index.tsx | 82 ------- exp_groups/webpack.config.js | 32 --- 14 files changed, 1479 deletions(-) delete mode 100644 exp_groups/controller.ts delete mode 100644 exp_groups/index.ts delete mode 100644 exp_groups/instance.ts delete mode 100644 exp_groups/messages.ts delete mode 100644 exp_groups/module/control.lua delete mode 100644 exp_groups/module/module.json delete mode 100644 exp_groups/module/module_exports.lua delete mode 100644 exp_groups/package.json delete mode 100644 exp_groups/tsconfig.browser.json delete mode 100644 exp_groups/tsconfig.json delete mode 100644 exp_groups/tsconfig.node.json delete mode 100644 exp_groups/web/components/groupTree.tsx delete mode 100644 exp_groups/web/index.tsx delete mode 100644 exp_groups/webpack.config.js diff --git a/exp_groups/controller.ts b/exp_groups/controller.ts deleted file mode 100644 index dde5515c8b..0000000000 --- a/exp_groups/controller.ts +++ /dev/null @@ -1,282 +0,0 @@ -import * as lib from "@clusterio/lib"; -import { BaseControllerPlugin, InstanceInfo } from "@clusterio/controller"; - -import { - PermissionStrings, PermissionStringsUpdate, - PermissionGroup, PermissionGroupUpdate, - InstancePermissionGroups, - PermissionInstanceId, - PermissionGroupEditEvent, -} from "./messages"; - -import path from "path"; -import fs from "fs-extra"; - -export class ControllerPlugin extends BaseControllerPlugin { - static permissionGroupsPath = "exp_groups.json"; - static userGroupsPath = "exp_user_groups.json"; - - userToGroup: Map = new Map(); // TODO this needs to be per instance - permissionStrings!: Map; - permissionGroups!: Map; - - async init() { - this.controller.handle(PermissionStringsUpdate, this.handlePermissionStringsUpdate.bind(this)); - this.controller.handle(PermissionGroupUpdate, this.handlePermissionGroupUpdate.bind(this)); - this.controller.handle(PermissionGroupEditEvent, this.handlePermissionGroupEditEvent.bind(this)); - this.controller.subscriptions.handle(PermissionStringsUpdate, this.handlePermissionStringsSubscription.bind(this)); - this.controller.subscriptions.handle(PermissionGroupUpdate, this.handlePermissionGroupSubscription.bind(this)); - this.controller.subscriptions.handle(PermissionGroupEditEvent); - this.permissionStrings = new Map([["Global", new PermissionStrings("Global", new Set())]]); - this.permissionGroups = new Map([["Global", new InstancePermissionGroups("Global")]]); - await this.loadData(); - - // Add the default group if missing and add any missing cluster roles - const clusterRoles = [...this.controller.userManager.roles.values()] - for (const instanceGroups of this.permissionGroups.values()) { - const groups = instanceGroups.groups; - const instanceRoles = [...groups.values()].flatMap(group => [...group.roleIds.values()]); - const missingRoles = clusterRoles.filter(role => instanceRoles.includes(role.id)); - const defaultGroup = groups.get("Default"); - if (defaultGroup) { - for (const role of missingRoles) { - defaultGroup.roleIds.add(role.id) - } - } else { - groups.set("Default", new PermissionGroup( - instanceGroups.instanceId, - "Default", - groups.size, - new Set(missingRoles.map(role => role.id)) - )); - } - } - } - - async onControllerConfigFieldChanged(field: string, curr: unknown, prev: unknown) { - if (field === "exp_groups.allow_role_inconsistency") { - // Do something with this.userToGroup - } - } - - async onInstanceConfigFieldChanged(instance: InstanceInfo, field: string, curr: unknown, prev: unknown) { - this.logger.info(`controller::onInstanceConfigFieldChanged ${instance.id} ${field}`); - if (field === "exp_groups.sync_permission_groups") { - const updates = [] - const now = Date.now(); - if (curr) { - // Global sync enabled, we dont need the instance config - const instanceGroups = this.permissionGroups.get(instance.id); - if (instanceGroups) { - this.permissionGroups.delete(instance.id); - for (const group of instanceGroups.groups.values()) { - group.updatedAtMs = now; - group.isDeleted = true; - updates.push(group); - } - } - } else { - // Global sync disabled, make a copy of the global config as a base - const global = this.permissionGroups.get("Global")!; - const oldInstanceGroups = this.permissionGroups.get(instance.id); - const instanceGroups = new InstancePermissionGroups( - instance.id, new Map([...global.groups.values()].map(group => [group.name, group.copy(instance.id)])) - ) - this.permissionGroups.set(instance.id, instanceGroups); - for (const group of instanceGroups.groups.values()) { - group.updatedAtMs = now; - updates.push(group); - } - // If it has an old config (unexpected) then deal with it - if (oldInstanceGroups) { - for (const group of oldInstanceGroups.groups.values()) { - if (!instanceGroups.groups.has(group.name)) { - group.updatedAtMs = now; - group.isDeleted = true; - updates.push(group); - } - } - } - } - // Send the updates to all instances and controls - if (updates.length) { - this.controller.subscriptions.broadcast(new PermissionGroupUpdate(updates)); - } - } - } - - async loadPermissionGroups() { - const file = path.resolve(this.controller.config.get("controller.database_directory"), ControllerPlugin.permissionGroupsPath); - this.logger.verbose(`Loading ${file}`); - try { - const content = await fs.readFile(file, { encoding: "utf8" }); - for (const groupRaw of JSON.parse(content)) { - const group = PermissionGroup.fromJSON(groupRaw); - const instanceGroups = this.permissionGroups.get(group.instanceId); - if (instanceGroups) { - instanceGroups.groups.set(group.name, group); - } else { - this.permissionGroups.set(group.instanceId, - new InstancePermissionGroups(group.instanceId, new Map([[group.name, group]])) - ); - } - }; - - } catch (err: any) { - if (err.code === "ENOENT") { - this.logger.verbose("Creating new permission group database"); - return; - } - throw err; - } - } - - async savePermissionGroups() { - const file = path.resolve(this.controller.config.get("controller.database_directory"), ControllerPlugin.permissionGroupsPath); - this.logger.verbose(`Writing ${file}`); - await lib.safeOutputFile(file, JSON.stringify( - [...this.permissionGroups.values()].flatMap(instanceGroups => [...instanceGroups.groups.values()]) - )); - } - - async loadUserGroups() { - if (!this.controller.config.get("exp_groups.allow_role_inconsistency")) return; - const file = path.resolve(this.controller.config.get("controller.database_directory"), ControllerPlugin.userGroupsPath); - this.logger.verbose(`Loading ${file}`); - try { - const content = await fs.readFile(file, { encoding: "utf8" }); - this.userToGroup = new Map(JSON.parse(content)); - - } catch (err: any) { - if (err.code === "ENOENT") { - this.logger.verbose("Creating new user group database"); - return; - } - throw err; - } - } - - async saveUserGroups() { - if (!this.controller.config.get("exp_groups.allow_role_inconsistency")) return; - const file = path.resolve(this.controller.config.get("controller.database_directory"), ControllerPlugin.userGroupsPath); - this.logger.verbose(`Writing ${file}`); - await lib.safeOutputFile(file, JSON.stringify([...this.permissionGroups.entries()])); - } - - async loadData() { - await Promise.all([ - this.loadPermissionGroups(), - this.loadUserGroups(), - ]) - } - - async onSaveData() { - await Promise.all([ - this.savePermissionGroups(), - this.saveUserGroups(), - ]) - } - - addPermisisonGroup(instanceId: PermissionInstanceId, name: string, permissions = new Set(), silent = false) { - const instanceGroups = this.permissionGroups.get(instanceId); - if (!instanceGroups) { - throw new Error("Instance ID does not exist"); - } - if (instanceGroups.groups.has(name)) { - return instanceGroups.groups.get(name)!; - } - for (const group of instanceGroups.groups.values()) { - group.order += 1; - } - const group = new PermissionGroup(instanceId, name, 0, new Set(), permissions, Date.now(), false); - instanceGroups.groups.set(group.id, group); - if (!silent) { - this.controller.subscriptions.broadcast(new PermissionGroupUpdate([group])); - } - return group; - } - - removePermissionGroup(instanceId: PermissionInstanceId, name: string, silent = false) { - const instanceGroups = this.permissionGroups.get(instanceId); - if (!instanceGroups) { - throw new Error("Instance ID does not exist"); - } - const group = instanceGroups.groups.get(name) - if (!group) { - return null; - } - for (const nextGroup of instanceGroups.groups.values()) { - if (nextGroup.order > group.order) { - nextGroup.order -= 1; - } - } - instanceGroups.groups.delete(group.id); - group.updatedAtMs = Date.now(); - group.isDeleted = true; - if (!silent) { - this.controller.subscriptions.broadcast(new PermissionGroupUpdate([group])); - } - return group; - } - - async handlePermissionGroupEditEvent(event: PermissionGroupEditEvent) { - // TODO - } - - async handlePermissionStringsUpdate(event: PermissionStringsUpdate) { - for (const update of event.updates) { - const global = this.permissionStrings.get("Global")! - this.permissionStrings.set(update.instanceId as number, update) - global.updatedAtMs = Math.max(global.updatedAtMs, update.updatedAtMs) - for (const permission of update.permissions) { - global.permissions.add(permission) - } - // TODO maybe check if changes have happened rather than always pushing updates - this.controller.subscriptions.broadcast(new PermissionStringsUpdate([global, update])) - } - } - - async handlePermissionGroupUpdate(event: PermissionGroupUpdate) { - const updates = []; - for (const group of event.updates) { - const groups = this.permissionGroups.get(group.instanceId); - if (!groups) continue; - const existingGroup = groups.groups.get(group.id); - let update - if (!existingGroup) { - update = this.addPermisisonGroup(group.instanceId, group.name, group.permissions, true); - } else if (group.isDeleted) { - update = this.removePermissionGroup(group.instanceId, group.name, true); - } else { - existingGroup.permissions = group.permissions; - existingGroup.updatedAtMs = Date.now(); - update = existingGroup; - } - if (update) updates.push(update); - } - this.controller.subscriptions.broadcast(new PermissionGroupUpdate(updates)); - } - - async handlePermissionStringsSubscription(request: lib.SubscriptionRequest, src: lib.Address) { - const updates = [ ...this.permissionStrings.values() ] - .filter( - value => value.updatedAtMs > request.lastRequestTimeMs, - ) - return updates.length ? new PermissionStringsUpdate(updates) : null; - } - - async handlePermissionGroupSubscription(request: lib.SubscriptionRequest, src: lib.Address) { - const updates = [ ...this.permissionGroups.values() ] - .flatMap(instanceGroups => [...instanceGroups.groups.values()]) - .filter( - value => value.updatedAtMs > request.lastRequestTimeMs, - ) - if (src.type === lib.Address.instance) { - const instanceUpdates = updates.filter(group => group.instanceId === src.id || group.instanceId === "Global"); - this.logger.info(JSON.stringify(updates)) - this.logger.info(JSON.stringify(instanceUpdates)) - return instanceUpdates.length ? new PermissionGroupUpdate(instanceUpdates) : null; - } - return updates.length ? new PermissionGroupUpdate(updates) : null; - } -} diff --git a/exp_groups/index.ts b/exp_groups/index.ts deleted file mode 100644 index f5e272b352..0000000000 --- a/exp_groups/index.ts +++ /dev/null @@ -1,84 +0,0 @@ -import * as lib from "@clusterio/lib"; -import * as Messages from "./messages"; - -lib.definePermission({ - name: "exp_groups.create_delete_groups", - title: "Create and delete permission groups", - description: "Create and delete permission groups.", -}); - -lib.definePermission({ - name: "exp_groups.reorder_groups", - title: "Reorder permission groups", - description: "Reorder groups and link them to user roles.", -}); - -lib.definePermission({ - name: "exp_groups.modify_permissions", - title: "Modify permission groups", - description: "Modify game permissions for groups.", -}); - -lib.definePermission({ - name: "exp_groups.assign_players", - title: "Change player group", - description: "Change the permission group of a player", -}); - -lib.definePermission({ - name: "exp_groups.list", - title: "View permission groups", - description: "View permission groups.", -}); - -lib.definePermission({ - name: "exp_groups.list.subscribe", - title: "Subscribe to permission group updates", - description: "Subscribe to permission group updates.", -}); - -declare module "@clusterio/lib" { - export interface ControllerConfigFields { - "exp_groups.allow_role_inconsistency": boolean; - } - export interface InstanceConfigFields { - "exp_groups.sync_permission_groups": boolean; - } -} - -export const plugin: lib.PluginDeclaration = { - name: "exp_groups", - title: "exp_groups", - description: "Create, modify, and link factorio permission groups to clusterio user roles.", - - controllerEntrypoint: "./dist/node/controller", - controllerConfigFields: { - "exp_groups.allow_role_inconsistency": { - title: "Allow User Role Inconsistency", - description: "When true, users can be assgined to any group regardless of their roles", - type: "boolean", - initialValue: false, - }, - }, - - instanceEntrypoint: "./dist/node/instance", - instanceConfigFields: { - "exp_groups.sync_permission_groups": { - title: "Sync Permission Groups", - description: "When true, the instance cannot deviate from the global group settings and will be hidden from the sellection dropdown.", - type: "boolean", - initialValue: true, - }, - }, - - messages: [ - Messages.PermissionGroupEditEvent, - Messages.PermissionStringsUpdate, - Messages.PermissionGroupUpdate, - ], - - webEntrypoint: "./web", - routes: [ - "/exp_groups", - ], -}; diff --git a/exp_groups/instance.ts b/exp_groups/instance.ts deleted file mode 100644 index 5142d933c3..0000000000 --- a/exp_groups/instance.ts +++ /dev/null @@ -1,129 +0,0 @@ -import * as lib from "@clusterio/lib"; -import { BaseInstancePlugin } from "@clusterio/host"; -import { - PermissionGroup, PermissionGroupEditEvent, PermissionGroupEditType, - PermissionGroupUpdate, PermissionInstanceId, PermissionStrings, PermissionStringsUpdate -} from "./messages"; - -const rconBase = "/sc local Groups = package.loaded['modules/exp_groups/module_exports'];" - -type EditIPC = { - type: PermissionGroupEditType, - changes: string[], - group: string, -}; - -type CreateIPC = { - group: string, - defiantion: [boolean, string[] | {}] -} - -type DeleteIPC = { - group: string, -} - -export class InstancePlugin extends BaseInstancePlugin { - permissions: Set = new Set(); - permissionGroups = new lib.EventSubscriber(PermissionGroupUpdate, this.instance); - permissionGroupUpdates = new lib.EventSubscriber(PermissionGroupEditEvent, this.instance); - syncId: PermissionInstanceId = this.instance.config.get("exp_groups.sync_permission_groups") ? "Global" : this.instance.id; - - async init() { - this.instance.server.handle("exp_groups-permission_group_edit", this.handleEditIPC.bind(this)); - this.instance.server.handle("exp_groups-permission_group_create", this.handleCreateIPC.bind(this)); - this.instance.server.handle("exp_groups-permission_group_delete", this.handleDeleteIPC.bind(this)); - } - - async onStart() { - // Send the most recent version of the permission string - const permissionsString = await this.sendRcon(rconBase + "rcon.print(Groups.get_actions_json())"); - this.permissions = new Set(JSON.parse(permissionsString)); - this.instance.sendTo("controller", new PermissionStringsUpdate([ - new PermissionStrings(this.instance.id, this.permissions, Date.now()) - ])); - - // Subscribe to get updates for permission groups - this.permissionGroups.subscribe(this.onPermissionGroupsUpdate.bind(this)); - this.permissionGroupUpdates.subscribe(this.onPermissionGroupUpdate.bind(this)); - } - - async onControllerConnectionEvent(event: any) { - this.permissionGroups.handleConnectionEvent(event); - } - - async onInstanceConfigFieldChanged(field: string, curr: unknown, prev: unknown) { - if (field === "exp_groups.sync_permission_groups") { - this.syncId = curr ? "Global" : this.instance.id; - const [snapshot, synced] = this.permissionGroups.getSnapshot(); - if (synced && this.instance.status !== "running") await this.syncPermissionGroups(snapshot.values()); - } - } - - async onPermissionGroupsUpdate(event: PermissionGroupUpdate | null, synced: boolean) { - if (!synced || this.instance.status !== "running" || !event?.updates.length) return; - await this.syncPermissionGroups(event.updates); - } - - async syncPermissionGroups(groups: Iterable) { - const updateCommands = [rconBase]; - for (const group of groups) { - if (group.instanceId === this.syncId && group.updatedAtMs > (this.permissionGroups.values.get(group.id)?.updatedAtMs ?? 0)) { - if (group.isDeleted) { - updateCommands.push(`Groups.destroy_group('${group.name}')`); - } else if (group.permissions.size < this.permissions.size / 2) { - updateCommands.push(`Groups.get_or_create('${group.name}'):from_json('${JSON.stringify([false, [...this.permissions.values()]])}')`); - } else { - const inverted = [...this.permissions.values()].filter(permission => !group.permissions.has(permission)); - updateCommands.push(`Groups.get_or_create('${group.name}'):from_json('${JSON.stringify([true, inverted])}')`); - } - } - } - await this.sendRcon(updateCommands.join(";"), true); - } - - async onPermissionGroupUpdate(event: PermissionGroupEditEvent | null, synced: boolean) { - if (!synced || this.instance.status !== "running" || !event) return; - if (event.src.equals(lib.Address.fromShorthand({ instanceId: this.instance.id }))) return; - const getCmd = `Groups.get_or_create('${event.group}')`; - if (event.type === "add_permissions") { - await this.sendRcon(rconBase + getCmd + `:allow_actions(Groups.json_to_actions('${JSON.stringify(event.changes)}'))`); - } else if (event.type === "remove_permissions") { - await this.sendRcon(rconBase + getCmd + `:disallow_actions(Groups.json_to_actions('${JSON.stringify(event.changes)}'))`); - } else if (event.type === "assign_players") { - await this.sendRcon(rconBase + getCmd + `:add_players(game.json_to_table('${JSON.stringify(event.changes)}'))`); - } - } - - async handleEditIPC(event: EditIPC) { - this.logger.info(JSON.stringify(event)) - this.instance.sendTo("controller", new PermissionGroupEditEvent( - lib.Address.fromShorthand({ instanceId: this.instance.id }), - event.type, event.group, event.changes - )) - } - - async handleCreateIPC(event: CreateIPC) { - this.logger.info(JSON.stringify(event)) - if (!this.permissionGroups.synced) return; - let [defaultAllow, permissionsRaw] = event.defiantion; - if (!Array.isArray(permissionsRaw)) { - permissionsRaw = [] // lua outputs {} for empty arrays - } - const permissions = [...this.permissions.values()] - .filter(permission => defaultAllow !== (permissionsRaw as String[]).includes(permission)); - this.instance.sendTo("controller", new PermissionGroupUpdate([ new PermissionGroup( - this.syncId, event.group, 0, new Set(), new Set(permissions) - ) ])); - } - - async handleDeleteIPC(event: DeleteIPC) { - if (!this.permissionGroups.synced) return; - const group = [...this.permissionGroups.values.values()] - .find(group => group.instanceId === this.syncId && group.name === event.group); - if (group) { - group.updatedAtMs = Date.now(); - group.isDeleted = true; - this.instance.sendTo("controller", new PermissionGroupUpdate([ group ])); - } - } -} diff --git a/exp_groups/messages.ts b/exp_groups/messages.ts deleted file mode 100644 index 9b7337a8a8..0000000000 --- a/exp_groups/messages.ts +++ /dev/null @@ -1,239 +0,0 @@ -import { User, InstanceDetails, IControllerUser, Link, MessageRequest, StringEnum, PermissionError, Address } from "@clusterio/lib"; -import { Type, Static } from "@sinclair/typebox"; - -export const PermissionInstanceIdSchema = Type.Union([InstanceDetails.jsonSchema.properties.id, Type.Literal("Global")]) -export type PermissionInstanceId = InstanceDetails["id"] | "Global" -export type GamePermission = string; // todo: maybe enum this? - -/** - * Data class for permission groups - */ -export class PermissionGroup { - constructor( - public instanceId: PermissionInstanceId, - public name: string, - /** A lower order assumes a lower permission group */ - public order: number = 0, - /** A role will use the highest order group it is apart of */ - public roleIds: User["roleIds"] = new Set(), - public permissions: Set = new Set(), - public updatedAtMs: number = 0, - public isDeleted: boolean = false, - ) { - } - - static jsonSchema = Type.Object({ - instanceId: PermissionInstanceIdSchema, - name: Type.String(), - order: Type.Number(), - roleIds: Type.Array(Type.Number()), - permissions: Type.Array(Type.String()), - updatedAtMs: Type.Optional(Type.Number()), - isDeleted: Type.Optional(Type.Boolean()), - }); - - static fromJSON(json: Static) { - return new this( - json.instanceId, - json.name, - json.order, - new Set(json.roleIds), - new Set(json.permissions), - json.updatedAtMs, - json.isDeleted - ); - } - - toJSON(): Static { - return { - instanceId: this.instanceId, - name: this.name, - order: this.order, - roleIds: [...this.roleIds.values()], - permissions: [...this.permissions.values()], - updatedAtMs: this.updatedAtMs > 0 ? this.updatedAtMs : undefined, - isDeleted: this.isDeleted ? this.isDeleted : undefined, - } - } - - get id() { - return `${this.instanceId}:${this.name}`; - } - - copy(newInstanceId: PermissionInstanceId) { - return new PermissionGroup( - newInstanceId, - this.name, - this.order, - new Set(this.roleIds), - new Set(this.permissions), - Date.now(), - false - ) - } -} - -export class InstancePermissionGroups { - constructor( - public instanceId: PermissionInstanceId, - public groups: Map = new Map(), - ) { - } - - static jsonSchema = Type.Object({ - instanceId: PermissionInstanceIdSchema, - permissionsGroups: Type.Array(PermissionGroup.jsonSchema), - }); - - static fromJSON(json: Static) { - return new InstancePermissionGroups( - json.instanceId, - new Map(json.permissionsGroups.map(group => [group.name, PermissionGroup.fromJSON(group)])), - ); - } - - toJSON() { - return { - instanceId: this.instanceId, - permissionsGroups: [...this.groups.values()], - } - } - - getUserGroup(user: User) { - const groups = [...user.roleIds.values()].map(roleId => - // There will always be one and only one group for each role - [...this.groups.values()].find(group => group.roleIds.has(roleId))! - ); - return groups.reduce((highest, group) => highest.order > group.order ? highest : group); - } - - get id() { - return this.instanceId; - } -} - -export class PermissionGroupUpdate { - declare ["constructor"]: typeof PermissionGroupUpdate; - static type = "event" as const; - static src = ["controller", "instance"] as const; - static dst = ["control", "instance", "controller"] as const; - static plugin = "exp_groups" as const; - static permission = "exp_groups.list.subscribe"; - - constructor( - public updates: PermissionGroup[], - ) { } - - static jsonSchema = Type.Object({ - "updates": Type.Array(PermissionGroup.jsonSchema), - }); - - static fromJSON(json: Static) { - return new this( - json.updates.map(update => PermissionGroup.fromJSON(update)) - ); - } -} - -export type PermissionGroupEditType = "assign_players" | "add_permissions" | "remove_permissions"; - -export class PermissionGroupEditEvent { - declare ["constructor"]: typeof PermissionGroupEditEvent; - static type = "event" as const; - static src = ["instance", "controller"] as const; - static dst = ["control", "instance", "controller"] as const; - static plugin = "exp_groups" as const; - - static permission(user: IControllerUser, message: MessageRequest) { - if (typeof message.data === "object" && message.data !== null) { - const data = message.data as Static; - if (data.type === "add_permissions" || data.type === "remove_permissions") { - user.checkPermission("exp_groups.modify_permissions") - } else if (data.type === "assign_players") { - user.checkPermission("exp_groups.assign_players") - } else { - throw new PermissionError("Permission denied"); - } - }; - } - - constructor( - public src: Address, - public type: PermissionGroupEditType, - public group: string, - public changes: String[], - ) { } - - static jsonSchema = Type.Object({ - "src": Address.jsonSchema, - "type": StringEnum(["assign_players", "add_permissions", "remove_permissions"]), - "group": Type.String(), - "changes": Type.Array(Type.String()), - }); - - static fromJSON(json: Static) { - return new this(Address.fromJSON(json.src), json.type, json.group, json.changes); - } -} - -export class PermissionStrings { - constructor( - public instanceId: PermissionInstanceId, - public permissions: Set, - public updatedAtMs: number = 0, - public isDeleted: boolean = false, - ) { - } - - static jsonSchema = Type.Object({ - instanceId: PermissionInstanceIdSchema, - permissions: Type.Array(Type.String()), - updatedAtMs: Type.Optional(Type.Number()), - isDeleted: Type.Optional(Type.Boolean()), - }); - - static fromJSON(json: Static) { - return new PermissionStrings( - json.instanceId, - new Set(json.permissions), - json.updatedAtMs, - json.isDeleted - ); - } - - toJSON() { - return { - instanceId: this.instanceId, - permissions: [...this.permissions.values()], - updatedAtMs: this.updatedAtMs > 0 ? this.updatedAtMs : undefined, - isDeleted: this.isDeleted ? this.isDeleted : undefined, - } - } - - get id() { - return this.instanceId - } -} - -export class PermissionStringsUpdate { - declare ["constructor"]: typeof PermissionStringsUpdate; - static type = "event" as const; - static src = ["instance", "controller"] as const; - static dst = ["controller", "control"] as const; - static plugin = "exp_groups" as const; - static permission = "exp_groups.list.subscribe"; - - constructor( - public updates: PermissionStrings[], - ) { } - - static jsonSchema = Type.Object({ - "updates": Type.Array(PermissionStrings.jsonSchema), - }); - - static fromJSON(json: Static) { - return new this( - json.updates.map(update => PermissionStrings.fromJSON(update)) - ); - } -} diff --git a/exp_groups/module/control.lua b/exp_groups/module/control.lua deleted file mode 100644 index af956afc51..0000000000 --- a/exp_groups/module/control.lua +++ /dev/null @@ -1,127 +0,0 @@ -local clusterio_api = require("modules/clusterio/api") -local Global = require("modules/exp_util/global") -local Groups = require("modules/exp_groups") - -local pending_updates = {} -Global.register(pending_updates, function(tbl) - pending_updates = tbl -end) - -local function on_permission_group_added(event) - if not event.player_index then return end - pending_updates[event.group.name] = { - created = true, - sync_all = true, - tick = event.tick, - permissions = {}, - players = {}, - } -end - -local function on_permission_group_deleted(event) - if not event.player_index then return end - local existing = pending_updates[event.group_name] - pending_updates[event.group_name] = nil - if not existing or not existing.created then - clusterio_api.send_json("exp_groups-permission_group_delete", { - group = event.group_name, - }) - end -end - -local function on_permission_group_edited(event) - if not event.player_index then return end - local pending = pending_updates[event.group.name] - if not pending then - pending = { - tick = event.tick, - permissions = {}, - players = {}, - } - pending_updates[event.group.name] = pending - end - pending.tick = event.tick - - if event.type == "add-permission" then - if not pending.sync_all then - pending.permissions[event.action] = true - end - elseif event.type == "remove-permission" then - if not pending.sync_all then - pending.permissions[event.action] = false - end - elseif event.type == "enable-all" then - pending.sync_all = true - elseif event.type == "disable-all" then - pending.sync_all = true - elseif event.type == "add-player" then - local player = game.get_player(event.other_player_index) --- @cast player -nil - pending.players[player.name] = true - elseif event.type == "remove-player" then - local player = game.get_player(event.other_player_index) --- @cast player -nil - pending.players[player.name] = nil - elseif event.type == "rename" then - pending.created = true - pending.sync_all = true - local old = pending_updates[event.old_name] - if old then pending.players = old.players end - on_permission_group_deleted{ - tick = event.tick, player_index = event.player_index, group_name = event.old_name, - } - end -end - -local function send_updates() - local tick = game.tick - 600 -- 10 Seconds - local done = {} - for group_name, pending in pairs(pending_updates) do - if pending.tick < tick then - done[group_name] = true - if pending.sync_all then - clusterio_api.send_json("exp_groups-permission_group_create", { - group = group_name, defiantion = Groups.get_group(group_name):to_json(true), - }) - else - if next(pending.players) then - clusterio_api.send_json("exp_groups-permission_group_edit", { - type = "assign_players", group = group_name, changes = table.get_keys(pending.players), - }) - end - local add, remove = {}, {} - for permission, state in pairs(pending.permissions) do - if state then - add[#add + 1] = permission - else - remove[#remove + 1] = permission - end - end - - if next(add) then - clusterio_api.send_json("exp_groups-permission_group_edit", { - type = "add_permissions", group = group_name, changes = Groups.actions_to_names(add), - }) - end - if next(remove) then - clusterio_api.send_json("exp_groups-permission_group_edit", { - type = "remove_permissions", group = group_name, changes = Groups.actions_to_names(remove), - }) - end - end - end - end - - for group_name in pairs(done) do - pending_updates[group_name] = nil - end -end - -return { - events = { - [defines.events.on_permission_group_added] = on_permission_group_added, - [defines.events.on_permission_group_deleted] = on_permission_group_deleted, - [defines.events.on_permission_group_edited] = on_permission_group_edited, - }, - on_nth_tick = { - [300] = send_updates, - }, -} diff --git a/exp_groups/module/module.json b/exp_groups/module/module.json deleted file mode 100644 index 391b1a1d60..0000000000 --- a/exp_groups/module/module.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "exp_groups", - "load": [ - "control.lua" - ], - "require": [ - ], - "dependencies": { - "clusterio": "*", - "exp_util": "*" - } -} diff --git a/exp_groups/module/module_exports.lua b/exp_groups/module/module_exports.lua deleted file mode 100644 index 56518bc83f..0000000000 --- a/exp_groups/module/module_exports.lua +++ /dev/null @@ -1,306 +0,0 @@ -local Async = require("modules/exp_util/async") - -local table_to_json = helpers.table_to_json -local json_to_table = helpers.json_to_table - ---- Top level module table, contains event handlers and public methods -local Groups = {} - ---- @class ExpGroup : LuaPermissionGroup ---- @field group LuaPermissionGroup The permission group for this group proxy -Groups._prototype = {} - -Groups._metatable = { - __index = setmetatable(Groups._prototype, { - --- @type any Annotation required because otherwise it is typed as 'table' - __index = function(self, key) - return self.group[key] - end, - }), - __class = "ExpGroup", -} - -local action_to_name = {} -for name, action in pairs(defines.input_action) do - action_to_name[action] = name -end - ---- Async Functions --- These are required to allow bypassing edit_permission_group - ---- Add a player to a permission group, requires edit_permission_group ---- @param player LuaPlayer Player to add to the group ---- @param group LuaPermissionGroup Group to add the player to ---- @return boolean # True if successful -local function add_player_to_group(player, group) - return group.add_player(player) -end - ---- Add a players to a permission group, requires edit_permission_group ---- @param players LuaPlayer[] Players to add to the group ---- @param group LuaPermissionGroup Group to add the players to ---- @return boolean # True if successful -local function add_players_to_group(players, group) - local add_player = group.add_player - if not add_player(players[1]) then - return false - end - for i = 2, #players do - add_player(players[i]) - end - - return true -end - --- Async will bypass edit_permission_group but takes at least one tick -local add_player_to_group_async = Async.register(add_player_to_group) -local add_players_to_group_async = Async.register(add_players_to_group) - ---- Static methods for gettings, creating and removing permission groups - ---- Gets the permission group proxy with the given name or group ID. ---- @param group_name string|uint32 The name or id of the permission group ---- @return ExpGroup? -function Groups.get_group(group_name) - local group = game.permissions.get_group(group_name) - if group == nil then return nil end - return setmetatable({ - group = group, - }, Groups._metatable) -end - ---- Gets the permission group proxy for a players group ---- @param player LuaPlayer The player to get the group of ---- @return ExpGroup? -function Groups.get_player_group(player) - local group = player.permission_group - if group == nil then return nil end - return setmetatable({ - group = group, - }, Groups._metatable) -end - ---- Creates a new permission group, requires add_permission_group ---- @param group_name string Name of the group to create ---- @return ExpGroup -function Groups.new_group(group_name) - local group = game.permissions.get_group(group_name) - assert(group == nil, "Group already exists with name: " .. group_name) - group = game.permissions.create_group(group_name) - assert(group ~= nil, "Requires permission add_permission_group") - return setmetatable({ - group = group, - }, Groups._metatable) -end - ---- Get or create a permisison group, must use the group name not the group id ---- @param group_name string Name of the group to create ---- @return ExpGroup -function Groups.get_or_create(group_name) - local group = game.permissions.get_group(group_name) - if group then - return setmetatable({ - group = group, - }, Groups._metatable) - else - group = game.permissions.create_group(group_name) - assert(group ~= nil, "Requires permission add_permission_group") - return setmetatable({ - group = group, - }, Groups._metatable) - end -end - ---- Destory a permission group, moves all players to default group ---- @param group_name string|uint32 The name or id of the permission group to destroy ---- @param move_to_name string|uint32? The name or id of the permission group to move players to -function Groups.destroy_group(group_name, move_to_name) - local group = game.permissions.get_group(group_name) - if group == nil then return end - - local players = group.players - if #players > 0 then - local move_to = game.permissions.get_group(move_to_name or "Default") - for _, player in ipairs(players) do - player.permission_group = move_to - end - end - - local success = group.destroy() - assert(success, "Requires permission delete_permission_group") -end - ---- Prototype methods for modifying and working with permission groups - ---- Add a player to the permission group ---- @param player LuaPlayer The player to add to the group -function Groups._prototype:add_player(player) - if not add_player_to_group(player, self.group) then - add_player_to_group_async(player, self.group) - end -end - ---- Add players to the permission group ---- @param players LuaPlayer[] The player to add to the group -function Groups._prototype:add_players(players) - if not add_players_to_group(players, self.group) then - add_players_to_group_async(players, self.group) - end -end - ---- Move all players to another group ---- @param other_group ExpGroup The group to move players to, default is the Default group -function Groups._prototype:move_players(other_group) - if not add_players_to_group(self.group.players, other_group.group) then - add_players_to_group_async(self.group.players, other_group.group) - end -end - ---- Allow a set of actions for this group ---- @param actions defines.input_action[] Actions to allow ---- @return ExpGroup -function Groups._prototype:allow_actions(actions) - local set_allow = self.group.set_allows_action - for _, action in ipairs(actions) do - set_allow(action, true) - end - - return self -end - ---- Disallow a set of actions for this group ---- @param actions defines.input_action[] Actions to disallow ---- @return ExpGroup -function Groups._prototype:disallow_actions(actions) - local set_allow = self.group.set_allows_action - for _, action in ipairs(actions) do - set_allow(action, false) - end - - return self -end - ---- Reset the allowed state of all actions ---- @param allowed boolean? default true for allow all actions, false to disallow all actions ---- @return ExpGroup -function Groups._prototype:reset(allowed) - local set_allow = self.group.set_allows_action - if allowed == nil then allowed = true end - for _, action in pairs(defines.input_action) do - set_allow(action, allowed) - end - - return self -end - ---- Returns if the group is allowed a given action ---- @param action string|defines.input_action Actions to test ---- @return boolean # True if successful -function Groups._prototype:allows(action) - if type(action) == "string" then - return self.group.allows_action(defines.input_action[action]) - end - return self.group.allows_action(action) -end - ---- Print a message to all players in the group -function Groups._prototype:print(...) - for _, player in ipairs(self.group.players) do - player.print(...) - end -end - ---- Static and Prototype methods for use with IPC - ---- Convert an array of strings into an array of action names ---- @param actions_names string[] An array of action names ---- @return defines.input_action[] -local function names_to_actions(actions_names) - --- @type defines.input_action[], number[], number - local actions, invalid, invalid_i = {}, {}, 1 - for i, action_name in ipairs(actions_names) do - local action = defines.input_action[action_name] --[[ @as defines.input_action? ]] - if action then - actions[i] = action - else - invalid[invalid_i] = i - invalid_i = invalid_i + 1 - end - end - - local last = #actions - for _, i in ipairs(invalid) do - actions[i] = actions[last] - last = last - 1 - end - - return actions -end - ---- Get the action names from the action numbers -function Groups.actions_to_names(actions) - local names = {} - for i, action in ipairs(actions) do - names[i] = action_to_name[action] - end - - return names -end - ---- Get all input actions that are defined -function Groups.get_actions_json() - local rtn, rtn_i = {}, 1 - for name in pairs(defines.input_action) do - rtn[rtn_i] = name - rtn_i = rtn_i + 1 - end - - return table_to_json(rtn) -end - ---- Convert a json string array into an array of input actions ---- @param json string A json string representing a string array of actions ---- @return defines.input_action[] -function Groups.json_to_actions(json) - local tbl = json_to_table(json) - assert(tbl, "Invalid Json String") - --- @cast tbl string[] - return names_to_actions(tbl) -end - ---- Returns the shortest defination of the allowed actions --- The first value of the return can be passed to :reset -function Groups._prototype:to_json(raw) - local allow, disallow = {}, {} - local allow_i, disallow_i = 1, 1 - local allows = self.group.allows_action - for name, action in pairs(defines.input_action) do - if allows(action) then - allow[allow_i] = name - allow_i = allow_i + 1 - else - disallow[disallow_i] = name - disallow_i = disallow_i + 1 - end - end - - if allow_i >= disallow_i then - return raw and { true, disallow } or table_to_json{ true, disallow } - end - return raw and { false, allow } or table_to_json{ false, allow } -end - ---- Restores this group to the state given in a json string ---- @param json string The json string to restore from -function Groups._prototype:from_json(json) - local tbl = json_to_table(json) - assert(tbl and type(tbl[1]) == "boolean" and type(tbl[2]) == "table", "Invalid Json String") - - if tbl[1] then - self:reset(true):disallow_actions(names_to_actions(tbl[2])) - return - end - self:reset(false):allow_actions(names_to_actions(tbl[2])) -end - -return Groups diff --git a/exp_groups/package.json b/exp_groups/package.json deleted file mode 100644 index 61dca7f904..0000000000 --- a/exp_groups/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "@expcluster/permission_groups", - "private": true, - "version": "0.0.0", - "description": "Example Description. Package. Change me in package.json", - "main": "dist/node/index.js", - "scripts": { - "$prepare": "tsc --build && webpack-cli --env production" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@clusterio/lib": "catalog:" - }, - "devDependencies": { - "@clusterio/lib": "catalog:", - "@clusterio/web_ui": "catalog:", - "@types/fs-extra": "^11.0.4", - "@types/node": "catalog:", - "@types/react": "catalog:", - "antd": "catalog:", - "react": "catalog:", - "react-dom": "catalog:", - "typescript": "catalog:", - "webpack": "catalog:", - "webpack-cli": "catalog:", - "webpack-merge": "catalog:" - }, - "dependencies": { - "@sinclair/typebox": "catalog:", - "fs-extra": "^11.3.3" - }, - "publishConfig": { - "access": "public" - }, - "keywords": [ - "clusterio", - "factorio" - ] -} diff --git a/exp_groups/tsconfig.browser.json b/exp_groups/tsconfig.browser.json deleted file mode 100644 index 1e3889e7d5..0000000000 --- a/exp_groups/tsconfig.browser.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "../tsconfig.browser.json", - "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], -} diff --git a/exp_groups/tsconfig.json b/exp_groups/tsconfig.json deleted file mode 100644 index be6d4e98a8..0000000000 --- a/exp_groups/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "files": [], - "references": [ - { "path": "./tsconfig.browser.json" }, - { "path": "./tsconfig.node.json" } - ] -} diff --git a/exp_groups/tsconfig.node.json b/exp_groups/tsconfig.node.json deleted file mode 100644 index 3218f2e757..0000000000 --- a/exp_groups/tsconfig.node.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "../tsconfig.node.json", - "include": ["./**/*.ts"], - "exclude": ["test/*", "./dist/*"], -} diff --git a/exp_groups/web/components/groupTree.tsx b/exp_groups/web/components/groupTree.tsx deleted file mode 100644 index a8bd671875..0000000000 --- a/exp_groups/web/components/groupTree.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import React, { useState } from 'react'; -import { Tree } from 'antd'; -import type { TreeDataNode, TreeProps } from 'antd'; - -const defaultData: TreeDataNode[] = [ - { - title: "Group 1", - key: "G-1", - icon: false, - children: [ - { - title: "Role 1", - key: "R-1" - }, - { - title: "Role 2", - key: "R-2" - }, - { - title: "Role 3", - key: "R-3" - } - ] - }, - { - title: "Group 2", - key: "G-2", - icon: false, - children: [ - { - title: "Role 4", - key: "R-4" - }, - { - title: "Role 5", - key: "R-5" - } - ] - }, - { - title: "Default", - key: "G-3", - icon: false, - children: [ - { - title: "Role 6", - key: "R-6" - } - ] - } -]; - -export function GroupTree() { - const [gData, setGData] = useState(defaultData); - - const onDrop: TreeProps['onDrop'] = (info) => { - const dropKey = info.node.key; - const dragKey = info.dragNode.key; - const dropPos = info.node.pos.split('-'); - const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]); // the drop position relative to the drop node, inside 0, top -1, bottom 1 - - const findKey = ( - data: TreeDataNode[], - key: React.Key, - callback: (node: TreeDataNode, i: number, data: TreeDataNode[]) => void, - ) => { - for (let i = 0; i < data.length; i++) { - if (data[i].key === key) { - return callback(data[i], i, data); - } - if (data[i].children) { - findKey(data[i].children!, key, callback); - } - } - }; - - const data = [...gData] - - // Find dragObject - let dragObj: TreeDataNode; - findKey(data, dragKey, (item, index, arr) => { - arr.splice(index, 1); - dragObj = item; - }); - - if (!info.dropToGap) { - // Drop on the content - findKey(data, dropKey, (item) => { - item.children = item.children || []; - // where to insert. New item was inserted to the start of the array in this example, but can be anywhere - item.children.unshift(dragObj); - }); - } else { - let ar: TreeDataNode[] = []; - let i: number; - findKey(data, dropKey, (_item, index, arr) => { - ar = arr; - i = index; - }); - if (dropPosition === -1) { - // Drop on the top of the drop node - ar.splice(i!, 0, dragObj!); - } else { - // Drop on the bottom of the drop node - ar.splice(i! + 1, 0, dragObj!); - } - } - - setGData(data) - }; - - const allowDrop: TreeProps['allowDrop'] = ({dragNode, dropNode, dropPosition}) => { - const dragType = (dragNode.key as string).charAt(0); - const dropType = (dropNode.key as string).charAt(0); - return dropType === dragType && dropPosition != 0 || dragType === "R" && dropType === "G" && dropPosition == 0 - } - - return ( - - ); -}; diff --git a/exp_groups/web/index.tsx b/exp_groups/web/index.tsx deleted file mode 100644 index 0f85661bd2..0000000000 --- a/exp_groups/web/index.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React, { - useContext, useEffect, useState, - useCallback, useSyncExternalStore, -} from "react"; - -// import { -// -// } from "antd"; - -import { - BaseWebPlugin, PageLayout, PageHeader, Control, ControlContext, notifyErrorHandler, - useInstances, -} from "@clusterio/web_ui"; - -import { PermissionGroupUpdate, PermissionInstanceId, PermissionStringsUpdate } from "../messages"; - -import * as lib from "@clusterio/lib"; - -import { GroupTree } from "./components/groupTree"; - -function MyTemplatePage() { - const control = useContext(ControlContext); - const plugin = control.plugins.get("exp_groups") as WebPlugin; - const [permissionStrings, permissionStringsSynced] = plugin.usePermissionStrings(); - const [permissionGroups, permissionGroupsSynced] = plugin.usePermissionGroups(); - const [instances, instancesSync] = useInstances(); - - let [roles, setRoles] = useState([]); - - useEffect(() => { - control.send(new lib.RoleListRequest()).then(newRoles => { - setRoles(newRoles); - }).catch(notifyErrorHandler("Error fetching role list")); - }, []); - - return - - Permission Strings: {String(permissionStringsSynced)} {JSON.stringify([...permissionStrings.values()])}
- Permission Groups: {String(permissionGroupsSynced)} {JSON.stringify([...permissionGroups.values()])}
- Instances: {String(instancesSync)} {JSON.stringify([...instances.values()].map(instance => [instance.id, instance.name]))}
- Roles: {JSON.stringify([...roles.values()].map(role => [role.id, role.name]))}
- -
; -} - -export class WebPlugin extends BaseWebPlugin { - permissionStrings = new lib.EventSubscriber(PermissionStringsUpdate, this.control); - permissionGroups = new lib.EventSubscriber(PermissionGroupUpdate, this.control); - - async init() { - this.pages = [ - { - path: "/exp_groups", - sidebarName: "exp_groups", - permission: "exp_groups.list", - content: , - }, - ]; - } - - useInstancePermissionStrings(instanceId?: PermissionInstanceId) { - const [permissionStrings, synced] = this.usePermissionStrings(); - return [instanceId !== undefined ? permissionStrings.get(instanceId) : undefined, synced] as const; - } - - usePermissionStrings() { - const control = useContext(ControlContext); - const subscribe = useCallback((callback: () => void) => this.permissionStrings.subscribe(callback), [control]); - return useSyncExternalStore(subscribe, () => this.permissionStrings.getSnapshot()); - } - - useInstancePermissionGroups(instanceId?: PermissionInstanceId) { - const [permissionGroups, synced] = this.usePermissionGroups(); - return [instanceId !== undefined ? [...permissionGroups.values()].filter(group => group.instanceId === instanceId) : undefined, synced] as const; - } - - usePermissionGroups() { - const control = useContext(ControlContext); - const subscribe = useCallback((callback: () => void) => this.permissionGroups.subscribe(callback), [control]); - return useSyncExternalStore(subscribe, () => this.permissionGroups.getSnapshot()); - } -} diff --git a/exp_groups/webpack.config.js b/exp_groups/webpack.config.js deleted file mode 100644 index 6c269a9500..0000000000 --- a/exp_groups/webpack.config.js +++ /dev/null @@ -1,32 +0,0 @@ -"use strict"; -const path = require("path"); -const webpack = require("webpack"); -const { merge } = require("webpack-merge"); - -const common = require("@clusterio/web_ui/webpack.common"); - -module.exports = (env = {}) => merge(common(env), { - context: __dirname, - entry: "./web/index.tsx", - output: { - path: path.resolve(__dirname, "dist", "web"), - }, - plugins: [ - new webpack.container.ModuleFederationPlugin({ - name: "exp_groups", - library: { type: "window", name: "plugin_exp_groups" }, - exposes: { - "./": "./index.ts", - "./package.json": "./package.json", - "./web": "./web/index.tsx", - }, - shared: { - "@clusterio/lib": { import: false }, - "@clusterio/web_ui": { import: false }, - "antd": { import: false }, - "react": { import: false }, - "react-dom": { import: false }, - }, - }), - ], -}); From b64e109bf11fa8b11f278ab70456a4a58121341f Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Wed, 20 May 2026 01:48:26 +0100 Subject: [PATCH 02/12] Plugin Setup exp_groups --- exp_groups/controller.ts | 6 +++++ exp_groups/index.ts | 22 +++++++++++++++++ exp_groups/instance.ts | 6 +++++ exp_groups/module/module.json | 11 +++++++++ exp_groups/module/module_exports.lua | 3 +++ exp_groups/package.json | 37 ++++++++++++++++++++++++++++ exp_groups/tsconfig.browser.json | 4 +++ exp_groups/tsconfig.json | 7 ++++++ exp_groups/tsconfig.node.json | 5 ++++ exp_groups/web/index.tsx | 0 exp_groups/webpack.config.js | 29 ++++++++++++++++++++++ exp_scenario/controller.ts | 5 ++-- exp_server_ups/package.json | 2 +- 13 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 exp_groups/controller.ts create mode 100644 exp_groups/index.ts create mode 100644 exp_groups/instance.ts create mode 100644 exp_groups/module/module.json create mode 100644 exp_groups/module/module_exports.lua create mode 100644 exp_groups/package.json create mode 100644 exp_groups/tsconfig.browser.json create mode 100644 exp_groups/tsconfig.json create mode 100644 exp_groups/tsconfig.node.json create mode 100644 exp_groups/web/index.tsx create mode 100644 exp_groups/webpack.config.js diff --git a/exp_groups/controller.ts b/exp_groups/controller.ts new file mode 100644 index 0000000000..fc761f627c --- /dev/null +++ b/exp_groups/controller.ts @@ -0,0 +1,6 @@ +import * as lib from "@clusterio/lib"; +import { BaseControllerPlugin } from "@clusterio/controller"; + +export class ControllerPlugin extends BaseControllerPlugin { + +} diff --git a/exp_groups/index.ts b/exp_groups/index.ts new file mode 100644 index 0000000000..14fe26e062 --- /dev/null +++ b/exp_groups/index.ts @@ -0,0 +1,22 @@ +import * as lib from "@clusterio/lib"; + +declare module "@clusterio/lib" { + export interface InstanceConfigFields { + } + export interface ControllerConfigFields { + } +} + +export const plugin: lib.PluginDeclaration = { + name: "exp_groups", + title: "ExpGaming - Permission Groups", + description: "Clusterio plugin providing syncing of permission groups", + + instanceEntrypoint: "./dist/node/instance", + instanceConfigFields: { + }, + + controllerEntrypoint: "./dist/node/controller", + controllerConfigFields: { + }, +}; diff --git a/exp_groups/instance.ts b/exp_groups/instance.ts new file mode 100644 index 0000000000..455d035c55 --- /dev/null +++ b/exp_groups/instance.ts @@ -0,0 +1,6 @@ +import * as lib from "@clusterio/lib"; +import { BaseInstancePlugin } from "@clusterio/host"; + +export class InstancePlugin extends BaseInstancePlugin { + +} diff --git a/exp_groups/module/module.json b/exp_groups/module/module.json new file mode 100644 index 0000000000..0d7ebefd0a --- /dev/null +++ b/exp_groups/module/module.json @@ -0,0 +1,11 @@ +{ + "name": "exp_groups", + "load": [ + "control.lua" + ], + "require": [ + ], + "dependencies": { + "clusterio": "*" + } +} diff --git a/exp_groups/module/module_exports.lua b/exp_groups/module/module_exports.lua new file mode 100644 index 0000000000..47762f6be7 --- /dev/null +++ b/exp_groups/module/module_exports.lua @@ -0,0 +1,3 @@ + +-- Access the exports from other modules using require("modules/exp_groups") +return require("modules/exp_groups/control") diff --git a/exp_groups/package.json b/exp_groups/package.json new file mode 100644 index 0000000000..518bc8e5b0 --- /dev/null +++ b/exp_groups/package.json @@ -0,0 +1,37 @@ +{ + "name": "@expcluster/permission-groups", + "version": "0.1.0", + "description": "Clusterio plugin providing syncing of permission groups", + "author": "Cooldude2606 ", + "license": "MIT", + "repository": "explosivegaming/ExpCluster", + "main": "dist/node/index.js", + "scripts": { + "prepare": "tsc --build && webpack-cli --env production" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@clusterio/lib": "catalog:" + }, + "devDependencies": { + "typescript": "catalog:", + "@types/node": "catalog:", + "@clusterio/lib": "catalog:", + "webpack": "catalog:", + "webpack-cli": "catalog:", + "webpack-merge": "catalog:" + }, + "dependencies": { + "@sinclair/typebox": "catalog:" + }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "clusterio", + "clusterio-plugin", + "factorio" + ] +} \ No newline at end of file diff --git a/exp_groups/tsconfig.browser.json b/exp_groups/tsconfig.browser.json new file mode 100644 index 0000000000..1ab2704ea8 --- /dev/null +++ b/exp_groups/tsconfig.browser.json @@ -0,0 +1,4 @@ +{ + "extends": "../tsconfig.browser.json", + "include": [ "web/**/*.tsx", "web/**/*.ts", "package.json" ], +} diff --git a/exp_groups/tsconfig.json b/exp_groups/tsconfig.json new file mode 100644 index 0000000000..303b8f284b --- /dev/null +++ b/exp_groups/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.node.json" }, + { "path": "./tsconfig.browser.json" } + ] +} diff --git a/exp_groups/tsconfig.node.json b/exp_groups/tsconfig.node.json new file mode 100644 index 0000000000..3218f2e757 --- /dev/null +++ b/exp_groups/tsconfig.node.json @@ -0,0 +1,5 @@ +{ + "extends": "../tsconfig.node.json", + "include": ["./**/*.ts"], + "exclude": ["test/*", "./dist/*"], +} diff --git a/exp_groups/web/index.tsx b/exp_groups/web/index.tsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exp_groups/webpack.config.js b/exp_groups/webpack.config.js new file mode 100644 index 0000000000..0baa40ac1c --- /dev/null +++ b/exp_groups/webpack.config.js @@ -0,0 +1,29 @@ +"use strict"; +const path = require("path"); +const webpack = require("webpack"); +const { merge } = require("webpack-merge"); + +const common = require("@clusterio/web_ui/webpack.common"); + +module.exports = (env = {}) => merge(common(env), { + context: __dirname, + entry: "./web/index.tsx", + output: { + path: path.resolve(__dirname, "dist", "web"), + }, + plugins: [ + new webpack.container.ModuleFederationPlugin({ + name: "exp_groups", + library: { type: "window", name: "plugin_exp_groups" }, + exposes: { + "./": "./index.ts", + "./package.json": "./package.json", + "./web": "./web/index.tsx", + }, + shared: { + "@clusterio/lib": { import: false }, + "@clusterio/web_ui": { import: false }, + }, + }), + ], +}); diff --git a/exp_scenario/controller.ts b/exp_scenario/controller.ts index 110c6c8611..fc761f627c 100644 --- a/exp_scenario/controller.ts +++ b/exp_scenario/controller.ts @@ -1,7 +1,6 @@ import * as lib from "@clusterio/lib"; -import { BaseControllerPlugin, InstanceInfo } from "@clusterio/controller"; +import { BaseControllerPlugin } from "@clusterio/controller"; export class ControllerPlugin extends BaseControllerPlugin { - async init() { - } + } diff --git a/exp_server_ups/package.json b/exp_server_ups/package.json index b446a746cb..f632ca4bef 100644 --- a/exp_server_ups/package.json +++ b/exp_server_ups/package.json @@ -1,5 +1,5 @@ { - "name": "@expcluster/server_ups", + "name": "@expcluster/server-ups", "version": "0.1.0", "description": "Clusterio plugin providing in game server ups counter", "author": "Cooldude2606 ", From 90d63952d3ba9747df0a58a42fb69e5434f17fdb Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Wed, 20 May 2026 01:48:37 +0100 Subject: [PATCH 03/12] Add lua module code --- exp_groups/module/control.lua | 436 ++++++++++++++++++++++++++++++++++ 1 file changed, 436 insertions(+) create mode 100644 exp_groups/module/control.lua diff --git a/exp_groups/module/control.lua b/exp_groups/module/control.lua new file mode 100644 index 0000000000..831e4ea65b --- /dev/null +++ b/exp_groups/module/control.lua @@ -0,0 +1,436 @@ +--[[-- Exp Permission Groups +Adds permission group syncing to clusterio +]] + +local clusterio_api = require("modules/clusterio/api") +local compat = require("modules/clusterio/compat") + +--- Top level module table, contains event handlers and public methods +--- @class ExpPermissionGroups +local ExpPermissionGroups = {} + +--- @class ExpPermissionGroups.GroupPermissions +--- @field [1] boolean -- is_blacklist, true means action names is a backlist +--- @field [2] string[] -- action_names, the actions to allow or disallow + +--- @class ExpPermissionGroups.GroupRecord +--- @field id number +--- @field name string +--- @field permissions ExpPermissionGroups.GroupPermissions? +--- @field isDeleted boolean + +--- @class ExpPermissionGroups.AssignmentRecord +--- @field name string +--- @field groupId number +--- @field isDeleted boolean + +--- @class ExpPermissionGroups.ScriptData +--- @field factorio_to_clusterio_id table +--- @field clusterio_id_to_group table +--- @field dirty_groups table +--- @field dirty_players table +--- @field emit_updates boolean +local script_data = {} + +local function setup_script_data() + if compat.script_data["exp_groups"] == nil then + --- @type ExpPermissionGroups.ScriptData + compat.script_data["exp_groups"] = { + factorio_to_clusterio_id = {}, + clusterio_id_to_group = {}, + dirty_groups = {}, + dirty_players = {}, + emit_updates = false, + } + end + + ExpPermissionGroups.on_load() +end + +--[[ + Helper methods +]] + +--- Get the default factorio permission group +--- @return LuaPermissionGroup +local function get_default_group() + return assert(game.permissions.get_group("Default")) +end + +--- Move all players from one group to another +--- @param group_src LuaPermissionGroup +--- @param group_dst LuaPermissionGroup +local function move_players(group_src, group_dst) + local add_player = group_dst.add_player + for _, player in pairs(group_src.players) do + add_player(player) + end +end + +--- Apply an encoded permission definition to a group +--- @param group LuaPermissionGroup +--- @param permissions ExpPermissionGroups.GroupPermissions +local function decode_group_permissions(group, permissions) + local is_blacklist = permissions[1] + local actions_names = permissions[2] + local action_allowed = not is_blacklist + + -- Construct a hash map for faster lookup + local action_map = {} + for _, input_action_name in pairs(actions_names) do + action_map[input_action_name] = true + end + + -- Apply the whitelist / backlist to the group + for input_action_name, input_action in pairs(defines.input_action) do + if action_map[input_action_name] then + group.set_allows_action(input_action, action_allowed) + else + group.set_allows_action(input_action, is_blacklist) + end + end +end + +--- Encode the permissions of a group in a shorthand format +--- @param group LuaPermissionGroup +--- @return ExpPermissionGroups.GroupPermissions +local function encode_group_permissions(group) + local whitelist = {} --- @type string[] + local blacklist = {} --- @type string[] + local whitelist_index = 0 + local blacklist_index = 0 + + -- Construct the whitelist and blacklist + local allows_action = group.allows_action + for input_action_name, input_action in pairs(defines.input_action) do + if allows_action(input_action) then + whitelist[whitelist_index] = input_action_name + whitelist_index = whitelist_index + 1 + else + blacklist[blacklist_index] = input_action_name + blacklist_index = blacklist_index + 1 + end + end + + -- Return the whitelist if it is smaller + if blacklist_index > whitelist_index then + return { false, whitelist } + end + + -- Otherwise return the blacklist as it is smaller + return { true, blacklist } +end + +--[[ + State handlers +]] + +--- Update the factorio permission group +--- @param group_record ExpPermissionGroups.GroupRecord +local function update_group(group_record) + assert(not group_record.isDeleted) + + -- Try find the group by id and then then name + local group = script_data.clusterio_id_to_group[group_record.id] + if not group then + group = game.permissions.get_group(group_record.name) + end + + -- Create a new group or update the found group + if not group or not group.valid then + group = assert(game.permissions.create_group(group_record.name)) + else + group.name = group_record.name + end + + -- Update the permissions for the group + if group_record.permissions then + decode_group_permissions(group, group_record.permissions) + end + + -- Update the script data + script_data.factorio_to_clusterio_id[group.group_id] = group_record.id + script_data.clusterio_id_to_group[group_record.id] = group +end + +--- Delete the factorio permission group +--- @param group_record ExpPermissionGroups.GroupRecord +local function delete_group(group_record) + assert(group_record.isDeleted) + + local default_group = get_default_group() + local group = script_data.clusterio_id_to_group[group_record.id] + if group then + move_players(group, default_group) + group.destroy() + end +end + +--- Update an assignment by moving the player to their new group +--- @param assignment_record ExpPermissionGroups.AssignmentRecord +local function update_assignment(assignment_record) + assert(not assignment_record.isDeleted) + + local group = script_data.clusterio_id_to_group[assignment_record.groupId] + local player = assert(game.get_player(assignment_record.name)) + if group then + group.add_player(player) + end +end + +--- Clear an assignment by moving the player to the default group +--- @param assignment_record ExpPermissionGroups.AssignmentRecord +local function delete_assignment(assignment_record) + assert(assignment_record.isDeleted) + + local default_group = get_default_group() + local player = assert(game.get_player(assignment_record.name)) + default_group.add_player(player) +end + +--[[ + Public methods +]] + +--- Restore local references to persistent script data after load +function ExpPermissionGroups.on_load() + script_data = compat.script_data["exp_groups"] +end + +--- Enable or disable emitting lua changes back to the instance plugin +--- @param enabled boolean? +function ExpPermissionGroups.set_emit_events(enabled) + script_data.emit_updates = enabled ~= false +end + +--- Replace local state with expected controller state on startup +--- @param group_records ExpPermissionGroups.GroupRecord[] +function ExpPermissionGroups.initialise_groups(group_records) + local _emit_events = script_data.emit_updates + script_data.emit_updates = false + + -- Update all the received groups + local seen_clusterio_ids = {} --- @type table + for _, group_record in pairs(group_records) do + update_group(group_record) + seen_clusterio_ids[group_record.id] = true + end + + -- Cleanup the script data, removing stale group ids + local factorio_to_clusterio_id = script_data.factorio_to_clusterio_id + local clusterio_id_to_group = script_data.clusterio_id_to_group + for factorio_id, clusterio_id in pairs(factorio_to_clusterio_id) do + if not seen_clusterio_ids[clusterio_id] then + factorio_to_clusterio_id[factorio_id] = nil + clusterio_id_to_group[clusterio_id] = nil + end + end + + -- Remove all other groups + local default_group = get_default_group() + local default_group_id = default_group.group_id + for _, group in pairs(game.permissions.groups) do + if not factorio_to_clusterio_id[group.group_id] and group.group_id ~= default_group_id then + move_players(group, default_group) + group.destroy() + end + end + + script_data.emit_updates = _emit_events +end + +--- Receive an updated version of a group record +--- @param group_record ExpPermissionGroups.GroupRecord +function ExpPermissionGroups.receive_group_update(group_record) + local _emit_events = script_data.emit_updates + script_data.emit_updates = false + + if group_record.isDeleted then + delete_group(group_record) + else + update_group(group_record) + end + + script_data.emit_updates = _emit_events +end + +--- Receive an updated version of a assignment record +--- @param assignment_record ExpPermissionGroups.AssignmentRecord +function ExpPermissionGroups.receive_assignment_update(assignment_record) + local _emit_events = script_data.emit_updates + script_data.emit_updates = false + + if assignment_record.isDeleted then + delete_assignment(assignment_record) + else + update_assignment(assignment_record) + end + + script_data.emit_updates = _emit_events +end + +--- Get the current script data for debugging purposes +--- @package +function ExpPermissionGroups._script_data() + return script_data +end + +--[[ + IPC events +]] + +--- Emit a group update to the instance plugin +--- @param group LuaPermissionGroup +local function emit_group_update(group) + clusterio_api.send_json("exp_group:group_updated", { + group_name = group.name, + group_id = script_data.factorio_to_clusterio_id[group.group_id], + permissions = encode_group_permissions(group), + }) +end + +--- Emit a group deletion to the instance plugin +--- @param group_id number +--- @param group_name string +local function emit_group_delete(group_id, group_name) + clusterio_api.send_json("exp_group:group_deleted", { + group_name = group_name, + group_id = script_data.factorio_to_clusterio_id[group_id], + }) +end + +--- Emit a player assignment to the instance plugin +--- @param assignments table +local function emit_player_assignments(assignments) + clusterio_api.send_json("exp_group:player_assignments", { + assignments = assignments + }) +end + +--[[ + IPC event queuing +]] + +--- Mark a group as changed +--- @param group LuaPermissionGroup +local function mark_group_dirty(group) + script_data.dirty_groups[group.group_id] = group +end + +--- Mark a player as changed +--- @param player LuaPlayer +local function mark_player_dirty(player) + script_data.dirty_players[player.name] = player +end + +--- Flush queued group updates to the instance plugin +local function flush_group_updates() + -- Check if updates should be updated + if not script_data.emit_updates then + script_data.dirty_groups = {} + return + end + + -- Get all the groups and emit their updates + local get_group = game.permissions.get_group + for _, group in pairs(script_data.dirty_groups) do + if group.valid then + emit_group_update(group) + end + end + + script_data.dirty_groups = {} +end + +--- Flush queued player updates to the instance plugin +local function flush_player_updates() + -- Check if updates should be updated + if not script_data.emit_updates then + script_data.dirty_players = {} + return + end + + -- Construct the update payload + local assignments = {} --- @type table + for player_name, player in pairs(script_data.dirty_players) do + local group = player.valid and player.permission_group + if group then + assignments[player_name] = script_data.factorio_to_clusterio_id[group.group_id] + end + end + + emit_player_assignments(assignments) + + script_data.dirty_players = {} +end + +--[[ + Factorio events +]] + +--- Handle clusterio server startup +local function on_server_startup() + setup_script_data() +end + +--- Handle creation of permission groups +--- @param event EventData.on_permission_group_added +local function on_permission_group_added(event) + -- Check if updates should be updated + if not script_data.emit_updates then + return + end + + emit_group_update(event.group) +end + +--- Handle deletion of permission groups +--- @param event EventData.on_permission_group_deleted +local function on_permission_group_deleted(event) + -- Check if updates should be updated + if not script_data.emit_updates then + return + end + + emit_group_delete(event.id, event.group_name) +end + +--- Handle edits make to permission groups +--- @param event EventData.on_permission_group_edited +local function on_permission_group_edited(event) + -- Check if updates should be updated + if not script_data.emit_updates then + return + end + + -- Check if this is a player or group event + if event.type == "add-player" or event.type == "remove-player" then + local player = assert(game.get_player(event.other_player_index)) + mark_player_dirty(player) + else + mark_group_dirty(event.group) + end +end + +--- Periodically flush queued changes +local function on_nth_tick_flush() + flush_group_updates() + flush_player_updates() +end + +local e = defines.events + +local events = { + [clusterio_api.events.on_server_startup] = on_server_startup, + [e.on_permission_group_added] = on_permission_group_added, + [e.on_permission_group_deleted] = on_permission_group_deleted, + [e.on_permission_group_edited] = on_permission_group_edited, +} + +local on_nth_tick = { + [300] = on_nth_tick_flush, +} + +ExpPermissionGroups.events = events --- @package +ExpPermissionGroups.on_nth_tick = on_nth_tick --- @package +return ExpPermissionGroups From 01af5dbc686333e8784669a1454e0901edbe6b6d Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Wed, 20 May 2026 22:04:53 +0100 Subject: [PATCH 04/12] Update deps --- pnpm-lock.yaml | 1682 +++++++++++++++++++++---------------------- pnpm-workspace.yaml | 20 +- 2 files changed, 836 insertions(+), 866 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae212b8820..279a56ca43 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,41 +7,41 @@ settings: catalogs: default: '@clusterio/lib': - specifier: 2.0.0-alpha.22b - version: 2.0.0-alpha.22b + specifier: 2.0.0-alpha.25 + version: 2.0.0-alpha.25 '@clusterio/web_ui': - specifier: 2.0.0-alpha.22b - version: 2.0.0-alpha.22b + specifier: 2.0.0-alpha.25 + version: 2.0.0-alpha.25 '@sinclair/typebox': specifier: ^0.30.4 version: 0.30.4 '@types/node': - specifier: ^20.19.29 - version: 20.19.29 + specifier: ^20.19.41 + version: 20.19.41 '@types/react': - specifier: 18.2.0 - version: 18.2.0 + specifier: ^18.3.29 + version: 18.3.29 antd: - specifier: 5.24.2 - version: 5.24.2 + specifier: ^5.29.3 + version: 5.29.3 react: - specifier: 18.2.0 - version: 18.2.0 + specifier: ^18.3.1 + version: 18.3.1 react-dom: - specifier: 18.2.0 - version: 18.2.0 + specifier: ^18.3.1 + version: 18.3.1 typescript: specifier: ^5.9.3 version: 5.9.3 webpack: - specifier: 5.98.0 - version: 5.98.0 + specifier: ^5.107.0 + version: 5.107.0 webpack-cli: - specifier: 5.1.4 + specifier: ^5.1.4 version: 5.1.4 webpack-merge: - specifier: 5.9.0 - version: 5.9.0 + specifier: ^5.10.0 + version: 5.10.0 importers: @@ -62,68 +62,47 @@ importers: devDependencies: '@clusterio/lib': specifier: 'catalog:' - version: 2.0.0-alpha.22b + version: 2.0.0-alpha.25 '@types/node': specifier: 'catalog:' - version: 20.19.29 + version: 20.19.41 typescript: specifier: 'catalog:' version: 5.9.3 webpack: specifier: 'catalog:' - version: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) webpack-cli: specifier: 'catalog:' - version: 5.1.4(webpack@5.98.0) + version: 5.1.4(webpack@5.107.0) webpack-merge: specifier: 'catalog:' - version: 5.9.0 + version: 5.10.0 exp_groups: dependencies: '@sinclair/typebox': specifier: 'catalog:' version: 0.30.4 - fs-extra: - specifier: ^11.3.3 - version: 11.3.3 devDependencies: '@clusterio/lib': specifier: 'catalog:' - version: 2.0.0-alpha.22b - '@clusterio/web_ui': - specifier: 'catalog:' - version: 2.0.0-alpha.22b - '@types/fs-extra': - specifier: ^11.0.4 - version: 11.0.4 + version: 2.0.0-alpha.25 '@types/node': specifier: 'catalog:' - version: 20.19.29 - '@types/react': - specifier: 'catalog:' - version: 18.2.0 - antd: - specifier: 'catalog:' - version: 5.24.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: - specifier: 'catalog:' - version: 18.2.0 - react-dom: - specifier: 'catalog:' - version: 18.2.0(react@18.2.0) + version: 20.19.41 typescript: specifier: 'catalog:' version: 5.9.3 webpack: specifier: 'catalog:' - version: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) webpack-cli: specifier: 'catalog:' - version: 5.1.4(webpack@5.98.0) + version: 5.1.4(webpack@5.107.0) webpack-merge: specifier: 'catalog:' - version: 5.9.0 + version: 5.10.0 exp_gui: dependencies: @@ -136,22 +115,22 @@ importers: devDependencies: '@clusterio/lib': specifier: 'catalog:' - version: 2.0.0-alpha.22b + version: 2.0.0-alpha.25 '@types/node': specifier: 'catalog:' - version: 20.19.29 + version: 20.19.41 typescript: specifier: 'catalog:' version: 5.9.3 webpack: specifier: 'catalog:' - version: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) webpack-cli: specifier: 'catalog:' - version: 5.1.4(webpack@5.98.0) + version: 5.1.4(webpack@5.107.0) webpack-merge: specifier: 'catalog:' - version: 5.9.0 + version: 5.10.0 exp_legacy: dependencies: @@ -167,22 +146,22 @@ importers: devDependencies: '@clusterio/lib': specifier: 'catalog:' - version: 2.0.0-alpha.22b + version: 2.0.0-alpha.25 '@types/node': specifier: 'catalog:' - version: 20.19.29 + version: 20.19.41 typescript: specifier: 'catalog:' version: 5.9.3 webpack: specifier: 'catalog:' - version: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) webpack-cli: specifier: 'catalog:' - version: 5.1.4(webpack@5.98.0) + version: 5.1.4(webpack@5.107.0) webpack-merge: specifier: 'catalog:' - version: 5.9.0 + version: 5.10.0 exp_scenario: dependencies: @@ -198,37 +177,37 @@ importers: devDependencies: '@clusterio/lib': specifier: 'catalog:' - version: 2.0.0-alpha.22b + version: 2.0.0-alpha.25 '@clusterio/web_ui': specifier: 'catalog:' - version: 2.0.0-alpha.22b + version: 2.0.0-alpha.25 '@types/node': specifier: 'catalog:' - version: 20.19.29 + version: 20.19.41 '@types/react': specifier: 'catalog:' - version: 18.2.0 + version: 18.3.29 antd: specifier: 'catalog:' - version: 5.24.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.29.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 'catalog:' - version: 18.2.0 + version: 18.3.1 react-dom: specifier: 'catalog:' - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) typescript: specifier: 'catalog:' version: 5.9.3 webpack: specifier: 'catalog:' - version: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) webpack-cli: specifier: 'catalog:' - version: 5.1.4(webpack@5.98.0) + version: 5.1.4(webpack@5.107.0) webpack-merge: specifier: 'catalog:' - version: 5.9.0 + version: 5.10.0 exp_server_ups: dependencies: @@ -247,22 +226,22 @@ importers: devDependencies: '@clusterio/lib': specifier: 'catalog:' - version: 2.0.0-alpha.22b + version: 2.0.0-alpha.25 '@types/node': specifier: 'catalog:' - version: 20.19.29 + version: 20.19.41 typescript: specifier: 'catalog:' version: 5.9.3 webpack: specifier: 'catalog:' - version: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) webpack-cli: specifier: 'catalog:' - version: 5.1.4(webpack@5.98.0) + version: 5.1.4(webpack@5.107.0) webpack-merge: specifier: 'catalog:' - version: 5.9.0 + version: 5.10.0 exp_util: dependencies: @@ -272,22 +251,22 @@ importers: devDependencies: '@clusterio/lib': specifier: 'catalog:' - version: 2.0.0-alpha.22b + version: 2.0.0-alpha.25 '@types/node': specifier: 'catalog:' - version: 20.19.29 + version: 20.19.41 typescript: specifier: 'catalog:' version: 5.9.3 webpack: specifier: 'catalog:' - version: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) webpack-cli: specifier: 'catalog:' - version: 5.1.4(webpack@5.98.0) + version: 5.1.4(webpack@5.107.0) webpack-merge: specifier: 'catalog:' - version: 5.9.0 + version: 5.10.0 packages: @@ -325,16 +304,16 @@ packages: peerDependencies: react: '>=16.9.0' - '@babel/runtime@7.28.6': - resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} - '@clusterio/lib@2.0.0-alpha.22b': - resolution: {integrity: sha512-tzuRsAaUBkgWQIhBmvuR4ynP7oxREEHibuLNaWk3mjYl4k4boDdiPFcYhJBrdYoteYVnsS5uH6iY+14Zsepw1w==} + '@clusterio/lib@2.0.0-alpha.25': + resolution: {integrity: sha512-kFHSpgxIiQ0ZIxLEsTxXIBSMAQoOl3WlkiFYMd7xcOx+SgDbLl9mWyRiAqqydhQwmscLYCbAlV0vDUUipRUDzg==} engines: {node: '>=12'} - '@clusterio/web_ui@2.0.0-alpha.22b': - resolution: {integrity: sha512-NLVNJ77dpDDczngdqgjSWtiZKXGsrW28wM0jIhnAshPlU5VkP2d/0Z/MDLS1/CzkSvHxghNsTosaxiMN6am3mw==} + '@clusterio/web_ui@2.0.0-alpha.25': + resolution: {integrity: sha512-ROXeVLQaICE5y4jtUUmcQhOSuG6D3+qpufTLdB2c57pO7i1RNBTo3lgbSfN7shy4HDWFd3n3r4VTNCav2pZGRQ==} engines: {node: '>=12'} '@colors/colors@1.6.0': @@ -354,14 +333,6 @@ packages: '@emotion/unitless@0.7.5': resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -394,8 +365,8 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - '@rc-component/mini-decimal@1.1.0': - resolution: {integrity: sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==} + '@rc-component/mini-decimal@1.1.3': + resolution: {integrity: sha512-bk/FJ09fLf+NLODMAFll6CfYrHPBioTedhW6lxDBuuWucJEqFUd4l/D/5JgIi3dina6sYahB8iuPAZTNz2pMxw==} engines: {node: '>=8.x'} '@rc-component/mutate-observer@1.1.0': @@ -412,8 +383,8 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - '@rc-component/qrcode@1.0.1': - resolution: {integrity: sha512-g8eeeaMyFXVlq8cZUeaxCDhfIYjpao0l9cvm5gFwKXy/Vm1yDWV7h2sjH5jHYzdFedlVKBpATFB1VKMrHzwaWQ==} + '@rc-component/qrcode@1.1.1': + resolution: {integrity: sha512-LfLGNymzKdUPjXUbRP+xOhIWY4jQ+YMj5MmWAcgcAq1Ij8XP7tRmAXqyuv96XvLUBE/5cA8hLFl9eO1JQMujrA==} engines: {node: '>=8.x'} peerDependencies: react: '>=16.9.0' @@ -443,68 +414,86 @@ packages: '@so-ric/colorspace@1.1.6': resolution: {integrity: sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==} - '@swc/core-darwin-arm64@1.15.8': - resolution: {integrity: sha512-M9cK5GwyWWRkRGwwCbREuj6r8jKdES/haCZ3Xckgkl8MUQJZA3XB7IXXK1IXRNeLjg6m7cnoMICpXv1v1hlJOg==} + '@swc/core-darwin-arm64@1.15.33': + resolution: {integrity: sha512-N+L0uXhuO7FIfzqwgxmzv0zIpV0qEp8wPX3QQs2p4atjMoywup2JTeDlXPw+z9pWJGCae3JjM+tZ6myclI+2gA==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.15.8': - resolution: {integrity: sha512-j47DasuOvXl80sKJHSi2X25l44CMc3VDhlJwA7oewC1nV1VsSzwX+KOwE5tLnfORvVJJyeiXgJORNYg4jeIjYQ==} + '@swc/core-darwin-x64@1.15.33': + resolution: {integrity: sha512-/Il4QHSOhV4FekbsDtkrNmKbsX26oSysvgrRswa/RYOHXAkwXDbB4jaeKq6PsJLSPkzJ2KzQ061gtBnk0vNHfA==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.15.8': - resolution: {integrity: sha512-siAzDENu2rUbwr9+fayWa26r5A9fol1iORG53HWxQL1J8ym4k7xt9eME0dMPXlYZDytK5r9sW8zEA10F2U3Xwg==} + '@swc/core-linux-arm-gnueabihf@1.15.33': + resolution: {integrity: sha512-C64hBnBxq4viOPQ8hlx+2lJ23bzZBGnjw7ryALmS+0Q3zHmwO8lw1/DArLENw4Q18/0w5wdEO1k3m1wWNtKGqQ==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.15.8': - resolution: {integrity: sha512-o+1y5u6k2FfPYbTRUPvurwzNt5qd0NTumCTFscCNuBksycloXY16J8L+SMW5QRX59n4Hp9EmFa3vpvNHRVv1+Q==} + '@swc/core-linux-arm64-gnu@1.15.33': + resolution: {integrity: sha512-TRJfnJbX3jqpxRDRoieMzRiCBS5jOmXNb3iQXmcgjFEHKLnAgK1RZRU8Cq1MsPqO4jAJp/ld1G4O3fXuxv85uw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [glibc] - '@swc/core-linux-arm64-musl@1.15.8': - resolution: {integrity: sha512-koiCqL09EwOP1S2RShCI7NbsQuG6r2brTqUYE7pV7kZm9O17wZ0LSz22m6gVibpwEnw8jI3IE1yYsQTVpluALw==} + '@swc/core-linux-arm64-musl@1.15.33': + resolution: {integrity: sha512-il7tYM+CpUNzieQbwAjFT1P8zqAhmGWNAGhQZBnxurXZ0aNn+5nqYFTEUKNZl7QibtT0uQXzTZrNGHCIj6Y1Og==} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [musl] - '@swc/core-linux-x64-gnu@1.15.8': - resolution: {integrity: sha512-4p6lOMU3bC+Vd5ARtKJ/FxpIC5G8v3XLoPEZ5s7mLR8h7411HWC/LmTXDHcrSXRC55zvAVia1eldy6zDLz8iFQ==} + '@swc/core-linux-ppc64-gnu@1.15.33': + resolution: {integrity: sha512-ZtNBwN0Z7CFj9Il0FcPaKdjgP7URyKu/3RfH46vq+0paOBqLj4NYldD6Qo//Duif/7IOtAraUfDOmp0PLAufog==} + engines: {node: '>=10'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-s390x-gnu@1.15.33': + resolution: {integrity: sha512-De1IyajoOmhOYYjw/lx66bKlyDpHZTueqwpDrWgf5O7T6d1ODeJJO9/OqMBmrBQc5C+dNnlmIufHsp4QVCWufA==} + engines: {node: '>=10'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@swc/core-linux-x64-gnu@1.15.33': + resolution: {integrity: sha512-mGTH0YxmUN+x6vRN/I6NOk5X0ogNktkwPnJ94IMvR7QjhRDwL0O8RXEDhyUM0YtwWrryBOqaJQBX4zruxEPRGw==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [glibc] - '@swc/core-linux-x64-musl@1.15.8': - resolution: {integrity: sha512-z3XBnbrZAL+6xDGAhJoN4lOueIxC/8rGrJ9tg+fEaeqLEuAtHSW2QHDHxDwkxZMjuF/pZ6MUTjHjbp8wLbuRLA==} + '@swc/core-linux-x64-musl@1.15.33': + resolution: {integrity: sha512-hj628ZkSEJf6zMf5VMbYrG2O6QqyTIp2qwY6VlCjvIa9lAEZ5c2lfPblCLVGYubTeLJDxadLB/CxqQYOQABeEQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [musl] - '@swc/core-win32-arm64-msvc@1.15.8': - resolution: {integrity: sha512-djQPJ9Rh9vP8GTS/Df3hcc6XP6xnG5c8qsngWId/BLA9oX6C7UzCPAn74BG/wGb9a6j4w3RINuoaieJB3t+7iQ==} + '@swc/core-win32-arm64-msvc@1.15.33': + resolution: {integrity: sha512-GV2oohtN2/5+KSccl86VULu3aT+LrISC8uzgSq0FRnikpD+Zwc+sBlXmoKQ+Db6jI57ITUOIB8jRkdGMABC29g==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.15.8': - resolution: {integrity: sha512-/wfAgxORg2VBaUoFdytcVBVCgf1isWZIEXB9MZEUty4wwK93M/PxAkjifOho9RN3WrM3inPLabICRCEgdHpKKQ==} + '@swc/core-win32-ia32-msvc@1.15.33': + resolution: {integrity: sha512-gtyvzSNR8DHKfFEA2uqb8Ld1myqi6uEg2jyeUq3ikn5ytYs7H8RpZYC8mdy4NXr8hfcdJfCLXPlYaqqfBXpoEQ==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.15.8': - resolution: {integrity: sha512-GpMePrh9Sl4d61o4KAHOOv5is5+zt6BEXCOCgs/H0FLGeii7j9bWDE8ExvKFy2GRRZVNR1ugsnzaGWHKM6kuzA==} + '@swc/core-win32-x64-msvc@1.15.33': + resolution: {integrity: sha512-d6fRqQSkJI+kmMEBWaDQ7TMl8+YjLYbwRUPZQ9DY0ORBJeTzOrG0twvfvlZ2xgw6jA0ScQKgfBm4vHLSLl5Hqg==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.15.8': - resolution: {integrity: sha512-T8keoJjXaSUoVBCIjgL6wAnhADIb09GOELzKg10CjNg+vLX48P93SME6jTfte9MZIm5m+Il57H3rTSk/0kzDUw==} + '@swc/core@1.15.33': + resolution: {integrity: sha512-jOlwnFV2xhuuZeAUILGFULeR6vDPfijEJ57evfocwznQldLU3w2cZ9bSDryY9ip+AsM3r1NJKzf47V2NXebkeQ==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -515,20 +504,11 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/types@0.1.25': - resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} + '@swc/types@0.1.26': + resolution: {integrity: sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==} - '@types/eslint-scope@3.7.7': - resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} - - '@types/eslint@9.6.1': - resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/fs-extra@11.0.4': - resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} '@types/glob@7.2.0': resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} @@ -536,24 +516,18 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/jsonfile@6.1.4': - resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - '@types/minimatch@6.0.0': resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. - '@types/node@20.19.29': - resolution: {integrity: sha512-YrT9ArrGaHForBaCNwFjoqJWmn8G1Pr7+BH/vwyLHciA9qT/wSiuOhxGCT50JA5xLvFBd6PIiGkE3afxcPE1nw==} + '@types/node@20.19.41': + resolution: {integrity: sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==} '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - '@types/react@18.2.0': - resolution: {integrity: sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA==} - - '@types/scheduler@0.26.0': - resolution: {integrity: sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA==} + '@types/react@18.3.29': + resolution: {integrity: sha512-ch0qJdr2JY0r04NXSprbK6TXOgnaJ1Tz23fm5W+z0/CBah6BSBc3n96h7K9GOtwh0HrilNWHIBzE1Ko4Dcw/Wg==} '@types/triple-beam@1.3.5': resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} @@ -634,8 +608,14 @@ packages: '@xtuc/long@4.2.2': resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} hasBin: true @@ -652,11 +632,11 @@ packages: peerDependencies: ajv: ^8.8.2 - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} - ajv@8.17.1: - resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -666,8 +646,8 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - antd@5.24.2: - resolution: {integrity: sha512-7Z9HsE3ZIK3sE/WuUqii3w7Gl1IJuRL21sDUTtkN95JS5KhRYP8ISv7m/HxsJ3Mn/yxgojBCgLPJ212+Dn+aPw==} + antd@5.29.3: + resolution: {integrity: sha512-3DdbGCa9tWAJGcCJ6rzR8EJFsv2CtyEbkVabZE14pfgUHfCicWCj0/QzQVLDYg8CPfQk9BH7fHCoTXHTy7MP/A==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' @@ -696,24 +676,33 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.9.14: - resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==} + baseline-browser-mapping@2.10.31: + resolution: {integrity: sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==} + engines: {node: '>=6.0.0'} hasBin: true big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} browserify-zlib@0.2.0: resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} - browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -727,16 +716,16 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} engines: {node: '>= 0.4'} call-bound@1.0.4: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} - caniuse-lite@1.0.30001764: - resolution: {integrity: sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==} + caniuse-lite@1.0.30001793: + resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -832,8 +821,8 @@ packages: csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - dayjs@1.11.19: - resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} @@ -851,8 +840,8 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - electron-to-chromium@1.5.267: - resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + electron-to-chromium@1.5.360: + resolution: {integrity: sha512-GkcBt6YYAw9SxFWn+xVar4cLVGlXVuswwtRLBozi2zp0GjXs4ZnOrqV4zbXzg35n7w81hCkyJNYicgXlVHAmBA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -864,8 +853,8 @@ packages: enabled@2.0.0: resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} - enhanced-resolve@5.18.4: - resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + enhanced-resolve@5.21.6: + resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==} engines: {node: '>=10.13.0'} envinfo@7.21.0: @@ -881,8 +870,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} @@ -918,8 +907,8 @@ packages: fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-uri@3.1.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} @@ -938,6 +927,10 @@ packages: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + fn.name@1.1.0: resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} @@ -945,10 +938,6 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} - fs-extra@11.3.3: - resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} - engines: {node: '>=14.14'} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -976,7 +965,7 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me globby@6.1.0: resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} @@ -1004,8 +993,8 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} engines: {node: '>= 0.4'} icss-utils@5.1.0: @@ -1044,8 +1033,8 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} engines: {node: '>= 0.4'} is-fullwidth-code-point@3.0.0: @@ -1105,9 +1094,6 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -1122,9 +1108,6 @@ packages: engines: {node: '>=6'} hasBin: true - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} - jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} @@ -1132,18 +1115,14 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - klaw@4.1.0: - resolution: {integrity: sha512-1zGZ9MF9H22UnkpVeuaGKOjfA2t6WrfdrJmGjy16ykcjnKQDmHVX+KI477rpbGevz/5FD4MC3xf1oxylBgcaQw==} - engines: {node: '>=14.14.0'} - kuler@2.0.0: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - loader-runner@4.3.1: - resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + loader-runner@4.3.2: + resolution: {integrity: sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==} engines: {node: '>=6.11.5'} loader-utils@2.0.4: @@ -1169,34 +1148,30 @@ packages: merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + node-releases@2.0.44: + resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==} null-loader@4.0.1: resolution: {integrity: sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==} @@ -1327,8 +1302,8 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} process-nextick-args@2.0.1: @@ -1342,11 +1317,8 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - - rc-cascader@3.33.1: - resolution: {integrity: sha512-Kyl4EJ7ZfCBuidmZVieegcbFw0RcU5bHHSbtEdmuLYd0fYHCAiYKZ6zon7fWAVyC6rWWOOib0XKdTSf7ElC9rg==} + rc-cascader@3.34.0: + resolution: {integrity: sha512-KpXypcvju9ptjW9FaN2NFcA2QH9E9LHKq169Y0eWtH4e/wHQ5Wh5qZakAgvb8EKZ736WZ3B0zLLOBsrsja5Dag==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' @@ -1369,8 +1341,8 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - rc-drawer@7.2.0: - resolution: {integrity: sha512-9lOQ7kBekEJRdEpScHvtmEtXnAsy+NGDXiRWc2ZVC7QXAazNVbeT4EraQKYwCME8BJLa8Bxqxvs5swwyOepRwg==} + rc-drawer@7.3.0: + resolution: {integrity: sha512-DX6CIgiBWNpJIMGFO8BAISFkxiuKitoizooj4BDyee8/SnBn0zwO2FHrNDpqqepj0E/TFTDpmEBCyFuTgC7MOg==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' @@ -1395,26 +1367,26 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - rc-image@7.11.1: - resolution: {integrity: sha512-XuoWx4KUXg7hNy5mRTy1i8c8p3K8boWg6UajbHpDXS5AlRVucNfTi5YxTtPBTBzegxAZpvuLfh3emXFt6ybUdA==} + rc-image@7.12.0: + resolution: {integrity: sha512-cZ3HTyyckPnNnUb9/DRqduqzLfrQRyi+CdHjdqgsyDpI3Ln5UX1kXnAhPBSJj9pVRzwRFgqkN7p9b6HBDjmu/Q==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' - rc-input-number@9.4.0: - resolution: {integrity: sha512-Tiy4DcXcFXAf9wDhN8aUAyMeCLHJUHA/VA/t7Hj8ZEx5ETvxG7MArDOSE6psbiSCo+vJPm4E3fGN710ITVn6GA==} + rc-input-number@9.5.0: + resolution: {integrity: sha512-bKaEvB5tHebUURAEXw35LDcnRZLq3x1k7GxfAqBMzmpHkDGzjAtnUL8y4y5N15rIFIg5IJgwr211jInl3cipag==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' - rc-input@1.7.3: - resolution: {integrity: sha512-A5w4egJq8+4JzlQ55FfQjDnPvOaAbzwC3VLOAdOytyek3TboSOP9qxN+Gifup+shVXfvecBLBbWBpWxmk02SWQ==} + rc-input@1.8.0: + resolution: {integrity: sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==} peerDependencies: react: '>=16.0.0' react-dom: '>=16.0.0' - rc-mentions@2.19.1: - resolution: {integrity: sha512-KK3bAc/bPFI993J3necmaMXD2reZTzytZdlTvkeBbp50IGH1BDPDvxLdHDUrpQx2b2TGaVJsn+86BvYa03kGqA==} + rc-mentions@2.20.0: + resolution: {integrity: sha512-w8HCMZEh3f0nR8ZEd466ATqmXFCMGMN5UFCzEUL0bM/nGw/wOS2GgRzKBcm19K++jDyuWCOJOdgcKGXU3fXfbQ==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' @@ -1522,22 +1494,22 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - rc-table@7.50.5: - resolution: {integrity: sha512-FDZu8aolhSYd3v9KOc3lZOVAU77wmRRu44R0Wfb8Oj1dXRUsloFaXMSl6f7yuWZUxArJTli7k8TEOX2mvhDl4A==} + rc-table@7.54.0: + resolution: {integrity: sha512-/wDTkki6wBTjwylwAGjpLKYklKo9YgjZwAU77+7ME5mBoS32Q4nAwoqhA2lSge6fobLW3Tap6uc5xfwaL2p0Sw==} engines: {node: '>=8.x'} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' - rc-tabs@15.5.2: - resolution: {integrity: sha512-Hbqf2IV6k/jPgfMjPtIDmPV0D0C9c/fN4B/fYcoh9qqaUzUZQoK0PYzsV3UaV+3UsmyoYt48p74m/HkLhGTw+w==} + rc-tabs@15.7.0: + resolution: {integrity: sha512-ZepiE+6fmozYdWf/9gVp7k56PKHB1YYoDsKeQA1CBlJ/POIhjkcYiv0AGP0w2Jhzftd3AVvZP/K+V+Lpi2ankA==} engines: {node: '>=8.x'} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' - rc-textarea@1.9.0: - resolution: {integrity: sha512-dQW/Bc/MriPBTugj2Kx9PMS5eXCCGn2cxoIaichjbNvOiARlaHdI99j4DTxLl/V8+PIfW06uFy7kjfUIDDKyxQ==} + rc-textarea@1.10.2: + resolution: {integrity: sha512-HfaeXiaSlpiSp0I/pvWpecFEHpVysZ9tpDLNkxQbMvMz6gsr7aVZ7FpWP9kt4t7DB+jJXesYS0us1uPZnlRnwQ==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' @@ -1561,8 +1533,8 @@ packages: react: '*' react-dom: '*' - rc-upload@4.8.1: - resolution: {integrity: sha512-toEAhwl4hjLAI1u8/CgKWt30BR06ulPa4iGQSMvSXoHzO88gPCslxqV/mnn4gJU7PDoltGIC9Eh+wkeudqgHyw==} + rc-upload@4.11.0: + resolution: {integrity: sha512-ZUyT//2JAehfHzjWowqROcwYJKnZkIUGWaTE/VogVrepSl7AFNbQf4+zGfX4zl9Vrj/Jm8scLO0R6UlPDKK4wA==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' @@ -1580,10 +1552,10 @@ packages: react: '>=16.9.0' react-dom: '>=16.9.0' - react-dom@18.2.0: - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: - react: ^18.2.0 + react: ^18.3.1 react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} @@ -1601,8 +1573,8 @@ packages: peerDependencies: react: '>=16.8' - react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} readable-stream@2.3.8: @@ -1635,8 +1607,8 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} engines: {node: '>= 0.4'} hasBin: true @@ -1673,14 +1645,11 @@ packages: scroll-into-view-if-needed@3.1.0: resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + semver@7.8.0: + resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} engines: {node: '>=10'} hasBin: true - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -1746,8 +1715,8 @@ packages: peerDependencies: webpack: ^5.0.0 - stylis@4.3.6: - resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} + stylis@4.4.0: + resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==} supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} @@ -1767,28 +1736,55 @@ packages: '@swc/core': ^1.2.147 webpack: '>=2' - tapable@2.3.0: - resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} - terser-webpack-plugin@5.3.16: - resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} + terser-webpack-plugin@5.6.0: + resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==} engines: {node: '>= 10.13.0'} peerDependencies: + '@minify-html/node': '*' '@swc/core': '*' + '@swc/css': '*' + '@swc/html': '*' + clean-css: '*' + cssnano: '*' + csso: '*' esbuild: '*' + html-minifier-terser: '*' + lightningcss: '*' + postcss: '*' uglify-js: '*' webpack: ^5.1.0 peerDependenciesMeta: + '@minify-html/node': + optional: true '@swc/core': optional: true + '@swc/css': + optional: true + '@swc/html': + optional: true + clean-css: + optional: true + cssnano: + optional: true + csso: + optional: true esbuild: optional: true + html-minifier-terser: + optional: true + lightningcss: + optional: true + postcss: + optional: true uglify-js: optional: true - terser@5.44.1: - resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==} + terser@5.47.1: + resolution: {integrity: sha512-tPbLXTI6ohPASb/1YViL428oEHu6/qv1OxqYnfaonVCFHqx4+wCd95pHrQWsL5X4pl90CTyW9piSAsS2L0VoMw==} engines: {node: '>=10'} hasBin: true @@ -1814,10 +1810,6 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -1833,8 +1825,8 @@ packages: util@0.12.5: resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} - watchpack@2.5.0: - resolution: {integrity: sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==} + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} engines: {node: '>=10.13.0'} webpack-cli@5.1.4: @@ -1860,20 +1852,20 @@ packages: peerDependencies: webpack: ^5.75.0 - webpack-merge@5.9.0: - resolution: {integrity: sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==} + webpack-merge@5.10.0: + resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} engines: {node: '>=10.0.0'} webpack-sources@2.3.1: resolution: {integrity: sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==} engines: {node: '>=10.13.0'} - webpack-sources@3.3.3: - resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + webpack-sources@3.4.1: + resolution: {integrity: sha512-eACpxRN02yaawnt+uUNIF7Qje6A9zArxBbcAJjK1PK3S9Ycg5jIuJ8pW4q8EMnwNZCEGltcjkRx1QzOxOkKD8A==} engines: {node: '>=10.13.0'} - webpack@5.98.0: - resolution: {integrity: sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==} + webpack@5.107.0: + resolution: {integrity: sha512-PSxeHk/dmLYZlnTU+vL1Gej6Evg5RNtl3flhxBresfznFnzxinHMzHKloHnywM/3ouQv7/AlZCswWDIkNSggUA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -1882,8 +1874,8 @@ packages: webpack-cli: optional: true - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} engines: {node: '>= 0.4'} which@2.0.2: @@ -1909,8 +1901,8 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.19.0: - resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + ws@8.20.1: + resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -1939,112 +1931,119 @@ snapshots: dependencies: '@ant-design/fast-color': 2.0.6 - '@ant-design/cssinjs-utils@1.1.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@ant-design/cssinjs-utils@1.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@ant-design/cssinjs': 1.24.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@babel/runtime': 7.28.6 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + '@ant-design/cssinjs': 1.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@babel/runtime': 7.29.2 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@ant-design/cssinjs@1.24.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@ant-design/cssinjs@1.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@emotion/hash': 0.8.0 '@emotion/unitless': 0.7.5 classnames: 2.5.1 csstype: 3.2.3 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - stylis: 4.3.6 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + stylis: 4.4.0 '@ant-design/fast-color@2.0.6': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@ant-design/icons-svg@4.4.2': {} - '@ant-design/icons@5.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@ant-design/icons@5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@ant-design/colors': 7.2.1 '@ant-design/icons-svg': 4.4.2 - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@ant-design/react-slick@1.1.2(react@18.2.0)': + '@ant-design/react-slick@1.1.2(react@18.3.1)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 json2mq: 0.2.0 - react: 18.2.0 + react: 18.3.1 resize-observer-polyfill: 1.5.1 throttle-debounce: 5.0.2 - '@babel/runtime@7.28.6': {} + '@babel/runtime@7.29.2': {} - '@clusterio/lib@2.0.0-alpha.22b': + '@clusterio/lib@2.0.0-alpha.25': dependencies: '@sinclair/typebox': 0.30.4 - ajv: 8.17.1 + ajv: 8.20.0 chalk: 4.1.2 fast-deep-equal: 3.1.3 - fs-extra: 11.3.3 jszip: 3.10.1 - klaw: 4.1.0 set-blocking: 2.0.0 triple-beam: 1.4.1 winston: 3.19.0 winston-transport: 4.9.0 - ws: 8.19.0 + ws: 8.20.1 yargs: 17.7.2 transitivePeerDependencies: - bufferutil - utf-8-validate - '@clusterio/web_ui@2.0.0-alpha.22b': + '@clusterio/web_ui@2.0.0-alpha.25': dependencies: - '@ant-design/icons': 5.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@clusterio/lib': 2.0.0-alpha.22b + '@ant-design/icons': 5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@clusterio/lib': 2.0.0-alpha.25 '@sinclair/typebox': 0.30.4 - '@swc/core': 1.15.8 - antd: 5.24.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@swc/core': 1.15.33 + antd: 5.29.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) assert: 2.1.0 browserify-zlib: 0.2.0 buffer: 6.0.3 - clean-webpack-plugin: 4.0.0(webpack@5.98.0) - css-loader: 6.11.0(webpack@5.98.0) + clean-webpack-plugin: 4.0.0(webpack@5.107.0) + css-loader: 6.11.0(webpack@5.107.0) events: 3.3.0 - file-loader: 6.2.0(webpack@5.98.0) - null-loader: 4.0.1(webpack@5.98.0) + file-loader: 6.2.0(webpack@5.107.0) + null-loader: 4.0.1(webpack@5.107.0) os-browserify: 0.3.0 path-browserify: 1.0.1 process: 0.11.10 - rc-field-form: 1.44.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-router-dom: 6.30.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + rc-field-form: 1.44.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router-dom: 6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) stream-browserify: 3.0.0 - style-loader: 3.3.4(webpack@5.98.0) - swc-loader: 0.2.7(@swc/core@1.15.8)(webpack@5.98.0) - terser-webpack-plugin: 5.3.16(@swc/core@1.15.8)(webpack@5.98.0) + style-loader: 3.3.4(webpack@5.107.0) + swc-loader: 0.2.7(@swc/core@1.15.33)(webpack@5.107.0) + terser-webpack-plugin: 5.6.0(@swc/core@1.15.33)(webpack@5.107.0) typescript: 5.9.3 util: 0.12.5 - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.98.0) - webpack-manifest-plugin: 5.0.1(webpack@5.98.0) + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack@5.107.0) + webpack-manifest-plugin: 5.0.1(webpack@5.107.0) transitivePeerDependencies: + - '@minify-html/node' - '@rspack/core' + - '@swc/css' - '@swc/helpers' + - '@swc/html' - '@webpack-cli/generators' - bufferutil + - clean-css + - cssnano + - csso - date-fns - esbuild + - html-minifier-terser + - lightningcss - luxon - moment + - postcss - uglify-js - utf-8-validate - webpack-bundle-analyzer @@ -2064,12 +2063,6 @@ snapshots: '@emotion/unitless@0.7.5': {} - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': - dependencies: - '@isaacs/balanced-match': 4.0.1 - '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -2091,71 +2084,70 @@ snapshots: '@rc-component/async-validator@5.1.0': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 - '@rc-component/color-picker@2.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@rc-component/color-picker@2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@ant-design/fast-color': 2.0.6 - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@rc-component/context@1.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@rc-component/context@1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.28.6 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + '@babel/runtime': 7.29.2 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@rc-component/mini-decimal@1.1.0': + '@rc-component/mini-decimal@1.1.3': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 - '@rc-component/mutate-observer@1.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@rc-component/mutate-observer@1.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@rc-component/portal@1.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@rc-component/portal@1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@rc-component/qrcode@1.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@rc-component/qrcode@1.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.28.6 - classnames: 2.5.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + '@babel/runtime': 7.29.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@rc-component/tour@1.15.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@rc-component/tour@1.15.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/portal': 1.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@rc-component/trigger': 2.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@rc-component/trigger@2.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@rc-component/trigger@2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/portal': 1.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-resize-observer: 1.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) '@remix-run/router@1.23.2': {} @@ -2166,104 +2158,90 @@ snapshots: color: 5.0.3 text-hex: 1.0.0 - '@swc/core-darwin-arm64@1.15.8': + '@swc/core-darwin-arm64@1.15.33': + optional: true + + '@swc/core-darwin-x64@1.15.33': optional: true - '@swc/core-darwin-x64@1.15.8': + '@swc/core-linux-arm-gnueabihf@1.15.33': optional: true - '@swc/core-linux-arm-gnueabihf@1.15.8': + '@swc/core-linux-arm64-gnu@1.15.33': optional: true - '@swc/core-linux-arm64-gnu@1.15.8': + '@swc/core-linux-arm64-musl@1.15.33': optional: true - '@swc/core-linux-arm64-musl@1.15.8': + '@swc/core-linux-ppc64-gnu@1.15.33': optional: true - '@swc/core-linux-x64-gnu@1.15.8': + '@swc/core-linux-s390x-gnu@1.15.33': optional: true - '@swc/core-linux-x64-musl@1.15.8': + '@swc/core-linux-x64-gnu@1.15.33': optional: true - '@swc/core-win32-arm64-msvc@1.15.8': + '@swc/core-linux-x64-musl@1.15.33': optional: true - '@swc/core-win32-ia32-msvc@1.15.8': + '@swc/core-win32-arm64-msvc@1.15.33': optional: true - '@swc/core-win32-x64-msvc@1.15.8': + '@swc/core-win32-ia32-msvc@1.15.33': optional: true - '@swc/core@1.15.8': + '@swc/core-win32-x64-msvc@1.15.33': + optional: true + + '@swc/core@1.15.33': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.25 + '@swc/types': 0.1.26 optionalDependencies: - '@swc/core-darwin-arm64': 1.15.8 - '@swc/core-darwin-x64': 1.15.8 - '@swc/core-linux-arm-gnueabihf': 1.15.8 - '@swc/core-linux-arm64-gnu': 1.15.8 - '@swc/core-linux-arm64-musl': 1.15.8 - '@swc/core-linux-x64-gnu': 1.15.8 - '@swc/core-linux-x64-musl': 1.15.8 - '@swc/core-win32-arm64-msvc': 1.15.8 - '@swc/core-win32-ia32-msvc': 1.15.8 - '@swc/core-win32-x64-msvc': 1.15.8 + '@swc/core-darwin-arm64': 1.15.33 + '@swc/core-darwin-x64': 1.15.33 + '@swc/core-linux-arm-gnueabihf': 1.15.33 + '@swc/core-linux-arm64-gnu': 1.15.33 + '@swc/core-linux-arm64-musl': 1.15.33 + '@swc/core-linux-ppc64-gnu': 1.15.33 + '@swc/core-linux-s390x-gnu': 1.15.33 + '@swc/core-linux-x64-gnu': 1.15.33 + '@swc/core-linux-x64-musl': 1.15.33 + '@swc/core-win32-arm64-msvc': 1.15.33 + '@swc/core-win32-ia32-msvc': 1.15.33 + '@swc/core-win32-x64-msvc': 1.15.33 '@swc/counter@0.1.3': {} - '@swc/types@0.1.25': + '@swc/types@0.1.26': dependencies: '@swc/counter': 0.1.3 - '@types/eslint-scope@3.7.7': - dependencies: - '@types/eslint': 9.6.1 - '@types/estree': 1.0.8 - - '@types/eslint@9.6.1': - dependencies: - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - - '@types/estree@1.0.8': {} - - '@types/fs-extra@11.0.4': - dependencies: - '@types/jsonfile': 6.1.4 - '@types/node': 20.19.29 + '@types/estree@1.0.9': {} '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 20.19.29 + '@types/node': 20.19.41 '@types/json-schema@7.0.15': {} - '@types/jsonfile@6.1.4': - dependencies: - '@types/node': 20.19.29 - '@types/minimatch@6.0.0': dependencies: - minimatch: 10.1.1 + minimatch: 10.2.5 - '@types/node@20.19.29': + '@types/node@20.19.41': dependencies: undici-types: 6.21.0 '@types/prop-types@15.7.15': {} - '@types/react@18.2.0': + '@types/react@18.3.29': dependencies: '@types/prop-types': 15.7.15 - '@types/scheduler': 0.26.0 csstype: 3.2.3 - '@types/scheduler@0.26.0': {} - '@types/triple-beam@1.3.5': {} '@webassemblyjs/ast@1.14.1': @@ -2342,51 +2320,55 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.98.0)': + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.107.0)': dependencies: - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.98.0) + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack@5.107.0) - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.98.0)': + '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.107.0)': dependencies: - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.98.0) + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack@5.107.0) - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack@5.98.0)': + '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack@5.107.0)': dependencies: - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.98.0) + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack@5.107.0) '@xtuc/ieee754@1.2.0': {} '@xtuc/long@4.2.2': {} - acorn@8.15.0: {} + acorn-import-phases@1.0.4(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} ajv-formats@2.1.1: dependencies: - ajv: 8.17.1 + ajv: 8.20.0 - ajv-keywords@3.5.2(ajv@6.12.6): + ajv-keywords@3.5.2(ajv@6.15.0): dependencies: - ajv: 6.12.6 + ajv: 6.15.0 - ajv-keywords@5.1.0(ajv@8.17.1): + ajv-keywords@5.1.0(ajv@8.20.0): dependencies: - ajv: 8.17.1 + ajv: 8.20.0 fast-deep-equal: 3.1.3 - ajv@6.12.6: + ajv@6.15.0: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.17.1: + ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 + fast-uri: 3.1.2 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -2396,57 +2378,57 @@ snapshots: dependencies: color-convert: 2.0.1 - antd@5.24.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + antd@5.29.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@ant-design/colors': 7.2.1 - '@ant-design/cssinjs': 1.24.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@ant-design/cssinjs-utils': 1.1.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@ant-design/cssinjs': 1.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ant-design/cssinjs-utils': 1.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@ant-design/fast-color': 2.0.6 - '@ant-design/icons': 5.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@ant-design/react-slick': 1.1.2(react@18.2.0) - '@babel/runtime': 7.28.6 - '@rc-component/color-picker': 2.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@rc-component/mutate-observer': 1.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@rc-component/qrcode': 1.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@rc-component/tour': 1.15.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@rc-component/trigger': 2.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@ant-design/icons': 5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ant-design/react-slick': 1.1.2(react@18.3.1) + '@babel/runtime': 7.29.2 + '@rc-component/color-picker': 2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/mutate-observer': 1.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/qrcode': 1.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/tour': 1.15.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 copy-to-clipboard: 3.3.3 - dayjs: 1.11.19 - rc-cascader: 3.33.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-checkbox: 3.5.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-collapse: 3.9.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-dialog: 9.6.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-drawer: 7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-dropdown: 4.2.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-field-form: 2.7.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-image: 7.11.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-input: 1.7.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-input-number: 9.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-mentions: 2.19.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-menu: 9.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-notification: 5.6.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-pagination: 5.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-picker: 4.11.3(dayjs@1.11.19)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-progress: 4.0.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-rate: 2.13.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-resize-observer: 1.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-segmented: 2.7.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-select: 14.16.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-slider: 11.1.9(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-steps: 6.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-switch: 4.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-table: 7.50.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-tabs: 15.5.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-textarea: 1.9.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-tooltip: 6.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-tree: 5.13.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-tree-select: 5.27.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-upload: 4.8.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + dayjs: 1.11.20 + rc-cascader: 3.34.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-checkbox: 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-collapse: 3.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-dialog: 9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-drawer: 7.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-dropdown: 4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-field-form: 2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-image: 7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-input-number: 9.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-mentions: 2.20.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-menu: 9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-notification: 5.6.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-pagination: 5.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-picker: 4.11.3(dayjs@1.11.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-progress: 4.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-rate: 2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-segmented: 2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-select: 14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-slider: 11.1.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-steps: 6.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-switch: 4.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-table: 7.54.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tabs: 15.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-textarea: 1.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tooltip: 6.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree: 5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree-select: 5.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-upload: 4.11.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) scroll-into-view-if-needed: 3.1.0 throttle-debounce: 5.0.2 transitivePeerDependencies: @@ -2462,7 +2444,7 @@ snapshots: assert@2.1.0: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 is-nan: 1.3.2 object-is: 1.1.6 object.assign: 4.1.7 @@ -2478,28 +2460,34 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base64-js@1.5.1: {} - baseline-browser-mapping@2.9.14: {} + baseline-browser-mapping@2.10.31: {} big.js@5.2.2: {} - brace-expansion@1.1.12: + brace-expansion@1.1.14: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + browserify-zlib@0.2.0: dependencies: pako: 1.0.11 - browserslist@4.28.1: + browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.9.14 - caniuse-lite: 1.0.30001764 - electron-to-chromium: 1.5.267 - node-releases: 2.0.27 - update-browserslist-db: 1.2.3(browserslist@4.28.1) + baseline-browser-mapping: 2.10.31 + caniuse-lite: 1.0.30001793 + electron-to-chromium: 1.5.360 + node-releases: 2.0.44 + update-browserslist-db: 1.2.3(browserslist@4.28.2) buffer-from@1.1.2: {} @@ -2513,7 +2501,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - call-bind@1.0.8: + call-bind@1.0.9: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 @@ -2525,7 +2513,7 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 - caniuse-lite@1.0.30001764: {} + caniuse-lite@1.0.30001793: {} chalk@4.1.2: dependencies: @@ -2536,10 +2524,10 @@ snapshots: classnames@2.5.1: {} - clean-webpack-plugin@4.0.0(webpack@5.98.0): + clean-webpack-plugin@4.0.0(webpack@5.107.0): dependencies: del: 4.1.1 - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) cliui@8.0.1: dependencies: @@ -2596,24 +2584,24 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-loader@6.11.0(webpack@5.98.0): + css-loader@6.11.0(webpack@5.107.0): dependencies: - icss-utils: 5.1.0(postcss@8.5.6) - postcss: 8.5.6 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.6) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.6) - postcss-modules-scope: 3.2.1(postcss@8.5.6) - postcss-modules-values: 4.0.0(postcss@8.5.6) + icss-utils: 5.1.0(postcss@8.5.15) + postcss: 8.5.15 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.15) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.15) + postcss-modules-scope: 3.2.1(postcss@8.5.15) + postcss-modules-values: 4.0.0(postcss@8.5.15) postcss-value-parser: 4.2.0 - semver: 7.7.3 + semver: 7.8.0 optionalDependencies: - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) cssesc@3.0.0: {} csstype@3.2.3: {} - dayjs@1.11.19: {} + dayjs@1.11.20: {} define-data-property@1.1.4: dependencies: @@ -2643,7 +2631,7 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - electron-to-chromium@1.5.267: {} + electron-to-chromium@1.5.360: {} emoji-regex@8.0.0: {} @@ -2651,10 +2639,10 @@ snapshots: enabled@2.0.0: {} - enhanced-resolve@5.18.4: + enhanced-resolve@5.21.6: dependencies: graceful-fs: 4.2.11 - tapable: 2.3.0 + tapable: 2.3.3 envinfo@7.21.0: {} @@ -2662,7 +2650,7 @@ snapshots: es-errors@1.3.0: {} - es-module-lexer@1.7.0: {} + es-module-lexer@2.1.0: {} es-object-atoms@1.1.1: dependencies: @@ -2689,35 +2677,31 @@ snapshots: fast-json-stable-stringify@2.1.0: {} - fast-uri@3.1.0: {} + fast-uri@3.1.2: {} fastest-levenshtein@1.0.16: {} fecha@4.2.3: {} - file-loader@6.2.0(webpack@5.98.0): + file-loader@6.2.0(webpack@5.107.0): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) find-up@4.1.0: dependencies: locate-path: 5.0.0 path-exists: 4.0.0 + flat@5.0.2: {} + fn.name@1.1.0: {} for-each@0.3.5: dependencies: is-callable: 1.2.7 - fs-extra@11.3.3: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.2.0 - universalify: 2.0.1 - fs.realpath@1.0.0: {} function-bind@1.1.2: {} @@ -2736,7 +2720,7 @@ snapshots: get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.2 + hasown: 2.0.3 math-intrinsics: 1.1.0 get-proto@1.0.1: @@ -2751,7 +2735,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.5 once: 1.4.0 path-is-absolute: 1.0.1 @@ -2779,13 +2763,13 @@ snapshots: dependencies: has-symbols: 1.1.0 - hasown@2.0.2: + hasown@2.0.3: dependencies: function-bind: 1.1.2 - icss-utils@5.1.0(postcss@8.5.6): + icss-utils@5.1.0(postcss@8.5.15): dependencies: - postcss: 8.5.6 + postcss: 8.5.15 ieee754@1.2.1: {} @@ -2812,9 +2796,9 @@ snapshots: is-callable@1.2.7: {} - is-core-module@2.16.1: + is-core-module@2.16.2: dependencies: - hasown: 2.0.2 + hasown: 2.0.3 is-fullwidth-code-point@3.0.0: {} @@ -2828,7 +2812,7 @@ snapshots: is-nan@1.3.2: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 is-path-cwd@2.2.0: {} @@ -2850,13 +2834,13 @@ snapshots: call-bound: 1.0.4 gopd: 1.2.0 has-tostringtag: 1.0.2 - hasown: 2.0.2 + hasown: 2.0.3 is-stream@2.0.1: {} is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 isarray@1.0.0: {} @@ -2866,14 +2850,12 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 20.19.29 + '@types/node': 20.19.41 merge-stream: 2.0.0 supports-color: 8.1.1 js-tokens@4.0.0: {} - json-parse-even-better-errors@2.3.1: {} - json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: {} @@ -2884,12 +2866,6 @@ snapshots: json5@2.2.3: {} - jsonfile@6.2.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - jszip@3.10.1: dependencies: lie: 3.3.0 @@ -2899,15 +2875,13 @@ snapshots: kind-of@6.0.3: {} - klaw@4.1.0: {} - kuler@2.0.0: {} lie@3.3.0: dependencies: immediate: 3.0.6 - loader-runner@4.3.1: {} + loader-runner@4.3.2: {} loader-utils@2.0.4: dependencies: @@ -2936,46 +2910,42 @@ snapshots: merge-stream@2.0.0: {} - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 + mime-db@1.54.0: {} - minimatch@10.1.1: + minimatch@10.2.5: dependencies: - '@isaacs/brace-expansion': 5.0.0 + brace-expansion: 5.0.6 - minimatch@3.1.2: + minimatch@3.1.5: dependencies: - brace-expansion: 1.1.12 + brace-expansion: 1.1.14 ms@2.1.3: {} - nanoid@3.3.11: {} + nanoid@3.3.12: {} neo-async@2.6.2: {} - node-releases@2.0.27: {} + node-releases@2.0.44: {} - null-loader@4.0.1(webpack@5.98.0): + null-loader@4.0.1(webpack@5.107.0): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) object-assign@4.1.1: {} object-is@1.1.6: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 object-keys@1.1.1: {} object.assign@4.1.7: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -3036,26 +3006,26 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-modules-extract-imports@3.1.0(postcss@8.5.6): + postcss-modules-extract-imports@3.1.0(postcss@8.5.15): dependencies: - postcss: 8.5.6 + postcss: 8.5.15 - postcss-modules-local-by-default@4.2.0(postcss@8.5.6): + postcss-modules-local-by-default@4.2.0(postcss@8.5.15): dependencies: - icss-utils: 5.1.0(postcss@8.5.6) - postcss: 8.5.6 + icss-utils: 5.1.0(postcss@8.5.15) + postcss: 8.5.15 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.1(postcss@8.5.6): + postcss-modules-scope@3.2.1(postcss@8.5.15): dependencies: - postcss: 8.5.6 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - postcss-modules-values@4.0.0(postcss@8.5.6): + postcss-modules-values@4.0.0(postcss@8.5.15): dependencies: - icss-utils: 5.1.0(postcss@8.5.6) - postcss: 8.5.6 + icss-utils: 5.1.0(postcss@8.5.15) + postcss: 8.5.15 postcss-selector-parser@7.1.1: dependencies: @@ -3064,9 +3034,9 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.5.6: + postcss@8.5.15: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -3076,358 +3046,354 @@ snapshots: punycode@2.3.1: {} - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - - rc-cascader@3.33.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-cascader@3.34.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-select: 14.16.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-tree: 5.13.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-select: 14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree: 5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-checkbox@3.5.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-checkbox@3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-collapse@3.9.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-collapse@3.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-dialog@9.6.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-dialog@9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/portal': 1.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-drawer@7.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-drawer@7.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/portal': 1.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-dropdown@4.2.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-dropdown@4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/trigger': 2.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-field-form@1.44.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-field-form@1.44.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 async-validator: 4.2.5 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-field-form@2.7.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 '@rc-component/async-validator': 5.1.0 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-image@7.11.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-image@7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/portal': 1.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-dialog: 9.6.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-dialog: 9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-input-number@9.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-input-number@9.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/mini-decimal': 1.1.0 + '@babel/runtime': 7.29.2 + '@rc-component/mini-decimal': 1.1.3 classnames: 2.5.1 - rc-input: 1.7.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-input@1.7.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-input@1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-mentions@2.19.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-mentions@2.20.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/trigger': 2.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-input: 1.7.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-menu: 9.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-textarea: 1.9.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-menu: 9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-textarea: 1.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-menu@9.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-menu@9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/trigger': 2.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-overflow: 1.5.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-overflow: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-motion@2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-motion@2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-notification@5.6.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-notification@5.6.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-overflow@1.5.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-overflow@1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-pagination@5.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-pagination@5.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-picker@4.11.3(dayjs@1.11.19)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-picker@4.11.3(dayjs@1.11.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/trigger': 2.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-overflow: 1.5.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-resize-observer: 1.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-overflow: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - dayjs: 1.11.19 + dayjs: 1.11.20 - rc-progress@4.0.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-progress@4.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-rate@2.13.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-rate@2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-resize-observer@1.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-resize-observer@1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) resize-observer-polyfill: 1.5.1 - rc-segmented@2.7.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-segmented@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-select@14.16.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-select@14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/trigger': 2.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-overflow: 1.5.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-virtual-list: 3.19.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-overflow: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-virtual-list: 3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-slider@11.1.9(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-slider@11.1.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-steps@6.0.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-steps@6.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-switch@4.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-switch@4.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-table@7.50.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-table@7.54.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/context': 1.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/context': 1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-virtual-list: 3.19.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-virtual-list: 3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-tabs@15.5.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-tabs@15.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-dropdown: 4.2.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-menu: 9.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-resize-observer: 1.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-dropdown: 4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-menu: 9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-textarea@1.9.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-textarea@1.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-input: 1.7.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-resize-observer: 1.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-tooltip@6.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-tooltip@6.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - '@rc-component/trigger': 2.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-tree-select@5.27.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-tree-select@5.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-select: 14.16.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-tree: 5.13.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-select: 14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree: 5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-tree@5.13.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-tree@5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-virtual-list: 3.19.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-virtual-list: 3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-upload@4.8.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-upload@4.11.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - rc-util@5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-util@5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + '@babel/runtime': 7.29.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) react-is: 18.3.1 - rc-virtual-list@3.19.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + rc-virtual-list@3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.28.6 + '@babel/runtime': 7.29.2 classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - rc-util: 5.44.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - react-dom@18.2.0(react@18.2.0): + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 - react: 18.2.0 + react: 18.3.1 scheduler: 0.23.2 react-is@18.3.1: {} - react-router-dom@6.30.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-router-dom@6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@remix-run/router': 1.23.2 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-router: 6.30.3(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router: 6.30.3(react@18.3.1) - react-router@6.30.3(react@18.2.0): + react-router@6.30.3(react@18.3.1): dependencies: '@remix-run/router': 1.23.2 - react: 18.2.0 + react: 18.3.1 - react@18.2.0: + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -3449,7 +3415,7 @@ snapshots: rechoir@0.8.0: dependencies: - resolve: 1.22.11 + resolve: 1.22.12 require-directory@2.1.1: {} @@ -3463,9 +3429,10 @@ snapshots: resolve-from@5.0.0: {} - resolve@1.22.11: + resolve@1.22.12: dependencies: - is-core-module: 2.16.1 + es-errors: 1.3.0 + is-core-module: 2.16.2 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -3492,25 +3459,21 @@ snapshots: schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) + ajv: 6.15.0 + ajv-keywords: 3.5.2(ajv@6.15.0) schema-utils@4.3.3: dependencies: '@types/json-schema': 7.0.15 - ajv: 8.17.1 + ajv: 8.20.0 ajv-formats: 2.1.1 - ajv-keywords: 5.1.0(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.20.0) scroll-into-view-if-needed@3.1.0: dependencies: compute-scroll-into-view: 3.1.1 - semver@7.7.3: {} - - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 + semver@7.8.0: {} set-blocking@2.0.0: {} @@ -3573,11 +3536,11 @@ snapshots: dependencies: ansi-regex: 5.0.1 - style-loader@3.3.4(webpack@5.98.0): + style-loader@3.3.4(webpack@5.107.0): dependencies: - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - stylis@4.3.6: {} + stylis@4.4.0: {} supports-color@7.2.0: dependencies: @@ -3589,29 +3552,28 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - swc-loader@0.2.7(@swc/core@1.15.8)(webpack@5.98.0): + swc-loader@0.2.7(@swc/core@1.15.33)(webpack@5.107.0): dependencies: - '@swc/core': 1.15.8 + '@swc/core': 1.15.33 '@swc/counter': 0.1.3 - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - tapable@2.3.0: {} + tapable@2.3.3: {} - terser-webpack-plugin@5.3.16(@swc/core@1.15.8)(webpack@5.98.0): + terser-webpack-plugin@5.6.0(@swc/core@1.15.33)(webpack@5.107.0): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - terser: 5.44.1 - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + terser: 5.47.1 + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) optionalDependencies: - '@swc/core': 1.15.8 + '@swc/core': 1.15.33 - terser@5.44.1: + terser@5.47.1: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.15.0 + acorn: 8.16.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -3627,11 +3589,9 @@ snapshots: undici-types@6.21.0: {} - universalify@2.0.1: {} - - update-browserslist-db@1.2.3(browserslist@4.28.1): + update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: - browserslist: 4.28.1 + browserslist: 4.28.2 escalade: 3.2.0 picocolors: 1.1.1 @@ -3647,19 +3607,19 @@ snapshots: is-arguments: 1.2.0 is-generator-function: 1.1.2 is-typed-array: 1.1.15 - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 - watchpack@2.5.0: + watchpack@2.5.1: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 - webpack-cli@5.1.4(webpack@5.98.0): + webpack-cli@5.1.4(webpack@5.107.0): dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.98.0) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.98.0) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack@5.98.0) + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.107.0) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.107.0) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack@5.107.0) colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.6 @@ -3668,18 +3628,19 @@ snapshots: import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) - webpack-merge: 5.9.0 + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) + webpack-merge: 5.10.0 - webpack-manifest-plugin@5.0.1(webpack@5.98.0): + webpack-manifest-plugin@5.0.1(webpack@5.107.0): dependencies: - tapable: 2.3.0 - webpack: 5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4) + tapable: 2.3.3 + webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) webpack-sources: 2.3.1 - webpack-merge@5.9.0: + webpack-merge@5.10.0: dependencies: clone-deep: 4.0.1 + flat: 5.0.2 wildcard: 2.0.1 webpack-sources@2.3.1: @@ -3687,44 +3648,53 @@ snapshots: source-list-map: 2.0.1 source-map: 0.6.1 - webpack-sources@3.3.3: {} + webpack-sources@3.4.1: {} - webpack@5.98.0(@swc/core@1.15.8)(webpack-cli@5.1.4): + webpack@5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4): dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 + '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.15.0 - browserslist: 4.28.1 + acorn: 8.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.4 - es-module-lexer: 1.7.0 + enhanced-resolve: 5.21.6 + es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.1 - mime-types: 2.1.35 + loader-runner: 4.3.2 + mime-db: 1.54.0 neo-async: 2.6.2 schema-utils: 4.3.3 - tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(@swc/core@1.15.8)(webpack@5.98.0) - watchpack: 2.5.0 - webpack-sources: 3.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(@swc/core@1.15.33)(webpack@5.107.0) + watchpack: 2.5.1 + webpack-sources: 3.4.1 optionalDependencies: - webpack-cli: 5.1.4(webpack@5.98.0) + webpack-cli: 5.1.4(webpack@5.107.0) transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - uglify-js - which-typed-array@1.1.19: + which-typed-array@1.1.20: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 for-each: 0.3.5 get-proto: 1.0.1 @@ -3765,7 +3735,7 @@ snapshots: wrappy@1.0.2: {} - ws@8.19.0: {} + ws@8.20.1: {} y18n@5.0.8: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index ca56af10fd..d881e382e3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,15 +2,15 @@ packages: - '*' catalog: - '@clusterio/lib': 2.0.0-alpha.22b - '@clusterio/web_ui': 2.0.0-alpha.22b + '@clusterio/lib': 2.0.0-alpha.25 + '@clusterio/web_ui': 2.0.0-alpha.25 '@sinclair/typebox': ^0.30.4 - '@types/node': ^20.19.29 - '@types/react': 18.2.0 - antd: 5.24.2 - react: 18.2.0 - react-dom: 18.2.0 + '@types/node': ^20.19.41 + '@types/react': ^18.3.29 + antd: ^5.29.3 + react: ^18.3.1 + react-dom: ^18.3.1 typescript: ^5.9.3 - webpack: 5.98.0 - webpack-cli: 5.1.4 - webpack-merge: 5.9.0 + webpack: ^5.107.0 + webpack-cli: ^5.1.4 + webpack-merge: ^5.10.0 From 7ddfa8e735d1cbe29e69a57b15899428c84746ac Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Wed, 20 May 2026 22:39:33 +0100 Subject: [PATCH 05/12] Add messages and permissions --- exp_groups/index.ts | 149 ++++++++++ exp_groups/messages.ts | 657 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 806 insertions(+) create mode 100644 exp_groups/messages.ts diff --git a/exp_groups/index.ts b/exp_groups/index.ts index 14fe26e062..ae6ba44171 100644 --- a/exp_groups/index.ts +++ b/exp_groups/index.ts @@ -1,19 +1,168 @@ import * as lib from "@clusterio/lib"; +import * as messages from "./messages"; declare module "@clusterio/lib" { export interface InstanceConfigFields { + "exp_groups.sync_mode": "enabled" | "disabled" | "bidirectional" } export interface ControllerConfigFields { } } +// Group permissions + +lib.definePermission({ + name: "exp_groups.group.get", + title: "Get Groups", + description: "Retrieve a specific Factorio permission group by ID.", + grantByDefault: true, +}); +lib.definePermission({ + name: "exp_groups.group.list", + title: "List Groups", + description: "List all Factorio permission groups.", + grantByDefault: true, +}); +lib.definePermission({ + name: "exp_groups.group.subscribe", + title: "Subscribe to Group Updates", + description: "Receive updates when Factorio permission groups change.", + grantByDefault: true, +}); +lib.definePermission({ + name: "exp_groups.group.create", + title: "Create Groups", + description: "Create new Factorio permission groups.", + grantByDefault: false, +}); +lib.definePermission({ + name: "exp_groups.group.update", + title: "Update Groups", + description: "Modify existing Factorio permission groups.", + grantByDefault: false, +}); +lib.definePermission({ + name: "exp_groups.group.delete", + title: "Delete Groups", + description: "Delete Factorio permission groups.", + grantByDefault: false, +}); + +// Assignment permissions + +lib.definePermission({ + name: "exp_groups.assignment.get", + title: "Get Assignments", + description: "Retrieve a specific manual group assignment for a player.", + grantByDefault: true, +}); +lib.definePermission({ + name: "exp_groups.assignment.list", + title: "List Assignments", + description: "List all manual group assignments.", + grantByDefault: true, +}); +lib.definePermission({ + name: "exp_groups.assignment.subscribe", + title: "Subscribe to Assignment Updates", + description: "Receive updates when manual group assignments change.", + grantByDefault: true, +}); +lib.definePermission({ + name: "exp_groups.assignment.create", + title: "Create Assignments", + description: "Manually assign players to groups, overriding role mappings.", + grantByDefault: false, +}); +lib.definePermission({ + name: "exp_groups.assignment.update", + title: "Update Assignments", + description: "Modify existing manual group assignments.", + grantByDefault: false, +}); +lib.definePermission({ + name: "exp_groups.assignment.delete", + title: "Delete Assignments", + description: "Remove manual group assignments.", + grantByDefault: false, +}); + +// Role mapping permissions + +lib.definePermission({ + name: "exp_groups.role_mapping.get", + title: "Get Role Mappings", + description: "Retrieve a specific role mapping rule.", + grantByDefault: true, +}); +lib.definePermission({ + name: "exp_groups.role_mapping.list", + title: "List Role Mappings", + description: "List all role mapping rules.", + grantByDefault: true, +}); +lib.definePermission({ + name: "exp_groups.role_mapping.subscribe", + title: "Subscribe to Role Mapping Updates", + description: "Receive updates when role mapping rules change.", + grantByDefault: true, +}); +lib.definePermission({ + name: "exp_groups.role_mapping.create", + title: "Create Role Mappings", + description: "Create rules that map user roles to Factorio permission groups.", + grantByDefault: false, +}); +lib.definePermission({ + name: "exp_groups.role_mapping.update", + title: "Update Role Mappings", + description: "Modify existing role mapping rules.", + grantByDefault: false, +}); +lib.definePermission({ + name: "exp_groups.role_mapping.delete", + title: "Delete Role Mappings", + description: "Delete role mapping rules.", + grantByDefault: false, +}); + export const plugin: lib.PluginDeclaration = { name: "exp_groups", title: "ExpGaming - Permission Groups", description: "Clusterio plugin providing syncing of permission groups", + messages: [ + messages.GroupUpdatedEvent, + messages.AssignmentUpdatedEvent, + messages.RoleMappingUpdatedEvent, + + messages.GroupCreateRequest, + messages.GroupUpdateRequest, + messages.GroupDeleteRequest, + messages.GroupGetRequest, + messages.GroupListRequest, + + messages.AssignmentCreateRequest, + messages.AssignmentUpdateRequest, + messages.AssignmentDeleteRequest, + messages.AssignmentGetRequest, + messages.AssignmentListRequest, + + messages.RoleMappingCreateRequest, + messages.RoleMappingUpdateRequest, + messages.RoleMappingDeleteRequest, + messages.RoleMappingGetRequest, + messages.RoleMappingListRequest, + ], + instanceEntrypoint: "./dist/node/instance", instanceConfigFields: { + "exp_groups.sync_mode": { + description: "Synchronize permission groups with the controller", + type: "string", + enum: ["disabled", "enabled", "bidirectional"], + initialValue: "bidirectional", + }, }, controllerEntrypoint: "./dist/node/controller", diff --git a/exp_groups/messages.ts b/exp_groups/messages.ts new file mode 100644 index 0000000000..4e337041ab --- /dev/null +++ b/exp_groups/messages.ts @@ -0,0 +1,657 @@ +import * as lib from "@clusterio/lib"; +import { Type, Static } from "@sinclair/typebox"; + +/* + Data records +*/ + +export class GroupPermissions { + constructor( + public isBlacklist: boolean, + public permissions: string[], + ) {} + + static jsonSchema = Type.Object({ + is_blacklist: Type.Boolean(), + permissions: Type.Array(Type.String()), + }); + + toJSON(): Static { + return { + is_blacklist: this.isBlacklist, + permissions: this.permissions, + }; + } + + static fromJSON(json: Static) { + return new this( + json.is_blacklist, + json.permissions, + ); + } +} + +export class GroupRecord { + constructor( + public id: number, + public name: string, + public permissions: GroupPermissions, + public updatedAtMs: number = 0, + public isDeleted: boolean = false, + ) {} + + static jsonSchema = Type.Object({ + id: Type.Integer(), + name: Type.String(), + permissions: GroupPermissions.jsonSchema, + updated_at_ms: Type.Optional(Type.Number()), + is_deleted: Type.Optional(Type.Boolean()), + }); + + toJSON() { + let json: Static = { + id: this.id, + name: this.name, + permissions: this.permissions.toJSON(), + }; + + if (this.updatedAtMs) { + json.updated_at_ms = this.updatedAtMs; + } + + if (this.isDeleted) { + json.is_deleted = true; + } + + return json; + } + + static fromJSON(json: Static) { + return new this( + json.id, + json.name, + GroupPermissions.fromJSON(json.permissions), + json.updated_at_ms ?? 0, + json.is_deleted ?? false, + ); + } +} + +export class AssignmentRecord { + constructor( + public name: string, + public groupId: number, + public updatedAtMs: number = 0, + public isDeleted: boolean = false, + ) {} + + static jsonSchema = Type.Object({ + name: Type.String(), + group_id: Type.Integer(), + updated_at_ms: Type.Optional(Type.Number()), + is_deleted: Type.Optional(Type.Boolean()), + }); + + toJSON(): Static { + let json: Static = { + name: this.name, + group_id: this.groupId, + }; + + if (this.updatedAtMs) { + json.updated_at_ms = this.updatedAtMs; + } + + if (this.isDeleted) { + json.is_deleted = true; + } + + return json; + } + + static fromJSON(json: Static) { + return new this( + json.name, + json.group_id, + json.updated_at_ms ?? 0, + json.is_deleted ?? false, + ); + } +} + +export class RoleMappingRecord { + constructor( + public id: number, + public roleIds: Set, + public groupId: number, + public priority: number, + public enabled: boolean, + public updatedAtMs: number = 0, + public isDeleted: boolean = false, + ) {} + + static jsonSchema = Type.Object({ + id: Type.Integer(), + role_ids: Type.Array(Type.Integer()), + group_id: Type.Integer(), + priority: Type.Number(), + enabled: Type.Boolean(), + updated_at_ms: Type.Optional(Type.Number()), + is_deleted: Type.Optional(Type.Boolean()), + }); + + toJSON(): Static { + let json: Static = { + id: this.id, + role_ids: [...this.roleIds], + group_id: this.groupId, + priority: this.priority, + enabled: this.enabled, + }; + + if (this.updatedAtMs) { + json.updated_at_ms = this.updatedAtMs; + } + + if (this.isDeleted) { + json.is_deleted = true; + } + + return json; + } + + static fromJSON(json: Static) { + return new this( + json.id, + new Set(json.role_ids), + json.group_id, + json.priority, + json.enabled, + json.updated_at_ms ?? 0, + json.is_deleted ?? false, + ); + } +} + +/* + Update events +*/ + +export class GroupUpdatedEvent { + declare ["constructor"]: typeof GroupUpdatedEvent; + static plugin = "exp_groups" as const; + static type = "event" as const; + static src = "controller" as const; + static dst = ["control", "instance"] as const; + static permission = "exp_groups.group.subscribe" as const; + + constructor( + public updates: GroupRecord[], + ) {} + + static jsonSchema = Type.Object({ + updates: Type.Array(GroupRecord.jsonSchema), + }); + + toJSON() { + return { updates: this.updates.map(group => group.toJSON()) }; + } + + static fromJSON(json: Static) { + return new this(json.updates.map(group => GroupRecord.fromJSON(group))); + } +} + +export class AssignmentUpdatedEvent { + declare ["constructor"]: typeof AssignmentUpdatedEvent; + static plugin = "exp_groups" as const; + static type = "event" as const; + static src = "controller" as const; + static dst = ["control", "instance"] as const; + static permission = "exp_groups.assignment.subscribe" as const; + + constructor( + public updates: AssignmentRecord[], + ) {} + + static jsonSchema = Type.Object({ + updates: Type.Array(AssignmentRecord.jsonSchema), + }); + + toJSON() { + return { updates: this.updates.map(assignment => assignment.toJSON()) }; + } + + static fromJSON(json: Static) { + return new this(json.updates.map(assignment => AssignmentRecord.fromJSON(assignment))); + } +} + +export class RoleMappingUpdatedEvent { + declare ["constructor"]: typeof RoleMappingUpdatedEvent; + static plugin = "exp_groups" as const; + static type = "event" as const; + static src = "controller" as const; + static dst = "control" as const; + static permission = "exp_groups.role_mapping.subscribe" as const; + + constructor( + public updates: RoleMappingRecord[], + ) {} + + static jsonSchema = Type.Object({ + updates: Type.Array(RoleMappingRecord.jsonSchema), + }); + + toJSON() { + return { updates: this.updates.map(roleMapping => roleMapping.toJSON()) }; + } + + static fromJSON(json: Static) { + return new this(json.updates.map(roleMapping => RoleMappingRecord.fromJSON(roleMapping))); + } +} + +/* + Group requests +*/ + +export class GroupCreateRequest { + declare ["constructor"]: typeof GroupCreateRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.group.create" as const; + + constructor( + public name: string, + public permissions: GroupPermissions, + ) {} + + static jsonSchema = Type.Object({ + name: Type.String(), + permissions: GroupPermissions.jsonSchema, + }); + + toJSON() { + return { + name: this.name, + permissions: this.permissions.toJSON(), + }; + } + + static fromJSON(json: Static) { + return new this( + json.name, + GroupPermissions.fromJSON(json.permissions), + ); + } +} + +export class GroupUpdateRequest { + declare ["constructor"]: typeof GroupUpdateRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.group.update" as const; + + constructor( + public group: GroupRecord, + ) {} + + static jsonSchema = Type.Object({ + group: GroupRecord.jsonSchema, + }); + + toJSON() { + return { + group: this.group.toJSON(), + }; + } + + static fromJSON(json: Static) { + return new this( + GroupRecord.fromJSON(json.group), + ); + } +} + +export class GroupDeleteRequest { + declare ["constructor"]: typeof GroupDeleteRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.group.delete" as const; + + constructor( + public groupId: number, + ) {} + + static jsonSchema = Type.Object({ + group_id: Type.Integer(), + }); + + toJSON() { + return { + group_id: this.groupId, + }; + } + + static fromJSON(json: Static) { + return new this(json.group_id); + } +} + +export class GroupGetRequest { + declare ["constructor"]: typeof GroupGetRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.group.get" as const; + static Response = GroupRecord; + + constructor( + public groupId: number, + ) {} + + static jsonSchema = Type.Object({ + group_id: Type.Integer(), + }); + + toJSON() { + return { + group_id: this.groupId, + }; + } + + static fromJSON(json: Static) { + return new this(json.group_id); + } +} + +export class GroupListRequest { + declare ["constructor"]: typeof GroupListRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.group.list" as const; + static Response = lib.jsonArray(GroupRecord); + + constructor() {} +} + +/* + Assignment requests +*/ + +export class AssignmentCreateRequest { + declare ["constructor"]: typeof AssignmentCreateRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.assignment.create" as const; + + constructor( + public name: string, + public groupId: number, + ) {} + + static jsonSchema = Type.Object({ + name: Type.String(), + group_id: Type.Integer(), + }); + + toJSON() { + return { + name: this.name, + group_id: this.groupId, + }; + } + + static fromJSON(json: Static) { + return new this(json.name, json.group_id); + } +} + +export class AssignmentUpdateRequest { + declare ["constructor"]: typeof AssignmentUpdateRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.assignment.update" as const; + + constructor( + public assignment: AssignmentRecord, + ) {} + + static jsonSchema = Type.Object({ + assignment: AssignmentRecord.jsonSchema, + }); + + toJSON() { + return { + assignment: this.assignment.toJSON(), + }; + } + + static fromJSON(json: Static) { + return new this( + AssignmentRecord.fromJSON(json.assignment), + ); + } +} + +export class AssignmentDeleteRequest { + declare ["constructor"]: typeof AssignmentDeleteRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.assignment.delete" as const; + + constructor( + public name: string, + ) {} + + static jsonSchema = Type.Object({ + name: Type.String(), + }); + + toJSON() { + return { + name: this.name, + }; + } + + static fromJSON(json: Static) { + return new this(json.name); + } +} + +export class AssignmentGetRequest { + declare ["constructor"]: typeof AssignmentGetRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.assignment.get" as const; + static Response = AssignmentRecord; + + constructor( + public name: string, + ) {} + + static jsonSchema = Type.Object({ + name: Type.String(), + }); + + toJSON() { + return { + name: this.name, + }; + } + + static fromJSON(json: Static) { + return new this(json.name); + } +} + +export class AssignmentListRequest { + declare ["constructor"]: typeof AssignmentListRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.assignment.list" as const; + static Response = lib.jsonArray(AssignmentRecord); + + constructor() {} +} + +/* + Role mapping requests +*/ + +export class RoleMappingCreateRequest { + declare ["constructor"]: typeof RoleMappingCreateRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.role_mapping.create" as const; + + constructor( + public roleIds: number[], + public groupId: number, + public priority: number, + public enabled: boolean, + ) {} + + static jsonSchema = Type.Object({ + role_ids: Type.Array(Type.Integer()), + group_id: Type.Integer(), + priority: Type.Number(), + enabled: Type.Boolean(), + }); + + toJSON() { + return { + role_ids: this.roleIds, + group_id: this.groupId, + priority: this.priority, + enabled: this.enabled, + }; + } + + static fromJSON(json: Static) { + return new this( + json.role_ids, + json.group_id, + json.priority, + json.enabled, + ); + } +} + +export class RoleMappingUpdateRequest { + declare ["constructor"]: typeof RoleMappingUpdateRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.role_mapping.update" as const; + + constructor( + public roleMapping: RoleMappingRecord, + ) {} + + static jsonSchema = Type.Object({ + role_mapping: RoleMappingRecord.jsonSchema, + }); + + toJSON() { + return { + role_mapping: this.roleMapping.toJSON(), + }; + } + + static fromJSON(json: Static) { + return new this( + RoleMappingRecord.fromJSON(json.role_mapping), + ); + } +} + +export class RoleMappingDeleteRequest { + declare ["constructor"]: typeof RoleMappingDeleteRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.role_mapping.delete" as const; + + constructor( + public id: number, + ) {} + + static jsonSchema = Type.Object({ + id: Type.Integer(), + }); + + toJSON() { + return { + id: this.id, + }; + } + + static fromJSON(json: Static) { + return new this(json.id); + } +} + +export class RoleMappingGetRequest { + declare ["constructor"]: typeof RoleMappingGetRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.role_mapping.get" as const; + static Response = RoleMappingRecord; + + constructor( + public id: number, + ) {} + + static jsonSchema = Type.Object({ + id: Type.Integer(), + }); + + toJSON() { + return { + id: this.id, + }; + } + + static fromJSON(json: Static) { + return new this(json.id); + } +} + +export class RoleMappingListRequest { + declare ["constructor"]: typeof RoleMappingListRequest; + static plugin = "exp_groups" as const; + static type = "request" as const; + static src = ["control", "instance"] as const; + static dst = "controller" as const; + static permission = "exp_groups.role_mapping.list" as const; + static Response = lib.jsonArray(RoleMappingRecord); + + constructor() {} +} From dca5086ce375ef592bee153b72eca18946c476c9 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Wed, 20 May 2026 22:39:44 +0100 Subject: [PATCH 06/12] Add instance plugin --- exp_groups/instance.ts | 149 +++++++++++++++++++++++++++++++++- exp_groups/module/control.lua | 51 ++++++------ exp_groups/module/globals.lua | 9 ++ 3 files changed, 181 insertions(+), 28 deletions(-) create mode 100644 exp_groups/module/globals.lua diff --git a/exp_groups/instance.ts b/exp_groups/instance.ts index 455d035c55..028663b924 100644 --- a/exp_groups/instance.ts +++ b/exp_groups/instance.ts @@ -1,6 +1,153 @@ -import * as lib from "@clusterio/lib"; import { BaseInstancePlugin } from "@clusterio/host"; +import * as lib from "@clusterio/lib"; +import * as messages from "./messages"; + +export type IpcGroupUpdated = { + group_name: string, + group_id: number | undefined, + permissions: { is_blacklist: boolean, permissions: string[] }, +}; + +export type IpcGroupDeleted = { + group_name: string, + group_id: number | undefined, +}; + +export type IpcPlayerAssignments = { + assignments: Record, +}; export class InstancePlugin extends BaseInstancePlugin { + async init() { + this.instance.handle(messages.GroupUpdatedEvent, this.handleGroupUpdatedEvent.bind(this)); + this.instance.handle(messages.AssignmentUpdatedEvent, this.handleAssignmentUpdatedEvent.bind(this)); + this.instance.server.handle(`exp_group:group_updated`, this.handleGroupUpdatedIPC.bind(this)) + this.instance.server.handle(`exp_group:group_deleted`, this.handleGroupDeletedIPC.bind(this)) + this.instance.server.handle(`exp_group:player_assignments`, this.handlePlayerAssignmentsIPC.bind(this)) + } + + async onInstanceConfigFieldChanged(field: string, curr: unknown, prev: unknown) { + switch(field) { + case "exp_groups.sync_mode": + await this.luaSetEmitEvents(curr == "bidirectional") + break; + } + } + + async onStart() { + await this.instance.sendTo("controller", new lib.SubscriptionRequest( + `exp_groups:${messages.GroupUpdatedEvent.name}`, true + )); + const groups = await this.instance.sendTo("controller", new messages.GroupListRequest()) + await this.luaSendInitialGroups(groups); + await this.luaSetEmitEvents(this.instance.config.get("exp_groups.sync_mode") == "bidirectional") + } + + async onPlayerEvent(event: lib.PlayerEvent) { + switch(event.type) { + case "join": + this.handlePlayerJoin(event.name); + break; + case "leave": + this.handlePlayerLeave(event.name); + break; + } + } + + async handlePlayerJoin(playerName: string) { + await this.subscribePlayerAssignment(playerName); + await this.requestPlayerAssignment(playerName); + } + + async handlePlayerLeave(playerName: string) { + await this.unsubscribePlayerAssignment(playerName); + } + + async handleGroupUpdatedEvent(event: messages.GroupUpdatedEvent) { + for (const group of event.updates) { + await this.luaSendGroupUpdate(group); + } + } + + async handleAssignmentUpdatedEvent(event: messages.AssignmentUpdatedEvent) { + for (const assignment of event.updates) { + await this.luaSendAssignmentUpdate(assignment); + } + } + + async handleGroupUpdatedIPC(event: IpcGroupUpdated) { + const permissions = new messages.GroupPermissions( + event.permissions.is_blacklist, + event.permissions.permissions, + ); + + if (event.group_id === undefined) { + await this.instance.sendTo("controller", + new messages.GroupCreateRequest(event.group_name, permissions), + ); + } else { + await this.instance.sendTo("controller", new messages.GroupUpdateRequest( + new messages.GroupRecord(event.group_id, event.group_name, permissions), + )); + } + } + + async handleGroupDeletedIPC(event: IpcGroupDeleted) { + if (event.group_id === undefined) { + return; + } + await this.instance.sendTo("controller", new messages.GroupDeleteRequest(event.group_id)); + } + + async handlePlayerAssignmentsIPC(event: IpcPlayerAssignments) { + await Promise.all( + Object.entries(event.assignments).map(([playerName, groupId]) => + this.instance.sendTo("controller", + new messages.AssignmentUpdateRequest(new messages.AssignmentRecord(playerName, groupId)), + ) + ) + ); + } + + async subscribePlayerAssignment(playerName: string) { + await this.instance.sendTo("controller", new lib.SubscriptionRequest( + `exp_groups:${messages.AssignmentUpdatedEvent.name}`, true, 0, playerName + )); + } + + async unsubscribePlayerAssignment(playerName: string) { + await this.instance.sendTo("controller", new lib.SubscriptionRequest( + `exp_groups:${messages.AssignmentUpdatedEvent.name}`, false, 0, playerName + )); + } + + async requestPlayerAssignment(playerName: string) { + const assignment = await this.instance.sendTo("controller", new messages.AssignmentGetRequest(playerName)); + await this.luaSendAssignmentUpdate(assignment); + } + + async luaSendInitialGroups(groups: messages.GroupRecord[]) { + if (this.instance.config.get("exp_groups.sync_mode") == "disabled") { + return; + } + await this.instance.sendRcon(`/sc exp_groups.initialise_groups(helpers.json_to_table${JSON.stringify(groups)})`) + } + + async luaSendGroupUpdate(group: messages.GroupRecord) { + if (this.instance.config.get("exp_groups.sync_mode") == "disabled") { + return; + } + await this.instance.sendRcon(`/sc exp_groups.receive_group_update(helpers.json_to_table${JSON.stringify(group)})`) + } + + async luaSendAssignmentUpdate(assignment: messages.AssignmentRecord) { + if (this.instance.config.get("exp_groups.sync_mode") == "disabled") { + return; + } + await this.instance.sendRcon(`/sc exp_groups.initialise_groups(helpers.receive_assignment_update${JSON.stringify(assignment)})`) + } + async luaSetEmitEvents(emitEvents: boolean) { + await this.instance.sendRcon(`/sc exp_groups.set_emit_events(${emitEvents})`) + } } diff --git a/exp_groups/module/control.lua b/exp_groups/module/control.lua index 831e4ea65b..2a854bdb51 100644 --- a/exp_groups/module/control.lua +++ b/exp_groups/module/control.lua @@ -1,4 +1,4 @@ ---[[-- Exp Permission Groups +--[[-- ExpGroups Adds permission group syncing to clusterio ]] @@ -6,18 +6,18 @@ local clusterio_api = require("modules/clusterio/api") local compat = require("modules/clusterio/compat") --- Top level module table, contains event handlers and public methods ---- @class ExpPermissionGroups -local ExpPermissionGroups = {} +--- @class ExpGroups +local ExpGroups = {} --- @class ExpPermissionGroups.GroupPermissions ---- @field [1] boolean -- is_blacklist, true means action names is a backlist ---- @field [2] string[] -- action_names, the actions to allow or disallow +--- @field is_blacklist boolean +--- @field permissions string[] --- @class ExpPermissionGroups.GroupRecord --- @field id number --- @field name string --- @field permissions ExpPermissionGroups.GroupPermissions? ---- @field isDeleted boolean +--- @field is_deleted boolean --- @class ExpPermissionGroups.AssignmentRecord --- @field name string @@ -44,7 +44,7 @@ local function setup_script_data() } end - ExpPermissionGroups.on_load() + ExpGroups.on_load() end --[[ @@ -71,17 +71,15 @@ end --- @param group LuaPermissionGroup --- @param permissions ExpPermissionGroups.GroupPermissions local function decode_group_permissions(group, permissions) - local is_blacklist = permissions[1] - local actions_names = permissions[2] - local action_allowed = not is_blacklist - -- Construct a hash map for faster lookup local action_map = {} - for _, input_action_name in pairs(actions_names) do + for _, input_action_name in pairs(permissions.permissions) do action_map[input_action_name] = true end -- Apply the whitelist / backlist to the group + local is_blacklist = permissions.is_blacklist + local action_allowed = not is_blacklist for input_action_name, input_action in pairs(defines.input_action) do if action_map[input_action_name] then group.set_allows_action(input_action, action_allowed) @@ -114,11 +112,11 @@ local function encode_group_permissions(group) -- Return the whitelist if it is smaller if blacklist_index > whitelist_index then - return { false, whitelist } + return { is_blacklist = false, permissions = whitelist } end -- Otherwise return the blacklist as it is smaller - return { true, blacklist } + return { is_blacklist = true, permissions = blacklist } end --[[ @@ -128,7 +126,7 @@ end --- Update the factorio permission group --- @param group_record ExpPermissionGroups.GroupRecord local function update_group(group_record) - assert(not group_record.isDeleted) + assert(not group_record.is_deleted) -- Try find the group by id and then then name local group = script_data.clusterio_id_to_group[group_record.id] @@ -156,7 +154,7 @@ end --- Delete the factorio permission group --- @param group_record ExpPermissionGroups.GroupRecord local function delete_group(group_record) - assert(group_record.isDeleted) + assert(group_record.is_deleted) local default_group = get_default_group() local group = script_data.clusterio_id_to_group[group_record.id] @@ -193,19 +191,19 @@ end ]] --- Restore local references to persistent script data after load -function ExpPermissionGroups.on_load() +function ExpGroups.on_load() script_data = compat.script_data["exp_groups"] end --- Enable or disable emitting lua changes back to the instance plugin --- @param enabled boolean? -function ExpPermissionGroups.set_emit_events(enabled) +function ExpGroups.set_emit_events(enabled) script_data.emit_updates = enabled ~= false end --- Replace local state with expected controller state on startup --- @param group_records ExpPermissionGroups.GroupRecord[] -function ExpPermissionGroups.initialise_groups(group_records) +function ExpGroups.initialise_groups(group_records) local _emit_events = script_data.emit_updates script_data.emit_updates = false @@ -241,11 +239,11 @@ end --- Receive an updated version of a group record --- @param group_record ExpPermissionGroups.GroupRecord -function ExpPermissionGroups.receive_group_update(group_record) +function ExpGroups.receive_group_update(group_record) local _emit_events = script_data.emit_updates script_data.emit_updates = false - if group_record.isDeleted then + if group_record.is_deleted then delete_group(group_record) else update_group(group_record) @@ -256,7 +254,7 @@ end --- Receive an updated version of a assignment record --- @param assignment_record ExpPermissionGroups.AssignmentRecord -function ExpPermissionGroups.receive_assignment_update(assignment_record) +function ExpGroups.receive_assignment_update(assignment_record) local _emit_events = script_data.emit_updates script_data.emit_updates = false @@ -271,7 +269,7 @@ end --- Get the current script data for debugging purposes --- @package -function ExpPermissionGroups._script_data() +function ExpGroups._script_data() return script_data end @@ -332,7 +330,6 @@ local function flush_group_updates() end -- Get all the groups and emit their updates - local get_group = game.permissions.get_group for _, group in pairs(script_data.dirty_groups) do if group.valid then emit_group_update(group) @@ -431,6 +428,6 @@ local on_nth_tick = { [300] = on_nth_tick_flush, } -ExpPermissionGroups.events = events --- @package -ExpPermissionGroups.on_nth_tick = on_nth_tick --- @package -return ExpPermissionGroups +ExpGroups.events = events --- @package +ExpGroups.on_nth_tick = on_nth_tick --- @package +return ExpGroups diff --git a/exp_groups/module/globals.lua b/exp_groups/module/globals.lua new file mode 100644 index 0000000000..fc42b91758 --- /dev/null +++ b/exp_groups/module/globals.lua @@ -0,0 +1,9 @@ +--[[ +It is best practice to not expose any globals because all modules share a global environment +However, sometimes you need globals, for example to access functions within rcon commands +Therefore, we advise that this should be the only file in your module to expose globals +Typically this would be your control file as shown in the example below +]] + +-- Access using `/sc exp_groups.foo()` +exp_groups = require("modules/exp_groups/control") From 230c83510357b505ba90979415b300de692aa0ac Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Thu, 21 May 2026 00:30:17 +0100 Subject: [PATCH 07/12] Add controller plugin --- exp_groups/controller.ts | 414 ++++++++++++++++++++++++++++++++++++++- exp_groups/index.ts | 2 +- exp_groups/instance.ts | 51 ++--- exp_groups/messages.ts | 38 +++- 4 files changed, 477 insertions(+), 28 deletions(-) diff --git a/exp_groups/controller.ts b/exp_groups/controller.ts index fc761f627c..bdc1860b3c 100644 --- a/exp_groups/controller.ts +++ b/exp_groups/controller.ts @@ -1,6 +1,418 @@ -import * as lib from "@clusterio/lib"; import { BaseControllerPlugin } from "@clusterio/controller"; +import * as lib from "@clusterio/lib"; +import * as messages from "./messages"; +import * as path from "node:path"; export class ControllerPlugin extends BaseControllerPlugin { + groups!: lib.SubscribableDatastore; + roleMappings!: lib.SubscribableDatastore; + manualAssignments!: lib.SubscribableDatastore; + resolvedAssignments!: lib.SubscribableDatastore; + + async init() { + const databaseDirectory = this.controller.config.get("controller.database_directory"); + + this.groups = new lib.SubscribableDatastore( + ...await new lib.JsonIdDatastoreProvider( + path.join(databaseDirectory, "exp_groups", "groups.json"), + messages.GroupRecord.fromJSON.bind(messages.GroupRecord), + ).bootstrap() + ); + + this.roleMappings = new lib.SubscribableDatastore( + ...await new lib.JsonIdDatastoreProvider( + path.join(databaseDirectory, "exp_groups", "role_mappings.json"), + messages.RoleMappingRecord.fromJSON.bind(messages.RoleMappingRecord), + ).bootstrap() + ); + + this.manualAssignments = new lib.SubscribableDatastore( + ...await new lib.JsonIdDatastoreProvider( + path.join(databaseDirectory, "exp_groups", "assignments.json"), + messages.AssignmentRecord.fromJSON.bind(messages.AssignmentRecord), + ).bootstrap() + ); + + this.resolvedAssignments = new lib.SubscribableDatastore(); + + this.controller.subscriptions.handle(messages.GroupUpdatedEvent, this.handleGroupSubscription.bind(this)); + this.controller.subscriptions.handle(messages.RoleMappingUpdatedEvent, this.handleRoleMappingSubscription.bind(this)); + this.controller.subscriptions.handle(messages.ManualAssignmentUpdatedEvent, this.handleManualAssignmentSubscription.bind(this)); + this.controller.subscriptions.handle(messages.ResolvedAssignmentUpdatedEvent, this.handleResolvedAssignmentSubscription.bind(this)); + + this.groups.on("update", this.groupsUpdated.bind(this)); + this.roleMappings.on("update", this.roleMappingsUpdated.bind(this)); + this.manualAssignments.on("update", this.manualAssignmentsUpdated.bind(this)); + this.resolvedAssignments.on("update", this.resolvedAssignmentsUpdated.bind(this)); + + this.controller.handle(messages.GroupCreateRequest, this.handleGroupCreateRequest.bind(this)); + this.controller.handle(messages.GroupUpdateRequest, this.handleGroupUpdateRequest.bind(this)); + this.controller.handle(messages.GroupDeleteRequest, this.handleGroupDeleteRequest.bind(this)); + this.controller.handle(messages.GroupGetRequest, this.handleGroupGetRequest.bind(this)); + this.controller.handle(messages.GroupListRequest, this.handleGroupListRequest.bind(this)); + + this.controller.handle(messages.AssignmentCreateRequest, this.handleAssignmentCreateRequest.bind(this)); + this.controller.handle(messages.AssignmentUpdateRequest, this.handleAssignmentUpdateRequest.bind(this)); + this.controller.handle(messages.AssignmentDeleteRequest, this.handleAssignmentDeleteRequest.bind(this)); + this.controller.handle(messages.AssignmentGetRequest, this.handleAssignmentGetRequest.bind(this)); + this.controller.handle(messages.AssignmentListRequest, this.handleAssignmentListRequest.bind(this)); + + this.controller.handle(messages.RoleMappingCreateRequest, this.handleRoleMappingCreateRequest.bind(this)); + this.controller.handle(messages.RoleMappingUpdateRequest, this.handleRoleMappingUpdateRequest.bind(this)); + this.controller.handle(messages.RoleMappingDeleteRequest, this.handleRoleMappingDeleteRequest.bind(this)); + this.controller.handle(messages.RoleMappingGetRequest, this.handleRoleMappingGetRequest.bind(this)); + this.controller.handle(messages.RoleMappingListRequest, this.handleRoleMappingListRequest.bind(this)); + } + + async onShutdown() { + await Promise.all([ + this.groups.save(), + this.manualAssignments.save(), + this.roleMappings.save(), + ]) + } + + /* + Subscriptions + */ + + async groupsUpdated(groups: messages.GroupRecord[]) { + this.controller.subscriptions.broadcast(new messages.GroupUpdatedEvent(groups)); + + // We need to do extra work if the group was deleted + const deletedGroupIds = groups.filter(g => g.isDeleted).map(g => g.id); + if (!deletedGroupIds.length) { + return; + } + + // Cascade the delete down to affected role mappings + const mappingsToDelete = []; + for (const mapping of this.roleMappings.values()) { + if (deletedGroupIds.includes(mapping.groupId)) { + mappingsToDelete.push(mapping); + } + } + if (mappingsToDelete.length) { + this.roleMappings.deleteMany(mappingsToDelete); + } + + // Cascade the delete down to affected manual assignments + const affectedPlayers = new Set(); + const assignmentsToDelete = []; + for (const assignment of this.manualAssignments.values()) { + if (deletedGroupIds.includes(assignment.groupId)) { + assignmentsToDelete.push(assignment); + affectedPlayers.add(assignment.name); + } + } + if (assignmentsToDelete.length) { + this.manualAssignments.deleteMany(assignmentsToDelete); + } + + // Find all the affected players who were assigned to this group + for (const resolved of this.resolvedAssignments.values()) { + if (deletedGroupIds.includes(resolved.groupId)) { + affectedPlayers.add(resolved.name); + } + } + if (affectedPlayers.size) { + this.resolvedAssignments.setMany(await this.computeResolvedAssignments([...affectedPlayers])); + } + } + + async handleGroupSubscription(request: lib.SubscriptionRequest) { + const groups = [...this.groups.values()] + .filter(group => group.updatedAtMs > request.lastRequestTimeMs); + return groups.length ? new messages.GroupUpdatedEvent(groups) : null; + } + + async roleMappingsUpdated(roleMappings: messages.RoleMappingRecord[]) { + this.controller.subscriptions.broadcast(new messages.RoleMappingUpdatedEvent(roleMappings)); + + // Mappings pointing to a deleted group have already been handled + // But if any are active, then we still must recompute all assignments + let hasActiveGroup = false; + for (const roleMapping of roleMappings) { + const group = this.groups.get(roleMapping.groupId); + if (group && !group.isDeleted) { + hasActiveGroup = true; + break; + } + } + if (!hasActiveGroup) { + return; + } + + // Affected players are those without manual assignments + const affectedPlayers = []; + for (const resolved of this.resolvedAssignments.values()) { + if (!this.manualAssignments.has(resolved.name)) { + affectedPlayers.push(resolved.name); + } + } + if (affectedPlayers.length) { + this.resolvedAssignments.setMany(await this.computeResolvedAssignments(affectedPlayers)); + } + } + + async handleRoleMappingSubscription(request: lib.SubscriptionRequest) { + const mappings = [...this.roleMappings.values()] + .filter(mapping => mapping.updatedAtMs > request.lastRequestTimeMs); + return mappings.length ? new messages.RoleMappingUpdatedEvent(mappings) : null; + } + + async manualAssignmentsUpdated(assignments: messages.AssignmentRecord[]) { + this.controller.subscriptions.broadcast(new messages.ManualAssignmentUpdatedEvent(assignments)); + + // Assignments pointing to a deleted group have already been handled + const affectedPlayers: string[] = []; + for (const assignment of assignments) { + const group = this.groups.get(assignment.groupId); + if (!group || group.isDeleted) continue; + affectedPlayers.push(assignment.name); + } + if (affectedPlayers.length) { + this.resolvedAssignments.setMany(await this.computeResolvedAssignments(affectedPlayers)); + } + } + + async handleManualAssignmentSubscription(request: lib.SubscriptionRequest) { + const assignments = [...this.resolvedAssignments.values()] + .filter(a => a.updatedAtMs > request.lastRequestTimeMs); + return assignments.length ? new messages.ManualAssignmentUpdatedEvent(assignments) : null; + } + + resolvedAssignmentsUpdated(assignments: messages.AssignmentRecord[]) { + this.controller.subscriptions.broadcast( + new messages.ResolvedAssignmentUpdatedEvent(assignments), + assignments.map(assignment => assignment.name), + ); + } + + async handleResolvedAssignmentSubscription(request: lib.SubscriptionRequest) { + // Check for any missing assignments to be computed on demand + const filters = Array.isArray(request.filters) ? request.filters : [request.filters!]; + if (request.filters && filters.length) { + const missing = filters.filter(name => !this.resolvedAssignments.has(name)); + if (missing.length) { + this.resolvedAssignments.setMany(await this.computeResolvedAssignments(missing)); + } + } + + // Filter the assignments + const assignments = (filters.length + ? filters.map(name => this.resolvedAssignments.get(name)).filter(Boolean) + : [...this.resolvedAssignments.values()] + ).filter(a => a.updatedAtMs > request.lastRequestTimeMs); + + return assignments.length ? new messages.ResolvedAssignmentUpdatedEvent(assignments) : null; + } + + /* + Groups + */ + + async handleGroupListRequest() { + return [...this.groups.values()]; + } + + async handleGroupCreateRequest(request: messages.GroupCreateRequest) { + if ([...this.groups.values()].some(g => g.name === request.name)) { + throw new lib.RequestError(`Group with name '${request.name}' already exists`); + } + + let id = Math.random() * 2**31 | 0; + while (this.groups.has(id)) { + id = Math.random() * 2**31 | 0; + } + + const group = new messages.GroupRecord(id, request.name, request.permissions); + this.groups.set(group); + } + + async handleGroupUpdateRequest(request: messages.GroupUpdateRequest) { + const group = request.group; + if (group.id === undefined || !this.groups.has(group.id)) { + throw new lib.RequestError(`Group with ID ${group.id} does not exist`); + } + + this.groups.set(group); + } + + async handleGroupDeleteRequest(request: messages.GroupDeleteRequest) { + const { groupId } = request; + + const group = this.groups.getMutable(groupId); + if (!group) { + throw new lib.RequestError(`Group with ID ${groupId} does not exist`); + } + + this.groups.delete(group); + } + + async handleGroupGetRequest(request: messages.GroupGetRequest) { + const group = this.groups.get(request.groupId); + if (!group) { + throw new lib.RequestError(`Group with ID ${request.groupId} does not exist`); + } + + return group; + } + + /* + Groups + */ + + async handleAssignmentListRequest() { + return [...this.manualAssignments.values()]; + } + + async handleAssignmentCreateRequest(request: messages.AssignmentCreateRequest) { + const { name, groupId } = request; + if (this.manualAssignments.has(name)) { + throw new lib.RequestError(`Assignment for '${name}' already exists`); + } + + const assignment = new messages.AssignmentRecord(name, groupId); + this.manualAssignments.set(assignment); + } + + async handleAssignmentUpdateRequest(request: messages.AssignmentUpdateRequest) { + const assignment = request.assignment; + if (!this.manualAssignments.has(assignment.name)) { + throw new lib.RequestError(`Assignment for '${assignment.name}' does not exist`); + } + + this.manualAssignments.set(assignment); + } + + async handleAssignmentDeleteRequest(request: messages.AssignmentDeleteRequest) { + const { name } = request; + + const assignment = this.manualAssignments.getMutable(name); + if (!assignment) { + throw new lib.RequestError(`Assignment for '${name}' does not exist`); + } + + this.manualAssignments.delete(assignment); + } + + async handleAssignmentGetRequest(request: messages.AssignmentGetRequest) { + if (request.resolve) { + let assignment = this.resolvedAssignments.get(request.name); + if (!assignment) { + assignment = await this.computeResolvedAssignment(request.name); + this.resolvedAssignments.set(assignment); + } + + return assignment; + } + + const assignment = this.manualAssignments.get(request.name); + if (!assignment) { + throw new lib.RequestError(`Assignment for '${request.name}' does not exist`); + } + + return assignment; + } + + /* + Role mappings + */ + + async handleRoleMappingListRequest() { + return [...this.roleMappings.values()]; + } + + async handleRoleMappingCreateRequest(request: messages.RoleMappingCreateRequest) { + let id = Math.random() * 2**31 | 0; + while (this.roleMappings.has(id)) { + id = Math.random() * 2**31 | 0; + } + + const mapping = new messages.RoleMappingRecord( + id, + new Set(request.roleIds), + request.groupId, + request.priority, + request.enabled, + ); + + this.roleMappings.set(mapping); + } + + async handleRoleMappingUpdateRequest(request: messages.RoleMappingUpdateRequest) { + const mapping = request.roleMapping; + if (mapping.id === undefined || !this.roleMappings.has(mapping.id)) { + throw new lib.RequestError(`Role mapping with ID ${mapping.id} does not exist`); + } + + this.roleMappings.set(mapping); + } + + async handleRoleMappingDeleteRequest(request: messages.RoleMappingDeleteRequest) { + const { id } = request; + + const mapping = this.roleMappings.getMutable(id); + if (!mapping) { + throw new lib.RequestError(`Role mapping with ID ${id} does not exist`); + } + + this.roleMappings.delete(mapping); + } + + async handleRoleMappingGetRequest(request: messages.RoleMappingGetRequest) { + const mapping = this.roleMappings.get(request.id); + if (!mapping) { + throw new lib.RequestError(`Role mapping with ID ${request.id} does not exist`); + } + + return mapping; + } + + /* + Calculating assignments + */ + + async computeResolvedAssignment(playerName: string): Promise { + // 1) Manual override + const manual = this.manualAssignments.get(playerName); + if (manual) { + return manual; + } + + const user = this.controller.users.get(playerName); + const userRoles = user?.roleIds ?? new Set(); + + // 2) Role mappings + let best: messages.RoleMappingRecord | null = null; + for (const mapping of this.roleMappings.values()) { + if (!mapping.enabled) continue; + + let matches = true; + for (const roleId of mapping.roleIds) { + if (!userRoles.has(roleId)) { + matches = false; + break; + } + } + + if (!matches) continue; + + if (!best || mapping.priority > best.priority) { + best = mapping; + } + } + + if (best) { + return new messages.AssignmentRecord(playerName, best.groupId); + } + + // 3) Default (deleted assignment, assigns to 'Default' in game) + return new messages.AssignmentRecord(playerName, 0, 0, true); + } + async computeResolvedAssignments(playerNames: string[]): Promise { + return Promise.all(playerNames.map(name => this.computeResolvedAssignment(name))); + } } diff --git a/exp_groups/index.ts b/exp_groups/index.ts index ae6ba44171..2b4330658d 100644 --- a/exp_groups/index.ts +++ b/exp_groups/index.ts @@ -133,7 +133,7 @@ export const plugin: lib.PluginDeclaration = { messages: [ messages.GroupUpdatedEvent, - messages.AssignmentUpdatedEvent, + messages.ManualAssignmentUpdatedEvent, messages.RoleMappingUpdatedEvent, messages.GroupCreateRequest, diff --git a/exp_groups/instance.ts b/exp_groups/instance.ts index 028663b924..1bfc66ba9e 100644 --- a/exp_groups/instance.ts +++ b/exp_groups/instance.ts @@ -18,9 +18,15 @@ export type IpcPlayerAssignments = { }; export class InstancePlugin extends BaseInstancePlugin { + // Once only, don't send permissions for these groups + // This is used for groups created on this instance that only need the controller generated id + skipSendingPermissions = new Set(); + // Track known online players so that we only apply assignment updates for them + onlinePlayers = new Set(); + async init() { this.instance.handle(messages.GroupUpdatedEvent, this.handleGroupUpdatedEvent.bind(this)); - this.instance.handle(messages.AssignmentUpdatedEvent, this.handleAssignmentUpdatedEvent.bind(this)); + this.instance.handle(messages.ResolvedAssignmentUpdatedEvent, this.handleResolvedAssignmentUpdatedEvent.bind(this)); this.instance.server.handle(`exp_group:group_updated`, this.handleGroupUpdatedIPC.bind(this)) this.instance.server.handle(`exp_group:group_deleted`, this.handleGroupDeletedIPC.bind(this)) this.instance.server.handle(`exp_group:player_assignments`, this.handlePlayerAssignmentsIPC.bind(this)) @@ -35,8 +41,9 @@ export class InstancePlugin extends BaseInstancePlugin { } async onStart() { + // We use Date.now() because we need to manually initialise the groups on the lua side await this.instance.sendTo("controller", new lib.SubscriptionRequest( - `exp_groups:${messages.GroupUpdatedEvent.name}`, true + `exp_groups:${messages.GroupUpdatedEvent.name}`, true, Date.now() )); const groups = await this.instance.sendTo("controller", new messages.GroupListRequest()) await this.luaSendInitialGroups(groups); @@ -46,32 +53,27 @@ export class InstancePlugin extends BaseInstancePlugin { async onPlayerEvent(event: lib.PlayerEvent) { switch(event.type) { case "join": - this.handlePlayerJoin(event.name); + this.onlinePlayers.add(event.name); + await this.subscribePlayerAssignment(event.name); break; case "leave": - this.handlePlayerLeave(event.name); + this.onlinePlayers.delete(event.name); + await this.unsubscribePlayerAssignment(event.name); break; } } - async handlePlayerJoin(playerName: string) { - await this.subscribePlayerAssignment(playerName); - await this.requestPlayerAssignment(playerName); - } - - async handlePlayerLeave(playerName: string) { - await this.unsubscribePlayerAssignment(playerName); - } - async handleGroupUpdatedEvent(event: messages.GroupUpdatedEvent) { for (const group of event.updates) { await this.luaSendGroupUpdate(group); } } - async handleAssignmentUpdatedEvent(event: messages.AssignmentUpdatedEvent) { + async handleResolvedAssignmentUpdatedEvent(event: messages.ManualAssignmentUpdatedEvent) { for (const assignment of event.updates) { - await this.luaSendAssignmentUpdate(assignment); + if (this.onlinePlayers.has(assignment.name)) { + await this.luaSendAssignmentUpdate(assignment); + } } } @@ -82,6 +84,7 @@ export class InstancePlugin extends BaseInstancePlugin { ); if (event.group_id === undefined) { + this.skipSendingPermissions.add(event.group_name); await this.instance.sendTo("controller", new messages.GroupCreateRequest(event.group_name, permissions), ); @@ -111,21 +114,16 @@ export class InstancePlugin extends BaseInstancePlugin { async subscribePlayerAssignment(playerName: string) { await this.instance.sendTo("controller", new lib.SubscriptionRequest( - `exp_groups:${messages.AssignmentUpdatedEvent.name}`, true, 0, playerName + `exp_groups:${messages.ResolvedAssignmentUpdatedEvent.name}`, true, 0, playerName )); } async unsubscribePlayerAssignment(playerName: string) { await this.instance.sendTo("controller", new lib.SubscriptionRequest( - `exp_groups:${messages.AssignmentUpdatedEvent.name}`, false, 0, playerName + `exp_groups:${messages.ResolvedAssignmentUpdatedEvent.name}`, false, 0, playerName )); } - async requestPlayerAssignment(playerName: string) { - const assignment = await this.instance.sendTo("controller", new messages.AssignmentGetRequest(playerName)); - await this.luaSendAssignmentUpdate(assignment); - } - async luaSendInitialGroups(groups: messages.GroupRecord[]) { if (this.instance.config.get("exp_groups.sync_mode") == "disabled") { return; @@ -137,7 +135,14 @@ export class InstancePlugin extends BaseInstancePlugin { if (this.instance.config.get("exp_groups.sync_mode") == "disabled") { return; } - await this.instance.sendRcon(`/sc exp_groups.receive_group_update(helpers.json_to_table${JSON.stringify(group)})`) + + const json = group.toJSON(); + if (this.skipSendingPermissions.has(group.name)) { + this.skipSendingPermissions.delete(group.name); + delete (json as any).permissions; + } + + await this.instance.sendRcon(`/sc exp_groups.receive_group_update(helpers.json_to_table${JSON.stringify(json)})`) } async luaSendAssignmentUpdate(assignment: messages.AssignmentRecord) { diff --git a/exp_groups/messages.ts b/exp_groups/messages.ts index 4e337041ab..691d8ca32b 100644 --- a/exp_groups/messages.ts +++ b/exp_groups/messages.ts @@ -85,6 +85,10 @@ export class AssignmentRecord { public isDeleted: boolean = false, ) {} + get id() { + return this.name; + } + static jsonSchema = Type.Object({ name: Type.String(), group_id: Type.Integer(), @@ -202,8 +206,33 @@ export class GroupUpdatedEvent { } } -export class AssignmentUpdatedEvent { - declare ["constructor"]: typeof AssignmentUpdatedEvent; +export class ManualAssignmentUpdatedEvent { + declare ["constructor"]: typeof ManualAssignmentUpdatedEvent; + static plugin = "exp_groups" as const; + static type = "event" as const; + static src = "controller" as const; + static dst = ["control", "instance"] as const; + static permission = "exp_groups.assignment.subscribe" as const; + + constructor( + public updates: AssignmentRecord[], + ) {} + + static jsonSchema = Type.Object({ + updates: Type.Array(AssignmentRecord.jsonSchema), + }); + + toJSON() { + return { updates: this.updates.map(assignment => assignment.toJSON()) }; + } + + static fromJSON(json: Static) { + return new this(json.updates.map(assignment => AssignmentRecord.fromJSON(assignment))); + } +} + +export class ResolvedAssignmentUpdatedEvent { + declare ["constructor"]: typeof ResolvedAssignmentUpdatedEvent; static plugin = "exp_groups" as const; static type = "event" as const; static src = "controller" as const; @@ -486,20 +515,23 @@ export class AssignmentGetRequest { constructor( public name: string, + public resolve: boolean = false, ) {} static jsonSchema = Type.Object({ name: Type.String(), + resolve: Type.Boolean(), }); toJSON() { return { name: this.name, + resolve: this.resolve, }; } static fromJSON(json: Static) { - return new this(json.name); + return new this(json.name, json.resolve); } } From a521cdd9012fbd7eb679409141d2083144d61409 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Fri, 22 May 2026 20:15:36 +0100 Subject: [PATCH 08/12] Change to dev env to fix building --- exp_commands/package.json | 4 +- exp_groups/package.json | 18 +- exp_gui/package.json | 4 +- exp_legacy/package.json | 4 +- exp_scenario/package.json | 6 +- exp_scenario/web/~index.tsx | 68 - exp_server_ups/package.json | 4 +- exp_util/package.json | 4 +- package.json | 12 - pnpm-lock.yaml | 3752 ----------------------------------- pnpm-workspace.yaml | 16 - 11 files changed, 28 insertions(+), 3864 deletions(-) delete mode 100644 exp_scenario/web/~index.tsx delete mode 100644 package.json delete mode 100644 pnpm-lock.yaml delete mode 100644 pnpm-workspace.yaml diff --git a/exp_commands/package.json b/exp_commands/package.json index 1bcf6c28be..bd7e0a20c4 100644 --- a/exp_commands/package.json +++ b/exp_commands/package.json @@ -13,10 +13,10 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "catalog:" + "@clusterio/lib": "workspace:^" }, "devDependencies": { - "@clusterio/lib": "catalog:", + "@clusterio/lib": "workspace:^", "@types/node": "catalog:", "typescript": "catalog:", "webpack": "catalog:", diff --git a/exp_groups/package.json b/exp_groups/package.json index 518bc8e5b0..05bd95794b 100644 --- a/exp_groups/package.json +++ b/exp_groups/package.json @@ -13,12 +13,24 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "catalog:" + "@clusterio/controller": "workspace:^", + "@clusterio/host": "workspace:^", + "@clusterio/lib": "workspace:^", + "@clusterio/web_ui": "workspace:^" }, "devDependencies": { - "typescript": "catalog:", + "@ant-design/icons": "^6.2.3", + "@clusterio/controller": "workspace:^", + "@clusterio/host": "workspace:^", + "@clusterio/lib": "workspace:^", + "@clusterio/web_ui": "workspace:^", "@types/node": "catalog:", - "@clusterio/lib": "catalog:", + "@types/react": "catalog:", + "antd": "catalog:", + "react": "catalog:", + "react-dom": "catalog:", + "react-router-dom": "catalog:", + "typescript": "catalog:", "webpack": "catalog:", "webpack-cli": "catalog:", "webpack-merge": "catalog:" diff --git a/exp_gui/package.json b/exp_gui/package.json index 4e112edbf3..441f7dff45 100644 --- a/exp_gui/package.json +++ b/exp_gui/package.json @@ -13,10 +13,10 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "catalog:" + "@clusterio/lib": "workspace:^" }, "devDependencies": { - "@clusterio/lib": "catalog:", + "@clusterio/lib": "workspace:^", "@types/node": "catalog:", "typescript": "catalog:", "webpack": "catalog:", diff --git a/exp_legacy/package.json b/exp_legacy/package.json index 5ab1fc1f26..70d90b2e53 100644 --- a/exp_legacy/package.json +++ b/exp_legacy/package.json @@ -13,10 +13,10 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "catalog:" + "@clusterio/lib": "workspace:^" }, "devDependencies": { - "@clusterio/lib": "catalog:", + "@clusterio/lib": "workspace:^", "@types/node": "catalog:", "typescript": "catalog:", "webpack": "catalog:", diff --git a/exp_scenario/package.json b/exp_scenario/package.json index 93ba07b1b1..a7abd8c2fc 100644 --- a/exp_scenario/package.json +++ b/exp_scenario/package.json @@ -13,11 +13,11 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "catalog:" + "@clusterio/lib": "workspace:^" }, "devDependencies": { - "@clusterio/lib": "catalog:", - "@clusterio/web_ui": "catalog:", + "@clusterio/lib": "workspace:^", + "@clusterio/web_ui": "workspace:^", "@types/node": "catalog:", "@types/react": "catalog:", "antd": "catalog:", diff --git a/exp_scenario/web/~index.tsx b/exp_scenario/web/~index.tsx deleted file mode 100644 index f4d7ff80d0..0000000000 --- a/exp_scenario/web/~index.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { - useContext, useEffect, useState, - useCallback, useSyncExternalStore, -} from "react"; - -// import { -// -// } from "antd"; - -import { - BaseWebPlugin, PageLayout, PageHeader, Control, ControlContext, notifyErrorHandler, -} from "@clusterio/web_ui"; - -import { - PluginExampleEvent, PluginExampleRequest, - ExampleSubscribableUpdate, ExampleSubscribableValue, -} from "../messages"; - -import * as lib from "@clusterio/lib"; - -function MyTemplatePage() { - const control = useContext(ControlContext); - const plugin = control.plugins.get("exp_scenario") as WebPlugin; - const [subscribableData, synced] = plugin.useSubscribableData(); - - return - - Synced: {String(synced)} Data: {JSON.stringify([...subscribableData.values()])} - ; -} - -export class WebPlugin extends BaseWebPlugin { - subscribableData = new lib.EventSubscriber(ExampleSubscribableUpdate, this.control); - - async init() { - this.pages = [ - { - path: "/exp_scenario", - sidebarName: "exp_scenario", - // This permission is client side only, so it must match the permission string of a resource request to be secure - // An undefined value means that the page will always be visible - permission: "exp_scenario.example.permission.subscribe", - content: , - }, - ]; - - this.control.handle(PluginExampleEvent, this.handlePluginExampleEvent.bind(this)); - this.control.handle(PluginExampleRequest, this.handlePluginExampleRequest.bind(this)); - } - - useSubscribableData() { - const control = useContext(ControlContext); - const subscribe = useCallback((callback: () => void) => this.subscribableData.subscribe(callback), [control]); - return useSyncExternalStore(subscribe, () => this.subscribableData.getSnapshot()); - } - - async handlePluginExampleEvent(event: PluginExampleEvent) { - this.logger.info(JSON.stringify(event)); - } - - async handlePluginExampleRequest(request: PluginExampleRequest) { - this.logger.info(JSON.stringify(request)); - return { - myResponseString: request.myString, - myResponseNumbers: request.myNumberArray, - }; - } -} diff --git a/exp_server_ups/package.json b/exp_server_ups/package.json index f632ca4bef..3cd9a76a95 100644 --- a/exp_server_ups/package.json +++ b/exp_server_ups/package.json @@ -13,12 +13,12 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "catalog:" + "@clusterio/lib": "workspace:^" }, "devDependencies": { + "@clusterio/lib": "workspace:^", "typescript": "catalog:", "@types/node": "catalog:", - "@clusterio/lib": "catalog:", "webpack": "catalog:", "webpack-cli": "catalog:", "webpack-merge": "catalog:" diff --git a/exp_util/package.json b/exp_util/package.json index 4ca7677513..ac95386f84 100644 --- a/exp_util/package.json +++ b/exp_util/package.json @@ -13,10 +13,10 @@ "node": ">=18" }, "peerDependencies": { - "@clusterio/lib": "catalog:" + "@clusterio/lib": "workspace:^" }, "devDependencies": { - "@clusterio/lib": "catalog:", + "@clusterio/lib": "workspace:^", "@types/node": "catalog:", "typescript": "catalog:", "webpack": "catalog:", diff --git a/package.json b/package.json deleted file mode 100644 index 4b00e095a4..0000000000 --- a/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "root", - "private": true, - "files": [], - "scripts": { - "build": "tsc --build", - "watch": "tsc --build --watch" - }, - "devDependencies": { - "typescript": "catalog:" - } -} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 279a56ca43..0000000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,3752 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: false - excludeLinksFromLockfile: false - -catalogs: - default: - '@clusterio/lib': - specifier: 2.0.0-alpha.25 - version: 2.0.0-alpha.25 - '@clusterio/web_ui': - specifier: 2.0.0-alpha.25 - version: 2.0.0-alpha.25 - '@sinclair/typebox': - specifier: ^0.30.4 - version: 0.30.4 - '@types/node': - specifier: ^20.19.41 - version: 20.19.41 - '@types/react': - specifier: ^18.3.29 - version: 18.3.29 - antd: - specifier: ^5.29.3 - version: 5.29.3 - react: - specifier: ^18.3.1 - version: 18.3.1 - react-dom: - specifier: ^18.3.1 - version: 18.3.1 - typescript: - specifier: ^5.9.3 - version: 5.9.3 - webpack: - specifier: ^5.107.0 - version: 5.107.0 - webpack-cli: - specifier: ^5.1.4 - version: 5.1.4 - webpack-merge: - specifier: ^5.10.0 - version: 5.10.0 - -importers: - - .: - devDependencies: - typescript: - specifier: 'catalog:' - version: 5.9.3 - - exp_commands: - dependencies: - '@expcluster/lib_util': - specifier: workspace:^ - version: link:../exp_util - '@sinclair/typebox': - specifier: 'catalog:' - version: 0.30.4 - devDependencies: - '@clusterio/lib': - specifier: 'catalog:' - version: 2.0.0-alpha.25 - '@types/node': - specifier: 'catalog:' - version: 20.19.41 - typescript: - specifier: 'catalog:' - version: 5.9.3 - webpack: - specifier: 'catalog:' - version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: - specifier: 'catalog:' - version: 5.1.4(webpack@5.107.0) - webpack-merge: - specifier: 'catalog:' - version: 5.10.0 - - exp_groups: - dependencies: - '@sinclair/typebox': - specifier: 'catalog:' - version: 0.30.4 - devDependencies: - '@clusterio/lib': - specifier: 'catalog:' - version: 2.0.0-alpha.25 - '@types/node': - specifier: 'catalog:' - version: 20.19.41 - typescript: - specifier: 'catalog:' - version: 5.9.3 - webpack: - specifier: 'catalog:' - version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: - specifier: 'catalog:' - version: 5.1.4(webpack@5.107.0) - webpack-merge: - specifier: 'catalog:' - version: 5.10.0 - - exp_gui: - dependencies: - '@expcluster/lib_util': - specifier: workspace:^ - version: link:../exp_util - '@sinclair/typebox': - specifier: 'catalog:' - version: 0.30.4 - devDependencies: - '@clusterio/lib': - specifier: 'catalog:' - version: 2.0.0-alpha.25 - '@types/node': - specifier: 'catalog:' - version: 20.19.41 - typescript: - specifier: 'catalog:' - version: 5.9.3 - webpack: - specifier: 'catalog:' - version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: - specifier: 'catalog:' - version: 5.1.4(webpack@5.107.0) - webpack-merge: - specifier: 'catalog:' - version: 5.10.0 - - exp_legacy: - dependencies: - '@expcluster/lib_commands': - specifier: workspace:^ - version: link:../exp_commands - '@expcluster/lib_util': - specifier: workspace:^ - version: link:../exp_util - '@sinclair/typebox': - specifier: 'catalog:' - version: 0.30.4 - devDependencies: - '@clusterio/lib': - specifier: 'catalog:' - version: 2.0.0-alpha.25 - '@types/node': - specifier: 'catalog:' - version: 20.19.41 - typescript: - specifier: 'catalog:' - version: 5.9.3 - webpack: - specifier: 'catalog:' - version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: - specifier: 'catalog:' - version: 5.1.4(webpack@5.107.0) - webpack-merge: - specifier: 'catalog:' - version: 5.10.0 - - exp_scenario: - dependencies: - '@expcluster/lib_commands': - specifier: workspace:^ - version: link:../exp_commands - '@expcluster/lib_util': - specifier: workspace:^ - version: link:../exp_util - '@sinclair/typebox': - specifier: 'catalog:' - version: 0.30.4 - devDependencies: - '@clusterio/lib': - specifier: 'catalog:' - version: 2.0.0-alpha.25 - '@clusterio/web_ui': - specifier: 'catalog:' - version: 2.0.0-alpha.25 - '@types/node': - specifier: 'catalog:' - version: 20.19.41 - '@types/react': - specifier: 'catalog:' - version: 18.3.29 - antd: - specifier: 'catalog:' - version: 5.29.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: - specifier: 'catalog:' - version: 18.3.1 - react-dom: - specifier: 'catalog:' - version: 18.3.1(react@18.3.1) - typescript: - specifier: 'catalog:' - version: 5.9.3 - webpack: - specifier: 'catalog:' - version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: - specifier: 'catalog:' - version: 5.1.4(webpack@5.107.0) - webpack-merge: - specifier: 'catalog:' - version: 5.10.0 - - exp_server_ups: - dependencies: - '@expcluster/lib_commands': - specifier: workspace:^ - version: link:../exp_commands - '@expcluster/lib_gui': - specifier: workspace:^ - version: link:../exp_gui - '@expcluster/lib_util': - specifier: workspace:^ - version: link:../exp_util - '@sinclair/typebox': - specifier: 'catalog:' - version: 0.30.4 - devDependencies: - '@clusterio/lib': - specifier: 'catalog:' - version: 2.0.0-alpha.25 - '@types/node': - specifier: 'catalog:' - version: 20.19.41 - typescript: - specifier: 'catalog:' - version: 5.9.3 - webpack: - specifier: 'catalog:' - version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: - specifier: 'catalog:' - version: 5.1.4(webpack@5.107.0) - webpack-merge: - specifier: 'catalog:' - version: 5.10.0 - - exp_util: - dependencies: - '@sinclair/typebox': - specifier: 'catalog:' - version: 0.30.4 - devDependencies: - '@clusterio/lib': - specifier: 'catalog:' - version: 2.0.0-alpha.25 - '@types/node': - specifier: 'catalog:' - version: 20.19.41 - typescript: - specifier: 'catalog:' - version: 5.9.3 - webpack: - specifier: 'catalog:' - version: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: - specifier: 'catalog:' - version: 5.1.4(webpack@5.107.0) - webpack-merge: - specifier: 'catalog:' - version: 5.10.0 - -packages: - - '@ant-design/colors@7.2.1': - resolution: {integrity: sha512-lCHDcEzieu4GA3n8ELeZ5VQ8pKQAWcGGLRTQ50aQM2iqPpq2evTxER84jfdPvsPAtEcZ7m44NI45edFMo8oOYQ==} - - '@ant-design/cssinjs-utils@1.1.3': - resolution: {integrity: sha512-nOoQMLW1l+xR1Co8NFVYiP8pZp3VjIIzqV6D6ShYF2ljtdwWJn5WSsH+7kvCktXL/yhEtWURKOfH5Xz/gzlwsg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@ant-design/cssinjs@1.24.0': - resolution: {integrity: sha512-K4cYrJBsgvL+IoozUXYjbT6LHHNt+19a9zkvpBPxLjFHas1UpPM2A5MlhROb0BT8N8WoavM5VsP9MeSeNK/3mg==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - '@ant-design/fast-color@2.0.6': - resolution: {integrity: sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==} - engines: {node: '>=8.x'} - - '@ant-design/icons-svg@4.4.2': - resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==} - - '@ant-design/icons@5.6.1': - resolution: {integrity: sha512-0/xS39c91WjPAZOWsvi1//zjx6kAp4kxWwctR6kuU6p133w8RU0D2dSCvZC19uQyharg/sAvYxGYWl01BbZZfg==} - engines: {node: '>=8'} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - '@ant-design/react-slick@1.1.2': - resolution: {integrity: sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==} - peerDependencies: - react: '>=16.9.0' - - '@babel/runtime@7.29.2': - resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} - engines: {node: '>=6.9.0'} - - '@clusterio/lib@2.0.0-alpha.25': - resolution: {integrity: sha512-kFHSpgxIiQ0ZIxLEsTxXIBSMAQoOl3WlkiFYMd7xcOx+SgDbLl9mWyRiAqqydhQwmscLYCbAlV0vDUUipRUDzg==} - engines: {node: '>=12'} - - '@clusterio/web_ui@2.0.0-alpha.25': - resolution: {integrity: sha512-ROXeVLQaICE5y4jtUUmcQhOSuG6D3+qpufTLdB2c57pO7i1RNBTo3lgbSfN7shy4HDWFd3n3r4VTNCav2pZGRQ==} - engines: {node: '>=12'} - - '@colors/colors@1.6.0': - resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} - engines: {node: '>=0.1.90'} - - '@dabh/diagnostics@2.0.8': - resolution: {integrity: sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==} - - '@discoveryjs/json-ext@0.5.7': - resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} - engines: {node: '>=10.0.0'} - - '@emotion/hash@0.8.0': - resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} - - '@emotion/unitless@0.7.5': - resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/source-map@0.3.11': - resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@rc-component/async-validator@5.1.0': - resolution: {integrity: sha512-n4HcR5siNUXRX23nDizbZBQPO0ZM/5oTtmKZ6/eqL0L2bo747cklFdZGRN2f+c9qWGICwDzrhW0H7tE9PptdcA==} - engines: {node: '>=14.x'} - - '@rc-component/color-picker@2.0.1': - resolution: {integrity: sha512-WcZYwAThV/b2GISQ8F+7650r5ZZJ043E57aVBFkQ+kSY4C6wdofXgB0hBx+GPGpIU0Z81eETNoDUJMr7oy/P8Q==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/context@1.4.0': - resolution: {integrity: sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/mini-decimal@1.1.3': - resolution: {integrity: sha512-bk/FJ09fLf+NLODMAFll6CfYrHPBioTedhW6lxDBuuWucJEqFUd4l/D/5JgIi3dina6sYahB8iuPAZTNz2pMxw==} - engines: {node: '>=8.x'} - - '@rc-component/mutate-observer@1.1.0': - resolution: {integrity: sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/portal@1.1.2': - resolution: {integrity: sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/qrcode@1.1.1': - resolution: {integrity: sha512-LfLGNymzKdUPjXUbRP+xOhIWY4jQ+YMj5MmWAcgcAq1Ij8XP7tRmAXqyuv96XvLUBE/5cA8hLFl9eO1JQMujrA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/tour@1.15.1': - resolution: {integrity: sha512-Tr2t7J1DKZUpfJuDZWHxyxWpfmj8EZrqSgyMZ+BCdvKZ6r1UDsfU46M/iWAAFBy961Ssfom2kv5f3UcjIL2CmQ==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/trigger@2.3.1': - resolution: {integrity: sha512-ORENF39PeXTzM+gQEshuk460Z8N4+6DkjpxlpE7Q3gYy1iBpLrx0FOJz3h62ryrJZ/3zCAUIkT1Pb/8hHWpb3A==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@remix-run/router@1.23.2': - resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==} - engines: {node: '>=14.0.0'} - - '@sinclair/typebox@0.30.4': - resolution: {integrity: sha512-wFuuDR+O1OAE2GL0q68h1Ty00RE6Ihcixr55A6TU5RCvOUHnwJw9LGuDVg9NxDiAp7m/YJpa+UaOuLAz0ziyOQ==} - - '@so-ric/colorspace@1.1.6': - resolution: {integrity: sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==} - - '@swc/core-darwin-arm64@1.15.33': - resolution: {integrity: sha512-N+L0uXhuO7FIfzqwgxmzv0zIpV0qEp8wPX3QQs2p4atjMoywup2JTeDlXPw+z9pWJGCae3JjM+tZ6myclI+2gA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - - '@swc/core-darwin-x64@1.15.33': - resolution: {integrity: sha512-/Il4QHSOhV4FekbsDtkrNmKbsX26oSysvgrRswa/RYOHXAkwXDbB4jaeKq6PsJLSPkzJ2KzQ061gtBnk0vNHfA==} - engines: {node: '>=10'} - cpu: [x64] - os: [darwin] - - '@swc/core-linux-arm-gnueabihf@1.15.33': - resolution: {integrity: sha512-C64hBnBxq4viOPQ8hlx+2lJ23bzZBGnjw7ryALmS+0Q3zHmwO8lw1/DArLENw4Q18/0w5wdEO1k3m1wWNtKGqQ==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - - '@swc/core-linux-arm64-gnu@1.15.33': - resolution: {integrity: sha512-TRJfnJbX3jqpxRDRoieMzRiCBS5jOmXNb3iQXmcgjFEHKLnAgK1RZRU8Cq1MsPqO4jAJp/ld1G4O3fXuxv85uw==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@swc/core-linux-arm64-musl@1.15.33': - resolution: {integrity: sha512-il7tYM+CpUNzieQbwAjFT1P8zqAhmGWNAGhQZBnxurXZ0aNn+5nqYFTEUKNZl7QibtT0uQXzTZrNGHCIj6Y1Og==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@swc/core-linux-ppc64-gnu@1.15.33': - resolution: {integrity: sha512-ZtNBwN0Z7CFj9Il0FcPaKdjgP7URyKu/3RfH46vq+0paOBqLj4NYldD6Qo//Duif/7IOtAraUfDOmp0PLAufog==} - engines: {node: '>=10'} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@swc/core-linux-s390x-gnu@1.15.33': - resolution: {integrity: sha512-De1IyajoOmhOYYjw/lx66bKlyDpHZTueqwpDrWgf5O7T6d1ODeJJO9/OqMBmrBQc5C+dNnlmIufHsp4QVCWufA==} - engines: {node: '>=10'} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@swc/core-linux-x64-gnu@1.15.33': - resolution: {integrity: sha512-mGTH0YxmUN+x6vRN/I6NOk5X0ogNktkwPnJ94IMvR7QjhRDwL0O8RXEDhyUM0YtwWrryBOqaJQBX4zruxEPRGw==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@swc/core-linux-x64-musl@1.15.33': - resolution: {integrity: sha512-hj628ZkSEJf6zMf5VMbYrG2O6QqyTIp2qwY6VlCjvIa9lAEZ5c2lfPblCLVGYubTeLJDxadLB/CxqQYOQABeEQ==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@swc/core-win32-arm64-msvc@1.15.33': - resolution: {integrity: sha512-GV2oohtN2/5+KSccl86VULu3aT+LrISC8uzgSq0FRnikpD+Zwc+sBlXmoKQ+Db6jI57ITUOIB8jRkdGMABC29g==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - - '@swc/core-win32-ia32-msvc@1.15.33': - resolution: {integrity: sha512-gtyvzSNR8DHKfFEA2uqb8Ld1myqi6uEg2jyeUq3ikn5ytYs7H8RpZYC8mdy4NXr8hfcdJfCLXPlYaqqfBXpoEQ==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - - '@swc/core-win32-x64-msvc@1.15.33': - resolution: {integrity: sha512-d6fRqQSkJI+kmMEBWaDQ7TMl8+YjLYbwRUPZQ9DY0ORBJeTzOrG0twvfvlZ2xgw6jA0ScQKgfBm4vHLSLl5Hqg==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - - '@swc/core@1.15.33': - resolution: {integrity: sha512-jOlwnFV2xhuuZeAUILGFULeR6vDPfijEJ57evfocwznQldLU3w2cZ9bSDryY9ip+AsM3r1NJKzf47V2NXebkeQ==} - engines: {node: '>=10'} - peerDependencies: - '@swc/helpers': '>=0.5.17' - peerDependenciesMeta: - '@swc/helpers': - optional: true - - '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - - '@swc/types@0.1.26': - resolution: {integrity: sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==} - - '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - - '@types/glob@7.2.0': - resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/minimatch@6.0.0': - resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} - deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. - - '@types/node@20.19.41': - resolution: {integrity: sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==} - - '@types/prop-types@15.7.15': - resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - - '@types/react@18.3.29': - resolution: {integrity: sha512-ch0qJdr2JY0r04NXSprbK6TXOgnaJ1Tz23fm5W+z0/CBah6BSBc3n96h7K9GOtwh0HrilNWHIBzE1Ko4Dcw/Wg==} - - '@types/triple-beam@1.3.5': - resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} - - '@webassemblyjs/ast@1.14.1': - resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} - - '@webassemblyjs/floating-point-hex-parser@1.13.2': - resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} - - '@webassemblyjs/helper-api-error@1.13.2': - resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} - - '@webassemblyjs/helper-buffer@1.14.1': - resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} - - '@webassemblyjs/helper-numbers@1.13.2': - resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} - - '@webassemblyjs/helper-wasm-bytecode@1.13.2': - resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} - - '@webassemblyjs/helper-wasm-section@1.14.1': - resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} - - '@webassemblyjs/ieee754@1.13.2': - resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} - - '@webassemblyjs/leb128@1.13.2': - resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} - - '@webassemblyjs/utf8@1.13.2': - resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} - - '@webassemblyjs/wasm-edit@1.14.1': - resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} - - '@webassemblyjs/wasm-gen@1.14.1': - resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} - - '@webassemblyjs/wasm-opt@1.14.1': - resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} - - '@webassemblyjs/wasm-parser@1.14.1': - resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} - - '@webassemblyjs/wast-printer@1.14.1': - resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - - '@webpack-cli/configtest@2.1.1': - resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} - engines: {node: '>=14.15.0'} - peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x - - '@webpack-cli/info@2.0.2': - resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==} - engines: {node: '>=14.15.0'} - peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x - - '@webpack-cli/serve@2.0.5': - resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==} - engines: {node: '>=14.15.0'} - peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x - webpack-dev-server: '*' - peerDependenciesMeta: - webpack-dev-server: - optional: true - - '@xtuc/ieee754@1.2.0': - resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} - - '@xtuc/long@4.2.2': - resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - - acorn-import-phases@1.0.4: - resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} - engines: {node: '>=10.13.0'} - peerDependencies: - acorn: ^8.14.0 - - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - - ajv-keywords@3.5.2: - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} - peerDependencies: - ajv: ^6.9.1 - - ajv-keywords@5.1.0: - resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} - peerDependencies: - ajv: ^8.8.2 - - ajv@6.15.0: - resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} - - ajv@8.20.0: - resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - antd@5.29.3: - resolution: {integrity: sha512-3DdbGCa9tWAJGcCJ6rzR8EJFsv2CtyEbkVabZE14pfgUHfCicWCj0/QzQVLDYg8CPfQk9BH7fHCoTXHTy7MP/A==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - array-union@1.0.2: - resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} - engines: {node: '>=0.10.0'} - - array-uniq@1.0.3: - resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} - engines: {node: '>=0.10.0'} - - assert@2.1.0: - resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} - - async-validator@4.2.5: - resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} - - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - baseline-browser-mapping@2.10.31: - resolution: {integrity: sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==} - engines: {node: '>=6.0.0'} - hasBin: true - - big.js@5.2.2: - resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - - brace-expansion@1.1.14: - resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} - - brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} - engines: {node: 18 || 20 || >=22} - - browserify-zlib@0.2.0: - resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} - - browserslist@4.28.2: - resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.9: - resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - caniuse-lite@1.0.30001793: - resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chrome-trace-event@1.0.4: - resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} - engines: {node: '>=6.0'} - - classnames@2.5.1: - resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} - - clean-webpack-plugin@4.0.0: - resolution: {integrity: sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w==} - engines: {node: '>=10.0.0'} - peerDependencies: - webpack: '>=4.0.0 <6.0.0' - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - clone-deep@4.0.1: - resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} - engines: {node: '>=6'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-convert@3.1.3: - resolution: {integrity: sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==} - engines: {node: '>=14.6'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - color-name@2.1.0: - resolution: {integrity: sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==} - engines: {node: '>=12.20'} - - color-string@2.1.4: - resolution: {integrity: sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==} - engines: {node: '>=18'} - - color@5.0.3: - resolution: {integrity: sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==} - engines: {node: '>=18'} - - colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - - commander@10.0.1: - resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} - engines: {node: '>=14'} - - commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - - compute-scroll-into-view@3.1.1: - resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - copy-to-clipboard@3.3.3: - resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} - - core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - css-loader@6.11.0: - resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} - engines: {node: '>= 12.13.0'} - peerDependencies: - '@rspack/core': 0.x || 1.x - webpack: ^5.0.0 - peerDependenciesMeta: - '@rspack/core': - optional: true - webpack: - optional: true - - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - dayjs@1.11.20: - resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - - del@4.1.1: - resolution: {integrity: sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==} - engines: {node: '>=6'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - electron-to-chromium@1.5.360: - resolution: {integrity: sha512-GkcBt6YYAw9SxFWn+xVar4cLVGlXVuswwtRLBozi2zp0GjXs4ZnOrqV4zbXzg35n7w81hCkyJNYicgXlVHAmBA==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emojis-list@3.0.0: - resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} - engines: {node: '>= 4'} - - enabled@2.0.0: - resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} - - enhanced-resolve@5.21.6: - resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==} - engines: {node: '>=10.13.0'} - - envinfo@7.21.0: - resolution: {integrity: sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==} - engines: {node: '>=4'} - hasBin: true - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-module-lexer@2.1.0: - resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-uri@3.1.2: - resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} - - fastest-levenshtein@1.0.16: - resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} - engines: {node: '>= 4.9.1'} - - fecha@4.2.3: - resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} - - file-loader@6.2.0: - resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} - engines: {node: '>= 10.13.0'} - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - - fn.name@1.1.0: - resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} - - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - generator-function@2.0.1: - resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} - engines: {node: '>= 0.4'} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - - globby@6.1.0: - resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} - engines: {node: '>=0.10.0'} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} - engines: {node: '>= 0.4'} - - icss-utils@5.1.0: - resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - immediate@3.0.6: - resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - - import-local@3.2.0: - resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} - engines: {node: '>=8'} - hasBin: true - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - interpret@3.1.1: - resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} - engines: {node: '>=10.13.0'} - - is-arguments@1.2.0: - resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} - engines: {node: '>= 0.4'} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} - engines: {node: '>= 0.4'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-generator-function@1.1.2: - resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} - engines: {node: '>= 0.4'} - - is-nan@1.3.2: - resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} - engines: {node: '>= 0.4'} - - is-path-cwd@2.2.0: - resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} - engines: {node: '>=6'} - - is-path-in-cwd@2.1.0: - resolution: {integrity: sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==} - engines: {node: '>=6'} - - is-path-inside@2.1.0: - resolution: {integrity: sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==} - engines: {node: '>=6'} - - is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - - jest-worker@27.5.1: - resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} - engines: {node: '>= 10.13.0'} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - - json2mq@0.2.0: - resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jszip@3.10.1: - resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} - - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - - kuler@2.0.0: - resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - - lie@3.3.0: - resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - - loader-runner@4.3.2: - resolution: {integrity: sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==} - engines: {node: '>=6.11.5'} - - loader-utils@2.0.4: - resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} - engines: {node: '>=8.9.0'} - - locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - - logform@2.7.0: - resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} - engines: {node: '>= 12.0.0'} - - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} - engines: {node: 18 || 20 || >=22} - - minimatch@3.1.5: - resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - nanoid@3.3.12: - resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - neo-async@2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - - node-releases@2.0.44: - resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==} - - null-loader@4.0.1: - resolution: {integrity: sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==} - engines: {node: '>= 10.13.0'} - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-is@1.1.6: - resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - one-time@1.0.0: - resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} - - os-browserify@0.3.0: - resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} - - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - - p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - - p-map@2.1.0: - resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} - engines: {node: '>=6'} - - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - - pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - - path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - path-is-inside@1.0.2: - resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - - pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - - pinkie-promise@2.0.1: - resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} - engines: {node: '>=0.10.0'} - - pinkie@2.0.4: - resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} - engines: {node: '>=0.10.0'} - - pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - - postcss-modules-extract-imports@3.1.0: - resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - - postcss-modules-local-by-default@4.2.0: - resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - - postcss-modules-scope@3.2.1: - resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - - postcss-modules-values@4.0.0: - resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - - postcss-selector-parser@7.1.1: - resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} - engines: {node: '>=4'} - - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - - postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} - engines: {node: ^10 || ^12 || >=14} - - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - - process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - rc-cascader@3.34.0: - resolution: {integrity: sha512-KpXypcvju9ptjW9FaN2NFcA2QH9E9LHKq169Y0eWtH4e/wHQ5Wh5qZakAgvb8EKZ736WZ3B0zLLOBsrsja5Dag==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-checkbox@3.5.0: - resolution: {integrity: sha512-aOAQc3E98HteIIsSqm6Xk2FPKIER6+5vyEFMZfo73TqM+VVAIqOkHoPjgKLqSNtVLWScoaM7vY2ZrGEheI79yg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-collapse@3.9.0: - resolution: {integrity: sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-dialog@9.6.0: - resolution: {integrity: sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-drawer@7.3.0: - resolution: {integrity: sha512-DX6CIgiBWNpJIMGFO8BAISFkxiuKitoizooj4BDyee8/SnBn0zwO2FHrNDpqqepj0E/TFTDpmEBCyFuTgC7MOg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-dropdown@4.2.1: - resolution: {integrity: sha512-YDAlXsPv3I1n42dv1JpdM7wJ+gSUBfeyPK59ZpBD9jQhK9jVuxpjj3NmWQHOBceA1zEPVX84T2wbdb2SD0UjmA==} - peerDependencies: - react: '>=16.11.0' - react-dom: '>=16.11.0' - - rc-field-form@1.44.0: - resolution: {integrity: sha512-el7w87fyDUsca63Y/s8qJcq9kNkf/J5h+iTdqG5WsSHLH0e6Usl7QuYSmSVzJMgtp40mOVZIY/W/QP9zwrp1FA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-field-form@2.7.1: - resolution: {integrity: sha512-vKeSifSJ6HoLaAB+B8aq/Qgm8a3dyxROzCtKNCsBQgiverpc4kWDQihoUwzUj+zNWJOykwSY4dNX3QrGwtVb9A==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-image@7.12.0: - resolution: {integrity: sha512-cZ3HTyyckPnNnUb9/DRqduqzLfrQRyi+CdHjdqgsyDpI3Ln5UX1kXnAhPBSJj9pVRzwRFgqkN7p9b6HBDjmu/Q==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-input-number@9.5.0: - resolution: {integrity: sha512-bKaEvB5tHebUURAEXw35LDcnRZLq3x1k7GxfAqBMzmpHkDGzjAtnUL8y4y5N15rIFIg5IJgwr211jInl3cipag==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-input@1.8.0: - resolution: {integrity: sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - rc-mentions@2.20.0: - resolution: {integrity: sha512-w8HCMZEh3f0nR8ZEd466ATqmXFCMGMN5UFCzEUL0bM/nGw/wOS2GgRzKBcm19K++jDyuWCOJOdgcKGXU3fXfbQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-menu@9.16.1: - resolution: {integrity: sha512-ghHx6/6Dvp+fw8CJhDUHFHDJ84hJE3BXNCzSgLdmNiFErWSOaZNsihDAsKq9ByTALo/xkNIwtDFGIl6r+RPXBg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-motion@2.9.5: - resolution: {integrity: sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-notification@5.6.4: - resolution: {integrity: sha512-KcS4O6B4qzM3KH7lkwOB7ooLPZ4b6J+VMmQgT51VZCeEcmghdeR4IrMcFq0LG+RPdnbe/ArT086tGM8Snimgiw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-overflow@1.5.0: - resolution: {integrity: sha512-Lm/v9h0LymeUYJf0x39OveU52InkdRXqnn2aYXfWmo8WdOonIKB2kfau+GF0fWq6jPgtdO9yMqveGcK6aIhJmg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-pagination@5.1.0: - resolution: {integrity: sha512-8416Yip/+eclTFdHXLKTxZvn70duYVGTvUUWbckCCZoIl3jagqke3GLsFrMs0bsQBikiYpZLD9206Ej4SOdOXQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-picker@4.11.3: - resolution: {integrity: sha512-MJ5teb7FlNE0NFHTncxXQ62Y5lytq6sh5nUw0iH8OkHL/TjARSEvSHpr940pWgjGANpjCwyMdvsEV55l5tYNSg==} - engines: {node: '>=8.x'} - peerDependencies: - date-fns: '>= 2.x' - dayjs: '>= 1.x' - luxon: '>= 3.x' - moment: '>= 2.x' - react: '>=16.9.0' - react-dom: '>=16.9.0' - peerDependenciesMeta: - date-fns: - optional: true - dayjs: - optional: true - luxon: - optional: true - moment: - optional: true - - rc-progress@4.0.0: - resolution: {integrity: sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-rate@2.13.1: - resolution: {integrity: sha512-QUhQ9ivQ8Gy7mtMZPAjLbxBt5y9GRp65VcUyGUMF3N3fhiftivPHdpuDIaWIMOTEprAjZPC08bls1dQB+I1F2Q==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-resize-observer@1.4.3: - resolution: {integrity: sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-segmented@2.7.1: - resolution: {integrity: sha512-izj1Nw/Dw2Vb7EVr+D/E9lUTkBe+kKC+SAFSU9zqr7WV2W5Ktaa9Gc7cB2jTqgk8GROJayltaec+DBlYKc6d+g==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - rc-select@14.16.8: - resolution: {integrity: sha512-NOV5BZa1wZrsdkKaiK7LHRuo5ZjZYMDxPP6/1+09+FB4KoNi8jcG1ZqLE3AVCxEsYMBe65OBx71wFoHRTP3LRg==} - engines: {node: '>=8.x'} - peerDependencies: - react: '*' - react-dom: '*' - - rc-slider@11.1.9: - resolution: {integrity: sha512-h8IknhzSh3FEM9u8ivkskh+Ef4Yo4JRIY2nj7MrH6GQmrwV6mcpJf5/4KgH5JaVI1H3E52yCdpOlVyGZIeph5A==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-steps@6.0.1: - resolution: {integrity: sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-switch@4.1.0: - resolution: {integrity: sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-table@7.54.0: - resolution: {integrity: sha512-/wDTkki6wBTjwylwAGjpLKYklKo9YgjZwAU77+7ME5mBoS32Q4nAwoqhA2lSge6fobLW3Tap6uc5xfwaL2p0Sw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-tabs@15.7.0: - resolution: {integrity: sha512-ZepiE+6fmozYdWf/9gVp7k56PKHB1YYoDsKeQA1CBlJ/POIhjkcYiv0AGP0w2Jhzftd3AVvZP/K+V+Lpi2ankA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-textarea@1.10.2: - resolution: {integrity: sha512-HfaeXiaSlpiSp0I/pvWpecFEHpVysZ9tpDLNkxQbMvMz6gsr7aVZ7FpWP9kt4t7DB+jJXesYS0us1uPZnlRnwQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-tooltip@6.4.0: - resolution: {integrity: sha512-kqyivim5cp8I5RkHmpsp1Nn/Wk+1oeloMv9c7LXNgDxUpGm+RbXJGL+OPvDlcRnx9DBeOe4wyOIl4OKUERyH1g==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-tree-select@5.27.0: - resolution: {integrity: sha512-2qTBTzwIT7LRI1o7zLyrCzmo5tQanmyGbSaGTIf7sYimCklAToVVfpMC6OAldSKolcnjorBYPNSKQqJmN3TCww==} - peerDependencies: - react: '*' - react-dom: '*' - - rc-tree@5.13.1: - resolution: {integrity: sha512-FNhIefhftobCdUJshO7M8uZTA9F4OPGVXqGfZkkD/5soDeOhwO06T/aKTrg0WD8gRg/pyfq+ql3aMymLHCTC4A==} - engines: {node: '>=10.x'} - peerDependencies: - react: '*' - react-dom: '*' - - rc-upload@4.11.0: - resolution: {integrity: sha512-ZUyT//2JAehfHzjWowqROcwYJKnZkIUGWaTE/VogVrepSl7AFNbQf4+zGfX4zl9Vrj/Jm8scLO0R6UlPDKK4wA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-util@5.44.4: - resolution: {integrity: sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-virtual-list@3.19.2: - resolution: {integrity: sha512-Ys6NcjwGkuwkeaWBDqfI3xWuZ7rDiQXlH1o2zLfFzATfEgXcqpk8CkgMfbJD81McqjcJVez25a3kPxCR807evA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} - peerDependencies: - react: ^18.3.1 - - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - - react-router-dom@6.30.3: - resolution: {integrity: sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' - - react-router@6.30.3: - resolution: {integrity: sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' - - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} - engines: {node: '>=0.10.0'} - - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - rechoir@0.8.0: - resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} - engines: {node: '>= 10.13.0'} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - - resize-observer-polyfill@1.5.1: - resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} - - resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} - engines: {node: '>= 0.4'} - hasBin: true - - rimraf@2.7.1: - resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} - - safe-stable-stringify@2.5.0: - resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} - engines: {node: '>=10'} - - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} - - schema-utils@3.3.0: - resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} - engines: {node: '>= 10.13.0'} - - schema-utils@4.3.3: - resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} - engines: {node: '>= 10.13.0'} - - scroll-into-view-if-needed@3.1.0: - resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} - - semver@7.8.0: - resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} - engines: {node: '>=10'} - hasBin: true - - set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - - shallow-clone@3.0.1: - resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} - engines: {node: '>=8'} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - source-list-map@2.0.1: - resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - stack-trace@0.0.10: - resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} - - stream-browserify@3.0.0: - resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} - - string-convert@0.2.1: - resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - style-loader@3.3.4: - resolution: {integrity: sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^5.0.0 - - stylis@4.4.0: - resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - swc-loader@0.2.7: - resolution: {integrity: sha512-nwYWw3Fh9ame3Rtm7StS9SBLpHRRnYcK7bnpF3UKZmesAK0gw2/ADvlURFAINmPvKtDLzp+GBiP9yLoEjg6S9w==} - peerDependencies: - '@swc/core': ^1.2.147 - webpack: '>=2' - - tapable@2.3.3: - resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} - engines: {node: '>=6'} - - terser-webpack-plugin@5.6.0: - resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@minify-html/node': '*' - '@swc/core': '*' - '@swc/css': '*' - '@swc/html': '*' - clean-css: '*' - cssnano: '*' - csso: '*' - esbuild: '*' - html-minifier-terser: '*' - lightningcss: '*' - postcss: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@minify-html/node': - optional: true - '@swc/core': - optional: true - '@swc/css': - optional: true - '@swc/html': - optional: true - clean-css: - optional: true - cssnano: - optional: true - csso: - optional: true - esbuild: - optional: true - html-minifier-terser: - optional: true - lightningcss: - optional: true - postcss: - optional: true - uglify-js: - optional: true - - terser@5.47.1: - resolution: {integrity: sha512-tPbLXTI6ohPASb/1YViL428oEHu6/qv1OxqYnfaonVCFHqx4+wCd95pHrQWsL5X4pl90CTyW9piSAsS2L0VoMw==} - engines: {node: '>=10'} - hasBin: true - - text-hex@1.0.0: - resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} - - throttle-debounce@5.0.2: - resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} - engines: {node: '>=12.22'} - - toggle-selection@1.0.6: - resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} - - triple-beam@1.4.1: - resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} - engines: {node: '>= 14.0.0'} - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - util@0.12.5: - resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} - - watchpack@2.5.1: - resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} - engines: {node: '>=10.13.0'} - - webpack-cli@5.1.4: - resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==} - engines: {node: '>=14.15.0'} - hasBin: true - peerDependencies: - '@webpack-cli/generators': '*' - webpack: 5.x.x - webpack-bundle-analyzer: '*' - webpack-dev-server: '*' - peerDependenciesMeta: - '@webpack-cli/generators': - optional: true - webpack-bundle-analyzer: - optional: true - webpack-dev-server: - optional: true - - webpack-manifest-plugin@5.0.1: - resolution: {integrity: sha512-xTlX7dC3hrASixA2inuWFMz6qHsNi6MT3Uiqw621sJjRTShtpMjbDYhPPZBwWUKdIYKIjSq9em6+uzWayf38aQ==} - engines: {node: '>=14'} - peerDependencies: - webpack: ^5.75.0 - - webpack-merge@5.10.0: - resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} - engines: {node: '>=10.0.0'} - - webpack-sources@2.3.1: - resolution: {integrity: sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==} - engines: {node: '>=10.13.0'} - - webpack-sources@3.4.1: - resolution: {integrity: sha512-eACpxRN02yaawnt+uUNIF7Qje6A9zArxBbcAJjK1PK3S9Ycg5jIuJ8pW4q8EMnwNZCEGltcjkRx1QzOxOkKD8A==} - engines: {node: '>=10.13.0'} - - webpack@5.107.0: - resolution: {integrity: sha512-PSxeHk/dmLYZlnTU+vL1Gej6Evg5RNtl3flhxBresfznFnzxinHMzHKloHnywM/3ouQv7/AlZCswWDIkNSggUA==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - - which-typed-array@1.1.20: - resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} - engines: {node: '>= 0.4'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - wildcard@2.0.1: - resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} - - winston-transport@4.9.0: - resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} - engines: {node: '>= 12.0.0'} - - winston@3.19.0: - resolution: {integrity: sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==} - engines: {node: '>= 12.0.0'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - ws@8.20.1: - resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - -snapshots: - - '@ant-design/colors@7.2.1': - dependencies: - '@ant-design/fast-color': 2.0.6 - - '@ant-design/cssinjs-utils@1.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@ant-design/cssinjs': 1.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@babel/runtime': 7.29.2 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@ant-design/cssinjs@1.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.29.2 - '@emotion/hash': 0.8.0 - '@emotion/unitless': 0.7.5 - classnames: 2.5.1 - csstype: 3.2.3 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - stylis: 4.4.0 - - '@ant-design/fast-color@2.0.6': - dependencies: - '@babel/runtime': 7.29.2 - - '@ant-design/icons-svg@4.4.2': {} - - '@ant-design/icons@5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@ant-design/colors': 7.2.1 - '@ant-design/icons-svg': 4.4.2 - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@ant-design/react-slick@1.1.2(react@18.3.1)': - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - json2mq: 0.2.0 - react: 18.3.1 - resize-observer-polyfill: 1.5.1 - throttle-debounce: 5.0.2 - - '@babel/runtime@7.29.2': {} - - '@clusterio/lib@2.0.0-alpha.25': - dependencies: - '@sinclair/typebox': 0.30.4 - ajv: 8.20.0 - chalk: 4.1.2 - fast-deep-equal: 3.1.3 - jszip: 3.10.1 - set-blocking: 2.0.0 - triple-beam: 1.4.1 - winston: 3.19.0 - winston-transport: 4.9.0 - ws: 8.20.1 - yargs: 17.7.2 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - '@clusterio/web_ui@2.0.0-alpha.25': - dependencies: - '@ant-design/icons': 5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@clusterio/lib': 2.0.0-alpha.25 - '@sinclair/typebox': 0.30.4 - '@swc/core': 1.15.33 - antd: 5.29.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - assert: 2.1.0 - browserify-zlib: 0.2.0 - buffer: 6.0.3 - clean-webpack-plugin: 4.0.0(webpack@5.107.0) - css-loader: 6.11.0(webpack@5.107.0) - events: 3.3.0 - file-loader: 6.2.0(webpack@5.107.0) - null-loader: 4.0.1(webpack@5.107.0) - os-browserify: 0.3.0 - path-browserify: 1.0.1 - process: 0.11.10 - rc-field-form: 1.44.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-router-dom: 6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - stream-browserify: 3.0.0 - style-loader: 3.3.4(webpack@5.107.0) - swc-loader: 0.2.7(@swc/core@1.15.33)(webpack@5.107.0) - terser-webpack-plugin: 5.6.0(@swc/core@1.15.33)(webpack@5.107.0) - typescript: 5.9.3 - util: 0.12.5 - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.107.0) - webpack-manifest-plugin: 5.0.1(webpack@5.107.0) - transitivePeerDependencies: - - '@minify-html/node' - - '@rspack/core' - - '@swc/css' - - '@swc/helpers' - - '@swc/html' - - '@webpack-cli/generators' - - bufferutil - - clean-css - - cssnano - - csso - - date-fns - - esbuild - - html-minifier-terser - - lightningcss - - luxon - - moment - - postcss - - uglify-js - - utf-8-validate - - webpack-bundle-analyzer - - webpack-dev-server - - '@colors/colors@1.6.0': {} - - '@dabh/diagnostics@2.0.8': - dependencies: - '@so-ric/colorspace': 1.1.6 - enabled: 2.0.0 - kuler: 2.0.0 - - '@discoveryjs/json-ext@0.5.7': {} - - '@emotion/hash@0.8.0': {} - - '@emotion/unitless@0.7.5': {} - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/source-map@0.3.11': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@rc-component/async-validator@5.1.0': - dependencies: - '@babel/runtime': 7.29.2 - - '@rc-component/color-picker@2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@ant-design/fast-color': 2.0.6 - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@rc-component/context@1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.29.2 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@rc-component/mini-decimal@1.1.3': - dependencies: - '@babel/runtime': 7.29.2 - - '@rc-component/mutate-observer@1.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@rc-component/portal@1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@rc-component/qrcode@1.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.29.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@rc-component/tour@1.15.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@rc-component/trigger@2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@remix-run/router@1.23.2': {} - - '@sinclair/typebox@0.30.4': {} - - '@so-ric/colorspace@1.1.6': - dependencies: - color: 5.0.3 - text-hex: 1.0.0 - - '@swc/core-darwin-arm64@1.15.33': - optional: true - - '@swc/core-darwin-x64@1.15.33': - optional: true - - '@swc/core-linux-arm-gnueabihf@1.15.33': - optional: true - - '@swc/core-linux-arm64-gnu@1.15.33': - optional: true - - '@swc/core-linux-arm64-musl@1.15.33': - optional: true - - '@swc/core-linux-ppc64-gnu@1.15.33': - optional: true - - '@swc/core-linux-s390x-gnu@1.15.33': - optional: true - - '@swc/core-linux-x64-gnu@1.15.33': - optional: true - - '@swc/core-linux-x64-musl@1.15.33': - optional: true - - '@swc/core-win32-arm64-msvc@1.15.33': - optional: true - - '@swc/core-win32-ia32-msvc@1.15.33': - optional: true - - '@swc/core-win32-x64-msvc@1.15.33': - optional: true - - '@swc/core@1.15.33': - dependencies: - '@swc/counter': 0.1.3 - '@swc/types': 0.1.26 - optionalDependencies: - '@swc/core-darwin-arm64': 1.15.33 - '@swc/core-darwin-x64': 1.15.33 - '@swc/core-linux-arm-gnueabihf': 1.15.33 - '@swc/core-linux-arm64-gnu': 1.15.33 - '@swc/core-linux-arm64-musl': 1.15.33 - '@swc/core-linux-ppc64-gnu': 1.15.33 - '@swc/core-linux-s390x-gnu': 1.15.33 - '@swc/core-linux-x64-gnu': 1.15.33 - '@swc/core-linux-x64-musl': 1.15.33 - '@swc/core-win32-arm64-msvc': 1.15.33 - '@swc/core-win32-ia32-msvc': 1.15.33 - '@swc/core-win32-x64-msvc': 1.15.33 - - '@swc/counter@0.1.3': {} - - '@swc/types@0.1.26': - dependencies: - '@swc/counter': 0.1.3 - - '@types/estree@1.0.9': {} - - '@types/glob@7.2.0': - dependencies: - '@types/minimatch': 6.0.0 - '@types/node': 20.19.41 - - '@types/json-schema@7.0.15': {} - - '@types/minimatch@6.0.0': - dependencies: - minimatch: 10.2.5 - - '@types/node@20.19.41': - dependencies: - undici-types: 6.21.0 - - '@types/prop-types@15.7.15': {} - - '@types/react@18.3.29': - dependencies: - '@types/prop-types': 15.7.15 - csstype: 3.2.3 - - '@types/triple-beam@1.3.5': {} - - '@webassemblyjs/ast@1.14.1': - dependencies: - '@webassemblyjs/helper-numbers': 1.13.2 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - - '@webassemblyjs/floating-point-hex-parser@1.13.2': {} - - '@webassemblyjs/helper-api-error@1.13.2': {} - - '@webassemblyjs/helper-buffer@1.14.1': {} - - '@webassemblyjs/helper-numbers@1.13.2': - dependencies: - '@webassemblyjs/floating-point-hex-parser': 1.13.2 - '@webassemblyjs/helper-api-error': 1.13.2 - '@xtuc/long': 4.2.2 - - '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} - - '@webassemblyjs/helper-wasm-section@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/wasm-gen': 1.14.1 - - '@webassemblyjs/ieee754@1.13.2': - dependencies: - '@xtuc/ieee754': 1.2.0 - - '@webassemblyjs/leb128@1.13.2': - dependencies: - '@xtuc/long': 4.2.2 - - '@webassemblyjs/utf8@1.13.2': {} - - '@webassemblyjs/wasm-edit@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/helper-wasm-section': 1.14.1 - '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/wasm-opt': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - '@webassemblyjs/wast-printer': 1.14.1 - - '@webassemblyjs/wasm-gen@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/ieee754': 1.13.2 - '@webassemblyjs/leb128': 1.13.2 - '@webassemblyjs/utf8': 1.13.2 - - '@webassemblyjs/wasm-opt@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - - '@webassemblyjs/wasm-parser@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-api-error': 1.13.2 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/ieee754': 1.13.2 - '@webassemblyjs/leb128': 1.13.2 - '@webassemblyjs/utf8': 1.13.2 - - '@webassemblyjs/wast-printer@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@xtuc/long': 4.2.2 - - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.107.0)': - dependencies: - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.107.0) - - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.107.0)': - dependencies: - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.107.0) - - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack@5.107.0)': - dependencies: - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.107.0) - - '@xtuc/ieee754@1.2.0': {} - - '@xtuc/long@4.2.2': {} - - acorn-import-phases@1.0.4(acorn@8.16.0): - dependencies: - acorn: 8.16.0 - - acorn@8.16.0: {} - - ajv-formats@2.1.1: - dependencies: - ajv: 8.20.0 - - ajv-keywords@3.5.2(ajv@6.15.0): - dependencies: - ajv: 6.15.0 - - ajv-keywords@5.1.0(ajv@8.20.0): - dependencies: - ajv: 8.20.0 - fast-deep-equal: 3.1.3 - - ajv@6.15.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ajv@8.20.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.2 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - ansi-regex@5.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - antd@5.29.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@ant-design/colors': 7.2.1 - '@ant-design/cssinjs': 1.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@ant-design/cssinjs-utils': 1.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@ant-design/fast-color': 2.0.6 - '@ant-design/icons': 5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@ant-design/react-slick': 1.1.2(react@18.3.1) - '@babel/runtime': 7.29.2 - '@rc-component/color-picker': 2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rc-component/mutate-observer': 1.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rc-component/qrcode': 1.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rc-component/tour': 1.15.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - copy-to-clipboard: 3.3.3 - dayjs: 1.11.20 - rc-cascader: 3.34.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-checkbox: 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-collapse: 3.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-dialog: 9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-drawer: 7.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-dropdown: 4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-field-form: 2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-image: 7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-input-number: 9.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-mentions: 2.20.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-menu: 9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-notification: 5.6.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-pagination: 5.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-picker: 4.11.3(dayjs@1.11.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-progress: 4.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-rate: 2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-segmented: 2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-select: 14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-slider: 11.1.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-steps: 6.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-switch: 4.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-table: 7.54.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-tabs: 15.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-textarea: 1.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-tooltip: 6.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-tree: 5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-tree-select: 5.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-upload: 4.11.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - scroll-into-view-if-needed: 3.1.0 - throttle-debounce: 5.0.2 - transitivePeerDependencies: - - date-fns - - luxon - - moment - - array-union@1.0.2: - dependencies: - array-uniq: 1.0.3 - - array-uniq@1.0.3: {} - - assert@2.1.0: - dependencies: - call-bind: 1.0.9 - is-nan: 1.3.2 - object-is: 1.1.6 - object.assign: 4.1.7 - util: 0.12.5 - - async-validator@4.2.5: {} - - async@3.2.6: {} - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.1.0 - - balanced-match@1.0.2: {} - - balanced-match@4.0.4: {} - - base64-js@1.5.1: {} - - baseline-browser-mapping@2.10.31: {} - - big.js@5.2.2: {} - - brace-expansion@1.1.14: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@5.0.6: - dependencies: - balanced-match: 4.0.4 - - browserify-zlib@0.2.0: - dependencies: - pako: 1.0.11 - - browserslist@4.28.2: - dependencies: - baseline-browser-mapping: 2.10.31 - caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.360 - node-releases: 2.0.44 - update-browserslist-db: 1.2.3(browserslist@4.28.2) - - buffer-from@1.1.2: {} - - buffer@6.0.3: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.9: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - caniuse-lite@1.0.30001793: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chrome-trace-event@1.0.4: {} - - classnames@2.5.1: {} - - clean-webpack-plugin@4.0.0(webpack@5.107.0): - dependencies: - del: 4.1.1 - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clone-deep@4.0.1: - dependencies: - is-plain-object: 2.0.4 - kind-of: 6.0.3 - shallow-clone: 3.0.1 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-convert@3.1.3: - dependencies: - color-name: 2.1.0 - - color-name@1.1.4: {} - - color-name@2.1.0: {} - - color-string@2.1.4: - dependencies: - color-name: 2.1.0 - - color@5.0.3: - dependencies: - color-convert: 3.1.3 - color-string: 2.1.4 - - colorette@2.0.20: {} - - commander@10.0.1: {} - - commander@2.20.3: {} - - compute-scroll-into-view@3.1.1: {} - - concat-map@0.0.1: {} - - copy-to-clipboard@3.3.3: - dependencies: - toggle-selection: 1.0.6 - - core-util-is@1.0.3: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - css-loader@6.11.0(webpack@5.107.0): - dependencies: - icss-utils: 5.1.0(postcss@8.5.15) - postcss: 8.5.15 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.15) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.15) - postcss-modules-scope: 3.2.1(postcss@8.5.15) - postcss-modules-values: 4.0.0(postcss@8.5.15) - postcss-value-parser: 4.2.0 - semver: 7.8.0 - optionalDependencies: - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - - cssesc@3.0.0: {} - - csstype@3.2.3: {} - - dayjs@1.11.20: {} - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - - del@4.1.1: - dependencies: - '@types/glob': 7.2.0 - globby: 6.1.0 - is-path-cwd: 2.2.0 - is-path-in-cwd: 2.1.0 - p-map: 2.1.0 - pify: 4.0.1 - rimraf: 2.7.1 - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - electron-to-chromium@1.5.360: {} - - emoji-regex@8.0.0: {} - - emojis-list@3.0.0: {} - - enabled@2.0.0: {} - - enhanced-resolve@5.21.6: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.3 - - envinfo@7.21.0: {} - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-module-lexer@2.1.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - escalade@3.2.0: {} - - eslint-scope@5.1.1: - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@4.3.0: {} - - estraverse@5.3.0: {} - - events@3.3.0: {} - - fast-deep-equal@3.1.3: {} - - fast-json-stable-stringify@2.1.0: {} - - fast-uri@3.1.2: {} - - fastest-levenshtein@1.0.16: {} - - fecha@4.2.3: {} - - file-loader@6.2.0(webpack@5.107.0): - dependencies: - loader-utils: 2.0.4 - schema-utils: 3.3.0 - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - - find-up@4.1.0: - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - - flat@5.0.2: {} - - fn.name@1.1.0: {} - - for-each@0.3.5: - dependencies: - is-callable: 1.2.7 - - fs.realpath@1.0.0: {} - - function-bind@1.1.2: {} - - generator-function@2.0.1: {} - - get-caller-file@2.0.5: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.3 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - glob-to-regexp@0.4.1: {} - - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.5 - once: 1.4.0 - path-is-absolute: 1.0.1 - - globby@6.1.0: - dependencies: - array-union: 1.0.2 - glob: 7.2.3 - object-assign: 4.1.1 - pify: 2.3.0 - pinkie-promise: 2.0.1 - - gopd@1.2.0: {} - - graceful-fs@4.2.11: {} - - has-flag@4.0.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.3: - dependencies: - function-bind: 1.1.2 - - icss-utils@5.1.0(postcss@8.5.15): - dependencies: - postcss: 8.5.15 - - ieee754@1.2.1: {} - - immediate@3.0.6: {} - - import-local@3.2.0: - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - interpret@3.1.1: {} - - is-arguments@1.2.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-callable@1.2.7: {} - - is-core-module@2.16.2: - dependencies: - hasown: 2.0.3 - - is-fullwidth-code-point@3.0.0: {} - - is-generator-function@1.1.2: - dependencies: - call-bound: 1.0.4 - generator-function: 2.0.1 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-nan@1.3.2: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - - is-path-cwd@2.2.0: {} - - is-path-in-cwd@2.1.0: - dependencies: - is-path-inside: 2.1.0 - - is-path-inside@2.1.0: - dependencies: - path-is-inside: 1.0.2 - - is-plain-object@2.0.4: - dependencies: - isobject: 3.0.1 - - is-regex@1.2.1: - dependencies: - call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.3 - - is-stream@2.0.1: {} - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.20 - - isarray@1.0.0: {} - - isexe@2.0.0: {} - - isobject@3.0.1: {} - - jest-worker@27.5.1: - dependencies: - '@types/node': 20.19.41 - merge-stream: 2.0.0 - supports-color: 8.1.1 - - js-tokens@4.0.0: {} - - json-schema-traverse@0.4.1: {} - - json-schema-traverse@1.0.0: {} - - json2mq@0.2.0: - dependencies: - string-convert: 0.2.1 - - json5@2.2.3: {} - - jszip@3.10.1: - dependencies: - lie: 3.3.0 - pako: 1.0.11 - readable-stream: 2.3.8 - setimmediate: 1.0.5 - - kind-of@6.0.3: {} - - kuler@2.0.0: {} - - lie@3.3.0: - dependencies: - immediate: 3.0.6 - - loader-runner@4.3.2: {} - - loader-utils@2.0.4: - dependencies: - big.js: 5.2.2 - emojis-list: 3.0.0 - json5: 2.2.3 - - locate-path@5.0.0: - dependencies: - p-locate: 4.1.0 - - logform@2.7.0: - dependencies: - '@colors/colors': 1.6.0 - '@types/triple-beam': 1.3.5 - fecha: 4.2.3 - ms: 2.1.3 - safe-stable-stringify: 2.5.0 - triple-beam: 1.4.1 - - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 - - math-intrinsics@1.1.0: {} - - merge-stream@2.0.0: {} - - mime-db@1.54.0: {} - - minimatch@10.2.5: - dependencies: - brace-expansion: 5.0.6 - - minimatch@3.1.5: - dependencies: - brace-expansion: 1.1.14 - - ms@2.1.3: {} - - nanoid@3.3.12: {} - - neo-async@2.6.2: {} - - node-releases@2.0.44: {} - - null-loader@4.0.1(webpack@5.107.0): - dependencies: - loader-utils: 2.0.4 - schema-utils: 3.3.0 - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - - object-assign@4.1.1: {} - - object-is@1.1.6: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - - object-keys@1.1.1: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - one-time@1.0.0: - dependencies: - fn.name: 1.1.0 - - os-browserify@0.3.0: {} - - p-limit@2.3.0: - dependencies: - p-try: 2.2.0 - - p-locate@4.1.0: - dependencies: - p-limit: 2.3.0 - - p-map@2.1.0: {} - - p-try@2.2.0: {} - - pako@1.0.11: {} - - path-browserify@1.0.1: {} - - path-exists@4.0.0: {} - - path-is-absolute@1.0.1: {} - - path-is-inside@1.0.2: {} - - path-key@3.1.1: {} - - path-parse@1.0.7: {} - - picocolors@1.1.1: {} - - pify@2.3.0: {} - - pify@4.0.1: {} - - pinkie-promise@2.0.1: - dependencies: - pinkie: 2.0.4 - - pinkie@2.0.4: {} - - pkg-dir@4.2.0: - dependencies: - find-up: 4.1.0 - - possible-typed-array-names@1.1.0: {} - - postcss-modules-extract-imports@3.1.0(postcss@8.5.15): - dependencies: - postcss: 8.5.15 - - postcss-modules-local-by-default@4.2.0(postcss@8.5.15): - dependencies: - icss-utils: 5.1.0(postcss@8.5.15) - postcss: 8.5.15 - postcss-selector-parser: 7.1.1 - postcss-value-parser: 4.2.0 - - postcss-modules-scope@3.2.1(postcss@8.5.15): - dependencies: - postcss: 8.5.15 - postcss-selector-parser: 7.1.1 - - postcss-modules-values@4.0.0(postcss@8.5.15): - dependencies: - icss-utils: 5.1.0(postcss@8.5.15) - postcss: 8.5.15 - - postcss-selector-parser@7.1.1: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss-value-parser@4.2.0: {} - - postcss@8.5.15: - dependencies: - nanoid: 3.3.12 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - process-nextick-args@2.0.1: {} - - process@0.11.10: {} - - punycode@2.3.1: {} - - rc-cascader@3.34.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-select: 14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-tree: 5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-checkbox@3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-collapse@3.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-dialog@9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-drawer@7.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-dropdown@4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-field-form@1.44.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - async-validator: 4.2.5 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/async-validator': 5.1.0 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-image@7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-dialog: 9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-input-number@9.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/mini-decimal': 1.1.3 - classnames: 2.5.1 - rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-input@1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-mentions@2.20.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-menu: 9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-textarea: 1.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-menu@9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-overflow: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-motion@2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-notification@5.6.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-overflow@1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-pagination@5.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-picker@4.11.3(dayjs@1.11.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-overflow: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - dayjs: 1.11.20 - - rc-progress@4.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-rate@2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-resize-observer@1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - resize-observer-polyfill: 1.5.1 - - rc-segmented@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-select@14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-overflow: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-virtual-list: 3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-slider@11.1.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-steps@6.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-switch@4.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-table@7.54.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/context': 1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-virtual-list: 3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-tabs@15.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-dropdown: 4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-menu: 9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-textarea@1.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-tooltip@6.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-tree-select@5.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-select: 14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-tree: 5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-tree@5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-virtual-list: 3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-upload@4.11.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - rc-util@5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-is: 18.3.1 - - rc-virtual-list@3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.29.2 - classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - react-dom@18.3.1(react@18.3.1): - dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 - - react-is@18.3.1: {} - - react-router-dom@6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@remix-run/router': 1.23.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-router: 6.30.3(react@18.3.1) - - react-router@6.30.3(react@18.3.1): - dependencies: - '@remix-run/router': 1.23.2 - react: 18.3.1 - - react@18.3.1: - dependencies: - loose-envify: 1.4.0 - - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - rechoir@0.8.0: - dependencies: - resolve: 1.22.12 - - require-directory@2.1.1: {} - - require-from-string@2.0.2: {} - - resize-observer-polyfill@1.5.1: {} - - resolve-cwd@3.0.0: - dependencies: - resolve-from: 5.0.0 - - resolve-from@5.0.0: {} - - resolve@1.22.12: - dependencies: - es-errors: 1.3.0 - is-core-module: 2.16.2 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - rimraf@2.7.1: - dependencies: - glob: 7.2.3 - - safe-buffer@5.1.2: {} - - safe-buffer@5.2.1: {} - - safe-regex-test@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-regex: 1.2.1 - - safe-stable-stringify@2.5.0: {} - - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 - - schema-utils@3.3.0: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 6.15.0 - ajv-keywords: 3.5.2(ajv@6.15.0) - - schema-utils@4.3.3: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 8.20.0 - ajv-formats: 2.1.1 - ajv-keywords: 5.1.0(ajv@8.20.0) - - scroll-into-view-if-needed@3.1.0: - dependencies: - compute-scroll-into-view: 3.1.1 - - semver@7.8.0: {} - - set-blocking@2.0.0: {} - - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - setimmediate@1.0.5: {} - - shallow-clone@3.0.1: - dependencies: - kind-of: 6.0.3 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - source-list-map@2.0.1: {} - - source-map-js@1.2.1: {} - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - stack-trace@0.0.10: {} - - stream-browserify@3.0.0: - dependencies: - inherits: 2.0.4 - readable-stream: 3.6.2 - - string-convert@0.2.1: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string_decoder@1.1.1: - dependencies: - safe-buffer: 5.1.2 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - style-loader@3.3.4(webpack@5.107.0): - dependencies: - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - - stylis@4.4.0: {} - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - swc-loader@0.2.7(@swc/core@1.15.33)(webpack@5.107.0): - dependencies: - '@swc/core': 1.15.33 - '@swc/counter': 0.1.3 - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - - tapable@2.3.3: {} - - terser-webpack-plugin@5.6.0(@swc/core@1.15.33)(webpack@5.107.0): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - jest-worker: 27.5.1 - schema-utils: 4.3.3 - terser: 5.47.1 - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - optionalDependencies: - '@swc/core': 1.15.33 - - terser@5.47.1: - dependencies: - '@jridgewell/source-map': 0.3.11 - acorn: 8.16.0 - commander: 2.20.3 - source-map-support: 0.5.21 - - text-hex@1.0.0: {} - - throttle-debounce@5.0.2: {} - - toggle-selection@1.0.6: {} - - triple-beam@1.4.1: {} - - typescript@5.9.3: {} - - undici-types@6.21.0: {} - - update-browserslist-db@1.2.3(browserslist@4.28.2): - dependencies: - browserslist: 4.28.2 - escalade: 3.2.0 - picocolors: 1.1.1 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - util-deprecate@1.0.2: {} - - util@0.12.5: - dependencies: - inherits: 2.0.4 - is-arguments: 1.2.0 - is-generator-function: 1.1.2 - is-typed-array: 1.1.15 - which-typed-array: 1.1.20 - - watchpack@2.5.1: - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - - webpack-cli@5.1.4(webpack@5.107.0): - dependencies: - '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.107.0) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.107.0) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack@5.107.0) - colorette: 2.0.20 - commander: 10.0.1 - cross-spawn: 7.0.6 - envinfo: 7.21.0 - fastest-levenshtein: 1.0.16 - import-local: 3.2.0 - interpret: 3.1.1 - rechoir: 0.8.0 - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-merge: 5.10.0 - - webpack-manifest-plugin@5.0.1(webpack@5.107.0): - dependencies: - tapable: 2.3.3 - webpack: 5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4) - webpack-sources: 2.3.1 - - webpack-merge@5.10.0: - dependencies: - clone-deep: 4.0.1 - flat: 5.0.2 - wildcard: 2.0.1 - - webpack-sources@2.3.1: - dependencies: - source-list-map: 2.0.1 - source-map: 0.6.1 - - webpack-sources@3.4.1: {} - - webpack@5.107.0(@swc/core@1.15.33)(webpack-cli@5.1.4): - dependencies: - '@types/estree': 1.0.9 - '@types/json-schema': 7.0.15 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.16.0 - acorn-import-phases: 1.0.4(acorn@8.16.0) - browserslist: 4.28.2 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.21.6 - es-module-lexer: 2.1.0 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - loader-runner: 4.3.2 - mime-db: 1.54.0 - neo-async: 2.6.2 - schema-utils: 4.3.3 - tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(@swc/core@1.15.33)(webpack@5.107.0) - watchpack: 2.5.1 - webpack-sources: 3.4.1 - optionalDependencies: - webpack-cli: 5.1.4(webpack@5.107.0) - transitivePeerDependencies: - - '@minify-html/node' - - '@swc/core' - - '@swc/css' - - '@swc/html' - - clean-css - - cssnano - - csso - - esbuild - - html-minifier-terser - - lightningcss - - postcss - - uglify-js - - which-typed-array@1.1.20: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wildcard@2.0.1: {} - - winston-transport@4.9.0: - dependencies: - logform: 2.7.0 - readable-stream: 3.6.2 - triple-beam: 1.4.1 - - winston@3.19.0: - dependencies: - '@colors/colors': 1.6.0 - '@dabh/diagnostics': 2.0.8 - async: 3.2.6 - is-stream: 2.0.1 - logform: 2.7.0 - one-time: 1.0.0 - readable-stream: 3.6.2 - safe-stable-stringify: 2.5.0 - stack-trace: 0.0.10 - triple-beam: 1.4.1 - winston-transport: 4.9.0 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrappy@1.0.2: {} - - ws@8.20.1: {} - - y18n@5.0.8: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml deleted file mode 100644 index d881e382e3..0000000000 --- a/pnpm-workspace.yaml +++ /dev/null @@ -1,16 +0,0 @@ -packages: - - '*' - -catalog: - '@clusterio/lib': 2.0.0-alpha.25 - '@clusterio/web_ui': 2.0.0-alpha.25 - '@sinclair/typebox': ^0.30.4 - '@types/node': ^20.19.41 - '@types/react': ^18.3.29 - antd: ^5.29.3 - react: ^18.3.1 - react-dom: ^18.3.1 - typescript: ^5.9.3 - webpack: ^5.107.0 - webpack-cli: ^5.1.4 - webpack-merge: ^5.10.0 From 2248f23a8d6363371f453223cfd1fadab5462d02 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Sat, 23 May 2026 03:51:16 +0100 Subject: [PATCH 09/12] Added web UI --- exp_groups/controller.ts | 38 ++- exp_groups/index.ts | 7 + exp_groups/messages.ts | 3 + exp_groups/module/control.lua | 1 + exp_groups/tsconfig.browser.json | 2 +- exp_groups/web/components/AssignmentForm.tsx | 59 ++++ .../web/components/AssignmentsTable.tsx | 65 ++++ exp_groups/web/components/GroupForm.tsx | 41 +++ exp_groups/web/components/GroupViewPage.tsx | 283 ++++++++++++++++++ exp_groups/web/components/GroupsTable.tsx | 48 +++ exp_groups/web/components/RoleMappingForm.tsx | 82 +++++ .../web/components/RoleMappingsTable.tsx | 74 +++++ exp_groups/web/index.tsx | 108 +++++++ exp_groups/webpack.config.js | 5 + 14 files changed, 804 insertions(+), 12 deletions(-) create mode 100644 exp_groups/web/components/AssignmentForm.tsx create mode 100644 exp_groups/web/components/AssignmentsTable.tsx create mode 100644 exp_groups/web/components/GroupForm.tsx create mode 100644 exp_groups/web/components/GroupViewPage.tsx create mode 100644 exp_groups/web/components/GroupsTable.tsx create mode 100644 exp_groups/web/components/RoleMappingForm.tsx create mode 100644 exp_groups/web/components/RoleMappingsTable.tsx diff --git a/exp_groups/controller.ts b/exp_groups/controller.ts index bdc1860b3c..10bfacd20d 100644 --- a/exp_groups/controller.ts +++ b/exp_groups/controller.ts @@ -228,6 +228,7 @@ export class ControllerPlugin extends BaseControllerPlugin { const group = new messages.GroupRecord(id, request.name, request.permissions); this.groups.set(group); + return group; } async handleGroupUpdateRequest(request: messages.GroupUpdateRequest) { @@ -275,6 +276,7 @@ export class ControllerPlugin extends BaseControllerPlugin { const assignment = new messages.AssignmentRecord(name, groupId); this.manualAssignments.set(assignment); + return assignment; } async handleAssignmentUpdateRequest(request: messages.AssignmentUpdateRequest) { @@ -330,24 +332,38 @@ export class ControllerPlugin extends BaseControllerPlugin { id = Math.random() * 2**31 | 0; } - const mapping = new messages.RoleMappingRecord( - id, - new Set(request.roleIds), - request.groupId, - request.priority, - request.enabled, + let priority = request.priority; + const existing = new Set([...this.roleMappings.values()].map(m => m.priority)); + while (existing.has(priority)) { + priority++; + } + + const roleMapping = new messages.RoleMappingRecord( + id, new Set(request.roleIds), request.groupId, priority, request.enabled, ); - this.roleMappings.set(mapping); + this.roleMappings.set(roleMapping); + return roleMapping; } async handleRoleMappingUpdateRequest(request: messages.RoleMappingUpdateRequest) { - const mapping = request.roleMapping; - if (mapping.id === undefined || !this.roleMappings.has(mapping.id)) { - throw new lib.RequestError(`Role mapping with ID ${mapping.id} does not exist`); + const roleMapping = request.roleMapping; + if (roleMapping.id === undefined || !this.roleMappings.has(roleMapping.id)) { + throw new lib.RequestError(`Role mapping with ID ${roleMapping.id} does not exist`); + } + + const existing = new Set( + [...this.roleMappings.values()] + .filter(m => m.id !== roleMapping.id) + .map(m => m.priority) + ); + + let priority = roleMapping.priority; + while (existing.has(priority)) { + priority++; } - this.roleMappings.set(mapping); + this.roleMappings.set(roleMapping); } async handleRoleMappingDeleteRequest(request: messages.RoleMappingDeleteRequest) { diff --git a/exp_groups/index.ts b/exp_groups/index.ts index 2b4330658d..e16f361b3c 100644 --- a/exp_groups/index.ts +++ b/exp_groups/index.ts @@ -134,6 +134,7 @@ export const plugin: lib.PluginDeclaration = { messages: [ messages.GroupUpdatedEvent, messages.ManualAssignmentUpdatedEvent, + messages.ResolvedAssignmentUpdatedEvent, messages.RoleMappingUpdatedEvent, messages.GroupCreateRequest, @@ -168,4 +169,10 @@ export const plugin: lib.PluginDeclaration = { controllerEntrypoint: "./dist/node/controller", controllerConfigFields: { }, + + webEntrypoint: "./web", + routes: [ + "/exp_groups", + "/exp_groups/:id/view", + ] }; diff --git a/exp_groups/messages.ts b/exp_groups/messages.ts index 691d8ca32b..b0e5e9860b 100644 --- a/exp_groups/messages.ts +++ b/exp_groups/messages.ts @@ -292,6 +292,7 @@ export class GroupCreateRequest { static src = ["control", "instance"] as const; static dst = "controller" as const; static permission = "exp_groups.group.create" as const; + static Response = GroupRecord; constructor( public name: string, @@ -425,6 +426,7 @@ export class AssignmentCreateRequest { static src = ["control", "instance"] as const; static dst = "controller" as const; static permission = "exp_groups.assignment.create" as const; + static Response = AssignmentRecord; constructor( public name: string, @@ -558,6 +560,7 @@ export class RoleMappingCreateRequest { static src = ["control", "instance"] as const; static dst = "controller" as const; static permission = "exp_groups.role_mapping.create" as const; + static Response = RoleMappingRecord; constructor( public roleIds: number[], diff --git a/exp_groups/module/control.lua b/exp_groups/module/control.lua index 2a854bdb51..3a3141e758 100644 --- a/exp_groups/module/control.lua +++ b/exp_groups/module/control.lua @@ -419,6 +419,7 @@ local e = defines.events local events = { [clusterio_api.events.on_server_startup] = on_server_startup, + [e.on_multiplayer_init] = on_server_startup, [e.on_permission_group_added] = on_permission_group_added, [e.on_permission_group_deleted] = on_permission_group_deleted, [e.on_permission_group_edited] = on_permission_group_edited, diff --git a/exp_groups/tsconfig.browser.json b/exp_groups/tsconfig.browser.json index 1ab2704ea8..1e3889e7d5 100644 --- a/exp_groups/tsconfig.browser.json +++ b/exp_groups/tsconfig.browser.json @@ -1,4 +1,4 @@ { "extends": "../tsconfig.browser.json", - "include": [ "web/**/*.tsx", "web/**/*.ts", "package.json" ], + "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], } diff --git a/exp_groups/web/components/AssignmentForm.tsx b/exp_groups/web/components/AssignmentForm.tsx new file mode 100644 index 0000000000..fc280ddb24 --- /dev/null +++ b/exp_groups/web/components/AssignmentForm.tsx @@ -0,0 +1,59 @@ +import React, { useContext } from "react"; +import { Modal, Form, Select } from "antd"; + +import { ControlContext, useUsers } from "@clusterio/web_ui"; +import * as messages from "../../messages"; + +export default function AssignmentForm({ open, setOpen, initial }: any) { + const control = useContext(ControlContext); + const plugin = control.plugins.get("exp_groups") as any; + + const [groups] = plugin.useGroups(); + const [users] = useUsers(); + + const [form] = Form.useForm(); + + function submit(values: any) { + if (initial) { + control.send(new messages.AssignmentUpdateRequest( + new messages.AssignmentRecord(values.name, values.groupId) + )); + } else { + control.send(new messages.AssignmentCreateRequest( + values.name, + values.groupId, + )); + } + + setOpen(false); + } + + return setOpen(false)} + onOk={() => form.submit()} + > +
+ + + + + + + +
+
; +} diff --git a/exp_groups/web/components/AssignmentsTable.tsx b/exp_groups/web/components/AssignmentsTable.tsx new file mode 100644 index 0000000000..559f49724e --- /dev/null +++ b/exp_groups/web/components/AssignmentsTable.tsx @@ -0,0 +1,65 @@ +import React, { useContext, useState } from "react"; +import { Table, Button, Popconfirm, Space } from "antd"; +import { EditOutlined, DeleteOutlined } from "@ant-design/icons"; + +import { ControlContext, useAccount } from "@clusterio/web_ui"; +import * as messages from "../../messages"; + +import AssignmentForm from "./AssignmentForm"; + +const strcmp = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }).compare; + +export default function AssignmentsTable() { + const control = useContext(ControlContext); + const plugin = control.plugins.get("exp_groups") as any; + const account = useAccount(); + + const [assignments, synced] = plugin.useAssignments(); + const [groups] = plugin.useGroups(); + + const [editing, setEditing] = useState(null); + const [open, setOpen] = useState(false); + + return <> + strcmp(a.name, b.name), + }, + { + title: "Group", + render: (_: any, a: any) => groups.get(a.groupId)?.name ?? a.groupId, + }, + { + title: "Actions", + render: (_: any, record: any) => ( + + {account.hasPermission("exp_groups.assignment.update") && + + + + + )} + +
+ + setName(e.target.value)} /> +
+ +

Permissions

+ + {!defaultModPack?.exportManifest?.assets?.defines && ( + + )} + + {defaultModPack?.exportManifest?.assets?.defines && !definesJson && } + + {definesJson && <> + setSearch(e.target.value)} + style={{ marginBottom: 16 }} + /> + + + {grouped.map(([groupName, permissions]) => ( +
+ + + {groupName} + + + + + + + +
+ {permissions.map(p => ( + + setPermissionState(prev => ({ ...prev, [p]: e.target.checked })) + } + > + {p} + + ))} +
+
+ ))} +
+ } + ; +} diff --git a/exp_groups/web/components/GroupsTable.tsx b/exp_groups/web/components/GroupsTable.tsx new file mode 100644 index 0000000000..08aba64c2e --- /dev/null +++ b/exp_groups/web/components/GroupsTable.tsx @@ -0,0 +1,48 @@ +import React, { useContext, useState } from "react"; +import { Table } from "antd"; +import { useNavigate } from "react-router-dom"; + +import { ControlContext, useAccount } from "@clusterio/web_ui"; + +import GroupForm from "./GroupForm"; + +const strcmp = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }).compare; + +export default function GroupsTable() { + const control = useContext(ControlContext); + const plugin = control.plugins.get("exp_groups") as any; + const navigate = useNavigate(); + + const [groups, synced] = plugin.useGroups(); + + const [open, setOpen] = useState(false); + + return <> +
strcmp(a.name, b.name), + }, + { + title: "Type", + render: (_: any, g: any) => g.permissions.isBlacklist ? "Blacklist" : "Whitelist", + }, + { + title: "Permissions", + render: (_: any, g: any) => g.permissions.permissions.length, + }, + ]} + dataSource={[...groups.values()]} + loading={!synced} + pagination={false} + rowKey={(g) => g.id} + onRow={(g) => ({ + onClick: () => navigate(`/exp_groups/${g.id}/view`), + })} + /> + + + ; +} \ No newline at end of file diff --git a/exp_groups/web/components/RoleMappingForm.tsx b/exp_groups/web/components/RoleMappingForm.tsx new file mode 100644 index 0000000000..d6801f7d8c --- /dev/null +++ b/exp_groups/web/components/RoleMappingForm.tsx @@ -0,0 +1,82 @@ +import React, { useContext } from "react"; +import { Modal, Form, Select, InputNumber, Switch } from "antd"; + +import { ControlContext, useRoles } from "@clusterio/web_ui"; +import * as messages from "../../messages"; + +export default function RoleMappingForm({ open, setOpen, initial }: any) { + const control = useContext(ControlContext); + const plugin = control.plugins.get("exp_groups") as any; + + const [groups] = plugin.useGroups(); + const [roles] = useRoles(); + + const [form] = Form.useForm(); + + function submit(values: any) { + const record = new messages.RoleMappingRecord( + initial?.id, + new Set(values.roleIds), + values.groupId, + values.priority, + values.enabled, + ); + + if (initial) { + control.send(new messages.RoleMappingUpdateRequest(record)); + } else { + control.send(new messages.RoleMappingCreateRequest( + values.roleIds, + values.groupId, + values.priority, + values.enabled, + )); + } + + setOpen(false); + } + + return setOpen(false)} + onOk={() => form.submit()} + > +
+ + + + + + + + + + + + + + + + +
; +} diff --git a/exp_groups/web/components/RoleMappingsTable.tsx b/exp_groups/web/components/RoleMappingsTable.tsx new file mode 100644 index 0000000000..587c6cfa5c --- /dev/null +++ b/exp_groups/web/components/RoleMappingsTable.tsx @@ -0,0 +1,74 @@ +import React, { useContext, useState } from "react"; +import { Table, Button, Popconfirm, Space, Tag } from "antd"; +import { EditOutlined, DeleteOutlined } from "@ant-design/icons"; + +import { ControlContext, useAccount, useRoles } from "@clusterio/web_ui"; +import * as messages from "../../messages"; + +import RoleMappingForm from "./RoleMappingForm"; + +export default function RoleMappingsTable() { + const control = useContext(ControlContext); + const plugin = control.plugins.get("exp_groups") as any; + const account = useAccount(); + + const [roleMappings, synced] = plugin.useRoleMappings(); + const [groups] = plugin.useGroups(); + const [roles] = useRoles(); + + const [editing, setEditing] = useState(null); + const [open, setOpen] = useState(false); + + return <> +
[...m.roleIds].map((id: number) => { + const role = roles.get(id); + return {role?.name ?? id}; + }), + }, + { + title: "Group", + render: (_: any, m: any) => groups.get(m.groupId)?.name ?? m.groupId, + }, + { + title: "Enabled", + render: (_: any, m: any) => m.enabled ? "Yes" : "No", + }, + { + title: "Actions", + render: (_: any, record: any) => ( + + {account.hasPermission("exp_groups.role_mapping.update") && + + : undefined + } + /> + + + } + + {account.hasPermission("exp_groups.role_mapping.list") && <> + setRoleMappingOpen(true)}>Create + : undefined + } + /> + + + } + + {account.hasPermission("exp_groups.assignment.list") && <> + setAssignmentOpen(true)}>Create + : undefined + } + /> + + + } + ; +} + +export class WebPlugin extends BaseWebPlugin { + groups = new lib.EventSubscriber(messages.GroupUpdatedEvent, this.control); + assignments = new lib.EventSubscriber(messages.ManualAssignmentUpdatedEvent, this.control); + roleMappings = new lib.EventSubscriber(messages.RoleMappingUpdatedEvent, this.control); + + async init() { + this.pages = [ + { + path: "/exp_groups", + sidebarName: "Permission Groups", + permission: (account => account.hasAnyPermission( + "exp_groups.group.list", + "exp_groups.assignment.list", + "exp_groups.role_mapping.list", + )), + content: , + }, + { + path: "/exp_groups/:id/view", + sidebarPath: "/exp_groups", + permission: "exp_groups.group.get", + content: , + }, + ]; + } + + useGroups() { + const subscribe = useCallback((cb: () => void) => this.groups.subscribe(cb), []); + return useSyncExternalStore(subscribe, () => this.groups.getSnapshot()); + } + + useAssignments() { + const subscribe = useCallback((cb: () => void) => this.assignments.subscribe(cb), []); + return useSyncExternalStore(subscribe, () => this.assignments.getSnapshot()); + } + + useRoleMappings() { + const subscribe = useCallback((cb: () => void) => this.roleMappings.subscribe(cb), []); + return useSyncExternalStore(subscribe, () => this.roleMappings.getSnapshot()); + } +} diff --git a/exp_groups/webpack.config.js b/exp_groups/webpack.config.js index 0baa40ac1c..b1f0116516 100644 --- a/exp_groups/webpack.config.js +++ b/exp_groups/webpack.config.js @@ -23,6 +23,11 @@ module.exports = (env = {}) => merge(common(env), { shared: { "@clusterio/lib": { import: false }, "@clusterio/web_ui": { import: false }, + "antd": { import: false }, + "react": { import: false }, + "react-dom": { import: false }, + "react-router": { import: false }, + "react-router-dom": { import: false }, }, }), ], From bb788f33da8f6d510ebd9092caddff92aed9ba2a Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Mon, 25 May 2026 20:43:51 +0100 Subject: [PATCH 10/12] Final Cleanup --- exp_groups/controller.ts | 2 +- exp_groups/index.ts | 9 +- exp_groups/instance.ts | 33 +++++-- exp_groups/module/control.lua | 26 ++--- exp_groups/module/module.json | 1 + exp_groups/web/components/AssignmentForm.tsx | 25 ++++- .../web/components/AssignmentsTable.tsx | 94 +++++++++++++----- exp_groups/web/components/DeleteConfirm.tsx | 16 ++++ exp_groups/web/components/GroupForm.tsx | 42 ++++---- exp_groups/web/components/GroupViewPage.tsx | 60 ++++++------ exp_groups/web/components/GroupsTable.tsx | 21 ++-- exp_groups/web/components/RoleMappingForm.tsx | 90 +++++++++++------- .../web/components/RoleMappingsTable.tsx | 95 +++++++++++++------ exp_groups/web/index.tsx | 8 +- 14 files changed, 344 insertions(+), 178 deletions(-) create mode 100644 exp_groups/web/components/DeleteConfirm.tsx diff --git a/exp_groups/controller.ts b/exp_groups/controller.ts index 10bfacd20d..6f94b2c036 100644 --- a/exp_groups/controller.ts +++ b/exp_groups/controller.ts @@ -397,7 +397,7 @@ export class ControllerPlugin extends BaseControllerPlugin { return manual; } - const user = this.controller.users.get(playerName); + const user = this.controller.users.getByName(playerName); const userRoles = user?.roleIds ?? new Set(); // 2) Role mappings diff --git a/exp_groups/index.ts b/exp_groups/index.ts index e16f361b3c..524ac7d914 100644 --- a/exp_groups/index.ts +++ b/exp_groups/index.ts @@ -131,6 +131,11 @@ export const plugin: lib.PluginDeclaration = { title: "ExpGaming - Permission Groups", description: "Clusterio plugin providing syncing of permission groups", + features: [ + "SavePatching", + "ScriptCommands", + ], + messages: [ messages.GroupUpdatedEvent, messages.ManualAssignmentUpdatedEvent, @@ -172,7 +177,7 @@ export const plugin: lib.PluginDeclaration = { webEntrypoint: "./web", routes: [ - "/exp_groups", - "/exp_groups/:id/view", + "/permission_groups", + "/permission_groups/:id/view", ] }; diff --git a/exp_groups/instance.ts b/exp_groups/instance.ts index 1bfc66ba9e..516c34bf0c 100644 --- a/exp_groups/instance.ts +++ b/exp_groups/instance.ts @@ -5,7 +5,7 @@ import * as messages from "./messages"; export type IpcGroupUpdated = { group_name: string, group_id: number | undefined, - permissions: { is_blacklist: boolean, permissions: string[] }, + permissions: { is_blacklist: boolean, permissions: string[] | undefined }, }; export type IpcGroupDeleted = { @@ -21,6 +21,8 @@ export class InstancePlugin extends BaseInstancePlugin { // Once only, don't send permissions for these groups // This is used for groups created on this instance that only need the controller generated id skipSendingPermissions = new Set(); + // This is used for groups updated / deleted on this instance to stop cycles + skipSendingUpdate = new Set(); // Track known online players so that we only apply assignment updates for them onlinePlayers = new Set(); @@ -80,8 +82,8 @@ export class InstancePlugin extends BaseInstancePlugin { async handleGroupUpdatedIPC(event: IpcGroupUpdated) { const permissions = new messages.GroupPermissions( event.permissions.is_blacklist, - event.permissions.permissions, - ); + event.permissions.permissions ?? [], + ) if (event.group_id === undefined) { this.skipSendingPermissions.add(event.group_name); @@ -89,6 +91,7 @@ export class InstancePlugin extends BaseInstancePlugin { new messages.GroupCreateRequest(event.group_name, permissions), ); } else { + this.skipSendingUpdate.add(event.group_id); await this.instance.sendTo("controller", new messages.GroupUpdateRequest( new messages.GroupRecord(event.group_id, event.group_name, permissions), )); @@ -99,6 +102,7 @@ export class InstancePlugin extends BaseInstancePlugin { if (event.group_id === undefined) { return; } + this.skipSendingUpdate.add(event.group_id); await this.instance.sendTo("controller", new messages.GroupDeleteRequest(event.group_id)); } @@ -125,14 +129,19 @@ export class InstancePlugin extends BaseInstancePlugin { } async luaSendInitialGroups(groups: messages.GroupRecord[]) { - if (this.instance.config.get("exp_groups.sync_mode") == "disabled") { + if (this.instance.config.get("exp_groups.sync_mode") === "disabled") { return; } - await this.instance.sendRcon(`/sc exp_groups.initialise_groups(helpers.json_to_table${JSON.stringify(groups)})`) + await this.luaSend("initialise_groups", groups); } async luaSendGroupUpdate(group: messages.GroupRecord) { - if (this.instance.config.get("exp_groups.sync_mode") == "disabled") { + if (this.instance.config.get("exp_groups.sync_mode") === "disabled") { + return; + } + + if (this.skipSendingUpdate.has(group.id)) { + this.skipSendingUpdate.delete(group.id); return; } @@ -142,17 +151,21 @@ export class InstancePlugin extends BaseInstancePlugin { delete (json as any).permissions; } - await this.instance.sendRcon(`/sc exp_groups.receive_group_update(helpers.json_to_table${JSON.stringify(json)})`) + await this.luaSend("receive_group_update", json); } async luaSendAssignmentUpdate(assignment: messages.AssignmentRecord) { - if (this.instance.config.get("exp_groups.sync_mode") == "disabled") { + if (this.instance.config.get("exp_groups.sync_mode") === "disabled") { return; } - await this.instance.sendRcon(`/sc exp_groups.initialise_groups(helpers.receive_assignment_update${JSON.stringify(assignment)})`) + await this.luaSend("receive_assignment_update", assignment); } async luaSetEmitEvents(emitEvents: boolean) { - await this.instance.sendRcon(`/sc exp_groups.set_emit_events(${emitEvents})`) + await this.luaSend("set_emit_events", emitEvents); + } + + async luaSend(receiver: string, json: any) { + await this.instance.sendRcon(`/c exp_groups.${receiver}(helpers.json_to_table[=[${JSON.stringify(json)}]=])`, true) } } diff --git a/exp_groups/module/control.lua b/exp_groups/module/control.lua index 3a3141e758..0c61af71db 100644 --- a/exp_groups/module/control.lua +++ b/exp_groups/module/control.lua @@ -11,7 +11,7 @@ local ExpGroups = {} --- @class ExpPermissionGroups.GroupPermissions --- @field is_blacklist boolean ---- @field permissions string[] +--- @field permissions string[]? --- @class ExpPermissionGroups.GroupRecord --- @field id number @@ -21,8 +21,8 @@ local ExpGroups = {} --- @class ExpPermissionGroups.AssignmentRecord --- @field name string ---- @field groupId number ---- @field isDeleted boolean +--- @field group_id number +--- @field is_deleted boolean --- @class ExpPermissionGroups.ScriptData --- @field factorio_to_clusterio_id table @@ -73,7 +73,7 @@ end local function decode_group_permissions(group, permissions) -- Construct a hash map for faster lookup local action_map = {} - for _, input_action_name in pairs(permissions.permissions) do + for _, input_action_name in pairs(assert(permissions.permissions)) do action_map[input_action_name] = true end @@ -112,11 +112,15 @@ local function encode_group_permissions(group) -- Return the whitelist if it is smaller if blacklist_index > whitelist_index then - return { is_blacklist = false, permissions = whitelist } + return whitelist_index > 0 + and { is_blacklist = false, permissions = whitelist } + or { is_blacklist = false } end -- Otherwise return the blacklist as it is smaller - return { is_blacklist = true, permissions = blacklist } + return blacklist_index > 0 + and { is_blacklist = true, permissions = blacklist } + or { is_blacklist = true } end --[[ @@ -167,9 +171,9 @@ end --- Update an assignment by moving the player to their new group --- @param assignment_record ExpPermissionGroups.AssignmentRecord local function update_assignment(assignment_record) - assert(not assignment_record.isDeleted) + assert(not assignment_record.is_deleted) - local group = script_data.clusterio_id_to_group[assignment_record.groupId] + local group = script_data.clusterio_id_to_group[assignment_record.group_id] local player = assert(game.get_player(assignment_record.name)) if group then group.add_player(player) @@ -179,7 +183,7 @@ end --- Clear an assignment by moving the player to the default group --- @param assignment_record ExpPermissionGroups.AssignmentRecord local function delete_assignment(assignment_record) - assert(assignment_record.isDeleted) + assert(assignment_record.is_deleted) local default_group = get_default_group() local player = assert(game.get_player(assignment_record.name)) @@ -258,7 +262,7 @@ function ExpGroups.receive_assignment_update(assignment_record) local _emit_events = script_data.emit_updates script_data.emit_updates = false - if assignment_record.isDeleted then + if assignment_record.is_deleted then delete_assignment(assignment_record) else update_assignment(assignment_record) @@ -378,7 +382,7 @@ local function on_permission_group_added(event) return end - emit_group_update(event.group) + mark_group_dirty(event.group) end --- Handle deletion of permission groups diff --git a/exp_groups/module/module.json b/exp_groups/module/module.json index 0d7ebefd0a..6d8893a706 100644 --- a/exp_groups/module/module.json +++ b/exp_groups/module/module.json @@ -4,6 +4,7 @@ "control.lua" ], "require": [ + "globals.lua" ], "dependencies": { "clusterio": "*" diff --git a/exp_groups/web/components/AssignmentForm.tsx b/exp_groups/web/components/AssignmentForm.tsx index fc280ddb24..41a6a8f297 100644 --- a/exp_groups/web/components/AssignmentForm.tsx +++ b/exp_groups/web/components/AssignmentForm.tsx @@ -1,12 +1,17 @@ -import React, { useContext } from "react"; +import React, { useContext, useEffect } from "react"; import { Modal, Form, Select } from "antd"; import { ControlContext, useUsers } from "@clusterio/web_ui"; import * as messages from "../../messages"; +import type { WebPlugin } from ".."; -export default function AssignmentForm({ open, setOpen, initial }: any) { +export default function AssignmentForm({ open, setOpen, initial }: { + open: boolean, + setOpen: (open: boolean) => void, + initial?: messages.AssignmentRecord, +}) { const control = useContext(ControlContext); - const plugin = control.plugins.get("exp_groups") as any; + const plugin = control.plugins.get("exp_groups") as WebPlugin; const [groups] = plugin.useGroups(); const [users] = useUsers(); @@ -16,7 +21,10 @@ export default function AssignmentForm({ open, setOpen, initial }: any) { function submit(values: any) { if (initial) { control.send(new messages.AssignmentUpdateRequest( - new messages.AssignmentRecord(values.name, values.groupId) + new messages.AssignmentRecord( + values.name, + values.groupId, + ) )); } else { control.send(new messages.AssignmentCreateRequest( @@ -28,13 +36,20 @@ export default function AssignmentForm({ open, setOpen, initial }: any) { setOpen(false); } + useEffect(() => { + if (open) { + form.resetFields(); + form.setFieldsValue(initial); + } + }, [open, initial]); + return setOpen(false)} onOk={() => form.submit()} > -
+
strcmp(a.name, b.name), + sorter: (a: AssignmentRecord, b: AssignmentRecord) => strcmp(a.name, b.name), + filterIcon: (filtered: boolean) => ( + + ), + onFilter: (value, record: AssignmentRecord) => ( + record.name.toLowerCase().includes(String(value).toLowerCase()) + ), + filterDropdownProps: { + onOpenChange: (open: boolean) => open && setTimeout(() => searchInput.current?.select(), 100), + }, + filterDropdown: ({ selectedKeys, setSelectedKeys, confirm, clearFilters }) => ( +
e.stopPropagation()}> + setSelectedKeys([e.target.value])} + onSearch={() => confirm({ closeDropdown: false })} + onClear={() => { + clearFilters?.({ closeDropdown: false }); + confirm({ closeDropdown: true }); + }} + /> +
+ ), }, { title: "Group", - render: (_: any, a: any) => groups.get(a.groupId)?.name ?? a.groupId, + width: "40%", + filters: groupFilters, + onFilter: (value, record: AssignmentRecord) => ( + record.groupId === value + ), + render: (_: any, a: any) => ( + groups.get(a.groupId)?.name ?? a.groupId + ), }, - { + ...(account.hasAnyPermission( + "exp_groups.assignment.update", + "exp_groups.assignment.delete", + ) ? [{ title: "Actions", - render: (_: any, record: any) => ( + width: "10%", + render: (_: any, record: AssignmentRecord) => ( {account.hasPermission("exp_groups.assignment.update") &&
[...m.roleIds].map((id: number) => { - const role = roles.get(id); - return {role?.name ?? id}; - }), + filters: roleFilters, + onFilter: (value, record: RoleMappingRecord) => ( + record.roleIds.has(value as number) + ), + render: (_: any, record: RoleMappingRecord) => ( + [...record.roleIds].map(id => {roles.get(id)?.name ?? id}) + ), }, { title: "Group", - render: (_: any, m: any) => groups.get(m.groupId)?.name ?? m.groupId, + width: "30%", + filters: groupFilters, + onFilter: (value, record: RoleMappingRecord) => ( + record.groupId === value + ), + render: (_: any, record: RoleMappingRecord) => ( + groups.get(record.groupId)?.name ?? record.groupId + ), }, { title: "Enabled", - render: (_: any, m: any) => m.enabled ? "Yes" : "No", + width: "10%", + filters: [ + { text: "Enabled", value: true }, + { text: "Disabled", value: false }, + ], + onFilter: (value, record: RoleMappingRecord) => ( + record.enabled === value + ), + render: (_: any, record: RoleMappingRecord) => ( + record.enabled ? "Yes" : "No" + ), }, - { + ...(account.hasAnyPermission( + "exp_groups.role_mapping.update", + "exp_groups.role_mapping.delete", + ) ? [{ title: "Actions", + width: "10%", render: (_: any, record: any) => ( - {account.hasPermission("exp_groups.role_mapping.update") && -