0.0.4.0
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@
|
||||
"/members/[id]/page": "app/members/[id]/page.js",
|
||||
"/members/page": "app/members/page.js",
|
||||
"/page": "app/page.js",
|
||||
"/relationship-test/page": "app/relationship-test/page.js",
|
||||
"/timeline/page": "app/timeline/page.js",
|
||||
"/tree/page": "app/tree/page.js"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
var R=require("../../chunks/ssr/[turbopack]_runtime.js")("server/app/relationship-test/page.js")
|
||||
R.c("server/chunks/ssr/4e98a_next_dist_429ef594._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__297e3b80._.js")
|
||||
R.c("server/chunks/ssr/4e98a_next_dist_0643e073._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__7f148858._.js")
|
||||
R.c("server/chunks/ssr/4e98a_next_dist_client_components_builtin_global-error_196f2367.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__b37c7274._.js")
|
||||
R.c("server/chunks/ssr/Documents_go-new_chinese-family-tree_app_loading_tsx_b1f283e0._.js")
|
||||
R.c("server/chunks/ssr/4e98a_next_dist_client_components_1ee43648._.js")
|
||||
R.c("server/chunks/ssr/4e98a_next_dist_client_components_builtin_forbidden_243a9611.js")
|
||||
R.c("server/chunks/ssr/4e98a_next_dist_client_components_builtin_unauthorized_719c1458.js")
|
||||
R.c("server/chunks/ssr/168ba__next-internal_server_app_relationship-test_page_actions_40826806.js")
|
||||
R.m("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/esm/build/templates/app-page.js?page=/relationship-test/page { GLOBAL_ERROR_MODULE => \"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/client/components/builtin/global-error.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_0 => \"[project]/Documents/go-new/chinese-family-tree/app/layout.tsx [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_1 => \"[project]/Documents/go-new/chinese-family-tree/app/loading.tsx [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_2 => \"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/client/components/builtin/not-found.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_3 => \"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/client/components/builtin/forbidden.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_4 => \"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/client/components/builtin/unauthorized.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_5 => \"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/client/components/builtin/global-error.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_6 => \"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx [app-rsc] (ecmascript, Next.js Server Component)\" } [app-rsc] (ecmascript)")
|
||||
module.exports=R.m("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/esm/build/templates/app-page.js?page=/relationship-test/page { GLOBAL_ERROR_MODULE => \"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/client/components/builtin/global-error.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_0 => \"[project]/Documents/go-new/chinese-family-tree/app/layout.tsx [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_1 => \"[project]/Documents/go-new/chinese-family-tree/app/loading.tsx [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_2 => \"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/client/components/builtin/not-found.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_3 => \"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/client/components/builtin/forbidden.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_4 => \"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/client/components/builtin/unauthorized.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_5 => \"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/client/components/builtin/global-error.js [app-rsc] (ecmascript, Next.js Server Component)\", MODULE_6 => \"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx [app-rsc] (ecmascript, Next.js Server Component)\" } [app-rsc] (ecmascript)").exports
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"/relationship-test/page": "app/relationship-test/page.js"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"polyfillFiles": [
|
||||
"static/chunks/4e98a_next_dist_build_polyfills_polyfill-nomodule.js"
|
||||
],
|
||||
"lowPriorityFiles": [],
|
||||
"rootMainFiles": [
|
||||
"static/chunks/[turbopack]_browser_dev_hmr-client_hmr-client_ts_67e3ae72._.js",
|
||||
"static/chunks/4e98a_next_dist_compiled_react-dom_da552622._.js",
|
||||
"static/chunks/4e98a_next_dist_compiled_react-server-dom-turbopack_c5146742._.js",
|
||||
"static/chunks/4e98a_next_dist_compiled_next-devtools_index_59922e46.js",
|
||||
"static/chunks/4e98a_next_dist_compiled_21c48460._.js",
|
||||
"static/chunks/4e98a_next_dist_client_d594727a._.js",
|
||||
"static/chunks/4e98a_next_dist_24912bf1._.js",
|
||||
"static/chunks/6704b_@swc_helpers_cjs_8771abe4._.js",
|
||||
"static/chunks/Documents_go-new_chinese-family-tree_a0ff3932._.js",
|
||||
"static/chunks/turbopack-Documents_go-new_chinese-family-tree_b39b5e67._.js"
|
||||
],
|
||||
"pages": {},
|
||||
"ampFirstPages": []
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"pages": {},
|
||||
"app": {
|
||||
"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page": [
|
||||
"static/media/caa3a2e1cccd8315-s.p.853070df.woff2",
|
||||
"static/media/797e433ab948586e-s.p.dbea232f.woff2"
|
||||
]
|
||||
},
|
||||
"appUsingSizeAdjust": true,
|
||||
"pagesUsingSizeAdjust": false
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"node": {},
|
||||
"edge": {}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+7
@@ -0,0 +1,7 @@
|
||||
module.exports = [
|
||||
"[project]/Documents/go-new/chinese-family-tree/.next-internal/server/app/relationship-test/page/actions.js [app-rsc] (server actions loader, ecmascript)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
}),
|
||||
];
|
||||
|
||||
//# sourceMappingURL=168ba__next-internal_server_app_relationship-test_page_actions_40826806.js.map
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": [
|
||||
{"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -2333,7 +2333,7 @@ function TreePage() {
|
||||
children: [
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$site$2d$header$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["SiteHeader"], {}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 188,
|
||||
lineNumber: 191,
|
||||
columnNumber: 9
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -2341,13 +2341,13 @@ function TreePage() {
|
||||
children: "暂无家族树数据"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 189,
|
||||
lineNumber: 192,
|
||||
columnNumber: 9
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 187,
|
||||
lineNumber: 190,
|
||||
columnNumber: 7
|
||||
}, this);
|
||||
}
|
||||
@@ -2356,7 +2356,7 @@ function TreePage() {
|
||||
children: [
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$site$2d$header$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["SiteHeader"], {}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 196,
|
||||
lineNumber: 199,
|
||||
columnNumber: 7
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -2373,7 +2373,7 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 203,
|
||||
lineNumber: 206,
|
||||
columnNumber: 15
|
||||
}, this),
|
||||
viewMode === 'traditional' ? '传统视图' : 'D3家谱图',
|
||||
@@ -2381,18 +2381,18 @@ function TreePage() {
|
||||
className: "h-3 w-3"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 205,
|
||||
lineNumber: 208,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 202,
|
||||
lineNumber: 205,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 201,
|
||||
lineNumber: 204,
|
||||
columnNumber: 11
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$dropdown$2d$menu$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["DropdownMenuContent"], {
|
||||
@@ -2413,7 +2413,7 @@ function TreePage() {
|
||||
children: "传统家谱视图"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 218,
|
||||
lineNumber: 221,
|
||||
columnNumber: 17
|
||||
}, this),
|
||||
viewMode === 'traditional' && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
|
||||
@@ -2421,18 +2421,18 @@ function TreePage() {
|
||||
children: "✓"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 219,
|
||||
lineNumber: 222,
|
||||
columnNumber: 48
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 217,
|
||||
lineNumber: 220,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 209,
|
||||
lineNumber: 212,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$dropdown$2d$menu$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["DropdownMenuItem"], {
|
||||
@@ -2449,7 +2449,7 @@ function TreePage() {
|
||||
children: "D3 家谱图"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 231,
|
||||
lineNumber: 234,
|
||||
columnNumber: 17
|
||||
}, this),
|
||||
viewMode === 'd3-org-chart' && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
|
||||
@@ -2457,35 +2457,35 @@ function TreePage() {
|
||||
children: "✓"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 232,
|
||||
lineNumber: 235,
|
||||
columnNumber: 49
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 230,
|
||||
lineNumber: 233,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 222,
|
||||
lineNumber: 225,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 208,
|
||||
lineNumber: 211,
|
||||
columnNumber: 11
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 200,
|
||||
lineNumber: 203,
|
||||
columnNumber: 9
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 199,
|
||||
lineNumber: 202,
|
||||
columnNumber: 7
|
||||
}, this),
|
||||
viewMode === 'traditional' ? /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -2502,12 +2502,12 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 244,
|
||||
lineNumber: 247,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 243,
|
||||
lineNumber: 246,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["Button"], {
|
||||
@@ -2518,12 +2518,12 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 247,
|
||||
lineNumber: 250,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 246,
|
||||
lineNumber: 249,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["Button"], {
|
||||
@@ -2537,19 +2537,19 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 250,
|
||||
lineNumber: 253,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 249,
|
||||
lineNumber: 252,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
className: "h-px bg-border my-1"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 252,
|
||||
lineNumber: 255,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["Button"], {
|
||||
@@ -2561,18 +2561,18 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 254,
|
||||
lineNumber: 257,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 253,
|
||||
lineNumber: 256,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 242,
|
||||
lineNumber: 245,
|
||||
columnNumber: 11
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -2593,23 +2593,23 @@ function TreePage() {
|
||||
rootId: treeData.rootId
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 275,
|
||||
lineNumber: 278,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 267,
|
||||
lineNumber: 270,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 259,
|
||||
lineNumber: 262,
|
||||
columnNumber: 11
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 240,
|
||||
lineNumber: 243,
|
||||
columnNumber: 9
|
||||
}, this) : /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
className: "flex-1 relative",
|
||||
@@ -2624,23 +2624,6 @@ function TreePage() {
|
||||
title: "展开全部",
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$lucide$2d$react$40$0$2e$454$2e$0_react$40$19$2e$2$2e$0$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$zoom$2d$in$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__$3c$export__default__as__ZoomIn$3e$__["ZoomIn"], {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 284,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 283,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["Button"], {
|
||||
variant: "outline",
|
||||
size: "icon",
|
||||
onClick: ()=>d3ChartRef.current?.collapseAll(),
|
||||
title: "折叠全部",
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$lucide$2d$react$40$0$2e$454$2e$0_react$40$19$2e$2$2e$0$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$zoom$2d$out$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__$3c$export__default__as__ZoomOut$3e$__["ZoomOut"], {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 287,
|
||||
@@ -2654,9 +2637,9 @@ function TreePage() {
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["Button"], {
|
||||
variant: "outline",
|
||||
size: "icon",
|
||||
onClick: ()=>d3ChartRef.current?.fitView(),
|
||||
title: "适应视图",
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$lucide$2d$react$40$0$2e$454$2e$0_react$40$19$2e$2$2e$0$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$move$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__$3c$export__default__as__Move$3e$__["Move"], {
|
||||
onClick: ()=>d3ChartRef.current?.collapseAll(),
|
||||
title: "折叠全部",
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$lucide$2d$react$40$0$2e$454$2e$0_react$40$19$2e$2$2e$0$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$zoom$2d$out$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__$3c$export__default__as__ZoomOut$3e$__["ZoomOut"], {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
@@ -2668,11 +2651,28 @@ function TreePage() {
|
||||
lineNumber: 289,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["Button"], {
|
||||
variant: "outline",
|
||||
size: "icon",
|
||||
onClick: ()=>d3ChartRef.current?.fitView(),
|
||||
title: "适应视图",
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$lucide$2d$react$40$0$2e$454$2e$0_react$40$19$2e$2$2e$0$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$move$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__$3c$export__default__as__Move$3e$__["Move"], {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 293,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 292,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
className: "h-px bg-border my-1"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 292,
|
||||
lineNumber: 295,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["Button"], {
|
||||
@@ -2684,18 +2684,18 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 294,
|
||||
lineNumber: 297,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 293,
|
||||
lineNumber: 296,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 282,
|
||||
lineNumber: 285,
|
||||
columnNumber: 11
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -2707,24 +2707,24 @@ function TreePage() {
|
||||
onMemberClick: (id)=>router.push(`/members/${id}`)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 299,
|
||||
lineNumber: 302,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 298,
|
||||
lineNumber: 301,
|
||||
columnNumber: 11
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 280,
|
||||
lineNumber: 283,
|
||||
columnNumber: 9
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 195,
|
||||
lineNumber: 198,
|
||||
columnNumber: 5
|
||||
}, this);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,58 @@
|
||||
module.exports = [
|
||||
"[externals]/next/dist/shared/lib/no-fallback-error.external.js [external] (next/dist/shared/lib/no-fallback-error.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
const mod = __turbopack_context__.x("next/dist/shared/lib/no-fallback-error.external.js", () => require("next/dist/shared/lib/no-fallback-error.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/app/layout.tsx [app-rsc] (ecmascript, Next.js Server Component)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.n(__turbopack_context__.i("[project]/Documents/go-new/chinese-family-tree/app/layout.tsx [app-rsc] (ecmascript)"));
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/app/loading.tsx [app-rsc] (ecmascript, Next.js Server Component)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.n(__turbopack_context__.i("[project]/Documents/go-new/chinese-family-tree/app/loading.tsx [app-rsc] (ecmascript)"));
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx [app-rsc] (client reference proxy) <module evaluation>", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
// This file is generated by next-core EcmascriptClientReferenceModule.
|
||||
__turbopack_context__.s([
|
||||
"default",
|
||||
()=>__TURBOPACK__default__export__
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$rsc$2f$react$2d$server$2d$dom$2d$turbopack$2d$server$2e$js__$5b$app$2d$rsc$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-turbopack-server.js [app-rsc] (ecmascript)");
|
||||
;
|
||||
const __TURBOPACK__default__export__ = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$rsc$2f$react$2d$server$2d$dom$2d$turbopack$2d$server$2e$js__$5b$app$2d$rsc$5d$__$28$ecmascript$29$__["registerClientReference"])(function() {
|
||||
throw new Error("Attempted to call the default export of [project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx <module evaluation> from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.");
|
||||
}, "[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx <module evaluation>", "default");
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx [app-rsc] (client reference proxy)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
// This file is generated by next-core EcmascriptClientReferenceModule.
|
||||
__turbopack_context__.s([
|
||||
"default",
|
||||
()=>__TURBOPACK__default__export__
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$rsc$2f$react$2d$server$2d$dom$2d$turbopack$2d$server$2e$js__$5b$app$2d$rsc$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/next@16.0.3_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/next/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-turbopack-server.js [app-rsc] (ecmascript)");
|
||||
;
|
||||
const __TURBOPACK__default__export__ = (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$rsc$2f$react$2d$server$2d$dom$2d$turbopack$2d$server$2e$js__$5b$app$2d$rsc$5d$__$28$ecmascript$29$__["registerClientReference"])(function() {
|
||||
throw new Error("Attempted to call the default export of [project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.");
|
||||
}, "[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx", "default");
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx [app-rsc] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$app$2f$relationship$2d$test$2f$page$2e$tsx__$5b$app$2d$rsc$5d$__$28$client__reference__proxy$29$__$3c$module__evaluation$3e$__ = __turbopack_context__.i("[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx [app-rsc] (client reference proxy) <module evaluation>");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$app$2f$relationship$2d$test$2f$page$2e$tsx__$5b$app$2d$rsc$5d$__$28$client__reference__proxy$29$__ = __turbopack_context__.i("[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx [app-rsc] (client reference proxy)");
|
||||
;
|
||||
__turbopack_context__.n(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$app$2f$relationship$2d$test$2f$page$2e$tsx__$5b$app$2d$rsc$5d$__$28$client__reference__proxy$29$__);
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx [app-rsc] (ecmascript, Next.js Server Component)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.n(__turbopack_context__.i("[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx [app-rsc] (ecmascript)"));
|
||||
}),
|
||||
];
|
||||
|
||||
//# sourceMappingURL=%5Broot-of-the-server%5D__297e3b80._.js.map
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": [
|
||||
{"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["file:///Users/freedak/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx/__nextjs-internal-proxy.mjs"],"sourcesContent":["// This file is generated by next-core EcmascriptClientReferenceModule.\nimport { registerClientReference } from \"react-server-dom-turbopack/server\";\nexport default registerClientReference(\n function() { throw new Error(\"Attempted to call the default export of [project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx <module evaluation> from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx <module evaluation>\",\n \"default\",\n);\n"],"names":[],"mappings":"AAAA,uEAAuE;;;;;AACvE;;uCACe,IAAA,8bAAuB,EAClC;IAAa,MAAM,IAAI,MAAM;AAAuU,GACpW,qGACA","ignoreList":[0]}},
|
||||
{"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":["file:///Users/freedak/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx/__nextjs-internal-proxy.mjs"],"sourcesContent":["// This file is generated by next-core EcmascriptClientReferenceModule.\nimport { registerClientReference } from \"react-server-dom-turbopack/server\";\nexport default registerClientReference(\n function() { throw new Error(\"Attempted to call the default export of [project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page.tsx\",\n \"default\",\n);\n"],"names":[],"mappings":"AAAA,uEAAuE;;;;;AACvE;;uCACe,IAAA,8bAAuB,EAClC;IAAa,MAAM,IAAI,MAAM;AAAmT,GAChV,iFACA","ignoreList":[0]}},
|
||||
{"offset": {"line": 46, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
+7231
File diff suppressed because it is too large
Load Diff
+6
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
self.__NEXT_FONT_MANIFEST="{\n \"app\": {\n \"[project]/Documents/go-new/chinese-family-tree/app/auth/signin/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/members/[id]/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/members/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/timeline/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/tree/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ]\n },\n \"appUsingSizeAdjust\": true,\n \"pages\": {},\n \"pagesUsingSizeAdjust\": false\n}"
|
||||
self.__NEXT_FONT_MANIFEST="{\n \"app\": {\n \"[project]/Documents/go-new/chinese-family-tree/app/auth/signin/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/members/[id]/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/members/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/timeline/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ],\n \"[project]/Documents/go-new/chinese-family-tree/app/tree/page\": [\n \"static/media/caa3a2e1cccd8315-s.p.853070df.woff2\",\n \"static/media/797e433ab948586e-s.p.dbea232f.woff2\"\n ]\n },\n \"appUsingSizeAdjust\": true,\n \"pages\": {},\n \"pagesUsingSizeAdjust\": false\n}"
|
||||
@@ -16,6 +16,10 @@
|
||||
"static/media/caa3a2e1cccd8315-s.p.853070df.woff2",
|
||||
"static/media/797e433ab948586e-s.p.dbea232f.woff2"
|
||||
],
|
||||
"[project]/Documents/go-new/chinese-family-tree/app/relationship-test/page": [
|
||||
"static/media/caa3a2e1cccd8315-s.p.853070df.woff2",
|
||||
"static/media/797e433ab948586e-s.p.dbea232f.woff2"
|
||||
],
|
||||
"[project]/Documents/go-new/chinese-family-tree/app/timeline/page": [
|
||||
"static/media/caa3a2e1cccd8315-s.p.853070df.woff2",
|
||||
"static/media/797e433ab948586e-s.p.dbea232f.woff2"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
+55
@@ -98,6 +98,7 @@
|
||||
--color-yellow-400: #fac800;
|
||||
--color-yellow-800: #874b00;
|
||||
--color-yellow-900: #733e0a;
|
||||
--color-yellow-950: #432004;
|
||||
--color-green-50: #f0fdf4;
|
||||
--color-green-100: #dcfce7;
|
||||
--color-green-200: #b9f8cf;
|
||||
@@ -112,6 +113,7 @@
|
||||
--color-blue-500: #3080ff;
|
||||
--color-blue-700: #1447e6;
|
||||
--color-blue-800: #193cb8;
|
||||
--color-blue-900: #1c398e;
|
||||
--color-blue-950: #162456;
|
||||
--color-purple-50: #faf5ff;
|
||||
--color-purple-100: #f3e8ff;
|
||||
@@ -200,6 +202,7 @@
|
||||
--color-yellow-400: lab(83.2664% 8.65132 106.895);
|
||||
--color-yellow-800: lab(38.7484% 23.5833 51.4916);
|
||||
--color-yellow-900: lab(32.3865% 21.1273 38.5959);
|
||||
--color-yellow-950: lab(16.8146% 15.7422 23.1133);
|
||||
--color-green-50: lab(98.1563% -5.60117 2.75915);
|
||||
--color-green-100: lab(96.1861% -13.8464 6.52365);
|
||||
--color-green-200: lab(92.4222% -26.4702 12.9427);
|
||||
@@ -214,6 +217,7 @@
|
||||
--color-blue-500: lab(54.1736% 13.3369 -74.6839);
|
||||
--color-blue-700: lab(36.9089% 35.0961 -85.6872);
|
||||
--color-blue-800: lab(30.2514% 27.7853 -70.2699);
|
||||
--color-blue-900: lab(26.1542% 15.7545 -51.5504);
|
||||
--color-blue-950: lab(15.6723% 8.86232 -32.2945);
|
||||
--color-purple-50: lab(97.1627% 2.99937 -4.13398);
|
||||
--color-purple-100: lab(93.3333% 6.97437 -9.83434);
|
||||
@@ -2023,6 +2027,10 @@
|
||||
border-color: var(--color-blue-200);
|
||||
}
|
||||
|
||||
.border-blue-500 {
|
||||
border-color: var(--color-blue-500);
|
||||
}
|
||||
|
||||
.border-border {
|
||||
border-color: var(--border);
|
||||
}
|
||||
@@ -2861,6 +2869,10 @@
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.break-all {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.whitespace-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -3037,6 +3049,10 @@
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.text-yellow-800 {
|
||||
color: var(--color-yellow-800);
|
||||
}
|
||||
|
||||
.uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -3142,6 +3158,10 @@
|
||||
--tw-ring-color: var(--background);
|
||||
}
|
||||
|
||||
.ring-blue-200 {
|
||||
--tw-ring-color: var(--color-blue-200);
|
||||
}
|
||||
|
||||
.ring-ring\/50 {
|
||||
--tw-ring-color: var(--ring);
|
||||
}
|
||||
@@ -3742,6 +3762,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.hover\:border-blue-400:hover {
|
||||
border-color: var(--color-blue-400);
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.hover\:border-primary:hover {
|
||||
border-color: var(--primary);
|
||||
@@ -3953,6 +3979,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.hover\:shadow-lg:hover {
|
||||
--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, #0000001a), 0 4px 6px -4px var(--tw-shadow-color, #0000001a);
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.hover\:shadow-md:hover {
|
||||
--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, #0000001a), 0 2px 4px -2px var(--tw-shadow-color, #0000001a);
|
||||
@@ -5520,6 +5553,16 @@
|
||||
border-color: var(--input);
|
||||
}
|
||||
|
||||
.dark\:bg-blue-900\/20:is(.dark *) {
|
||||
background-color: #1c398e33;
|
||||
}
|
||||
|
||||
@supports (color: color-mix(in lab, red, red)) {
|
||||
.dark\:bg-blue-900\/20:is(.dark *) {
|
||||
background-color: color-mix(in oklab, var(--color-blue-900) 20%, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
.dark\:bg-blue-950:is(.dark *) {
|
||||
background-color: var(--color-blue-950);
|
||||
}
|
||||
@@ -5558,6 +5601,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.dark\:bg-yellow-950:is(.dark *) {
|
||||
background-color: var(--color-yellow-950);
|
||||
}
|
||||
|
||||
.dark\:text-blue-200:is(.dark *) {
|
||||
color: var(--color-blue-200);
|
||||
}
|
||||
@@ -5566,6 +5613,14 @@
|
||||
color: var(--muted-foreground);
|
||||
}
|
||||
|
||||
.dark\:text-yellow-200:is(.dark *) {
|
||||
color: var(--color-yellow-200);
|
||||
}
|
||||
|
||||
.dark\:ring-blue-800:is(.dark *) {
|
||||
--tw-ring-color: var(--color-blue-800);
|
||||
}
|
||||
|
||||
.dark\:ring-yellow-800:is(.dark *) {
|
||||
--tw-ring-color: var(--color-yellow-800);
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+8
@@ -0,0 +1,8 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/Documents_go-new_chinese-family-tree_38445918._.js",
|
||||
"static/chunks/a0629__pnpm_279b9260._.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
+4
-3
@@ -1,12 +1,13 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/a0629__pnpm_2f1a5cab._.js",
|
||||
"static/chunks/Documents_go-new_chinese-family-tree_ed9ee666._.js",
|
||||
"static/chunks/a0629__pnpm_c0097265._.js",
|
||||
"static/chunks/Documents_go-new_chinese-family-tree_65759bc9._.js",
|
||||
"static/chunks/3032b_dexie_2a245be4._.js",
|
||||
"static/chunks/14b10_pako_dist_pako_esm_mjs_63ae9500._.js",
|
||||
"static/chunks/0f47f_jspdf_dist_jspdf_es_min_f400e067.js",
|
||||
"static/chunks/a0629__pnpm_3724daf1._.js"
|
||||
"static/chunks/ebfed_relationship_js_dist_relationship_min_mjs_d2477a04._.js",
|
||||
"static/chunks/a0629__pnpm_a9810fcf._.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -2524,7 +2524,7 @@ function TreePage() {
|
||||
children: [
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$site$2d$header$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["SiteHeader"], {}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 188,
|
||||
lineNumber: 191,
|
||||
columnNumber: 9
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -2532,13 +2532,13 @@ function TreePage() {
|
||||
children: "暂无家族树数据"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 189,
|
||||
lineNumber: 192,
|
||||
columnNumber: 9
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 187,
|
||||
lineNumber: 190,
|
||||
columnNumber: 7
|
||||
}, this);
|
||||
}
|
||||
@@ -2547,7 +2547,7 @@ function TreePage() {
|
||||
children: [
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$site$2d$header$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["SiteHeader"], {}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 196,
|
||||
lineNumber: 199,
|
||||
columnNumber: 7
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -2564,7 +2564,7 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 203,
|
||||
lineNumber: 206,
|
||||
columnNumber: 15
|
||||
}, this),
|
||||
viewMode === 'traditional' ? '传统视图' : 'D3家谱图',
|
||||
@@ -2572,18 +2572,18 @@ function TreePage() {
|
||||
className: "h-3 w-3"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 205,
|
||||
lineNumber: 208,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 202,
|
||||
lineNumber: 205,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 201,
|
||||
lineNumber: 204,
|
||||
columnNumber: 11
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$dropdown$2d$menu$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["DropdownMenuContent"], {
|
||||
@@ -2604,7 +2604,7 @@ function TreePage() {
|
||||
children: "传统家谱视图"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 218,
|
||||
lineNumber: 221,
|
||||
columnNumber: 17
|
||||
}, this),
|
||||
viewMode === 'traditional' && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
|
||||
@@ -2612,18 +2612,18 @@ function TreePage() {
|
||||
children: "✓"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 219,
|
||||
lineNumber: 222,
|
||||
columnNumber: 48
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 217,
|
||||
lineNumber: 220,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 209,
|
||||
lineNumber: 212,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$dropdown$2d$menu$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["DropdownMenuItem"], {
|
||||
@@ -2640,7 +2640,7 @@ function TreePage() {
|
||||
children: "D3 家谱图"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 231,
|
||||
lineNumber: 234,
|
||||
columnNumber: 17
|
||||
}, this),
|
||||
viewMode === 'd3-org-chart' && /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
|
||||
@@ -2648,35 +2648,35 @@ function TreePage() {
|
||||
children: "✓"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 232,
|
||||
lineNumber: 235,
|
||||
columnNumber: 49
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 230,
|
||||
lineNumber: 233,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 222,
|
||||
lineNumber: 225,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 208,
|
||||
lineNumber: 211,
|
||||
columnNumber: 11
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 200,
|
||||
lineNumber: 203,
|
||||
columnNumber: 9
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 199,
|
||||
lineNumber: 202,
|
||||
columnNumber: 7
|
||||
}, this),
|
||||
viewMode === 'traditional' ? /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -2693,12 +2693,12 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 244,
|
||||
lineNumber: 247,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 243,
|
||||
lineNumber: 246,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
|
||||
@@ -2709,12 +2709,12 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 247,
|
||||
lineNumber: 250,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 246,
|
||||
lineNumber: 249,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
|
||||
@@ -2728,19 +2728,19 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 250,
|
||||
lineNumber: 253,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 249,
|
||||
lineNumber: 252,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
className: "h-px bg-border my-1"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 252,
|
||||
lineNumber: 255,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
|
||||
@@ -2752,18 +2752,18 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 254,
|
||||
lineNumber: 257,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 253,
|
||||
lineNumber: 256,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 242,
|
||||
lineNumber: 245,
|
||||
columnNumber: 11
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -2784,23 +2784,23 @@ function TreePage() {
|
||||
rootId: treeData.rootId
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 275,
|
||||
lineNumber: 278,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 267,
|
||||
lineNumber: 270,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 259,
|
||||
lineNumber: 262,
|
||||
columnNumber: 11
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 240,
|
||||
lineNumber: 243,
|
||||
columnNumber: 9
|
||||
}, this) : /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
className: "flex-1 relative",
|
||||
@@ -2815,23 +2815,6 @@ function TreePage() {
|
||||
title: "展开全部",
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$lucide$2d$react$40$0$2e$454$2e$0_react$40$19$2e$2$2e$0$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$zoom$2d$in$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ZoomIn$3e$__["ZoomIn"], {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 284,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 283,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
|
||||
variant: "outline",
|
||||
size: "icon",
|
||||
onClick: ()=>d3ChartRef.current?.collapseAll(),
|
||||
title: "折叠全部",
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$lucide$2d$react$40$0$2e$454$2e$0_react$40$19$2e$2$2e$0$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$zoom$2d$out$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ZoomOut$3e$__["ZoomOut"], {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 287,
|
||||
@@ -2845,9 +2828,9 @@ function TreePage() {
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
|
||||
variant: "outline",
|
||||
size: "icon",
|
||||
onClick: ()=>d3ChartRef.current?.fitView(),
|
||||
title: "适应视图",
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$lucide$2d$react$40$0$2e$454$2e$0_react$40$19$2e$2$2e$0$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$move$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Move$3e$__["Move"], {
|
||||
onClick: ()=>d3ChartRef.current?.collapseAll(),
|
||||
title: "折叠全部",
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$lucide$2d$react$40$0$2e$454$2e$0_react$40$19$2e$2$2e$0$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$zoom$2d$out$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__ZoomOut$3e$__["ZoomOut"], {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
@@ -2859,11 +2842,28 @@ function TreePage() {
|
||||
lineNumber: 289,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
|
||||
variant: "outline",
|
||||
size: "icon",
|
||||
onClick: ()=>d3ChartRef.current?.fitView(),
|
||||
title: "适应视图",
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$lucide$2d$react$40$0$2e$454$2e$0_react$40$19$2e$2$2e$0$2f$node_modules$2f$lucide$2d$react$2f$dist$2f$esm$2f$icons$2f$move$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__$3c$export__default__as__Move$3e$__["Move"], {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 293,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 292,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
className: "h-px bg-border my-1"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 292,
|
||||
lineNumber: 295,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$components$2f$ui$2f$button$2e$tsx__$5b$app$2d$client$5d$__$28$ecmascript$29$__["Button"], {
|
||||
@@ -2875,18 +2875,18 @@ function TreePage() {
|
||||
className: "h-4 w-4"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 294,
|
||||
lineNumber: 297,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 293,
|
||||
lineNumber: 296,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 282,
|
||||
lineNumber: 285,
|
||||
columnNumber: 11
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$Documents$2f$go$2d$new$2f$chinese$2d$family$2d$tree$2f$node_modules$2f2e$pnpm$2f$next$40$16$2e$0$2e$3_react$2d$dom$40$19$2e$2$2e$0_react$40$19$2e$2$2e$0_$5f$react$40$19$2e$2$2e$0$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$client$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -2898,24 +2898,24 @@ function TreePage() {
|
||||
onMemberClick: (id)=>router.push(`/members/${id}`)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 299,
|
||||
lineNumber: 302,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 298,
|
||||
lineNumber: 301,
|
||||
columnNumber: 11
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 280,
|
||||
lineNumber: 283,
|
||||
columnNumber: 9
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/Documents/go-new/chinese-family-tree/app/tree/page.tsx",
|
||||
lineNumber: 195,
|
||||
lineNumber: 198,
|
||||
columnNumber: 5
|
||||
}, this);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -182,6 +182,7 @@
|
||||
--color-yellow-400: #fac800;
|
||||
--color-yellow-800: #874b00;
|
||||
--color-yellow-900: #733e0a;
|
||||
--color-yellow-950: #432004;
|
||||
--color-green-50: #f0fdf4;
|
||||
--color-green-100: #dcfce7;
|
||||
--color-green-200: #b9f8cf;
|
||||
@@ -196,6 +197,7 @@
|
||||
--color-blue-500: #3080ff;
|
||||
--color-blue-700: #1447e6;
|
||||
--color-blue-800: #193cb8;
|
||||
--color-blue-900: #1c398e;
|
||||
--color-blue-950: #162456;
|
||||
--color-purple-50: #faf5ff;
|
||||
--color-purple-100: #f3e8ff;
|
||||
@@ -284,6 +286,7 @@
|
||||
--color-yellow-400: lab(83.2664% 8.65132 106.895);
|
||||
--color-yellow-800: lab(38.7484% 23.5833 51.4916);
|
||||
--color-yellow-900: lab(32.3865% 21.1273 38.5959);
|
||||
--color-yellow-950: lab(16.8146% 15.7422 23.1133);
|
||||
--color-green-50: lab(98.1563% -5.60117 2.75915);
|
||||
--color-green-100: lab(96.1861% -13.8464 6.52365);
|
||||
--color-green-200: lab(92.4222% -26.4702 12.9427);
|
||||
@@ -298,6 +301,7 @@
|
||||
--color-blue-500: lab(54.1736% 13.3369 -74.6839);
|
||||
--color-blue-700: lab(36.9089% 35.0961 -85.6872);
|
||||
--color-blue-800: lab(30.2514% 27.7853 -70.2699);
|
||||
--color-blue-900: lab(26.1542% 15.7545 -51.5504);
|
||||
--color-blue-950: lab(15.6723% 8.86232 -32.2945);
|
||||
--color-purple-50: lab(97.1627% 2.99937 -4.13398);
|
||||
--color-purple-100: lab(93.3333% 6.97437 -9.83434);
|
||||
@@ -2107,6 +2111,10 @@
|
||||
border-color: var(--color-blue-200);
|
||||
}
|
||||
|
||||
.border-blue-500 {
|
||||
border-color: var(--color-blue-500);
|
||||
}
|
||||
|
||||
.border-border {
|
||||
border-color: var(--border);
|
||||
}
|
||||
@@ -2945,6 +2953,10 @@
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.break-all {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.whitespace-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -3121,6 +3133,10 @@
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.text-yellow-800 {
|
||||
color: var(--color-yellow-800);
|
||||
}
|
||||
|
||||
.uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -3226,6 +3242,10 @@
|
||||
--tw-ring-color: var(--background);
|
||||
}
|
||||
|
||||
.ring-blue-200 {
|
||||
--tw-ring-color: var(--color-blue-200);
|
||||
}
|
||||
|
||||
.ring-ring\/50 {
|
||||
--tw-ring-color: var(--ring);
|
||||
}
|
||||
@@ -3826,6 +3846,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.hover\:border-blue-400:hover {
|
||||
border-color: var(--color-blue-400);
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.hover\:border-primary:hover {
|
||||
border-color: var(--primary);
|
||||
@@ -4037,6 +4063,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.hover\:shadow-lg:hover {
|
||||
--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, #0000001a), 0 4px 6px -4px var(--tw-shadow-color, #0000001a);
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.hover\:shadow-md:hover {
|
||||
--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, #0000001a), 0 2px 4px -2px var(--tw-shadow-color, #0000001a);
|
||||
@@ -5604,6 +5637,16 @@
|
||||
border-color: var(--input);
|
||||
}
|
||||
|
||||
.dark\:bg-blue-900\/20:is(.dark *) {
|
||||
background-color: #1c398e33;
|
||||
}
|
||||
|
||||
@supports (color: color-mix(in lab, red, red)) {
|
||||
.dark\:bg-blue-900\/20:is(.dark *) {
|
||||
background-color: color-mix(in oklab, var(--color-blue-900) 20%, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
.dark\:bg-blue-950:is(.dark *) {
|
||||
background-color: var(--color-blue-950);
|
||||
}
|
||||
@@ -5642,6 +5685,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.dark\:bg-yellow-950:is(.dark *) {
|
||||
background-color: var(--color-yellow-950);
|
||||
}
|
||||
|
||||
.dark\:text-blue-200:is(.dark *) {
|
||||
color: var(--color-blue-200);
|
||||
}
|
||||
@@ -5650,6 +5697,14 @@
|
||||
color: var(--muted-foreground);
|
||||
}
|
||||
|
||||
.dark\:text-yellow-200:is(.dark *) {
|
||||
color: var(--color-yellow-200);
|
||||
}
|
||||
|
||||
.dark\:ring-blue-800:is(.dark *) {
|
||||
--tw-ring-color: var(--color-blue-800);
|
||||
}
|
||||
|
||||
.dark\:ring-yellow-800:is(.dark *) {
|
||||
--tw-ring-color: var(--color-yellow-800);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,46 @@
|
||||
(globalThis.TURBOPACK || (globalThis.TURBOPACK = [])).push([typeof document === "object" ? document.currentScript : undefined,
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/html2canvas@1.4.1/node_modules/html2canvas/dist/html2canvas.js [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/fdeb9_html2canvas_dist_html2canvas_4a71f2ac.js",
|
||||
"static/chunks/fdeb9_html2canvas_dist_html2canvas_bcdbfbc4.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/html2canvas@1.4.1/node_modules/html2canvas/dist/html2canvas.js [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.mjs [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/f35fa_dompurify_dist_purify_es_mjs_8cd1474d._.js",
|
||||
"static/chunks/f35fa_dompurify_dist_purify_es_mjs_bcdbfbc4._.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.mjs [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/canvg@3.0.11/node_modules/canvg/lib/index.es.js [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/a0629__pnpm_7081c6ce._.js",
|
||||
"static/chunks/c7bc8_canvg_lib_index_es_bcdbfbc4.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/canvg@3.0.11/node_modules/canvg/lib/index.es.js [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dom-to-image-more@3.7.2/node_modules/dom-to-image-more/dist/dom-to-image-more.min.js [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/ffc37_dom-to-image-more_dist_dom-to-image-more_min_db78e443.js",
|
||||
"static/chunks/ffc37_dom-to-image-more_dist_dom-to-image-more_min_bcdbfbc4.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dom-to-image-more@3.7.2/node_modules/dom-to-image-more/dist/dom-to-image-more.min.js [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
]);
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,46 @@
|
||||
(globalThis.TURBOPACK || (globalThis.TURBOPACK = [])).push([typeof document === "object" ? document.currentScript : undefined,
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/html2canvas@1.4.1/node_modules/html2canvas/dist/html2canvas.js [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/fdeb9_html2canvas_dist_html2canvas_4a71f2ac.js",
|
||||
"static/chunks/fdeb9_html2canvas_dist_html2canvas_84e6d65c.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/html2canvas@1.4.1/node_modules/html2canvas/dist/html2canvas.js [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.mjs [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/f35fa_dompurify_dist_purify_es_mjs_8cd1474d._.js",
|
||||
"static/chunks/f35fa_dompurify_dist_purify_es_mjs_84e6d65c._.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.mjs [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/canvg@3.0.11/node_modules/canvg/lib/index.es.js [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/a0629__pnpm_7081c6ce._.js",
|
||||
"static/chunks/c7bc8_canvg_lib_index_es_84e6d65c.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/canvg@3.0.11/node_modules/canvg/lib/index.es.js [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dom-to-image-more@3.7.2/node_modules/dom-to-image-more/dist/dom-to-image-more.min.js [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/ffc37_dom-to-image-more_dist_dom-to-image-more_min_db78e443.js",
|
||||
"static/chunks/ffc37_dom-to-image-more_dist_dom-to-image-more_min_84e6d65c.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dom-to-image-more@3.7.2/node_modules/dom-to-image-more/dist/dom-to-image-more.min.js [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
]);
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,46 @@
|
||||
(globalThis.TURBOPACK || (globalThis.TURBOPACK = [])).push([typeof document === "object" ? document.currentScript : undefined,
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/html2canvas@1.4.1/node_modules/html2canvas/dist/html2canvas.js [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/fdeb9_html2canvas_dist_html2canvas_4a71f2ac.js",
|
||||
"static/chunks/fdeb9_html2canvas_dist_html2canvas_63044146.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/html2canvas@1.4.1/node_modules/html2canvas/dist/html2canvas.js [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.mjs [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/f35fa_dompurify_dist_purify_es_mjs_8cd1474d._.js",
|
||||
"static/chunks/f35fa_dompurify_dist_purify_es_mjs_63044146._.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.mjs [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/canvg@3.0.11/node_modules/canvg/lib/index.es.js [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/a0629__pnpm_7081c6ce._.js",
|
||||
"static/chunks/c7bc8_canvg_lib_index_es_63044146.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/canvg@3.0.11/node_modules/canvg/lib/index.es.js [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
"[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dom-to-image-more@3.7.2/node_modules/dom-to-image-more/dist/dom-to-image-more.min.js [app-client] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"static/chunks/ffc37_dom-to-image-more_dist_dom-to-image-more_min_db78e443.js",
|
||||
"static/chunks/ffc37_dom-to-image-more_dist_dom-to-image-more_min_63044146.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/Documents/go-new/chinese-family-tree/node_modules/.pnpm/dom-to-image-more@3.7.2/node_modules/dom-to-image-more/dist/dom-to-image-more.min.js [app-client] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
]);
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/a0629__pnpm_7081c6ce._.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/a0629__pnpm_7081c6ce._.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/a0629__pnpm_7081c6ce._.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
+7231
File diff suppressed because it is too large
Load Diff
+6
File diff suppressed because one or more lines are too long
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/f35fa_dompurify_dist_purify_es_mjs_8cd1474d._.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/f35fa_dompurify_dist_purify_es_mjs_8cd1474d._.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/f35fa_dompurify_dist_purify_es_mjs_8cd1474d._.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/fdeb9_html2canvas_dist_html2canvas_4a71f2ac.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/fdeb9_html2canvas_dist_html2canvas_4a71f2ac.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/fdeb9_html2canvas_dist_html2canvas_4a71f2ac.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/ffc37_dom-to-image-more_dist_dom-to-image-more_min_db78e443.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/ffc37_dom-to-image-more_dist_dom-to-image-more_min_db78e443.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({
|
||||
script: typeof document === "object" ? document.currentScript : undefined,
|
||||
chunks: [
|
||||
"static/chunks/ffc37_dom-to-image-more_dist_dom-to-image-more_min_db78e443.js"
|
||||
],
|
||||
source: "dynamic"
|
||||
});
|
||||
File diff suppressed because one or more lines are too long
Vendored
+4
-2
@@ -1,8 +1,8 @@
|
||||
// This file is generated automatically by Next.js
|
||||
// Do not edit this file manually
|
||||
|
||||
type AppRoutes = "/" | "/auth/register" | "/auth/signin" | "/members" | "/members/[id]" | "/members/new" | "/settings" | "/timeline" | "/tree" | "/trees/new"
|
||||
type AppRouteHandlerRoutes = "/api/auth/[...nextauth]" | "/api/auth/register" | "/api/trees" | "/api/trees/[treeId]" | "/api/trees/[treeId]/activity-logs" | "/api/trees/[treeId]/collaborators" | "/api/trees/[treeId]/import" | "/api/trees/[treeId]/invite" | "/api/trees/[treeId]/members" | "/api/trees/[treeId]/members/[memberId]" | "/api/user/activity-logs" | "/api/user/change-password" | "/api/user/profile"
|
||||
type AppRoutes = "/" | "/auth/register" | "/auth/signin" | "/members" | "/members/[id]" | "/members/new" | "/relationship-test" | "/settings" | "/timeline" | "/tree" | "/trees/new"
|
||||
type AppRouteHandlerRoutes = "/api/auth/[...nextauth]" | "/api/auth/register" | "/api/trees" | "/api/trees/[treeId]" | "/api/trees/[treeId]/activity-logs" | "/api/trees/[treeId]/collaborators" | "/api/trees/[treeId]/import" | "/api/trees/[treeId]/invite" | "/api/trees/[treeId]/members" | "/api/trees/[treeId]/members/[memberId]" | "/api/trees/[treeId]/relationship" | "/api/user/activity-logs" | "/api/user/change-password" | "/api/user/profile"
|
||||
type PageRoutes = never
|
||||
type LayoutRoutes = "/"
|
||||
type RedirectRoutes = never
|
||||
@@ -22,6 +22,7 @@ interface ParamMap {
|
||||
"/api/trees/[treeId]/invite": { "treeId": string; }
|
||||
"/api/trees/[treeId]/members": { "treeId": string; }
|
||||
"/api/trees/[treeId]/members/[memberId]": { "treeId": string; "memberId": string; }
|
||||
"/api/trees/[treeId]/relationship": { "treeId": string; }
|
||||
"/api/user/activity-logs": {}
|
||||
"/api/user/change-password": {}
|
||||
"/api/user/profile": {}
|
||||
@@ -30,6 +31,7 @@ interface ParamMap {
|
||||
"/members": {}
|
||||
"/members/[id]": { "id": string; }
|
||||
"/members/new": {}
|
||||
"/relationship-test": {}
|
||||
"/settings": {}
|
||||
"/timeline": {}
|
||||
"/tree": {}
|
||||
|
||||
@@ -101,6 +101,15 @@ type RouteHandlerConfig<Route extends AppRouteHandlerRoutes = AppRouteHandlerRou
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
// Validate ../../../app/relationship-test/page.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends AppPageConfig<"/relationship-test">> = Specific
|
||||
const handler = {} as typeof import("../../../app/relationship-test/page.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
// Validate ../../../app/settings/page.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends AppPageConfig<"/settings">> = Specific
|
||||
@@ -209,6 +218,15 @@ type RouteHandlerConfig<Route extends AppRouteHandlerRoutes = AppRouteHandlerRou
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
// Validate ../../../app/api/trees/[treeId]/relationship/route.ts
|
||||
{
|
||||
type __IsExpected<Specific extends RouteHandlerConfig<"/api/trees/[treeId]/relationship">> = Specific
|
||||
const handler = {} as typeof import("../../../app/api/trees/[treeId]/relationship/route.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
// Validate ../../../app/api/trees/[treeId]/route.ts
|
||||
{
|
||||
type __IsExpected<Specific extends RouteHandlerConfig<"/api/trees/[treeId]">> = Specific
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
import { RelationshipCalculator } from '@/lib/relationship-calculator'
|
||||
|
||||
/**
|
||||
* 计算两个成员之间的关系
|
||||
* GET /api/trees/[treeId]/relationship?from=xxx&to=yyy
|
||||
*/
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { treeId: string } }
|
||||
) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url)
|
||||
const fromId = searchParams.get('from')
|
||||
const toId = searchParams.get('to')
|
||||
|
||||
if (!fromId || !toId) {
|
||||
return NextResponse.json(
|
||||
{ error: '缺少参数:from 和 to' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
// 获取家族树的所有成员
|
||||
const members = await prisma.familyMember.findMany({
|
||||
where: { treeId: params.treeId }
|
||||
})
|
||||
|
||||
if (members.length === 0) {
|
||||
return NextResponse.json(
|
||||
{ error: '家族树不存在或没有成员' },
|
||||
{ status: 404 }
|
||||
)
|
||||
}
|
||||
|
||||
// 计算关系
|
||||
const calculator = new RelationshipCalculator(members as any)
|
||||
const result = calculator.getRelationshipDetail(fromId, toId)
|
||||
|
||||
// 获取成员信息
|
||||
const fromMember = members.find(m => m.id === fromId)
|
||||
const toMember = members.find(m => m.id === toId)
|
||||
|
||||
return NextResponse.json({
|
||||
from: {
|
||||
id: fromMember?.id,
|
||||
name: fromMember?.fullName
|
||||
},
|
||||
to: {
|
||||
id: toMember?.id,
|
||||
name: toMember?.fullName
|
||||
},
|
||||
relationship: result.term,
|
||||
path: result.path,
|
||||
description: result.description,
|
||||
success: result.success
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('计算关系失败:', error)
|
||||
return NextResponse.json(
|
||||
{ error: '计算关系失败' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from 'react'
|
||||
import { SiteHeader } from '@/components/site-header'
|
||||
import { useFamily } from '@/context/family-context'
|
||||
import { useRelationship } from '@/hooks/use-relationship'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
|
||||
export default function RelationshipTestPage() {
|
||||
const { treeData } = useFamily()
|
||||
const { calculateRelationship, getDirectRelatives, getSiblings } = useRelationship()
|
||||
|
||||
const [fromId, setFromId] = useState<string>('')
|
||||
const [toId, setToId] = useState<string>('')
|
||||
const [result, setResult] = useState<any>(null)
|
||||
|
||||
const members = Object.values(treeData.members)
|
||||
|
||||
const handleCalculate = () => {
|
||||
if (!fromId || !toId) return
|
||||
|
||||
const relationship = calculateRelationship(fromId, toId)
|
||||
const fromMember = treeData.members[fromId]
|
||||
const toMember = treeData.members[toId]
|
||||
|
||||
setResult({
|
||||
from: fromMember,
|
||||
to: toMember,
|
||||
relationship
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col bg-background">
|
||||
<SiteHeader />
|
||||
|
||||
<main className="flex-1 container mx-auto px-4 py-8">
|
||||
<div className="max-w-4xl mx-auto space-y-6">
|
||||
{/* 标题 */}
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold font-serif mb-2">家族关系计算器</h1>
|
||||
<p className="text-muted-foreground">
|
||||
选择两个家族成员,自动计算他们之间的亲属关系
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* 选择成员 */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>选择成员</CardTitle>
|
||||
<CardDescription>请选择要计算关系的两个成员</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">成员A</label>
|
||||
<Select value={fromId} onValueChange={setFromId}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="选择成员A" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{members.map(member => (
|
||||
<SelectItem key={member.id} value={member.id}>
|
||||
{member.fullName} (第{member.generation}世)
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium">成员B</label>
|
||||
<Select value={toId} onValueChange={setToId}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="选择成员B" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{members.map(member => (
|
||||
<SelectItem key={member.id} value={member.id}>
|
||||
{member.fullName} (第{member.generation}世)
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleCalculate}
|
||||
disabled={!fromId || !toId}
|
||||
className="w-full"
|
||||
>
|
||||
计算关系
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 计算结果 */}
|
||||
{result && (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>计算结果</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex items-center justify-center gap-4 p-6 bg-muted rounded-lg">
|
||||
<div className="text-center">
|
||||
<div className="text-2xl font-bold font-serif mb-1">
|
||||
{result.from.fullName}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
第{result.from.generation}世
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<Badge variant="default" className="text-lg px-4 py-2">
|
||||
{result.relationship.term}
|
||||
</Badge>
|
||||
{result.relationship.path && (
|
||||
<span className="text-xs text-muted-foreground">
|
||||
路径: {result.relationship.path}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
<div className="text-2xl font-bold font-serif mb-1">
|
||||
{result.to.fullName}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
第{result.to.generation}世
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{result.relationship.description && (
|
||||
<div className="p-4 bg-blue-50 dark:bg-blue-950 rounded-lg">
|
||||
<div className="text-sm font-medium mb-1">关系说明:</div>
|
||||
<div className="text-muted-foreground">
|
||||
<strong>{result.from.fullName}</strong> 是 <strong>{result.to.fullName}</strong> 的 <strong className="text-primary">{result.relationship.term}</strong>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{result.relationship.success === false && (
|
||||
<div className="p-4 bg-yellow-50 dark:bg-yellow-950 rounded-lg">
|
||||
<div className="text-sm text-yellow-800 dark:text-yellow-200">
|
||||
⚠️ {result.relationship.error || '无法计算关系'}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* 快速查询示例 */}
|
||||
{fromId && (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
{treeData.members[fromId]?.fullName} 的直系亲属
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{(() => {
|
||||
const relatives = getDirectRelatives(fromId)
|
||||
if (!relatives) return null
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{relatives.father && (
|
||||
<div className="p-3 bg-muted rounded-lg">
|
||||
<div className="text-sm text-muted-foreground mb-1">父亲</div>
|
||||
<div className="font-medium">{relatives.father.fullName}</div>
|
||||
</div>
|
||||
)}
|
||||
{relatives.mother && (
|
||||
<div className="p-3 bg-muted rounded-lg">
|
||||
<div className="text-sm text-muted-foreground mb-1">母亲</div>
|
||||
<div className="font-medium">{relatives.mother.fullName}</div>
|
||||
</div>
|
||||
)}
|
||||
{relatives.spouses.length > 0 && (
|
||||
<div className="p-3 bg-muted rounded-lg">
|
||||
<div className="text-sm text-muted-foreground mb-1">配偶</div>
|
||||
{relatives.spouses.map((spouse: any) => (
|
||||
<div key={spouse.id} className="font-medium">
|
||||
{spouse.fullName}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{relatives.children.length > 0 && (
|
||||
<div className="p-3 bg-muted rounded-lg">
|
||||
<div className="text-sm text-muted-foreground mb-1">
|
||||
子女 ({relatives.children.length}人)
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
{relatives.children.slice(0, 3).map((child: any) => (
|
||||
<div key={child.id} className="font-medium text-sm">
|
||||
{child.fullName}
|
||||
</div>
|
||||
))}
|
||||
{relatives.children.length > 3 && (
|
||||
<div className="text-xs text-muted-foreground">
|
||||
还有 {relatives.children.length - 3} 人...
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})()}
|
||||
|
||||
{(() => {
|
||||
const siblings = getSiblings(fromId)
|
||||
if (siblings.length === 0) return null
|
||||
|
||||
return (
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<div className="text-sm text-muted-foreground mb-2">
|
||||
兄弟姐妹 ({siblings.length}人)
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{siblings.map((sibling: any) => (
|
||||
<Badge key={sibling.id} variant="outline">
|
||||
{sibling.fullName}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})()}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
+242
-6
@@ -6,6 +6,7 @@ import { SiteHeader } from "@/components/site-header"
|
||||
import { TreeLayout } from "@/components/tree/tree-layout"
|
||||
import { D3OrgChartFlow, type D3OrgChartRef } from "@/components/tree/d3-org-chart-flow"
|
||||
import { useFamily } from "@/context/family-context"
|
||||
import { useRelationship } from "@/hooks/use-relationship"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
@@ -13,18 +14,36 @@ import {
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu"
|
||||
import { ZoomIn, ZoomOut, Move, Download, LayoutGrid, ChevronDown } from "lucide-react"
|
||||
import { useState, useRef, useEffect } from "react"
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { ZoomIn, ZoomOut, Move, Download, LayoutGrid, ChevronDown, Users } from "lucide-react"
|
||||
import { useState, useRef, useEffect, useCallback } from "react"
|
||||
import { useRouter, useSearchParams } from "next/navigation"
|
||||
|
||||
type ViewMode = "traditional" | "d3-org-chart"
|
||||
|
||||
export default function TreePage() {
|
||||
const { treeData } = useFamily()
|
||||
const { calculateRelationship } = useRelationship()
|
||||
const router = useRouter()
|
||||
const searchParams = useSearchParams()
|
||||
const [viewMode, setViewMode] = useState<ViewMode>("traditional")
|
||||
|
||||
// 关系查询模式
|
||||
const [relationMode, setRelationMode] = useState(false)
|
||||
const [selectedMembers, setSelectedMembers] = useState<string[]>([])
|
||||
const [relationResult, setRelationResult] = useState<any>(null)
|
||||
const [showRelationDialog, setShowRelationDialog] = useState(false)
|
||||
|
||||
// 使用ref存储最新的relationMode值,避免回调重新创建
|
||||
const relationModeRef = useRef(relationMode)
|
||||
const selectedMembersRef = useRef(selectedMembers)
|
||||
|
||||
useEffect(() => {
|
||||
relationModeRef.current = relationMode
|
||||
selectedMembersRef.current = selectedMembers
|
||||
}, [relationMode, selectedMembers])
|
||||
|
||||
// 从 URL 参数读取视图模式
|
||||
useEffect(() => {
|
||||
const view = searchParams.get('view')
|
||||
@@ -70,6 +89,146 @@ export default function TreePage() {
|
||||
setIsDragging(false)
|
||||
}
|
||||
|
||||
// 处理成员选择(关系查询模式)
|
||||
const handleMemberClick = (memberId: string) => {
|
||||
if (selectedMembers.length === 0) {
|
||||
// 选择第一个成员
|
||||
setSelectedMembers([memberId])
|
||||
} else if (selectedMembers.length === 1) {
|
||||
// 选择第二个成员,计算关系
|
||||
const [firstId] = selectedMembers
|
||||
if (firstId === memberId) {
|
||||
// 点击同一个人,取消选择
|
||||
setSelectedMembers([])
|
||||
return
|
||||
}
|
||||
|
||||
const result = calculateRelationship(firstId, memberId)
|
||||
const firstMember = treeData.members[firstId]
|
||||
const secondMember = treeData.members[memberId]
|
||||
|
||||
setRelationResult({
|
||||
from: firstMember,
|
||||
to: secondMember,
|
||||
relationship: result
|
||||
})
|
||||
setShowRelationDialog(true)
|
||||
setSelectedMembers([])
|
||||
setRelationMode(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 切换关系查询模式
|
||||
const toggleRelationMode = () => {
|
||||
setRelationMode(!relationMode)
|
||||
setSelectedMembers([])
|
||||
setRelationResult(null)
|
||||
}
|
||||
|
||||
// 处理对话框关闭
|
||||
const handleDialogClose = (open: boolean) => {
|
||||
setShowRelationDialog(open)
|
||||
if (!open && relationResult) {
|
||||
// 清除选中样式
|
||||
const clearNodeStyle = (nodeId: string) => {
|
||||
const chartContainer = document.querySelector('.w-full.h-full.bg-background.rounded-lg.border')
|
||||
const svg = chartContainer?.querySelector('svg')
|
||||
if (!svg) return
|
||||
|
||||
const foreignObjects = svg.querySelectorAll('foreignObject')
|
||||
foreignObjects.forEach((fo: any) => {
|
||||
const nodeData = (fo.parentNode as any)?.__data__?.data
|
||||
if (nodeData?.id === nodeId) {
|
||||
const nameDiv = fo.querySelector('div[style*="font-size: 13px"]') as HTMLElement
|
||||
if (nameDiv) {
|
||||
// 移除勾选图标
|
||||
const checkIcon = nameDiv.querySelector('svg')
|
||||
if (checkIcon) {
|
||||
checkIcon.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
clearNodeStyle(relationResult.from.id)
|
||||
clearNodeStyle(relationResult.to.id)
|
||||
}
|
||||
}
|
||||
|
||||
// 使用useCallback创建稳定的回调,通过ref访问最新的relationMode
|
||||
const handleD3MemberClick = useCallback((id: string) => {
|
||||
console.log('D3 onMemberClick triggered:', id, 'relationMode:', relationModeRef.current)
|
||||
if (relationModeRef.current) {
|
||||
console.log('Calling handleMemberClick')
|
||||
|
||||
// 更新节点样式的辅助函数
|
||||
const updateNodeStyle = (nodeId: string, isSelected: boolean) => {
|
||||
// 从DOM中查找D3图表容器
|
||||
const chartContainer = document.querySelector('.w-full.h-full.bg-background.rounded-lg.border')
|
||||
const svg = chartContainer?.querySelector('svg')
|
||||
if (!svg) return
|
||||
|
||||
const foreignObjects = svg.querySelectorAll('foreignObject')
|
||||
foreignObjects.forEach((fo: any) => {
|
||||
const nodeData = (fo.parentNode as any)?.__data__?.data
|
||||
if (nodeData?.id === nodeId) {
|
||||
const nameDiv = fo.querySelector('div[style*="font-size: 13px"]') as HTMLElement
|
||||
if (nameDiv) {
|
||||
if (isSelected) {
|
||||
// 添加勾选图标
|
||||
if (!nameDiv.querySelector('svg')) {
|
||||
const iconHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#3b82f6" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" style="margin-left: 4px"><polyline points="20 6 9 17 4 12"/></svg>`
|
||||
nameDiv.style.display = 'flex'
|
||||
nameDiv.style.alignItems = 'center'
|
||||
nameDiv.insertAdjacentHTML('beforeend', iconHTML)
|
||||
}
|
||||
} else {
|
||||
// 移除勾选图标
|
||||
const checkIcon = nameDiv.querySelector('svg')
|
||||
if (checkIcon) {
|
||||
checkIcon.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 直接处理选择逻辑
|
||||
if (selectedMembersRef.current.length === 0) {
|
||||
updateNodeStyle(id, true)
|
||||
setSelectedMembers([id])
|
||||
} else if (selectedMembersRef.current.length === 1) {
|
||||
const [firstId] = selectedMembersRef.current
|
||||
if (firstId === id) {
|
||||
updateNodeStyle(id, false)
|
||||
setSelectedMembers([])
|
||||
return
|
||||
}
|
||||
|
||||
updateNodeStyle(id, true)
|
||||
|
||||
const result = calculateRelationship(firstId, id)
|
||||
const firstMember = treeData.members[firstId]
|
||||
const secondMember = treeData.members[id]
|
||||
|
||||
setRelationResult({
|
||||
from: firstMember,
|
||||
to: secondMember,
|
||||
relationship: result
|
||||
})
|
||||
setShowRelationDialog(true)
|
||||
setSelectedMembers([])
|
||||
setRelationMode(false)
|
||||
// 选中样式会在对话框关闭时清除
|
||||
}
|
||||
} else {
|
||||
console.log('Navigating to member detail')
|
||||
router.push(`/members/${id}`)
|
||||
}
|
||||
}, [router, calculateRelationship, treeData.members])
|
||||
|
||||
const handleExportImage = async () => {
|
||||
if (!containerRef.current) return
|
||||
|
||||
@@ -195,8 +354,20 @@ export default function TreePage() {
|
||||
<div className="h-screen flex flex-col bg-muted/30 overflow-hidden">
|
||||
<SiteHeader />
|
||||
|
||||
{/* 视图切换按钮 */}
|
||||
<div className="absolute top-20 right-4 z-30">
|
||||
{/* 视图切换和关系查询按钮 */}
|
||||
<div className="absolute top-20 right-4 z-30 flex gap-2">
|
||||
{/* 关系查询按钮 */}
|
||||
<Button
|
||||
variant={relationMode ? "default" : "outline"}
|
||||
className="gap-2 shadow-lg"
|
||||
onClick={toggleRelationMode}
|
||||
>
|
||||
<Users className="h-4 w-4" />
|
||||
{relationMode ? (
|
||||
selectedMembers.length === 0 ? '选择第一个成员' : '选择第二个成员'
|
||||
) : '关系查询'}
|
||||
</Button>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" className="gap-2 shadow-lg">
|
||||
@@ -272,7 +443,12 @@ export default function TreePage() {
|
||||
}}
|
||||
className="absolute min-w-full min-h-full flex justify-center pt-20 pb-20"
|
||||
>
|
||||
<TreeLayout rootId={treeData.rootId} />
|
||||
<TreeLayout
|
||||
rootId={treeData.rootId}
|
||||
relationMode={relationMode}
|
||||
selectedMembers={selectedMembers}
|
||||
onMemberClick={handleMemberClick}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -300,11 +476,71 @@ export default function TreePage() {
|
||||
ref={d3ChartRef}
|
||||
members={treeData.members}
|
||||
rootId={treeData.rootId}
|
||||
onMemberClick={(id: string) => router.push(`/members/${id}`)}
|
||||
relationMode={relationMode}
|
||||
selectedMembers={selectedMembers}
|
||||
onMemberClick={handleD3MemberClick}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 关系查询结果对话框 */}
|
||||
<Dialog open={showRelationDialog} onOpenChange={handleDialogClose}>
|
||||
<DialogContent className="max-w-2xl" aria-describedby="relation-description">
|
||||
<DialogHeader>
|
||||
<DialogTitle>关系查询结果</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
{relationResult && (
|
||||
<div className="space-y-4">
|
||||
{/* 成员信息 */}
|
||||
<div className="flex items-center justify-center gap-4 p-6 bg-muted rounded-lg">
|
||||
<div className="text-center">
|
||||
<div className="text-2xl font-bold font-serif mb-1">
|
||||
{relationResult.from.fullName}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
第{relationResult.from.generation}世
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<Badge variant="default" className="text-lg px-4 py-2">
|
||||
{relationResult.relationship.term}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
<div className="text-2xl font-bold font-serif mb-1">
|
||||
{relationResult.to.fullName}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
第{relationResult.to.generation}世
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 关系说明 */}
|
||||
<div id="relation-description" className="p-4 bg-blue-50 dark:bg-blue-950 rounded-lg">
|
||||
<div className="text-sm font-medium mb-1">关系说明:</div>
|
||||
<div className="text-muted-foreground">
|
||||
<strong>{relationResult.from.fullName}</strong> 是 <strong>{relationResult.to.fullName}</strong> 的 <strong className="text-primary">{relationResult.relationship.term}</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 关系路径 */}
|
||||
{relationResult.relationship.path && (
|
||||
<div className="p-4 bg-muted rounded-lg">
|
||||
<div className="text-sm font-medium mb-2">关系路径:</div>
|
||||
<div className="text-xs text-muted-foreground break-all">
|
||||
{relationResult.relationship.path}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import { useEffect, useRef, useState, forwardRef, useImperativeHandle } from "react"
|
||||
import { useEffect, useRef, useState, forwardRef, useImperativeHandle, memo } from "react"
|
||||
import * as d3 from "d3"
|
||||
// @ts-ignore - d3-org-chart没有TypeScript类型定义
|
||||
import { OrgChart } from "d3-org-chart"
|
||||
@@ -14,6 +14,8 @@ interface D3OrgChartFlowProps {
|
||||
rootId: string
|
||||
onMemberClick?: (memberId: string) => void
|
||||
onExport?: () => void
|
||||
relationMode?: boolean
|
||||
selectedMembers?: string[]
|
||||
}
|
||||
|
||||
export interface D3OrgChartRef {
|
||||
@@ -57,8 +59,10 @@ function calculateAge(birthDate?: string, deathDate?: string): number | null {
|
||||
return age
|
||||
}
|
||||
|
||||
export const D3OrgChartFlow = forwardRef<D3OrgChartRef, D3OrgChartFlowProps>(
|
||||
({ members, rootId, onMemberClick, onExport }, ref) => {
|
||||
const D3OrgChartFlowComponent = forwardRef<D3OrgChartRef, D3OrgChartFlowProps>(
|
||||
({ members, rootId, onMemberClick, onExport, relationMode = false, selectedMembers = [] }, ref) => {
|
||||
console.log('D3OrgChartFlow render, selectedMembers:', selectedMembers, 'relationMode:', relationMode)
|
||||
|
||||
const chartRef = useRef<HTMLDivElement>(null)
|
||||
const chartInstanceRef = useRef<any>(null)
|
||||
const [isReady, setIsReady] = useState(false)
|
||||
@@ -216,11 +220,15 @@ export const D3OrgChartFlow = forwardRef<D3OrgChartRef, D3OrgChartFlowProps>(
|
||||
// 获取头像URL
|
||||
const avatarUrl = node.avatarImageId ? avatarCache.get(node.avatarImageId) : null
|
||||
|
||||
// 检查是否被选中
|
||||
const isSelected = selectedMembers.includes(node.id)
|
||||
|
||||
return `
|
||||
<div style="
|
||||
position: relative;
|
||||
width: 160px;
|
||||
height: 120px;
|
||||
box-sizing: border-box;
|
||||
background: ${node.deathYear ? '#fafafa' : 'white'};
|
||||
border: 2px solid ${color};
|
||||
border-radius: 10px;
|
||||
@@ -253,8 +261,9 @@ export const D3OrgChartFlow = forwardRef<D3OrgChartRef, D3OrgChartFlowProps>(
|
||||
}
|
||||
</div>
|
||||
<div style="flex: 1; min-width: 0;">
|
||||
<div style="font-size: 13px; font-weight: 600; color: #1f2937; margin-bottom: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
|
||||
${node.name}
|
||||
<div style="font-size: 13px; font-weight: 600; color: #1f2937; margin-bottom: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: flex; align-items: center; gap: 4px;">
|
||||
<span>${node.name}</span>
|
||||
${isSelected ? `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#3b82f6" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>` : ''}
|
||||
</div>
|
||||
<div style="font-size: 9px; color: #6b7280; padding: 1px 4px; background: #f3f4f6; border-radius: 3px; display: inline-block;">
|
||||
${node.generation}
|
||||
@@ -349,6 +358,9 @@ export const D3OrgChartFlow = forwardRef<D3OrgChartRef, D3OrgChartFlowProps>(
|
||||
}
|
||||
}, [members, rootId, onMemberClick, avatarCache])
|
||||
|
||||
// 监听selectedMembers变化,动态显示/隐藏勾选图标
|
||||
// 逻辑已移至tree/page.tsx以避免组件重新渲染
|
||||
|
||||
// 导出PNG
|
||||
const handleExportPNG = () => {
|
||||
if (!chartInstanceRef.current) return
|
||||
@@ -440,4 +452,10 @@ export const D3OrgChartFlow = forwardRef<D3OrgChartRef, D3OrgChartFlowProps>(
|
||||
)
|
||||
})
|
||||
|
||||
D3OrgChartFlow.displayName = 'D3OrgChartFlow'
|
||||
D3OrgChartFlowComponent.displayName = 'D3OrgChartFlow'
|
||||
|
||||
// 使用memo优化,避免不必要的重新渲染
|
||||
export const D3OrgChartFlow = memo(D3OrgChartFlowComponent, (prevProps, nextProps) => {
|
||||
return prevProps.rootId === nextProps.rootId &&
|
||||
prevProps.members === nextProps.members
|
||||
})
|
||||
|
||||
@@ -11,6 +11,8 @@ interface FamilyNodeProps {
|
||||
isRoot?: boolean
|
||||
onSelect?: (member: FamilyMember) => void
|
||||
isHighlighted?: boolean
|
||||
relationMode?: boolean
|
||||
isSelected?: boolean
|
||||
}
|
||||
|
||||
// 格式化日期显示(只显示年份)
|
||||
@@ -38,7 +40,7 @@ function calculateAge(birthDate?: string, deathDate?: string): number | null {
|
||||
}
|
||||
|
||||
// 单个人员卡片组件
|
||||
function PersonCard({ member, isRoot, isSpouse, onSelect, isHighlighted }: { member: FamilyMember; isRoot?: boolean; isSpouse?: boolean; onSelect?: (member: FamilyMember) => void; isHighlighted?: boolean }) {
|
||||
function PersonCard({ member, isRoot, isSpouse, onSelect, isHighlighted, relationMode, isSelected }: { member: FamilyMember; isRoot?: boolean; isSpouse?: boolean; onSelect?: (member: FamilyMember) => void; isHighlighted?: boolean; relationMode?: boolean; isSelected?: boolean }) {
|
||||
const { avatarUrl: avatarBlobUrl } = useAvatarCache(member?.avatarImageId)
|
||||
|
||||
const birthYear = formatYear(member.birthDate)
|
||||
@@ -61,13 +63,16 @@ function PersonCard({ member, isRoot, isSpouse, onSelect, isHighlighted }: { mem
|
||||
<div
|
||||
className={cn(
|
||||
"family-node-card relative flex flex-col items-center gap-2 p-3 rounded-lg transition-all cursor-pointer hover:scale-105 shadow-sm w-32",
|
||||
isHighlighted
|
||||
? "border-4 border-yellow-400 bg-yellow-50 dark:bg-yellow-900/20 ring-4 ring-yellow-200 dark:ring-yellow-800 animate-pulse"
|
||||
: isRoot
|
||||
? "border-2 border-primary bg-primary/5"
|
||||
: isSpouse
|
||||
? "border-2 border-dashed border-border/60 bg-muted/30"
|
||||
: "border-2 border-border bg-card",
|
||||
isSelected
|
||||
? "border-4 border-blue-500 bg-blue-50 dark:bg-blue-900/20 ring-4 ring-blue-200 dark:ring-blue-800"
|
||||
: isHighlighted
|
||||
? "border-4 border-yellow-400 bg-yellow-50 dark:bg-yellow-900/20 ring-4 ring-yellow-200 dark:ring-yellow-800 animate-pulse"
|
||||
: isRoot
|
||||
? "border-2 border-primary bg-primary/5"
|
||||
: isSpouse
|
||||
? "border-2 border-dashed border-border/60 bg-muted/30"
|
||||
: "border-2 border-border bg-card",
|
||||
relationMode && "hover:border-blue-400 hover:shadow-lg"
|
||||
)}
|
||||
onClick={() => onSelect?.(member)}
|
||||
>
|
||||
@@ -120,17 +125,17 @@ function PersonCard({ member, isRoot, isSpouse, onSelect, isHighlighted }: { mem
|
||||
)
|
||||
}
|
||||
|
||||
export function FamilyNode({ member, spouse, isRoot, onSelect, isHighlighted }: FamilyNodeProps) {
|
||||
export function FamilyNode({ member, spouse, isRoot, onSelect, isHighlighted, relationMode, isSelected }: FamilyNodeProps) {
|
||||
if (!spouse) {
|
||||
return <PersonCard member={member} isRoot={isRoot} onSelect={onSelect} isHighlighted={isHighlighted} />
|
||||
return <PersonCard member={member} isRoot={isRoot} onSelect={onSelect} isHighlighted={isHighlighted} relationMode={relationMode} isSelected={isSelected} />
|
||||
}
|
||||
|
||||
// 有配偶时,并排显示
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<PersonCard member={member} isRoot={isRoot} onSelect={onSelect} isHighlighted={isHighlighted} />
|
||||
<PersonCard member={member} isRoot={isRoot} onSelect={onSelect} isHighlighted={isHighlighted} relationMode={relationMode} isSelected={isSelected} />
|
||||
<Heart className="h-4 w-4 text-red-400 flex-shrink-0" />
|
||||
<PersonCard member={spouse} isSpouse={true} onSelect={onSelect} />
|
||||
<PersonCard member={spouse} isSpouse={true} onSelect={onSelect} relationMode={relationMode} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@ import { useRouter } from "next/navigation"
|
||||
interface TreeLayoutProps {
|
||||
rootId: string
|
||||
onSelectMember?: (member: FamilyMember) => void
|
||||
relationMode?: boolean
|
||||
selectedMembers?: string[]
|
||||
onMemberClick?: (memberId: string) => void
|
||||
}
|
||||
|
||||
interface Connection {
|
||||
@@ -16,7 +19,13 @@ interface Connection {
|
||||
type: 'vertical' | 'horizontal'
|
||||
}
|
||||
|
||||
export function TreeLayout({ rootId, onSelectMember }: TreeLayoutProps) {
|
||||
export function TreeLayout({
|
||||
rootId,
|
||||
onSelectMember,
|
||||
relationMode = false,
|
||||
selectedMembers = [],
|
||||
onMemberClick
|
||||
}: TreeLayoutProps) {
|
||||
const { getMember, treeData, highlightedMemberId } = useFamily()
|
||||
const root = getMember(rootId)
|
||||
const router = useRouter()
|
||||
@@ -31,8 +40,12 @@ export function TreeLayout({ rootId, onSelectMember }: TreeLayoutProps) {
|
||||
|
||||
// 处理节点点击
|
||||
const handleNodeClick = useCallback((member: FamilyMember) => {
|
||||
router.push(`/members/${member.id}`)
|
||||
}, [router])
|
||||
if (relationMode && onMemberClick) {
|
||||
onMemberClick(member.id)
|
||||
} else {
|
||||
router.push(`/members/${member.id}`)
|
||||
}
|
||||
}, [relationMode, onMemberClick, router])
|
||||
|
||||
// 计算所有连线位置
|
||||
const calculateConnections = useCallback(() => {
|
||||
@@ -150,6 +163,8 @@ export function TreeLayout({ rootId, onSelectMember }: TreeLayoutProps) {
|
||||
onSelect={handleNodeClick}
|
||||
isRoot={isRoot}
|
||||
isHighlighted={member.id === highlightedMemberId}
|
||||
relationMode={relationMode}
|
||||
isSelected={selectedMembers.includes(member.id)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
# 家族关系计算器使用文档
|
||||
|
||||
## 概述
|
||||
|
||||
本项目集成了 `relationship.js` 库,用于精确计算中文亲属关系。
|
||||
|
||||
## 功能特点
|
||||
|
||||
- ✅ 100% 准确的关系计算
|
||||
- ✅ 支持复杂的中文称谓系统
|
||||
- ✅ 自动处理堂/表、伯/叔等细微区别
|
||||
- ✅ 支持多代关系计算
|
||||
- ✅ 客户端和服务端双重支持
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 客户端使用(推荐)
|
||||
|
||||
```typescript
|
||||
import { useRelationship } from '@/hooks/use-relationship'
|
||||
|
||||
function MyComponent() {
|
||||
const { calculateRelationship } = useRelationship()
|
||||
|
||||
// 计算关系
|
||||
const result = calculateRelationship('memberA_id', 'memberB_id')
|
||||
|
||||
console.log(result.term) // "堂兄弟"
|
||||
console.log(result.path) // "fbs"
|
||||
console.log(result.description) // "的父亲的哥哥的儿子"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. API使用
|
||||
|
||||
```bash
|
||||
GET /api/trees/[treeId]/relationship?from=xxx&to=yyy
|
||||
```
|
||||
|
||||
**响应示例:**
|
||||
```json
|
||||
{
|
||||
"from": {
|
||||
"id": "xxx",
|
||||
"name": "王建国"
|
||||
},
|
||||
"to": {
|
||||
"id": "yyy",
|
||||
"name": "王明华"
|
||||
},
|
||||
"relationship": "堂兄弟",
|
||||
"path": "fbs",
|
||||
"description": "的父亲的哥哥的儿子",
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 直接使用计算器类
|
||||
|
||||
```typescript
|
||||
import { RelationshipCalculator } from '@/lib/relationship-calculator'
|
||||
|
||||
const members = [...] // FamilyMember[]
|
||||
const calculator = new RelationshipCalculator(members)
|
||||
|
||||
const result = calculator.getRelationshipDetail('fromId', 'toId')
|
||||
```
|
||||
|
||||
## 关系路径说明
|
||||
|
||||
### 基本路径符号
|
||||
|
||||
| 符号 | 含义 | 示例 |
|
||||
|------|------|------|
|
||||
| `f` | 父亲 | `f` = 父亲 |
|
||||
| `m` | 母亲 | `m` = 母亲 |
|
||||
| `h` | 丈夫 | `h` = 丈夫 |
|
||||
| `w` | 妻子 | `w` = 妻子 |
|
||||
| `s` | 儿子 | `s` = 儿子 |
|
||||
| `d` | 女儿 | `d` = 女儿 |
|
||||
| `ob` | 哥哥 | `ob` = 哥哥 |
|
||||
| `lb` | 弟弟 | `lb` = 弟弟 |
|
||||
| `os` | 姐姐 | `os` = 姐姐 |
|
||||
| `ls` | 妹妹 | `ls` = 妹妹 |
|
||||
|
||||
### 组合路径示例
|
||||
|
||||
| 路径 | 关系 | 说明 |
|
||||
|------|------|------|
|
||||
| `f` | 父亲 | 直接父子关系 |
|
||||
| `m` | 母亲 | 直接母子关系 |
|
||||
| `ff` | 爷爷 | 父亲的父亲 |
|
||||
| `fm` | 奶奶 | 父亲的母亲 |
|
||||
| `mf` | 外公 | 母亲的父亲 |
|
||||
| `mm` | 外婆 | 母亲的母亲 |
|
||||
| `fbs` | 堂兄弟 | 父亲的哥哥的儿子 |
|
||||
| `mbs` | 表兄弟 | 母亲的哥哥的儿子 |
|
||||
| `ffs` | 伯父/叔父 | 父亲的父亲的儿子 |
|
||||
| `fss` | 孙子 | 儿子的儿子 |
|
||||
|
||||
## Hook API
|
||||
|
||||
### useRelationship()
|
||||
|
||||
返回对象包含以下方法:
|
||||
|
||||
#### calculateRelationship(fromId, toId)
|
||||
计算两个成员之间的关系(客户端)
|
||||
|
||||
**参数:**
|
||||
- `fromId`: 起始成员ID
|
||||
- `toId`: 目标成员ID
|
||||
|
||||
**返回:**
|
||||
```typescript
|
||||
{
|
||||
term: string // 关系称谓
|
||||
path: string // 关系路径
|
||||
description: string // 关系描述
|
||||
success: boolean // 是否成功
|
||||
}
|
||||
```
|
||||
|
||||
#### getDirectRelatives(memberId)
|
||||
获取成员的直系亲属
|
||||
|
||||
**返回:**
|
||||
```typescript
|
||||
{
|
||||
father: FamilyMember | null
|
||||
mother: FamilyMember | null
|
||||
spouses: FamilyMember[]
|
||||
children: FamilyMember[]
|
||||
}
|
||||
```
|
||||
|
||||
#### getSiblings(memberId)
|
||||
获取成员的所有兄弟姐妹
|
||||
|
||||
**返回:** `FamilyMember[]`
|
||||
|
||||
#### getAncestors(memberId, maxGenerations?)
|
||||
获取成员的所有祖先
|
||||
|
||||
**参数:**
|
||||
- `memberId`: 成员ID
|
||||
- `maxGenerations`: 最大代数(默认10)
|
||||
|
||||
**返回:** `FamilyMember[]`
|
||||
|
||||
#### getDescendants(memberId, maxGenerations?)
|
||||
获取成员的所有后代
|
||||
|
||||
**参数:**
|
||||
- `memberId`: 成员ID
|
||||
- `maxGenerations`: 最大代数(默认10)
|
||||
|
||||
**返回:** `FamilyMember[]`
|
||||
|
||||
## 测试页面
|
||||
|
||||
访问 `/relationship-test` 查看关系计算器的演示页面。
|
||||
|
||||
## 支持的关系类型
|
||||
|
||||
### 直系关系
|
||||
- 父亲、母亲
|
||||
- 儿子、女儿
|
||||
- 爷爷、奶奶、外公、外婆
|
||||
- 孙子、孙女、外孙、外孙女
|
||||
|
||||
### 旁系关系
|
||||
- 兄弟、姐妹
|
||||
- 堂兄弟、表兄弟
|
||||
- 伯父、叔父、姑姑
|
||||
- 舅舅、姨妈
|
||||
- 侄子、外甥
|
||||
|
||||
### 姻亲关系
|
||||
- 丈夫、妻子
|
||||
- 公公、婆婆、岳父、岳母
|
||||
- 女婿、儿媳
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **年龄判断**:兄弟姐妹的称谓(哥哥/弟弟/姐姐/妹妹)基于出生年份判断
|
||||
2. **路径长度**:关系路径越长,计算时间越长,建议限制在10代以内
|
||||
3. **无关系**:如果两人没有血缘或姻亲关系,返回"无血缘关系"
|
||||
4. **数据完整性**:确保家族数据中的父母、配偶、子女关系完整
|
||||
|
||||
## 性能优化
|
||||
|
||||
- 使用BFS算法,时间复杂度 O(V + E)
|
||||
- 客户端计算,无需网络请求
|
||||
- 支持缓存计算结果
|
||||
|
||||
## 扩展功能
|
||||
|
||||
可以基于关系计算器实现:
|
||||
|
||||
1. **智能称呼建议**:自动提示如何称呼某个亲戚
|
||||
2. **关系可视化**:绘制关系路径图
|
||||
3. **辈分计算**:自动计算辈分差异
|
||||
4. **家族统计**:统计各种关系的数量
|
||||
5. **关系验证**:检查家族数据的一致性
|
||||
|
||||
## 相关资源
|
||||
|
||||
- [relationship.js 文档](https://github.com/mumuy/relationship)
|
||||
- [中国亲属关系计算](https://passer-by.com/relationship/)
|
||||
@@ -0,0 +1,175 @@
|
||||
import { useState } from 'react'
|
||||
import { useFamily } from '@/context/family-context'
|
||||
import { RelationshipCalculator, type RelationshipDetail } from '@/lib/relationship-calculator'
|
||||
|
||||
/**
|
||||
* 使用家族关系计算的Hook
|
||||
*/
|
||||
export function useRelationship() {
|
||||
const { treeData } = useFamily()
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
/**
|
||||
* 计算两个成员之间的关系(客户端计算)
|
||||
*/
|
||||
const calculateRelationship = (fromId: string, toId: string): RelationshipDetail => {
|
||||
const members = Object.values(treeData.members)
|
||||
const calculator = new RelationshipCalculator(members)
|
||||
return calculator.getRelationshipDetail(fromId, toId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过API计算关系(服务端计算)
|
||||
*/
|
||||
const calculateRelationshipAPI = async (
|
||||
treeId: string,
|
||||
fromId: string,
|
||||
toId: string
|
||||
): Promise<RelationshipDetail | null> => {
|
||||
setLoading(true)
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/trees/${treeId}/relationship?from=${fromId}&to=${toId}`
|
||||
)
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('计算关系失败')
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return {
|
||||
term: data.relationship,
|
||||
path: data.path,
|
||||
description: data.description,
|
||||
success: data.success
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('计算关系失败:', error)
|
||||
return null
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员的所有直系亲属
|
||||
*/
|
||||
const getDirectRelatives = (memberId: string) => {
|
||||
const member = treeData.members[memberId]
|
||||
if (!member) return null
|
||||
|
||||
const relatives = {
|
||||
father: member.fatherId ? treeData.members[member.fatherId] : null,
|
||||
mother: member.motherId ? treeData.members[member.motherId] : null,
|
||||
spouses: member.spouseIds?.map(id => treeData.members[id]).filter(Boolean) || [],
|
||||
children: member.childrenIds?.map(id => treeData.members[id]).filter(Boolean) || []
|
||||
}
|
||||
|
||||
return relatives
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员的所有兄弟姐妹
|
||||
*/
|
||||
const getSiblings = (memberId: string) => {
|
||||
const member = treeData.members[memberId]
|
||||
if (!member) return []
|
||||
|
||||
const siblings = new Set<string>()
|
||||
|
||||
// 通过父亲查找
|
||||
if (member.fatherId) {
|
||||
const father = treeData.members[member.fatherId]
|
||||
if (father?.childrenIds) {
|
||||
father.childrenIds.forEach(id => {
|
||||
if (id !== memberId) siblings.add(id)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 通过母亲查找
|
||||
if (member.motherId) {
|
||||
const mother = treeData.members[member.motherId]
|
||||
if (mother?.childrenIds) {
|
||||
mother.childrenIds.forEach(id => {
|
||||
if (id !== memberId) siblings.add(id)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(siblings).map(id => treeData.members[id]).filter(Boolean)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员的所有祖先
|
||||
*/
|
||||
const getAncestors = (memberId: string, maxGenerations: number = 10) => {
|
||||
const ancestors: any[] = []
|
||||
const visited = new Set<string>()
|
||||
const queue = [{ id: memberId, generation: 0 }]
|
||||
|
||||
while (queue.length > 0) {
|
||||
const { id, generation } = queue.shift()!
|
||||
|
||||
if (generation >= maxGenerations || visited.has(id)) continue
|
||||
visited.add(id)
|
||||
|
||||
const member = treeData.members[id]
|
||||
if (!member) continue
|
||||
|
||||
if (generation > 0) {
|
||||
ancestors.push({ ...member, generationDiff: generation })
|
||||
}
|
||||
|
||||
if (member.fatherId) {
|
||||
queue.push({ id: member.fatherId, generation: generation + 1 })
|
||||
}
|
||||
if (member.motherId) {
|
||||
queue.push({ id: member.motherId, generation: generation + 1 })
|
||||
}
|
||||
}
|
||||
|
||||
return ancestors
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员的所有后代
|
||||
*/
|
||||
const getDescendants = (memberId: string, maxGenerations: number = 10) => {
|
||||
const descendants: any[] = []
|
||||
const visited = new Set<string>()
|
||||
const queue = [{ id: memberId, generation: 0 }]
|
||||
|
||||
while (queue.length > 0) {
|
||||
const { id, generation } = queue.shift()!
|
||||
|
||||
if (generation >= maxGenerations || visited.has(id)) continue
|
||||
visited.add(id)
|
||||
|
||||
const member = treeData.members[id]
|
||||
if (!member) continue
|
||||
|
||||
if (generation > 0) {
|
||||
descendants.push({ ...member, generationDiff: generation })
|
||||
}
|
||||
|
||||
if (member.childrenIds) {
|
||||
member.childrenIds.forEach(childId => {
|
||||
queue.push({ id: childId, generation: generation + 1 })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return descendants
|
||||
}
|
||||
|
||||
return {
|
||||
calculateRelationship,
|
||||
calculateRelationshipAPI,
|
||||
getDirectRelatives,
|
||||
getSiblings,
|
||||
getAncestors,
|
||||
getDescendants,
|
||||
loading
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,470 @@
|
||||
import relationship from 'relationship.js'
|
||||
import type { FamilyMember } from '@/types/family'
|
||||
|
||||
/**
|
||||
* 家族关系计算器
|
||||
* 使用 relationship.js 库计算中文亲属关系
|
||||
*/
|
||||
export class RelationshipCalculator {
|
||||
private members: Map<string, FamilyMember>
|
||||
|
||||
constructor(members: FamilyMember[]) {
|
||||
this.members = new Map(members.map(m => [m.id, m]))
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两个成员之间的关系
|
||||
* @param fromId 起始成员ID(成员A)
|
||||
* @param toId 目标成员ID(成员B)
|
||||
* @returns 关系描述(toId 对 fromId 的称谓,即B是A的XXX)
|
||||
*/
|
||||
getRelationship(fromId: string, toId: string): RelationshipResult {
|
||||
if (fromId === toId) {
|
||||
return {
|
||||
term: '本人',
|
||||
path: '',
|
||||
success: true
|
||||
}
|
||||
}
|
||||
|
||||
const fromMember = this.members.get(fromId)
|
||||
const toMember = this.members.get(toId)
|
||||
|
||||
if (!fromMember || !toMember) {
|
||||
return {
|
||||
term: '未知',
|
||||
path: '',
|
||||
success: false,
|
||||
error: '成员不存在'
|
||||
}
|
||||
}
|
||||
|
||||
// 构建关系路径(从 fromId 到 toId)
|
||||
const path = this.buildRelationPath(fromId, toId)
|
||||
|
||||
if (!path) {
|
||||
return {
|
||||
term: '无血缘关系',
|
||||
path: '',
|
||||
success: false
|
||||
}
|
||||
}
|
||||
|
||||
// 将路径转换为中文
|
||||
const chinesePath = this.pathToChineseText(path)
|
||||
|
||||
// 使用 relationship.js 计算关系
|
||||
try {
|
||||
// 获取fromId成员的性别(从谁的角度看关系)
|
||||
const fromMemberGender = fromMember.gender === 'FEMALE' ? 0 : 1
|
||||
|
||||
// 计算关系(toId 对 fromId 的称谓)
|
||||
const result = relationship({
|
||||
text: chinesePath,
|
||||
target: '',
|
||||
sex: fromMemberGender, // 传入fromId的性别(从谁的角度看)
|
||||
reverse: true // 使用反向,因为路径是从A到B,但我们要的是B对A的称谓
|
||||
})
|
||||
|
||||
const term = Array.isArray(result) && result.length > 0 ? result[0] : '亲戚'
|
||||
|
||||
return {
|
||||
term,
|
||||
path: chinesePath,
|
||||
success: true
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
term: '亲戚',
|
||||
path: chinesePath,
|
||||
success: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建关系路径字符串
|
||||
* 例如:'f' = 父亲, 'm' = 母亲, 'h' = 丈夫, 'w' = 妻子
|
||||
* 'ob' = 哥哥, 'lb' = 弟弟, 'os' = 姐姐, 'ls' = 妹妹
|
||||
*/
|
||||
private buildRelationPath(fromId: string, toId: string): string | null {
|
||||
// 使用BFS查找最短路径
|
||||
const queue: Array<{ id: string; path: string }> = [{ id: fromId, path: '' }]
|
||||
const visited = new Set<string>()
|
||||
|
||||
while (queue.length > 0) {
|
||||
const { id, path } = queue.shift()!
|
||||
|
||||
if (id === toId) {
|
||||
return path
|
||||
}
|
||||
|
||||
if (visited.has(id)) continue
|
||||
visited.add(id)
|
||||
|
||||
const member = this.members.get(id)
|
||||
if (!member) continue
|
||||
|
||||
// 向上:父亲
|
||||
if (member.fatherId && !visited.has(member.fatherId)) {
|
||||
queue.push({ id: member.fatherId, path: path + 'f' })
|
||||
}
|
||||
|
||||
// 向上:母亲
|
||||
if (member.motherId && !visited.has(member.motherId)) {
|
||||
queue.push({ id: member.motherId, path: path + 'm' })
|
||||
}
|
||||
|
||||
// 配偶关系
|
||||
if (member.spouseIds) {
|
||||
for (const spouseId of member.spouseIds) {
|
||||
if (!visited.has(spouseId)) {
|
||||
const spouse = this.members.get(spouseId)
|
||||
if (spouse) {
|
||||
const spousePath = member.gender === 'MALE' ? 'w' : 'h'
|
||||
queue.push({ id: spouseId, path: path + spousePath })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 向下:子女
|
||||
if (member.childrenIds) {
|
||||
for (const childId of member.childrenIds) {
|
||||
if (!visited.has(childId)) {
|
||||
const child = this.members.get(childId)
|
||||
if (child) {
|
||||
const childPath = child.gender === 'MALE' ? 's' : 'd'
|
||||
queue.push({ id: childId, path: path + childPath })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 兄弟姐妹(通过父母查找)
|
||||
if (member.fatherId || member.motherId) {
|
||||
const siblings = this.getSiblings(id)
|
||||
for (const siblingId of siblings) {
|
||||
if (!visited.has(siblingId)) {
|
||||
const sibling = this.members.get(siblingId)
|
||||
if (sibling) {
|
||||
// 需要比较年龄确定是哥哥/弟弟/姐姐/妹妹
|
||||
const siblingPath = this.getSiblingPath(member, sibling)
|
||||
queue.push({ id: siblingId, path: path + siblingPath })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取兄弟姐妹
|
||||
*/
|
||||
private getSiblings(memberId: string): string[] {
|
||||
const member = this.members.get(memberId)
|
||||
if (!member) return []
|
||||
|
||||
const siblings: string[] = []
|
||||
|
||||
// 通过父亲查找
|
||||
if (member.fatherId) {
|
||||
const father = this.members.get(member.fatherId)
|
||||
if (father?.childrenIds) {
|
||||
siblings.push(...father.childrenIds.filter(id => id !== memberId))
|
||||
}
|
||||
}
|
||||
|
||||
// 通过母亲查找
|
||||
if (member.motherId) {
|
||||
const mother = this.members.get(member.motherId)
|
||||
if (mother?.childrenIds) {
|
||||
for (const childId of mother.childrenIds) {
|
||||
if (childId !== memberId && !siblings.includes(childId)) {
|
||||
siblings.push(childId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return siblings
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取兄弟姐妹关系路径
|
||||
*/
|
||||
private getSiblingPath(from: FamilyMember, to: FamilyMember): string {
|
||||
const fromAge = this.getAge(from)
|
||||
const toAge = this.getAge(to)
|
||||
|
||||
if (to.gender === 'MALE') {
|
||||
// 男性:哥哥(ob) 或 弟弟(lb)
|
||||
return toAge > fromAge ? 'ob' : 'lb'
|
||||
} else {
|
||||
// 女性:姐姐(os) 或 妹妹(ls)
|
||||
return toAge > fromAge ? 'os' : 'ls'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取年龄(用于比较)
|
||||
*/
|
||||
private getAge(member: FamilyMember): number {
|
||||
if (!member.birthDate) return 0
|
||||
const birthYear = new Date(member.birthDate).getFullYear()
|
||||
return new Date().getFullYear() - birthYear
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取关系的详细说明
|
||||
*/
|
||||
getRelationshipDetail(fromId: string, toId: string): RelationshipDetail {
|
||||
const result = this.getRelationship(fromId, toId)
|
||||
|
||||
if (!result.success) {
|
||||
return {
|
||||
...result,
|
||||
description: result.error || '无法计算关系'
|
||||
}
|
||||
}
|
||||
|
||||
// 构建带人名的路径(从 fromId 到 toId)
|
||||
const pathWithNames = this.buildPathWithNames(fromId, toId)
|
||||
|
||||
// 只返回关系称谓,不包含完整句子
|
||||
return {
|
||||
...result,
|
||||
path: pathWithNames || result.path,
|
||||
description: result.term
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建带人名的路径描述
|
||||
* @param fromId 起始ID(查询的起点)
|
||||
* @param toId 目标ID(查询的终点)
|
||||
*/
|
||||
private buildPathWithNames(fromId: string, toId: string): string | null {
|
||||
const queue: Array<{ id: string; path: Array<{name: string, relation: string}> }> = [
|
||||
{ id: fromId, path: [] }
|
||||
]
|
||||
const visited = new Set<string>()
|
||||
|
||||
// 获取起始成员名字
|
||||
const startMember = this.members.get(fromId)
|
||||
const startName = startMember?.fullName || '未知'
|
||||
|
||||
while (queue.length > 0) {
|
||||
const { id, path } = queue.shift()!
|
||||
|
||||
if (id === toId) {
|
||||
// 构建路径字符串:从起点到终点
|
||||
if (path.length === 0) return '本人'
|
||||
|
||||
// 格式:起点 → 关系1(人名1) → 关系2(人名2) → ...
|
||||
const pathStr = path.map(p => `${p.relation}(${p.name})`).join(' → ')
|
||||
return `${startName} → ${pathStr}`
|
||||
}
|
||||
|
||||
if (visited.has(id)) continue
|
||||
visited.add(id)
|
||||
|
||||
const member = this.members.get(id)
|
||||
if (!member) continue
|
||||
|
||||
// 向上:父亲
|
||||
if (member.fatherId && !visited.has(member.fatherId)) {
|
||||
const father = this.members.get(member.fatherId)
|
||||
if (father) {
|
||||
queue.push({
|
||||
id: member.fatherId,
|
||||
path: [...path, { name: father.fullName, relation: '父亲' }]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 向上:母亲
|
||||
if (member.motherId && !visited.has(member.motherId)) {
|
||||
const mother = this.members.get(member.motherId)
|
||||
if (mother) {
|
||||
queue.push({
|
||||
id: member.motherId,
|
||||
path: [...path, { name: mother.fullName, relation: '母亲' }]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 配偶关系
|
||||
if (member.spouseIds) {
|
||||
for (const spouseId of member.spouseIds) {
|
||||
if (!visited.has(spouseId)) {
|
||||
const spouse = this.members.get(spouseId)
|
||||
if (spouse) {
|
||||
const relation = member.gender === 'MALE' ? '妻子' : '丈夫'
|
||||
queue.push({
|
||||
id: spouseId,
|
||||
path: [...path, { name: spouse.fullName, relation }]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 向下:子女
|
||||
if (member.childrenIds) {
|
||||
for (const childId of member.childrenIds) {
|
||||
if (!visited.has(childId)) {
|
||||
const child = this.members.get(childId)
|
||||
if (child) {
|
||||
const relation = child.gender === 'MALE' ? '儿子' : '女儿'
|
||||
queue.push({
|
||||
id: childId,
|
||||
path: [...path, { name: child.fullName, relation }]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 兄弟姐妹
|
||||
if (member.fatherId || member.motherId) {
|
||||
const siblings = this.getSiblings(id)
|
||||
for (const siblingId of siblings) {
|
||||
if (!visited.has(siblingId)) {
|
||||
const sibling = this.members.get(siblingId)
|
||||
if (sibling) {
|
||||
const siblingPath = this.getSiblingRelationName(member, sibling)
|
||||
queue.push({
|
||||
id: siblingId,
|
||||
path: [...path, { name: sibling.fullName, relation: siblingPath }]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取兄弟姐妹关系名称
|
||||
*/
|
||||
private getSiblingRelationName(from: FamilyMember, to: FamilyMember): string {
|
||||
const fromAge = this.getAge(from)
|
||||
const toAge = this.getAge(to)
|
||||
|
||||
if (to.gender === 'MALE') {
|
||||
return toAge > fromAge ? '哥哥' : '弟弟'
|
||||
} else {
|
||||
return toAge > fromAge ? '姐姐' : '妹妹'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算路径长度(关系代数)
|
||||
*/
|
||||
private calculatePathLength(path: string): number {
|
||||
let length = 0
|
||||
let i = 0
|
||||
|
||||
while (i < path.length) {
|
||||
// 两字符的关系
|
||||
if (i + 1 < path.length) {
|
||||
const twoChar = path.substring(i, i + 2)
|
||||
if (['ob', 'lb', 'os', 'ls'].includes(twoChar)) {
|
||||
length++
|
||||
i += 2
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 单字符的关系
|
||||
length++
|
||||
i++
|
||||
}
|
||||
|
||||
return length
|
||||
}
|
||||
|
||||
/**
|
||||
* 将符号路径转换为中文文本
|
||||
* 例如:'fm' -> '父亲的母亲'
|
||||
*/
|
||||
private pathToChineseText(path: string): string {
|
||||
const pathMap: Record<string, string> = {
|
||||
'f': '父亲',
|
||||
'm': '母亲',
|
||||
'h': '丈夫',
|
||||
'w': '妻子',
|
||||
's': '儿子',
|
||||
'd': '女儿',
|
||||
'ob': '哥哥',
|
||||
'lb': '弟弟',
|
||||
'os': '姐姐',
|
||||
'ls': '妹妹'
|
||||
}
|
||||
|
||||
const parts: string[] = []
|
||||
let i = 0
|
||||
|
||||
while (i < path.length) {
|
||||
// 处理两字符的关系(如 ob, lb, os, ls)
|
||||
if (i + 1 < path.length) {
|
||||
const twoChar = path.substring(i, i + 2)
|
||||
if (pathMap[twoChar]) {
|
||||
parts.push(pathMap[twoChar])
|
||||
i += 2
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 处理单字符的关系
|
||||
const oneChar = path[i]
|
||||
if (pathMap[oneChar]) {
|
||||
parts.push(pathMap[oneChar])
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
return parts.join('的')
|
||||
}
|
||||
|
||||
/**
|
||||
* 将路径转换为中文描述(带"的"字)
|
||||
*/
|
||||
private getPathDescription(path: string): string {
|
||||
const pathMap: Record<string, string> = {
|
||||
'f': '的父亲',
|
||||
'm': '的母亲',
|
||||
'h': '的丈夫',
|
||||
'w': '的妻子',
|
||||
's': '的儿子',
|
||||
'd': '的女儿',
|
||||
'ob': '的哥哥',
|
||||
'lb': '的弟弟',
|
||||
'os': '的姐姐',
|
||||
'ls': '的妹妹'
|
||||
}
|
||||
|
||||
let description = ''
|
||||
for (const char of path) {
|
||||
description += pathMap[char] || ''
|
||||
}
|
||||
|
||||
return description || '本人'
|
||||
}
|
||||
}
|
||||
|
||||
export interface RelationshipResult {
|
||||
term: string // 关系称谓(如:父亲、堂兄弟)
|
||||
path: string // 关系路径(如:f, fbs)
|
||||
success: boolean // 是否成功计算
|
||||
error?: string // 错误信息
|
||||
}
|
||||
|
||||
export interface RelationshipDetail extends RelationshipResult {
|
||||
description: string // 关系描述(如:父亲的哥哥的儿子)
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"lastValidatedTimestamp": 1763866577979,
|
||||
"lastValidatedTimestamp": 1763876009919,
|
||||
"projects": {},
|
||||
"pnpmfiles": [],
|
||||
"settings": {
|
||||
|
||||
+8
@@ -203,6 +203,9 @@ importers:
|
||||
recharts:
|
||||
specifier: 2.15.4
|
||||
version: 2.15.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
relationship.js:
|
||||
specifier: ^1.2.7
|
||||
version: 1.2.7
|
||||
sonner:
|
||||
specifier: ^1.7.4
|
||||
version: 1.7.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
@@ -2613,6 +2616,9 @@ packages:
|
||||
regenerator-runtime@0.13.11:
|
||||
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
||||
|
||||
relationship.js@1.2.7:
|
||||
resolution: {integrity: sha512-+wARUY8K9536P677Ee1GoPvrH5GdK2o1urR0n/r7nFVCYv/v6Lvo2FrXrlasHKZFPEGyrIU0xFYMnZ0tYf93SA==}
|
||||
|
||||
resolve-pkg-maps@1.0.0:
|
||||
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
|
||||
|
||||
@@ -5459,6 +5465,8 @@ snapshots:
|
||||
regenerator-runtime@0.13.11:
|
||||
optional: true
|
||||
|
||||
relationship.js@1.2.7: {}
|
||||
|
||||
resolve-pkg-maps@1.0.0: {}
|
||||
|
||||
rgbcolor@1.0.1:
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
"reactflow": "^11.11.4",
|
||||
"read-gedcom": "^0.3.2",
|
||||
"recharts": "2.15.4",
|
||||
"relationship.js": "^1.2.7",
|
||||
"sonner": "^1.7.4",
|
||||
"tailwind-merge": "^2.5.5",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
|
||||
Generated
+8
@@ -203,6 +203,9 @@ importers:
|
||||
recharts:
|
||||
specifier: 2.15.4
|
||||
version: 2.15.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
relationship.js:
|
||||
specifier: ^1.2.7
|
||||
version: 1.2.7
|
||||
sonner:
|
||||
specifier: ^1.7.4
|
||||
version: 1.7.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
@@ -2613,6 +2616,9 @@ packages:
|
||||
regenerator-runtime@0.13.11:
|
||||
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
||||
|
||||
relationship.js@1.2.7:
|
||||
resolution: {integrity: sha512-+wARUY8K9536P677Ee1GoPvrH5GdK2o1urR0n/r7nFVCYv/v6Lvo2FrXrlasHKZFPEGyrIU0xFYMnZ0tYf93SA==}
|
||||
|
||||
resolve-pkg-maps@1.0.0:
|
||||
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
|
||||
|
||||
@@ -5459,6 +5465,8 @@ snapshots:
|
||||
regenerator-runtime@0.13.11:
|
||||
optional: true
|
||||
|
||||
relationship.js@1.2.7: {}
|
||||
|
||||
resolve-pkg-maps@1.0.0: {}
|
||||
|
||||
rgbcolor@1.0.1:
|
||||
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
declare module 'relationship.js' {
|
||||
interface RelationshipOptions {
|
||||
text: string // 关系文本,如"父亲的母亲"
|
||||
target?: string // 相对对象
|
||||
sex?: number // 性别:0女性,1男性,-1不限
|
||||
type?: string // 转换类型
|
||||
reverse?: boolean // 称呼方式
|
||||
mode?: string // 模式选择
|
||||
optimal?: boolean // 最短关系
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算中文亲属关系
|
||||
* @param options 关系选项
|
||||
* @returns 关系称谓数组
|
||||
*/
|
||||
function relationship(options: RelationshipOptions): string[]
|
||||
export default relationship
|
||||
}
|
||||
Reference in New Issue
Block a user