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.
Files changed (609) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +4 -0
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/prerender-manifest.json +42 -14
  5. package/.next/standalone/.next/routes-manifest.json +24 -0
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_not-found/page.js +1 -1
  12. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.rsc +26 -18
  16. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +26 -18
  17. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +25 -16
  18. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  19. package/.next/standalone/.next/server/app/api/admin-delete/route.js +2 -2
  20. package/.next/standalone/.next/server/app/api/admin-delete/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/admin-update/route.js +2 -2
  22. package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/bridges/route.js +2 -2
  24. package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/bulk-import/route.js +2 -2
  26. package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js +3 -3
  28. package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/company-scores/route.js +3 -3
  30. package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/connections/route.js +2 -2
  32. package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/data/backup/route/app-paths-manifest.json +3 -0
  34. package/.next/standalone/.next/server/app/api/data/backup/route/build-manifest.json +12 -0
  35. package/.next/standalone/.next/server/app/api/data/backup/route/server-reference-manifest.json +4 -0
  36. package/.next/standalone/.next/server/app/api/data/backup/route.js +7 -0
  37. package/.next/standalone/.next/server/app/api/data/backup/route.js.map +5 -0
  38. package/.next/standalone/.next/server/app/api/data/backup/route.js.nft.json +1 -0
  39. package/.next/standalone/.next/server/app/api/data/backup/route_client-reference-manifest.js +3 -0
  40. package/.next/standalone/.next/server/app/api/data/csv/route/app-paths-manifest.json +3 -0
  41. package/.next/standalone/.next/server/app/api/data/csv/route/build-manifest.json +12 -0
  42. package/.next/standalone/.next/server/app/api/data/csv/route/server-reference-manifest.json +4 -0
  43. package/.next/standalone/.next/server/app/api/data/csv/route.js +8 -0
  44. package/.next/standalone/.next/server/app/api/data/csv/route.js.map +5 -0
  45. package/.next/standalone/.next/server/app/api/data/csv/route.js.nft.json +1 -0
  46. package/.next/standalone/.next/server/app/api/data/csv/route_client-reference-manifest.js +3 -0
  47. package/.next/standalone/.next/server/app/api/data/export/route.js +1 -1
  48. package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/api/data/import/route.js +1 -1
  50. package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/api/data/restart/route.js +1 -1
  52. package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/api/data/restore/route/app-paths-manifest.json +3 -0
  54. package/.next/standalone/.next/server/app/api/data/restore/route/build-manifest.json +12 -0
  55. package/.next/standalone/.next/server/app/api/data/restore/route/server-reference-manifest.json +4 -0
  56. package/.next/standalone/.next/server/app/api/data/restore/route.js +7 -0
  57. package/.next/standalone/.next/server/app/api/data/restore/route.js.map +5 -0
  58. package/.next/standalone/.next/server/app/api/data/restore/route.js.nft.json +1 -0
  59. package/.next/standalone/.next/server/app/api/data/restore/route_client-reference-manifest.js +3 -0
  60. package/.next/standalone/.next/server/app/api/data/reveal/route.js +1 -1
  61. package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/api/data/route.js +1 -1
  63. package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -1
  64. package/.next/standalone/.next/server/app/api/delete-cluster/route.js +2 -2
  65. package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/api/ingest/route.js +2 -2
  67. package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/api/network/route.js +2 -2
  69. package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/api/notifications/route.js +2 -2
  71. package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  72. package/.next/standalone/.next/server/app/api/outreach/route.js +3 -3
  73. package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
  74. package/.next/standalone/.next/server/app/api/queue/route.js +2 -2
  75. package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/api/scraper/route.js +5 -3
  77. package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
  78. package/.next/standalone/.next/server/app/api/settings/route.js +3 -3
  79. package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  80. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js +3 -3
  81. package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js +3 -3
  83. package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/api/setup-profile/route.js +2 -2
  85. package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
  86. package/.next/standalone/.next/server/app/api/social/crm/route.js +1 -1
  87. package/.next/standalone/.next/server/app/api/social/crm/route.js.nft.json +1 -1
  88. package/.next/standalone/.next/server/app/api/social/messages/route.js +1 -1
  89. package/.next/standalone/.next/server/app/api/social/messages/route.js.nft.json +1 -1
  90. package/.next/standalone/.next/server/app/api/social/route.js +2 -2
  91. package/.next/standalone/.next/server/app/api/social/route.js.nft.json +1 -1
  92. package/.next/standalone/.next/server/app/api/unlock/route.js +2 -2
  93. package/.next/standalone/.next/server/app/api/unlock/route.js.nft.json +1 -1
  94. package/.next/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  95. package/.next/standalone/.next/server/app/api/update-images/route.js +2 -2
  96. package/.next/standalone/.next/server/app/api/update-images/route.js.nft.json +1 -1
  97. package/.next/standalone/.next/server/app/api/users/route.js +2 -2
  98. package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
  99. package/.next/standalone/.next/server/app/avatars/[file]/route.js +1 -1
  100. package/.next/standalone/.next/server/app/avatars/[file]/route.js.nft.json +1 -1
  101. package/.next/standalone/.next/server/app/import/page.js +1 -1
  102. package/.next/standalone/.next/server/app/import/page.js.nft.json +1 -1
  103. package/.next/standalone/.next/server/app/import/page_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/import.html +1 -1
  105. package/.next/standalone/.next/server/app/import.rsc +32 -24
  106. package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +32 -24
  107. package/.next/standalone/.next/server/app/import.segments/_tree.segment.rsc +2 -2
  108. package/.next/standalone/.next/server/app/import.segments/import/__PAGE__.segment.rsc +23 -18
  109. package/.next/standalone/.next/server/app/index.html +1 -1
  110. package/.next/standalone/.next/server/app/index.rsc +29 -22
  111. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +20 -15
  112. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +29 -22
  113. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  114. package/.next/standalone/.next/server/app/insights/page/app-paths-manifest.json +3 -0
  115. package/.next/standalone/.next/server/app/insights/page/build-manifest.json +20 -0
  116. package/.next/standalone/.next/server/app/insights/page/next-font-manifest.json +11 -0
  117. package/.next/standalone/.next/server/app/insights/page/react-loadable-manifest.json +1 -0
  118. package/.next/standalone/.next/server/app/insights/page/server-reference-manifest.json +4 -0
  119. package/.next/standalone/.next/server/app/insights/page.js +13 -0
  120. package/.next/standalone/.next/server/app/insights/page.js.map +5 -0
  121. package/.next/standalone/.next/server/app/insights/page.js.nft.json +1 -0
  122. package/.next/standalone/.next/server/app/insights/page_client-reference-manifest.js +3 -0
  123. package/.next/standalone/.next/server/app/insights.html +1 -0
  124. package/.next/standalone/.next/server/app/insights.meta +26 -0
  125. package/.next/standalone/.next/server/app/insights.rsc +35 -0
  126. package/.next/standalone/.next/server/app/insights.segments/_full.segment.rsc +35 -0
  127. package/.next/standalone/.next/server/app/insights.segments/_tree.segment.rsc +4 -0
  128. package/.next/standalone/.next/server/app/insights.segments/insights/__PAGE__.segment.rsc +33 -0
  129. package/.next/standalone/.next/server/app/launch/page.js +1 -1
  130. package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
  131. package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/app/launch.html +2 -2
  133. package/.next/standalone/.next/server/app/launch.rsc +32 -24
  134. package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +32 -24
  135. package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +2 -2
  136. package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +23 -18
  137. package/.next/standalone/.next/server/app/page.js +1 -1
  138. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  139. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  140. package/.next/standalone/.next/server/app/paths/page.js +1 -1
  141. package/.next/standalone/.next/server/app/paths/page.js.nft.json +1 -1
  142. package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
  143. package/.next/standalone/.next/server/app/paths.html +1 -1
  144. package/.next/standalone/.next/server/app/paths.rsc +32 -24
  145. package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +32 -24
  146. package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +2 -2
  147. package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +21 -18
  148. package/.next/standalone/.next/server/app/profile/page.js +1 -1
  149. package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
  150. package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
  151. package/.next/standalone/.next/server/app/profile.html +1 -1
  152. package/.next/standalone/.next/server/app/profile.rsc +32 -24
  153. package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +32 -24
  154. package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +2 -2
  155. package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +23 -18
  156. package/.next/standalone/.next/server/app/queue/page.js +1 -1
  157. package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
  158. package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
  159. package/.next/standalone/.next/server/app/queue.html +1 -1
  160. package/.next/standalone/.next/server/app/queue.rsc +32 -24
  161. package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +32 -24
  162. package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +2 -2
  163. package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +21 -18
  164. package/.next/standalone/.next/server/app/scores/page.js +1 -1
  165. package/.next/standalone/.next/server/app/scores/page.js.nft.json +1 -1
  166. package/.next/standalone/.next/server/app/scores/page_client-reference-manifest.js +1 -1
  167. package/.next/standalone/.next/server/app/scores.html +1 -1
  168. package/.next/standalone/.next/server/app/scores.rsc +32 -24
  169. package/.next/standalone/.next/server/app/scores.segments/_full.segment.rsc +32 -24
  170. package/.next/standalone/.next/server/app/scores.segments/_tree.segment.rsc +2 -2
  171. package/.next/standalone/.next/server/app/scores.segments/scores/__PAGE__.segment.rsc +23 -18
  172. package/.next/standalone/.next/server/app/settings/page.js +1 -1
  173. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  174. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  175. package/.next/standalone/.next/server/app/settings.html +1 -1
  176. package/.next/standalone/.next/server/app/settings.rsc +32 -24
  177. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +32 -24
  178. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  179. package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +20 -18
  180. package/.next/standalone/.next/server/app/setup/page.js +1 -1
  181. package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
  182. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  183. package/.next/standalone/.next/server/app/setup.html +1 -1
  184. package/.next/standalone/.next/server/app/setup.rsc +32 -24
  185. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +32 -24
  186. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  187. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +21 -18
  188. package/.next/standalone/.next/server/app/social/page.js +1 -1
  189. package/.next/standalone/.next/server/app/social/page.js.nft.json +1 -1
  190. package/.next/standalone/.next/server/app/social/page_client-reference-manifest.js +1 -1
  191. package/.next/standalone/.next/server/app/social.html +1 -1
  192. package/.next/standalone/.next/server/app/social.rsc +32 -24
  193. package/.next/standalone/.next/server/app/social.segments/_full.segment.rsc +32 -24
  194. package/.next/standalone/.next/server/app/social.segments/_tree.segment.rsc +2 -2
  195. package/.next/standalone/.next/server/app/social.segments/social/__PAGE__.segment.rsc +23 -18
  196. package/.next/standalone/.next/server/app-paths-manifest.json +4 -0
  197. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00la_y0._.js +1 -1
  198. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05_3-22._.js +1 -1
  199. package/.next/standalone/.next/server/chunks/[root-of-the-server]__066rab1._.js +7 -0
  200. package/.next/standalone/.next/server/chunks/[root-of-the-server]__07t47cm._.js +1 -1
  201. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cj5jqc._.js +1 -1
  202. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e0fei3._.js +1 -1
  203. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fooke1._.js +7 -0
  204. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljnyho._.js +1 -1
  205. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o5-tcg._.js +1 -1
  206. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qrnous._.js +1 -1
  207. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__15wc9e-._.js → [root-of-the-server]__0r-0t-9._.js} +2 -2
  208. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ra6xyg._.js +15 -0
  209. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__20rwfdw._.js → [root-of-the-server]__0rcpjad._.js} +6 -3
  210. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t3v1a1._.js +1 -1
  211. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t6y79e._.js +7 -0
  212. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wmexuc._.js +1 -1
  213. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0x29muh._.js +7 -0
  214. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xu34sz._.js +1 -1
  215. package/.next/standalone/.next/server/chunks/[root-of-the-server]__133knx1._.js +1 -1
  216. package/.next/standalone/.next/server/chunks/[root-of-the-server]__15-17hl._.js +1 -1
  217. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19b7mig._.js +1 -1
  218. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a_6x37._.js +8 -0
  219. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1an_8pa._.js +7 -0
  220. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1bbcwub._.js +1 -1
  221. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ducpz2._.js +3 -0
  222. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1eris29._.js +1 -1
  223. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1gjo_cq._.js +1 -1
  224. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qcm08_._.js +1 -1
  225. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tir0vc._.js +1 -1
  226. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1w25q0m._.js +1 -1
  227. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1xhyinn._.js +3 -0
  228. package/.next/standalone/.next/server/chunks/_072jl0y._.js +1 -1
  229. package/.next/standalone/.next/server/chunks/_0lw8_i0._.js +1 -1
  230. package/.next/standalone/.next/server/chunks/_0sqqpzb._.js +3 -0
  231. package/.next/standalone/.next/server/chunks/_1_fynia._.js +7 -7
  232. package/.next/standalone/.next/server/chunks/_1fn30_l._.js +1 -1
  233. package/.next/standalone/.next/server/chunks/_1itd1o_._.js +1 -1
  234. package/.next/standalone/.next/server/chunks/_1iwkh8t._.js +1 -1
  235. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_backup_route_actions_0zoj04p.js +3 -0
  236. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_csv_route_actions_0l6m7lg.js +3 -0
  237. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_restore_route_actions_0-b05bv.js +3 -0
  238. package/.next/standalone/.next/server/chunks/lib_02iz_9q._.js +4 -0
  239. package/.next/standalone/.next/server/chunks/lib_05agvk3._.js +4 -0
  240. package/.next/standalone/.next/server/chunks/lib_0v84u66._.js +4 -0
  241. package/.next/standalone/.next/server/chunks/lib_db-client_0_dch35.js +174 -0
  242. package/.next/standalone/.next/server/chunks/lib_linkedin-export_12imqxg.js +1 -1
  243. package/.next/standalone/.next/server/chunks/lib_rpc_00nndai.js +3 -0
  244. package/.next/standalone/.next/server/chunks/lib_rpc_03ibb-x.js +3 -0
  245. package/.next/standalone/.next/server/chunks/lib_rpc_03ri3ji.js +3 -0
  246. package/.next/standalone/.next/server/chunks/lib_rpc_078ce48.js +3 -0
  247. package/.next/standalone/.next/server/chunks/lib_rpc_0a69mgr.js +3 -0
  248. package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +7 -0
  249. package/.next/standalone/.next/server/chunks/lib_rpc_0cej3t8.js +3 -0
  250. package/.next/standalone/.next/server/chunks/lib_rpc_0cmh4g6.js +3 -0
  251. package/.next/standalone/.next/server/chunks/lib_rpc_0nx2_pc.js +3 -0
  252. package/.next/standalone/.next/server/chunks/lib_rpc_0r79-w1.js +3 -0
  253. package/.next/standalone/.next/server/chunks/lib_rpc_0t552z6.js +3 -0
  254. package/.next/standalone/.next/server/chunks/lib_rpc_0yx8ynd.js +3 -0
  255. package/.next/standalone/.next/server/chunks/lib_rpc_12p-o9-.js +3 -0
  256. package/.next/standalone/.next/server/chunks/lib_rpc_1466dnb.js +3 -0
  257. package/.next/standalone/.next/server/chunks/lib_rpc_1sryxv6.js +3 -0
  258. package/.next/standalone/.next/server/chunks/lib_rpc_1trn-x5.js +3 -0
  259. package/.next/standalone/.next/server/chunks/lib_rpc_1ygu_mv.js +3 -0
  260. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0egamyq._.js +3 -0
  261. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qd8pzm._.js +3 -0
  262. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qdeuyo._.js → [root-of-the-server]__1-012q1._.js} +2 -2
  263. package/.next/standalone/.next/server/chunks/ssr/_04am_h8._.js +3 -0
  264. package/.next/standalone/.next/server/chunks/ssr/_06rgzfh._.js +3 -0
  265. package/.next/standalone/.next/server/chunks/ssr/_07zb7lu._.js +3 -0
  266. package/.next/standalone/.next/server/chunks/ssr/_0_79idq._.js +3 -0
  267. package/.next/standalone/.next/server/chunks/ssr/_0gds903._.js +3 -0
  268. package/.next/standalone/.next/server/chunks/ssr/_0hb-dhy._.js +3 -0
  269. package/.next/standalone/.next/server/chunks/ssr/_0klqt9z._.js +3 -0
  270. package/.next/standalone/.next/server/chunks/ssr/_14jak5s._.js +7 -0
  271. package/.next/standalone/.next/server/chunks/ssr/_14nxd3q._.js +3 -0
  272. package/.next/standalone/.next/server/chunks/ssr/_1cj2yog._.js +3 -0
  273. package/.next/standalone/.next/server/chunks/ssr/_1fm1ih_._.js +2 -2
  274. package/.next/standalone/.next/server/chunks/ssr/_1hdqw0-._.js +7 -0
  275. package/.next/standalone/.next/server/chunks/ssr/_1k2nmbw._.js +2 -2
  276. package/.next/standalone/.next/server/chunks/ssr/_1r62six._.js +7 -0
  277. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_insights_page_actions_0-0tf75.js +3 -0
  278. package/.next/standalone/.next/server/chunks/ssr/app_141w189._.js +1 -1
  279. package/.next/standalone/.next/server/chunks/ssr/app_components_0uuff77._.js +25 -2
  280. package/.next/standalone/.next/server/chunks/ssr/app_components_1j3q-h5._.js +25 -2
  281. package/.next/standalone/.next/server/chunks/ssr/app_components_CompanyScores_1g0mytz.js +1 -1
  282. package/.next/standalone/.next/server/chunks/ssr/app_components_settings_SectorPicker_1c-29qw.js +1 -1
  283. package/.next/standalone/.next/server/chunks/ssr/app_components_ui_0pdmz2z.js +3 -0
  284. package/.next/standalone/.next/server/chunks/ssr/app_import_page_1fmu6_l.js +1 -1
  285. package/.next/standalone/.next/server/chunks/ssr/app_insights_page_1d_chja.js +3 -0
  286. package/.next/standalone/.next/server/chunks/ssr/app_launch_page_19t0dyd.js +1 -1
  287. package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +26 -14
  288. package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +2 -2
  289. package/.next/standalone/.next/server/chunks/ssr/app_profile_page_0u3-l5y.js +1 -1
  290. package/.next/standalone/.next/server/chunks/ssr/app_queue_page_0c6znd6.js +11 -11
  291. package/.next/standalone/.next/server/chunks/ssr/app_settings_page_1f8mjj_.js +1 -1
  292. package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +12 -13
  293. package/.next/standalone/.next/server/chunks/ssr/app_social_page_0h7zxda.js +1 -1
  294. package/.next/standalone/.next/server/chunks/ssr/{lib_1c4ieuw._.js → lib_csv_1ttiu_h.js} +2 -2
  295. package/.next/standalone/.next/server/chunks/ssr/lib_galaxy-lab_108_lu-.js +1 -1
  296. package/.next/standalone/.next/server/chunks/ssr/lib_separation_1305zsx.js +3 -0
  297. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0pco7a6._.js +1 -1
  298. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  299. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  300. package/.next/standalone/.next/server/next-font-manifest.js +1 -1
  301. package/.next/standalone/.next/server/next-font-manifest.json +4 -0
  302. package/.next/standalone/.next/server/pages/404.html +1 -1
  303. package/.next/standalone/.next/server/pages/500.html +1 -1
  304. package/.next/standalone/.next/server/prefetch-hints.json +14 -0
  305. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  306. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  307. package/.next/standalone/.next/static/chunks/02wnf8dkxegxg.js +34 -0
  308. package/.next/standalone/.next/static/chunks/03-_esd2x_yk6.js +1 -0
  309. package/.next/standalone/.next/static/chunks/03-demj2iy-0p.js +44 -0
  310. package/.next/standalone/.next/static/chunks/0838_s6w-i_ik.js +1 -0
  311. package/.next/standalone/.next/static/chunks/0_1r-3csplxnj.js +1 -0
  312. package/.next/standalone/.next/static/chunks/0ka4prpk3w9wn.js +34 -0
  313. package/.next/standalone/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
  314. package/.next/standalone/.next/static/chunks/0s_xxwp7z88vv.js +1 -0
  315. package/.next/standalone/.next/static/chunks/1-nnl8amfm4yh.js +57 -0
  316. package/.next/standalone/.next/static/chunks/112mv-com-mqa.js +21 -0
  317. package/.next/standalone/.next/static/chunks/1bkt_hhjzvbh8.js +1 -0
  318. package/.next/standalone/.next/static/chunks/1cmphb3kh2ers.css +3 -0
  319. package/.next/standalone/.next/static/chunks/1d8yv3k_atka7.js +1 -0
  320. package/.next/standalone/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
  321. package/.next/standalone/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
  322. package/.next/standalone/.next/static/chunks/23hc51oa4vkhc.js +5 -0
  323. package/.next/standalone/.next/static/chunks/27n8k9wxlz5-7.js +1 -0
  324. package/.next/standalone/.next/static/chunks/2q9i7pcxcnph1.js +7 -0
  325. package/.next/standalone/.next/static/chunks/2w-y83mjlpnse.js +1 -0
  326. package/.next/standalone/.next/static/chunks/2ws1xf293j-tm.js +5 -0
  327. package/.next/standalone/.next/static/chunks/2z1-q0_vunbql.js +2 -0
  328. package/.next/standalone/.next/static/chunks/34g73qhayuevu.js +1 -0
  329. package/.next/standalone/.next/static/chunks/3cqn-r-y5rrw1.js +5 -0
  330. package/.next/standalone/.next/static/chunks/3opgg1efrx8q6.js +1 -0
  331. package/.next/standalone/.next/static/chunks/3p51fpxxi4d5y.js +34 -0
  332. package/.next/standalone/.next/static/chunks/3y40z6of3r9py.js +1 -0
  333. package/.next/standalone/.next/static/chunks/403dpflln8ah5.js +1 -0
  334. package/.next/standalone/.next/static/chunks/43pg2sursiypz.js +1 -0
  335. package/.next/standalone/CHANGELOG.md +203 -0
  336. package/.next/standalone/README.md +96 -50
  337. package/.next/standalone/SECURITY.md +25 -11
  338. package/.next/standalone/app/api/data/backup/route.js +25 -0
  339. package/.next/standalone/app/api/data/csv/route.js +74 -0
  340. package/.next/standalone/app/api/data/export/route.js +1 -1
  341. package/.next/standalone/app/api/data/restore/route.js +48 -0
  342. package/.next/standalone/app/api/data/reveal/route.js +19 -6
  343. package/.next/standalone/app/api/data/route.js +15 -4
  344. package/.next/standalone/app/api/ingest/route.js +1 -1
  345. package/.next/standalone/app/api/outreach/route.js +13 -73
  346. package/.next/standalone/app/api/queue/route.js +1 -1
  347. package/.next/standalone/app/api/scraper/route.js +217 -36
  348. package/.next/standalone/app/api/social/crm/route.js +2 -1
  349. package/.next/standalone/app/components/AppHeader.js +41 -21
  350. package/.next/standalone/app/components/AppTabs.js +12 -8
  351. package/.next/standalone/app/components/AutoConnect.js +286 -0
  352. package/.next/standalone/app/components/AutoScanButton.js +2 -2
  353. package/.next/standalone/app/components/Avatar.js +1 -1
  354. package/.next/standalone/app/components/ChainView.js +258 -113
  355. package/.next/standalone/app/components/CirclePanel.js +16 -16
  356. package/.next/standalone/app/components/ClusterSpinner.js +64 -0
  357. package/.next/standalone/app/components/CompanyScores.js +20 -20
  358. package/.next/standalone/app/components/EmptyState.js +39 -18
  359. package/.next/standalone/app/components/FieldStep.js +15 -13
  360. package/.next/standalone/app/components/FilterPanel.js +25 -18
  361. package/.next/standalone/app/components/ForceGraph.js +49 -14
  362. package/.next/standalone/app/components/GalaxyLab.js +33 -33
  363. package/.next/standalone/app/components/GridView.js +18 -18
  364. package/.next/standalone/app/components/LegacyScoresCard.js +10 -11
  365. package/.next/standalone/app/components/LinkedInLimits.js +57 -27
  366. package/.next/standalone/app/components/LiquidGlass.js +99 -0
  367. package/.next/standalone/app/components/ListView.js +20 -20
  368. package/.next/standalone/app/components/MapControls.js +5 -5
  369. package/.next/standalone/app/components/MappingProgress.js +16 -16
  370. package/.next/standalone/app/components/NoteDetail.js +13 -13
  371. package/.next/standalone/app/components/OnboardingGate.js +4 -4
  372. package/.next/standalone/app/components/OutlinkQuest.js +56 -35
  373. package/.next/standalone/app/components/PathsAnalyzer.js +37 -36
  374. package/.next/standalone/app/components/PeopleMap.js +21 -21
  375. package/.next/standalone/app/components/RingsView.js +11 -11
  376. package/.next/standalone/app/components/ScanRadar.js +84 -39
  377. package/.next/standalone/app/components/ScanStatusBar.js +40 -21
  378. package/.next/standalone/app/components/ScanTrail.js +21 -8
  379. package/.next/standalone/app/components/SeparationView.js +172 -124
  380. package/.next/standalone/app/components/Sidebar.js +308 -199
  381. package/.next/standalone/app/components/StaleServerBanner.js +4 -4
  382. package/.next/standalone/app/components/TheirCircle.js +26 -26
  383. package/.next/standalone/app/components/ThemeDefs.js +42 -0
  384. package/.next/standalone/app/components/ThemeLoader.js +20 -1
  385. package/.next/standalone/app/components/UpdatePanel.js +22 -22
  386. package/.next/standalone/app/components/UserProvider.js +22 -15
  387. package/.next/standalone/app/components/insights/Boards.js +275 -0
  388. package/.next/standalone/app/components/insights/PeopleView.js +266 -0
  389. package/.next/standalone/app/components/insights/Rail.js +156 -0
  390. package/.next/standalone/app/components/insights/Report.js +382 -0
  391. package/.next/standalone/app/components/insights/parts.js +239 -0
  392. package/.next/standalone/app/components/settings/AppearanceSection.js +47 -24
  393. package/.next/standalone/app/components/settings/DataSection.js +276 -109
  394. package/.next/standalone/app/components/settings/NetworkHealthSection.js +13 -13
  395. package/.next/standalone/app/components/settings/SectorPicker.js +12 -12
  396. package/.next/standalone/app/components/settings/SectorSection.js +13 -14
  397. package/.next/standalone/app/components/settings/TierSection.js +9 -9
  398. package/.next/standalone/app/components/settings/TitleSection.js +11 -11
  399. package/.next/standalone/app/components/settings/UsageSection.js +360 -0
  400. package/.next/standalone/app/components/ui.js +8 -8
  401. package/.next/standalone/app/globals.css +161 -5
  402. package/.next/standalone/app/import/page.js +94 -38
  403. package/.next/standalone/app/insights/page.js +220 -0
  404. package/.next/standalone/app/launch/page.js +5 -5
  405. package/.next/standalone/app/layout.js +6 -2
  406. package/.next/standalone/app/page.js +53 -53
  407. package/.next/standalone/app/paths/page.js +63 -63
  408. package/.next/standalone/app/profile/page.js +58 -58
  409. package/.next/standalone/app/queue/page.js +84 -72
  410. package/.next/standalone/app/scores/page.js +2 -2
  411. package/.next/standalone/app/settings/page.js +16 -13
  412. package/.next/standalone/app/setup/page.js +236 -133
  413. package/.next/standalone/app/social/Crm.js +63 -62
  414. package/.next/standalone/app/social/SocialHub.js +22 -22
  415. package/.next/standalone/app/social/Thread.js +7 -7
  416. package/.next/standalone/app/social/page.js +2 -2
  417. package/.next/standalone/lib/auto-connect.js +145 -0
  418. package/.next/standalone/lib/backups.js +458 -0
  419. package/.next/standalone/lib/chain-layout.js +32 -0
  420. package/.next/standalone/lib/companies.js +1 -1
  421. package/.next/standalone/lib/csv-store.js +131 -0
  422. package/.next/standalone/lib/csv.js +137 -39
  423. package/.next/standalone/lib/data-folder.js +19 -3
  424. package/.next/standalone/lib/data-import.js +5 -2
  425. package/.next/standalone/lib/db-client.js +78 -20
  426. package/.next/standalone/lib/demo.js +5 -4
  427. package/.next/standalone/lib/galaxy-export.js +9 -2
  428. package/.next/standalone/lib/galaxy-lab.js +19 -5
  429. package/.next/standalone/lib/galaxy-layouts.js +43 -0
  430. package/.next/standalone/lib/gate.js +10 -4
  431. package/.next/standalone/lib/in-progress.js +46 -0
  432. package/.next/standalone/lib/ingest.js +1 -1
  433. package/.next/standalone/lib/insights-board.js +613 -0
  434. package/.next/standalone/lib/linkedin-limits.js +240 -14
  435. package/.next/standalone/lib/liquid-glass.js +59 -0
  436. package/.next/standalone/lib/notifications.js +13 -0
  437. package/.next/standalone/lib/requests-client.js +10 -0
  438. package/.next/standalone/lib/requests.js +124 -0
  439. package/.next/standalone/lib/scan-pace.js +11 -0
  440. package/.next/standalone/lib/scan-progress.js +20 -0
  441. package/.next/standalone/lib/scan-risk.js +44 -0
  442. package/.next/standalone/lib/scan-state.js +1 -0
  443. package/.next/standalone/lib/scanner-setup.js +97 -15
  444. package/.next/standalone/lib/scraper-client.js +35 -8
  445. package/.next/standalone/lib/search-risk.js +7 -3
  446. package/.next/standalone/lib/settings-client.js +5 -3
  447. package/.next/standalone/lib/settings.js +13 -0
  448. package/.next/standalone/lib/social-store.js +3 -2
  449. package/.next/standalone/lib/synced-setting.js +46 -0
  450. package/.next/standalone/lib/theme-store.js +42 -10
  451. package/.next/standalone/lib/themes.js +111 -21
  452. package/.next/standalone/lib/usage.js +200 -0
  453. package/.next/standalone/package-lock.json +2 -2
  454. package/.next/standalone/package.json +1 -1
  455. package/.next/standalone/scripts/scrape.py +595 -11
  456. package/.next/static/chunks/02wnf8dkxegxg.js +34 -0
  457. package/.next/static/chunks/03-_esd2x_yk6.js +1 -0
  458. package/.next/static/chunks/03-demj2iy-0p.js +44 -0
  459. package/.next/static/chunks/0838_s6w-i_ik.js +1 -0
  460. package/.next/static/chunks/0_1r-3csplxnj.js +1 -0
  461. package/.next/static/chunks/0ka4prpk3w9wn.js +34 -0
  462. package/.next/static/chunks/0kscsqnvfq3-r.js +1 -0
  463. package/.next/static/chunks/0s_xxwp7z88vv.js +1 -0
  464. package/.next/static/chunks/1-nnl8amfm4yh.js +57 -0
  465. package/.next/static/chunks/112mv-com-mqa.js +21 -0
  466. package/.next/static/chunks/1bkt_hhjzvbh8.js +1 -0
  467. package/.next/static/chunks/1cmphb3kh2ers.css +3 -0
  468. package/.next/static/chunks/1d8yv3k_atka7.js +1 -0
  469. package/.next/static/chunks/{0ws7zy0w57ufi.js → 1eyajb9ntzlrl.js} +1 -1
  470. package/.next/static/chunks/1z9lb-dbcg4aa.js +1 -0
  471. package/.next/static/chunks/23hc51oa4vkhc.js +5 -0
  472. package/.next/static/chunks/27n8k9wxlz5-7.js +1 -0
  473. package/.next/static/chunks/2q9i7pcxcnph1.js +7 -0
  474. package/.next/static/chunks/2w-y83mjlpnse.js +1 -0
  475. package/.next/static/chunks/2ws1xf293j-tm.js +5 -0
  476. package/.next/static/chunks/2z1-q0_vunbql.js +2 -0
  477. package/.next/static/chunks/34g73qhayuevu.js +1 -0
  478. package/.next/static/chunks/3cqn-r-y5rrw1.js +5 -0
  479. package/.next/static/chunks/3opgg1efrx8q6.js +1 -0
  480. package/.next/static/chunks/3p51fpxxi4d5y.js +34 -0
  481. package/.next/static/chunks/3y40z6of3r9py.js +1 -0
  482. package/.next/static/chunks/403dpflln8ah5.js +1 -0
  483. package/.next/static/chunks/43pg2sursiypz.js +1 -0
  484. package/CHANGELOG.md +203 -0
  485. package/README.md +96 -50
  486. package/SECURITY.md +25 -11
  487. package/lib/auto-connect.js +145 -0
  488. package/lib/backups.js +458 -0
  489. package/lib/chain-layout.js +32 -0
  490. package/lib/companies.js +1 -1
  491. package/lib/csv-store.js +131 -0
  492. package/lib/csv.js +137 -39
  493. package/lib/data-folder.js +19 -3
  494. package/lib/data-import.js +5 -2
  495. package/lib/db-client.js +78 -20
  496. package/lib/demo.js +5 -4
  497. package/lib/galaxy-export.js +9 -2
  498. package/lib/galaxy-lab.js +19 -5
  499. package/lib/galaxy-layouts.js +43 -0
  500. package/lib/gate.js +10 -4
  501. package/lib/in-progress.js +46 -0
  502. package/lib/ingest.js +1 -1
  503. package/lib/insights-board.js +613 -0
  504. package/lib/linkedin-limits.js +240 -14
  505. package/lib/liquid-glass.js +59 -0
  506. package/lib/notifications.js +13 -0
  507. package/lib/requests-client.js +10 -0
  508. package/lib/requests.js +124 -0
  509. package/lib/scan-pace.js +11 -0
  510. package/lib/scan-progress.js +20 -0
  511. package/lib/scan-risk.js +44 -0
  512. package/lib/scan-state.js +1 -0
  513. package/lib/scanner-setup.js +97 -15
  514. package/lib/scraper-client.js +35 -8
  515. package/lib/search-risk.js +7 -3
  516. package/lib/settings-client.js +5 -3
  517. package/lib/settings.js +13 -0
  518. package/lib/social-store.js +3 -2
  519. package/lib/synced-setting.js +46 -0
  520. package/lib/theme-store.js +42 -10
  521. package/lib/themes.js +111 -21
  522. package/lib/usage.js +200 -0
  523. package/package.json +1 -1
  524. package/scripts/scrape.py +595 -11
  525. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-rnla2._.js +0 -3
  526. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13dx4sd._.js +0 -8
  527. package/.next/standalone/.next/server/chunks/[root-of-the-server]__14ou7j5._.js +0 -3
  528. package/.next/standalone/.next/server/chunks/[root-of-the-server]__16iu0hv._.js +0 -3
  529. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1kbl21f._.js +0 -3
  530. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rphsdk._.js +0 -3
  531. package/.next/standalone/.next/server/chunks/_02twlca._.js +0 -10
  532. package/.next/standalone/.next/server/chunks/lib_0851sk0._.js +0 -8
  533. package/.next/standalone/.next/server/chunks/lib_1q7p2ro._.js +0 -8
  534. package/.next/standalone/.next/server/chunks/lib_1r6l86l._.js +0 -8
  535. package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +0 -174
  536. package/.next/standalone/.next/server/chunks/lib_rpc_04s8mzr.js +0 -3
  537. package/.next/standalone/.next/server/chunks/lib_rpc_053z7as.js +0 -3
  538. package/.next/standalone/.next/server/chunks/lib_rpc_0b_-2te.js +0 -3
  539. package/.next/standalone/.next/server/chunks/lib_rpc_0dhbxdm.js +0 -3
  540. package/.next/standalone/.next/server/chunks/lib_rpc_0dxlk31.js +0 -3
  541. package/.next/standalone/.next/server/chunks/lib_rpc_0f8b-qc.js +0 -3
  542. package/.next/standalone/.next/server/chunks/lib_rpc_0pzie7_.js +0 -3
  543. package/.next/standalone/.next/server/chunks/lib_rpc_0r76fq_.js +0 -3
  544. package/.next/standalone/.next/server/chunks/lib_rpc_0ut7pjp.js +0 -3
  545. package/.next/standalone/.next/server/chunks/lib_rpc_15zyqaz.js +0 -3
  546. package/.next/standalone/.next/server/chunks/lib_rpc_18zpjtq.js +0 -3
  547. package/.next/standalone/.next/server/chunks/lib_rpc_1a8xkiz.js +0 -3
  548. package/.next/standalone/.next/server/chunks/lib_rpc_1e_55xo.js +0 -3
  549. package/.next/standalone/.next/server/chunks/lib_rpc_1oxfd1_.js +0 -3
  550. package/.next/standalone/.next/server/chunks/lib_rpc_1s0lod0.js +0 -3
  551. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08oxiqh._.js +0 -3
  552. package/.next/standalone/.next/server/chunks/ssr/_03l7vge._.js +0 -3
  553. package/.next/standalone/.next/server/chunks/ssr/_08g31gm._.js +0 -3
  554. package/.next/standalone/.next/server/chunks/ssr/_0gk_ofx._.js +0 -3
  555. package/.next/standalone/.next/server/chunks/ssr/_0nwsf93._.js +0 -3
  556. package/.next/standalone/.next/server/chunks/ssr/_0vho1lb._.js +0 -3
  557. package/.next/standalone/.next/server/chunks/ssr/_1-658fq._.js +0 -3
  558. package/.next/standalone/.next/server/chunks/ssr/_1bc46kz._.js +0 -3
  559. package/.next/standalone/.next/server/chunks/ssr/_1f_n00p._.js +0 -3
  560. package/.next/standalone/.next/server/chunks/ssr/_2105jz8._.js +0 -3
  561. package/.next/standalone/.next/server/chunks/ssr/app_components_0t908t-._.js +0 -3
  562. package/.next/standalone/.next/static/chunks/02pq76u7y4v9-.js +0 -22
  563. package/.next/standalone/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
  564. package/.next/standalone/.next/static/chunks/0i02yxppzds1o.js +0 -1
  565. package/.next/standalone/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
  566. package/.next/standalone/.next/static/chunks/0oyslj62jkubd.js +0 -1
  567. package/.next/standalone/.next/static/chunks/0vo-l8hxneba6.css +0 -3
  568. package/.next/standalone/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
  569. package/.next/standalone/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
  570. package/.next/standalone/.next/static/chunks/172e10mi-tpo_.js +0 -34
  571. package/.next/standalone/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
  572. package/.next/standalone/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
  573. package/.next/standalone/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
  574. package/.next/standalone/.next/static/chunks/1m3017gp790pw.js +0 -45
  575. package/.next/standalone/.next/static/chunks/1t20e8u0st7ep.js +0 -1
  576. package/.next/standalone/.next/static/chunks/2-ch9rm27eril.js +0 -11
  577. package/.next/standalone/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
  578. package/.next/standalone/.next/static/chunks/3bp284gjf7dyq.js +0 -1
  579. package/.next/standalone/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
  580. package/.next/standalone/.next/static/chunks/3l4t8je6iguzc.js +0 -1
  581. package/.next/standalone/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
  582. package/.next/standalone/.next/static/chunks/42m0bqr8pbovz.js +0 -11
  583. package/.next/static/chunks/02pq76u7y4v9-.js +0 -22
  584. package/.next/static/chunks/0cmq0exd4d0h9.js +0 -1
  585. package/.next/static/chunks/0i02yxppzds1o.js +0 -1
  586. package/.next/static/chunks/0m_p4k-q2qh--.js +0 -1
  587. package/.next/static/chunks/0oyslj62jkubd.js +0 -1
  588. package/.next/static/chunks/0vo-l8hxneba6.css +0 -3
  589. package/.next/static/chunks/0yh8z2tbrc5i_.js +0 -1
  590. package/.next/static/chunks/17-rhp8sg4m1b.js +0 -44
  591. package/.next/static/chunks/172e10mi-tpo_.js +0 -34
  592. package/.next/static/chunks/1ei5vbe2uw6fl.js +0 -1
  593. package/.next/static/chunks/1f7_pl_wq7lh3.js +0 -11
  594. package/.next/static/chunks/1jzbe7zdx9vbj.js +0 -2
  595. package/.next/static/chunks/1m3017gp790pw.js +0 -45
  596. package/.next/static/chunks/1t20e8u0st7ep.js +0 -1
  597. package/.next/static/chunks/2-ch9rm27eril.js +0 -11
  598. package/.next/static/chunks/2ldv-v3s9yaif.js +0 -1
  599. package/.next/static/chunks/3bp284gjf7dyq.js +0 -1
  600. package/.next/static/chunks/3k1f6clbn3gj3.js +0 -7
  601. package/.next/static/chunks/3l4t8je6iguzc.js +0 -1
  602. package/.next/static/chunks/3tplzuc9jk-tl.js +0 -1
  603. package/.next/static/chunks/42m0bqr8pbovz.js +0 -11
  604. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_buildManifest.js +0 -0
  605. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_clientMiddlewareManifest.js +0 -0
  606. /package/.next/standalone/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_ssgManifest.js +0 -0
  607. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_buildManifest.js +0 -0
  608. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_clientMiddlewareManifest.js +0 -0
  609. /package/.next/static/{dQUvvVSXqbkEFC3-CNcwT → 3NCyJyAPDCEYsYTwF1Ieu}/_ssgManifest.js +0 -0
