This commit is contained in:
linfeng 2025-03-05 21:37:38 +08:00
commit ead0026d01
146 changed files with 423 additions and 2958 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@ backup
# dependencies # dependencies
**/node_modules/ **/node_modules/
volumes volumes
web-dist
/.pnp /.pnp
.pnp.js .pnp.js
*.tar *.tar

View File

@ -1,51 +1,23 @@
# 基础镜像 # 基础镜像
FROM node:18.17-alpine as base FROM node:18.17-alpine as base
# 更改 apk 镜像源为阿里云
# RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 使用阿里云镜像源 + 完整仓库声明
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
echo "https://mirrors.aliyun.com/alpine/v3.18/community" >> /etc/apk/repositories echo "https://mirrors.aliyun.com/alpine/v3.18/community" >> /etc/apk/repositories
# 安装最新稳定版 PostgreSQL 客户端15.11
RUN apk update --no-cache && \
apk add --no-cache \
postgresql15-client \
libpq \
readline
RUN apk add --no-cache ffmpeg
# 设置 npm 镜像源
RUN yarn config set registry https://registry.npmmirror.com RUN yarn config set registry https://registry.npmmirror.com
# 全局安装 pnpm 并设置其镜像源
RUN yarn global add pnpm && pnpm config set registry https://registry.npmmirror.com RUN yarn global add pnpm && pnpm config set registry https://registry.npmmirror.com
# 设置工作目录
WORKDIR /app WORKDIR /app
# 复制 pnpm workspace 配置文件
COPY pnpm-workspace.yaml ./ COPY pnpm-workspace.yaml ./
# 首先复制 package.json, package-lock.json 和 pnpm-lock.yaml 文件
COPY package*.json pnpm-lock.yaml* ./ COPY package*.json pnpm-lock.yaml* ./
COPY tsconfig.base.json . COPY tsconfig.base.json .
# 利用 Docker 缓存机制,如果依赖没有改变则不会重新执行 pnpm install
#100-500 5-40
FROM base As server-build FROM base As server-build
WORKDIR /app WORKDIR /app
COPY packages/common /app/packages/common COPY . .
COPY packages/tus /app/packages/tus RUN pnpm install
COPY apps/server /app/apps/server RUN pnpm --filter common build
RUN pnpm config set registry https://registry.npmmirror.com/
RUN pnpm install --filter common
RUN pnpm install --filter tus
RUN pnpm install --filter server
RUN pnpm --filter common generate && pnpm --filter common build:cjs
RUN pnpm --filter tus build RUN pnpm --filter tus build
RUN pnpm --filter utils build
RUN pnpm --filter server build RUN pnpm --filter server build
FROM base As server-prod-dep FROM base As server-prod-dep
@ -55,6 +27,7 @@ COPY packages/tus /app/packages/tus
COPY apps/server /app/apps/server COPY apps/server /app/apps/server
RUN pnpm install --filter common --prod RUN pnpm install --filter common --prod
RUN pnpm install --filter tus --prod RUN pnpm install --filter tus --prod
RUN pnpm install --filter utils --prod
RUN pnpm install --filter server --prod RUN pnpm install --filter server --prod
@ -66,10 +39,8 @@ COPY --from=server-build /app/packages/common/dist ./packages/common/dist
COPY --from=server-build /app/packages/tus/dist ./packages/tus/dist COPY --from=server-build /app/packages/tus/dist ./packages/tus/dist
COPY --from=server-build /app/apps/server/dist ./apps/server/dist COPY --from=server-build /app/apps/server/dist ./apps/server/dist
COPY apps/server/entrypoint.sh ./apps/server/entrypoint.sh COPY apps/server/entrypoint.sh ./apps/server/entrypoint.sh
RUN chmod +x ./apps/server/entrypoint.sh RUN chmod +x ./apps/server/entrypoint.sh
RUN apk add --no-cache postgresql-client RUN apk add --no-cache ffmpeg
EXPOSE 3000 EXPOSE 3000
@ -108,21 +79,15 @@ CMD ["/usr/bin/entrypoint.sh"]
# 使用 Nginx 的 Alpine 版本作为基础镜像 # 使用 Nginx 的 Alpine 版本作为基础镜像
FROM nginx:stable-alpine as nginx FROM nginx:stable-alpine as nginx
# 替换 Alpine 的软件源为阿里云镜像 # 替换 Alpine 的软件源为阿里云镜像
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 设置工作目录 # 设置工作目录
WORKDIR /usr/share/nginx/html WORKDIR /usr/share/nginx/html
# 设置环境变量 # 设置环境变量
ENV NODE_ENV production ENV NODE_ENV production
# 安装 envsubst 和 inotify-tools # 安装 envsubst 和 inotify-tools
RUN apk add --no-cache gettext inotify-tools RUN apk add --no-cache gettext inotify-tools
# 创建 /data/uploads 目录 # 创建 /data/uploads 目录
RUN mkdir -p /data/uploads RUN mkdir -p /data/uploads
# 暴露 80 端口 # 暴露 80 端口
EXPOSE 80 EXPOSE 80

View File

@ -1,20 +1,28 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { TrpcService } from '@server/trpc/trpc.service'; import { TrpcService } from '@server/trpc/trpc.service';
import { DepartmentService } from './department.service'; // assuming it's in the same directory import { DepartmentService } from './department.service'; // assuming it's in the same directory
import { DepartmentMethodSchema, Prisma, UpdateOrderSchema } from '@nice/common'; import {
DepartmentMethodSchema,
Prisma,
UpdateOrderSchema,
} from '@nice/common';
import { z, ZodType } from 'zod'; import { z, ZodType } from 'zod';
import { DepartmentRowService } from './department.row.service'; import { DepartmentRowService } from './department.row.service';
const DepartmentCreateArgsSchema: ZodType<Prisma.DepartmentCreateArgs> = z.any() const DepartmentCreateArgsSchema: ZodType<Prisma.DepartmentCreateArgs> =
const DepartmentUpdateArgsSchema: ZodType<Prisma.DepartmentUpdateArgs> = z.any() z.any();
const DepartmentFindFirstArgsSchema: ZodType<Prisma.DepartmentFindFirstArgs> = z.any() const DepartmentUpdateArgsSchema: ZodType<Prisma.DepartmentUpdateArgs> =
const DepartmentFindManyArgsSchema: ZodType<Prisma.DepartmentFindManyArgs> = z.any() z.any();
const DepartmentFindFirstArgsSchema: ZodType<Prisma.DepartmentFindFirstArgs> =
z.any();
const DepartmentFindManyArgsSchema: ZodType<Prisma.DepartmentFindManyArgs> =
z.any();
@Injectable() @Injectable()
export class DepartmentRouter { export class DepartmentRouter {
constructor( constructor(
private readonly trpc: TrpcService, private readonly trpc: TrpcService,
private readonly departmentService: DepartmentService, // 注入 DepartmentService private readonly departmentService: DepartmentService, // 注入 DepartmentService
private readonly departmentRowService: DepartmentRowService private readonly departmentRowService: DepartmentRowService,
) {} ) {}
router = this.trpc.router({ router = this.trpc.router({
// 创建部门 // 创建部门
@ -36,8 +44,10 @@ export class DepartmentRouter {
return this.departmentService.softDeleteByIds(input.ids); return this.departmentService.softDeleteByIds(input.ids);
}), }),
// 更新部门顺序 // 更新部门顺序
updateOrder: this.trpc.protectProcedure.input(UpdateOrderSchema).mutation(async ({ input }) => { updateOrder: this.trpc.protectProcedure
return this.departmentService.updateOrder(input) .input(UpdateOrderSchema)
.mutation(async ({ input }) => {
return this.departmentService.updateOrder(input);
}), }),
// 查询多个部门 // 查询多个部门
findMany: this.trpc.procedure findMany: this.trpc.procedure
@ -53,13 +63,15 @@ export class DepartmentRouter {
}), }),
// 获取子部门的简单树结构 // 获取子部门的简单树结构
getChildSimpleTree: this.trpc.procedure getChildSimpleTree: this.trpc.procedure
.input(DepartmentMethodSchema.getSimpleTree).query(async ({ input }) => { .input(DepartmentMethodSchema.getSimpleTree)
return await this.departmentService.getChildSimpleTree(input) .query(async ({ input }) => {
return await this.departmentService.getChildSimpleTree(input);
}), }),
// 获取父部门的简单树结构 // 获取父部门的简单树结构
getParentSimpleTree: this.trpc.procedure getParentSimpleTree: this.trpc.procedure
.input(DepartmentMethodSchema.getSimpleTree).query(async ({ input }) => { .input(DepartmentMethodSchema.getSimpleTree)
return await this.departmentService.getParentSimpleTree(input) .query(async ({ input }) => {
return await this.departmentService.getParentSimpleTree(input);
}), }),
// 获取部门行数据 // 获取部门行数据
getRows: this.trpc.protectProcedure getRows: this.trpc.protectProcedure

View File

