@eqtylab/explorer 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.api +6 -0
- package/.env.iframe +2 -0
- package/.env.manifest +2 -0
- package/.envrc +1 -0
- package/.eslintrc.cjs +17 -0
- package/.github/workflows/ci.yml +46 -0
- package/.github/workflows/publish.yml +44 -0
- package/.husky/pre-push +2 -0
- package/.prettierignore +2 -0
- package/.prettierrc.json +13 -0
- package/LICENSE +201 -0
- package/README.md +84 -0
- package/flake.lock +61 -0
- package/flake.nix +23 -0
- package/index.html +13 -0
- package/package.json +93 -0
- package/postcss.config.js +5 -0
- package/public/logos/eci.svg +23 -0
- package/public/logos/eqty.svg +3 -0
- package/public/manifests/B-200-merged.json +773 -0
- package/public/manifests/amd-sev.json +426 -0
- package/public/manifests/anchors.json +609 -0
- package/public/manifests/association-no-metadata.json +1393 -0
- package/public/manifests/association.json +1402 -0
- package/public/manifests/eqty-docker.json +562 -0
- package/public/manifests/governance.json +1324 -0
- package/public/manifests/intel-tdx-with-nvidia.json +441 -0
- package/public/manifests/intel-tdx.json +404 -0
- package/public/manifests/iroh-collections.json +1285 -0
- package/public/manifests/model-signing.json +1536 -0
- package/public/manifests/multiple-registrations.json +129 -0
- package/public/manifests/no-vcs.json +114 -0
- package/public/manifests/storage.json +294 -0
- package/public/manifests/sub-graphs.json +1 -0
- package/src/animations/variants.ts +52 -0
- package/src/app/apiClient/integrityService/fetchAttributes.ts +29 -0
- package/src/app/apiClient/integrityService/fetchManifest.ts +28 -0
- package/src/app/apiClient/integrityService/types.ts +12 -0
- package/src/app/components/integrityService/IntegrityService.tsx +105 -0
- package/src/app/components/integrityService/components/AuthButton.tsx +26 -0
- package/src/app/components/integrityService/components/FiltersModal.tsx +214 -0
- package/src/app/components/integrityService/components/FiltersToggle.tsx +28 -0
- package/src/app/components/manifestViewer/ManifestViewer.tsx +90 -0
- package/src/app/components/manifestViewer/components/ManifestButtons.tsx +215 -0
- package/src/app/config.json +23 -0
- package/src/app/config.ts +28 -0
- package/src/app/pages/index.tsx +34 -0
- package/src/app/stores/manifestStore.ts +19 -0
- package/src/app/utils/appMode.ts +37 -0
- package/src/assets/fonts/TWKLausanne-300.woff +0 -0
- package/src/assets/fonts/TWKLausanne-300.woff2 +0 -0
- package/src/assets/fonts/TWKLausanne-400.woff +0 -0
- package/src/assets/fonts/TWKLausanne-400.woff2 +0 -0
- package/src/assets/fonts/TWKLausanne-500.woff +0 -0
- package/src/assets/fonts/TWKLausanne-500.woff2 +0 -0
- package/src/assets/fonts/TWKLausanne-600.woff +0 -0
- package/src/assets/fonts/TWKLausanne-600.woff2 +0 -0
- package/src/assets/vectors/eqtylab.svg +6 -0
- package/src/components/app-header.tsx +61 -0
- package/src/components/dark-mode-switch.tsx +16 -0
- package/src/components/ui/accordion.tsx +47 -0
- package/src/components/ui/certificate-chain.tsx +60 -0
- package/src/components/ui/certificate-code.tsx +39 -0
- package/src/components/ui/details.tsx +20 -0
- package/src/components/ui/display-code.tsx +47 -0
- package/src/components/ui/panel-label.tsx +12 -0
- package/src/components/ui/verify-state-badge.tsx +32 -0
- package/src/explorer-component/LineageExplorer.tsx +89 -0
- package/src/explorer-component/components/CustomEdge.tsx +28 -0
- package/src/explorer-component/components/LineageFlow.tsx +220 -0
- package/src/explorer-component/components/NodeIconLoader.tsx +26 -0
- package/src/explorer-component/components/nodes/ComputationNode.tsx +56 -0
- package/src/explorer-component/components/nodes/CustomNode.tsx +112 -0
- package/src/explorer-component/components/nodes/index.ts +4 -0
- package/src/explorer-component/components/nodes/nodes.tsx +144 -0
- package/src/explorer-component/components/nodes/types.ts +167 -0
- package/src/explorer-component/components/sidebar/SectionList.tsx +54 -0
- package/src/explorer-component/components/sidebar/SectionTitle.tsx +10 -0
- package/src/explorer-component/components/sidebar/Sidebar.tsx +70 -0
- package/src/explorer-component/components/sidebar/SidebarWrapper.tsx +76 -0
- package/src/explorer-component/components/sidebar/sections/CustomSection.tsx +238 -0
- package/src/explorer-component/components/sidebar/sections/FileViewer.tsx +229 -0
- package/src/explorer-component/components/sidebar/sections/GovernanceSection.tsx +52 -0
- package/src/explorer-component/components/sidebar/sections/RegistrationSection.tsx +254 -0
- package/src/explorer-component/components/sidebar/sections/SigstoreSection.tsx +37 -0
- package/src/explorer-component/components/sidebar/sections/StorageSection.tsx +73 -0
- package/src/explorer-component/components/sidebar/sections/custom/IrohCollectionsView.tsx +139 -0
- package/src/explorer-component/components/sidebar/sections/registration/VerificationIcon.tsx +108 -0
- package/src/explorer-component/components/sidebar/sections/registration/actor/ActorBadge.tsx +62 -0
- package/src/explorer-component/components/sidebar/sections/registration/actor/svg/AMDLogo.tsx +40 -0
- package/src/explorer-component/components/sidebar/sections/registration/actor/svg/AzureLogo.tsx +65 -0
- package/src/explorer-component/components/sidebar/sections/registration/actor/svg/IntelLogo.tsx +24 -0
- package/src/explorer-component/components/sidebar/sections/registration/actor/svg/NvidiaLogo.tsx +27 -0
- package/src/explorer-component/components/sidebar/sections/registration/verifierClient.ts +13 -0
- package/src/explorer-component/icons/AttributionIcon.svg +6 -0
- package/src/explorer-component/icons/BenchmarkIcon.svg +6 -0
- package/src/explorer-component/icons/BenchmarkResultIcon.svg +6 -0
- package/src/explorer-component/icons/CertificateIcon.svg +6 -0
- package/src/explorer-component/icons/CodeIcon.svg +6 -0
- package/src/explorer-component/icons/ComputationIcon.svg +6 -0
- package/src/explorer-component/icons/DataIcon.svg +6 -0
- package/src/explorer-component/icons/DatabaseIcon.svg +6 -0
- package/src/explorer-component/icons/DatasetIcon.svg +6 -0
- package/src/explorer-component/icons/DeltaLakeIcon.svg +7 -0
- package/src/explorer-component/icons/DocumentIcon.svg +6 -0
- package/src/explorer-component/icons/MediaIcon.svg +6 -0
- package/src/explorer-component/icons/ModelIcon.svg +6 -0
- package/src/explorer-component/icons/TeamIcon.svg +3 -0
- package/src/explorer-component/icons/TokenIcon.svg +6 -0
- package/src/explorer-component/icons/UnknownIcon.svg +6 -0
- package/src/explorer-component/icons/index.ts +35 -0
- package/src/explorer-component/index.ts +5 -0
- package/src/explorer-component/integrityTypes/AnchorTypes.ts +31 -0
- package/src/explorer-component/integrityTypes/StatementTypes.ts +333 -0
- package/src/explorer-component/integrityTypes/VCTypes.ts +85 -0
- package/src/explorer-component/integrityTypes/types.ts +3 -0
- package/src/explorer-component/utils/config.ts +163 -0
- package/src/explorer-component/utils/formatTimestamp.ts +5 -0
- package/src/explorer-component/utils/generateGraph.ts +271 -0
- package/src/explorer-component/utils/layoutGraph.ts +148 -0
- package/src/explorer-component/utils/resolveIrohBlobs.ts +117 -0
- package/src/explorer-component/utils/statementHelpers.ts +252 -0
- package/src/explorer-component/utils/stripPrefix.ts +4 -0
- package/src/hooks/use-mobile.tsx +19 -0
- package/src/index.ts +3 -0
- package/src/lib/resource-types.ts +31 -0
- package/src/lib/use-escape-key.tsx +16 -0
- package/src/lib/utils.ts +19 -0
- package/src/main.css +82 -0
- package/src/main.tsx +39 -0
- package/src/v-comp-viewer/components/container-did-details.tsx +53 -0
- package/src/v-comp-viewer/components/system-did-details.tsx +356 -0
- package/src/v-comp-viewer/useVComp.ts +196 -0
- package/src/v-comp-viewer/utils.tsx +824 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +33 -0
- package/tsconfig.node.json +10 -0
- package/vercel.json +13 -0
- package/vite.app.config.ts +48 -0
- package/vite.lib.config.ts +61 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { stripCidPrefix } from "./stripPrefix.ts";
|
|
2
|
+
import {
|
|
3
|
+
Actor,
|
|
4
|
+
createEmptyActor,
|
|
5
|
+
vcFromString,
|
|
6
|
+
isVCompType,
|
|
7
|
+
VCompType,
|
|
8
|
+
VCompEvidence,
|
|
9
|
+
VCompEvidenceList,
|
|
10
|
+
Statement,
|
|
11
|
+
StorageStatement,
|
|
12
|
+
StorageStatementFromJSON,
|
|
13
|
+
VcStatement,
|
|
14
|
+
MetadataStatement,
|
|
15
|
+
MetadataStatementFromJSON,
|
|
16
|
+
VcStatementFromJSON,
|
|
17
|
+
RegistrationTypes,
|
|
18
|
+
GovernanceStatement,
|
|
19
|
+
GovernanceStatementFromJSON,
|
|
20
|
+
SigstoreStatement,
|
|
21
|
+
SigstoreStatementFromJSON,
|
|
22
|
+
SigstoreBundle,
|
|
23
|
+
} from "../integrityTypes/types";
|
|
24
|
+
import { MetadataLineage, StorageLineage } from "@/explorer-component/components/nodes/types.ts";
|
|
25
|
+
|
|
26
|
+
const statementTypePriority: Record<string, number> = {
|
|
27
|
+
CredentialRegistration: 0,
|
|
28
|
+
MetadataRegistration: 1,
|
|
29
|
+
DidRegistration: 2,
|
|
30
|
+
DataRegistration: 3,
|
|
31
|
+
ComputationRegistration: 4,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Sort the statements by type, and then by timestamp to that indexing doesn't need to repeatedly iterate all the statements looking for VCs, metadata, etc
|
|
35
|
+
export function sortStatements(statements: Record<string, object>): Map<string, object> {
|
|
36
|
+
const sortedStatements = Object.entries(statements).sort(([, a], [, b]) => {
|
|
37
|
+
const typeA = (a as any)["@type"] || "";
|
|
38
|
+
const typeB = (b as any)["@type"] || "";
|
|
39
|
+
|
|
40
|
+
const priorityDiff = (statementTypePriority[typeA] ?? 99) - (statementTypePriority[typeB] ?? 99);
|
|
41
|
+
if (priorityDiff !== 0) return priorityDiff;
|
|
42
|
+
|
|
43
|
+
const timeA = new Date((a as any)["timestamp"] ?? 0).getTime();
|
|
44
|
+
const timeB = new Date((b as any)["timestamp"] ?? 0).getTime();
|
|
45
|
+
|
|
46
|
+
return timeB - timeA; // sort by descending timestamp
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return new Map(sortedStatements);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/// Iterates over the statments to resolve related nodes (metadata, etc)
|
|
53
|
+
// The provided statements Map MUST be sorted
|
|
54
|
+
export function indexStatements(
|
|
55
|
+
statements: Map<string, object>,
|
|
56
|
+
blobs: Record<string, string>,
|
|
57
|
+
): {
|
|
58
|
+
metadataLineage: Map<string, MetadataLineage[]>;
|
|
59
|
+
vcs: Map<string, VcStatement[]>;
|
|
60
|
+
actors: Map<string, any>;
|
|
61
|
+
storage: Map<string, StorageLineage>;
|
|
62
|
+
governance: Map<string, GovernanceStatement>;
|
|
63
|
+
sigstoreBundles: Map<string, SigstoreBundle[]>;
|
|
64
|
+
} {
|
|
65
|
+
const metadataJsonMap: Map<string, any[]> = new Map(); // key=subject cid, value=user defined json
|
|
66
|
+
const metadataStatements: Map<string, MetadataLineage[]> = new Map(); // key=subject cid
|
|
67
|
+
const vcMap: Map<string, VcStatement[]> = new Map(); // key=subject ID
|
|
68
|
+
const actorsMap: Map<string, Actor> = new Map(); // key=did
|
|
69
|
+
const storageMap: Map<string, StorageLineage> = new Map(); // key=data CID
|
|
70
|
+
const governanceMap: Map<string, GovernanceStatement> = new Map(); // key=subject CID
|
|
71
|
+
const sbMap: Map<string, SigstoreBundle[]> = new Map(); // key=subject CID, value=sigstore statement
|
|
72
|
+
|
|
73
|
+
for (const [, statement] of statements) {
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
switch (statement["@type"]) {
|
|
76
|
+
case RegistrationTypes.Metadata: {
|
|
77
|
+
const metadataStatement: MetadataStatement = MetadataStatementFromJSON(statement);
|
|
78
|
+
|
|
79
|
+
if (metadataStatement.subject.startsWith("urn:cid:")) {
|
|
80
|
+
// metadata for a CID
|
|
81
|
+
const blobStr = blobs[stripCidPrefix(metadataStatement.metadata)] || "";
|
|
82
|
+
|
|
83
|
+
const metadataJson = blobStr.length > 0 ? JSON.parse(atob(blobStr)) : null;
|
|
84
|
+
const existingJson = metadataJsonMap.get(metadataStatement.subject) || [];
|
|
85
|
+
existingJson.push(metadataJson);
|
|
86
|
+
metadataJsonMap.set(metadataStatement.subject, existingJson);
|
|
87
|
+
|
|
88
|
+
const existingStatement = metadataStatements.get(metadataStatement.subject) || [];
|
|
89
|
+
const metadataVC = vcMap.get(metadataStatement.id);
|
|
90
|
+
existingStatement.push({
|
|
91
|
+
statement: metadataStatement,
|
|
92
|
+
metadata: metadataJson,
|
|
93
|
+
vc: metadataVC?.[0]?.credential,
|
|
94
|
+
});
|
|
95
|
+
metadataStatements.set(metadataStatement.subject, existingStatement);
|
|
96
|
+
} else if (metadataStatement.subject.startsWith("did:")) {
|
|
97
|
+
// metadata for a DID
|
|
98
|
+
const did = metadataStatement.subject;
|
|
99
|
+
|
|
100
|
+
const blobStr = blobs[stripCidPrefix(metadataStatement.metadata)] || "";
|
|
101
|
+
|
|
102
|
+
const metadataJson = blobStr.length > 0 ? JSON.parse(atob(blobStr)) : null;
|
|
103
|
+
|
|
104
|
+
// TODO: handle multiple metadata statements for the same DID similarly to how we handle metadata for CIDs
|
|
105
|
+
if (!actorsMap.has(did)) {
|
|
106
|
+
actorsMap.set(did, createEmptyActor(did));
|
|
107
|
+
}
|
|
108
|
+
const actor = actorsMap.get(did);
|
|
109
|
+
if (actor) {
|
|
110
|
+
actor.actorName = metadataJson.name || null;
|
|
111
|
+
actor.metadata = metadataJson;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case RegistrationTypes.Credential: {
|
|
118
|
+
if ("sigstoreBundle" in statement) {
|
|
119
|
+
const sbStatement: SigstoreStatement = SigstoreStatementFromJSON(statement);
|
|
120
|
+
const sb = JSON.parse(atob(sbStatement.sigstoreBundle));
|
|
121
|
+
const subjectId = sbStatement.subject;
|
|
122
|
+
if (!sbMap.has(subjectId)) {
|
|
123
|
+
sbMap.set(subjectId, []);
|
|
124
|
+
}
|
|
125
|
+
sbMap.get(subjectId)!.push(sb);
|
|
126
|
+
} else {
|
|
127
|
+
const vcStatement: VcStatement = VcStatementFromJSON(statement);
|
|
128
|
+
const vc = vcFromString(vcStatement.credential);
|
|
129
|
+
if (!vc) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const subjectId = vc.credentialSubject.id;
|
|
133
|
+
|
|
134
|
+
if (!vcMap.has(subjectId)) {
|
|
135
|
+
vcMap.set(subjectId, []);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
vcMap.get(subjectId)!.push(vcStatement);
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
case RegistrationTypes.Did: {
|
|
143
|
+
handleDidRegistration(statement, actorsMap, vcMap);
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case RegistrationTypes.Storage: {
|
|
147
|
+
const storageStatement: StorageStatement = StorageStatementFromJSON(statement);
|
|
148
|
+
const blobStr = blobs[stripCidPrefix(storageStatement.storedOn)] || "";
|
|
149
|
+
const data = blobStr.length > 0 ? JSON.parse(atob(blobStr)) : null;
|
|
150
|
+
|
|
151
|
+
const storage = { statement: storageStatement, metadata: data };
|
|
152
|
+
storageMap.set(storageStatement.data, storage);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case RegistrationTypes.Governance: {
|
|
156
|
+
const governanceStatement: GovernanceStatement = GovernanceStatementFromJSON(statement);
|
|
157
|
+
governanceMap.set(governanceStatement.subject, governanceStatement);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (metadataJsonMap.keys.length !== metadataStatements.keys.length) {
|
|
164
|
+
throw new Error("Count mismatch with the number of metadatastatements and metadata blobs");
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
metadataLineage: metadataStatements,
|
|
168
|
+
vcs: vcMap,
|
|
169
|
+
actors: actorsMap,
|
|
170
|
+
storage: storageMap,
|
|
171
|
+
governance: governanceMap,
|
|
172
|
+
sigstoreBundles: sbMap,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Update the ActorMap with DidRegistration details
|
|
177
|
+
function handleDidRegistration(statement: object, actorsMap: Map<string, Actor>, vcMap: Map<string, VcStatement[]>) {
|
|
178
|
+
const sVal = JSON.parse(JSON.stringify(statement));
|
|
179
|
+
const id = sVal["@id"];
|
|
180
|
+
const did = sVal["did"];
|
|
181
|
+
const vcomp = sVal["vcomp"];
|
|
182
|
+
if (!vcomp || typeof vcomp !== "object") return;
|
|
183
|
+
|
|
184
|
+
const vcompType = vcomp["@type"];
|
|
185
|
+
|
|
186
|
+
if (!isVCompType(vcompType)) {
|
|
187
|
+
console.warn("Unknown vcomp type:", vcompType);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const vcompStatementsMap = new Map<VCompType, Statement[]>();
|
|
192
|
+
const vcompEvidenceMap = new Map<VCompEvidence, VcStatement[]>();
|
|
193
|
+
|
|
194
|
+
if (!vcompStatementsMap.has(vcompType)) {
|
|
195
|
+
vcompStatementsMap.set(vcompType, []);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
vcompStatementsMap.get(vcompType)!.push(VcStatementFromJSON(statement));
|
|
199
|
+
|
|
200
|
+
for (const evidenceType of VCompEvidenceList) {
|
|
201
|
+
const vcStatements = vcMap.get(id);
|
|
202
|
+
if (vcStatements) {
|
|
203
|
+
for (const vc of vcStatements) {
|
|
204
|
+
const type = (vc.credential as any)?.evidence?.type;
|
|
205
|
+
if (Array.isArray(type) && type.includes(evidenceType)) {
|
|
206
|
+
vcompEvidenceMap.set(evidenceType, vcStatements);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const teeEnv = (() => {
|
|
213
|
+
if (!vcompStatementsMap) return null;
|
|
214
|
+
|
|
215
|
+
if (vcompStatementsMap.has("EqtyVCompAmdSevV1") && vcompEvidenceMap.has("EqtyVCompAmdSevV1Evidence")) {
|
|
216
|
+
return "AMD SEV";
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (vcompStatementsMap.has("EqtyVCompIntelTdxV0") && vcompEvidenceMap.has("EqtyVCompIntelTdxV0Evidence")) {
|
|
220
|
+
return "Intel TDX";
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (vcompStatementsMap.has("EqtyVCompAzureV1") && vcompEvidenceMap.has("EqtyVCompAzureV1Evidence")) {
|
|
224
|
+
return "Azure";
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (vcompStatementsMap.has("EqtyVCompDockerV1")) {
|
|
228
|
+
return "EQTY Docker";
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return null;
|
|
232
|
+
})();
|
|
233
|
+
|
|
234
|
+
const usesNvidia = (() => {
|
|
235
|
+
if (vcompEvidenceMap.has("EqtyVCompNvidiaCcV0Evidence")) {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return false;
|
|
240
|
+
})();
|
|
241
|
+
|
|
242
|
+
if (!actorsMap.has(did)) {
|
|
243
|
+
actorsMap.set(did, createEmptyActor(did));
|
|
244
|
+
}
|
|
245
|
+
const actor = actorsMap.get(did);
|
|
246
|
+
if (actor) {
|
|
247
|
+
actor.vcompStatements = vcompStatementsMap;
|
|
248
|
+
actor.vcompEvidence = vcompEvidenceMap;
|
|
249
|
+
actor.usesNvidia = usesNvidia;
|
|
250
|
+
actor.teeEnv = teeEnv;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
const MOBILE_BREAKPOINT = 768;
|
|
4
|
+
|
|
5
|
+
export function useIsMobile() {
|
|
6
|
+
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);
|
|
7
|
+
|
|
8
|
+
React.useEffect(() => {
|
|
9
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
10
|
+
const onChange = () => {
|
|
11
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
12
|
+
};
|
|
13
|
+
mql.addEventListener("change", onChange);
|
|
14
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
15
|
+
return () => mql.removeEventListener("change", onChange);
|
|
16
|
+
}, []);
|
|
17
|
+
|
|
18
|
+
return !!isMobile;
|
|
19
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ResourceType } from "@eqtylab/equality";
|
|
2
|
+
|
|
3
|
+
// lowercase display type to resource type
|
|
4
|
+
const DISPLAY_TYPE_TO_RESOURCE_TYPE: Record<string, ResourceType> = {
|
|
5
|
+
default: "unknown",
|
|
6
|
+
unknown: "unknown",
|
|
7
|
+
dataset: "dataset",
|
|
8
|
+
model: "model",
|
|
9
|
+
code: "code",
|
|
10
|
+
document: "document",
|
|
11
|
+
prompt: "prompt",
|
|
12
|
+
token: "token",
|
|
13
|
+
inference: "inference",
|
|
14
|
+
tool: "tools",
|
|
15
|
+
benchmarks: "benchmark",
|
|
16
|
+
benchmark: "benchmark",
|
|
17
|
+
guards: "guard",
|
|
18
|
+
agent: "agent",
|
|
19
|
+
guardrail: "guardrail",
|
|
20
|
+
computation: "compute",
|
|
21
|
+
systemprompt: "system-prompt",
|
|
22
|
+
context: "context",
|
|
23
|
+
reasoning: "reasoning",
|
|
24
|
+
systemparameters: "system-parameters",
|
|
25
|
+
database: "database",
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const getResourceTypeFromDisplayType = (displayType: string): ResourceType => {
|
|
29
|
+
const lowercasedDisplayType = displayType.toLowerCase() as keyof typeof DISPLAY_TYPE_TO_RESOURCE_TYPE;
|
|
30
|
+
return DISPLAY_TYPE_TO_RESOURCE_TYPE[lowercasedDisplayType] || "unknown";
|
|
31
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
export const useEscapeKey = (value: any, callback: () => void) =>
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const handleDocumentKeydown = (event: KeyboardEvent) => {
|
|
7
|
+
if (!value) return;
|
|
8
|
+
if (event.key === "Escape") {
|
|
9
|
+
callback();
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
document.addEventListener("keydown", handleDocumentKeydown);
|
|
13
|
+
return () => {
|
|
14
|
+
document.removeEventListener("keydown", handleDocumentKeydown);
|
|
15
|
+
};
|
|
16
|
+
}, [value, callback]);
|
package/src/lib/utils.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { clsx, type ClassValue } from "clsx";
|
|
2
|
+
import { twMerge } from "tailwind-merge";
|
|
3
|
+
|
|
4
|
+
export function cn(...inputs: ClassValue[]) {
|
|
5
|
+
return twMerge(clsx(inputs));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function toNumber(value: string | undefined | null) {
|
|
9
|
+
return value ? parseInt(value, 10) : undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function formatFileSize(bytes: number): string {
|
|
13
|
+
if (bytes === 0) return "0 Bytes";
|
|
14
|
+
|
|
15
|
+
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
|
16
|
+
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
17
|
+
|
|
18
|
+
return `${parseFloat((bytes / Math.pow(1024, i)).toFixed(2))} ${sizes[i]}`;
|
|
19
|
+
}
|
package/src/main.css
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
@layer theme, base, components, utilities;
|
|
2
|
+
|
|
3
|
+
@import "tailwindcss/theme.css" layer(theme) theme(inline);
|
|
4
|
+
@import "tailwindcss/utilities.css" layer(utilities);
|
|
5
|
+
|
|
6
|
+
@import "@eqtylab/equality/theme-config.css";
|
|
7
|
+
|
|
8
|
+
@layer base {
|
|
9
|
+
main {
|
|
10
|
+
@apply bg-background font-sans text-text-primary transition-colors;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* COLORS */
|
|
14
|
+
html {
|
|
15
|
+
/* Primary */
|
|
16
|
+
--brand-lineage-explorer: var(--color-blue-600);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
html[data-equality-theme="dark"] {
|
|
20
|
+
--brand-lineage-explorer: var(--color-blue-300);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@theme inline {
|
|
25
|
+
/* COLORS */
|
|
26
|
+
--color-brand-lineage-explorer: var(--brand-lineage-explorer);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@layer utilities {
|
|
30
|
+
:root {
|
|
31
|
+
font-synthesis: none;
|
|
32
|
+
text-rendering: optimizeLegibility;
|
|
33
|
+
-webkit-font-smoothing: antialiased;
|
|
34
|
+
-moz-osx-font-smoothing: grayscale;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@font-face {
|
|
39
|
+
font-family: "TWK Lausanne";
|
|
40
|
+
src:
|
|
41
|
+
url("./assets/fonts/TWKLausanne-300.woff") format("woff"),
|
|
42
|
+
url("./assets/fonts/TWKLausanne-300.woff2") format("woff2");
|
|
43
|
+
font-style: normal;
|
|
44
|
+
font-weight: 300;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@font-face {
|
|
48
|
+
font-family: "TWK Lausanne";
|
|
49
|
+
src:
|
|
50
|
+
url("./assets/fonts/TWKLausanne-400.woff") format("woff"),
|
|
51
|
+
url("./assets/fonts/TWKLausanne-400.woff2") format("woff2");
|
|
52
|
+
font-style: normal;
|
|
53
|
+
font-weight: 400;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@font-face {
|
|
57
|
+
font-family: "TWK Lausanne";
|
|
58
|
+
src:
|
|
59
|
+
url("./assets/fonts/TWKLausanne-500.woff") format("woff"),
|
|
60
|
+
url("./assets/fonts/TWKLausanne-500.woff2") format("woff2");
|
|
61
|
+
font-style: normal;
|
|
62
|
+
font-weight: 500;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@font-face {
|
|
66
|
+
font-family: "TWK Lausanne";
|
|
67
|
+
src:
|
|
68
|
+
url("./assets/fonts/TWKLausanne-600.woff") format("woff"),
|
|
69
|
+
url("./assets/fonts/TWKLausanne-600.woff2") format("woff2");
|
|
70
|
+
font-style: normal;
|
|
71
|
+
font-weight: 600;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
iframe {
|
|
75
|
+
color-scheme: light;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* This is needed to prevent edges from getting cut off*/
|
|
79
|
+
.react-flow__pane {
|
|
80
|
+
width: 320rem !important;
|
|
81
|
+
height: 320rem !important;
|
|
82
|
+
}
|
package/src/main.tsx
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
import { createBrowserRouter, redirect, RouterProvider } from "react-router-dom";
|
|
4
|
+
import "@fontsource/ibm-plex-mono";
|
|
5
|
+
|
|
6
|
+
import "./main.css";
|
|
7
|
+
|
|
8
|
+
const router = createBrowserRouter([
|
|
9
|
+
{
|
|
10
|
+
children: [
|
|
11
|
+
{
|
|
12
|
+
path: "/",
|
|
13
|
+
lazy: () => import("./app/pages/index"),
|
|
14
|
+
id: "graph",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
// adding redirect to root to catch any static links/demos that are using this url
|
|
18
|
+
path: "/explorer/lineage",
|
|
19
|
+
loader: async ({ request }) => {
|
|
20
|
+
const url = new URL(request.url);
|
|
21
|
+
const searchParams = url.searchParams.toString();
|
|
22
|
+
return redirect(`/?${searchParams}`);
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
// {
|
|
26
|
+
// path: "/prolly-proof/:cid/:id",
|
|
27
|
+
// loader: async (req) => prollyProofLoader(req),
|
|
28
|
+
// },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
34
|
+
<React.StrictMode>
|
|
35
|
+
<main>
|
|
36
|
+
<RouterProvider router={router} />
|
|
37
|
+
</main>
|
|
38
|
+
</React.StrictMode>,
|
|
39
|
+
);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import Details from "@/components/ui/details";
|
|
2
|
+
import { SectionList } from "@/explorer-component/components/sidebar/SectionList";
|
|
3
|
+
import { VCompContainerInfo } from "@/v-comp-viewer/utils";
|
|
4
|
+
import DisplayCode from "@/components/ui/display-code";
|
|
5
|
+
|
|
6
|
+
const ContainerDidDetails = ({ containerInfo }: { containerInfo: VCompContainerInfo }) => {
|
|
7
|
+
const data = [
|
|
8
|
+
{
|
|
9
|
+
label: "Container Notary",
|
|
10
|
+
value: <DisplayCode value={`${containerInfo.did.value}`} validated={containerInfo.did.validated} />,
|
|
11
|
+
offsetTopLabel: true,
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
label: "Docker Compose",
|
|
15
|
+
value: (
|
|
16
|
+
<DisplayCode
|
|
17
|
+
value={`cid:${containerInfo.dockerComposeId.value}`}
|
|
18
|
+
validated={containerInfo.dockerComposeId.validated}
|
|
19
|
+
/>
|
|
20
|
+
),
|
|
21
|
+
offsetTopLabel: true,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
label: "Docker Images",
|
|
25
|
+
value: (
|
|
26
|
+
<div className="space-y-4">
|
|
27
|
+
{containerInfo.dockerImages.images.map((image: { name: string; sha256: string }) => {
|
|
28
|
+
return (
|
|
29
|
+
<DisplayCode
|
|
30
|
+
key={image.name}
|
|
31
|
+
value={`sha256:${image.sha256}`}
|
|
32
|
+
validated={containerInfo.dockerImages.validated}
|
|
33
|
+
slot={<code>{image.name}</code>}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
})}
|
|
37
|
+
</div>
|
|
38
|
+
),
|
|
39
|
+
offsetTopLabel: true,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
label: "Signed By",
|
|
43
|
+
value: (
|
|
44
|
+
<DisplayCode value={`${containerInfo.signedBy.value}`} validated={containerInfo.signedBy.validated} />
|
|
45
|
+
),
|
|
46
|
+
offsetTopLabel: true,
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
return <Details title="Details" content={<SectionList data={data} className="mt-4 pb-4" />} />;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default ContainerDidDetails;
|