@@ -0,0 +1,44 @@
1
+ // Saying yes to the scanner's risk, once, before it first touches LinkedIn.
2
+ //
3
+ // The Scan page used to carry the risk as a grey line at the bottom. Now the
4
+ // first scan waits for an explicit "I understand" to three plain points, kept
5
+ // as a setting (app_meta, lib/settings.js) so it travels with a copy of the
6
+ // data. The server checks it too, so no button anywhere (the header's Check for
7
+ // new, a Scan button in a panel) can start a first scan without it.
8
+ //
9
+ // Someone who scanned before this existed has seen the risk and chosen it: the
10
+ // scanner's own Chrome profile in the data folder is the sign, since only the
11
+ // scanner makes one, and it never travels in a copy. They aren't asked again.
12
+ //
13
+ // No Node imports: the Scan page reads the points from here too.
14
+
15
+ export const RISK_POINTS = [
16
+ 'It runs your own LinkedIn account automatically, in a Chrome window on this computer.',
17
+ 'LinkedIn’s User Agreement doesn’t allow automated tools, and LinkedIn may restrict accounts that use them. The safe limits, 50 searches a day and 250 a month, stay on unless you change them.',
18
+ 'Nothing leaves your computer. There is no account with us and nothing is uploaded.',
19
+ ];
20
+
21
+ export const RISK_REFUSAL = 'Before the first scan, open the Scan page and confirm you understand what scanning risks.';
22
+
23
+ // The scanner's actions that never open LinkedIn: installing its Python and
24
+ // packages, and saving photos already linked from it (no browser, no search).
25
+ const OFF_LINKEDIN = new Set(['install', 'setup', 'photos']);
26
+
27
+ export const touchesLinkedIn = (action) => !OFF_LINKEDIN.has(String(action));
28
+
29
+ /** When the risk was accepted (ISO time), or null; set from the Scan page. */
30
+ export const SCAN_RISK_SETTING = {
31
+ default: null,
32
+ parse(value) {
33
+ if (value === null) return null;
34
+ if (typeof value !== 'string' || Number.isNaN(Date.parse(value))) {
35
+ throw new Error('When the scanning risk was accepted is a date and time.');
36
+ }
37
+ return new Date(value).toISOString();
38
+ },
39
+ };
40
+
41
+ /** @param {{ acceptedAt?: string | null, scannedBefore?: boolean }} state */
42
+ export function riskAccepted({ acceptedAt = null, scannedBefore = false } = {}) {
43
+ return Boolean(acceptedAt) || scannedBefore;
44
+ }
@@ -41,6 +41,7 @@ export function runningNow(job) {
41
41
  case 'setup': return 'The scanner is being set up';
42
42
  case 'login': return 'The LinkedIn sign-in window is open';
43
43
  case 'photos': return 'Profile photos are being saved';
44
+ case 'connect': return 'A connection request is being sent';
44
45
  default: return 'A scan is running';
45
46
  }
