six-degrees 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +4 -0
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +42 -14
- package/.next/standalone/.next/routes-manifest.json +24 -0
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +26 -18
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +26 -18
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +25 -16
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/admin-delete/route.js +2 -2
- package/.next/standalone/.next/server/app/api/admin-delete/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/admin-update/route.js +2 -2
- package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/bridges/route.js +2 -2
- package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/bulk-import/route.js +2 -2
- package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js +3 -3
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/company-scores/route.js +3 -3
- package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/connections/route.js +2 -2
- package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/backup/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/backup/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/backup/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/backup/route.js +7 -0
- package/.next/standalone/.next/server/app/api/data/backup/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/backup/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/backup/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/data/csv/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/csv/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/csv/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/csv/route.js +8 -0
- package/.next/standalone/.next/server/app/api/data/csv/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/csv/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/csv/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/data/export/route.js +1 -1
- package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/import/route.js +1 -1
- package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/restart/route.js +1 -1
- package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/restore/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/restore/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/restore/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/restore/route.js +7 -0
- package/.next/standalone/.next/server/app/api/data/restore/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/restore/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/restore/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/data/reveal/route.js +1 -1
- package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/route.js +1 -1
- package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/delete-cluster/route.js +2 -2
- package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/route.js +2 -2
- package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/network/route.js +2 -2
- package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/outreach/route.js +3 -3
- package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/queue/route.js +2 -2
- package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/scraper/route.js +5 -3
- package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/route.js +3 -3
- package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js +3 -3
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js +3 -3
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/setup-profile/route.js +2 -2
- package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/social/crm/route.js +1 -1
- package/.next/standalone/.next/server/app/api/social/crm/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/social/messages/route.js +1 -1
- package/.next/standalone/.next/server/app/api/social/messages/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/social/route.js +2 -2
- package/.next/standalone/.next/server/app/api/social/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/unlock/route.js +2 -2
- package/.next/standalone/.next/server/app/api/unlock/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/update-images/route.js +2 -2
- package/.next/standalone/.next/server/app/api/update-images/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/users/route.js +2 -2
- package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/avatars/[file]/route.js +1 -1
- package/.next/standalone/.next/server/app/avatars/[file]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/import/page.js +1 -1
- package/.next/standalone/.next/server/app/import/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/import/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/import.html +1 -1
- package/.next/standalone/.next/server/app/import.rsc +32 -24
- package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +32 -24
- package/.next/standalone/.next/server/app/import.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/import.segments/import/__PAGE__.segment.rsc +23 -18
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +29 -22
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +20 -15
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +29 -22
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/insights/page/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/insights/page/build-manifest.json +20 -0
- package/.next/standalone/.next/server/app/insights/page/next-font-manifest.json +11 -0
- package/.next/standalone/.next/server/app/insights/page/react-loadable-manifest.json +1 -0
- package/.next/standalone/.next/server/app/insights/page/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/insights/page.js +13 -0
- package/.next/standalone/.next/server/app/insights/page.js.map +5 -0
- package/.next/standalone/.next/server/app/insights/page.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/insights/page_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/insights.html +1 -0
- package/.next/standalone/.next/server/app/insights.meta +26 -0
- package/.next/standalone/.next/server/app/insights.rsc +35 -0
- package/.next/standalone/.next/server/app/insights.segments/_full.segment.rsc +35 -0
- package/.next/standalone/.next/server/app/insights.segments/_tree.segment.rsc +4 -0
- package/.next/standalone/.next/server/app/insights.segments/insights/__PAGE__.segment.rsc +33 -0
- package/.next/standalone/.next/server/app/launch/page.js +1 -1
- package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/launch.html +2 -2
- package/.next/standalone/.next/server/app/launch.rsc +32 -24
- package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +32 -24
- package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +23 -18
- package/.next/standalone/.next/server/app/page.js +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/paths/page.js +1 -1
- package/.next/standalone/.next/server/app/paths/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/paths.html +1 -1
- package/.next/standalone/.next/server/app/paths.rsc +32 -24
- package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +32 -24
- package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +21 -18
- package/.next/standalone/.next/server/app/profile/page.js +1 -1
- package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/profile.html +1 -1
- package/.next/standalone/.next/server/app/profile.rsc +32 -24
- package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +32 -24
- package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +23 -18
- package/.next/standalone/.next/server/app/queue/page.js +1 -1
- package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/queue.html +1 -1
- package/.next/standalone/.next/server/app/queue.rsc +32 -24
- package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +32 -24
- package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +21 -18
- package/.next/standalone/.next/server/app/scores/page.js +1 -1
- package/.next/standalone/.next/server/app/scores/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/scores/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/scores.html +1 -1
- package/.next/standalone/.next/server/app/scores.rsc +32 -24
- package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +32 -24
- package/.next/standalone/.next/server/app/scores.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/scores.segments/scores/__PAGE__.segment.rsc +23 -18
- package/.next/standalone/.next/server/app/settings/page.js +1 -1
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings.html +1 -1
- package/.next/standalone/.next/server/app/settings.rsc +32 -24
- package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +32 -24
- package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +20 -18
- package/.next/standalone/.next/server/app/setup/page.js +1 -1
- package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup.html +1 -1
- package/.next/standalone/.next/server/app/setup.rsc +32 -24
- package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +32 -24
- package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +21 -18
- package/.next/standalone/.next/server/app/social/page.js +1 -1
- package/.next/standalone/.next/server/app/social/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/social.html +1 -1
- package/.next/standalone/.next/server/app/social.rsc +32 -24
- package/.next/standalone/.next/server/app/social.segments/_full.segment.rsc +32 -24
- package/.next/standalone/.next/server/app/social.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/social.segments/social/__PAGE__.segment.rsc +23 -18
- package/.next/standalone/.next/server/app-paths-manifest.json +4 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__00la_y0._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__05_3-22._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__066rab1._.js +7 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07t47cm._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cj5jqc._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e0fei3._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fooke1._.js +7 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljnyho._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o5-tcg._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qrnous._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__15wc9e-._.js → [root-of-the-server]__0r-0t-9._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ra6xyg._.js +15 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__20rwfdw._.js → [root-of-the-server]__0rcpjad._.js} +6 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t3v1a1._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t6y79e._.js +7 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wmexuc._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0x29muh._.js +7 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xu34sz._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__133knx1._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__15-17hl._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__19b7mig._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a_6x37._.js +8 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1an_8pa._.js +7 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1bbcwub._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ducpz2._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1eris29._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1gjo_cq._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qcm08_._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tir0vc._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1w25q0m._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1xhyinn._.js +3 -0
- package/.next/standalone/.next/server/chunks/_072jl0y._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0lw8_i0._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0sqqpzb._.js +3 -0
- package/.next/standalone/.next/server/chunks/_1_fynia._.js +7 -7
- package/.next/standalone/.next/server/chunks/_1fn30_l._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1itd1o_._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1iwkh8t._.js +1 -1
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_backup_route_actions_0zoj04p.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_csv_route_actions_0l6m7lg.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_restore_route_actions_0-b05bv.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_02iz_9q._.js +4 -0
- package/.next/standalone/.next/server/chunks/lib_05agvk3._.js +4 -0
- package/.next/standalone/.next/server/chunks/lib_0v84u66._.js +4 -0
- package/.next/standalone/.next/server/chunks/lib_db-client_0_dch35.js +174 -0
- package/.next/standalone/.next/server/chunks/lib_linkedin-export_12imqxg.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_rpc_00nndai.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_03ibb-x.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_03ri3ji.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_078ce48.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0a69mgr.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +7 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0cej3t8.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0cmh4g6.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0nx2_pc.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0r79-w1.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0t552z6.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0yx8ynd.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_12p-o9-.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1466dnb.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1sryxv6.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1trn-x5.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1ygu_mv.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0egamyq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qd8pzm._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qdeuyo._.js → [root-of-the-server]__1-012q1._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_04am_h8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_06rgzfh._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_07zb7lu._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0_79idq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0gds903._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0hb-dhy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0klqt9z._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_14jak5s._.js +7 -0
- package/.next/standalone/.next/server/chunks/ssr/_14nxd3q._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1cj2yog._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1fm1ih_._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1hdqw0-._.js +7 -0
- package/.next/standalone/.next/server/chunks/ssr/_1k2nmbw._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1r62six._.js +7 -0
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_insights_page_actions_0-0tf75.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_141w189._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_components_0uuff77._.js +25 -2
- package/.next/standalone/.next/server/chunks/ssr/app_components_1j3q-h5._.js +25 -2
- package/.next/standalone/.next/server/chunks/ssr/app_components_CompanyScores_1g0mytz.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_components_settings_SectorPicker_1c-29qw.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_components_ui_0pdmz2z.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_import_page_1fmu6_l.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_insights_page_1d_chja.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_launch_page_19t0dyd.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +26 -14
- package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_profile_page_0u3-l5y.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_queue_page_0c6znd6.js +11 -11
- package/.next/standalone/.next/server/chunks/ssr/app_settings_page_1f8mjj_.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +12 -13
- package/.next/standalone/.next/server/chunks/ssr/app_social_page_0h7zxda.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{lib_1c4ieuw._.js → lib_csv_1ttiu_h.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/lib_galaxy-lab_108_lu-.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/lib_separation_1305zsx.js +3 -0
- package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0pco7a6._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- package/.next/standalone/.next/server/next-font-manifest.js +1 -1
- package/.next/standalone/.next/server/next-font-manifest.json +4 -0
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/prefetch-hints.json +14 -0
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/02wnf8dkxegxg.js +34 -0
- package/.next/standalone/.next/static/chunks/03-_esd2x_yk6.js +1 -0
- package/.next/standalone/.next/static/chunks/03-demj2iy-0p.js +44 -0
- package/.next/standalone/.next/static/chunks/0838_s6w-i_ik.js +1 -0
- package/.next/standalone/.next/static/chunks/0_1r-3csplxnj.js +1 -0
- package/.next/standalone/.next/static/chunks/0ka4prpk3w9wn.js +34 -0
- package/.next/standalone/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
- package/.next/standalone/.next/static/chunks/0s_xxwp7z88vv.js +1 -0
- package/.next/standalone/.next/static/chunks/1-nnl8amfm4yh.js +57 -0
- package/.next/standalone/.next/static/chunks/112mv-com-mqa.js +21 -0
- package/.next/standalone/.next/static/chunks/1bkt_hhjzvbh8.js +1 -0
- package/.next/standalone/.next/static/chunks/1cmphb3kh2ers.css +3 -0
- package/.next/standalone/.next/static/chunks/1d8yv3k_atka7.js +1 -0
- package/.next/standalone/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
- package/.next/standalone/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
- package/.next/standalone/.next/static/chunks/23hc51oa4vkhc.js +5 -0
- package/.next/standalone/.next/static/chunks/27n8k9wxlz5-7.js +1 -0
- package/.next/standalone/.next/static/chunks/2q9i7pcxcnph1.js +7 -0
- package/.next/standalone/.next/static/chunks/2w-y83mjlpnse.js +1 -0
- package/.next/standalone/.next/static/chunks/2ws1xf293j-tm.js +5 -0
- package/.next/standalone/.next/static/chunks/2z1-q0_vunbql.js +2 -0
- package/.next/standalone/.next/static/chunks/34g73qhayuevu.js +1 -0
- package/.next/standalone/.next/static/chunks/3cqn-r-y5rrw1.js +5 -0
- package/.next/standalone/.next/static/chunks/3opgg1efrx8q6.js +1 -0
- package/.next/standalone/.next/static/chunks/3p51fpxxi4d5y.js +34 -0
- package/.next/standalone/.next/static/chunks/3y40z6of3r9py.js +1 -0
- package/.next/standalone/.next/static/chunks/403dpflln8ah5.js +1 -0
- package/.next/standalone/.next/static/chunks/43pg2sursiypz.js +1 -0
- package/.next/standalone/CHANGELOG.md +203 -0
- package/.next/standalone/README.md +96 -50
- package/.next/standalone/SECURITY.md +25 -11
- package/.next/standalone/app/api/data/backup/route.js +25 -0
- package/.next/standalone/app/api/data/csv/route.js +74 -0
- package/.next/standalone/app/api/data/export/route.js +1 -1
- package/.next/standalone/app/api/data/restore/route.js +48 -0
- package/.next/standalone/app/api/data/reveal/route.js +19 -6
- package/.next/standalone/app/api/data/route.js +15 -4
- package/.next/standalone/app/api/ingest/route.js +1 -1
- package/.next/standalone/app/api/outreach/route.js +13 -73
- package/.next/standalone/app/api/queue/route.js +1 -1
- package/.next/standalone/app/api/scraper/route.js +217 -36
- package/.next/standalone/app/api/social/crm/route.js +2 -1
- package/.next/standalone/app/components/AppHeader.js +41 -21
- package/.next/standalone/app/components/AppTabs.js +12 -8
- package/.next/standalone/app/components/AutoConnect.js +286 -0
- package/.next/standalone/app/components/AutoScanButton.js +2 -2
- package/.next/standalone/app/components/Avatar.js +1 -1
- package/.next/standalone/app/components/ChainView.js +258 -113
- package/.next/standalone/app/components/CirclePanel.js +16 -16
- package/.next/standalone/app/components/ClusterSpinner.js +64 -0
- package/.next/standalone/app/components/CompanyScores.js +20 -20
- package/.next/standalone/app/components/EmptyState.js +39 -18
- package/.next/standalone/app/components/FieldStep.js +15 -13
- package/.next/standalone/app/components/FilterPanel.js +25 -18
- package/.next/standalone/app/components/ForceGraph.js +49 -14
- package/.next/standalone/app/components/GalaxyLab.js +33 -33
- package/.next/standalone/app/components/GridView.js +18 -18
- package/.next/standalone/app/components/LegacyScoresCard.js +10 -11
- package/.next/standalone/app/components/LinkedInLimits.js +57 -27
- package/.next/standalone/app/components/LiquidGlass.js +99 -0
- package/.next/standalone/app/components/ListView.js +20 -20
- package/.next/standalone/app/components/MapControls.js +5 -5
- package/.next/standalone/app/components/MappingProgress.js +16 -16
- package/.next/standalone/app/components/NoteDetail.js +13 -13
- package/.next/standalone/app/components/OnboardingGate.js +4 -4
- package/.next/standalone/app/components/OutlinkQuest.js +56 -35
- package/.next/standalone/app/components/PathsAnalyzer.js +37 -36
- package/.next/standalone/app/components/PeopleMap.js +21 -21
- package/.next/standalone/app/components/RingsView.js +11 -11
- package/.next/standalone/app/components/ScanRadar.js +84 -39
- package/.next/standalone/app/components/ScanStatusBar.js +40 -21
- package/.next/standalone/app/components/ScanTrail.js +21 -8
- package/.next/standalone/app/components/SeparationView.js +172 -124
- package/.next/standalone/app/components/Sidebar.js +308 -199
- package/.next/standalone/app/components/StaleServerBanner.js +4 -4
- package/.next/standalone/app/components/TheirCircle.js +26 -26
- package/.next/standalone/app/components/ThemeDefs.js +42 -0
- package/.next/standalone/app/components/ThemeLoader.js +20 -1
- package/.next/standalone/app/components/UpdatePanel.js +22 -22
- package/.next/standalone/app/components/UserProvider.js +22 -15
- package/.next/standalone/app/components/insights/Boards.js +275 -0
- package/.next/standalone/app/components/insights/PeopleView.js +266 -0
- package/.next/standalone/app/components/insights/Rail.js +156 -0
- package/.next/standalone/app/components/insights/Report.js +382 -0
- package/.next/standalone/app/components/insights/parts.js +239 -0
- package/.next/standalone/app/components/settings/AppearanceSection.js +47 -24
- package/.next/standalone/app/components/settings/DataSection.js +276 -109
- package/.next/standalone/app/components/settings/NetworkHealthSection.js +13 -13
- package/.next/standalone/app/components/settings/SectorPicker.js +12 -12
- package/.next/standalone/app/components/settings/SectorSection.js +13 -14
- package/.next/standalone/app/components/settings/TierSection.js +9 -9
- package/.next/standalone/app/components/settings/TitleSection.js +11 -11
- package/.next/standalone/app/components/settings/UsageSection.js +360 -0
- package/.next/standalone/app/components/ui.js +8 -8
- package/.next/standalone/app/globals.css +161 -5
- package/.next/standalone/app/import/page.js +94 -38
- package/.next/standalone/app/insights/page.js +220 -0
- package/.next/standalone/app/launch/page.js +5 -5
- package/.next/standalone/app/layout.js +6 -2
- package/.next/standalone/app/page.js +53 -53
- package/.next/standalone/app/paths/page.js +63 -63
- package/.next/standalone/app/profile/page.js +58 -58
- package/.next/standalone/app/queue/page.js +84 -72
- package/.next/standalone/app/scores/page.js +2 -2
- package/.next/standalone/app/settings/page.js +16 -13
- package/.next/standalone/app/setup/page.js +236 -133
- package/.next/standalone/app/social/Crm.js +63 -62
- package/.next/standalone/app/social/SocialHub.js +22 -22
- package/.next/standalone/app/social/Thread.js +7 -7
- package/.next/standalone/app/social/page.js +2 -2
- package/.next/standalone/lib/auto-connect.js +145 -0
- package/.next/standalone/lib/backups.js +458 -0
- package/.next/standalone/lib/chain-layout.js +32 -0
- package/.next/standalone/lib/companies.js +1 -1
- package/.next/standalone/lib/csv-store.js +131 -0
- package/.next/standalone/lib/csv.js +137 -39
- package/.next/standalone/lib/data-folder.js +19 -3
- package/.next/standalone/lib/data-import.js +5 -2
- package/.next/standalone/lib/db-client.js +78 -20
- package/.next/standalone/lib/demo.js +5 -4
- package/.next/standalone/lib/galaxy-export.js +9 -2
- package/.next/standalone/lib/galaxy-lab.js +19 -5
- package/.next/standalone/lib/galaxy-layouts.js +43 -0
- package/.next/standalone/lib/gate.js +10 -4
- package/.next/standalone/lib/in-progress.js +46 -0
- package/.next/standalone/lib/ingest.js +1 -1
- package/.next/standalone/lib/insights-board.js +613 -0
- package/.next/standalone/lib/linkedin-limits.js +240 -14
- package/.next/standalone/lib/liquid-glass.js +59 -0
- package/.next/standalone/lib/notifications.js +13 -0
- package/.next/standalone/lib/requests-client.js +10 -0
- package/.next/standalone/lib/requests.js +124 -0
- package/.next/standalone/lib/scan-pace.js +11 -0
- package/.next/standalone/lib/scan-progress.js +20 -0
- package/.next/standalone/lib/scan-risk.js +44 -0
- package/.next/standalone/lib/scan-state.js +1 -0
- package/.next/standalone/lib/scanner-setup.js +97 -15
- package/.next/standalone/lib/scraper-client.js +35 -8
- package/.next/standalone/lib/search-risk.js +7 -3
- package/.next/standalone/lib/settings-client.js +5 -3
- package/.next/standalone/lib/settings.js +13 -0
- package/.next/standalone/lib/social-store.js +3 -2
- package/.next/standalone/lib/synced-setting.js +46 -0
- package/.next/standalone/lib/theme-store.js +42 -10
- package/.next/standalone/lib/themes.js +111 -21
- package/.next/standalone/lib/usage.js +200 -0
- package/.next/standalone/package-lock.json +2 -2
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/scripts/scrape.py +595 -11
- package/.next/static/chunks/02wnf8dkxegxg.js +34 -0
- package/.next/static/chunks/03-_esd2x_yk6.js +1 -0
- package/.next/static/chunks/03-demj2iy-0p.js +44 -0
- package/.next/static/chunks/0838_s6w-i_ik.js +1 -0
- package/.next/static/chunks/0_1r-3csplxnj.js +1 -0
- package/.next/static/chunks/0ka4prpk3w9wn.js +34 -0
- package/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
- package/.next/static/chunks/0s_xxwp7z88vv.js +1 -0
- package/.next/static/chunks/1-nnl8amfm4yh.js +57 -0
- package/.next/static/chunks/112mv-com-mqa.js +21 -0
- package/.next/static/chunks/1bkt_hhjzvbh8.js +1 -0
- package/.next/static/chunks/1cmphb3kh2ers.css +3 -0
- package/.next/static/chunks/1d8yv3k_atka7.js +1 -0
- package/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
- package/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
- package/.next/static/chunks/23hc51oa4vkhc.js +5 -0
- package/.next/static/chunks/27n8k9wxlz5-7.js +1 -0
- package/.next/static/chunks/2q9i7pcxcnph1.js +7 -0
- package/.next/static/chunks/2w-y83mjlpnse.js +1 -0
- package/.next/static/chunks/2ws1xf293j-tm.js +5 -0
- package/.next/static/chunks/2z1-q0_vunbql.js +2 -0
- package/.next/static/chunks/34g73qhayuevu.js +1 -0
- package/.next/static/chunks/3cqn-r-y5rrw1.js +5 -0
- package/.next/static/chunks/3opgg1efrx8q6.js +1 -0
- package/.next/static/chunks/3p51fpxxi4d5y.js +34 -0
- package/.next/static/chunks/3y40z6of3r9py.js +1 -0
- package/.next/static/chunks/403dpflln8ah5.js +1 -0
- package/.next/static/chunks/43pg2sursiypz.js +1 -0
- package/CHANGELOG.md +203 -0
- package/README.md +96 -50
- package/SECURITY.md +25 -11
- package/lib/auto-connect.js +145 -0
- package/lib/backups.js +458 -0
- package/lib/chain-layout.js +32 -0
- package/lib/companies.js +1 -1
- package/lib/csv-store.js +131 -0
- package/lib/csv.js +137 -39
- package/lib/data-folder.js +19 -3
- package/lib/data-import.js +5 -2
- package/lib/db-client.js +78 -20
- package/lib/demo.js +5 -4
- package/lib/galaxy-export.js +9 -2
- package/lib/galaxy-lab.js +19 -5
- package/lib/galaxy-layouts.js +43 -0
- package/lib/gate.js +10 -4
- package/lib/in-progress.js +46 -0
- package/lib/ingest.js +1 -1
- package/lib/insights-board.js +613 -0
- package/lib/linkedin-limits.js +240 -14
- package/lib/liquid-glass.js +59 -0
- package/lib/notifications.js +13 -0
- package/lib/requests-client.js +10 -0
- package/lib/requests.js +124 -0
- package/lib/scan-pace.js +11 -0
- package/lib/scan-progress.js +20 -0
- package/lib/scan-risk.js +44 -0
- package/lib/scan-state.js +1 -0
- package/lib/scanner-setup.js +97 -15
- package/lib/scraper-client.js +35 -8
- package/lib/search-risk.js +7 -3
- package/lib/settings-client.js +5 -3
- package/lib/settings.js +13 -0
- package/lib/social-store.js +3 -2
- package/lib/synced-setting.js +46 -0
- package/lib/theme-store.js +42 -10
- package/lib/themes.js +111 -21
- package/lib/usage.js +200 -0
- package/package.json +1 -1
- package/scripts/scrape.py +595 -11
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-rnla2._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__13dx4sd._.js +0 -8
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__14ou7j5._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__16iu0hv._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1kbl21f._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rphsdk._.js +0 -3
- package/.next/standalone/.next/server/chunks/_02twlca._.js +0 -10
- package/.next/standalone/.next/server/chunks/lib_0851sk0._.js +0 -8
- package/.next/standalone/.next/server/chunks/lib_1q7p2ro._.js +0 -8
- package/.next/standalone/.next/server/chunks/lib_1r6l86l._.js +0 -8
- package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +0 -174
- package/.next/standalone/.next/server/chunks/lib_rpc_04s8mzr.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_053z7as.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0b_-2te.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0dhbxdm.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0dxlk31.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0f8b-qc.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0pzie7_.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0r76fq_.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_0ut7pjp.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_15zyqaz.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_18zpjtq.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1a8xkiz.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1e_55xo.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1oxfd1_.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_rpc_1s0lod0.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08oxiqh._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_03l7vge._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_08g31gm._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0gk_ofx._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0nwsf93._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0vho1lb._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1-658fq._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1bc46kz._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1f_n00p._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_2105jz8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_components_0t908t-._.js +0 -3
- package/.next/standalone/.next/static/chunks/02pq76u7y4v9-.js +0 -22
- package/.next/standalone/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
- package/.next/standalone/.next/static/chunks/0i02yxppzds1o.js +0 -1
- package/.next/standalone/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
- package/.next/standalone/.next/static/chunks/0oyslj62jkubd.js +0 -1
- package/.next/standalone/.next/static/chunks/0vo-l8hxneba6.css +0 -3
- package/.next/standalone/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
- package/.next/standalone/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
- package/.next/standalone/.next/static/chunks/172e10mi-tpo_.js +0 -34
- package/.next/standalone/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
- package/.next/standalone/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
- package/.next/standalone/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
- package/.next/standalone/.next/static/chunks/1m3017gp790pw.js +0 -45
- package/.next/standalone/.next/static/chunks/1t20e8u0st7ep.js +0 -1
- package/.next/standalone/.next/static/chunks/2-ch9rm27eril.js +0 -11
- package/.next/standalone/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
- package/.next/standalone/.next/static/chunks/3bp284gjf7dyq.js +0 -1
- package/.next/standalone/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
- package/.next/standalone/.next/static/chunks/3l4t8je6iguzc.js +0 -1
- package/.next/standalone/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
- package/.next/standalone/.next/static/chunks/42m0bqr8pbovz.js +0 -11
- package/.next/static/chunks/02pq76u7y4v9-.js +0 -22
- package/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
- package/.next/static/chunks/0i02yxppzds1o.js +0 -1
- package/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
- package/.next/static/chunks/0oyslj62jkubd.js +0 -1
- package/.next/static/chunks/0vo-l8hxneba6.css +0 -3
- package/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
- package/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
- package/.next/static/chunks/172e10mi-tpo_.js +0 -34
- package/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
- package/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
- package/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
- package/.next/static/chunks/1m3017gp790pw.js +0 -45
- package/.next/static/chunks/1t20e8u0st7ep.js +0 -1
- package/.next/static/chunks/2-ch9rm27eril.js +0 -11
- package/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
- package/.next/static/chunks/3bp284gjf7dyq.js +0 -1
- package/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
- package/.next/static/chunks/3l4t8je6iguzc.js +0 -1
- package/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
- package/.next/static/chunks/42m0bqr8pbovz.js +0 -11
- /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_ssgManifest.js +0 -0
- /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_buildManifest.js +0 -0
- /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_ssgManifest.js +0 -0
package/lib/csv.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { scorePerson, curveCutoffs, curvedTier } from './scoring.js';
|
|
2
2
|
import { toIsoDate } from './ingest.js';
|
|
3
|
-
// LinkedIn Connections.csv import
|
|
3
|
+
// LinkedIn Connections.csv import, read in the browser.
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
5
|
+
// The file itself never leaves the page. What the map needs about each person
|
|
6
|
+
// goes to this computer's own server, which keeps it in the data folder
|
|
7
|
+
// (csv-network.json, lib/csv-store.js) so it's still there after the window
|
|
8
|
+
// closes. It's never written into the database or mixed with a scanned
|
|
9
|
+
// network, and nothing goes anywhere else.
|
|
8
10
|
//
|
|
9
11
|
// The official export carries six usable columns — First Name, Last Name,
|
|
10
12
|
// URL, Company, Position, Connected On. It has NO profile photos and no rich
|
|
@@ -55,7 +57,7 @@ export function scoreRecord(headline, company) {
|
|
|
55
57
|
* a CSV import uses the app's defaults, never your settings (no company
|
|
56
58
|
* scores, no sector), and the curve is the default, so the first look at any
|
|
57
59
|
* export has a top. Scores → Tiers says so while one is open. Run on the
|
|
58
|
-
* parse (the import page's counts) and on every load (the
|
|
60
|
+
* parse (the import page's counts) and on every load (the data folder keeps only
|
|
59
61
|
* what the export says, packConnections), so the two always agree.
|
|
60
62
|
*/
|
|
61
63
|
function gradeOnCurve(connections) {
|
|
@@ -154,20 +156,46 @@ export function parseConnectionsCsv(text) {
|
|
|
154
156
|
return { connections, skipped, total: connections.length + skipped };
|
|
155
157
|
}
|
|
156
158
|
|
|
157
|
-
// ──
|
|
158
|
-
|
|
159
|
+
// ── Where an open network is kept ──────────────────────────────────────────
|
|
160
|
+
// A CSV import is kept in the data folder through /api/data/csv
|
|
161
|
+
// (lib/csv-store.js) until × beside "Your CSV" removes it. It used to live in
|
|
162
|
+
// sessionStorage and was gone when the window closed (the 1.0 list,
|
|
163
|
+
// 2026-10-03: CSV imports survive closing the window).
|
|
164
|
+
//
|
|
165
|
+
// The sample network stays in this window only. It's a look around, not
|
|
166
|
+
// anyone's network, so it never goes into the data folder, a copy or a backup.
|
|
167
|
+
|
|
168
|
+
const SAMPLE_KEY = 'six-degrees-sample-network';
|
|
169
|
+
const CSV_ROUTE = '/api/data/csv';
|
|
170
|
+
|
|
171
|
+
export function saveSampleNetwork({ degree1 = [], degree2 = [] }) {
|
|
159
172
|
try {
|
|
160
|
-
sessionStorage.setItem(
|
|
173
|
+
sessionStorage.setItem(SAMPLE_KEY, JSON.stringify({ degree1, degree2, source: 'sample', importedAt: Date.now() }));
|
|
161
174
|
return true;
|
|
162
175
|
} catch {
|
|
163
|
-
return false; //
|
|
176
|
+
return false; // storage full or off
|
|
164
177
|
}
|
|
165
178
|
}
|
|
166
179
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
180
|
+
function sampleOpen() {
|
|
181
|
+
try { return !!sessionStorage.getItem(SAMPLE_KEY); } catch { return false; }
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function sampleNetwork() {
|
|
185
|
+
try {
|
|
186
|
+
const parsed = JSON.parse(sessionStorage.getItem(SAMPLE_KEY));
|
|
187
|
+
return parsed ? { degree1: parsed.degree1 || [], degree2: parsed.degree2 || [], source: 'sample' } : null;
|
|
188
|
+
} catch { return null; }
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function leaveSample() {
|
|
192
|
+
try { sessionStorage.removeItem(SAMPLE_KEY); } catch { /* storage off: nothing was kept */ }
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// The file keeps only what the export says about each person (~130 characters)
|
|
196
|
+
// and the page scores it again on every load, so it always follows the scoring
|
|
197
|
+
// model and LinkedIn's maximum of 30,000 connections is one request of about
|
|
198
|
+
// 4 MB, well under the 10 MB Next reads before middleware (docs/brain/ENDPOINTS.md).
|
|
171
199
|
export function packConnections(connections) {
|
|
172
200
|
return connections.map((c) => [c.id, c.name, c.role, c.company, c.profile_url, c.connected_date]);
|
|
173
201
|
}
|
|
@@ -177,41 +205,111 @@ export function unpackConnections(rows = []) {
|
|
|
177
205
|
.sort((a, b) => b.power_score - a.power_score);
|
|
178
206
|
}
|
|
179
207
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
208
|
+
/**
|
|
209
|
+
* Which network every page opens on: 'sample', 'csv' or 'own' (the database).
|
|
210
|
+
* The one rule, so the map, Paths, Settings and who "you" are can't disagree.
|
|
211
|
+
*
|
|
212
|
+
* The sample, opened in this window, is shown until it's left. A kept CSV
|
|
213
|
+
* import is shown only while the database has no 1st-degree people: once you
|
|
214
|
+
* have scanned your own connections, the scan is your network. When the CSV
|
|
215
|
+
* lived in the window, closing it handed the map back to the scan by itself;
|
|
216
|
+
* kept, it would otherwise hide every scan after it for good (the 1.0 review,
|
|
217
|
+
* 2026-10-03). The file itself stays on the disk, never deleted for you, and
|
|
218
|
+
* the import page says it's there and offers to remove it.
|
|
219
|
+
*/
|
|
220
|
+
export function openNetworkSource({ sample = false, csvKept = false, scannedFirstDegree = 0 } = {}) {
|
|
221
|
+
if (sample) return 'sample';
|
|
222
|
+
if (csvKept && !(Number(scannedFirstDegree) > 0)) return 'csv';
|
|
223
|
+
return 'own';
|
|
189
224
|
}
|
|
190
225
|
|
|
191
|
-
|
|
192
|
-
|
|
226
|
+
// The kept import, and how many 1st-degree people the database has, asked for
|
|
227
|
+
// once per page: who "you" are, the map, and the Settings sections all ask,
|
|
228
|
+
// and it's the same answer. Forgotten whenever it changes, since a link to
|
|
229
|
+
// another page keeps this module loaded.
|
|
230
|
+
let kept = null;
|
|
231
|
+
function keptCsv() {
|
|
232
|
+
kept ??= fetch(CSV_ROUTE, { cache: 'no-store' })
|
|
233
|
+
.then(async (r) => {
|
|
234
|
+
const j = await r.json().catch(() => ({}));
|
|
235
|
+
if (!r.ok) return { csv: null, scanned: 0, problem: `Your kept CSV import couldn't be loaded (${j.error || `the app answered ${r.status}`}).` };
|
|
236
|
+
return { csv: j.csv || null, scanned: Number(j.scanned) || 0, problem: j.problem || null };
|
|
237
|
+
})
|
|
238
|
+
// No answer at all: the app isn't running, and nothing else on the page will load either.
|
|
239
|
+
.catch(() => ({ csv: null, scanned: 0, problem: null }));
|
|
240
|
+
return kept;
|
|
193
241
|
}
|
|
194
242
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const raw = sessionStorage.getItem(STORAGE_KEY);
|
|
199
|
-
return raw ? JSON.parse(raw).source || 'csv' : null;
|
|
200
|
-
} catch { return null; }
|
|
243
|
+
async function opening() {
|
|
244
|
+
const k = await keptCsv();
|
|
245
|
+
return { ...k, source: openNetworkSource({ sample: sampleOpen(), csvKept: Boolean(k.csv), scannedFirstDegree: k.scanned }) };
|
|
201
246
|
}
|
|
202
247
|
|
|
203
|
-
|
|
248
|
+
/** The network open instead of the database: the sample or a kept CSV import (openNetworkSource), else null. */
|
|
249
|
+
export async function loadCsvNetwork() {
|
|
250
|
+
const { source, csv } = await opening();
|
|
251
|
+
if (source === 'sample') return sampleNetwork();
|
|
252
|
+
if (source !== 'csv') return null;
|
|
253
|
+
return { degree1: unpackConnections(csv.connections), degree2: [], source: 'csv', importedAt: csv.importedAt };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** 'sample' or 'csv' when one is open instead of the database, else null, without scoring it as loadCsvNetwork() does. */
|
|
257
|
+
export async function csvNetworkSource() {
|
|
258
|
+
const { source } = await opening();
|
|
259
|
+
return source === 'own' ? null : source;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* A CSV import kept here but not shown, because the database has your scanned
|
|
264
|
+
* connections: `{ people, importedAt }`, else null. The import page says so
|
|
265
|
+
* and offers to remove it.
|
|
266
|
+
*/
|
|
267
|
+
export async function keptBehindScan() {
|
|
268
|
+
const { source, csv } = await opening();
|
|
269
|
+
return csv && source === 'own' ? { people: csv.people, importedAt: csv.importedAt } : null;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** What × and the import page's Remove ask before a kept import is deleted. */
|
|
273
|
+
export const REMOVE_CSV_QUESTION = 'Remove this CSV import from this computer? Your Connections.csv file isn’t touched, so you can import it again.';
|
|
274
|
+
|
|
275
|
+
/** Why a kept import is there but can't be opened, or null. Said on the welcome screen, never passed off as no import (TRAPS §7). */
|
|
276
|
+
export async function keptCsvProblem() {
|
|
277
|
+
return (await keptCsv()).problem;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** Keep an import, in place of any kept before. Resolves { ok: true, people } or { ok: false, error }, the error fit to show. */
|
|
281
|
+
export async function saveCsvNetwork(connections) {
|
|
282
|
+
kept = null;
|
|
204
283
|
try {
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
284
|
+
const r = await fetch(CSV_ROUTE, {
|
|
285
|
+
method: 'POST',
|
|
286
|
+
headers: { 'Content-Type': 'application/json' },
|
|
287
|
+
body: JSON.stringify({ connections: packConnections(connections) }),
|
|
288
|
+
});
|
|
289
|
+
const j = await r.json().catch(() => ({}));
|
|
290
|
+
if (!r.ok) return { ok: false, error: j.error || `The import couldn't be kept (the app answered ${r.status}).` };
|
|
291
|
+
// The import is what the map opens on now, not a sample still open in this window.
|
|
292
|
+
leaveSample();
|
|
293
|
+
return { ok: true, people: j.people };
|
|
294
|
+
} catch {
|
|
295
|
+
return { ok: false, error: "The import couldn't be kept: Six Degrees didn't answer. Check that it's still running, then try again." };
|
|
296
|
+
}
|
|
211
297
|
}
|
|
212
298
|
|
|
213
|
-
|
|
214
|
-
|
|
299
|
+
/** Close what's open: the sample is forgotten by this window; a CSV import is removed from the data folder. Resolves { ok } or { ok: false, error }. */
|
|
300
|
+
export async function closeCsvNetwork(source) {
|
|
301
|
+
kept = null;
|
|
302
|
+
if (source === 'sample') {
|
|
303
|
+
leaveSample();
|
|
304
|
+
return { ok: true };
|
|
305
|
+
}
|
|
306
|
+
try {
|
|
307
|
+
const r = await fetch(CSV_ROUTE, { method: 'DELETE' });
|
|
308
|
+
const j = await r.json().catch(() => ({}));
|
|
309
|
+
return r.ok ? { ok: true } : { ok: false, error: j.error || `The import couldn't be removed (the app answered ${r.status}).` };
|
|
310
|
+
} catch {
|
|
311
|
+
return { ok: false, error: "The import couldn't be removed: Six Degrees didn't answer. Check that it's still running, then try again." };
|
|
312
|
+
}
|
|
215
313
|
}
|
|
216
314
|
|
|
217
315
|
export const CSV_USER = { id: 'csv-local-user', name: 'You' };
|
package/lib/data-folder.js
CHANGED
|
@@ -17,18 +17,29 @@ import { AVATAR_FILE } from './photos.js';
|
|
|
17
17
|
// import accepts exactly those names.
|
|
18
18
|
export { AVATAR_FILE };
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* A LinkedIn Connections.csv import, kept so it is still there after the
|
|
22
|
+
* window closes (lib/csv-store.js). Kept beside the database, never merged
|
|
23
|
+
* into it: a CSV row has no bridge, no user and no id the scanner made, and
|
|
24
|
+
* folding it in by profile link is how duplicates and lost rows happened
|
|
25
|
+
* before (TRAPS §19, §25, §36).
|
|
26
|
+
*/
|
|
27
|
+
export const CSV_NETWORK_FILE = 'csv-network.json';
|
|
28
|
+
|
|
20
29
|
/**
|
|
21
30
|
* The scanner's notes about the network itself: without them, people whose
|
|
22
31
|
* circles are hidden or half-read would be retried from scratch on the new
|
|
23
32
|
* computer (TRAPS §15, §34). They describe one network's people, so an import
|
|
24
33
|
* replaces them along with the network: this computer's notes would say which
|
|
25
34
|
* pages of the old network's people were read, and the scanner would skip
|
|
26
|
-
* those pages for the new one.
|
|
35
|
+
* those pages for the new one. A kept CSV import is a network of its own, so
|
|
36
|
+
* it travels and is replaced the same way (what was here goes to backups/).
|
|
27
37
|
*/
|
|
28
38
|
export const NETWORK_FILES = [
|
|
29
39
|
'bridge-progress.json',
|
|
30
40
|
'bridge-skips.json',
|
|
31
41
|
'bridge-unclear.json',
|
|
42
|
+
CSV_NETWORK_FILE,
|
|
32
43
|
];
|
|
33
44
|
|
|
34
45
|
/**
|
|
@@ -209,10 +220,15 @@ export function folderOpener(platform = process.platform) {
|
|
|
209
220
|
/**
|
|
210
221
|
* Open the data folder in Finder (or the Linux file browser). The path is the
|
|
211
222
|
* data folder itself, never anything from a request. Resolves { ok, message }.
|
|
223
|
+
* `select` is a file in `dir` (a backup, lib/backups.js), its whole path, that
|
|
224
|
+
* Finder shows selected (`open -R`); a Linux file browser just opens the
|
|
225
|
+
* folder. The caller builds the path: one built here makes Next's build trace
|
|
226
|
+
* the whole project into the app (TRAPS §27).
|
|
212
227
|
*/
|
|
213
|
-
export function revealFolder(dir, { platform = process.platform, spawnImpl = spawn, waitMs = 3000 } = {}) {
|
|
228
|
+
export function revealFolder(dir, { platform = process.platform, spawnImpl = spawn, waitMs = 3000, select = null } = {}) {
|
|
214
229
|
const cmd = folderOpener(platform);
|
|
215
230
|
if (!cmd) return Promise.resolve({ ok: false, message: 'There is no file browser to open it with on this computer.' });
|
|
231
|
+
const args = select && cmd === 'open' ? ['-R', select] : [dir];
|
|
216
232
|
return new Promise((resolve) => {
|
|
217
233
|
let timer = null;
|
|
218
234
|
let settled = false;
|
|
@@ -224,7 +240,7 @@ export function revealFolder(dir, { platform = process.platform, spawnImpl = spa
|
|
|
224
240
|
};
|
|
225
241
|
let child;
|
|
226
242
|
try {
|
|
227
|
-
child = spawnImpl(cmd,
|
|
243
|
+
child = spawnImpl(cmd, args, { stdio: 'ignore', detached: true });
|
|
228
244
|
} catch (err) {
|
|
229
245
|
done({ ok: false, message: `It couldn't be opened (${err.message}).` });
|
|
230
246
|
return;
|
package/lib/data-import.js
CHANGED
|
@@ -270,7 +270,7 @@ export function validateImport(file, { applySchema, schemaSql, appVersion, retir
|
|
|
270
270
|
}
|
|
271
271
|
const present = new Set(objects.filter((o) => o.type === 'table').map((o) => o.name));
|
|
272
272
|
if (!present.has('sd_export_manifest') || !present.has('sd_export_files')) {
|
|
273
|
-
throw new ImportError("This is a database but not a Six Degrees export, so nothing was imported. Make one on the other computer with Settings → Your data
|
|
273
|
+
throw new ImportError("This is a database but not a Six Degrees export, so nothing was imported. Make one on the other computer with Export backup file… in Settings → Your data.");
|
|
274
274
|
}
|
|
275
275
|
for (const [t, { required, allowed }] of ref.tables) {
|
|
276
276
|
if (!present.has(t)) {
|
|
@@ -380,7 +380,7 @@ export function validateImport(file, { applySchema, schemaSql, appVersion, retir
|
|
|
380
380
|
* @returns what the Settings page shows while the import waits.
|
|
381
381
|
*/
|
|
382
382
|
export function stageImport(upload, {
|
|
383
|
-
dir, applySchema, schemaSql, appVersion, replacedPeople = 0, now = new Date(), retired = RETIRED,
|
|
383
|
+
dir, applySchema, schemaSql, appVersion, replacedPeople = 0, now = new Date(), retired = RETIRED, restoredFrom = null,
|
|
384
384
|
}) {
|
|
385
385
|
const info = validateImport(upload, { applySchema, schemaSql, appVersion, retired });
|
|
386
386
|
const work = path.dirname(upload);
|
|
@@ -436,6 +436,8 @@ export function stageImport(upload, {
|
|
|
436
436
|
people: info.people,
|
|
437
437
|
photos: info.photos,
|
|
438
438
|
replacedPeople,
|
|
439
|
+
// A backup from backups/ being put back (lib/backups.js restoreBackup), by its name.
|
|
440
|
+
...(restoredFrom ? { restoredFrom } : {}),
|
|
439
441
|
};
|
|
440
442
|
writeFileSync(path.join(work, 'READY'), `${JSON.stringify(ready, null, 2)}\n`);
|
|
441
443
|
// On the disk before import-pending/ appears: the next start moves this
|
|
@@ -822,6 +824,7 @@ export function applyPendingImport({ dir, dbFile, now = new Date(), copyDatabase
|
|
|
822
824
|
people: ready.people ?? null,
|
|
823
825
|
photos: ready.photos ?? null,
|
|
824
826
|
replacedPeople: ready.replacedPeople ?? null,
|
|
827
|
+
restoredFrom: ready.restoredFrom ?? null,
|
|
825
828
|
keptDatabase: exists(keptDb) ? shown(keptDb) : null,
|
|
826
829
|
keptFiles: exists(keptFiles) ? shown(keptFiles) : null,
|
|
827
830
|
// Set when the database that was here couldn't be read, so it was kept
|
package/lib/db-client.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { DatabaseSync } from 'node:sqlite';
|
|
2
|
-
import { mkdirSync, existsSync, readFileSync, writeFileSync,
|
|
2
|
+
import { mkdirSync, existsSync, readFileSync, writeFileSync, renameSync, rmSync } from 'node:fs';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { SCHEMA_SQL } from '../db/schema.js';
|
|
6
6
|
import { APP_VERSION } from './app-version.js';
|
|
7
7
|
import { applyPendingImport, recordImport } from './data-import.js';
|
|
8
|
+
import { compareVersions } from './release.js';
|
|
9
|
+
import { durable } from './durable.js';
|
|
10
|
+
import {
|
|
11
|
+
makeBackup, rotateBackups, dailyBackupIfDue, noteBackupFailure, AUTO_BACKUP_PREFIX,
|
|
12
|
+
} from './backups.js';
|
|
8
13
|
|
|
9
14
|
// The database lives OUTSIDE the app directory so an installed copy never
|
|
10
15
|
// writes into its own package. Override with SIX_DEGREES_HOME.
|
|
@@ -78,7 +83,7 @@ export function getDb() {
|
|
|
78
83
|
// Before this version changes anything: if a different version opened this
|
|
79
84
|
// data last, keep a copy of it as it was. See backupOnNewVersion().
|
|
80
85
|
try {
|
|
81
|
-
const saved = backupOnNewVersion(_db, { dir: path.dirname(file), version: APP_VERSION });
|
|
86
|
+
const saved = backupOnNewVersion(_db, { dir: path.dirname(file), dataDir: dataDir(), version: APP_VERSION });
|
|
82
87
|
if (saved) console.log(`Six Degrees ${APP_VERSION}: backed up your data first → ${saved}`);
|
|
83
88
|
} catch (err) {
|
|
84
89
|
console.error(`Six Degrees: could not back up your data before ${APP_VERSION} (will try again next start): ${err.message}`);
|
|
@@ -90,11 +95,39 @@ export function getDb() {
|
|
|
90
95
|
|
|
91
96
|
if (imported) {
|
|
92
97
|
try { recordImport(_db, imported); } catch { /* only the Settings page's note is lost */ }
|
|
98
|
+
// The copy that import kept of what was here joins the rotation (lib/backups.js KEEP).
|
|
99
|
+
try { rotateBackups(backupsFolder()); } catch { /* tried again after the next backup */ }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Once a day: checked here, as the server opens the data, and after each
|
|
103
|
+
// scan (app/api/scraper/route.js). No timer: nothing runs that nobody started.
|
|
104
|
+
try {
|
|
105
|
+
const daily = backUpDailyIfDue(_db);
|
|
106
|
+
if (daily) console.log(`Six Degrees: made today's backup → ${daily.file}`);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
console.error(`Six Degrees: could not make today's backup (will try again after the next scan or start): ${err.message}`);
|
|
93
109
|
}
|
|
94
110
|
|
|
95
111
|
return _db;
|
|
96
112
|
}
|
|
97
113
|
|
|
114
|
+
/** backups/, beside the database (where an import keeps its copy too). */
|
|
115
|
+
export function backupsFolder() {
|
|
116
|
+
return path.join(path.dirname(dbFile()), 'backups');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** What lib/backups.js needs to make, check and restore this copy's backups. */
|
|
120
|
+
export function backupOptions(db = getDb()) {
|
|
121
|
+
return {
|
|
122
|
+
db, dataDir: dataDir(), backupsDir: backupsFolder(), appVersion: APP_VERSION, schemaSql: SCHEMA_SQL, applySchema,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** The daily backup, if one is due (lib/backups.js dailyBackupIfDue). @returns it, or null. */
|
|
127
|
+
export function backUpDailyIfDue(db = getDb(), now = new Date()) {
|
|
128
|
+
return dailyBackupIfDue({ ...backupOptions(db), now });
|
|
129
|
+
}
|
|
130
|
+
|
|
98
131
|
/**
|
|
99
132
|
* Every table, index and column this version uses, made if missing. An import
|
|
100
133
|
* is rebuilt into exactly this (lib/data-import.js), so only rows travel.
|
|
@@ -120,16 +153,24 @@ function addMissingColumns(db) {
|
|
|
120
153
|
|
|
121
154
|
// ── a copy of the data before each new version touches it ──────────────────
|
|
122
155
|
// The first time a version opens a database that a different version (or one
|
|
123
|
-
// from before this existed) used last, it
|
|
124
|
-
// backups
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
// disk) is retried
|
|
156
|
+
// from before this existed) used last, it backs it up, as it was, into
|
|
157
|
+
// backups/: before the schema step or anything else writes to it. The backup
|
|
158
|
+
// is the whole network, photos and files too (lib/backups.js makeBackup), so
|
|
159
|
+
// Settings → Your data → Restore can put it back. The newest three are kept;
|
|
160
|
+
// anything someone put in backups/ themselves is never touched. The marker is
|
|
161
|
+
// written only after a copy succeeds, so a failed one (a full disk) is retried
|
|
162
|
+
// at the next start.
|
|
163
|
+
//
|
|
164
|
+
// If that backup can't be made or fails its check (a database holding
|
|
165
|
+
// something an export never does, say), the database alone is still copied,
|
|
166
|
+
// as every version before this did: a copy that only a person can put back is
|
|
167
|
+
// better than none before an update. The page says the backup didn't work.
|
|
129
168
|
|
|
130
|
-
export
|
|
169
|
+
export { AUTO_BACKUP_PREFIX };
|
|
131
170
|
|
|
132
|
-
export function backupOnNewVersion(db, {
|
|
171
|
+
export function backupOnNewVersion(db, {
|
|
172
|
+
dir, version, dataDir: filesDir = dir, now = new Date(), schemaSql = SCHEMA_SQL, applySchema: schemaStep = applySchema,
|
|
173
|
+
}) {
|
|
133
174
|
const marker = path.join(dir, 'app-version');
|
|
134
175
|
let last = null;
|
|
135
176
|
try { last = readFileSync(marker, 'utf8').trim(); } catch { /* first run, or older than this */ }
|
|
@@ -141,16 +182,33 @@ export function backupOnNewVersion(db, { dir, version, keep = 5, now = new Date(
|
|
|
141
182
|
).get().n > 0;
|
|
142
183
|
if (hasData) {
|
|
143
184
|
const folder = path.join(dir, 'backups');
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
185
|
+
// The data is the last version's, not this one's: say so in the copy, so
|
|
186
|
+
// that version can restore it if this one has to be put back. (Data a
|
|
187
|
+
// newer version wrote, or with no marker, is labelled with this version.)
|
|
188
|
+
const known = /^v?\d+\.\d+\.\d+/.test(last || '') && compareVersions(last, version) <= 0;
|
|
189
|
+
try {
|
|
190
|
+
saved = makeBackup('before-update', {
|
|
191
|
+
db, dataDir: filesDir, backupsDir: folder, appVersion: version, dataVersion: known ? last : version,
|
|
192
|
+
schemaSql, applySchema: schemaStep, now,
|
|
193
|
+
}).file;
|
|
194
|
+
} catch (err) {
|
|
195
|
+
noteBackupFailure('before-update', err, now);
|
|
196
|
+
mkdirSync(folder, { recursive: true });
|
|
197
|
+
saved = path.join(folder, `${AUTO_BACKUP_PREFIX}${version}-${now.toISOString().replace(/[:.]/g, '-')}.sqlite`);
|
|
198
|
+
// Through the open handle, and synced before it takes its name (the
|
|
199
|
+
// vacuumCopy pattern, lib/data-import.js).
|
|
200
|
+
const partial = path.join(folder, `.${path.basename(saved)}.partial`);
|
|
201
|
+
try {
|
|
202
|
+
db.exec(`VACUUM INTO '${partial.replace(/'/g, "''")}'`);
|
|
203
|
+
durable.syncFile(partial);
|
|
204
|
+
renameSync(partial, saved);
|
|
205
|
+
durable.syncFolder(folder);
|
|
206
|
+
} catch (copyErr) {
|
|
207
|
+
rmSync(partial, { force: true });
|
|
208
|
+
throw copyErr;
|
|
209
|
+
}
|
|
210
|
+
try { rotateBackups(folder, { now }); } catch { /* tried again after the next one */ }
|
|
211
|
+
}
|
|
154
212
|
}
|
|
155
213
|
writeFileSync(marker, `${version}\n`);
|
|
156
214
|
return saved;
|
package/lib/demo.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// It exists so a first run has something to show, so screenshots contain no real
|
|
5
5
|
// people, and so the Bridges view can be explored before you have data of your own.
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { saveSampleNetwork } from './csv';
|
|
8
8
|
|
|
9
9
|
export const IS_DEMO = process.env.NEXT_PUBLIC_DEMO_MODE === 'true';
|
|
10
10
|
|
|
@@ -19,16 +19,17 @@ let _cache = null;
|
|
|
19
19
|
export async function loadDemoNetwork() {
|
|
20
20
|
if (_cache) return _cache;
|
|
21
21
|
const res = await fetch('/demo-data.json', { cache: 'no-cache' });
|
|
22
|
-
if (!res.ok) throw new Error('demo-data.json not found
|
|
22
|
+
if (!res.ok) throw new Error('demo-data.json not found. Run: node scripts/gen-synthetic.mjs');
|
|
23
23
|
const data = await res.json();
|
|
24
24
|
_cache = { degree1: data.degree1 || [], degree2: data.degree2 || [] };
|
|
25
25
|
return _cache;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
// Loads the sample into this browser tab and reports how big it is. Nothing is
|
|
29
|
-
// written to the database, so it disappears when the tab
|
|
29
|
+
// written to the database or the data folder, so it disappears when the tab
|
|
30
|
+
// closes (a CSV import is kept; the sample isn't anyone's: lib/csv.js).
|
|
30
31
|
export async function loadSampleIntoSession() {
|
|
31
32
|
const net = await loadDemoNetwork();
|
|
32
|
-
|
|
33
|
+
saveSampleNetwork({ degree1: net.degree1, degree2: net.degree2 });
|
|
33
34
|
return { degree1: net.degree1.length, degree2: net.degree2.length };
|
|
34
35
|
}
|
package/lib/galaxy-export.js
CHANGED
|
@@ -8,6 +8,10 @@ import { MAP_LOOK } from './themes.js';
|
|
|
8
8
|
|
|
9
9
|
let current = null; // { svg, stamp: () => text or null, legend: () => [[label, colour]] }
|
|
10
10
|
|
|
11
|
+
// The small credit in the corner of every picture and video. A shared picture is
|
|
12
|
+
// how someone finds the app, so it names where to get it.
|
|
13
|
+
export const CREDIT = 'sixdegreesapp.com';
|
|
14
|
+
|
|
11
15
|
export function registerGalaxy(entry) {
|
|
12
16
|
current = entry;
|
|
13
17
|
return () => { if (current === entry) current = null; };
|
|
@@ -31,7 +35,10 @@ function svgImage(svg) {
|
|
|
31
35
|
// The page's font, which the <svg> inherits on screen but not in a file.
|
|
32
36
|
clone.setAttribute('font-family', getComputedStyle(svg).fontFamily || 'system-ui, sans-serif');
|
|
33
37
|
const style = document.createElementNS('http://www.w3.org/2000/svg', 'style');
|
|
34
|
-
|
|
38
|
+
// The theme's colours (lib/themes.js), which the map reads from the page and a file can't.
|
|
39
|
+
const root = document.documentElement;
|
|
40
|
+
const vars = [...root.style].filter((k) => k.startsWith('--sd-')).map((k) => `${k}:${root.style.getPropertyValue(k)}`).join(';');
|
|
41
|
+
style.textContent = `svg{${vars}}${EXPORT_CSS}`;
|
|
35
42
|
clone.insertBefore(style, clone.firstChild);
|
|
36
43
|
const xml = new XMLSerializer().serializeToString(clone);
|
|
37
44
|
const img = new Image();
|
|
@@ -76,7 +83,7 @@ async function drawFrame(ctx, w, h) {
|
|
|
76
83
|
}
|
|
77
84
|
ctx.textAlign = 'right';
|
|
78
85
|
ctx.fillStyle = 'rgba(255,255,255,0.35)';
|
|
79
|
-
ctx.fillText(
|
|
86
|
+
ctx.fillText(CREDIT, cw - 16, 24);
|
|
80
87
|
ctx.restore();
|
|
81
88
|
}
|
|
82
89
|
|
package/lib/galaxy-lab.js
CHANGED
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
import { keyFor, score } from './separation.js';
|
|
11
11
|
import { warmthOf } from './linkedin-export.js';
|
|
12
|
+
import { LAYOUT_KEYS, cleanLayouts } from './galaxy-layouts.js';
|
|
13
|
+
import { saveSettings } from './settings-client.js';
|
|
14
|
+
import { reconcileSaved } from './synced-setting.js';
|
|
12
15
|
|
|
13
16
|
const KEY = 'six-degrees-galaxy-lab';
|
|
14
17
|
const LAYOUTS_KEY = 'six-degrees-galaxy-layouts';
|
|
@@ -34,9 +37,6 @@ export const LAB_DEFAULTS = Object.freeze({
|
|
|
34
37
|
v: 2, // which defaults a saved setting was made under (2: the branch starts off)
|
|
35
38
|
});
|
|
36
39
|
|
|
37
|
-
/** The slider settings a saved layout keeps (not whether the lab is on, nor the names switch). */
|
|
38
|
-
const LAYOUT_KEYS = ['gravity', 'rings', 'push', 'pull', 'distance', 'orbit', 'dotSize', 'lines', 'sizeBy', 'names', 'branch', 'colourBy', 'speed', 'loop'];
|
|
39
|
-
|
|
40
40
|
/** The forces a layout sets, and the ones the Galaxy re-settles for when they change. */
|
|
41
41
|
export const FORCE_KEYS = ['gravity', 'rings', 'push', 'pull', 'distance'];
|
|
42
42
|
|
|
@@ -105,7 +105,10 @@ export function watchLab(f) {
|
|
|
105
105
|
/** What the Galaxy should use: the sliders while the lab is on, today's layout otherwise (with the names switch). */
|
|
106
106
|
export const effectiveLab = (lab) => (lab.on ? lab : lab.labels === LAB_DEFAULTS.labels ? LAB_DEFAULTS : { ...LAB_DEFAULTS, labels: lab.labels });
|
|
107
107
|
|
|
108
|
-
// Saved layouts: your own named slider settings,
|
|
108
|
+
// Saved layouts: your own named slider settings (lib/galaxy-layouts.js), saved
|
|
109
|
+
// with the network's settings so they travel with a backup or a restore, and
|
|
110
|
+
// copied in this browser to show before the server has answered
|
|
111
|
+
// (lib/synced-setting.js, app/components/ThemeLoader.js).
|
|
109
112
|
let layoutsCache = null;
|
|
110
113
|
const layoutListeners = new Set();
|
|
111
114
|
export function layoutsNow() {
|
|
@@ -115,10 +118,21 @@ export function layoutsNow() {
|
|
|
115
118
|
}
|
|
116
119
|
return layoutsCache;
|
|
117
120
|
}
|
|
118
|
-
function writeLayouts(list) {
|
|
121
|
+
function writeLayouts(list, { save = true } = {}) {
|
|
119
122
|
layoutsCache = list;
|
|
120
123
|
try { localStorage.setItem(LAYOUTS_KEY, JSON.stringify(list)); } catch {}
|
|
121
124
|
layoutListeners.forEach((f) => f());
|
|
125
|
+
if (save) saveSettings({ galaxyLayouts: list });
|
|
126
|
+
}
|
|
127
|
+
/** The layouts saved with the network (GET /api/settings 'galaxyLayouts'), once the page has them. */
|
|
128
|
+
export function adoptSavedLayouts(saved) {
|
|
129
|
+
const cached = cleanLayouts(layoutsNow());
|
|
130
|
+
const { use, save, changed } = reconcileSaved({
|
|
131
|
+
saved: saved == null ? null : cleanLayouts(saved), cached,
|
|
132
|
+
isDefault: (list) => list.length === 0, same: (a, b) => JSON.stringify(a) === JSON.stringify(b),
|
|
133
|
+
});
|
|
134
|
+
if (save) saveSettings({ galaxyLayouts: cached });
|
|
135
|
+
if (changed) writeLayouts(use, { save: false });
|
|
122
136
|
}
|
|
123
137
|
export function watchLayouts(f) { layoutListeners.add(f); return () => layoutListeners.delete(f); }
|
|
124
138
|
export function saveLayout(name) {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// The Galaxy's saved layouts (Physics → Save layout): your own named slider
|
|
2
|
+
// settings. Kept with the network's settings (lib/settings.js), so they travel
|
|
3
|
+
// with a backup, an export and a restore; the browser keeps a copy to read
|
|
4
|
+
// before the page has asked the server (lib/galaxy-lab.js). No imports: the
|
|
5
|
+
// server checks a saved list with the same rules the browser keeps it by.
|
|
6
|
+
|
|
7
|
+
/** The slider settings a saved layout keeps (not whether the lab is on, nor the names switch). */
|
|
8
|
+
export const LAYOUT_KEYS = ['gravity', 'rings', 'push', 'pull', 'distance', 'orbit', 'dotSize', 'lines', 'sizeBy', 'names', 'branch', 'colourBy', 'speed', 'loop'];
|
|
9
|
+
|
|
10
|
+
/** More than anyone names by hand, and a bound on what a stray request can store. */
|
|
11
|
+
export const MAX_LAYOUTS = 50;
|
|
12
|
+
|
|
13
|
+
const fine = (v) => (typeof v === 'boolean')
|
|
14
|
+
|| (typeof v === 'number' && Number.isFinite(v) && Math.abs(v) <= 1000)
|
|
15
|
+
|| (typeof v === 'string' && /^[a-z]{1,20}$/i.test(v));
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A saved list made safe: each layout a name (1 to 40 characters) and only the
|
|
19
|
+
* slider settings a layout keeps, each a plain number, word or switch. A name
|
|
20
|
+
* saved twice keeps its last settings, where the first one stood.
|
|
21
|
+
*/
|
|
22
|
+
export function cleanLayouts(raw) {
|
|
23
|
+
if (!Array.isArray(raw)) return [];
|
|
24
|
+
const byName = new Map();
|
|
25
|
+
for (const item of raw) {
|
|
26
|
+
const name = typeof item?.name === 'string' ? item.name.trim().slice(0, 40) : '';
|
|
27
|
+
if (!name || !item.settings || typeof item.settings !== 'object' || Array.isArray(item.settings)) continue;
|
|
28
|
+
const settings = {};
|
|
29
|
+
for (const k of LAYOUT_KEYS) if (Object.hasOwn(item.settings, k) && fine(item.settings[k])) settings[k] = item.settings[k];
|
|
30
|
+
byName.set(name, { name, settings });
|
|
31
|
+
}
|
|
32
|
+
return [...byName.values()].slice(0, MAX_LAYOUTS);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** In lib/settings.js: null until a list is saved on this network, so a browser's own list is saved once. */
|
|
36
|
+
export const GALAXY_LAYOUTS_SETTING = {
|
|
37
|
+
default: null,
|
|
38
|
+
parse(value) {
|
|
39
|
+
if (value === null) return null;
|
|
40
|
+
if (!Array.isArray(value)) throw new Error('Saved layouts must be a list.');
|
|
41
|
+
return cleanLayouts(value);
|
|
42
|
+
},
|
|
43
|
+
};
|
package/lib/gate.js
CHANGED
|
@@ -8,10 +8,13 @@
|
|
|
8
8
|
// /api/update changes the code that will run next, both of which are more power
|
|
9
9
|
// than any of the others, so they sit behind the same gate.
|
|
10
10
|
//
|
|
11
|
-
// The
|
|
12
|
-
// whole network in one file, import replaces it, restart stops the server,
|
|
13
|
-
// reveal starts a process
|
|
14
|
-
//
|
|
11
|
+
// The six under /api/data are Settings → Your data: export hands over the
|
|
12
|
+
// whole network in one file, import replaces it, restart stops the server,
|
|
13
|
+
// reveal starts a process, backup writes the whole network to a file, and
|
|
14
|
+
// restore replaces it with a backup. Reading /api/data itself (sizes, the
|
|
15
|
+
// folder's path, the backups) changes nothing and stays open, like every other read.
|
|
16
|
+
// /api/data/csv keeps, replaces, hands over and removes a CSV import kept in
|
|
17
|
+
// the data folder.
|
|
15
18
|
export const DESTRUCTIVE_ROUTES = [
|
|
16
19
|
'/api/admin-delete',
|
|
17
20
|
'/api/admin-update',
|
|
@@ -23,6 +26,9 @@ export const DESTRUCTIVE_ROUTES = [
|
|
|
23
26
|
'/api/data/import',
|
|
24
27
|
'/api/data/restart',
|
|
25
28
|
'/api/data/reveal',
|
|
29
|
+
'/api/data/backup',
|
|
30
|
+
'/api/data/restore',
|
|
31
|
+
'/api/data/csv',
|
|
26
32
|
];
|
|
27
33
|
|
|
28
34
|
const LOOPBACK = new Set(['127.0.0.1', '::1', 'localhost']);
|