recce-nightly 1.9.0.20250622__py3-none-any.whl → 1.9.0.20250623__py3-none-any.whl
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.
- recce/VERSION +1 -1
- recce/adapter/dbt_adapter/__init__.py +108 -45
- recce/cli.py +12 -11
- recce/data/404.html +1 -1
- recce/data/_next/static/chunks/app/{page-707b8e8d98d7f780.js → page-59241c42b7dd4fcf.js} +1 -1
- recce/data/index.html +2 -2
- recce/data/index.txt +2 -2
- recce/models/types.py +7 -0
- recce/server.py +14 -30
- recce/util/api_token.py +1 -9
- recce/util/lineage.py +16 -12
- recce/util/onboarding_state.py +45 -0
- recce/util/recce_cloud.py +7 -7
- {recce_nightly-1.9.0.20250622.dist-info → recce_nightly-1.9.0.20250623.dist-info}/METADATA +1 -1
- {recce_nightly-1.9.0.20250622.dist-info → recce_nightly-1.9.0.20250623.dist-info}/RECORD +22 -21
- tests/adapter/dbt_adapter/test_dbt_cll.py +9 -9
- /recce/data/_next/static/{M3_t2h-wA4_IXOtKHdJqV → WrRUb3nV8BhAZG_R8kVma}/_buildManifest.js +0 -0
- /recce/data/_next/static/{M3_t2h-wA4_IXOtKHdJqV → WrRUb3nV8BhAZG_R8kVma}/_ssgManifest.js +0 -0
- {recce_nightly-1.9.0.20250622.dist-info → recce_nightly-1.9.0.20250623.dist-info}/WHEEL +0 -0
- {recce_nightly-1.9.0.20250622.dist-info → recce_nightly-1.9.0.20250623.dist-info}/entry_points.txt +0 -0
- {recce_nightly-1.9.0.20250622.dist-info → recce_nightly-1.9.0.20250623.dist-info}/licenses/LICENSE +0 -0
- {recce_nightly-1.9.0.20250622.dist-info → recce_nightly-1.9.0.20250623.dist-info}/top_level.txt +0 -0
recce/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.9.0.
|
|
1
|
+
1.9.0.20250623
|
|
@@ -915,65 +915,128 @@ class DbtAdapter(BaseAdapter):
|
|
|
915
915
|
diff=diff,
|
|
916
916
|
)
|
|
917
917
|
|
|
918
|
-
def get_cll(
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
upstream
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
p_map, c_map = filter_dependency_maps(cll.parent_map, cll.child_map, relevant_columns)
|
|
929
|
-
return CllData(
|
|
930
|
-
nodes=nodes,
|
|
931
|
-
columns=columns,
|
|
932
|
-
parent_map=p_map,
|
|
933
|
-
child_map=c_map,
|
|
934
|
-
)
|
|
935
|
-
|
|
936
|
-
def get_cll_by_node_id(self, node_id: str, base: Optional[bool] = False) -> CllData:
|
|
918
|
+
def get_cll(
|
|
919
|
+
self,
|
|
920
|
+
node_id: Optional[str] = None,
|
|
921
|
+
column: Optional[str] = None,
|
|
922
|
+
change_analysis: Optional[bool] = False,
|
|
923
|
+
cll: Optional[bool] = True,
|
|
924
|
+
upstream: Optional[bool] = True,
|
|
925
|
+
downstream: Optional[bool] = True,
|
|
926
|
+
no_filter: Optional[bool] = False,
|
|
927
|
+
) -> CllData:
|
|
937
928
|
cll_tracker = CLLPerformanceTracking()
|
|
938
929
|
cll_tracker.start_column_lineage()
|
|
939
930
|
|
|
940
|
-
manifest = self.curr_manifest
|
|
931
|
+
manifest = self.curr_manifest
|
|
941
932
|
manifest_dict = manifest.to_dict()
|
|
942
933
|
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
934
|
+
# Find related model nodes
|
|
935
|
+
if node_id is not None:
|
|
936
|
+
cll_node_ids = {node_id}
|
|
937
|
+
else:
|
|
938
|
+
lineage_diff = self.get_lineage_diff()
|
|
939
|
+
cll_node_ids = lineage_diff.diff.keys()
|
|
947
940
|
|
|
948
941
|
nodes = {}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
942
|
+
columns = {}
|
|
943
|
+
parent_map = {}
|
|
944
|
+
child_map = {}
|
|
945
|
+
|
|
946
|
+
if upstream:
|
|
947
|
+
cll_node_ids = cll_node_ids.union(find_upstream(cll_node_ids, manifest_dict.get("parent_map")))
|
|
948
|
+
if downstream:
|
|
949
|
+
cll_node_ids = cll_node_ids.union(find_downstream(cll_node_ids, manifest_dict.get("child_map")))
|
|
950
|
+
|
|
951
|
+
if cll:
|
|
952
|
+
for cll_node_id in cll_node_ids:
|
|
953
|
+
if (
|
|
954
|
+
cll_node_id not in manifest.sources
|
|
955
|
+
and cll_node_id not in manifest.nodes
|
|
956
|
+
and cll_node_id not in manifest.exposures
|
|
957
|
+
):
|
|
958
|
+
continue
|
|
959
|
+
cll_data_one = self.get_cll_cached(cll_node_id, base=False)
|
|
960
|
+
if cll_data_one is None:
|
|
961
|
+
continue
|
|
962
|
+
|
|
963
|
+
node_diff = self.get_lineage_diff().diff.get(cll_node_id) if change_analysis else None
|
|
964
|
+
for n_id, n in cll_data_one.nodes.items():
|
|
965
|
+
nodes[n_id] = n
|
|
966
|
+
|
|
967
|
+
if node_diff is not None:
|
|
968
|
+
n.change_status = node_diff.change_status
|
|
969
|
+
if node_diff.change is not None:
|
|
970
|
+
n.change_category = node_diff.change.category
|
|
971
|
+
for c_id, c in cll_data_one.columns.items():
|
|
972
|
+
columns[c_id] = c
|
|
973
|
+
if node_diff is not None and node_diff.change is not None:
|
|
974
|
+
column_diff = node_diff.change.columns.get(c.name)
|
|
975
|
+
if column_diff:
|
|
976
|
+
c.change_status = column_diff
|
|
977
|
+
|
|
978
|
+
for p_id, parents in cll_data_one.parent_map.items():
|
|
979
|
+
parent_map[p_id] = parents
|
|
962
980
|
|
|
963
981
|
# build the child map
|
|
964
|
-
|
|
965
|
-
for node_id, parents in cll_data.parent_map.items():
|
|
982
|
+
for parent_id, parents in parent_map.items():
|
|
966
983
|
for parent in parents:
|
|
967
|
-
if parent not in
|
|
968
|
-
|
|
969
|
-
|
|
984
|
+
if parent not in child_map:
|
|
985
|
+
child_map[parent] = set()
|
|
986
|
+
child_map[parent].add(parent_id)
|
|
987
|
+
|
|
988
|
+
# Find the anchor nodes
|
|
989
|
+
anchor_node_ids = set()
|
|
990
|
+
if node_id is None and column is None:
|
|
991
|
+
if change_analysis:
|
|
992
|
+
# If change analysis is requested, we need to find the nodes that have changes
|
|
993
|
+
for node_id, node_diff in self.get_lineage_diff().diff.items():
|
|
994
|
+
if node_diff.change.category == "breaking":
|
|
995
|
+
anchor_node_ids.add(node_id)
|
|
996
|
+
for column_name in node_diff.change.columns:
|
|
997
|
+
anchor_node_ids.add(f"{node_id}_{column_name}")
|
|
998
|
+
else:
|
|
999
|
+
lineage_diff = self.get_lineage_diff()
|
|
1000
|
+
anchor_node_ids = lineage_diff.diff.keys()
|
|
1001
|
+
elif node_id is not None and column is None:
|
|
1002
|
+
if change_analysis:
|
|
1003
|
+
# If change analysis is requested, we need to find the nodes that have changes
|
|
1004
|
+
node_diff = self.get_lineage_diff().diff.get(node_id)
|
|
1005
|
+
if node_diff:
|
|
1006
|
+
if node_diff.change.category == "breaking":
|
|
1007
|
+
anchor_node_ids.add(node_id)
|
|
1008
|
+
for column_name in node_diff.change.columns:
|
|
1009
|
+
anchor_node_ids.add(f"{node_id}_{column_name}")
|
|
1010
|
+
else:
|
|
1011
|
+
anchor_node_ids.add(node_id)
|
|
1012
|
+
else:
|
|
1013
|
+
anchor_node_ids.add(node_id)
|
|
1014
|
+
else:
|
|
1015
|
+
anchor_node_ids.add(f"{node_id}_{column}")
|
|
1016
|
+
|
|
1017
|
+
result_node_ids = set(anchor_node_ids)
|
|
1018
|
+
if upstream:
|
|
1019
|
+
result_node_ids = result_node_ids.union(find_upstream(anchor_node_ids, parent_map))
|
|
1020
|
+
if downstream:
|
|
1021
|
+
result_node_ids = result_node_ids.union(find_downstream(anchor_node_ids, child_map))
|
|
1022
|
+
|
|
1023
|
+
# Filter the nodes and columns based on the anchor nodes
|
|
1024
|
+
if not no_filter:
|
|
1025
|
+
nodes = {k: v for k, v in nodes.items() if k in result_node_ids}
|
|
1026
|
+
columns = {k: v for k, v in columns.items() if k in result_node_ids}
|
|
1027
|
+
parent_map, child_map = filter_dependency_maps(parent_map, child_map, result_node_ids)
|
|
970
1028
|
|
|
971
1029
|
cll_tracker.end_column_lineage()
|
|
972
1030
|
cll_tracker.set_total_nodes(len(nodes))
|
|
973
1031
|
log_performance("column level lineage", cll_tracker.to_dict())
|
|
974
1032
|
cll_tracker.reset()
|
|
975
1033
|
|
|
976
|
-
return
|
|
1034
|
+
return CllData(
|
|
1035
|
+
nodes=nodes,
|
|
1036
|
+
columns=columns,
|
|
1037
|
+
parent_map=parent_map,
|
|
1038
|
+
child_map=child_map,
|
|
1039
|
+
)
|
|
977
1040
|
|
|
978
1041
|
@lru_cache(maxsize=128)
|
|
979
1042
|
def get_cll_cached(self, node_id: str, base: Optional[bool] = False) -> Optional[CllData]:
|
|
@@ -1202,7 +1265,7 @@ class DbtAdapter(BaseAdapter):
|
|
|
1202
1265
|
change_category = diff_info.change.category
|
|
1203
1266
|
|
|
1204
1267
|
if change_category == "breaking":
|
|
1205
|
-
cll = self.
|
|
1268
|
+
cll = self.get_cll(node_id, no_filter=True)
|
|
1206
1269
|
_, downstream = find_column_dependencies(node_id, cll.parent_map, cll.child_map)
|
|
1207
1270
|
relevant_columns = {node_id}
|
|
1208
1271
|
relevant_columns.update(downstream)
|
|
@@ -1220,7 +1283,7 @@ class DbtAdapter(BaseAdapter):
|
|
|
1220
1283
|
return CllData()
|
|
1221
1284
|
change_columns = diff_info.change.columns
|
|
1222
1285
|
|
|
1223
|
-
cll = self.
|
|
1286
|
+
cll = self.get_cll(node_id, no_filter=True)
|
|
1224
1287
|
relevant_columns = set()
|
|
1225
1288
|
for col, change_status in change_columns.items():
|
|
1226
1289
|
if change_status == "removed":
|
recce/cli.py
CHANGED
|
@@ -17,9 +17,9 @@ from recce.state import RecceCloudStateManager, RecceShareStateManager, RecceSta
|
|
|
17
17
|
from recce.summary import generate_markdown_summary
|
|
18
18
|
from recce.util.api_token import prepare_api_token, show_invalid_api_token_message
|
|
19
19
|
from recce.util.logger import CustomFormatter
|
|
20
|
+
from recce.util.onboarding_state import update_onboarding_state
|
|
20
21
|
from recce.util.recce_cloud import (
|
|
21
22
|
RecceCloudException,
|
|
22
|
-
get_recce_cloud_onboarding_state,
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
from .core import RecceContext, set_default_context
|
|
@@ -397,15 +397,21 @@ def server(host, port, lifetime, state_file=None, **kwargs):
|
|
|
397
397
|
is_cloud = kwargs.get("cloud", False)
|
|
398
398
|
console = Console()
|
|
399
399
|
cloud_options = None
|
|
400
|
-
flag = {"
|
|
400
|
+
flag = {"single_env_onboarding": False, "show_relaunch_hint": False}
|
|
401
401
|
if is_cloud:
|
|
402
402
|
cloud_options = {
|
|
403
403
|
"host": kwargs.get("state_file_host"),
|
|
404
404
|
"token": kwargs.get("cloud_token"),
|
|
405
405
|
"password": kwargs.get("password"),
|
|
406
406
|
}
|
|
407
|
-
|
|
408
|
-
|
|
407
|
+
|
|
408
|
+
# Check Single Environment Onboarding Mode if the review mode is False
|
|
409
|
+
if not Path(kwargs.get("target_base_path", "target-base")).is_dir() and not is_review:
|
|
410
|
+
# Mark as single env onboarding mode if user provides the target-path only
|
|
411
|
+
flag["single_env_onboarding"] = True
|
|
412
|
+
flag["show_relaunch_hint"] = True
|
|
413
|
+
# Use the target path as the base path
|
|
414
|
+
kwargs["target_base_path"] = kwargs.get("target_path")
|
|
409
415
|
|
|
410
416
|
auth_options = {}
|
|
411
417
|
try:
|
|
@@ -415,13 +421,8 @@ def server(host, port, lifetime, state_file=None, **kwargs):
|
|
|
415
421
|
exit(1)
|
|
416
422
|
auth_options["api_token"] = api_token
|
|
417
423
|
|
|
418
|
-
#
|
|
419
|
-
|
|
420
|
-
# Mark as single env onboarding mode if user provides the target-path only
|
|
421
|
-
flag["single_env_onboarding"] = True
|
|
422
|
-
flag["show_relaunch_hint"] = True
|
|
423
|
-
# Use the target path as the base path
|
|
424
|
-
kwargs["target_base_path"] = kwargs.get("target_path")
|
|
424
|
+
# Onboarding State logic update here
|
|
425
|
+
update_onboarding_state(api_token, flag["single_env_onboarding"])
|
|
425
426
|
|
|
426
427
|
state_loader = create_state_loader(is_review, is_cloud, state_file, cloud_options)
|
|
427
428
|
|
recce/data/404.html
CHANGED
|
@@ -19,4 +19,4 @@
|
|
|
19
19
|
pre
|
|
20
20
|
){margin:0;}button{background:transparent;padding:0;}fieldset{margin:0;padding:0;}:where(ol, ul){margin:0;padding:0;}textarea{resize:vertical;}:where(button, [role="button"]){cursor:pointer;}button::-moz-focus-inner{border:0!important;}table{border-collapse:collapse;}:where(h1, h2, h3, h4, h5, h6){font-size:inherit;font-weight:inherit;}:where(button, input, optgroup, select, textarea){padding:0;line-height:inherit;color:inherit;}:where(img, svg, video, canvas, audio, iframe, embed, object){display:block;}:where(img, video){max-width:100%;height:auto;}[data-js-focus-visible] :focus:not([data-focus-visible-added]):not(
|
|
21
21
|
[data-focus-visible-disabled]
|
|
22
|
-
){outline:none;box-shadow:none;}select::-ms-expand{display:none;}:root,:host{--chakra-vh:100vh;}@supports (height: -webkit-fill-available){:root,:host{--chakra-vh:-webkit-fill-available;}}@supports (height: -moz-fill-available){:root,:host{--chakra-vh:-moz-fill-available;}}@supports (height: 100dvh){:root,:host{--chakra-vh:100dvh;}}</style><style data-emotion="css-global 1cgn62j">body{font-family:var(--chakra-fonts-body);color:var(--chakra-colors-chakra-body-text);background:var(--chakra-colors-chakra-body-bg);transition-property:background-color;transition-duration:var(--chakra-transition-duration-normal);line-height:var(--chakra-lineHeights-base);}*::-webkit-input-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*::-moz-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*:-ms-input-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*::placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*,*::before,::after{border-color:var(--chakra-colors-chakra-border-color);}</style><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><span></span><span id="__chakra_env" hidden=""></span><script src="/_next/static/chunks/webpack-7b49d5ba7e3a434d.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/1b121dc4d36aeb4d.css\",\"style\"]\n2:HL[\"/_next/static/css/951e2e0eea2d4a5b.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"3:I[35639,[],\"\"]\n5:I[51454,[],\"\"]\n6:I[48464,[],\"\"]\n7:I[76413,[\"509\",\"static/chunks/9746af58-a42b7d169cacadf0.js\",\"989\",\"static/chunks/47d8844f-929aed9b1c73a905.js\",\"147\",\"static/chunks/a30376cd-de84559016d7e133.js\",\"495\",\"static/chunks/6dc81886-adbfa45836061d79.js\",\"376\",\"static/chunks/3a92ee20-1081c360214f9602.js\",\"678\",\"static/chunks/3998a672-03adacad07b346ac.js\",\"20\",\"static/chunks/1bff33f1-1ef85cf5e658a751.js\",\"413\",\"static/chunks/bbda5537-9ec25eb1dd62348a.js\",\"42\",\"static/chunks/42-cd3c06533f5fd47c.js\",\"608\",\"static/chunks/608-3b079b544e5d5f5e.js\",\"92\",\"static/chunks/92-7ab55ae02606193c.js\",\"185\",\"static/chunks/app/layout-177a410a97e0d018.js\"],\"default\"]\nd:I[26480,[],\"\"]\n8:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n9:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\na:{\"display\":\"inline-block\"}\nb:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\ne:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L3\",null,{\"buildId\":\"
|
|
22
|
+
){outline:none;box-shadow:none;}select::-ms-expand{display:none;}:root,:host{--chakra-vh:100vh;}@supports (height: -webkit-fill-available){:root,:host{--chakra-vh:-webkit-fill-available;}}@supports (height: -moz-fill-available){:root,:host{--chakra-vh:-moz-fill-available;}}@supports (height: 100dvh){:root,:host{--chakra-vh:100dvh;}}</style><style data-emotion="css-global 1cgn62j">body{font-family:var(--chakra-fonts-body);color:var(--chakra-colors-chakra-body-text);background:var(--chakra-colors-chakra-body-bg);transition-property:background-color;transition-duration:var(--chakra-transition-duration-normal);line-height:var(--chakra-lineHeights-base);}*::-webkit-input-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*::-moz-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*:-ms-input-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*::placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*,*::before,::after{border-color:var(--chakra-colors-chakra-border-color);}</style><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><span></span><span id="__chakra_env" hidden=""></span><script src="/_next/static/chunks/webpack-7b49d5ba7e3a434d.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/1b121dc4d36aeb4d.css\",\"style\"]\n2:HL[\"/_next/static/css/951e2e0eea2d4a5b.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"3:I[35639,[],\"\"]\n5:I[51454,[],\"\"]\n6:I[48464,[],\"\"]\n7:I[76413,[\"509\",\"static/chunks/9746af58-a42b7d169cacadf0.js\",\"989\",\"static/chunks/47d8844f-929aed9b1c73a905.js\",\"147\",\"static/chunks/a30376cd-de84559016d7e133.js\",\"495\",\"static/chunks/6dc81886-adbfa45836061d79.js\",\"376\",\"static/chunks/3a92ee20-1081c360214f9602.js\",\"678\",\"static/chunks/3998a672-03adacad07b346ac.js\",\"20\",\"static/chunks/1bff33f1-1ef85cf5e658a751.js\",\"413\",\"static/chunks/bbda5537-9ec25eb1dd62348a.js\",\"42\",\"static/chunks/42-cd3c06533f5fd47c.js\",\"608\",\"static/chunks/608-3b079b544e5d5f5e.js\",\"92\",\"static/chunks/92-7ab55ae02606193c.js\",\"185\",\"static/chunks/app/layout-177a410a97e0d018.js\"],\"default\"]\nd:I[26480,[],\"\"]\n8:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n9:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\na:{\"display\":\"inline-block\"}\nb:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\ne:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L3\",null,{\"buildId\":\"WrRUb3nV8BhAZG_R8kVma\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L4\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/1b121dc4d36aeb4d.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/951e2e0eea2d4a5b.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L7\",null,{\"children\":[\"$\",\"$L5\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L6\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$8\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$9\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$a\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$b\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$Lc\"],\"globalErrorComponent\":\"$d\",\"missingSlots\":\"$We\"}]\n"])</script><script>self.__next_f.push([1,"c:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}]]\n4:null\n"])</script></body></html>
|