46
47
  }
@@ -1,12 +1,71 @@
1
1
  // What the Scan page's first step says and offers, from the checks GET
2
- // /api/scraper reports (app/api/scraper/route.js, lib/scanner-python.js), and
3
- // whether it asks for your field before that (askForField).
2
+ // /api/scraper reports (app/api/scraper/route.js, lib/scanner-python.js),
3
+ // whether it asks for your field once your connections are in (askForField),
4
+ // and two answers the server gives that step: is Google Chrome here
5
+ // (chromeInstalled), and are you signed in to LinkedIn (signedInFrom).
4
6
  // Plain data in, plain data out: the page draws it, and
5
7
  // tests/scanner-setup.test.mjs checks every state without a browser. No Node
6
8
  // imports here; the page runs in the browser.
7
9
 
8
10
  const MB = 1024 * 1024;
9
11
 
12
+ // The scanner drives Google Chrome (scripts/scrape.py, channel "chrome"), so a
13
+ // computer without it can set up the scanner's Python and still never scan.
14
+ // It used to be a red box above the steps while step 1 said Ready; now step 1
15
+ // isn't done without it, and the server refuses anything that opens LinkedIn
16
+ // with the same words (app/api/scraper/route.js).
17
+ export const CHROME_DOWNLOAD = 'https://www.google.com/chrome/';
18
+ export const CHROME_MISSING = 'The scanner works in Google Chrome, and Chrome isn’t on this computer.';
19
+ export const CHROME_BUTTON = 'Install Google Chrome, then come back';
20
+ export const CHROME_REFUSAL = `${CHROME_MISSING} ${CHROME_BUTTON}.`;
21
+
22
+ /**
23
+ * Is Google Chrome where Playwright's "chrome" channel looks for it (Chromium
24
+ * doesn't count)? `exists` is the file check (existsSync on the server), so
25
+ * this runs in a test with no Chrome at all.
26
+ *
27
+ * SIX_DEGREES_TEST_CHROME=found or =missing answers for the computer, for
28
+ * tests and for checking the Scan page's states by eye: the route's tests then
29
+ * don't depend on whether the machine running them has Chrome. Nothing in the
30
+ * app sets it; any other value is ignored.
31
+ */
32
+ export function chromeInstalled({ platform, env = {}, exists }) {
33
+ const forced = env.SIX_DEGREES_TEST_CHROME;
34
+ if (forced === 'found') return true;
35
+ if (forced === 'missing') return false;
36
+ if (platform === 'darwin') return exists('/Applications/Google Chrome.app');
37
+ if (platform === 'linux') return exists('/opt/google/chrome/chrome');
38
+ // On Windows, for this user, then for everyone.
39
+ if (platform === 'win32') {
40
+ return [env.LOCALAPPDATA, env.PROGRAMFILES, env['PROGRAMFILES(X86)']]
41
+ .filter(Boolean)
42
+ .some((root) => exists(`${String(root).replace(/[\\/]+$/, '')}\\Google\\Chrome\\Application\\chrome.exe`));
43
+ }
44
+ return true; // elsewhere Playwright resolves the channel itself
45
+ }
46
+
47
+ // The scanner's note that LinkedIn's session was confirmed (scripts/scrape.py
48
+ // SIGNED_IN_FILE): { signedIn, at }, written when the li_at cookie is seen past
49
+ // any sign-in wall, and set to false while it waits for you to sign in.
50
+ export const SIGNED_IN_FILE = 'signed-in.json';
51
+
52
+ /**
53
+ * Step 2's "Signed in". It used to be "Chrome's cookie file exists", which is
54
+ * true the moment the scanner's window first opens, so opening LinkedIn and
55
+ * closing the window without signing in ticked the step. Now the scanner's own
56
+ * note says it (`note`, the parsed SIGNED_IN_FILE, or null when there is none
57
+ * or it can't be read), and only while its Chrome profile is still there
58
+ * (`profile`): deleting that signs you out.
59
+ *
60
+ * A data folder from before the note existed has none, and there the old
61
+ * check stands (`cookies`), so nobody already signed in is told they're signed
62
+ * out; the next scan writes the note.
63
+ */
64
+ export function signedInFrom({ note, profile, cookies }) {
65
+ if (note && typeof note === 'object' && typeof note.signedIn === 'boolean') return note.signedIn && Boolean(profile);
66
+ return Boolean(cookies);
67
+ }
68
+
10
69
  /** "Python 3.9.6 is too old…": why a Python this computer has won't do, or ''. */