@ -61,6 +61,18 @@ export class StaffRouter {
.query(async ({ input }) => { .query(async ({ input }) => {
return await this.staffService.findMany(input); return await this.staffService.findMany(input);
}), }),
findManyWithPagination: this.trpc.procedure
.input(
z.object({
page: z.number().optional(),
pageSize: z.number().optional(),
where: StaffWhereInputSchema.optional(),
select: StaffSelectSchema.optional(),
}),
) // Assuming StaffMethodSchema.findMany is the Zod schema for finding staffs by keyword
.query(async ({ input }) => {
return await this.staffService.findManyWithPagination(input);
}),
getRows: this.trpc.protectProcedure getRows: this.trpc.protectProcedure
.input(StaffMethodSchema.getRows) .input(StaffMethodSchema.getRows)
.query(async ({ input, ctx }) => { .query(async ({ input, ctx }) => {

View File

@ -15,13 +15,13 @@ import { z } from 'zod';
import { isFieldCondition } from '../base/sql-builder'; import { isFieldCondition } from '../base/sql-builder';
@Injectable() @Injectable()
export class StaffRowService extends RowCacheService { export class StaffRowService extends RowCacheService {
constructor( constructor(private readonly departmentService: DepartmentService) {
private readonly departmentService: DepartmentService,
) {
super(ObjectType.STAFF, false); super(ObjectType.STAFF, false);
} }
createUnGroupingRowSelect(request?: RowModelRequest): string[] { createUnGroupingRowSelect(request?: RowModelRequest): string[] {
const result = super.createUnGroupingRowSelect(request).concat([ const result = super
.createUnGroupingRowSelect(request)
.concat([
`${this.tableName}.id AS id`, `${this.tableName}.id AS id`,
`${this.tableName}.username AS username`, `${this.tableName}.username AS username`,
`${this.tableName}.showname AS showname`, `${this.tableName}.showname AS showname`,
@ -33,7 +33,7 @@ export class StaffRowService extends RowCacheService {
'dept.name AS dept_name', 'dept.name AS dept_name',
'domain.name AS domain_name', 'domain.name AS domain_name',
]); ]);
return result return result;
} }
createJoinSql(request?: RowModelRequest): string[] { createJoinSql(request?: RowModelRequest): string[] {
return [ return [
@ -94,17 +94,13 @@ export class StaffRowService extends RowCacheService {
const deptId = data?.deptId; const deptId = data?.deptId;
const isFromSameDept = staff.deptIds?.includes(deptId); const isFromSameDept = staff.deptIds?.includes(deptId);
const domainChildDeptIds = await this.departmentService.getDescendantIds( const domainChildDeptIds = await this.departmentService.getDescendantIds(
staff.domainId, true staff.domainId,
); true,
const belongsToDomain = domainChildDeptIds.includes(
deptId,
); );
const belongsToDomain = domainChildDeptIds.includes(deptId);
return { isFromSameDept, belongsToDomain }; return { isFromSameDept, belongsToDomain };
} }
protected async setResPermissions( protected async setResPermissions(data: Staff, staff: UserProfile) {
data: Staff,
staff: UserProfile,
) {
const permissions: ResPerm = {}; const permissions: ResPerm = {};
const { isFromSameDept, belongsToDomain } = await this.getPermissionContext( const { isFromSameDept, belongsToDomain } = await this.getPermissionContext(
data.id, data.id,
@ -131,5 +127,4 @@ export class StaffRowService extends RowCacheService {
}); });
return { ...data, perm: permissions }; return { ...data, perm: permissions };
} }
} }

View File

@ -14,7 +14,6 @@ import EventBus, { CrudOperation } from '@server/utils/event-bus';
@Injectable() @Injectable()
export class StaffService extends BaseService<Prisma.StaffDelegate> { export class StaffService extends BaseService<Prisma.StaffDelegate> {
constructor(private readonly departmentService: DepartmentService) { constructor(private readonly departmentService: DepartmentService) {
super(db, ObjectType.STAFF, true); super(db, ObjectType.STAFF, true);
} }
@ -25,7 +24,10 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
*/ */
async findByDept(data: z.infer<typeof StaffMethodSchema.findByDept>) { async findByDept(data: z.infer<typeof StaffMethodSchema.findByDept>) {
const { deptId, domainId } = data; const { deptId, domainId } = data;
const childDepts = await this.departmentService.getDescendantIds(deptId, true); const childDepts = await this.departmentService.getDescendantIds(
deptId,
true,
);
const result = await db.staff.findMany({ const result = await db.staff.findMany({
where: { where: {
deptId: { in: childDepts }, deptId: { in: childDepts },
@ -50,7 +52,9 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
await this.validateUniqueFields(data, where.id); await this.validateUniqueFields(data, where.id);
const updateData = { const updateData = {
...data, ...data,
...(data.password && { password: await argon2.hash(data.password as string) }) ...(data.password && {
password: await argon2.hash(data.password as string),
}),
}; };
const result = await super.update({ ...args, data: updateData }); const result = await super.update({ ...args, data: updateData });
this.emitDataChangedEvent(result, CrudOperation.UPDATED); this.emitDataChangedEvent(result, CrudOperation.UPDATED);
@ -58,17 +62,26 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
} }
private async validateUniqueFields(data: any, excludeId?: string) { private async validateUniqueFields(data: any, excludeId?: string) {
const uniqueFields = [ const uniqueFields = [
{ field: 'officerId', errorMsg: (val: string) => `证件号为${val}的用户已存在` }, {
{ field: 'phoneNumber', errorMsg: (val: string) => `手机号为${val}的用户已存在` }, field: 'officerId',
{ field: 'username', errorMsg: (val: string) => `帐号为${val}的用户已存在` } errorMsg: (val: string) => `证件号为${val}的用户已存在`,
},
{
field: 'phoneNumber',
errorMsg: (val: string) => `手机号为${val}的用户已存在`,
},
{
field: 'username',
errorMsg: (val: string) => `帐号为${val}的用户已存在`,
},
]; ];
for (const { field, errorMsg } of uniqueFields) { for (const { field, errorMsg } of uniqueFields) {
if (data[field]) { if (data[field]) {
const count = await db.staff.count({ const count = await db.staff.count({
where: { where: {
[field]: data[field], [field]: data[field],
...(excludeId && { id: { not: excludeId } }) ...(excludeId && { id: { not: excludeId } }),
} },
}); });
if (count > 0) { if (count > 0) {
throw new Error(errorMsg(data[field])); throw new Error(errorMsg(data[field]));
@ -77,9 +90,8 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
} }
} }
private emitDataChangedEvent(data: any, operation: CrudOperation) { private emitDataChangedEvent(data: any, operation: CrudOperation) {
EventBus.emit("dataChanged", { EventBus.emit('dataChanged', {
type: this.objectType, type: this.objectType,
operation, operation,
data, data,
@ -92,7 +104,7 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
* @returns * @returns
*/ */
async updateUserDomain(data: { domainId?: string }, staff?: UserProfile) { async updateUserDomain(data: { domainId?: string }, staff?: UserProfile) {
let { domainId } = data; const { domainId } = data;
if (staff.domainId !== domainId) { if (staff.domainId !== domainId) {
const result = await this.update({ const result = await this.update({
where: { id: staff.id }, where: { id: staff.id },
@ -107,7 +119,6 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
} }
} }
// /** // /**
// * 根据关键词或ID集合查找员工 // * 根据关键词或ID集合查找员工
// * @param data 包含关键词、域ID和ID集合的对象 // * @param data 包含关键词、域ID和ID集合的对象
@ -176,5 +187,4 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
// return combinedResults; // return combinedResults;
// } // }
} }

View File

@ -107,10 +107,10 @@ export async function updatePostViewCount(id: string, type: VisitType) {
where: { id: course.id }, where: { id: course.id },
data: { data: {
[metaFieldMap[type]]: courseViews._sum.views || 0, [metaFieldMap[type]]: courseViews._sum.views || 0,
meta: { // meta: {
...((post?.meta as any) || {}), // ...((post?.meta as any) || {}),
[metaFieldMap[type]]: courseViews._sum.views || 0, // [metaFieldMap[type]]: courseViews._sum.views || 0,
}, // },
}, },
}); });
} }
@ -127,10 +127,10 @@ export async function updatePostViewCount(id: string, type: VisitType) {
where: { id }, where: { id },
data: { data: {
[metaFieldMap[type]]: totalViews._sum.views || 0, [metaFieldMap[type]]: totalViews._sum.views || 0,
meta: { // meta: {
...((post?.meta as any) || {}), // ...((post?.meta as any) || {}),
[metaFieldMap[type]]: totalViews._sum.views || 0, // [metaFieldMap[type]]: totalViews._sum.views || 0,
}, // },
}, },
}); });
} }

View File

@ -41,12 +41,11 @@ export class InitService {
const existingTaxonomies = await db.taxonomy.findMany(); const existingTaxonomies = await db.taxonomy.findMany();
const existingTaxonomyMap = new Map( const existingTaxonomyMap = new Map(
existingTaxonomies.map((taxonomy) => [taxonomy.name, taxonomy]), existingTaxonomies.map((taxonomy) => [taxonomy.slug, taxonomy]),
); );
for (const [index, taxonomy] of InitTaxonomies.entries()) { for (const [index, taxonomy] of InitTaxonomies.entries()) {
const existingTaxonomy = existingTaxonomyMap.get(taxonomy.name); const existingTaxonomy = existingTaxonomyMap.get(taxonomy.slug);
if (!existingTaxonomy) { if (!existingTaxonomy) {
// Create new taxonomy // Create new taxonomy
await db.taxonomy.create({ await db.taxonomy.create({
@ -56,7 +55,7 @@ export class InitService {
}, },
}); });
this.logger.log(`Created new taxonomy: ${taxonomy.name}`); this.logger.log(`Created new taxonomy: ${taxonomy.name}`);
} else { } else if(process.env.NODE_ENV === 'development'){
// Check for differences and update if necessary // Check for differences and update if necessary
const differences = Object.keys(taxonomy).filter( const differences = Object.keys(taxonomy).filter(
(key) => taxonomy[key] !== existingTaxonomy[key], (key) => taxonomy[key] !== existingTaxonomy[key],

View File

@ -1,4 +1,4 @@
VITE_APP_SERVER_IP=192.168.252.239 VITE_APP_SERVER_IP=localhost
VITE_APP_SERVER_PORT=3000 VITE_APP_SERVER_PORT=3000
VITE_APP_FILE_PORT=80 VITE_APP_FILE_PORT=80
VITE_APP_VERSION=0.3.0 VITE_APP_VERSION=0.3.0

View File

@ -7,12 +7,14 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script> <script>
window.env = { window.env = {
VITE_APP_SERVER_IP: "$VITE_APP_SERVER_IP", VITE_APP_SERVER_IP: "$SERVER_IP",
VITE_APP_APP_NAME: "$VITE_APP_APP_NAME", VITE_APP_SERVER_PORT: "$SERVER_PORT",
VITE_APP_VERSION: "$VITE_APP_VERSION", VITE_APP_APP_NAME: "$APP_NAME",
VITE_APP_VERSION: "$VERSION",
VITE_APP_FILE_PORT: "$FILE_PORT",
}; };
</script> </script>
<title>fhmooc</title> <title>$APP_NAME</title>
</head> </head>
<body> <body>

View File

@ -34,7 +34,6 @@
"@nice/common": "workspace:^", "@nice/common": "workspace:^",
"@nice/config": "workspace:^", "@nice/config": "workspace:^",
"@nice/iconer": "workspace:^", "@nice/iconer": "workspace:^",
"@nice/ui": "workspace:^",
"@nice/utils": "workspace:^", "@nice/utils": "workspace:^",
"@tanstack/query-async-storage-persister": "^5.51.9", "@tanstack/query-async-storage-persister": "^5.51.9",
"@tanstack/react-query": "^5.51.21", "@tanstack/react-query": "^5.51.21",

0
apps/web/public/placeholder.webp Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -18,16 +18,6 @@ import type { CarouselRef } from "antd/es/carousel";
import { useAppConfig } from "@nice/client"; import { useAppConfig } from "@nice/client";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
const { Title, Text } = Typography;
interface CarouselItem {
title: string;
desc: string;
image: string;
action: string;
color: string;
}
interface PlatformStat { interface PlatformStat {
icon: React.ReactNode; icon: React.ReactNode;
value: number; value: number;

View File

View File

View File

View File

View File

0
apps/web/src/app/main/path/components/DeptInfo.tsx Normal file → Executable file
View File

0
apps/web/src/app/main/path/components/TermInfo.tsx Normal file → Executable file
View File

View File

View File

@ -20,9 +20,11 @@ import { useTusUpload } from "@web/src/hooks/useTusUpload";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { useAuth } from "@web/src/providers/auth-provider"; import { useAuth } from "@web/src/providers/auth-provider";
import { MIND_OPTIONS } from "./constant"; import { MIND_OPTIONS } from "./constant";
import { SaveOutlined } from "@ant-design/icons"; import { LinkOutlined, SaveOutlined } from "@ant-design/icons";
import JoinButton from "../../models/course/detail/CourseOperationBtns/JoinButton"; import JoinButton from "../../models/course/detail/CourseOperationBtns/JoinButton";
import { CourseDetailContext } from "../../models/course/detail/PostDetailContext"; import { CourseDetailContext } from "../../models/course/detail/PostDetailContext";
import ReactDOM from "react-dom";
import { createRoot } from "react-dom/client";
export default function MindEditor({ id }: { id?: string }) { export default function MindEditor({ id }: { id?: string }) {
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const { const {
@ -57,6 +59,17 @@ export default function MindEditor({ id }: { id?: string }) {
}); });
const { handleFileUpload } = useTusUpload(); const { handleFileUpload } = useTusUpload();
const [form] = Form.useForm(); const [form] = Form.useForm();
const CustomLinkIconPlugin = (mind) => {
mind.bus.addListener('operation', async () => {
const hyperLinkElement = await document.querySelectorAll('.hyper-link');
console.log('hyperLinkElement', hyperLinkElement);
hyperLinkElement.forEach((item) => {
const hyperLinkDom = createRoot(item)
hyperLinkDom.render(<LinkOutlined />)
});
});
};
useEffect(() => { useEffect(() => {
if (post?.id && id) { if (post?.id && id) {
read.mutateAsync({ read.mutateAsync({
@ -98,6 +111,7 @@ export default function MindEditor({ id }: { id?: string }) {
nodeMenu: canEdit, // 禁用节点右键菜单 nodeMenu: canEdit, // 禁用节点右键菜单
keypress: canEdit, // 禁用键盘快捷键 keypress: canEdit, // 禁用键盘快捷键
}); });
mind.install(CustomLinkIconPlugin);
mind.init(MindElixir.new("新思维导图")); mind.init(MindElixir.new("新思维导图"));
containerRef.current.hidden = true; containerRef.current.hidden = true;
//挂载实例 //挂载实例
@ -180,9 +194,6 @@ export default function MindEditor({ id }: { id?: string }) {
useEffect(() => { useEffect(() => {
containerRef.current.style.height = `${Math.floor(window.innerHeight - 271)}px`; containerRef.current.style.height = `${Math.floor(window.innerHeight - 271)}px`;
}, []); }, []);
useEffect(()=>{
console.log(canEdit,user?.id,post?.author?.id)
})
return ( return (
<div className={` flex-col flex `}> <div className={` flex-col flex `}>
{taxonomies && ( {taxonomies && (
@ -214,7 +225,7 @@ export default function MindEditor({ id }: { id?: string }) {
multiple multiple
/> />
</Form.Item> </Form.Item>
<JoinButton></JoinButton> {post && id ? <JoinButton></JoinButton> : <></>}
</div> </div>
<div> <div>
{canEdit && ( {canEdit && (

0
apps/web/src/components/common/editor/constant.ts Normal file → Executable file
View File

View File

@ -1,6 +1,6 @@
// components/CourseDetailDisplayArea.tsx // components/CourseDetailDisplayArea.tsx
import { motion, useScroll, useTransform } from "framer-motion"; import { motion, useScroll, useTransform } from "framer-motion";
import React, { useContext, useRef, useState } from "react"; import React, { useContext, useEffect, useRef, useState } from "react";
import { VideoPlayer } from "@web/src/components/presentation/video-player/VideoPlayer"; import { VideoPlayer } from "@web/src/components/presentation/video-player/VideoPlayer";
import { CourseDetailDescription } from "./CourseDetailDescription"; import { CourseDetailDescription } from "./CourseDetailDescription";
import { Course, LectureType, PostType } from "@nice/common"; import { Course, LectureType, PostType } from "@nice/common";
@ -40,7 +40,7 @@ export const CourseDetailDisplayArea: React.FC = () => {
opacity: videoOpacity, opacity: videoOpacity,
}} }}
className="w-full bg-black rounded-lg "> className="w-full bg-black rounded-lg ">
<div className=" w-full "> <div className=" w-full cursor-pointer">
<VideoPlayer src={lecture?.meta?.videoUrl} /> <VideoPlayer src={lecture?.meta?.videoUrl} />
</div> </div>
</motion.div> </motion.div>

View File

@ -28,6 +28,7 @@ export default function PostList({
renderItem, renderItem,
}: PostListProps) { }: PostListProps) {
const [currentPage, setCurrentPage] = useState<number>(params?.page || 1); const [currentPage, setCurrentPage] = useState<number>(params?.page || 1);
const { data, isLoading }: PostPagnationProps = const { data, isLoading }: PostPagnationProps =
api.post.findManyWithPagination.useQuery({ api.post.findManyWithPagination.useQuery({
select: courseDetailSelect, select: courseDetailSelect,

0
apps/web/src/components/models/post/PostCard.tsx Normal file → Executable file
View File

View File

@ -0,0 +1,12 @@
import { api } from "@nice/client";
export default function PostSelect() {
const { data } = api.post.findMany.useQuery({
where: {
title: {
contains: ""
}
}
})
}

View File

@ -91,6 +91,7 @@ export default function PostSelect({
dropdownStyle={{ dropdownStyle={{
minWidth: 200, // 设置合适的最小宽度 minWidth: 200, // 设置合适的最小宽度
}} }}
autoClearSearchValue
placeholder={placeholder} placeholder={placeholder}
onChange={onChange} onChange={onChange}
filterOption={false} filterOption={false}

View File

View File

View File

@ -25,6 +25,7 @@ export const VideoDisplay: React.FC<VideoDisplayProps> = ({
isDragging, isDragging,
setIsDragging, setIsDragging,
progressRef, progressRef,
isPlaying
} = useContext(VideoPlayerContext); } = useContext(VideoPlayerContext);
// 处理进度条拖拽 // 处理进度条拖拽
@ -191,9 +192,20 @@ export const VideoDisplay: React.FC<VideoDisplayProps> = ({
}; };
}, [src, onError, autoPlay]); }, [src, onError, autoPlay]);
const handleVideoClick = () => {
if (videoRef.current && isPlaying) {
videoRef.current.pause();
setIsPlaying(false);
}else if (videoRef.current && !isPlaying) {
videoRef.current.play();
setIsPlaying(true);
}
};
return ( return (
<div className="relative w-full aspect-video" > <div className="relative w-full aspect-video" >
<video <video
onClick={handleVideoClick}
ref={videoRef} ref={videoRef}
className="w-full h-full" className="w-full h-full"
poster={poster} poster={poster}

View File

@ -0,0 +1,6 @@
import { api } from "packages/client/dist";
import { ReactNode } from "react";
export default function StaffList({ renderItem }: { renderItem: ReactNode }) {
const { data } = api.staff.findManyWithPagination.useQuery({});
data.items.map((staff) => renderItem);
}

View File

@ -11,6 +11,7 @@ ModuleRegistry.registerModules([ClientSideRowModelModule]);
LicenseManager.setLicenseKey( LicenseManager.setLicenseKey(
'LICENSE_KEY_BODY[version=v3][0102]_EXPIRY_NDg4NDc0ODcwNTExMw==094bf1c7852b11df1841f4d14457ae96' 'LICENSE_KEY_BODY[version=v3][0102]_EXPIRY_NDg4NDc0ODcwNTExMw==094bf1c7852b11df1841f4d14457ae96'
); );
ReactDOM.createRoot(document.getElementById("root")!).render( ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode> <React.StrictMode>
<App /> <App />

View File

@ -9,6 +9,7 @@ import {
import apiClient from "../utils/axios-client"; import apiClient from "../utils/axios-client";
import { AuthSchema, RolePerms, UserProfile } from "@nice/common"; import { AuthSchema, RolePerms, UserProfile } from "@nice/common";
import { z } from "zod"; import { z } from "zod";
import { env } from "../env";
interface AuthContextProps { interface AuthContextProps {
accessToken: string | null; accessToken: string | null;
refreshToken: string | null; refreshToken: string | null;
@ -115,10 +116,12 @@ export function AuthProvider({ children }: AuthProviderProps) {
const login = async (username: string, password: string): Promise<void> => { const login = async (username: string, password: string): Promise<void> => {
try { try {
setIsLoading(true); setIsLoading(true);
console.error(env.SERVER_IP, env.SERVER_PORT)
const response = await apiClient.post(`/auth/login`, { const response = await apiClient.post(`/auth/login`, {
username, username,
password, password,
}); });
const { const {
access_token, access_token,
refresh_token, refresh_token,

View File

@ -72,9 +72,7 @@ export const routes: CustomRouteObject[] = [
{ {
path: "editor/:id?", path: "editor/:id?",
element: ( element: (
<WithAuth>
<PathEditorPage></PathEditorPage> <PathEditorPage></PathEditorPage>
</WithAuth>
), ),
}, },
], ],

View File

@ -1,6 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import { env } from '../env'; import { env } from '../env';
const BASE_URL = `http://${env.SERVER_IP}:${env?.SERVER_PORT}` const BASE_URL = `http://${env.SERVER_IP}:${env?.SERVER_PORT}`
const apiClient = axios.create({ const apiClient = axios.create({
baseURL: BASE_URL, baseURL: BASE_URL,
// withCredentials: true, // withCredentials: true,

View File

@ -100,7 +100,11 @@ server {
# 仅供内部使用 # 仅供内部使用
internal; internal;
# 代理到认证服务 # 代理到认证服务
<<<<<<< HEAD
proxy_pass http://host.docker.internal:3000/auth/file; proxy_pass http://host.docker.internal:3000/auth/file;
=======
proxy_pass http://host.docker.internal:3001/auth/file;
>>>>>>> fdb7b2357a6f025bc5d2ec0a8803142015fb2500
# 请求优化:不传递请求体 # 请求优化:不传递请求体
proxy_pass_request_body off; proxy_pass_request_body off;

View File

@ -14,8 +14,11 @@ done
# Check if the index.html file exists before processing # Check if the index.html file exists before processing
if [ -f "/usr/share/nginx/html/index.html" ]; then if [ -f "/usr/share/nginx/html/index.html" ]; then
# Use envsubst to replace environment variable placeholders # Use envsubst to replace environment variable placeholders
envsubst < /usr/share/nginx/html/index.html > /usr/share/nginx/html/index.html.tmp echo "Processing /usr/share/nginx/html/index.html"
envsubst < /usr/share/nginx/html/index.temp > /usr/share/nginx/html/index.html.tmp
mv /usr/share/nginx/html/index.html.tmp /usr/share/nginx/html/index.html mv /usr/share/nginx/html/index.html.tmp /usr/share/nginx/html/index.html
echo "Processed content:"
cat /usr/share/nginx/html/index.html
else else
echo "Info: /usr/share/nginx/html/index.html does not exist , skip replace env" echo "Info: /usr/share/nginx/html/index.html does not exist , skip replace env"
exit 1 exit 1

View File

@ -39,32 +39,9 @@ services:
environment: environment:
- PGADMIN_DEFAULT_EMAIL=insiinc@outlook.com - PGADMIN_DEFAULT_EMAIL=insiinc@outlook.com
- PGADMIN_DEFAULT_PASSWORD=Letusdoit000 - PGADMIN_DEFAULT_PASSWORD=Letusdoit000
# tusd:
# image: tusproject/tusd
# ports:
# - "8080:8080"
# environment:
# - AWS_REGION=cn-north-1
# - AWS_ACCESS_KEY_ID=minioadmin
# - AWS_SECRET_ACCESS_KEY=minioadmin
# command: -verbose -s3-bucket app -s3-endpoint http://minio:9000 -hooks-http http://host.docker.internal:3000/upload/hook
# volumes:
# - ./volumes/tusd:/data
# extra_hosts:
# - "host.docker.internal:host-gateway"
# depends_on:
# - minio
# tusd:
# image: tusproject/tusd
# ports:
# - "8080:8080"
# command: -verbose -upload-dir /data -hooks-http http://host.docker.internal:3000/upload/hook
# volumes:
# - ./uploads:/data
# extra_hosts:
# - "host.docker.internal:host-gateway"
nginx: nginx:
image: nice-nginx:2.0 image: nice-nginx:latest
ports: ports:
- "80:80" - "80:80"
volumes: volumes:
@ -74,12 +51,14 @@ services:
- ./web-dist:/usr/share/nginx/html # 添加前端构建文件的挂载 - ./web-dist:/usr/share/nginx/html # 添加前端构建文件的挂载
- ./config/nginx/entrypoint.sh:/docker-entrypoint.sh - ./config/nginx/entrypoint.sh:/docker-entrypoint.sh
environment: environment:
- SERVER_IP=host.docker.internal - SERVER_IP=192.168.252.77
- SERVER_PORT=3000 - SERVER_PORT=3000
- FILE_PORT=80
- APP_NAME=test
- VERSION=0.30
entrypoint: ["/docker-entrypoint.sh"] entrypoint: ["/docker-entrypoint.sh"]
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
redis: redis:
image: redis:latest image: redis:latest
ports: ports:

View File

@ -63,6 +63,6 @@ export function useAppConfig() {
isLoading, isLoading,
slides, slides,
slideLinks, slideLinks,
statistics, statistics
}; };
} }

View File

@ -8,9 +8,8 @@
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"generate": "pnpm prisma generate", "generate": "pnpm prisma generate",
"build": "pnpm generate && tsup", "build": "pnpm generate && tsup --no-watch",
"dev": "pnpm generate && tsup --watch ", "dev": "pnpm generate && tsup --watch ",
"dev-nowatch": "pnpm generate && tsup --no-watch ",
"studio": "pnpm prisma studio", "studio": "pnpm prisma studio",
"db:clear": "rm -rf prisma/migrations && pnpm prisma migrate dev --name init", "db:clear": "rm -rf prisma/migrations && pnpm prisma migrate dev --name init",
"postinstall": "pnpm generate" "postinstall": "pnpm generate"

View File

@ -6,7 +6,7 @@
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "tsup", "build": "tsup --no-watch",
"dev": "tsup --watch", "dev": "tsup --watch",
"clean": "rimraf dist", "clean": "rimraf dist",
"typecheck": "tsc --noEmit" "typecheck": "tsc --noEmit"

View File

@ -1,38 +0,0 @@
{
"name": "@nice/ui",
"version": "1.0.0",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"private": true,
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"clean": "rimraf dist",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@dagrejs/dagre": "^1.1.4",
"@nice/utils": "workspace:^",
"@xyflow/react": "^12.3.6",
"dagre": "^0.8.5",
"nanoid": "^5.0.9",
"react-hotkeys-hook": "^4.6.1",
"zustand": "^5.0.3"
},
"peerDependencies": {
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@types/dagre": "^0.7.52",
"@types/node": "^20.3.1",
"@types/react": "18.2.38",
"@types/react-dom": "18.2.15",
"concurrently": "^8.0.0",
"rimraf": "^6.0.1",
"ts-node": "^10.9.1",
"tsup": "^8.3.5",
"typescript": "^5.5.4"
}
}

View File

@ -1,90 +0,0 @@
import { useCallback, useState, useRef, useEffect } from 'react';
import {
ReactFlow,
Controls,
Background,
useReactFlow,
Panel,
ReactFlowProvider,
NodeOrigin,
ConnectionLineType,
useStoreApi,
InternalNode,
} from '@xyflow/react';
import MindMapNode from './MindMapNode';
import useMindMapStore, { RFState } from './store';
import { shallow, useShallow } from 'zustand/shallow';
import MindMapEdge from './MindMapEdge';
import '@xyflow/react/dist/style.css';
import { useFlowKeyboardControls } from './hooks/useFlowKeyboardControl';
const selector = (state: RFState) => ({
nodes: state.nodes,
edges: state.edges,
onNodesChange: state.onNodesChange,
onEdgesChange: state.onEdgesChange,
addChildNode: state.addChildNode,
addSiblingNode: state.addSiblingNode,
selectedNodeId: state.selectedNodeId,
setSelectedNodeIdId: state.setSelectedNodeId,
undo: state.undo,
redo: state.redo,
canUndo: state.canUndo,
canRedo: state.canRedo
});
const nodeOrigin: NodeOrigin = [0.5, 0.5];
// 节点类型定义
const nodeTypes = {
mindmap: MindMapNode,
};
const edgeTypes = {
mindmap: MindMapEdge,
};
const connectionLineStyle = {
stroke: '#999',
strokeWidth: 2,
radius: 20 // Add corner radius for orthogonal lines
};
const defaultEdgeOptions = {
style: connectionLineStyle,
type: 'mindmap',
animated: false
};
export function Flow() {
const { nodes, edges, onNodesChange, undo, redo, setSelectedNodeIdId, onEdgesChange, addChildNode, addSiblingNode, selectedNodeId } = useMindMapStore(
useShallow(selector)
);
useFlowKeyboardControls()
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
nodeOrigin={nodeOrigin}
connectionLineStyle={connectionLineStyle}
defaultEdgeOptions={defaultEdgeOptions}
connectionLineType={ConnectionLineType.SmoothStep}
fitView
panOnDrag={[2]}
minZoom={0.2}
maxZoom={4}
nodesConnectable={false}
>
<Background />
<Controls />
<Panel position="top-left">React Flow Mind Map</Panel>
</ReactFlow>
);
}
export function MindMap() {
return <ReactFlowProvider>
<Flow></Flow>
</ReactFlowProvider>
}

View File

@ -1,16 +0,0 @@
import { BaseEdge, EdgeProps, getBezierPath, getStraightPath } from '@xyflow/react';
function MindMapEdge(props: EdgeProps) {
const { sourceX, sourceY, targetX, targetY } = props;
const [edgePath] = getBezierPath({
sourceX,
sourceY,
targetX,
targetY,
});
return <BaseEdge path={edgePath} {...props} />;
}
export default MindMapEdge;

View File

@ -1,83 +0,0 @@
import { Handle, NodeProps, Position, useEdges } from '@xyflow/react';
import { MindMapNodeType } from './types';
import useMindMapStore, { RFState } from './store';
import { useEffect, useRef, useState } from 'react';
import { useShallow } from 'zustand/shallow';
import { useClickOutside } from '../../hooks/useClickOutside';
import { useHotkeys } from 'react-hotkeys-hook';
const selector = (state: RFState) => ({
selectedNodeId: state.selectedNodeId,
editingNodeId: state.editingNodeId,
updateNodeLabel: state.updateNodeLabel,
setSelectedNodeId: state.setSelectedNodeId,
setEditingNodeId: state.setEditingNodeId
});
function MindMapNode({ id, data }: NodeProps<MindMapNodeType>) {
const nodeRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
const [inputValue, setInputValue] = useState(data.label);
const {
updateNodeLabel,
selectedNodeId,
setSelectedNodeId,
setEditingNodeId,
editingNodeId
} = useMindMapStore(useShallow(selector));
useEffect(() => {
if (editingNodeId === id) {
setEditingNodeId(id);
setInputValue(data.label);
setTimeout(() => {
inputRef.current?.focus();
inputRef.current?.select();
}, 0);
} else {
inputRef.current?.blur()
}
}, [editingNodeId])
const handleDoubleClick = (e: React.MouseEvent) => {
e.stopPropagation();
setEditingNodeId(id)
};
useHotkeys("space", (e) => {
if (selectedNodeId === id)
setEditingNodeId(id)
}, { preventDefault: true });
const handleClick = (e: React.MouseEvent) => {
setSelectedNodeId(id);
};
useClickOutside(nodeRef, () => {
console.log(selectedNodeId, id)
if (selectedNodeId === id)
setSelectedNodeId(null)
if (editingNodeId === id) {
setEditingNodeId(null)
updateNodeLabel(id, inputValue)
}
});
return (
<div
ref={nodeRef}
onDoubleClick={handleDoubleClick}
onClick={handleClick}
className={`mindmap-node ${id === selectedNodeId ? 'selected' : ''}`}
>
<input
ref={inputRef}
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
className="input"
readOnly={id !== editingNodeId}
/>
<Handle type="target" position={Position.Top} />
<Handle type="source" position={Position.Top} />
</div>
);
}
export default MindMapNode;

View File

@ -1,11 +0,0 @@
import type { Edge, EdgeTypes } from "@xyflow/react";
export const initialEdges = [
{ id: "a->c", source: "a", target: "c", animated: true },
{ id: "b->d", source: "b", target: "d" },
{ id: "c->d", source: "c", target: "d", animated: true },
] satisfies Edge[];
export const edgeTypes = {
// Add your custom edge types here!
} satisfies EdgeTypes;

View File

@ -1,145 +0,0 @@
import { useCallback } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { useStoreApi } from '@xyflow/react';
import useMindMapStore, { RFState } from '../store';
import { useShallow } from 'zustand/shallow';
const controlsSelector = (state: RFState) => ({
selectedNodeId: state.selectedNodeId,
setSelectedNodeId: state.setSelectedNodeId,
addChildNode: state.addChildNode,
addSiblingNode: state.addSiblingNode,
undo: state.undo,
redo: state.redo,
});
export function useFlowKeyboardControls() {
const {
selectedNodeId,
setSelectedNodeId,
addChildNode,
addSiblingNode,
undo,
redo,
} = useMindMapStore(useShallow(controlsSelector));
const store = useStoreApi();
const getNextNodeInDirection = useCallback((direction: 'left' | 'right' | 'up' | 'down') => {
const { nodeLookup, edges } = store.getState();
if (!selectedNodeId) return null;
const currentNode = nodeLookup.get(selectedNodeId);
if (!currentNode) return null;
// 构建节点关系图
const nodeRelations = new Map<string, { parent: string | null; children: string[]; siblings: string[] }>();
edges.forEach(edge => {
const source = edge.source;
const target = edge.target;
if (!nodeRelations.has(source)) {
nodeRelations.set(source, { parent: null, children: [], siblings: [] });
}
if (!nodeRelations.has(target)) {
nodeRelations.set(target, { parent: null, children: [], siblings: [] });
}
nodeRelations.get(target)!.parent = source;
nodeRelations.get(source)!.children.push(target);
});
// 找出同级节点
const currentRelation = nodeRelations.get(selectedNodeId);
if (currentRelation?.parent) {
const parentRelation = nodeRelations.get(currentRelation.parent);
if (parentRelation) {
currentRelation.siblings = parentRelation.children.filter(id => id !== selectedNodeId);
}
}
// 根据方向决定下一个节点
switch (direction) {
case 'left': {
// 如果当前节点是子节点,优先选择父节点
if (currentRelation?.parent) {
const parentNode = nodeLookup.get(currentRelation.parent);
if (parentNode && parentNode.position.x < currentNode.position.x) {
return currentRelation.parent;
}
}
break;
}
case 'right': {
// 如果有子节点,选择第一个子节点
const children = currentRelation?.children || [];
if (children.length > 0) {
return children[0];
}
break;
}
case 'up': {
// 在同级节点中找位置靠上的节点
const siblings = currentRelation?.siblings || [];
const upperSiblings = siblings
.map(id => nodeLookup.get(id))
.filter(node => node && node.position.y < currentNode.position.y)
.sort((a, b) => b!.position.y - a!.position.y);
if (upperSiblings.length > 0) {
return upperSiblings[0]!.id;
}
break;
}
case 'down': {
// 在同级节点中找位置靠下的节点
const siblings = currentRelation?.siblings || [];
const lowerSiblings = siblings
.map(id => nodeLookup.get(id))
.filter(node => node && node.position.y > currentNode.position.y)
.sort((a, b) => a!.position.y - b!.position.y);
if (lowerSiblings.length > 0) {
return lowerSiblings[0]!.id;
}
break;
}
}
return null;
}, [selectedNodeId, store]);
// Tab 键添加子节点
useHotkeys('tab', (e) => {
e.preventDefault();
if (selectedNodeId) addChildNode(selectedNodeId);
}, { enableOnFormTags: true, preventDefault: true });
// Enter 键添加同级节点
useHotkeys('enter', (e) => {
e.preventDefault();
if (selectedNodeId) addSiblingNode(selectedNodeId);
}, { enableOnFormTags: true, preventDefault: true });
// 撤销重做
// useHotkeys('ctrl+z, cmd+z', (e) => {
// undo();
// }, { enableOnFormTags: false });
// useHotkeys('ctrl+y, cmd+y', (e) => {
// redo();
// }, { enableOnFormTags: false });
// 方向键导航
const directions = ['left', 'right', 'up', 'down'] as const;
directions.forEach(direction => {
useHotkeys(direction, (e) => {
e.preventDefault();
const nextNodeId = getNextNodeInDirection(direction);
if (nextNodeId) setSelectedNodeId(nextNodeId);
}, { enableOnFormTags: true });
});
}

View File

@ -1 +0,0 @@
export * from "./MindMap"

View File

@ -1,43 +0,0 @@
import { Edge, Node } from '@xyflow/react';
import dagre from 'dagre';
export const getLayoutedElements = (nodes: Node[], edges: Edge[], direction = 'LR') => {
const dagreGraph = new dagre.graphlib.Graph();
dagreGraph.setDefaultEdgeLabel(() => ({}));
const nodeWidth = 200;
const nodeHeight = 50;
dagreGraph.setGraph({
rankdir: direction,
nodesep: 80,
ranksep: 100
});
// 添加节点
nodes.forEach((node) => {
dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
});
// 添加边
edges.forEach((edge) => {
dagreGraph.setEdge(edge.source, edge.target);
});
// 计算布局
dagre.layout(dagreGraph);
// 获取新的节点位置
const layoutedNodes = nodes.map((node) => {
const nodeWithPosition = dagreGraph.node(node.id);
return {
...node,
position: {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2,
},
};
});
return { nodes: layoutedNodes, edges };
};

View File

@ -1,234 +0,0 @@
import {
Edge,
EdgeChange,
Node,
NodeChange,
OnNodesChange,
OnEdgesChange,
applyNodeChanges,
applyEdgeChanges,
XYPosition,
} from '@xyflow/react';
import { nanoid } from 'nanoid';
import { create } from 'zustand';
import { HistoryData, HistoryState, NodeLayout, NodeRelationType } from './types';
import { getLayoutedElements } from './layout';
const createHistoryState = (initialPresent: HistoryData): HistoryState<HistoryData> => ({
past: [],
present: initialPresent,
future: [],
});
const initialNodes: Node[] = [{
id: 'root',
type: 'mindmap',
data: { label: 'React Flow Mind Map' },
position: { x: 0, y: 0 },
}];
export type RFState = {
nodes: Node[];
edges: Edge[];
onNodesChange: OnNodesChange;
onEdgesChange: OnEdgesChange;
history: HistoryState<HistoryData>;
addChildNode: (nodeId: string, position?: XYPosition) => void;
updateNodeLabel: (nodeId: string, label: string) => void
addSiblingNode: (nodeId: string, position?: XYPosition) => void
selectedNodeId: string | null;
setSelectedNodeId: (nodeId: string | null) => void;
editingNodeId: string | null;
setEditingNodeId: (nodeId: string | null) => void;
isEditing: boolean;
undo: () => void;
redo: () => void;
canUndo: boolean;
canRedo: boolean;
};
const useMindMapStore = create<RFState>((set, get) => {
const updateHistory = (newState: Partial<HistoryData>) => {
const currentState = get().history.present;
return {
past: [...get().history.past, currentState],
present: { ...currentState, ...newState },
future: [],
};
};
const createNewNode = (label: string = 'New Node'): Node => ({
id: nanoid(),
type: 'mindmap',
data: { label },
position: { x: 0, y: 0 }
});
const addNode = (
parentId: string,
relationType: NodeRelationType
) => {
const { nodes, edges, editingNodeId } = get();
const parentNode = nodes.find(node => node.id === parentId);
if (!parentNode) return;
const newNode = createNewNode();
const newEdge = {
id: nanoid(),
source: relationType === 'child' ? parentId : edges.find(e => e.target === parentId)?.source ?? parentId,
target: newNode.id,
type: 'smoothstep',
};
const newNodes = [...nodes, newNode];
const newEdges = [...edges, newEdge];
const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(newNodes, newEdges);
set({
nodes: layoutedNodes,
edges: layoutedEdges,
selectedNodeId: newNode.id,
history: updateHistory({
nodes: layoutedNodes,
edges: layoutedEdges,
selectedNodeId: newNode.id,
editingNodeId,
}),
});
};
return {
nodes: initialNodes,
edges: [],
isEditing: false,
history: createHistoryState({ nodes: initialNodes, edges: [], selectedNodeId: null, editingNodeId: null }),
editingNodeId: null,
setEditingNodeId: (nodeId: string | null) => {
const { nodes, edges, selectedNodeId } = get();
set({
editingNodeId: nodeId,
isEditing: Boolean(nodeId),
history: {
past: [...get().history.past, get().history.present],
present: {
nodes,
edges,
selectedNodeId,
editingNodeId: nodeId
},
future: [],
},
});
},
selectedNodeId: null,
setSelectedNodeId: (nodeId: string | null) => {
const { nodes, edges, editingNodeId } = get();
set({
selectedNodeId: nodeId,
history: {
past: [...get().history.past, get().history.present],
present: { nodes, edges, selectedNodeId: nodeId, editingNodeId },
future: [],
},
});
},
updateNodeLabel: (nodeId: string, label: string) => {
const { nodes, edges, selectedNodeId, editingNodeId } = get();
const newNodes = nodes.map((node) => {
if (node.id === nodeId) {
return { ...node, data: { ...node.data, label } };
}
return node;
});
set({
nodes: newNodes,
edges,
selectedNodeId,
history: {
past: [...get().history.past, get().history.present],
present: { nodes: newNodes, edges, selectedNodeId, editingNodeId },
future: [],
},
});
},
onNodesChange: (changes: NodeChange[]) => {
console.log('on node change', changes)
const { nodes, edges, selectedNodeId } = get();
const newNodes = applyNodeChanges(changes, nodes);
set({ nodes: newNodes });
},
onEdgesChange: (changes: EdgeChange[]) => {
const { nodes, edges, selectedNodeId } = get();
const newEdges = applyEdgeChanges(changes, edges);
set({ edges: newEdges });
},
addChildNode: (nodeId: string) =>
addNode(nodeId, 'child'),
addSiblingNode: (nodeId: string) =>
addNode(nodeId, 'sibling'),
undo: () => {
const { history } = get();
console.log('[Undo] Starting undo operation');
if (history.past.length === 0) {
console.log('[Undo] No past states available, undo skipped');
return;
}
const previous = history.past[history.past.length - 1];
const newPast = history.past.slice(0, -1);
const newPresent = { ...history.present };
console.log('[Undo] Previous state:', previous);
console.log('[Undo] New past length:', newPast.length);
set({
nodes: previous.nodes,
edges: previous.edges,
selectedNodeId: previous.selectedNodeId,
editingNodeId: previous.editingNodeId,
history: {
past: newPast,
present: previous,
future: [newPresent, ...history.future],
},
});
console.log('[Undo] Operation completed');
},
redo: () => {
const { history } = get();
console.log('[Redo] Starting redo operation');
if (history.future.length === 0) {
console.log('[Redo] No future states available, redo skipped');
return;
}
const next = history.future[0];
const newFuture = history.future.slice(1);
console.log('[Redo] Next state:', next);
console.log('[Redo] New future length:', newFuture.length);
set({
nodes: next.nodes,
edges: next.edges,
selectedNodeId: next.selectedNodeId,
editingNodeId: next.editingNodeId,
history: {
past: [...history.past, history.present],
present: next,
future: newFuture,
},
});
console.log('[Redo] Operation completed');
},
get canUndo() {
return get().history.past.length > 0;
},
get canRedo() {
return get().history.future.length > 0;
},
}
});
export default useMindMapStore;

View File

@ -1,32 +0,0 @@
import type { Node, NodeTypes, BuiltInNode, Edge } from "@xyflow/react";
export type MindMapNodeType = Node<
{
label: string
level: number
isExpanded?: boolean
metadata?: Record<string, number>
}, "mindmap">
export type MindMapEdgeType = Edge<{
label: string
}, "mindmap">
export type HistoryState<T> = {
past: T[];
present: T;
future: T[];
};
export type HistoryData = {
nodes: Node[];
edges: Edge[];
selectedNodeId: string | null;
editingNodeId: string | null; // Add this
};
export type NodeRelationType = 'child' | 'sibling';
export type NodeLayout = {
horizontalSpacing: number;
verticalSpacing: number;
nodeWidth: number;
nodeHeight: number;
};

View File

@ -1,15 +0,0 @@
import { useEffect, RefObject } from 'react';
export function useClickOutside<T extends HTMLElement>(ref: RefObject<T>, handler: () => void) {
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
console.log(event.target)
if (ref.current && !ref.current.contains(event.target as Node)) {
handler();
}
}
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, [ref, handler]);
}

View File

@ -1 +0,0 @@
export * from "./components/mindmap"

View File

@ -1,43 +0,0 @@
{
"compilerOptions": {
"target": "es2022",
"module": "esnext",
"allowJs": true,
"lib": [
"DOM",
"es2022",
"DOM.Iterable"
],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"removeComments": true,
"skipLibCheck": true,
"strict": true,
"isolatedModules": true,
"jsx": "react-jsx",
"esModuleInterop": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noImplicitReturns": false,
"noFallthroughCasesInSwitch": false,
"noUncheckedIndexedAccess": false,
"noImplicitOverride": false,
"noPropertyAccessFromIndexSignature": false,
"outDir": "dist",
"incremental": true,
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
},
"include": [
"src"
],
"exclude": [
"node_modules",
"dist",
"**/*.test.ts",
"**/*.spec.ts",
"**/__tests__"
]
}

View File

@ -1,13 +0,0 @@
import { defineConfig } from 'tsup'
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
clean: true,
sourcemap: true,
minify: true,
external: ['react', 'react-dom'],
bundle: true,
target: "esnext"
})

View File

@ -6,9 +6,8 @@
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "tsup", "build": "tsup --no-watch",
"dev": "tsup --watch", "dev": "tsup --watch",
"dev-static": "tsup --no-watch",
"clean": "rimraf dist", "clean": "rimraf dist",
"typecheck": "tsc --noEmit" "typecheck": "tsc --noEmit"
}, },

View File

@ -12,7 +12,7 @@ importers:
dependencies: dependencies:
'@nestjs/bullmq': '@nestjs/bullmq':
specifier: ^10.2.0 specifier: ^10.2.0
version: 10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))(bullmq@5.34.8) version: 10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(bullmq@5.34.8)
'@nestjs/common': '@nestjs/common':
specifier: ^10.3.10 specifier: ^10.3.10
version: 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) version: 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)
@ -33,7 +33,7 @@ importers:
version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.15)(rxjs@7.8.1) version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.15)(rxjs@7.8.1)
'@nestjs/schedule': '@nestjs/schedule':
specifier: ^4.1.0 specifier: ^4.1.0
version: 4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)) version: 4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)
'@nestjs/websockets': '@nestjs/websockets':
specifier: ^10.3.10 specifier: ^10.3.10
version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-socket.io@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-socket.io@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)
@ -148,7 +148,7 @@ importers:
version: 10.2.3(chokidar@3.6.0)(typescript@5.7.2) version: 10.2.3(chokidar@3.6.0)(typescript@5.7.2)
'@nestjs/testing': '@nestjs/testing':
specifier: ^10.0.0 specifier: ^10.0.0
version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)) version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-express@10.4.15)
'@types/exceljs': '@types/exceljs':
specifier: ^1.3.0 specifier: ^1.3.0
version: 1.3.2 version: 1.3.2
@ -296,9 +296,6 @@ importers:
'@nice/iconer': '@nice/iconer':
specifier: workspace:^ specifier: workspace:^
version: link:../../packages/iconer version: link:../../packages/iconer
'@nice/ui':
specifier: workspace:^
version: link:../../packages/ui
'@nice/utils': '@nice/utils':
specifier: workspace:^ specifier: workspace:^
version: link:../../packages/utils version: link:../../packages/utils
@ -785,64 +782,6 @@ importers:
specifier: ^5.5.4 specifier: ^5.5.4
version: 5.7.2 version: 5.7.2
packages/ui:
dependencies:
'@dagrejs/dagre':
specifier: ^1.1.4
version: 1.1.4
'@nice/utils':
specifier: workspace:^
version: link:../utils
'@xyflow/react':
specifier: ^12.3.6
version: 12.3.6(@types/react@18.2.38)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
dagre:
specifier: ^0.8.5
version: 0.8.5
nanoid:
specifier: ^5.0.9
version: 5.0.9
react:
specifier: 18.2.0
version: 18.2.0
react-dom:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
react-hotkeys-hook:
specifier: ^4.6.1
version: 4.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
zustand:
specifier: ^5.0.3
version: 5.0.3(@types/react@18.2.38)(react@18.2.0)(use-sync-external-store@1.4.0(react@18.2.0))
devDependencies:
'@types/dagre':
specifier: ^0.7.52
version: 0.7.52
'@types/node':
specifier: ^20.3.1
version: 20.17.12
'@types/react':
specifier: 18.2.38
version: 18.2.38
'@types/react-dom':
specifier: 18.2.15
version: 18.2.15
concurrently:
specifier: ^8.0.0
version: 8.2.2
rimraf:
specifier: ^6.0.1
version: 6.0.1
ts-node:
specifier: ^10.9.1
version: 10.9.2(@swc/core@1.10.6(@swc/helpers@0.5.15))(@types/node@20.17.12)(typescript@5.7.2)
tsup:
specifier: ^8.3.5
version: 8.3.5(@microsoft/api-extractor@7.49.2(@types/node@20.17.12))(@swc/core@1.10.6(@swc/helpers@0.5.15))(jiti@1.21.7)(postcss@8.4.49)(typescript@5.7.2)(yaml@2.7.0)
typescript:
specifier: ^5.5.4
version: 5.7.2
packages/utils: packages/utils:
devDependencies: devDependencies:
'@types/node': '@types/node':
@ -1395,13 +1334,6 @@ packages:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'} engines: {node: '>=12'}
'@dagrejs/dagre@1.1.4':
resolution: {integrity: sha512-QUTc54Cg/wvmlEUxB+uvoPVKFazM1H18kVHBQNmK2NbrDR5ihOCR6CXLnDSZzMcSQKJtabPUWridBOlJM3WkDg==}
'@dagrejs/graphlib@2.2.4':
resolution: {integrity: sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw==}
engines: {node: '>17.0.0'}
'@dnd-kit/accessibility@3.1.1': '@dnd-kit/accessibility@3.1.1':
resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==} resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==}
peerDependencies: peerDependencies:
@ -1987,67 +1919,79 @@ packages:
resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-arm@1.0.5': '@img/sharp-libvips-linux-arm@1.0.5':
resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-s390x@1.0.4': '@img/sharp-libvips-linux-s390x@1.0.4':
resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-x64@1.0.4': '@img/sharp-libvips-linux-x64@1.0.4':
resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-libvips-linuxmusl-arm64@1.0.4': '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@img/sharp-libvips-linuxmusl-x64@1.0.4': '@img/sharp-libvips-linuxmusl-x64@1.0.4':
resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@img/sharp-linux-arm64@0.33.5': '@img/sharp-linux-arm64@0.33.5':
resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-linux-arm@0.33.5': '@img/sharp-linux-arm@0.33.5':
resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-linux-s390x@0.33.5': '@img/sharp-linux-s390x@0.33.5':
resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-linux-x64@0.33.5': '@img/sharp-linux-x64@0.33.5':
resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@img/sharp-linuxmusl-arm64@0.33.5': '@img/sharp-linuxmusl-arm64@0.33.5':
resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@img/sharp-linuxmusl-x64@0.33.5': '@img/sharp-linuxmusl-x64@0.33.5':
resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@img/sharp-wasm32@0.33.5': '@img/sharp-wasm32@0.33.5':
resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
@ -2515,51 +2459,61 @@ packages:
resolution: {integrity: sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==} resolution: {integrity: sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.30.1': '@rollup/rollup-linux-arm-musleabihf@4.30.1':
resolution: {integrity: sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==} resolution: {integrity: sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.30.1': '@rollup/rollup-linux-arm64-gnu@4.30.1':
resolution: {integrity: sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==} resolution: {integrity: sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.30.1': '@rollup/rollup-linux-arm64-musl@4.30.1':
resolution: {integrity: sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==} resolution: {integrity: sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-loongarch64-gnu@4.30.1': '@rollup/rollup-linux-loongarch64-gnu@4.30.1':
resolution: {integrity: sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==} resolution: {integrity: sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-powerpc64le-gnu@4.30.1': '@rollup/rollup-linux-powerpc64le-gnu@4.30.1':
resolution: {integrity: sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==} resolution: {integrity: sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-gnu@4.30.1': '@rollup/rollup-linux-riscv64-gnu@4.30.1':
resolution: {integrity: sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==} resolution: {integrity: sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-s390x-gnu@4.30.1': '@rollup/rollup-linux-s390x-gnu@4.30.1':
resolution: {integrity: sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==} resolution: {integrity: sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.30.1': '@rollup/rollup-linux-x64-gnu@4.30.1':
resolution: {integrity: sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==} resolution: {integrity: sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.30.1': '@rollup/rollup-linux-x64-musl@4.30.1':
resolution: {integrity: sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==} resolution: {integrity: sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-win32-arm64-msvc@4.30.1': '@rollup/rollup-win32-arm64-msvc@4.30.1':
resolution: {integrity: sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==} resolution: {integrity: sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==}
@ -2918,24 +2872,28 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@swc/core-linux-arm64-musl@1.10.6': '@swc/core-linux-arm64-musl@1.10.6':
resolution: {integrity: sha512-hB2xZFmXCKf2iJF5y2z01PSuLqEoUP3jIX/XlIHN+/AIP7PkSKsValE63LnjlnWPnSEI0IxUyRE3T3FzWE/fQQ==} resolution: {integrity: sha512-hB2xZFmXCKf2iJF5y2z01PSuLqEoUP3jIX/XlIHN+/AIP7PkSKsValE63LnjlnWPnSEI0IxUyRE3T3FzWE/fQQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@swc/core-linux-x64-gnu@1.10.6': '@swc/core-linux-x64-gnu@1.10.6':
resolution: {integrity: sha512-PRGPp0I22+oJ8RMGg8M4hXYxEffH3ayu0WoSDPOjfol1F51Wj1tfTWN4wVa2RibzJjkBwMOT0KGLGb/hSEDDXQ==} resolution: {integrity: sha512-PRGPp0I22+oJ8RMGg8M4hXYxEffH3ayu0WoSDPOjfol1F51Wj1tfTWN4wVa2RibzJjkBwMOT0KGLGb/hSEDDXQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@swc/core-linux-x64-musl@1.10.6': '@swc/core-linux-x64-musl@1.10.6':
resolution: {integrity: sha512-SoNBxlA86lnoV9vIz/TCyakLkdRhFSHx6tFMKNH8wAhz1kKYbZfDmpYoIzeQqdTh0tpx8e/Zu1zdK4smovsZqQ==} resolution: {integrity: sha512-SoNBxlA86lnoV9vIz/TCyakLkdRhFSHx6tFMKNH8wAhz1kKYbZfDmpYoIzeQqdTh0tpx8e/Zu1zdK4smovsZqQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@swc/core-win32-arm64-msvc@1.10.6': '@swc/core-win32-arm64-msvc@1.10.6':
resolution: {integrity: sha512-6L5Y2E+FVvM+BtoA+mJFjf/SjpFr73w2kHBxINxwH8/PkjAjkePDr5m0ibQhPXV61bTwX49+1otzTY85EsUW9Q==} resolution: {integrity: sha512-6L5Y2E+FVvM+BtoA+mJFjf/SjpFr73w2kHBxINxwH8/PkjAjkePDr5m0ibQhPXV61bTwX49+1otzTY85EsUW9Q==}
@ -4275,9 +4233,6 @@ packages:
resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==}
engines: {node: '>=12'} engines: {node: '>=12'}
dagre@0.8.5:
resolution: {integrity: sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==}
dargs@7.0.0: dargs@7.0.0:
resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -5016,9 +4971,6 @@ packages:
graphemer@1.4.0: graphemer@1.4.0:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
graphlib@2.1.8:
resolution: {integrity: sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==}
hard-rejection@2.1.0: hard-rejection@2.1.0:
resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -6706,12 +6658,6 @@ packages:
react: '>=16' react: '>=16'
react-dom: '>=16' react-dom: '>=16'
react-hotkeys-hook@4.6.1:
resolution: {integrity: sha512-XlZpbKUj9tkfgPgT9gA+1p7Ey6vFIZHttUjPqpTdyT5nqQ8mHL7elxvSbaC+dpSiHUSmr21Ya1mDxBZG3aje4Q==}
peerDependencies:
react: '>=16.8.1'
react-dom: '>=16.8.1'
react-is@16.13.1: react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
@ -7885,24 +7831,6 @@ packages:
react: react:
optional: true optional: true
zustand@5.0.3:
resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==}
engines: {node: '>=12.20.0'}
peerDependencies:
'@types/react': '>=18.0.0'
immer: '>=9.0.6'
react: '>=18.0.0'
use-sync-external-store: '>=1.2.0'
peerDependenciesMeta:
'@types/react':
optional: true
immer:
optional: true
react:
optional: true
use-sync-external-store:
optional: true
snapshots: snapshots:
'@ag-grid-community/client-side-row-model@32.3.3': '@ag-grid-community/client-side-row-model@32.3.3':
@ -8911,12 +8839,6 @@ snapshots:
dependencies: dependencies:
'@jridgewell/trace-mapping': 0.3.9 '@jridgewell/trace-mapping': 0.3.9
'@dagrejs/dagre@1.1.4':
dependencies:
'@dagrejs/graphlib': 2.2.4
'@dagrejs/graphlib@2.2.4': {}
'@dnd-kit/accessibility@3.1.1(react@18.2.0)': '@dnd-kit/accessibility@3.1.1(react@18.2.0)':
dependencies: dependencies:
react: 18.2.0 react: 18.2.0
@ -9654,15 +9576,15 @@ snapshots:
'@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3':
optional: true optional: true
'@nestjs/bull-shared@10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))': '@nestjs/bull-shared@10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)':
dependencies: dependencies:
'@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)
'@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)
tslib: 2.8.1 tslib: 2.8.1
'@nestjs/bullmq@10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))(bullmq@5.34.8)': '@nestjs/bullmq@10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(bullmq@5.34.8)':
dependencies: dependencies:
'@nestjs/bull-shared': 10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)) '@nestjs/bull-shared': 10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)
'@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)
'@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)
bullmq: 5.34.8 bullmq: 5.34.8
@ -9759,7 +9681,7 @@ snapshots:
- supports-color - supports-color
- utf-8-validate - utf-8-validate
'@nestjs/schedule@4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))': '@nestjs/schedule@4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)':
dependencies: dependencies:
'@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)
'@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)
@ -9777,7 +9699,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- chokidar - chokidar
'@nestjs/testing@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15))': '@nestjs/testing@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-express@10.4.15)':
dependencies: dependencies:
'@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)
'@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)
@ -12118,11 +12040,6 @@ snapshots:
d3-selection: 3.0.0 d3-selection: 3.0.0
d3-transition: 3.0.1(d3-selection@3.0.0) d3-transition: 3.0.1(d3-selection@3.0.0)
dagre@0.8.5:
dependencies:
graphlib: 2.1.8
lodash: 4.17.21
dargs@7.0.0: {} dargs@7.0.0: {}
date-fns@2.30.0: date-fns@2.30.0:
@ -12984,10 +12901,6 @@ snapshots:
graphemer@1.4.0: {} graphemer@1.4.0: {}
graphlib@2.1.8:
dependencies:
lodash: 4.17.21
hard-rejection@2.1.0: {} hard-rejection@2.1.0: {}
has-flag@4.0.0: {} has-flag@4.0.0: {}
@ -14872,11 +14785,6 @@ snapshots:
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
react-hotkeys-hook@4.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
dependencies:
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
react-is@16.13.1: {} react-is@16.13.1: {}
react-is@18.3.1: {} react-is@18.3.1: {}
@ -16106,9 +16014,3 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/react': 18.2.38 '@types/react': 18.2.38
react: 18.2.0 react: 18.2.0
zustand@5.0.3(@types/react@18.2.38)(react@18.2.0)(use-sync-external-store@1.4.0(react@18.2.0)):
optionalDependencies:
'@types/react': 18.2.38
react: 18.2.0
use-sync-external-store: 1.4.0(react@18.2.0)

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const r=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:40,height:40,viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M20 2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4l4 4l4-4h4a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2m-8 2.3c1.5 0 2.7 1.2 2.7 2.7S13.5 9.7 12 9.7S9.3 8.5 9.3 7s1.2-2.7 2.7-2.7M18 15H6v-.9c0-2 4-3.1 6-3.1s6 1.1 6 3.1z"}));export{r as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const h=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"M11 13H5v-2h6V5h2v6h6v2h-6v6h-2z"}));export{h as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const l=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"M12 23C6.443 21.765 2 16.522 2 11V5l10-4l10 4v6c0 5.524-4.443 10.765-10 12M4 6v5a10.58 10.58 0 0 0 8 10a10.58 10.58 0 0 0 8-10V6l-8-3Z"}),e.createElement("circle",{cx:12,cy:8.5,r:2.5,fill:"currentColor"}),e.createElement("path",{fill:"currentColor",d:"M7 15a5.78 5.78 0 0 0 5 3a5.78 5.78 0 0 0 5-3c-.025-1.896-3.342-3-5-3c-1.667 0-4.975 1.104-5 3"}));export{l as default};

View File

@ -1 +0,0 @@
import{r as l}from"./index-De5TXRhh.js";const h=t=>l.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},l.createElement("path",{fill:"currentColor",d:"m6.923 13.442l1.848-4.75H5.038l-1.267 1.904H3.02l.827-2.865l-.827-2.885h.752L5.04 6.75h3.73L6.923 2h1l3.335 4.75h3.146q.413 0 .697.284q.284.283.284.697t-.284.687q-.284.274-.697.274h-3.146l-3.335 4.75zM16.096 22l-3.335-4.75H9.617q-.414 0-.698-.284q-.283-.283-.283-.697t.283-.697t.698-.284h3.146l3.334-4.73h1l-1.848 4.73h3.733l1.267-1.884H21l-.827 2.865l.827 2.885h-.752l-1.267-1.904h-3.733L17.096 22z"}));export{h as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const h=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M4.5 20q-.213 0-.356-.144T4 19.499t.144-.356T4.5 19h15q.213 0 .356.144t.144.357t-.144.356T19.5 20zm4-3.75q-.213 0-.356-.144T8 15.749t.144-.356t.356-.143h7q.213 0 .356.144t.144.357t-.144.356t-.356.143zm-4-3.75q-.213 0-.356-.144T4 11.999t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm4-3.75q-.213 0-.356-.144T8 8.249t.144-.356t.356-.143h7q.213 0 .356.144t.144.357t-.144.356t-.356.143zM4.5 5q-.213 0-.356-.144T4 4.499t.144-.356T4.5 4h15q.213 0 .356.144t.144.357t-.144.356T19.5 5z"}));export{h as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const h=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M4.5 20q-.213 0-.356-.144T4 19.499t.144-.356T4.5 19h15q.213 0 .356.144t.144.357t-.144.356T19.5 20zm0-3.75q-.213 0-.356-.144T4 15.749t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm0-3.75q-.213 0-.356-.144T4 11.999t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm0-3.75q-.213 0-.356-.144T4 8.249t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zM4.5 5q-.213 0-.356-.144T4 4.499t.144-.356T4.5 4h15q.213 0 .356.144t.144.357t-.144.356T19.5 5z"}));export{h as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const h=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M4.5 20q-.213 0-.356-.144T4 19.499t.144-.356T4.5 19h15q.213 0 .356.144t.144.357t-.144.356T19.5 20zm0-3.75q-.213 0-.356-.144T4 15.749t.144-.356t.356-.143h9q.213 0 .356.144t.144.357t-.144.356t-.356.143zm0-3.75q-.213 0-.356-.144T4 11.999t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm0-3.75q-.213 0-.356-.144T4 8.249t.144-.356t.356-.143h9q.213 0 .356.144t.144.357t-.144.356t-.356.143zM4.5 5q-.213 0-.356-.144T4 4.499t.144-.356T4.5 4h15q.213 0 .356.144t.144.357t-.144.356T19.5 5z"}));export{h as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const h=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M4.5 5q-.213 0-.356-.144T4 4.499t.144-.356T4.5 4h15q.213 0 .356.144t.144.357t-.144.356T19.5 5zm6 3.75q-.213 0-.356-.144T10 8.249t.144-.356t.356-.143h9q.213 0 .356.144t.144.357t-.144.356t-.356.143zm-6 3.75q-.213 0-.356-.144T4 11.999t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm6 3.75q-.213 0-.356-.144T10 15.749t.144-.356t.356-.143h9q.213 0 .356.144t.144.357t-.144.356t-.356.143zM4.5 20q-.213 0-.356-.144T4 19.499t.144-.356T4.5 19h15q.213 0 .356.144t.144.357t-.144.356T19.5 20z"}));export{h as default};

View File

@ -1 +0,0 @@
import{r as l}from"./index-De5TXRhh.js";const r=t=>l.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},l.createElement("path",{fill:"currentColor",d:"m23 12l-2.44-2.78l.34-3.68l-3.61-.82l-1.89-3.18L12 3L8.6 1.54L6.71 4.72l-3.61.81l.34 3.68L1 12l2.44 2.78l-.34 3.69l3.61.82l1.89 3.18L12 21l3.4 1.46l1.89-3.18l3.61-.82l-.34-3.68zm-13 5l-4-4l1.41-1.41L10 14.17l6.59-6.59L18 9z"}));export{r as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const l=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"m11.565 13.873l-2.677-2.677q-.055-.055-.093-.129q-.037-.073-.037-.157q0-.168.11-.289q.112-.121.294-.121h5.677q.181 0 .292.124t.111.288q0 .042-.13.284l-2.677 2.677q-.093.093-.2.143t-.235.05t-.235-.05t-.2-.143"}));export{l as default};

View File

@ -1 +0,0 @@
import{r as l}from"./index-De5TXRhh.js";const t=a=>l.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:40,height:40,viewBox:"0 0 36 36",...a},l.createElement("path",{fill:"currentColor",d:"m33.53 18.76l-6.93-3.19V6.43a1 1 0 0 0-.6-.9l-7.5-3.45a1 1 0 0 0-.84 0l-7.5 3.45a1 1 0 0 0-.58.91v9.14l-6.9 3.18a1 1 0 0 0-.58.91v9.78a1 1 0 0 0 .58.91l7.5 3.45a1 1 0 0 0 .84 0l7.08-3.26l7.08 3.26a1 1 0 0 0 .84 0l7.5-3.45a1 1 0 0 0 .58-.91v-9.78a1 1 0 0 0-.57-.91M25.61 22l-5.11-2.33l5.11-2.35l5.11 2.35Zm-1-6.44l-6.44 3v-7.69a1 1 0 0 0 .35-.08L24.6 8v7.58ZM18.1 4.08l5.11 2.35l-5.11 2.35L13 6.43Zm-7.5 13.23l5.11 2.35L10.6 22l-5.11-2.33Zm6.5 11.49l-6.5 3v-7.69A1 1 0 0 0 11 24l6.08-2.8Zm15 0l-6.46 3v-7.69A1 1 0 0 0 26 24l6.08-2.8Z",className:"clr-i-solid clr-i-solid-path-1"}),l.createElement("path",{fill:"none",d:"M0 0h36v36H0z"}));export{t as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const r=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M8.916 18.25q-.441 0-.74-.299t-.299-.74V6.79q0-.441.299-.74t.74-.299h3.159q1.433 0 2.529.904T15.7 9.006q0 .967-.508 1.693t-1.257 1.065q.913.255 1.55 1.073t.638 1.97q0 1.61-1.202 2.527q-1.202.916-2.646.916zm.236-1.184h3.062q1.161 0 1.875-.7q.715-.699.715-1.627q0-.93-.714-1.629q-.715-.698-1.894-.698H9.152zm0-5.816h2.864q.997 0 1.69-.617t.692-1.546q0-.947-.704-1.553q-.704-.605-1.667-.605H9.152z"}));export{r as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const l=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 16 16",...t},e.createElement("path",{fill:"currentColor",fillRule:"evenodd",d:"M6.705 11.823a.73.73 0 0 1-1.205-.552V4.729a.73.73 0 0 1 1.205-.552L10.214 7.2a1 1 0 0 1 .347.757v.084a1 1 0 0 1-.347.757z",clipRule:"evenodd"}));export{l as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const r=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"M11 13.5v8H3v-8zm-2 2H5v4h4zM12 2l5.5 9h-11zm0 3.86L10.08 9h3.84zM17.5 13c2.5 0 4.5 2 4.5 4.5S20 22 17.5 22S13 20 13 17.5s2-4.5 4.5-4.5m0 2a2.5 2.5 0 0 0-2.5 2.5a2.5 2.5 0 0 0 2.5 2.5a2.5 2.5 0 0 0 2.5-2.5a2.5 2.5 0 0 0-2.5-2.5"}));export{r as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const l=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"m9.55 18l-5.7-5.7l1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"}));export{l as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const o=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 48 48",...t},e.createElement("g",{fill:"none",stroke:"currentColor",strokeLinejoin:"round",strokeWidth:4},e.createElement("path",{d:"M24 44a19.94 19.94 0 0 0 14.142-5.858A19.94 19.94 0 0 0 44 24a19.94 19.94 0 0 0-5.858-14.142A19.94 19.94 0 0 0 24 4A19.94 19.94 0 0 0 9.858 9.858A19.94 19.94 0 0 0 4 24a19.94 19.94 0 0 0 5.858 14.142A19.94 19.94 0 0 0 24 44Z"}),e.createElement("path",{strokeLinecap:"round",d:"m16 24l6 6l12-12"})));export{o as default};

View File

@ -1 +0,0 @@
import{r as a}from"./index-De5TXRhh.js";const h=t=>a.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:40,height:40,viewBox:"0 0 24 24",...t},a.createElement("path",{fill:"currentColor",d:"M13.75 2.25a.75.75 0 0 1 .75.75v4A.75.75 0 0 1 13 7V5.75H3a.75.75 0 0 1 0-1.5h10V3a.75.75 0 0 1 .75-.75M17.25 5a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1-.75-.75m-6.5 4.25a.75.75 0 0 1 .75.75v1.25H21a.75.75 0 0 1 0 1.5h-9.5V14a.75.75 0 0 1-1.5 0v-4a.75.75 0 0 1 .75-.75M2.25 12a.75.75 0 0 1 .75-.75h4a.75.75 0 0 1 0 1.5H3a.75.75 0 0 1-.75-.75m11.5 4.25a.75.75 0 0 1 .75.75v4a.75.75 0 0 1-1.5 0v-1.25H3a.75.75 0 0 1 0-1.5h10V17a.75.75 0 0 1 .75-.75m3.5 2.75a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1-.75-.75"}));export{h as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const h=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M5.73 15.885h12.54v-1H5.73zm0-3.385h12.54v-1H5.73zm0-3.384h8.77v-1H5.73zM4.616 19q-.69 0-1.153-.462T3 17.384V6.616q0-.691.463-1.153T4.615 5h14.77q.69 0 1.152.463T21 6.616v10.769q0 .69-.463 1.153T19.385 19zm0-1h14.77q.23 0 .423-.192t.192-.424V6.616q0-.231-.192-.424T19.385 6H4.615q-.23 0-.423.192T4 6.616v10.769q0 .23.192.423t.423.192M4 18V6z"}));export{h as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const q=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M9.116 17q-.691 0-1.153-.462T7.5 15.385V4.615q0-.69.463-1.153T9.116 3h7.769q.69 0 1.153.462t.462 1.153v10.77q0 .69-.462 1.152T16.884 17zm0-1h7.769q.23 0 .423-.192t.192-.423V4.615q0-.23-.192-.423T16.884 4H9.116q-.231 0-.424.192t-.192.423v10.77q0 .23.192.423t.423.192m-3 4q-.69 0-1.153-.462T4.5 18.385V6.615h1v11.77q0 .23.192.423t.423.192h8.77v1zM8.5 16V4z"}));export{q as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const l=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 256 256",...t},e.createElement("g",{fill:"currentColor"},e.createElement("path",{d:"M128 129.09V232a8 8 0 0 1-3.84-1l-88-48.16a8 8 0 0 1-4.16-7V80.2a8 8 0 0 1 .7-3.27Z",opacity:.2}),e.createElement("path",{d:"m223.68 66.15l-88-48.15a15.88 15.88 0 0 0-15.36 0l-88 48.17a16 16 0 0 0-8.32 14v95.64a16 16 0 0 0 8.32 14l88 48.17a15.88 15.88 0 0 0 15.36 0l88-48.17a16 16 0 0 0 8.32-14V80.18a16 16 0 0 0-8.32-14.03M128 32l80.34 44L128 120L47.66 76ZM40 90l80 43.78v85.79l-80-43.75Zm96 129.57v-85.75L216 90v85.78Z"})));export{l as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const m=h=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 2048 2048",...h},t.createElement("path",{fill:"currentColor",d:"M1792 993q60 41 107 93t81 114t50 131t18 141q0 119-45 224t-124 183t-183 123t-224 46q-91 0-176-27t-156-78t-126-122t-85-157H128V128h256V0h128v128h896V0h128v128h256zM256 256v256h1408V256h-128v128h-128V256H512v128H384V256zm643 1280q-3-31-3-64q0-86 24-167t73-153h-97v-128h128v86q41-51 91-90t108-67t121-42t128-15q100 0 192 33V640H256v896zm573 384q93 0 174-35t142-96t96-142t36-175q0-93-35-174t-96-142t-142-96t-175-36q-93 0-174 35t-142 96t-96 142t-36 175q0 93 35 174t96 142t142 96t175 36m64-512h192v128h-320v-384h128zM384 1024h128v128H384zm256 0h128v128H640zm0-256h128v128H640zm-256 512h128v128H384zm256 0h128v128H640zm384-384H896V768h128zm256 0h-128V768h128zm256 0h-128V768h128z"}));export{m as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const r=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:40,height:40,viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zM17 6H7v13h10zM9 17h2V8H9zm4 0h2V8h-2zM7 6v13z"}));export{r as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const o=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"M3 21v-4.25L17.625 2.175L21.8 6.45L7.25 21zM17.6 7.8L19 6.4L17.6 5l-1.4 1.4z"}));export{o as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const h=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"M12 4c-4.42 0-8 3.58-8 8s3.58 8 8 8s8-3.58 8-8s-3.58-8-8-8m1 13h-2v-2h2zm0-4h-2V7h2z",opacity:.3}),e.createElement("path",{fill:"currentColor",d:"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2M12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8s8 3.58 8 8s-3.58 8-8 8m-1-5h2v2h-2zm0-8h2v6h-2z"}));export{h as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const r=T=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...T},t.createElement("path",{fill:"currentColor",d:"M12 17q.425 0 .713-.288T13 16t-.288-.712T12 15t-.712.288T11 16t.288.713T12 17m-1-4h2V7h-2zm1 9q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22m0-2q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8"}));export{r as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const l=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 16 16",...t},e.createElement("path",{fill:"currentColor",d:"M12 10V8H7V6h5V4l3 3zm-1-1v4H6v3l-6-3V0h11v5h-1V1H2l4 2v9h4V9z"}));export{l as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const r=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 512 512",...t},e.createElement("path",{fill:"currentColor",d:"M472 168H40a24 24 0 0 1 0-48h432a24 24 0 0 1 0 48m-80 112H120a24 24 0 0 1 0-48h272a24 24 0 0 1 0 48m-96 112h-80a24 24 0 0 1 0-48h80a24 24 0 0 1 0 48"}));export{r as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const a=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 28 28",...t},e.createElement("path",{fill:"currentColor",d:"M13 20.5c0 2.098.862 3.995 2.25 5.357q-1.077.142-2.25.143c-5.79 0-10-2.567-10-6.285V19a3 3 0 0 1 3-3h8.5a7.47 7.47 0 0 0-1.5 4.5M13 2a6 6 0 1 1 0 12a6 6 0 0 1 0-12m14 18.5a6.5 6.5 0 1 1-13 0a6.5 6.5 0 0 1 13 0m-5.786-3.96a.742.742 0 0 0-1.428 0l-.716 2.298h-2.318c-.727 0-1.03.97-.441 1.416l1.875 1.42l-.716 2.298c-.225.721.567 1.32 1.155.875l1.875-1.42l1.875 1.42c.588.446 1.38-.154 1.155-.875l-.716-2.298l1.875-1.42c.588-.445.286-1.416-.441-1.416H21.93z"}));export{a as default};

View File

@ -1 +0,0 @@
import{r as h}from"./index-De5TXRhh.js";const v=e=>h.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},h.createElement("path",{fill:"currentColor",d:"M11.5 16V9h-3V8h7v1h-3v7zm-9.115 5.616v-4.232H4V6.616H2.385V2.385h4.23V4h10.77V2.385h4.23v4.23H20v10.77h1.616v4.23h-4.232V20H6.616v1.616zM6.615 19h10.77v-1.616H19V6.616h-1.616V5H6.616v1.616H5v10.769h1.616z"}));export{v as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const t=r=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...r},e.createElement("path",{fill:"currentColor",d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8s8 3.59 8 8s-3.59 8-8 8"}),e.createElement("circle",{cx:8,cy:14,r:2,fill:"currentColor"}),e.createElement("circle",{cx:12,cy:8,r:2,fill:"currentColor"}),e.createElement("circle",{cx:16,cy:14,r:2,fill:"currentColor"}));export{t as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const o=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("g",{fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5},e.createElement("path",{d:"M2.5 12.89H7l3-5l4 9l3-5h4.43"}),e.createElement("path",{d:"M12 21.5a9.5 9.5 0 1 0 0-19a9.5 9.5 0 0 0 0 19"})));export{o as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const o=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M12 21q-3.45 0-6.012-2.287T3.05 13H5.1q.35 2.6 2.313 4.3T12 19q2.925 0 4.963-2.037T19 12t-2.037-4.962T12 5q-1.725 0-3.225.8T6.25 8H9v2H3V4h2v2.35q1.275-1.6 3.113-2.475T12 3q1.875 0 3.513.713t2.85 1.924t1.925 2.85T21 12t-.712 3.513t-1.925 2.85t-2.85 1.925T12 21m2.8-4.8L11 12.4V7h2v4.6l3.2 3.2z"}));export{o as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const r=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:40,height:40,viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M12 3L2 12h3v8h6v-6h2v6h6v-8h3zm5 15h-2v-6H9v6H7v-7.81l5-4.5l5 4.5z"}),t.createElement("path",{fill:"currentColor",d:"M7 10.19V18h2v-6h6v6h2v-7.81l-5-4.5z",opacity:.3}));export{r as default};

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const o=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M5.5 12.5q-.213 0-.356-.144T5 11.999t.144-.356t.356-.143h13q.213 0 .356.144t.144.357t-.144.356t-.356.143z"}));export{o as default};

View File

@ -1 +0,0 @@
import{r as e}from"./index-De5TXRhh.js";const r=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 50 50",...t},e.createElement("path",{fill:"currentColor",d:"M39 38H11c-1.7 0-3-1.3-3-3V15c0-1.7 1.3-3 3-3h28c1.7 0 3 1.3 3 3v20c0 1.7-1.3 3-3 3M11 14c-.6 0-1 .4-1 1v20c0 .6.4 1 1 1h28c.6 0 1-.4 1-1V15c0-.6-.4-1-1-1z"}),e.createElement("path",{fill:"currentColor",d:"M30 24c-2.2 0-4-1.8-4-4s1.8-4 4-4s4 1.8 4 4s-1.8 4-4 4m0-6c-1.1 0-2 .9-2 2s.9 2 2 2s2-.9 2-2s-.9-2-2-2m5.3 19.7L19 22.4L9.7 31l-1.4-1.4l10.7-10l17.7 16.7z"}),e.createElement("path",{fill:"currentColor",d:"M40.4 32.7L35 28.3L30.5 32l-1.3-1.6l5.8-4.7l6.6 5.4z"}));export{r as default};

View File

@ -1 +0,0 @@
import{r as l}from"./index-De5TXRhh.js";const a=e=>l.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},l.createElement("g",{fill:"none",fillRule:"evenodd"},l.createElement("path",{d:"m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"}),l.createElement("path",{fill:"currentColor",d:"M5.83 5.106A2 2 0 0 1 7.617 4h8.764a2 2 0 0 1 1.789 1.106l3.512 7.025a3 3 0 0 1 .318 1.34V19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-5.528a3 3 0 0 1 .317-1.341zM16.381 6H7.618L4.12 13H7.5A1.5 1.5 0 0 1 9 14.5v1a.5.5 0 0 0 .5.5h5a.5.5 0 0 0 .5-.5v-1a1.5 1.5 0 0 1 1.5-1.5h3.38z"})));export{a as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
import{r as t}from"./index-De5TXRhh.js";const l=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M6.346 18.25q-.234 0-.396-.162t-.161-.397t.161-.396t.396-.16h3.077l3.48-10.27H9.828q-.234 0-.396-.162t-.162-.397t.162-.395t.396-.161h7.192q.235 0 .396.162t.162.397t-.162.396q-.161.16-.396.16h-2.961l-3.481 10.27h2.962q.234 0 .395.162t.162.397t-.162.396t-.395.16z"}));export{l as default};

Some files were not shown because too many files have changed in this diff Show More