arize-phoenix 6.1.0__py3-none-any.whl → 7.0.0__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.
Potentially problematic release.
This version of arize-phoenix might be problematic. Click here for more details.
- {arize_phoenix-6.1.0.dist-info → arize_phoenix-7.0.0.dist-info}/METADATA +9 -8
- {arize_phoenix-6.1.0.dist-info → arize_phoenix-7.0.0.dist-info}/RECORD +52 -38
- phoenix/config.py +4 -1
- phoenix/db/engines.py +1 -1
- phoenix/db/insertion/span.py +65 -30
- phoenix/db/migrate.py +4 -1
- phoenix/db/migrations/data_migration_scripts/__init__.py +0 -0
- phoenix/db/migrations/data_migration_scripts/populate_project_sessions.py +199 -0
- phoenix/db/migrations/versions/4ded9e43755f_create_project_sessions_table.py +66 -0
- phoenix/db/models.py +27 -0
- phoenix/metrics/wrappers.py +7 -1
- phoenix/server/api/context.py +15 -2
- phoenix/server/api/dataloaders/__init__.py +14 -2
- phoenix/server/api/dataloaders/session_io.py +75 -0
- phoenix/server/api/dataloaders/session_num_traces.py +30 -0
- phoenix/server/api/dataloaders/session_num_traces_with_error.py +32 -0
- phoenix/server/api/dataloaders/session_token_usages.py +41 -0
- phoenix/server/api/dataloaders/session_trace_latency_ms_quantile.py +55 -0
- phoenix/server/api/dataloaders/trace_by_trace_ids.py +25 -0
- phoenix/server/api/dataloaders/trace_root_spans.py +32 -0
- phoenix/server/api/input_types/ProjectSessionSort.py +29 -0
- phoenix/server/api/mutations/chat_mutations.py +5 -0
- phoenix/server/api/mutations/project_mutations.py +12 -2
- phoenix/server/api/queries.py +14 -9
- phoenix/server/api/subscriptions.py +6 -0
- phoenix/server/api/types/EmbeddingDimension.py +1 -1
- phoenix/server/api/types/ExperimentRun.py +3 -4
- phoenix/server/api/types/ExperimentRunAnnotation.py +3 -4
- phoenix/server/api/types/Project.py +150 -12
- phoenix/server/api/types/ProjectSession.py +139 -0
- phoenix/server/api/types/Span.py +6 -19
- phoenix/server/api/types/SpanIOValue.py +15 -0
- phoenix/server/api/types/TokenUsage.py +11 -0
- phoenix/server/api/types/Trace.py +59 -2
- phoenix/server/app.py +15 -2
- phoenix/server/static/.vite/manifest.json +40 -31
- phoenix/server/static/assets/{components-CdiZ1Osh.js → components-DKH6AzJw.js} +410 -351
- phoenix/server/static/assets/index-DLV87qiO.js +93 -0
- phoenix/server/static/assets/{pages-FArMEfgg.js → pages-CVY3Nv4Z.js} +638 -316
- phoenix/server/static/assets/vendor-Cb3zlNNd.js +894 -0
- phoenix/server/static/assets/{vendor-arizeai-BG6iwyLC.js → vendor-arizeai-Buo4e1A6.js} +2 -2
- phoenix/server/static/assets/{vendor-codemirror-BotnVFFX.js → vendor-codemirror-BuAQiUVf.js} +5 -5
- phoenix/server/static/assets/{vendor-recharts-Dy5gEFzQ.js → vendor-recharts-Cl9dK5tC.js} +1 -1
- phoenix/server/static/assets/{vendor-Bnv1dNRQ.js → vendor-shiki-CazYUixL.js} +5 -898
- phoenix/session/client.py +13 -4
- phoenix/trace/fixtures.py +8 -0
- phoenix/trace/schemas.py +16 -0
- phoenix/version.py +1 -1
- phoenix/server/api/dataloaders/trace_row_ids.py +0 -33
- phoenix/server/static/assets/index-D_sCOjlG.js +0 -101
- {arize_phoenix-6.1.0.dist-info → arize_phoenix-7.0.0.dist-info}/WHEEL +0 -0
- {arize_phoenix-6.1.0.dist-info → arize_phoenix-7.0.0.dist-info}/entry_points.txt +0 -0
- {arize_phoenix-6.1.0.dist-info → arize_phoenix-7.0.0.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-6.1.0.dist-info → arize_phoenix-7.0.0.dist-info}/licenses/LICENSE +0 -0
phoenix/session/client.py
CHANGED
|
@@ -129,6 +129,7 @@ class Client(TraceDataExtractor):
|
|
|
129
129
|
root_spans_only (bool, optional): If True, only root spans are returned. Default None.
|
|
130
130
|
project_name (str, optional): The project name to query spans for. This can be set
|
|
131
131
|
using environment variables. If not provided, falls back to the default project.
|
|
132
|
+
timeout (int, optional): The number of seconds to wait for the server to respond.
|
|
132
133
|
|
|
133
134
|
Returns:
|
|
134
135
|
Union[pd.DataFrame, list[pd.DataFrame]]:
|
|
@@ -216,6 +217,8 @@ class Client(TraceDataExtractor):
|
|
|
216
217
|
def get_evaluations(
|
|
217
218
|
self,
|
|
218
219
|
project_name: Optional[str] = None,
|
|
220
|
+
*, # Only support kwargs from now on
|
|
221
|
+
timeout: Optional[int] = DEFAULT_TIMEOUT_IN_SECONDS,
|
|
219
222
|
) -> list[Evaluations]:
|
|
220
223
|
"""
|
|
221
224
|
Retrieves evaluations for a given project from the Phoenix server or active session.
|
|
@@ -224,6 +227,7 @@ class Client(TraceDataExtractor):
|
|
|
224
227
|
project_name (str, optional): The name of the project to retrieve evaluations for.
|
|
225
228
|
This can be set using environment variables. If not provided, falls back to the
|
|
226
229
|
default project.
|
|
230
|
+
timeout (int, optional): The number of seconds to wait for the server to respond.
|
|
227
231
|
|
|
228
232
|
Returns:
|
|
229
233
|
list[Evaluations]:
|
|
@@ -237,6 +241,7 @@ class Client(TraceDataExtractor):
|
|
|
237
241
|
"project_name": project_name,
|
|
238
242
|
"project-name": project_name, # for backward-compatibility
|
|
239
243
|
},
|
|
244
|
+
timeout=timeout,
|
|
240
245
|
)
|
|
241
246
|
if response.status_code == 404:
|
|
242
247
|
logger.info("No evaluations found.")
|
|
@@ -263,15 +268,18 @@ class Client(TraceDataExtractor):
|
|
|
263
268
|
f"with `import phoenix as px; px.launch_app()`"
|
|
264
269
|
)
|
|
265
270
|
|
|
266
|
-
def log_evaluations(
|
|
271
|
+
def log_evaluations(
|
|
272
|
+
self,
|
|
273
|
+
*evals: Evaluations,
|
|
274
|
+
timeout: Optional[int] = DEFAULT_TIMEOUT_IN_SECONDS,
|
|
275
|
+
**kwargs: Any,
|
|
276
|
+
) -> None:
|
|
267
277
|
"""
|
|
268
278
|
Logs evaluation data to the Phoenix server.
|
|
269
279
|
|
|
270
280
|
Args:
|
|
271
281
|
evals (Evaluations): One or more Evaluations objects containing the data to log.
|
|
272
|
-
|
|
273
|
-
This can be set using environment variables. If not provided, falls back to the
|
|
274
|
-
default project.
|
|
282
|
+
timeout (int, optional): The number of seconds to wait for the server to respond.
|
|
275
283
|
|
|
276
284
|
Returns:
|
|
277
285
|
None
|
|
@@ -290,6 +298,7 @@ class Client(TraceDataExtractor):
|
|
|
290
298
|
url=urljoin(self._base_url, "v1/evaluations"),
|
|
291
299
|
content=cast(bytes, sink.getvalue().to_pybytes()),
|
|
292
300
|
headers=headers,
|
|
301
|
+
timeout=timeout,
|
|
293
302
|
).raise_for_status()
|
|
294
303
|
|
|
295
304
|
def log_traces(self, trace_dataset: TraceDataset, project_name: Optional[str] = None) -> None:
|
phoenix/trace/fixtures.py
CHANGED
|
@@ -222,6 +222,13 @@ llama_index_rag_fixture = TracesFixture(
|
|
|
222
222
|
),
|
|
223
223
|
)
|
|
224
224
|
|
|
225
|
+
project_sessions_llama_index_rag_arize_docs_fixture = TracesFixture(
|
|
226
|
+
name="project_sessions_llama_index_rag_arize_docs",
|
|
227
|
+
project_name="SESSIONS-DEMO",
|
|
228
|
+
file_name="project_sessions_demo_llama_index_query_engine_arize_docs.parquet",
|
|
229
|
+
description="RAG queries grouped by session.id and user.id.",
|
|
230
|
+
)
|
|
231
|
+
|
|
225
232
|
llama_index_calculator_agent_fixture = TracesFixture(
|
|
226
233
|
name="llama_index_calculator_agent",
|
|
227
234
|
description="Traces from running the llama_index with calculator tools.",
|
|
@@ -290,6 +297,7 @@ TRACES_FIXTURES: list[TracesFixture] = [
|
|
|
290
297
|
llama_index_calculator_agent_fixture,
|
|
291
298
|
vision_fixture,
|
|
292
299
|
anthropic_tools_fixture,
|
|
300
|
+
project_sessions_llama_index_rag_arize_docs_fixture,
|
|
293
301
|
]
|
|
294
302
|
|
|
295
303
|
NAME_TO_TRACES_FIXTURE: dict[str, TracesFixture] = {
|
phoenix/trace/schemas.py
CHANGED
|
@@ -187,6 +187,22 @@ class MimeType(Enum):
|
|
|
187
187
|
return None if v else cls.TEXT
|
|
188
188
|
|
|
189
189
|
|
|
190
|
+
@dataclass(frozen=True)
|
|
191
|
+
class SpanIOValue:
|
|
192
|
+
value: str
|
|
193
|
+
mime_type: MimeType = MimeType.TEXT
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@dataclass(frozen=True)
|
|
197
|
+
class TokenUsage:
|
|
198
|
+
prompt: int = 0
|
|
199
|
+
completion: int = 0
|
|
200
|
+
|
|
201
|
+
def __post_init__(self) -> None:
|
|
202
|
+
assert self.prompt >= 0, "prompt must be non-negative"
|
|
203
|
+
assert self.completion >= 0, "completion must be non-negative"
|
|
204
|
+
|
|
205
|
+
|
|
190
206
|
ATTRIBUTE_PREFIX = "attributes."
|
|
191
207
|
CONTEXT_PREFIX = "context."
|
|
192
208
|
COMPUTED_PREFIX = "__computed__."
|
phoenix/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "
|
|
1
|
+
__version__ = "7.0.0"
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
|
-
from sqlalchemy import select
|
|
4
|
-
from strawberry.dataloader import DataLoader
|
|
5
|
-
from typing_extensions import TypeAlias
|
|
6
|
-
|
|
7
|
-
from phoenix.db import models
|
|
8
|
-
from phoenix.server.types import DbSessionFactory
|
|
9
|
-
|
|
10
|
-
TraceId: TypeAlias = str
|
|
11
|
-
Key: TypeAlias = TraceId
|
|
12
|
-
TraceRowId: TypeAlias = int
|
|
13
|
-
ProjectRowId: TypeAlias = int
|
|
14
|
-
Result: TypeAlias = Optional[tuple[TraceRowId, ProjectRowId]]
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class TraceRowIdsDataLoader(DataLoader[Key, Result]):
|
|
18
|
-
def __init__(self, db: DbSessionFactory) -> None:
|
|
19
|
-
super().__init__(load_fn=self._load_fn)
|
|
20
|
-
self._db = db
|
|
21
|
-
|
|
22
|
-
async def _load_fn(self, keys: list[Key]) -> list[Result]:
|
|
23
|
-
stmt = select(
|
|
24
|
-
models.Trace.trace_id,
|
|
25
|
-
models.Trace.id,
|
|
26
|
-
models.Trace.project_rowid,
|
|
27
|
-
).where(models.Trace.trace_id.in_(keys))
|
|
28
|
-
async with self._db() as session:
|
|
29
|
-
result = {
|
|
30
|
-
trace_id: (id_, project_rowid)
|
|
31
|
-
async for trace_id, id_, project_rowid in await session.stream(stmt)
|
|
32
|
-
}
|
|
33
|
-
return list(map(result.get, keys))
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import{r as c,j as e,dv as v,l as n,U as F,R as w,D as E,bb as R,dw as S,dx as L,dy as r,dz as z,dA as k,t as A,dB as $}from"./vendor-Bnv1dNRQ.js";import{D as C,d as I,$ as _,G as j,t as O,a4 as D}from"./vendor-arizeai-BG6iwyLC.js";import{E as T,L as G,R as N,r as B,b as M,F as U,A as J,c as K,d as W,P as q,h as H,M as V,e as m,D as Y,f as Q,g as X,i as Z,j as ee,k as re,l as ae,p as te,n as g,o as oe,q as ne,s as u,t as se,v as h,w as x,x as le,y as ie,z as de,B as ce,C as pe,G as f,H as me,S as ge,I as ue,J as he,K as xe,N as fe,O as be}from"./pages-FArMEfgg.js";import{c6 as ye,$ as Pe,R as ve,c7 as Fe,c8 as we}from"./components-CdiZ1Osh.js";import"./vendor-three-DwGkEfCM.js";import"./vendor-recharts-Dy5gEFzQ.js";import"./vendor-codemirror-BotnVFFX.js";(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const t of document.querySelectorAll('link[rel="modulepreload"]'))d(t);new MutationObserver(t=>{for(const o of t)if(o.type==="childList")for(const l of o.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&d(l)}).observe(document,{childList:!0,subtree:!0});function i(t){const o={};return t.integrity&&(o.integrity=t.integrity),t.referrerPolicy&&(o.referrerPolicy=t.referrerPolicy),t.crossOrigin==="use-credentials"?o.credentials="include":t.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function d(t){if(t.ep)return;t.ep=!0;const o=i(t);fetch(t.href,o)}})();const b="arize-phoenix-feature-flags",p={__RESET__:!1};function Ee(){const a=localStorage.getItem(b);if(!a)return p;try{const s=JSON.parse(a);return Object.assign({},p,s)}catch{return p}}const y=c.createContext(null);function Re(){const a=w.useContext(y);if(a===null)throw new Error("useFeatureFlags must be used within a FeatureFlagsProvider");return a}function Se(a){const[s,i]=c.useState(Ee()),d=t=>{localStorage.setItem(b,JSON.stringify(t)),i(t)};return e(y.Provider,{value:{featureFlags:s,setFeatureFlags:d},children:e(Le,{children:a.children})})}function Le(a){const{children:s}=a,{featureFlags:i,setFeatureFlags:d}=Re(),[t,o]=c.useState(!1);return v("ctrl+shift+f",()=>o(!0)),n(F,{children:[s,e(j,{type:"modal",isDismissable:!0,onDismiss:()=>o(!1),children:t&&e(C,{title:"Feature Flags",children:e(I,{height:"size-1000",padding:"size-100",children:Object.keys(i).map(l=>e(_,{isSelected:i[l],onChange:P=>d({...i,[l]:P}),children:l},l))})})})]})}function ze(){return e(R,{styles:a=>E`
|
|
2
|
-
body {
|
|
3
|
-
background-color: var(--ac-global-color-grey-75);
|
|
4
|
-
color: var(--ac-global-text-color-900);
|
|
5
|
-
font-family: "Roboto";
|
|
6
|
-
font-size: ${a.typography.sizes.medium.fontSize}px;
|
|
7
|
-
margin: 0;
|
|
8
|
-
overflow: hidden;
|
|
9
|
-
#root,
|
|
10
|
-
#root > div[data-overlay-container="true"],
|
|
11
|
-
#root > div[data-overlay-container="true"] > .ac-theme {
|
|
12
|
-
height: 100vh;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/* Remove list styling */
|
|
17
|
-
ul {
|
|
18
|
-
display: block;
|
|
19
|
-
list-style-type: none;
|
|
20
|
-
margin-block-start: none;
|
|
21
|
-
margin-block-end: 0;
|
|
22
|
-
padding-inline-start: 0;
|
|
23
|
-
margin-block-start: 0;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/* A reset style for buttons */
|
|
27
|
-
.button--reset {
|
|
28
|
-
background: none;
|
|
29
|
-
border: none;
|
|
30
|
-
padding: 0;
|
|
31
|
-
}
|
|
32
|
-
/* this css class is added to html via modernizr @see modernizr.js */
|
|
33
|
-
.no-hiddenscroll {
|
|
34
|
-
/* Works on Firefox */
|
|
35
|
-
* {
|
|
36
|
-
scrollbar-width: thin;
|
|
37
|
-
scrollbar-color: var(--ac-global-color-grey-300)
|
|
38
|
-
var(--ac-global-color-grey-400);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/* Works on Chrome, Edge, and Safari */
|
|
42
|
-
*::-webkit-scrollbar {
|
|
43
|
-
width: 14px;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
*::-webkit-scrollbar-track {
|
|
47
|
-
background: var(--ac-global-color-grey-100);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
*::-webkit-scrollbar-thumb {
|
|
51
|
-
background-color: var(--ac-global-color-grey-75);
|
|
52
|
-
border-radius: 8px;
|
|
53
|
-
border: 1px solid var(--ac-global-color-grey-300);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
:root {
|
|
58
|
-
--px-blue-color: ${a.colors.arizeBlue};
|
|
59
|
-
|
|
60
|
-
--px-flex-gap-sm: ${a.spacing.margin4}px;
|
|
61
|
-
--px-flex-gap-sm: ${a.spacing.margin8}px;
|
|
62
|
-
|
|
63
|
-
--px-section-background-color: ${a.colors.gray500};
|
|
64
|
-
|
|
65
|
-
/* An item is a typically something in a list */
|
|
66
|
-
--px-item-background-color: ${a.colors.gray800};
|
|
67
|
-
--px-item-border-color: ${a.colors.gray600};
|
|
68
|
-
|
|
69
|
-
--px-spacing-sm: ${a.spacing.padding4}px;
|
|
70
|
-
--px-spacing-med: ${a.spacing.padding8}px;
|
|
71
|
-
--px-spacing-lg: ${a.spacing.padding16}px;
|
|
72
|
-
|
|
73
|
-
--px-border-radius-med: ${a.borderRadius.medium}px;
|
|
74
|
-
|
|
75
|
-
--px-font-size-sm: ${a.typography.sizes.small.fontSize}px;
|
|
76
|
-
--px-font-size-med: ${a.typography.sizes.medium.fontSize}px;
|
|
77
|
-
--px-font-size-lg: ${a.typography.sizes.large.fontSize}px;
|
|
78
|
-
|
|
79
|
-
--px-gradient-bar-height: 8px;
|
|
80
|
-
|
|
81
|
-
--px-nav-collapsed-width: 45px;
|
|
82
|
-
--px-nav-expanded-width: 200px;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.ac-theme--dark {
|
|
86
|
-
--px-primary-color: #9efcfd;
|
|
87
|
-
--px-primary-color--transparent: rgb(158, 252, 253, 0.2);
|
|
88
|
-
--px-reference-color: #baa1f9;
|
|
89
|
-
--px-reference-color--transparent: #baa1f982;
|
|
90
|
-
--px-corpus-color: #92969c;
|
|
91
|
-
--px-corpus-color--transparent: #92969c63;
|
|
92
|
-
}
|
|
93
|
-
.ac-theme--light {
|
|
94
|
-
--px-primary-color: #00add0;
|
|
95
|
-
--px-primary-color--transparent: rgba(0, 173, 208, 0.2);
|
|
96
|
-
--px-reference-color: #4500d9;
|
|
97
|
-
--px-reference-color--transparent: rgba(69, 0, 217, 0.2);
|
|
98
|
-
--px-corpus-color: #92969c;
|
|
99
|
-
--px-corpus-color--transparent: #92969c63;
|
|
100
|
-
}
|
|
101
|
-
`})}const ke=S(L(n(r,{path:"/",errorElement:e(T,{}),children:[e(r,{path:"/login",element:e(G,{})}),e(r,{path:"/reset-password",element:e(N,{}),loader:B}),e(r,{path:"/reset-password-with-token",element:e(M,{})}),e(r,{path:"/forgot-password",element:e(U,{})}),e(r,{element:e(J,{}),loader:K,children:n(r,{element:e(W,{}),children:[e(r,{path:"/profile",handle:{crumb:()=>"profile"},element:e(q,{})}),e(r,{index:!0,loader:H}),n(r,{path:"/model",handle:{crumb:()=>"model"},element:e(V,{}),children:[e(r,{index:!0,element:e(m,{})}),e(r,{element:e(m,{}),children:e(r,{path:"dimensions",children:e(r,{path:":dimensionId",element:e(Y,{}),loader:Q})})}),e(r,{path:"embeddings",children:e(r,{path:":embeddingDimensionId",element:e(X,{}),loader:Z,handle:{crumb:a=>a.embedding.name}})})]}),n(r,{path:"/projects",handle:{crumb:()=>"projects"},element:e(ee,{}),children:[e(r,{index:!0,element:e(re,{})}),n(r,{path:":projectId",element:e(ae,{}),loader:te,handle:{crumb:a=>a.project.name},children:[e(r,{index:!0,element:e(g,{})}),e(r,{element:e(g,{}),children:e(r,{path:"traces/:traceId",element:e(oe,{})})})]})]}),n(r,{path:"/datasets",handle:{crumb:()=>"datasets"},children:[e(r,{index:!0,element:e(ne,{})}),n(r,{path:":datasetId",loader:u,handle:{crumb:a=>a.dataset.name},children:[n(r,{element:e(se,{}),loader:u,children:[e(r,{index:!0,element:e(h,{}),loader:x}),e(r,{path:"experiments",element:e(h,{}),loader:x}),e(r,{path:"examples",element:e(le,{}),loader:ie,children:e(r,{path:":exampleId",element:e(de,{})})})]}),e(r,{path:"compare",handle:{crumb:()=>"compare"},loader:ce,element:e(pe,{})})]})]}),n(r,{path:"/playground",handle:{crumb:()=>"Playground"},children:[e(r,{index:!0,element:e(f,{})}),e(r,{path:"datasets/:datasetId",element:e(f,{}),children:e(r,{path:"examples/:exampleId",element:e(me,{})})}),e(r,{path:"spans/:spanId",element:e(ge,{}),loader:ue,handle:{crumb:a=>a.span.__typename==="Span"?`span ${a.span.context.spanId}`:"span unknown"}})]}),e(r,{path:"/apis",element:e(he,{}),handle:{crumb:()=>"APIs"}}),e(r,{path:"/settings",element:e(xe,{}),handle:{crumb:()=>"Settings"}})]})})]})),{basename:window.Config.basename});function Ae(){return e(z,{router:ke})}function $e(){return e(fe,{children:e(ye,{children:e(Ce,{})})})}function Ce(){const{theme:a}=Pe();return e(D,{theme:a,children:e(k,{theme:O,children:n(A.RelayEnvironmentProvider,{environment:ve,children:[e(ze,{}),e(Se,{children:e(Fe,{children:e(be,{children:e(c.Suspense,{children:e(we,{children:e(Ae,{})})})})})})]})})})}const Ie=document.getElementById("root"),_e=$.createRoot(Ie);_e.render(e($e,{}));
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|