11
70
  function whyNotThisPython(found) {
12
71
  if (!found?.version) return 'This computer has no Python the scanner can use.';
@@ -40,10 +99,11 @@ function ownPythonNote(own, { done, button }) {
40
99
  }
41
100
 
42
101
  /**
43
- * Step 1, "Set up the scanner": { done, text, button, note }, where button is
44
- * { action: 'install'|'setup', label } or null (nothing to press), and note is
45
- * a line to show above the step when the Python inside the app didn't work
46
- * (ownPythonNote), or null.
102
+ * Step 1, "Set up the scanner": { done, text, button, note, chrome }, where
103
+ * button is { action: 'install'|'setup', label } or null (nothing to press),
104
+ * note is a line to show above the step when the Python inside the app didn't
105
+ * work (ownPythonNote), or null, and chrome is { label, href } when Google
106
+ * Chrome isn't on this computer (the way to get it), or null.
47
107
  *
48
108
  * ready the app's own Python (nothing to install), one named by
49
109
  * SIX_DEGREES_PYTHON, or the scanner's environment / a Python
@@ -53,10 +113,24 @@ function ownPythonNote(own, { done, button }) {
53
113
  * setup none, but a standalone Python for this computer is pinned:
54
114
  * "Set up the scanner" downloads it, then installs
55
115
  * neither no Python and nothing to download for this computer
116
+ *
117
+ * Any of them without Chrome isn't done: the Python's part is said first if
118
+ * there is one, then Chrome's. Only a definite "no Chrome" counts; a status
119
+ * that couldn't say (none yet, or an older server's) leaves it out.
56
120
  */
57
121
  export function setupStep(status) {
58
122
  const step = stepOnly(status);
59
- return { ...step, note: ownPythonNote(status?.checks?.ownPython, step) };
123
+ const note = ownPythonNote(status?.checks?.ownPython, step);
124
+ if (status?.checks?.chrome !== false) return { ...step, note, chrome: null };
125
+ return {
126
+ ...step,
127
+ done: false,
128
+ // "Ready" or "Installed." would read as finished: with the Python done,
129
+ // Chrome is all the step says.
130
+ text: step.done ? CHROME_MISSING : `${step.text} ${CHROME_MISSING}`,
131
+ note,
132
+ chrome: { label: CHROME_BUTTON, href: CHROME_DOWNLOAD },
133
+ };
60
134
  }
61
135
 
62
136
  function stepOnly(status) {
@@ -105,19 +179,27 @@ function stepOnly(status) {
105
179
  }
106
180
 
107
181
  /**
108
- * Whether the Scan page asks for your field first (app/components/FieldStep.js):
109
- * once, before the first scan. Never to someone who already has a network, has
110
- * picked a sector (Scores → Your sector), or answered or skipped the question
111
- * before (`fieldAsked`). `status` is GET /api/scraper's answer (null while it
112
- * loads), `settings` GET /api/settings' `settings` (undefined while it loads,
113
- * null when it couldn't be read). null means not known yet: the page waits,
114
- * rather than show the steps and then swap them for the question.
182
+ * Whether the Scan page asks for your field (app/components/FieldStep.js):
183
+ * once, when your own connections are in (step 3) and before who they know is
184
+ * mapped, under "Your galaxy is ready". It used to stand in front of step 1,
185
+ * one more thing between someone new and their first scan; asked here, it
186
+ * rescores people they can already see.
187
+ *
188
+ * Never before step 3, never once a 2nd-degree or company scan is in (that
189
+ * network's owner is past onboarding), never while a scan runs, and never to
190
+ * someone who has picked a sector (Scores → Your sector) or answered or
191
+ * skipped it before (`fieldAsked`, saved either way). So whoever has only
192
+ * their 1st degree mapped, someone from before this moved included, is asked
193
+ * once. `status` is GET /api/scraper's answer (null while it loads), `settings`
194
+ * GET /api/settings' `settings` (undefined while it loads, null when it
195
+ * couldn't be read). null means not known yet: the page leaves the question
196
+ * out until it is, rather than show it and take it away.
115
197
  */
116
198
  export function askForField(status, settings) {
117
199
  if (!status) return null;
118
200
  const n = status.network;
119
201
  // No counts means the app couldn't be asked; a scan running is past asking.
120
- if (!n || n.first || n.second || n.third || status.running) return false;
202
+ if (!n || !n.first || n.second || n.third || status.running) return false;
121
203
  if (settings === undefined) return null;
122
204
  return Boolean(settings && !settings.fieldAsked && !settings.sectorFocus?.sectors?.length);
123
205
  }
@@ -8,6 +8,7 @@
8
8
  // Now they all call this, which talks to /api/scraper on the app itself.
9
9
 
10
10
  import { runningNow } from './scan-state.js';
11
+ import { CHROME_REFUSAL } from './scanner-setup.js';
11
12
 
12
13
  export async function scraperStatus() {
13
14
  const r = await fetch('/api/scraper');
@@ -38,7 +39,13 @@ export async function startScrape(action, name, extra = {}) {
38
39
  body: JSON.stringify(scanRequest(action, { ...(name ? { name } : {}), ...extra })),
39
40
  });
40
41
  const d = await r.json().catch(() => ({}));
41
- if (!r.ok) throw new Error(d.error || 'Could not start the scanner.');
42
+ if (!r.ok) {
43
+ // The answer's flags travel with the error (needsAutoAcceptance, say), so a
44
+ // button can tell a question to ask from a reason to show.
45
+ const err = new Error(d.error || 'Could not start the scanner.');
46
+ err.details = d;
47
+ throw err;
48
+ }
42
49
  return d;
43
50
  }
44
51
 
@@ -54,12 +61,13 @@ export async function resumePoint(id) {
54
61
  }
55
62
 
56
63
  /** Nothing noted: before the first answer, and for the sample or a CSV. */
57
- export const NO_SCAN_NOTES = Object.freeze({ skips: [], read: [] });
64
+ export const NO_SCAN_NOTES = Object.freeze({ skips: [], read: [], lists: {} });
58
65
 
59
66
  /**
60
67
  * What the scanner noted, for lib/reach.js: `skips`, the hidden lists
61
- * ([{ profileUrl, … }]), and `read`, the profile URLs of every list it has
62
- * read. Never throws: with no answer (the app restarting, say) nothing is
68
+ * ([{ profileUrl, … }]), `read`, the profile URLs of every list it has
69
+ * read, and `lists`, how far each was read ({ url: { pages, more, total } }).
70
+ * Never throws: with no answer (the app restarting, say) nothing is
63
71
  * noted, so a hidden list shows as ready rather than anyone going missing.
64
72
  */
65
73
  export async function loadScanNotes() {
@@ -67,7 +75,11 @@ export async function loadScanNotes() {
67
75
  const r = await fetch('/api/scraper?reach=1');
68
76
  if (!r.ok) return NO_SCAN_NOTES;
69
77
  const d = await r.json();
70
- return { skips: Array.isArray(d.skips) ? d.skips : [], read: Array.isArray(d.read) ? d.read : [] };
78
+ // `lists` is how far each list was read, for the rings round a dot
79
+ // (lib/reach.js scanBars). Dropped here until 10/3, every scanned
80
+ // connection drew 2 of 5 bars, "partly read", even with the whole list in.
81
+ const lists = d.lists && typeof d.lists === 'object' && !Array.isArray(d.lists) ? d.lists : {};
82
+ return { skips: Array.isArray(d.skips) ? d.skips : [], read: Array.isArray(d.read) ? d.read : [], lists };
71
83
  } catch {
72
84
  return NO_SCAN_NOTES;
73
85
  }
@@ -88,9 +100,10 @@ export function notReadyMessage(status) {
88
100
  if (!c.dependencies) {
89
101
  // With no Python and nothing to download for this computer, Scan can't help yet.
90
102
  if (!c.python && !c.download) return 'No Python 3.10 to 3.14 is installed on this machine.';
91
- return 'The scanner is not set up yet — open Scan to set it up.';
103
+ return 'The scanner is not set up yet. Open Scan to set it up.';
92
104
  }
93
- if (!c.chrome) return 'Google Chrome is not installed.';
105
+ // The words the Scan page and the server use (lib/scanner-setup.js).
106
+ if (!c.chrome) return CHROME_REFUSAL;
94
107
  return null;
95
108
  }
96
109
 
@@ -121,7 +134,7 @@ const QUIET_MS = 5000;
121
134
  /** Before the first answer, and on the server, where nothing is asked. */
122
135
  export const SCANNER_UNKNOWN = Object.freeze({
123
136
  known: false, running: false, pending: false, action: null, target: null,
124
- startedAt: null, progress: null, pages: 0, log: [], finished: [],
137
+ startedAt: null, progress: null, pages: 0, found: [], log: [], finished: [],
125
138
  });
126
139
 
127
140
  const listeners = new Set();
@@ -165,6 +178,7 @@ function take(s) {
165
178
  startedAt: running ? s.startedAt ?? null : null,
166
179
  progress: running ? s.progress ?? null : null,
167
180
  pages: running ? Number(s.pages) || 0 : 0, // pages read so far (app/api/scraper/route.js)
181
+ found: running && Array.isArray(s.found) ? s.found.map(Number).filter(Number.isFinite) : [], // people each page found
168
182
  budget: running ? s.budget ?? null : null,
169
183
  log: running && Array.isArray(s.log) ? s.log : [],
170
184
  finished,
@@ -271,6 +285,17 @@ export function isCircleScan(job) {
271
285
  return Boolean(job?.target) && ['bridge', 'rescrape', 'resume'].includes(job.action);
272
286
  }
273
287
 
288
+ /**
289
+ * Does this job add people to circles on the map while it runs: one person's
290
+ * circle, or a batch of them (Map 2nd degree, every paused list)? The map
291
+ * looks again every so often while one does, with Bridge Chains open
292
+ * (app/page.js NetworkRefresh), so the Scan page's "Watch it fill in" shows
293
+ * the circle filling in, not as it was when the page opened.
294
+ */
295
+ export function fillsCircles(job) {
296
+ return isCircleScan(job) || ['auto-bridge', 'auto-bridge-retry', 'resume-all'].includes(job?.action);
297
+ }
298
+
274
299
  /**
275
300
  * Is this job, running or finished, a read of this person's circle? By id when
276
301
  * both have one: two connections can share a name. Else by name.
@@ -300,6 +325,8 @@ export function busyReason(job = now) {
300
325
  case 'full':
301
326
  case 'refresh':
302
327
  return 'Your own connections are being scanned';
328
+ case 'connect':
329
+ return who ? `A request to ${who} is being sent` : 'A connection request is being sent';
303
330
  default:
304
331
  return runningNow(job.action);
305
332
  }
@@ -28,10 +28,14 @@ export function limitQuestion(from = {}, to = {}) {
28
28
  return null;
29
29
  }
30
30
 
31
- /** The note under the picker while the budget is risky; null when it isn't. */
32
- export function limitNote({ daily, monthly } = {}) {
31
+ /**
32
+ * The note under the picker while the budget is risky; null when it isn't.
33
+ * `restriction: false` leaves out the 373 sentence, for Settings → LinkedIn
34
+ * usage when its own warning has just said it (lib/usage.js warningParts).
35
+ */
36
+ export function limitNote({ daily, monthly } = {}, { restriction = true } = {}) {
33
37
  if (!riskyLimits({ daily, monthly })) return null;
34
- const parts = [`A real account was restricted after ${RESTRICTED_AT} searches in 24 hours.`];
38
+ const parts = restriction ? [`A real account was restricted after ${RESTRICTED_AT} searches in 24 hours.`] : [];
35
39
  if (riskyDaily(daily)) parts.push(`${daily} a day can use up a free account's month in a day or two.`);
36
40
  if (monthly === 0) parts.push('With no monthly cap, nothing but the daily budget stops a long run.');
37
41
  return parts.join(' ');
@@ -1,17 +1,19 @@
1
1
  // Saving settings from the browser: POST /api/settings with only the settings
2
2
  // that change (lib/settings.js keeps the rest as stored). Scores → Your sector
3
3
  // and Tiers save through it, and so does the Scan page's question about your
4
- // field before the first scan (app/components/FieldStep.js).
4
+ // field before the first scan (app/components/FieldStep.js), and the look and
5
+ // the Galaxy's saved layouts (lib/synced-setting.js).
5
6
 
6
7
  /**
8
+ * `keepalive` lets a save sent as the page goes away still arrive.
7
9
  * @returns { settings, effects, error }: `settings` as saved, also when the
8
10
  * save landed but the work it set in motion failed (lib/settings-effects.js);
9
11
  * `effects` what that work reported; `error` a message fit to show, or null.
10
12
  */
11
- export async function saveSettings(patch) {
13
+ export async function saveSettings(patch, { keepalive = false } = {}) {
12
14
  try {
13
15
  const r = await fetch('/api/settings', {
14
- method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ settings: patch }),
16
+ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ settings: patch }), keepalive,
15
17
  });
16
18
  const d = await r.json();
17
19
  return { settings: d.settings || null, effects: d.effects || null, error: r.ok ? null : d.error || 'Could not save.' };
@@ -13,6 +13,10 @@
13
13
  import { SECTOR_FOCUS_SETTING, FIELD_ASKED_SETTING } from './sector-focus.js';
14
14
  import { TIER_SCALE_SETTING } from './scoring.js';
15
15
  import { TITLE_RANKING_SETTING } from './title-ranking.js';
16
+ import { SCAN_RISK_SETTING } from './scan-risk.js';
17
+ import { AUTO_ACCEPTED_SETTING } from './auto-connect.js';
18
+ import { THEME_SETTING } from './themes.js';
19
+ import { GALAXY_LAYOUTS_SETTING } from './galaxy-layouts.js';
16
20
 
17
21
  export const SETTINGS = {
18
22
  // Scores → Your sector: industries whose companies count for more (lib/sector-focus.js).
@@ -23,6 +27,15 @@ export const SETTINGS = {
23
27
  tierScale: TIER_SCALE_SETTING,
24
28
  // Scores → Titles: how much each kind of title counts, and roles you're looking for (lib/title-ranking.js).
25
29
  titleRanking: TITLE_RANKING_SETTING,
30
+ // The Scan page's "I understand" before the first scan: when it was given (lib/scan-risk.js).
31
+ scanRiskAccepted: SCAN_RISK_SETTING,
32
+ // Auto's one-time question before its first connection request: when it was answered yes (lib/auto-connect.js).
33
+ autoConnectAccepted: AUTO_ACCEPTED_SETTING,
34
+ // Settings → Appearance: the look (lib/themes.js). Here so it travels with a
35
+ // backup or a restore; the browser keeps a copy to paint with first (lib/theme-store.js).
36
+ theme: THEME_SETTING,
37
+ // The Galaxy's saved layouts (lib/galaxy-layouts.js), here for the same reason.
38
+ galaxyLayouts: GALAXY_LAYOUTS_SETTING,
26
39
  };
27
40
 
28
41
  const KEY = 'settings';
@@ -14,8 +14,9 @@
14
14
  //
15
15
  // Two files so that turning Keep my messages off, or Forget it, deletes the
16
16
  // words by deleting one file, and so the everyday file the Galaxy and the
17
- // Social tab read stays small however many messages there are. "Save a copy of my network" carries
18
- // them when its Social box is ticked (lib/data-folder.js SOCIAL_FILE).
17
+ // Social tab read stays small however many messages there are. "Export backup file…" carries
18
+ // them when its Social box is ticked (lib/data-folder.js SOCIAL_FILE); the backups Six Degrees
19
+ // makes by itself never do, so deleting them here deletes them everywhere (lib/backups.js).
19
20
 
20
21
  import { readFileSync, writeFileSync, renameSync, rmSync, statSync } from 'node:fs';
21
22
  import path from 'node:path';
@@ -0,0 +1,46 @@
1
+ // A choice kept with the network (lib/settings.js), so it travels with a
2
+ // backup, an export and a restore, while the browser keeps a copy of it to
3
+ // read before the page paints (the look) or before the server answers. The
4
+ // look and the Galaxy's saved layouts work this way (lib/theme-store.js,
5
+ // lib/galaxy-lab.js). No imports: pure, so the tests can pin it.
6
+
7
+ /**
8
+ * What to use once the server has answered, and whether to save the browser's
9
+ * copy to it.
10
+ *
11
+ * - The server has one (`saved`): it wins. A restore or an import brings its
12
+ * own look, and another window of the app (the Mac app and a browser tab
13
+ * keep separate copies) may have changed it.
14
+ * - The server has none (null: never saved on this network, as for everyone
15
+ * before this was kept there): the browser's copy stands, and is saved once,
16
+ * unless it is only the default.
17
+ *
18
+ * @returns {{ use, save: boolean, changed: boolean }}
19
+ */
20
+ export function reconcileSaved({ saved, cached, isDefault, same }) {
21
+ if (saved === null || saved === undefined) return { use: cached, save: !isDefault(cached), changed: false };
22
+ return { use: saved, save: false, changed: !same(saved, cached) };
23
+ }
24
+
25
+ /**
26
+ * Save at most once per `wait` ms, the last value winning: a colour picker
27
+ * changes the look many times a second while it's dragged. `flush()` sends a
28
+ * waiting save now (the page is going away: otherwise the network's older
29
+ * value would win when it opens again). `save(value, { now })` is told which.
30
+ */
31
+ export function laterSaver(save, wait = 400) {
32
+ let timer = null;
33
+ let next;
34
+ const send = (now) => {
35
+ clearTimeout(timer);
36
+ timer = null;
37
+ Promise.resolve(save(next, { now })).catch(() => { /* kept in this browser; saved with the next change */ });
38
+ };
39
+ const later = (value) => {
40
+ next = value;
41
+ if (timer) clearTimeout(timer);
42
+ timer = setTimeout(() => send(false), wait);
43
+ };
44
+ later.flush = () => { if (timer) send(true); };
45
+ return later;
46
+ }
@@ -1,13 +1,17 @@
1
- // The theme in use, in this browser (lib/themes.js has what a theme is). Read
2
- // once when the page loads, before anything draws, so the dots, your dot and
3
- // the map's lines come out in its colours; changed from Settings → Appearance.
1
+ // The theme in use (lib/themes.js has what a theme is). Read once when the
2
+ // page loads, before anything draws, so the dots, your dot and the map's lines
3
+ // come out in its colours; changed from Settings → Appearance.
4
4
  //
5
- // Kept in localStorage, like the Galaxy's sliders: a look belongs to the
6
- // screen it's on. The CSS variables are kept beside it, ready made, for the
7
- // script in app/layout.js that puts them on the page before it paints, so a
8
- // theme never flashes the standard colours first.
5
+ // Saved with the network's settings (lib/settings.js 'theme'), so a backup, an
6
+ // export or a restore carries the look with it. localStorage keeps a copy, the
7
+ // one read before the page paints: the CSS variables are kept beside it, ready
8
+ // made, for the script in app/layout.js that puts them on the page first, so a
9
+ // theme never flashes the standard colours. Once the server answers
10
+ // (app/components/ThemeLoader.js), its look wins (lib/synced-setting.js).
9
11
 
10
- import { cleanTheme, resolveTheme, themeVars, themeAttrs, TIER_COLORS, MAP_LOOK } from './themes.js';
12
+ import { cleanTheme, resolveTheme, themeVars, themeAttrs, isLight, TIER_COLORS, MAP_LOOK } from './themes.js';
13
+ import { saveSettings } from './settings-client.js';
14
+ import { reconcileSaved, laterSaver } from './synced-setting.js';
11
15
 
12
16
  const KEY = 'six-degrees-theme';
13
17
  export const VARS_KEY = 'six-degrees-theme-vars';
@@ -24,12 +28,16 @@ function read() {
24
28
  function apply(next) {
25
29
  const theme = resolveTheme(next);
26
30
  Object.assign(TIER_COLORS, theme.tiers);
27
- Object.assign(MAP_LOOK, { you: theme.you, lines: theme.lines, line: theme.line, bg: theme.bg });
31
+ const light = isLight(theme);
32
+ Object.assign(MAP_LOOK, { you: theme.you, lines: theme.lines, line: theme.line, bg: theme.bg, dots: theme.dots, light, text: light ? '#11141c' : '#ffffff' });
28
33
  if (typeof document === 'undefined') return;
29
34
  const vars = themeVars(next);
30
35
  const root = document.documentElement;
36
+ // A light look's words and borders go when a dark one comes: they fall back to the dark values.
37
+ for (const k of [...root.style]) if (k.startsWith('--sd-') && !(k in vars)) root.style.removeProperty(k);
31
38
  for (const [k, v] of Object.entries(vars)) root.style.setProperty(k, v);
32
39
  Object.assign(root.dataset, themeAttrs(next));
40
+ root.style.colorScheme = light ? 'light' : 'dark';
33
41
  try { localStorage.setItem(VARS_KEY, JSON.stringify({ vars, attrs: themeAttrs(next) })); } catch { /* it's applied anyway */ }
34
42
  }
35
43
 
@@ -48,13 +56,37 @@ if (typeof window !== 'undefined') {
48
56
  export const themeNow = () => choice;
49
57
  export const serverTheme = () => DEFAULT;
50
58
 
51
- export function setTheme(next) {
59
+ const same = (a, b) => JSON.stringify(cleanTheme(a)) === JSON.stringify(cleanTheme(b));
60
+ const saveLater = laterSaver((theme, { now }) => saveSettings({ theme }, { keepalive: now }));
61
+ // A look picked just before a reload is saved on the way out, or the
62
+ // network's older one would replace it as the page opens again.
63
+ if (typeof window !== 'undefined') window.addEventListener('pagehide', () => saveLater.flush());
64
+
65
+ function choose(next) {
52
66
  choice = cleanTheme(next);
53
67
  try { localStorage.setItem(KEY, JSON.stringify(choice)); } catch { /* this visit only */ }
54
68
  apply(choice);
55
69
  listeners.forEach((f) => f());
56
70
  }
57
71
 
72
+ export function setTheme(next) {
73
+ choose(next);
74
+ saveLater(choice);
75
+ }
76
+
77
+ /**
78
+ * The look saved with the network (GET /api/settings 'theme'), once the page
79
+ * has it: it replaces this browser's copy, or, when the network has none yet,
80
+ * this browser's look is saved to it once.
81
+ */
82
+ export function adoptSavedTheme(saved) {
83
+ const { use: next, save, changed } = reconcileSaved({
84
+ saved: saved == null ? null : cleanTheme(saved), cached: choice, isDefault: (t) => same(t, DEFAULT), same,
85
+ });
86
+ if (save) saveSettings({ theme: choice });
87
+ if (changed) choose(next);
88
+ }
89
+
58
90
  export function watchTheme(f) {
59
91
  listeners.add(f);
60
92
  return () => listeners.delete(f);