Spaces:
Running on RTX PRO 6000
Running on RTX PRO 6000
Batch 10-16 12:2xZ: UI dist slim-ui-e06d4a92 (!730 native joints, !732 reader 00c663a + .br, !734 glass r3) + #93 nginx template (reader .br to br clients); add 7 picked up at start
Browse files- .gitattributes +1 -0
- docker/hf-space/nginx.conf.template +55 -0
- services/explorer/dist/build-info.json +3 -3
- services/explorer/dist/index.html +1 -1
- services/explorer/dist/static/js/482.f97e527d.chunk.js +1 -0
- services/explorer/dist/static/js/main.3b513bd4.js +0 -0
- services/explorer/dist/static/js/main.3b513bd4.js.LICENSE.txt +39 -0
- services/explorer/dist/static/usd-reader/00c663a/esm/errors.js +15 -0
- services/explorer/dist/static/usd-reader/00c663a/esm/errors.js.br +0 -0
- services/explorer/dist/static/usd-reader/00c663a/esm/hub-prefetch.js +94 -0
- services/explorer/dist/static/usd-reader/00c663a/esm/hub-prefetch.js.br +0 -0
- services/explorer/dist/static/usd-reader/00c663a/esm/load-core.js +760 -0
- services/explorer/dist/static/usd-reader/00c663a/esm/load-core.js.br +0 -0
- services/explorer/dist/static/usd-reader/00c663a/esm/worker.js +150 -0
- services/explorer/dist/static/usd-reader/00c663a/esm/worker.js.br +0 -0
- services/explorer/dist/static/usd-reader/00c663a/wasm/usd_wasm.js +760 -0
- services/explorer/dist/static/usd-reader/00c663a/wasm/usd_wasm.js.br +0 -0
- services/explorer/dist/static/usd-reader/00c663a/wasm/usd_wasm_bg.wasm +3 -0
- services/explorer/dist/static/usd-reader/00c663a/wasm/usd_wasm_bg.wasm.br +3 -0
- services/explorer/dist/third-party-notices.txt +1 -1
.gitattributes
CHANGED
|
@@ -37,3 +37,4 @@ docker/hf-space/siglip2-model/model_repo/tokenizer/1/tokenizer/tokenizer.json fi
|
|
| 37 |
docker/hf-space/wheels/deepsearch_api-0.1.0-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text
|
| 38 |
docker/hf-space/wheels/search_utils-0.1.0-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text
|
| 39 |
docker/hf-space/wheels/siglip2_triton_client-0.6.1-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 37 |
docker/hf-space/wheels/deepsearch_api-0.1.0-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text
|
| 38 |
docker/hf-space/wheels/search_utils-0.1.0-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text
|
| 39 |
docker/hf-space/wheels/siglip2_triton_client-0.6.1-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
services/explorer/dist/static/usd-reader/00c663a/wasm/usd_wasm_bg.wasm.br filter=lfs diff=lfs merge=lfs -text
|
docker/hf-space/nginx.conf.template
CHANGED
|
@@ -290,6 +290,61 @@ server {
|
|
| 290 |
gzip_vary on;
|
| 291 |
gzip_types application/wasm application/javascript;
|
| 292 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 293 |
# index.html must always revalidate (covers the try_files fallback too): a swap or rollback
|
| 294 |
# must not leave a browser holding an index.html that names deleted chunks.
|
| 295 |
location = /index.html {
|
|
|
|
| 290 |
gzip_vary on;
|
| 291 |
gzip_types application/wasm application/javascript;
|
| 292 |
}
|
| 293 |
+
# Its .wasm and .js: copy-usd-reader.js writes <file>.br beside each (brotli 11; this nginx has no brotli encoder).
|
| 294 |
+
# A client whose Accept-Encoding names br ($slim_accepts_br, above) gets the .br, Content-Encoding br and the
|
| 295 |
+
# file's own type (application/wasm: WebAssembly.compileStreaming refuses any other), whole (never a Range of the
|
| 296 |
+
# encoding). Else, or with no .br, @slim_reader_identity sends the file as the location above does. Both vary on
|
| 297 |
+
# Accept-Encoding. A regex location: it wins over the prefix above. add_header drops his server-level headers: his
|
| 298 |
+
# CORS lines re-declared, so the reader's responses carry them as they did from the prefix location.
|
| 299 |
+
location ~ ^/static/usd-reader/.+\.wasm$ {
|
| 300 |
+
root /usr/share/nginx/explorer;
|
| 301 |
+
error_page 418 = @slim_reader_identity;
|
| 302 |
+
if ($slim_accepts_br = 0) { return 418; }
|
| 303 |
+
try_files $uri.br @slim_reader_identity;
|
| 304 |
+
types { }
|
| 305 |
+
default_type application/wasm;
|
| 306 |
+
gzip off;
|
| 307 |
+
max_ranges 0;
|
| 308 |
+
add_header Content-Encoding br;
|
| 309 |
+
add_header Vary Accept-Encoding always;
|
| 310 |
+
add_header Access-Control-Allow-Origin "*" always;
|
| 311 |
+
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
|
| 312 |
+
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
|
| 313 |
+
}
|
| 314 |
+
location ~ ^/static/usd-reader/.+\.js$ {
|
| 315 |
+
root /usr/share/nginx/explorer;
|
| 316 |
+
error_page 418 = @slim_reader_identity;
|
| 317 |
+
if ($slim_accepts_br = 0) { return 418; }
|
| 318 |
+
try_files $uri.br @slim_reader_identity;
|
| 319 |
+
types { }
|
| 320 |
+
default_type application/javascript;
|
| 321 |
+
gzip off;
|
| 322 |
+
max_ranges 0;
|
| 323 |
+
add_header Content-Encoding br;
|
| 324 |
+
add_header Vary Accept-Encoding always;
|
| 325 |
+
add_header Access-Control-Allow-Origin "*" always;
|
| 326 |
+
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
|
| 327 |
+
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
|
| 328 |
+
}
|
| 329 |
+
location @slim_reader_identity {
|
| 330 |
+
root /usr/share/nginx/explorer;
|
| 331 |
+
try_files $uri =404;
|
| 332 |
+
types { application/wasm wasm; application/javascript js; }
|
| 333 |
+
default_type application/octet-stream;
|
| 334 |
+
gzip_static on;
|
| 335 |
+
gzip on;
|
| 336 |
+
gzip_comp_level 6;
|
| 337 |
+
gzip_types application/wasm application/javascript;
|
| 338 |
+
add_header Vary Accept-Encoding always;
|
| 339 |
+
add_header Access-Control-Allow-Origin "*" always;
|
| 340 |
+
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
|
| 341 |
+
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
|
| 342 |
+
}
|
| 343 |
+
# A reader .br is an encoding of its file, never a URL of its own.
|
| 344 |
+
location ~ ^/static/usd-reader/.+\.br$ {
|
| 345 |
+
default_type application/json;
|
| 346 |
+
return 404 '{"detail":"Not Found"}';
|
| 347 |
+
}
|
| 348 |
# index.html must always revalidate (covers the try_files fallback too): a swap or rollback
|
| 349 |
# must not leave a browser holding an index.html that names deleted chunks.
|
| 350 |
location = /index.html {
|
services/explorer/dist/build-info.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
{
|
| 2 |
"product": "simready-central-slim-explorer",
|
| 3 |
-
"version": "slim-ui-
|
| 4 |
-
"bundle_id": "main.
|
| 5 |
-
"built_at": "2026-10-
|
| 6 |
"flags": {"public_mode": true, "email_auth": false, "create_ui": false, "hierarchy_editor": false, "create_search": false, "auth_ui": false, "credentials_ui": false, "index_management": false, "inference_backend": "hub", "vlm_asset_refs": false, "validation_image_max_px": 448, "validation_max_retries": 0, "validation_max_concurrent": 32, "validation_tail_concurrent": 8, "validation_eager_count": 50, "validation_batch_stream": true, "library_idle_prefetch": false, "validation_score_scale": "percent", "parse_gate_fields": true, "parse_fast_path": true, "featured_landing": true, "hf_download_commands": true, "dependency_views": true, "model_viewer": false, "library_viewer": true, "library_media": "runtime", "spell_correction": false, "downloads": "runtime", "submit_content": "runtime", "third_party_notices": "runtime"}
|
| 7 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"product": "simready-central-slim-explorer",
|
| 3 |
+
"version": "slim-ui-e06d4a92",
|
| 4 |
+
"bundle_id": "main.3b513bd4.js",
|
| 5 |
+
"built_at": "2026-10-16T11:00:03Z",
|
| 6 |
"flags": {"public_mode": true, "email_auth": false, "create_ui": false, "hierarchy_editor": false, "create_search": false, "auth_ui": false, "credentials_ui": false, "index_management": false, "inference_backend": "hub", "vlm_asset_refs": false, "validation_image_max_px": 448, "validation_max_retries": 0, "validation_max_concurrent": 32, "validation_tail_concurrent": 8, "validation_eager_count": 50, "validation_batch_stream": true, "library_idle_prefetch": false, "validation_score_scale": "percent", "parse_gate_fields": true, "parse_fast_path": true, "featured_landing": true, "hf_download_commands": true, "dependency_views": true, "model_viewer": false, "library_viewer": true, "library_media": "runtime", "spell_correction": false, "downloads": "runtime", "submit_content": "runtime", "third_party_notices": "runtime"}
|
| 7 |
}
|
services/explorer/dist/index.html
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/ds.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="SimReady Central — SimReady asset search"/><meta name="ui-version" content="slim-ui-
|
|
|
|
| 1 |
+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/ds.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="SimReady Central — SimReady asset search"/><meta name="ui-version" content="slim-ui-e06d4a92"><script src="/config.js"></script><title>SimReady Central</title><script defer="defer" src="/static/js/main.3b513bd4.js"></script><link href="/static/css/main.c80b163d.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
services/explorer/dist/static/js/482.f97e527d.chunk.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
"use strict";(self.webpackChunkdeepsearch_ui=self.webpackChunkdeepsearch_ui||[]).push([[482],{482(e,t,o){o.r(t),o.d(t,{COLLIDERS_LAYER:()=>x,HD_LAYER:()=>A,LOCAL:()=>L,NORMAL_MODES:()=>ie,OPENPBR_CORE_MAPS:()=>q,OPENPBR_EXT_MAPS:()=>J,READER_TEXTURES:()=>P,RECYCLE_BYTES:()=>U,ROOT_KEY:()=>_,ROOT_LAYER:()=>S,SLOTS:()=>G,WARM_KEY:()=>k,WebUsdError:()=>R,_readerState:()=>Je,_resetWebUsdReader:()=>qe,colorSpaceOf:()=>X,compactRecord:()=>Z,compactThickness:()=>ae,compileFrom:()=>Re,expected:()=>Ne,fallbackWarning:()=>ve,fileKey:()=>F,flipV:()=>$,geometryArrays:()=>le,isWebUsdError:()=>O,loadWebUsd:()=>He,lowBitLog2:()=>ee,mapUrl:()=>z,materialGaps:()=>ge,materialParams:()=>ye,openpbrOnly:()=>fe,physicsResult:()=>De,pieceOf:()=>I,planHints:()=>D,quantizeLattice:()=>se,roleOf:()=>K,rootLayerText:()=>T,setWebUsdReader:()=>Le,siblingUrl:()=>N,snormNormals:()=>re,tierLayers:()=>j,uvDequant:()=>ne,uvMatrix:()=>de,warmWebUsdReader:()=>je,webUsdReaderFailure:()=>C,webUsdReaderSet:()=>Ue});var s=o(834),r=o(979),n=o(533);const a="/Asset",i="".concat(a,"/Bodies"),l="".concat(a,"/Joints"),c=["simready"],u={version:1,frame:"gltf",units:{length:"m",angle:"deg",mass:"kg"}},d={kind:["simready:kind",!1],sequence:["simready:sequence",!1],order:["simready:order",!1],fixed_base:["simready:fixedBase",!1],static_reason:["simready:staticReason",!1],poses:["simready:poses",!0],pose_problems:["simready:poseProblems",!0],physics_variants:["simready:physicsVariants",!0],selftest:["simready:selftest",!0]},p={PhysicsRevoluteJoint:"revolute",PhysicsPrismaticJoint:"prismatic",PhysicsFixedJoint:"fixed"},m=new Set(["revolute","prismatic"]),h=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),f=e=>String(e).split("/").pop(),y=e=>String(e).slice(0,String(e).lastIndexOf("/"));function v(e){const[t,o,s,r]=e.map(Number);return[1-2*(s*s+r*r),2*(o*s+t*r),2*(o*r-t*s)]}function g(e,t){if(!e)throw new Error("webUsdPhysics: ".concat(t))}function b(e){const t=(0,r.A)({},(null===e||void 0===e?void 0:e.attributes)||{});for(const[o,s]of Object.entries((null===e||void 0===e?void 0:e.unreadable)||{}))g("string[]"===s,"".concat(e.path,".").concat(o,": the reader could not read it (").concat(s||"no type",")")),t[o]=[];return t}function w(e,t){const o=p[e.type];g(o,"".concat(e.path,": not a joint of the profile (").concat(e.type,")"));const s=b(e),r=e.relationships||{},n=new Set(e.apiSchemas||[]),a={};for(const[p,m]of Object.entries(s))!p.startsWith("physics:")&&!p.startsWith("simready:")||p.startsWith("physics:body")||p.startsWith("drive:")||(a[p]=m);const i={};for(const[p,m]of Object.entries(r))p.startsWith("simready:")&&(i[p]=m.map(f));const l=e=>r[e]&&r[e].length?f(r[e][0]):null;let c=null;for(const p of["angular","linear"]){var u,d;if(!n.has("PhysicsDriveAPI:".concat(p)))continue;const e=e=>s["drive:".concat(p,":physics:").concat(e)],t="drive:".concat(p,":physics:maxForce");c={stiffness:null!==(u=e("stiffness"))&&void 0!==u?u:0,damping:null!==(d=e("damping"))&&void 0!==d?d:0,maxForce:h(s,t)?s[t]:null}}const y={id:f(e.path),type:o,body0:l("physics:body0"),body1:l("physics:body1"),label:h(a,"simready:label")?a["simready:label"]:null};t&&h(a,"simready:name")&&(y.name=a["simready:name"]),h(a,"simready:lockedFrom")&&(y.locked_from=a["simready:lockedFrom"]);const w=e=>h(a,e)?a[e]:null;if(m.has(o)){const t=h(a,"simready:rest")?a["simready:rest"]:0;g(Array.isArray(a["physics:localRot0"]),"".concat(e.path,": no physics:localRot0")),g(Array.isArray(a["physics:localPos0"]),"".concat(e.path,": no physics:localPos0"));const o=e=>"number"===typeof a[e]?a[e]+t:null;if(Object.assign(y,{axis:v(a["physics:localRot0"]),pivot:[...a["physics:localPos0"]],unit:w("simready:unit"),lower:o("physics:lowerLimit"),upper:o("physics:upperLimit"),rest:w("simready:rest"),home:w("simready:home"),far:w("simready:far"),partial:w("simready:partial"),drive:null}),c){const e=c.stiffness||0,t=c.damping||0,o=c.maxForce;y.drive={type:e>0?"position":t>0?"velocity":"none",stiffness:e,damping:t,max_force:"number"===typeof o&&Number.isFinite(o)?o:null}}h(a,"simready:range")&&(y.range=[...a["simready:range"]]);for(const e of["mimic","coupled"])h(i,"simready:".concat(e,"Of"))&&(y[e]={of:i["simready:".concat(e,"Of")][0],gearing:a["simready:".concat(e,"Gearing")],offset:a["simready:".concat(e,"Offset")]},"coupled"===e&&(y[e].source=w("simready:coupledSource")));h(a,"simready:loop")&&(y.loop=JSON.parse(a["simready:loop"])),a["physics:excludeFromArticulation"]&&(y.closes=!0)}let M=null;if(h(a,"simready:tree")){const t=i["simready:treeParent"]&&i["simready:treeParent"].length?i["simready:treeParent"]:[null];g(i["simready:treeChild"]&&i["simready:treeChild"].length,"".concat(e.path,": no simready:treeChild")),M=[a["simready:tree"],{joint:y.id,parent:t[0],child:i["simready:treeChild"][0],inverse:!!a["simready:treeInverse"]}]}return{row:y,tree:M}}const M=["warnings"],S="asset.usdc",A="hd.usdc",x="colliders.usdc",_="simready-web.usda",k="simready-warm.usda",L="local:///",U=268435456,P="none";class R extends Error{constructor(e,t){let{cause:o,url:s,status:r,fatal:n}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};super(t),this.name="WebUsdError",this.code=e,void 0!==o&&(this.cause=o),void 0!==s&&(this.url=s),void 0!==r&&(this.status=r),n&&(this.fatal=!0)}}const O=e=>e instanceof R;let B=null;function E(e,t){let o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return B=new R(e,t,(0,r.A)((0,r.A)({},o),{},{fatal:!0})),B}const C=()=>B,W=/\/Bodies\/(b\d+)\/(?:lo|hd)\/(m\d+)$/;function I(e){const t=W.exec(e||"");return t?{body:t[1],name:t[1]+t[2]}:null}function T(){const e=2===(arguments.length>0&&void 0!==arguments[0]?arguments[0]:1)?"full":"preview";return["#usda 1.0","(",' defaultPrim = "Asset"'," metersPerUnit = 1",' upAxis = "Y"'," subLayers = ["," @./".concat(S,"@")," ]",")","",'over "Asset" ('," variants = {",' string lod = "'.concat(e,'"'),' string textures = "web"'," }",")","{","}",""].join("\n")}const j=function(){return 2===(arguments.length>0&&void 0!==arguments[0]?arguments[0]:1)?[S,A]:[S]},F=e=>String(e).split(/[?#]/)[0];function N(e,t){const o=new URL(e,t);return o.search||(o.search=new URL(t).search),o.href}function z(e,t){return String(e).startsWith(L)?N(String(e).slice(L.length).replace(/^\/+/,""),t):new URL(e,t).href}function D(e,t){const o=new Map;for(const s of e||[]){if("string"!==typeof s||!s.trim())continue;const e=N(s.trim(),t),r=F(e);o.has(r)||o.set(r,e)}return o}const G={diffuseColor:"map",emissiveColor:"emissiveMap",roughness:"roughnessMap",metallic:"metalnessMap",occlusion:"aoMap",opacity:"alphaMap",normal:"normalMap"},H={map:"rgb",emissiveMap:"rgb",roughnessMap:"g",metalnessMap:"b",aoMap:"r",alphaMap:"g",normalMap:"rgb",transmissionMap:"r",clearcoatMap:"r",clearcoatRoughnessMap:"g",clearcoatNormalMap:"rgb",specularIntensityMap:"a",specularColorMap:"rgb",sheenColorMap:"rgb",sheenRoughnessMap:"a"},q={base_color:"map",base_metalness:"metalnessMap",specular_roughness:"roughnessMap",geometry_normal:"normalMap",emission_color:"emissiveMap",geometry_opacity:"alphaMap"},J={transmission_weight:"transmissionMap",coat_weight:"clearcoatMap",coat_roughness:"clearcoatRoughnessMap",geometry_coat_normal:"clearcoatNormalMap",specular_weight:"specularIntensityMap",specular_color:"specularColorMap",fuzz_color:"sheenColorMap",fuzz_roughness:"sheenRoughnessMap"},Y=new Set(["map","emissiveMap","sheenColorMap","specularColorMap"]),K=e=>Y.has(e)?"color":"data",X=e=>"color"===e?"srgb":"",V=(e,t)=>Math.abs(e-t)<1e-6,Q={r:0,g:1,b:2,a:3};function $(e){for(let t=1;t<e.length;t+=2)e[t]=1-e[t];return e}function Z(e,t){var o,s;if(!0===e)return!0;if(Array.isArray(e))return 3===e.length&&e.every(e=>Number.isInteger(e)&&e>0);if(e&&"object"===typeof e)return!!e.bits||Number.isInteger(e.points_log2);let r=null===t||void 0===t||null===(o=t.customLayerData)||void 0===o||null===(s=o.simready)||void 0===s?void 0:s.tiers;if("string"===typeof r)try{r=JSON.parse(r)}catch(n){r=null}return!(!r||"object"!==typeof r||!r.compact)}function ee(e){const t=new Uint32Array(e.buffer,e.byteOffset,e.length);let o=1/0;for(let s=0;s<t.length;s+=1){const e=t[s];if(0===(2147483647&e)){if(0!==e)return null;continue}const r=e>>>23&255;if(255===r)return null;const n=r?8388607&e|8388608:8388607&e,a=(r||1)-150+(31-Math.clz32(n&-n));a<o&&(o=a)}return o===1/0?0:o}const te=[-32768,32767],oe=[0,65535];function se(e,t){let o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t;const s=e.length/t;if(!(s>0)||!Number.isInteger(s))return null;const r=ee(e);if(null===r)return null;const n=2**-r,a=new Array(t).fill(1/0),i=new Array(t).fill(-1/0);for(let m=0,h=0;m<s;m+=1)for(let o=0;o<t;o+=1,h+=1){const t=e[h]*n;t<a[o]&&(a[o]=t),t>i[o]&&(i[o]=t)}const l=Math.min(...a),c=Math.max(...i);let u=null,d=new Array(t).fill(0);if(l>=te[0]&&c<=te[1])u=Int16Array;else if(l>=oe[0]&&c<=oe[1])u=Uint16Array;else{if(!a.every((e,t)=>i[t]-e<=oe[1]))return null;u=Uint16Array,d=a.slice()}const p=new u(s*o);for(let m=0,h=0;m<s;m+=1)for(let s=0;s<t;s+=1,h+=1)p[m*o+s]=e[h]*n-d[s];return{array:p,k:r,offset:d,min:a.map((e,t)=>e-d[t]),max:i.map((e,t)=>e-d[t])}}function re(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:8;const o=16===t?Int16Array:Int8Array,s=16===t?32767:127,r=e.length/3,n=new o(4*r);for(let a=0;a<r;a+=1)for(let t=0;t<3;t+=1){const o=Math.max(-1,Math.min(1,e[3*a+t]||0));n[4*a+t]=Math.sign(o)*Math.floor(Math.abs(o)*s+.5)}return n}const ne=e=>{let{k:t,offset:o}=e;const s=2**t;return[s,0,o[0]*s,0,s,o[1]*s,0,0,1].map(e=>e+0)},ae=(e,t)=>e/2**t,ie={int8:8,int16:16,float:0};function le(e,t){let o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"int8";const s=(e.uvs||[]).map($),r=e=>e?(e.array||e).byteLength:0,n=r(e.positions)+r(e.normals)+s.reduce((e,t)=>e+t.byteLength,0),a={position:e.positions,normal:e.normals,uvs:s.slice(),positionLattice:null,uvLattice:null};if(t){var i;a.positionLattice=se(e.positions,3,4),a.positionLattice&&(a.position=a.positionLattice);const t=null!==(i=ie[o])&&void 0!==i?i:8;t&&e.normals&&(a.normal={array:re(e.normals,t),bits:t}),s[0]&&(a.uvLattice=se(s[0],2,2),a.uvLattice&&(a.uvs[0]=a.uvLattice))}return a.bytes={float:n,upload:r(a.position)+r(a.normal)+a.uvs.reduce((e,t)=>e+r(t),0)},a}const ce=(e,t)=>[0,1,2].flatMap(o=>[0,1,2].map(s=>e[3*o]*t[s]+e[3*o+1]*t[3+s]+e[3*o+2]*t[6+s])),ue=[1,0,0,0,-1,1,0,0,1];function de(e){const[t,o]=(null===e||void 0===e?void 0:e.uvScale)||[1,1],[s,r]=(null===e||void 0===e?void 0:e.uvTranslation)||[0,0],n=((null===e||void 0===e?void 0:e.uvRotation)||0)*Math.PI/180;if(1===t&&1===o&&0===s&&0===r&&0===n)return null;const a=Math.cos(n),i=Math.sin(n);return ce(ce(ue,[a*t,-i*o,s,i*t,a*o,r,0,0,1]),ue).map(e=>e+0)}const pe={mirror:"mirror",clamp:"clamp",black:"clamp"},me={specular_weight:"specularIntensity",specular_color:"specularColor",specular_ior:"ior",transmission_weight:"transmission",transmission_color:"attenuationColor",transmission_depth:"attenuationDistance",coat_weight:"clearcoat",coat_roughness:"clearcoatRoughness",fuzz_color:"sheenColor",fuzz_roughness:"sheenRoughness",specular_roughness_anisotropy:"anisotropy"},he={base_weight:1,base_color:[.8,.8,.8],base_metalness:0,specular_roughness:.3,geometry_opacity:1,emission_color:[1,1,1]},fe=e=>"fallback"===(null===e||void 0===e?void 0:e.kind)&&!(null===e||void 0===e||!e.openpbr);function ye(e){var t,o,s,r;const n=e&&e.openpbr||{},a=e&&e.simready||{},i=e&&e.maps||{},l={name:(null===e||void 0===e?void 0:e.path)||"",color:[...(null===e||void 0===e?void 0:e.color)||[1,1,1]],opacity:null!==(t=null===e||void 0===e?void 0:e.opacity)&&void 0!==t?t:1,roughness:null!==(o=null===e||void 0===e?void 0:e.roughness)&&void 0!==o?o:1,metalness:null!==(s=null===e||void 0===e?void 0:e.metallic)&&void 0!==s?s:1,emissive:[...(null===e||void 0===e?void 0:e.emissive)||[0,0,0]],emissiveIntensity:1,alphaMode:"OPAQUE",alphaTest:0,transparent:!1,depthWrite:!0,doubleSided:null,normalScale:1,aoMapIntensity:1,physical:{},maps:{},gaps:[]},c=(e,t)=>{l.maps[e]={path:t.path,role:K(e),wrap:[pe[t.wrapS]||"repeat",pe[t.wrapT]||"repeat"],matrix:de(t)};const o=H[e];o&&t.channel!==o&&l.gaps.push("".concat(e," reads ").concat(t.channel,", three samples ").concat(o))},u=e=>e.channel in Q?e.scale[Q[e.channel]]:e.scale[0],d=i.diffuseColor;let p=!1;for(const[b,w]of Object.entries(i)){const t=G[b];t&&w&&w.path?(w.uvSet&&"st"!==w.uvSet&&l.gaps.push("".concat(b," samples primvar ").concat(w.uvSet,", not st")),"diffuseColor"===b?(l.color=[0,1,2].map(t=>{var o,s;return(null!==(o=null===(s=e.color)||void 0===s?void 0:s[t])&&void 0!==o?o:1)*w.scale[t]}),c(t,w)):"emissiveColor"===b?(l.emissive=[0,1,2].map(e=>w.scale[e]),c(t,w)):"roughness"===b?(l.roughness=u(w),c(t,w)):"metallic"===b?(l.metalness=u(w),c(t,w)):"occlusion"===b?(l.aoMapIntensity=u(w),c(t,w)):"normal"===b?(V(w.scale[0],2)&&V(w.bias[0],-1)||l.gaps.push("normal map not at scale 2 / bias -1"),c(t,w)):"opacity"===b&&(p=!0,l.opacity=u(w),d&&d.path===w.path&&"a"===w.channel||c(t,w)),"normal"!==b&&"occlusion"!==b&&w.bias&&w.bias.some(e=>!V(e,0))&&l.gaps.push("".concat(b," has a bias"))):l.gaps.push("".concat(b,": no three.js map"))}const m=fe(e),h=new Set(e&&e.openpbrTextured||[]),f=e&&e.openpbrMaps||{},y=new Set,v=(e,t)=>{var o;const s=f[e];s&&s.path&&(s.uvSet&&"st"!==s.uvSet&&l.gaps.push("".concat(e," samples ").concat(s.uvSet,", not st")),s.unsupported&&l.gaps.push("".concat(e,": ").concat(s.unsupported)),y.add(e),"alphaMap"===t&&"a"===s.channel&&(null===(o=f.base_color)||void 0===o?void 0:o.path)===s.path||c(t,s))};if(m){const t=(e,t)=>t(n[e])?n[e]:he[e],o=e=>"number"===typeof e,s=e=>Array.isArray(e)&&3===e.length,r=t("base_weight",o);l.color=t("base_color",s).map(e=>e*r),l.metalness=t("base_metalness",o),l.roughness=t("specular_roughness",o),l.opacity=t("geometry_opacity",o);const a=void 0!==n.emission_color||n.emission_luminance>0;l.emissive=a?[...t("emission_color",s)]:[0,0,0],p=h.has("geometry_opacity");for(const[e,n]of Object.entries(q))v(e,n);for(const e of h)Object.hasOwn(he,e)&&!y.has(e)&&l.gaps.push("".concat(e,": its map is not read (factor only)"));"number"!==typeof e.normalScale||y.has("geometry_normal")||l.gaps.push("geometry_normal: its map is not read")}for(const[b,w]of Object.entries(J))v(b,w);l.alphaMode=a.alphaMode||((null===e||void 0===e?void 0:e.opacityThreshold)>0?"MASK":p||l.opacity<1?"BLEND":"OPAQUE"),"MASK"===l.alphaMode&&(l.alphaTest=null!==(r=a.alphaCutoff)&&void 0!==r?r:(null===e||void 0===e?void 0:e.opacityThreshold)>0?e.opacityThreshold:.5),"BLEND"===l.alphaMode&&(l.transparent=!0,l.depthWrite=!1),"boolean"===typeof a.doubleSided&&(l.doubleSided=a.doubleSided),"number"===typeof(null===e||void 0===e?void 0:e.normalScale)&&(l.normalScale=e.normalScale),"number"===typeof a.occlusionStrength&&(l.aoMapIntensity=a.occlusionStrength);for(const[b,w]of Object.entries(me))void 0!==n[b]&&(l.physical[w]=n[b]);for(const b of h)me[b]&&!y.has(b)&&l.gaps.push("".concat(b,": its map is not read (factor only)"));n.fuzz_weight>0&&(l.physical.sheen=1),"number"===typeof a.thickness&&(l.physical.thickness=a.thickness),n.geometry_thin_walled&&(l.physical.thickness=0),"number"===typeof a.anisotropyRotation&&(l.physical.anisotropyRotation=a.anisotropyRotation);const g=n.emission_luminance;return"number"===typeof g&&g>0&&(l.emissiveIntensity=g,m||(l.emissive=l.emissive.map(e=>e/g))),l}function ve(e){const t=(e||[]).filter(e=>"fallback"===(null===e||void 0===e?void 0:e.kind)&&e.path&&!fe(e));return t.length?{code:"material-fallback",path:t[0].path,message:"".concat(t.length," material(s) have no ")+"UsdPreviewSurface, OpenPBR surface or supported MDL material and show as grey"}:null}function ge(e){var t;const o=[];return null!==e&&void 0!==e&&e.openpbr||o.push("openpbr: specular weight/colour, ior, transmission, coat, fuzz, anisotropy, emission luminance"),null!==e&&void 0!==e&&e.simready||o.push("simready: alphaMode, alphaCutoff, doubleSided, occlusionStrength, thickness, anisotropyRotation"),"number"!==typeof(null===e||void 0===e?void 0:e.normalScale)&&null!==e&&void 0!==e&&null!==(t=e.maps)&&void 0!==t&&t.normal&&o.push("normal scale"),o}let be=null,we=null,Me=null,Se=null,Ae=0,xe=null,_e=0,ke=0;function Le(e){Se&&Ee(Se),Se=null,we=null,Me=null,xe=null,_e=0,ke=0,be=e||null}const Ue=()=>!!be,Pe=function(e,t){let o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return new R("fetch","webUsdLoader: the reader's WASM did not load: ".concat(t),(0,r.A)({url:String(e)},o))};async function Re(e){let t,o;try{t=await fetch(e,{credentials:"same-origin"})}catch(s){throw Pe(e,(null===s||void 0===s?void 0:s.message)||String(s),{cause:s})}if(!t.ok)throw Pe(e,"HTTP ".concat(t.status),{status:t.status});if("function"===typeof WebAssembly.compileStreaming&&(e=>{var t,o;return"application/wasm"===String((null===e||void 0===e||null===(t=e.headers)||void 0===t||null===(o=t.get)||void 0===o?void 0:o.call(t,"content-type"))||"").split(";")[0].trim().toLowerCase()})(t))try{return await WebAssembly.compileStreaming(t)}catch(s){throw s instanceof TypeError?Pe(e,s.message||String(s),{cause:s}):s}try{o=await t.arrayBuffer()}catch(s){throw Pe(e,(null===s||void 0===s?void 0:s.message)||String(s),{cause:s})}if(!(0,n.Hr)(o))throw new Error("not WebAssembly (a page served in its place?)");return WebAssembly.compile(o)}function Oe(){if(!be)return Promise.reject(new R("reader","webUsdLoader: no reader set"));if(!we){const e=performance.now(),t=be,o=Promise.resolve().then(()=>t.compile?t.compile():Re(t.wasmUrl)).then(t=>(Me=performance.now()-e,t)).catch(e=>{if(O(e)&&"fetch"===e.code)throw e;throw E("reader","webUsdLoader: could not compile the reader's WASM: ".concat((null===e||void 0===e?void 0:e.message)||e),{cause:e,url:t.wasmUrl&&String(t.wasmUrl)})});o.catch(()=>{we===o&&(we=null)}),we=o}return we}function Be(){let e;try{e=be.createWorker?be.createWorker():new Worker(be.workerUrl,{type:"module"})}catch(t){throw E("reader","webUsdLoader: could not start the reader's worker: ".concat((null===t||void 0===t?void 0:t.message)||t),{cause:t})}return Ae+=1,{worker:e,dead:!1,ready:Promise.resolve(!0)}}function Ee(e){e&&!e.dead&&(e.dead=!0,e.worker.onmessage=null,e.worker.onerror=null,e.worker.terminate())}const Ce={fetch:"fetch",compose:"compose",aborted:"aborted",worker:"reader"};function We(e,t,o,s){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};return new Promise((n,a)=>{const{worker:i}=e;let l=0,c=!1;r.posted=!1;const u=t=>{c||(c=!0,null===s||void 0===s||s.removeEventListener("abort",d),i.onmessage=null,i.onerror=null,t?(r.posted&&Ee(e),a(t)):n(l))};function d(){u(new R("aborted","webUsdLoader: the load was aborted",{url:t.url}))}if(null!==s&&void 0!==s&&s.aborted)d();else{null===s||void 0===s||s.addEventListener("abort",d,{once:!0}),i.onmessage=e=>{var t,s,r;let{data:n}=e;if(!c&&n)if("texture"===n.type&&(null===(t=n.bitmap)||void 0===t||null===(s=t.close)||void 0===s||s.call(t)),"scene"===n.type&&(l=(null===(r=n.stats)||void 0===r?void 0:r.wasmMemoryBytes)||0),"done"!==n.type)if("error"!==n.type)try{o(n)}catch(a){u(O(a)?a:new R("compose","webUsdLoader: could not build the scene: ".concat((null===a||void 0===a?void 0:a.message)||a),{cause:a}))}else u(new R(Ce[n.code]||"compose","webUsdLoader: ".concat(n.message),{url:n.url,status:n.status}));else u(null)},i.onerror=e=>{var o;null===e||void 0===e||null===(o=e.preventDefault)||void 0===o||o.call(e),(e=>!(!e||!(e.message||e.filename||e.error)))(e)?u(E("reader","webUsdLoader: the reader's worker failed: ".concat((null===e||void 0===e?void 0:e.message)||"error"))):u(new R("fetch","webUsdLoader: the reader's worker did not load its script",{url:t.url}))};try{i.postMessage(t),r.posted=!0}catch(p){u(new R("reader","webUsdLoader: could not post to the reader's worker: ".concat((null===p||void 0===p?void 0:p.message)||p),{cause:p}))}}})}function Ie(e,t){e.dead||(Se||t>U?Ee(e):Se=e)}let Te=null;function je(){if(!be)return Promise.resolve(!1);if(Se){const e=Se;return e.ready.then(t=>t&&!e.dead)}if(Te)return Te;const e=Oe().then(e=>{if(Se)return Se.ready;if(ke>0)return!0;const t=Be();return t.ready=We(t,(e=>({url:L+k,wasmModule:e,textures:P,files:new Map([[k,new Blob(['#usda 1.0\n(\n defaultPrim = "Asset"\n)\n\ndef Xform "Asset"\n{\n}\n'],{type:"text/plain"})]])}))(e),()=>{}).then(()=>!0,()=>(Se===t&&(Se=null),Ee(t),!1)),Se=t,t.ready}).then(e=>{var t;return e&&null!==(t=be)&&void 0!==t&&t.warm?function(){var e;const t=null===(e=be)||void 0===e?void 0:e.warm;return null===t||void 0===t||!t.assetUrl||!xe&&_e>0?Promise.resolve(!1):(xe||(xe=He(t.assetUrl,(0,r.A)({warm:!0,tier:1,ktx2Hint:t.ktx2Hint||null,compact:null!==(o=t.compact)&&void 0!==o?o:null,ktx2:t.ktx2||(()=>(0,n.B4)())},t.fetchFn?{fetchFn:t.fetchFn}:{})).then(e=>(e.dispose(),!0),()=>!1)),xe);var o}().then(()=>!0):e}).catch(()=>!1).finally(()=>{Te===e&&(Te=null)});return Te=e,e}function Fe(e){let{ktx2:t,fetchFn:o,headers:s,signal:r,t0:n}=e;const a=new Map;let i=null;const l=(e,l)=>{const c=F(e);if(a.has(c))return a.get(c);const u={url:e,hinted:l,used:!1,startMs:performance.now()-n,readyMs:null,texture:null,error:null,derived:new Map};return u.promise=Promise.all([(i||(i=Promise.resolve("function"===typeof t?t():t).then(e=>{if(!e)throw new R("textures","webUsdLoader: maps need the page's KTX2 loader");return e})),i),Promise.resolve(o(e,{signal:r,headers:s,credentials:"same-origin"})).then(t=>{if(!t.ok)throw new R("textures","webUsdLoader: map ".concat(e,": HTTP ").concat(t.status),{url:e,status:t.status});return t.arrayBuffer()})]).then(e=>{let[t,o]=e;return((e,t)=>new Promise((o,s)=>e.parse(t,o,s)))(t,o)}).then(e=>(u.texture=e,u.readyMs=performance.now()-n,e)).catch(t=>{throw u.error=O(t)?t:new R(null!==r&&void 0!==r&&r.aborted?"aborted":"textures","webUsdLoader: map ".concat(e,": ").concat((null===t||void 0===t?void 0:t.message)||t),{cause:t,url:e}),u.error}),u.promise.catch(()=>{}),a.set(c,u),u};return{files:a,start:l,use(e){const t=l(e,!1);return t.used=!0,t},settle:()=>Promise.all([...a.values()].filter(e=>e.used).map(e=>e.promise)),texture(e,t,o,s,r){const n=a.get(F(t)),i=n.texture,l="color"===o?e.SRGBColorSpace:e.NoColorSpace,c=t=>"mirror"===t?e.MirroredRepeatWrapping:"clamp"===t?e.ClampToEdgeWrapping:e.RepeatWrapping,u="".concat(l,"|").concat(s.join(","),"|").concat(r?r.join(","):"");if(n.derived.size||(i.flipY=!1,i.colorSpace=l,i.magFilter=e.LinearFilter,i.minFilter=e.LinearMipmapLinearFilter,i.wrapS=c(s[0]),i.wrapT=c(s[1]),r&&(i.matrixAutoUpdate=!1,i.matrix.set(...r)),i.needsUpdate=!0,n.derived.set(u,i)),!n.derived.has(u)){const e=i.clone();e.colorSpace=l,e.wrapS=c(s[0]),e.wrapT=c(s[1]),e.matrixAutoUpdate=!r,r?e.matrix.set(...r):e.matrix.identity(),e.needsUpdate=!0,n.derived.set(u,e)}return n.derived.get(u)},all:()=>[...a.values()].flatMap(e=>[...e.derived.values()]),unused:()=>[...a.values()].filter(e=>!e.used&&e.texture).map(e=>e.texture)}}const Ne=e=>"".concat((null===e||void 0===e?void 0:e.path)||""," ").concat((null===e||void 0===e?void 0:e.message)||"").includes(x);function ze(e,t){let{maps:o,base:r,tier:n,compact:a=null,normals:i="int8",collidersHanded:l=!1}=t;const c=e=>!l&&Ne(e),u=new e.Group;u.name="usd";const d=new Map,p=[],m=new Map,h=[],f=[];let y=null,v=[],g=new Map,b=!1;const w={meshes:0,triangles:0,loose:0},S={compact:!1,geometries:0,position:0,normal:0,uv:0,floatBytes:0,uploadBytes:0,ms:0},A=t=>{if(!d.has(t)){const o=new e.Group;o.name=t,d.set(t,o),u.add(o)}return d.get(t)},x=function(t,o,s){let n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null;const i=v[t],l=n&&Object.keys(i.maps).length?n.join(","):"",c=null!==a&&i.physical.thickness>0?a:"",u="".concat(t,"|").concat(o,"|").concat(s,"|").concat(l,"|").concat(c);if(!m.has(u)){const t=function(e,t,o){var s;let r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];const n=new e.MeshPhysicalMaterial;n.name=t.name,n.color.setRGB(t.color[0],t.color[1],t.color[2],e.LinearSRGBColorSpace),n.opacity=t.opacity,n.roughness=t.roughness,n.metalness=t.metalness,n.emissive.setRGB(t.emissive[0],t.emissive[1],t.emissive[2],e.LinearSRGBColorSpace),n.emissiveIntensity=t.emissiveIntensity,n.transparent=t.transparent,n.depthWrite=t.depthWrite,n.alphaTest=t.alphaTest,n.side=(null!==(s=t.doubleSided)&&void 0!==s?s:o)?e.DoubleSide:e.FrontSide,n.normalScale.set(t.normalScale,r?-t.normalScale:t.normalScale),r&&(n.clearcoatNormalScale.y*=-1),n.aoMapIntensity=t.aoMapIntensity;for(const[i,l]of Object.entries(t.physical)){var a;null!==(a=n[i])&&void 0!==a&&a.isColor&&Array.isArray(l)?n[i].setRGB(l[0],l[1],l[2],e.LinearSRGBColorSpace):"number"===typeof l&&(n[i]=l)}return n}(e,i,o,s);""!==c&&(t.thickness=ae(i.physical.thickness,a));for(const[e,o]of Object.entries(i.maps)){const s=l?o.matrix?ce(o.matrix,n).map(e=>e+0):n:o.matrix;h.push([t,e,z(o.path,r),o.role,o.wrap,s])}m.set(u,t)}return m.get(u)};let _=null,k=[];return{root:u,bodies:d,geometries:p,materials:m,warnings:f,receive:t=>{if("meta"===t.type)(e=>{y=e.meta,b=Z(a,y),S.compact=b,v=(y.materials||[]).map(ye);for(const t of v){for(const e of t.gaps)f.push({code:"material",message:"".concat(t.name,": ").concat(e)});for(const e of Object.values(t.maps))o.use(z(e.path,r))}g=new Map;for(const t of y.instances||[]){const e=I(t.path);e&&A(e.body),g.has(t.geometry)||g.set(t.geometry,[]),g.get(t.geometry).push(t)}for(const t of y.warnings||[])if("material-fallback"===t.code){const e=ve(y.materials);e&&f.push(e)}else c(t)||f.push(t)})(t);else if("geometry"===t.type)(t=>{var o;let{index:s,meta:r,arrays:n}=t;if(!r)return;if(!n)throw new Error("a geometry without its arrays");const a=new e.BufferGeometry,l=performance.now(),c=le(n,b,i);S.ms+=performance.now()-l;const d=c.positionLattice;let m=null;if(d){a.setAttribute("position",new e.InterleavedBufferAttribute(new e.InterleavedBuffer(d.array,4),3,0,!1));const t=2**d.k;m=(new e.Matrix4).makeScale(t,t,t).setPosition(d.offset[0]*t,d.offset[1]*t,d.offset[2]*t),a.boundingBox=new e.Box3(new e.Vector3(...d.min),new e.Vector3(...d.max))}else a.setAttribute("position",new e.BufferAttribute(c.position,3)),a.boundingBox=(new e.Box3).setFromArray(r.bounds);null!==(o=c.normal)&&void 0!==o&&o.bits?a.setAttribute("normal",new e.InterleavedBufferAttribute(new e.InterleavedBuffer(c.normal.array,4),3,0,!0)):c.normal&&a.setAttribute("normal",new e.BufferAttribute(c.normal,3)),c.uvs.forEach((t,o)=>a.setAttribute(o?"uv".concat(o):"uv",new e.BufferAttribute(t.array||t,2,!1)));const h=c.uvLattice?ne(c.uvLattice):null;var y;a.setIndex(new e.BufferAttribute(n.indices,1)),a.boundingSphere=a.boundingBox.getBoundingSphere(new e.Sphere),b&&(S.geometries+=1,S.position+=d?1:0,S.normal+=null!==(y=c.normal)&&void 0!==y&&y.bits?1:0,S.uv+=h?1:0),S.floatBytes+=c.bytes.float,S.uploadBytes+=c.bytes.upload,r.groups.length>1&&r.groups.forEach((e,t)=>{let[o,s]=e;return a.addGroup(o,s,t)}),r.hasColors&&f.push({code:"vertex-colors",message:"geometry ".concat(s,": vertex colours ignored")}),p.push(a);const v=r.groups.reduce((e,t)=>{let[,o]=t;return e+o/3},0),M=void 0===a.attributes.tangent;for(const i of g.get(s)||[]){const t=r.groups.map(e=>{let[,,t]=e;return x(void 0!==t&&Object.hasOwn(i.subsets||{},t)?i.subsets[t]:i.material,!!i.doubleSided,M,h,d?d.k:null)}),o=new e.Mesh(a,t.length>1?t:t[0]),s=I(i.path);o.name=s?s.name:i.path.split("/").pop(),o.matrix.fromArray(i.matrix),m&&o.matrix.multiply(m),o.matrix.decompose(o.position,o.quaternion,o.scale),s?A(s.body).add(o):(w.loose+=1,u.add(o)),w.meshes+=1,w.triangles+=v}})(t);else if("collider"===t.type){var n,l;k.push({meta:t.meta,points:(null===(n=t.arrays)||void 0===n?void 0:n.points)||null,indices:(null===(l=t.arrays)||void 0===l?void 0:l.indices)||null})}else if("scene"===t.type){const e=t.stats||{},{warnings:o}=e,r=(0,s.A)(e,M);_=r;for(const t of o||[])c(t)||f.push(t)}},attachMaps:()=>{for(const[t,s,r,n,a,i]of h)t[s]=o.texture(e,r,n,a,i);for(const e of m.values())e.needsUpdate=!0},counts:w,attrs:S,takeColliders:()=>{const e=k;return k=[],e},stats:()=>_,meta:()=>y,tier:n}}function De(e,t,o){let s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:[],{colliders:r="read"}=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};const n="skip"===r,c={asked:!!e,read:!1,colliders:n&&e?"not read":(null===o||void 0===o?void 0:o.length)||0,problems:[]};if(!e)return{articulation:null,info:c};if(null===t||void 0===t||!t.physics){const e=[...(null===t||void 0===t?void 0:t.warnings)||[],...s].find(e=>"physics"===(null===e||void 0===e?void 0:e.code));return c.problems.push(e?"the reader could not read it: ".concat(e.message||"no reason given"):"the reader reports no physics (a reader without UsdPhysics)"),{articulation:null,info:c}}c.read=!0;let p=null;try{p=function(e){var t,o;let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];g(e&&Array.isArray(e.prims),"no physics in the reader's meta"),g(!e.root||e.root.path===a,"the default prim is ".concat(null===(t=e.root)||void 0===t?void 0:t.path,", not ").concat(a));const r=b(new Map(e.prims.map(e=>[e.path,e])).get(a)),n=JSON.parse(JSON.stringify(u)),c={};for(const[a,[i,l]]of Object.entries(d))h(r,i)&&(c[a]=l?JSON.parse(r[i]):r[i]);const p=null===(o=e.root)||void 0===o?void 0:o.extentsHint;Array.isArray(p)&&p.length>=2&&(n.bbox=[[...p[0]],[...p[1]]]),h(c,"kind")&&(n.kind=c.kind,delete c.kind);const m="robot"===n.kind,v=[],M=new Set;for(const a of e.prims){const e=f(a.path);if(y(a.path)!==i||!e.startsWith("b")||"Xform"!==a.type)continue;const t=b(a),o=new Set(a.apiSchemas||[]);g(h(t,"simready:role")&&h(t,"simready:colliders"),"".concat(a.path,": no simready:role / simready:colliders")),v.push({id:e,role:t["simready:role"],rigid:o.has("PhysicsRigidBodyAPI"),mass_kg:o.has("PhysicsMassAPI")&&h(t,"physics:mass")?t["physics:mass"]:null,colliders:Math.trunc(Number(t["simready:colliders"]))}),M.add(e)}const S=[];for(const a of s){var A;const e=(null===a||void 0===a||null===(A=a.meta)||void 0===A?void 0:A.path)||"",t=e.split("/");if(6!==t.length||y(y(y(e)))!==i||"collision"!==t[4])continue;if(!M.has(t[3]))continue;const o=a.points||new Float32Array(0),s=a.indices||new Uint32Array(0),r=[];for(let a=0;a+2<o.length;a+=3)r.push([o[a],o[a+1],o[a+2]]);const n=[];for(let a=0;a<s.length;a+=3)n.push(Array.from(s.subarray(a,Math.min(a+3,s.length))));S.push([t[5],{body:t[3],points:r,faces:n}])}S.sort((e,t)=>e[0]<t[0]?-1:e[0]>t[0]?1:0);const x=[],_=[];for(const a of e.prims){if(y(a.path)!==l)continue;const{row:e,tree:t}=w(a,m);x.push(e),t&&_.push(t)}return _.sort((e,t)=>e[0]-t[0]),n.sequence=h(c,"sequence")?c.sequence:null,n.order=h(c,"order")?c.order:[],delete c.sequence,delete c.order,n.bodies=v,n.joints=x,n.tree=_.map(e=>{let[,t]=e;return t}),n.colliders=S.map(e=>{let[,t]=e;return t}),n.selftest=h(c,"selftest")?c.selftest:[],delete c.selftest,Object.assign(n,c),n}(t.physics,n?[]:o||[]),"missing"===r&&c.problems.push("".concat(x," did not load")),n||c.problems.push(...function(e){const t=((null===e||void 0===e?void 0:e.bodies)||[]).reduce((e,t)=>e+(Number(t.colliders)||0),0),o=((null===e||void 0===e?void 0:e.colliders)||[]).length;return t===o?[]:["".concat(t," colliders declared, ").concat(o," read")]}(p))}catch(m){c.problems.push((null===m||void 0===m?void 0:m.message)||String(m))}return c.problems.length&&(p=null,s.push({code:"physics",message:"articulation not read from the USD: ".concat(c.problems.join("; "))})),{articulation:p,info:c}}async function Ge(e,t,o){let s,{signal:r,headers:n}=o;try{s=await e(t,{signal:r,headers:n,credentials:"same-origin"})}catch(a){throw new R(null!==r&&void 0!==r&&r.aborted?"aborted":"fetch","webUsdLoader: ".concat(t,": ").concat((null===a||void 0===a?void 0:a.message)||a),{cause:a,url:t})}if(!s.ok)throw new R("fetch","webUsdLoader: ".concat(t,": HTTP ").concat(s.status),{url:t,status:s.status});return s.blob()}async function He(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{tier:s=1,ktx2:n=null,ktx2Hint:a=null,signal:i=null,headers:l,onStage:u=null,compact:d=null,normals:p="int8",physics:m=!1,colliders:h=!0,onPhysics:f=null}=t,y=!!m&&1===s,v=y&&!!h,g=t.fetchFn||function(){return fetch(...arguments)},b=performance.now(),w={},M=e=>{w[e]=Math.round(10*(performance.now()-b))/10,null===u||void 0===u||u(e,w[e])};if(!be)throw new R("reader","webUsdLoader: no reader set");if(null!==i&&void 0!==i&&i.aborted)throw new R("aborted","webUsdLoader: the load was aborted",{url:e});const A=new URL(e,"undefined"===typeof window?void 0:window.location.href).href,k=new AbortController,U=()=>k.abort(i.reason);null===i||void 0===i||i.addEventListener("abort",U,{once:!0});const B=Fe({ktx2:n,fetchFn:g,headers:l,signal:k.signal,t0:b});for(const o of D(a,A).values())B.start(o,!0);a&&M("hintStarted");const E=j(s),C=Promise.all(E.map(e=>Ge(g,e===S?A:N(e,A),{signal:k.signal,headers:l})));C.catch(()=>{});const W=v?Ge(g,N(x,A),{signal:k.signal,headers:l}).catch(()=>null):Promise.resolve(null),I=Promise.all([o.e(111),o.e(628)]).then(o.bind(o,628)),F=null===Me,z=async function(){const e=await Oe(),t=Se;return Se=null,t&&(await t.ready,!t.dead)?{slot:t,module:e}:{slot:Be(),module:e}}();z.catch(()=>{});let G=null,H=!1;const q={posted:!1};let J=null;const Y=()=>{if(k.signal.aborted)throw new R("aborted","webUsdLoader: the load was aborted",{url:e})},K=!t.warm;K&&(_e+=1,ke+=1);try{const[{slot:t,module:o},n,a,i]=await Promise.all([z,C,I,W]);G=t,H=!0,F&&null!==Me&&(w.wasmCompile=Math.round(10*Me)/10),M("ready"),Y(),J=ze(a,{maps:B,base:A,tier:s,compact:d,normals:p,collidersHanded:!!i});const l=new Map([[_,new Blob([T(s)],{type:"text/plain"})]]);E.forEach((e,t)=>l.set(e,n[t])),i&&l.set(x,i);const u={url:L+_,wasmModule:o,textures:P,files:l};y&&(u.physics={namespaces:c});if(Ie(G,await We(G,u,J.receive,k.signal,q)),G=null,M("geometry"),Y(),!J.bodies.size)throw new R("shape","webUsdLoader: no piece under /Asset/Bodies",{url:e});const m=De(y,J.meta(),J.takeColliders(),J.warnings,{colliders:v?i?"read":"missing":"skip"});if(y){M("physics");try{null===f||void 0===f||f(m)}catch(X){}}await B.settle(),Y(),M("textures"),Y(),J.attachMaps();for(const e of B.unused())e.dispose();M("total"),Y();const h=J.stats()||{},g=B.all(),b=[...B.files.values()],S=()=>{J.geometries.forEach(e=>e.dispose());for(const e of J.materials.values())e.dispose();g.forEach(e=>e.dispose())};return{scene:J.root,bodies:J.bodies,materials:[...J.materials.values()],textures:g,articulation:m.articulation,info:{tier:s,meshes:J.counts.meshes,triangles:J.counts.triangles,loose:J.counts.loose,bodies:J.bodies.size,geometries:J.geometries.length,materials:J.materials.size,maps:b.filter(e=>e.used).length,hinted:b.filter(e=>e.hinted).length,hintMissed:b.filter(e=>e.used&&!e.hinted).length,hintUnused:b.filter(e=>!e.used).length,mapFiles:b.map(e=>({url:e.url,hinted:e.hinted,used:e.used,startMs:Math.round(e.startMs),readyMs:null===e.readyMs?null:Math.round(e.readyMs)})),reader:h,warnings:J.warnings,attributes:(0,r.A)((0,r.A)({},J.attrs),{},{ms:Math.round(10*J.attrs.ms)/10}),physics:m.info},timings:w,dispose:S}}catch(V){if(k.abort(),G?q.posted?Ee(G):Ie(G,0):H||z.then(e=>Ie(e.slot,0),()=>{}),J){J.geometries.forEach(e=>e.dispose());for(const e of J.materials.values())e.dispose()}const t=new Set(B.all());if(B.files.forEach(e=>{e.texture?t.add(e.texture):e.promise.then(e=>e.dispose(),()=>{})}),t.forEach(e=>e.dispose()),O(V))throw V;throw new R(null!==i&&void 0!==i&&i.aborted?"aborted":"compose","webUsdLoader: ".concat((null===V||void 0===V?void 0:V.message)||V),{cause:V,url:e})}finally{null===i||void 0===i||i.removeEventListener("abort",U),K&&(ke=Math.max(0,ke-1))}}function qe(){Le(null),Te=null,Ae=0,B=null}const Je=()=>({spawned:Ae,kept:!!Se,compiled:!!we})}}]);
|
services/explorer/dist/static/js/main.3b513bd4.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
services/explorer/dist/static/js/main.3b513bd4.js.LICENSE.txt
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* @license React
|
| 3 |
+
* react-dom.production.min.js
|
| 4 |
+
*
|
| 5 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
| 6 |
+
*
|
| 7 |
+
* This source code is licensed under the MIT license found in the
|
| 8 |
+
* LICENSE file in the root directory of this source tree.
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* @license React
|
| 13 |
+
* react-jsx-runtime.production.min.js
|
| 14 |
+
*
|
| 15 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
| 16 |
+
*
|
| 17 |
+
* This source code is licensed under the MIT license found in the
|
| 18 |
+
* LICENSE file in the root directory of this source tree.
|
| 19 |
+
*/
|
| 20 |
+
|
| 21 |
+
/**
|
| 22 |
+
* @license React
|
| 23 |
+
* react.production.min.js
|
| 24 |
+
*
|
| 25 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
| 26 |
+
*
|
| 27 |
+
* This source code is licensed under the MIT license found in the
|
| 28 |
+
* LICENSE file in the root directory of this source tree.
|
| 29 |
+
*/
|
| 30 |
+
|
| 31 |
+
/**
|
| 32 |
+
* @license React
|
| 33 |
+
* scheduler.production.min.js
|
| 34 |
+
*
|
| 35 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
| 36 |
+
*
|
| 37 |
+
* This source code is licensed under the MIT license found in the
|
| 38 |
+
* LICENSE file in the root directory of this source tree.
|
| 39 |
+
*/
|
services/explorer/dist/static/usd-reader/00c663a/esm/errors.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/** Why a load failed: `aborted`, `fetch` (root layer or a resource limit), `compose`, `worker` or `webgl`. */
|
| 2 |
+
export class UsdLoadError extends Error {
|
| 3 |
+
name = "UsdLoadError";
|
| 4 |
+
code;
|
| 5 |
+
constructor(code, message, { url, status, cause } = {}) {
|
| 6 |
+
super(message, cause === undefined ? undefined : { cause });
|
| 7 |
+
this.code = code;
|
| 8 |
+
if (url !== undefined) {
|
| 9 |
+
this.url = url;
|
| 10 |
+
}
|
| 11 |
+
if (status !== undefined) {
|
| 12 |
+
this.status = status;
|
| 13 |
+
}
|
| 14 |
+
}
|
| 15 |
+
}
|
services/explorer/dist/static/usd-reader/00c663a/esm/errors.js.br
ADDED
|
Binary file (239 Bytes). View file
|
|
|
services/explorer/dist/static/usd-reader/00c663a/esm/hub-prefetch.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// The layers of a Hub package, listed with one tree-API call, so a load can
|
| 2 |
+
// request them all at once instead of discovering them a round trip at a time.
|
| 3 |
+
const RESOLVE = /^(https:\/\/(?:huggingface\.co|hf\.co))\/((?:datasets\/|spaces\/)?)([^/?#]+\/[^/?#]+)\/resolve\/([^/?#]+)\/([^?#]+)$/;
|
| 4 |
+
const LAYER = /\.(usd|usda|usdc)$/i;
|
| 5 |
+
const SIMREADY_PACKAGE = "com.nvidia.simready.packaging.json";
|
| 6 |
+
const MAX_FILES = 256;
|
| 7 |
+
const MAX_BYTES = 64 * 2 ** 20;
|
| 8 |
+
/**
|
| 9 |
+
* The USD layers of the package holding a Hub `resolve` URL, as `{ url, size }`:
|
| 10 |
+
* the directory with a SimReady packaging manifest among the root's parent
|
| 11 |
+
* and grandparent, else everything under the root's own directory. `eager`
|
| 12 |
+
* when a manifest declares the package, so its layers are worth requesting
|
| 13 |
+
* before the root is read. No layers, without a request, for a root at the
|
| 14 |
+
* top of its repo or any other URL, and none if the listing fails: the load then discovers layers as usual.
|
| 15 |
+
*/
|
| 16 |
+
export async function hubPackageLayers(rootUrl, request) {
|
| 17 |
+
const match = rootUrl.split(/[?#]/)[0].match(RESOLVE);
|
| 18 |
+
const none = { layers: [], eager: false };
|
| 19 |
+
if (!match) {
|
| 20 |
+
return none;
|
| 21 |
+
}
|
| 22 |
+
const [, origin, prefix, repo, revision, path] = match;
|
| 23 |
+
const parent = path.split("/").slice(0, -1);
|
| 24 |
+
// A root at the top of a repo would list, and preload, the whole repo.
|
| 25 |
+
if (!parent.length) {
|
| 26 |
+
return none;
|
| 27 |
+
}
|
| 28 |
+
const listed = parent.length > 1 ? parent.slice(0, -1) : parent;
|
| 29 |
+
try {
|
| 30 |
+
const response = await request(`${origin}/api/${prefix || "models/"}${repo}/tree/${revision}/${listed.join("/")}?recursive=true`);
|
| 31 |
+
if (!response.ok) {
|
| 32 |
+
return none;
|
| 33 |
+
}
|
| 34 |
+
const entries = await response.json();
|
| 35 |
+
const decoded = parent.map(decodeURIComponent);
|
| 36 |
+
const manifest = [decoded, decoded.slice(0, -1)].find((dir) => dir.length >= listed.length && entries.some((e) => e.path === [...dir, SIMREADY_PACKAGE].join("/")));
|
| 37 |
+
const depth = (manifest ?? decoded).length;
|
| 38 |
+
const packageDir = decoded
|
| 39 |
+
.slice(0, depth)
|
| 40 |
+
.map((name) => name + "/")
|
| 41 |
+
.join("");
|
| 42 |
+
// As the root spells it, so URLs match the ones composition resolves.
|
| 43 |
+
const base = `${origin}/${prefix}${repo}/resolve/${revision}/${parent
|
| 44 |
+
.slice(0, depth)
|
| 45 |
+
.map((name) => name + "/")
|
| 46 |
+
.join("")}`;
|
| 47 |
+
const layers = [];
|
| 48 |
+
let bytes = 0;
|
| 49 |
+
for (const { type, path: file, size } of entries) {
|
| 50 |
+
if (type !== "file" || !file.startsWith(packageDir) || !LAYER.test(file)) {
|
| 51 |
+
continue;
|
| 52 |
+
}
|
| 53 |
+
if (layers.length >= MAX_FILES || bytes + size > MAX_BYTES) {
|
| 54 |
+
continue;
|
| 55 |
+
}
|
| 56 |
+
bytes += size;
|
| 57 |
+
layers.push({
|
| 58 |
+
url: new URL(file.slice(packageDir.length).replace(/[%#?]/g, encodeURIComponent), base).href,
|
| 59 |
+
size,
|
| 60 |
+
});
|
| 61 |
+
}
|
| 62 |
+
return { layers, eager: !!manifest };
|
| 63 |
+
}
|
| 64 |
+
catch {
|
| 65 |
+
return none;
|
| 66 |
+
}
|
| 67 |
+
}
|
| 68 |
+
/**
|
| 69 |
+
* A Hub `resolve` URL pinned to the commit its branch or tag points at now,
|
| 70 |
+
* so every layer and texture of one load (all resolved against the root)
|
| 71 |
+
* comes from the same commit even if the repo is pushed to meanwhile. Unchanged,
|
| 72 |
+
* without a request, for a commit or any other URL, and if the lookup fails.
|
| 73 |
+
*/
|
| 74 |
+
export async function pinHubRevision(rootUrl, request) {
|
| 75 |
+
const match = rootUrl.split(/[?#]/)[0].match(RESOLVE);
|
| 76 |
+
if (!match) {
|
| 77 |
+
return rootUrl;
|
| 78 |
+
}
|
| 79 |
+
const [, origin, prefix, repo, revision] = match;
|
| 80 |
+
if (/^[0-9a-f]{40}$/.test(revision)) {
|
| 81 |
+
return rootUrl;
|
| 82 |
+
}
|
| 83 |
+
try {
|
| 84 |
+
const response = await request(`${origin}/api/${prefix || "models/"}${repo}/revision/${revision}?expand%5B%5D=sha`);
|
| 85 |
+
const { sha } = response.ok ? await response.json() : {};
|
| 86 |
+
if (!/^[0-9a-f]{40}$/.test(sha ?? "")) {
|
| 87 |
+
return rootUrl;
|
| 88 |
+
}
|
| 89 |
+
return rootUrl.replace(`/resolve/${revision}/`, `/resolve/${sha}/`);
|
| 90 |
+
}
|
| 91 |
+
catch {
|
| 92 |
+
return rootUrl;
|
| 93 |
+
}
|
| 94 |
+
}
|
services/explorer/dist/static/usd-reader/00c663a/esm/hub-prefetch.js.br
ADDED
|
Binary file (1.38 kB). View file
|
|
|
services/explorer/dist/static/usd-reader/00c663a/esm/load-core.js
ADDED
|
@@ -0,0 +1,760 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { UsdLoadError } from "./errors.js";
|
| 2 |
+
/** The load options' defaults, and the largest image side read at all. SECURITY.md documents the limits. */
|
| 3 |
+
export const DEFAULTS = {
|
| 4 |
+
textures: "preview",
|
| 5 |
+
maxTextureSize: 1024,
|
| 6 |
+
maxConcurrentFetches: 16,
|
| 7 |
+
maxLayerBytes: 768 * 2 ** 20,
|
| 8 |
+
maxLayers: 1024,
|
| 9 |
+
maxInstances: 100000,
|
| 10 |
+
maxTriangles: 20e6,
|
| 11 |
+
maxTextureBytes: 512 * 2 ** 20,
|
| 12 |
+
maxImageSize: 16384,
|
| 13 |
+
};
|
| 14 |
+
/** Loads and composes the stage at `rootUrl`. */
|
| 15 |
+
export async function composeStage({ UsdLoader, fetchBytes, rootUrl, maxConcurrentFetches = DEFAULTS.maxConcurrentFetches, maxLayerBytes = DEFAULTS.maxLayerBytes, maxLayers = DEFAULTS.maxLayers, maxInstances = DEFAULTS.maxInstances, allowedOrigins, preload, onProgress = () => { }, physics, }) {
|
| 16 |
+
const root = rootUrl.split(/[?#]/)[0];
|
| 17 |
+
const urlOf = (path) => (path === root ? rootUrl : path);
|
| 18 |
+
const loader = new UsdLoader();
|
| 19 |
+
if (physics) {
|
| 20 |
+
loader.setPhysics([...physics]);
|
| 21 |
+
}
|
| 22 |
+
const stats = {
|
| 23 |
+
layers: 0,
|
| 24 |
+
layerBytes: 0,
|
| 25 |
+
missing: 0,
|
| 26 |
+
rounds: 0,
|
| 27 |
+
fetchMs: 0,
|
| 28 |
+
parseMs: 0,
|
| 29 |
+
composeMs: 0,
|
| 30 |
+
warnings: [],
|
| 31 |
+
};
|
| 32 |
+
const started = new Map();
|
| 33 |
+
const progress = () => onProgress({ stage: "layers", loaded: stats.layers + stats.missing, total: started.size, bytes: stats.layerBytes });
|
| 34 |
+
const throttle = limiter(maxConcurrentFetches);
|
| 35 |
+
// One budget for every layer body, charged as its bytes arrive, so fetches
|
| 36 |
+
// in parallel cannot each count on the whole remainder.
|
| 37 |
+
let heldBytes = 0;
|
| 38 |
+
const charge = (bytes, path) => {
|
| 39 |
+
heldBytes += bytes;
|
| 40 |
+
if (heldBytes > maxLayerBytes) {
|
| 41 |
+
throw resourceLimit(`layers exceed maxLayerBytes (${maxLayerBytes} bytes) at ${path}`);
|
| 42 |
+
}
|
| 43 |
+
};
|
| 44 |
+
// Re-fetched layers replace their earlier bytes, so count each path once.
|
| 45 |
+
const layerSizes = new Map();
|
| 46 |
+
// Speculative fetches by URL, dropped once composition is done. One that
|
| 47 |
+
// has not started when its layer is asked for, or that failed, gives way to
|
| 48 |
+
// the regular fetch, so the result is the same as without them. Their
|
| 49 |
+
// bytes are charged as they arrive, and stay charged once used.
|
| 50 |
+
const preloaded = new Map();
|
| 51 |
+
let composed = false;
|
| 52 |
+
// Every distinct layer URL requested, preloads included, for maxLayers.
|
| 53 |
+
const requested = new Set();
|
| 54 |
+
const startPreload = (layers) => {
|
| 55 |
+
let bytes = 0;
|
| 56 |
+
for (const { url, size } of layers) {
|
| 57 |
+
const key = urlKey(url);
|
| 58 |
+
bytes += size;
|
| 59 |
+
if (composed || bytes > maxLayerBytes) {
|
| 60 |
+
break;
|
| 61 |
+
}
|
| 62 |
+
if (requested.has(key)) {
|
| 63 |
+
continue;
|
| 64 |
+
}
|
| 65 |
+
if (requested.size >= maxLayers) {
|
| 66 |
+
break;
|
| 67 |
+
}
|
| 68 |
+
requested.add(key);
|
| 69 |
+
const entry = { started: false, charged: 0 };
|
| 70 |
+
preloaded.set(key, entry);
|
| 71 |
+
// Unused once composed: the next chunk cancels the body.
|
| 72 |
+
const budget = (bytes) => {
|
| 73 |
+
if (composed) {
|
| 74 |
+
throw new Error("composed without it");
|
| 75 |
+
}
|
| 76 |
+
entry.charged += bytes;
|
| 77 |
+
charge(bytes, url);
|
| 78 |
+
};
|
| 79 |
+
entry.bytes = throttle(async () => {
|
| 80 |
+
if (composed || preloaded.get(key) !== entry) {
|
| 81 |
+
return null;
|
| 82 |
+
}
|
| 83 |
+
entry.started = true;
|
| 84 |
+
const bytes = await fetchBytes(url, budget);
|
| 85 |
+
if (bytes) {
|
| 86 |
+
budget(bytes.byteLength - entry.charged);
|
| 87 |
+
}
|
| 88 |
+
return bytes;
|
| 89 |
+
}, { later: true }).catch(() => {
|
| 90 |
+
heldBytes -= entry.charged;
|
| 91 |
+
entry.charged = 0;
|
| 92 |
+
return null;
|
| 93 |
+
});
|
| 94 |
+
}
|
| 95 |
+
};
|
| 96 |
+
const takePreloaded = (path) => {
|
| 97 |
+
const entry = preloaded.get(urlKey(path));
|
| 98 |
+
preloaded.delete(urlKey(path));
|
| 99 |
+
return entry?.started ? entry : null;
|
| 100 |
+
};
|
| 101 |
+
// Jobs in flight. A job queues its dependencies here rather than awaiting
|
| 102 |
+
// them, so layers that reference each other cannot wait on each other.
|
| 103 |
+
const pending = [];
|
| 104 |
+
const drain = async () => {
|
| 105 |
+
while (pending.length) {
|
| 106 |
+
await Promise.all(pending.splice(0));
|
| 107 |
+
}
|
| 108 |
+
};
|
| 109 |
+
const fetchLayer = (path) => {
|
| 110 |
+
if (loader.has(path) || started.has(path)) {
|
| 111 |
+
return;
|
| 112 |
+
}
|
| 113 |
+
requested.add(urlKey(path));
|
| 114 |
+
if (requested.size > maxLayers) {
|
| 115 |
+
throw resourceLimit(`more than maxLayers (${maxLayers}) layer files at ${path}`);
|
| 116 |
+
}
|
| 117 |
+
const { refused } = requestPolicy(urlOf(path), rootUrl, allowedOrigins);
|
| 118 |
+
if (refused) {
|
| 119 |
+
started.set(path, Promise.resolve());
|
| 120 |
+
stats.missing++;
|
| 121 |
+
stats.warnings.push({ code: "layer-missing", message: `layer not fetched: ${refused}`, path });
|
| 122 |
+
loader.markUnavailable(path);
|
| 123 |
+
progress();
|
| 124 |
+
return;
|
| 125 |
+
}
|
| 126 |
+
const job = (async () => {
|
| 127 |
+
const t0 = performance.now();
|
| 128 |
+
heldBytes -= layerSizes.get(path) ?? 0;
|
| 129 |
+
layerSizes.delete(path);
|
| 130 |
+
let charged = 0;
|
| 131 |
+
const budget = (bytes) => {
|
| 132 |
+
charged += bytes;
|
| 133 |
+
charge(bytes, path);
|
| 134 |
+
};
|
| 135 |
+
// Any fetch failure, HTTP or network: the root fails the load, any
|
| 136 |
+
// other layer is left out with a warning.
|
| 137 |
+
let bytes = null;
|
| 138 |
+
let failure = null;
|
| 139 |
+
try {
|
| 140 |
+
const entry = takePreloaded(path);
|
| 141 |
+
bytes = entry && (await entry.bytes);
|
| 142 |
+
if (entry && bytes) {
|
| 143 |
+
charged = entry.charged;
|
| 144 |
+
}
|
| 145 |
+
bytes ??= await throttle(() => fetchBytes(urlOf(path), budget));
|
| 146 |
+
}
|
| 147 |
+
catch (error) {
|
| 148 |
+
heldBytes -= charged;
|
| 149 |
+
// HTTP errors carry a status; network errors are TypeErrors (as from fetch).
|
| 150 |
+
if (error?.status === undefined && !(error instanceof TypeError)) {
|
| 151 |
+
throw error;
|
| 152 |
+
}
|
| 153 |
+
failure = error;
|
| 154 |
+
}
|
| 155 |
+
stats.fetchMs = Math.max(stats.fetchMs, performance.now() - t0);
|
| 156 |
+
if (!bytes) {
|
| 157 |
+
if (path === root) {
|
| 158 |
+
const status = failure?.status ?? (failure ? undefined : 404);
|
| 159 |
+
throw new UsdLoadError("fetch", `could not fetch ${rootUrl}${status ? ` (HTTP ${status})` : ""}`, {
|
| 160 |
+
url: rootUrl,
|
| 161 |
+
status,
|
| 162 |
+
cause: failure ?? undefined,
|
| 163 |
+
});
|
| 164 |
+
}
|
| 165 |
+
stats.missing++;
|
| 166 |
+
stats.warnings.push({
|
| 167 |
+
code: "layer-missing",
|
| 168 |
+
message: `layer not found: ${failure?.message ?? urlOf(path)}`,
|
| 169 |
+
path: urlOf(path),
|
| 170 |
+
});
|
| 171 |
+
loader.markUnavailable(path);
|
| 172 |
+
progress();
|
| 173 |
+
return;
|
| 174 |
+
}
|
| 175 |
+
charge(bytes.byteLength - charged, path);
|
| 176 |
+
layerSizes.set(path, bytes.byteLength);
|
| 177 |
+
stats.layers++;
|
| 178 |
+
stats.layerBytes += bytes.byteLength;
|
| 179 |
+
const t1 = performance.now();
|
| 180 |
+
let deps;
|
| 181 |
+
try {
|
| 182 |
+
deps = loader.addLayer(path, bytes);
|
| 183 |
+
}
|
| 184 |
+
catch (error) {
|
| 185 |
+
// After a trap the module is unusable: the load fails.
|
| 186 |
+
if (isTrap(error)) {
|
| 187 |
+
throw error;
|
| 188 |
+
}
|
| 189 |
+
// An unreadable layer is left out; composition carries on without it.
|
| 190 |
+
stats.warnings.push({
|
| 191 |
+
code: "layer-unreadable",
|
| 192 |
+
message: String(error.message || error),
|
| 193 |
+
path: urlOf(path),
|
| 194 |
+
});
|
| 195 |
+
loader.markUnavailable(path);
|
| 196 |
+
progress();
|
| 197 |
+
return;
|
| 198 |
+
}
|
| 199 |
+
finally {
|
| 200 |
+
stats.parseMs += performance.now() - t1;
|
| 201 |
+
}
|
| 202 |
+
progress();
|
| 203 |
+
for (const dep of deps) {
|
| 204 |
+
fetchLayer(dep);
|
| 205 |
+
}
|
| 206 |
+
})();
|
| 207 |
+
started.set(path, job);
|
| 208 |
+
pending.push(job);
|
| 209 |
+
};
|
| 210 |
+
fetchLayer(root);
|
| 211 |
+
// A root without dependencies needs nothing else from its directory.
|
| 212 |
+
const rootHasDependencies = () => (started.get(root) ?? Promise.resolve()).then(() => started.size > 1, () => false);
|
| 213 |
+
preload?.then(async ({ layers, eager }) => (eager || (await rootHasDependencies())) && startPreload(layers));
|
| 214 |
+
await drain();
|
| 215 |
+
if (!loader.has(root)) {
|
| 216 |
+
const reason = stats.warnings.find((w) => w.path === rootUrl)?.message;
|
| 217 |
+
throw new UsdLoadError("compose", `could not read ${rootUrl}${reason ? `: ${reason}` : ""}`, { url: rootUrl });
|
| 218 |
+
}
|
| 219 |
+
for (;;) {
|
| 220 |
+
stats.rounds++;
|
| 221 |
+
onProgress({ stage: "compose", round: stats.rounds });
|
| 222 |
+
const t0 = performance.now();
|
| 223 |
+
const missing = loader.compose(root, maxInstances);
|
| 224 |
+
stats.composeMs += performance.now() - t0;
|
| 225 |
+
if (!missing.length) {
|
| 226 |
+
break;
|
| 227 |
+
}
|
| 228 |
+
if (stats.rounds > 16) {
|
| 229 |
+
throw new UsdLoadError("compose", `composition still missing layers: ${missing.join(", ")}`);
|
| 230 |
+
}
|
| 231 |
+
// The list also names layers the failed attempt consumed; fetch them again.
|
| 232 |
+
for (const path of missing) {
|
| 233 |
+
started.delete(path);
|
| 234 |
+
}
|
| 235 |
+
missing.forEach(fetchLayer);
|
| 236 |
+
await drain();
|
| 237 |
+
}
|
| 238 |
+
composed = true;
|
| 239 |
+
const scene = loader.takeScene();
|
| 240 |
+
loader.free();
|
| 241 |
+
const meta = JSON.parse(scene.meta());
|
| 242 |
+
return { scene, meta, stats };
|
| 243 |
+
}
|
| 244 |
+
/**
|
| 245 |
+
* What the page is told about a failed load. Fetch and resource-limit errors
|
| 246 |
+
* keep their code, url and status; anything the WASM side throws is a
|
| 247 |
+
* composition failure. Running out of WASM memory (4 GiB at most) reads as a
|
| 248 |
+
* scene too large to load: an allocation that fails while reading a layer
|
| 249 |
+
* reports "out of memory", one that aborts traps as a bare `unreachable`. A
|
| 250 |
+
* Rust panic, which also traps as `unreachable`, gives its message instead,
|
| 251 |
+
* read with `lastPanic` (the module's export). Overflowing the stack, the WASM one (an
|
| 252 |
+
* out-of-bounds access) or the engine's, means layers nested too deeply to read.
|
| 253 |
+
*/
|
| 254 |
+
export function loadFailure(error, wasmMemoryBytes, lastPanic) {
|
| 255 |
+
const { code = "compose", url, status } = (error ?? {});
|
| 256 |
+
const message = String(error?.message || error);
|
| 257 |
+
const failure = (detail) => ({ code, message: detail, url, status });
|
| 258 |
+
if (code !== "compose") {
|
| 259 |
+
return failure(message);
|
| 260 |
+
}
|
| 261 |
+
const tooLarge = () => failure(`scene too large to load: ran out of memory (${(wasmMemoryBytes / 2 ** 30).toFixed(1)} GiB of WebAssembly memory in use): ${message}`);
|
| 262 |
+
if (OUT_OF_MEMORY.test(message) || (error instanceof WebAssembly.RuntimeError && wasmMemoryBytes > 3 * 2 ** 30)) {
|
| 263 |
+
return tooLarge();
|
| 264 |
+
}
|
| 265 |
+
if (!isTrap(error)) {
|
| 266 |
+
return failure(message);
|
| 267 |
+
}
|
| 268 |
+
const panic = readPanic(lastPanic);
|
| 269 |
+
if (panic) {
|
| 270 |
+
return failure(`${message}: ${panic}`);
|
| 271 |
+
}
|
| 272 |
+
if (/out of bounds|call stack|recursion/i.test(message)) {
|
| 273 |
+
return failure(`stack overflow: the layers nest too deeply to read (${message})`);
|
| 274 |
+
}
|
| 275 |
+
// Rust aborts on a failed allocation without a panic: a bare `unreachable`.
|
| 276 |
+
if (/unreachable/i.test(message)) {
|
| 277 |
+
return tooLarge();
|
| 278 |
+
}
|
| 279 |
+
return failure(message);
|
| 280 |
+
}
|
| 281 |
+
/** Messages of allocations that failed, in Rust or in the engine. */
|
| 282 |
+
export const OUT_OF_MEMORY = /out of memory|memory allocation|allocation failed|memory size exceeded|could not allocate/i;
|
| 283 |
+
/** Reading the panic calls into the trapped module, which can trap again (an exhausted stack does). */
|
| 284 |
+
function readPanic(lastPanic) {
|
| 285 |
+
try {
|
| 286 |
+
return lastPanic?.();
|
| 287 |
+
}
|
| 288 |
+
catch {
|
| 289 |
+
return undefined;
|
| 290 |
+
}
|
| 291 |
+
}
|
| 292 |
+
/** A WebAssembly trap or an exhausted engine call stack: the module is no longer usable. */
|
| 293 |
+
function isTrap(error) {
|
| 294 |
+
return (error instanceof WebAssembly.RuntimeError ||
|
| 295 |
+
error instanceof RangeError ||
|
| 296 |
+
error?.name === "InternalError");
|
| 297 |
+
}
|
| 298 |
+
function resourceLimit(detail) {
|
| 299 |
+
return new UsdLoadError("fetch", `resource limit exceeded: ${detail}`);
|
| 300 |
+
}
|
| 301 |
+
/** Runs at most `max` of the given tasks at once; tasks marked `later` wait for the others. */
|
| 302 |
+
export function limiter(max) {
|
| 303 |
+
let active = 0;
|
| 304 |
+
const queue = [];
|
| 305 |
+
const later = [];
|
| 306 |
+
const next = () => {
|
| 307 |
+
if (active >= max) {
|
| 308 |
+
return;
|
| 309 |
+
}
|
| 310 |
+
const job = queue.shift() ?? later.shift();
|
| 311 |
+
if (!job) {
|
| 312 |
+
return;
|
| 313 |
+
}
|
| 314 |
+
active++;
|
| 315 |
+
const { task, resolve, reject } = job;
|
| 316 |
+
task()
|
| 317 |
+
.then(resolve, reject)
|
| 318 |
+
.finally(() => {
|
| 319 |
+
active--;
|
| 320 |
+
next();
|
| 321 |
+
});
|
| 322 |
+
};
|
| 323 |
+
return (task, { later: low = false } = {}) => new Promise((resolve, reject) => {
|
| 324 |
+
(low ? later : queue).push({ task, resolve: resolve, reject });
|
| 325 |
+
next();
|
| 326 |
+
});
|
| 327 |
+
}
|
| 328 |
+
/** A layer URL as fetch would spell it, so an authored `a b.usd` matches a listed `a%20b.usd`. */
|
| 329 |
+
function urlKey(url) {
|
| 330 |
+
try {
|
| 331 |
+
return new URL(url).href;
|
| 332 |
+
}
|
| 333 |
+
catch {
|
| 334 |
+
return url;
|
| 335 |
+
}
|
| 336 |
+
}
|
| 337 |
+
/**
|
| 338 |
+
* Fetches a body, passing each chunk's size to `budget` as it arrives and
|
| 339 |
+
* giving up (cancelling the body) when `budget` throws. An HTTP error throws a
|
| 340 |
+
* `fetch` UsdLoadError carrying the status. `fetchFn` is the global fetch or a
|
| 341 |
+
* stand-in with the same contract. Rate limiting (429) and server errors
|
| 342 |
+
* (5xx) are retried with backoff, as the Hub answers bursts with 429.
|
| 343 |
+
*/
|
| 344 |
+
export async function fetchLimited(url, budget, { fetchFn = fetch, retries = 3, retryDelayMs = 500, } = {}) {
|
| 345 |
+
let response = await fetchFn(url);
|
| 346 |
+
for (let attempt = 0; attempt < retries && (response.status === 429 || response.status >= 500); attempt++) {
|
| 347 |
+
response.body?.cancel().catch(() => { });
|
| 348 |
+
const retryAfterMs = Number(response.headers?.get("retry-after")) * 1000;
|
| 349 |
+
const delay = retryAfterMs > 0 ? Math.min(retryAfterMs, 10_000) : retryDelayMs * 2 ** attempt * (1 + Math.random());
|
| 350 |
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
| 351 |
+
response = await fetchFn(url);
|
| 352 |
+
}
|
| 353 |
+
if (!response.ok) {
|
| 354 |
+
throw new UsdLoadError("fetch", `HTTP ${response.status} for ${url}`, { url, status: response.status });
|
| 355 |
+
}
|
| 356 |
+
if (!response.body) {
|
| 357 |
+
return new Uint8Array();
|
| 358 |
+
}
|
| 359 |
+
const reader = response.body.getReader();
|
| 360 |
+
const chunks = [];
|
| 361 |
+
let size = 0;
|
| 362 |
+
for (;;) {
|
| 363 |
+
const { done, value } = await reader.read();
|
| 364 |
+
if (done) {
|
| 365 |
+
break;
|
| 366 |
+
}
|
| 367 |
+
try {
|
| 368 |
+
budget(value.byteLength);
|
| 369 |
+
}
|
| 370 |
+
catch (error) {
|
| 371 |
+
await reader.cancel();
|
| 372 |
+
throw error;
|
| 373 |
+
}
|
| 374 |
+
size += value.byteLength;
|
| 375 |
+
chunks.push(value);
|
| 376 |
+
}
|
| 377 |
+
const out = new Uint8Array(size);
|
| 378 |
+
let offset = 0;
|
| 379 |
+
for (const chunk of chunks) {
|
| 380 |
+
out.set(chunk, offset);
|
| 381 |
+
offset += chunk.byteLength;
|
| 382 |
+
}
|
| 383 |
+
return out;
|
| 384 |
+
}
|
| 385 |
+
/**
|
| 386 |
+
* Size of a PNG, JPEG or WebP from its header, without decoding, and whether
|
| 387 |
+
* it is color: 8-bit RGB(A) or palette, rather than greyscale or 16-bit data
|
| 388 |
+
* (the images `sourceColorSpace = "auto"` decodes as sRGB; WebP is always
|
| 389 |
+
* color). Null for other formats, whose size cannot be checked before decoding.
|
| 390 |
+
*/
|
| 391 |
+
export function imageInfo(b) {
|
| 392 |
+
const v = new DataView(b.buffer, b.byteOffset, b.byteLength);
|
| 393 |
+
const ascii = (at, text) => [...text].every((c, i) => b[at + i] === c.charCodeAt(0));
|
| 394 |
+
if (b.length > 25 && b[0] === 0x89 && ascii(1, "PNG")) {
|
| 395 |
+
const [bitDepth, colorType] = [b[24], b[25]];
|
| 396 |
+
const color = colorType === 3 || (bitDepth === 8 && (colorType === 2 || colorType === 6));
|
| 397 |
+
return { width: v.getUint32(16), height: v.getUint32(20), color };
|
| 398 |
+
}
|
| 399 |
+
if (b[0] === 0xff && b[1] === 0xd8) {
|
| 400 |
+
let i = 2;
|
| 401 |
+
while (i + 9 < b.length) {
|
| 402 |
+
if (b[i] !== 0xff) {
|
| 403 |
+
return null;
|
| 404 |
+
}
|
| 405 |
+
const marker = b[i + 1];
|
| 406 |
+
const length = (b[i + 2] << 8) | b[i + 3];
|
| 407 |
+
const isFrame = marker >= 0xc0 && marker <= 0xcf && marker !== 0xc4 && marker !== 0xc8 && marker !== 0xcc;
|
| 408 |
+
if (isFrame) {
|
| 409 |
+
return {
|
| 410 |
+
height: (b[i + 5] << 8) | b[i + 6],
|
| 411 |
+
width: (b[i + 7] << 8) | b[i + 8],
|
| 412 |
+
color: b[i + 4] === 8 && b[i + 9] >= 3,
|
| 413 |
+
};
|
| 414 |
+
}
|
| 415 |
+
i += 2 + length;
|
| 416 |
+
}
|
| 417 |
+
return null;
|
| 418 |
+
}
|
| 419 |
+
if (b.length >= 30 && ascii(0, "RIFF") && ascii(8, "WEBP")) {
|
| 420 |
+
// The first chunk: lossy (VP8), lossless (VP8L) or extended (VP8X).
|
| 421 |
+
if (ascii(12, "VP8 ")) {
|
| 422 |
+
return { width: v.getUint16(26, true) & 0x3fff, height: v.getUint16(28, true) & 0x3fff, color: true };
|
| 423 |
+
}
|
| 424 |
+
if (ascii(12, "VP8L")) {
|
| 425 |
+
const bits = v.getUint32(21, true);
|
| 426 |
+
return { width: (bits & 0x3fff) + 1, height: ((bits >>> 14) & 0x3fff) + 1, color: true };
|
| 427 |
+
}
|
| 428 |
+
if (ascii(12, "VP8X")) {
|
| 429 |
+
const u24 = (at) => b[at] | (b[at + 1] << 8) | (b[at + 2] << 16);
|
| 430 |
+
return { width: u24(24) + 1, height: u24(27) + 1, color: true };
|
| 431 |
+
}
|
| 432 |
+
}
|
| 433 |
+
return null;
|
| 434 |
+
}
|
| 435 |
+
// A trailing dot names the same host (`huggingface.co.`), so it matches too.
|
| 436 |
+
const HUB_HOST = /^(huggingface\.co|hf\.co)\.?$/;
|
| 437 |
+
const HUB_CDN = /\.hf\.co\.?$/;
|
| 438 |
+
// Paths of Hub repo files, of the tree listing the prefetch reads and of the
|
| 439 |
+
// revision lookup that pins a load to one commit: the only Hub URLs a load
|
| 440 |
+
// requests, never other `/api/*` endpoints or account pages. The last group is
|
| 441 |
+
// the revision.
|
| 442 |
+
const HUB_FILE = /^\/(?:(datasets|spaces)\/)?([\w.-]+)\/([\w.-]+)\/resolve\/([^/]*)/;
|
| 443 |
+
const HUB_TREE = /^\/api\/(datasets|models|spaces)\/([\w.-]+)\/([\w.-]+)\/(?:tree|revision)\/([^/]*)/;
|
| 444 |
+
// First path segments of Hub pages and endpoints: never a model's owner.
|
| 445 |
+
const HUB_RESERVED = new Set([
|
| 446 |
+
"api",
|
| 447 |
+
"oauth",
|
| 448 |
+
"settings",
|
| 449 |
+
"login",
|
| 450 |
+
"logout",
|
| 451 |
+
"join",
|
| 452 |
+
"docs",
|
| 453 |
+
"models",
|
| 454 |
+
"datasets",
|
| 455 |
+
"spaces",
|
| 456 |
+
"organizations",
|
| 457 |
+
"new",
|
| 458 |
+
"pricing",
|
| 459 |
+
"blog",
|
| 460 |
+
"papers",
|
| 461 |
+
"posts",
|
| 462 |
+
"collections",
|
| 463 |
+
"notifications",
|
| 464 |
+
"search",
|
| 465 |
+
"chat",
|
| 466 |
+
"learn",
|
| 467 |
+
"tasks",
|
| 468 |
+
"enterprise",
|
| 469 |
+
"billing",
|
| 470 |
+
"static-proxy",
|
| 471 |
+
"avatars",
|
| 472 |
+
"front",
|
| 473 |
+
]);
|
| 474 |
+
/** The path match of a Hub file or tree-listing URL (`[, type, owner, repo, revision]`), else null. */
|
| 475 |
+
function hubMatch(url) {
|
| 476 |
+
if (!HUB_HOST.test(url.hostname) || url.protocol !== "https:") {
|
| 477 |
+
return null;
|
| 478 |
+
}
|
| 479 |
+
const file = url.pathname.match(HUB_FILE);
|
| 480 |
+
if (file && (file[1] || !HUB_RESERVED.has(file[2].toLowerCase()))) {
|
| 481 |
+
return file;
|
| 482 |
+
}
|
| 483 |
+
return url.pathname.match(HUB_TREE);
|
| 484 |
+
}
|
| 485 |
+
/** `type/owner/repo` of a Hub file or tree-listing URL, else null. */
|
| 486 |
+
function hubRepo(url) {
|
| 487 |
+
const match = hubMatch(url);
|
| 488 |
+
return match && `${match[1] ?? "models"}/${match[2]}/${match[3]}`;
|
| 489 |
+
}
|
| 490 |
+
/**
|
| 491 |
+
* A URL on hf.co, the Hub's short domain, as the huggingface.co URL it
|
| 492 |
+
* redirects to: fetched directly, a request keeps its headers (a redirect
|
| 493 |
+
* to another origin drops them) and its credentials scope stays the same.
|
| 494 |
+
*/
|
| 495 |
+
export function canonicalUrl(url) {
|
| 496 |
+
try {
|
| 497 |
+
const parsed = new URL(url);
|
| 498 |
+
if (!/^hf\.co\.?$/.test(parsed.hostname)) {
|
| 499 |
+
return url;
|
| 500 |
+
}
|
| 501 |
+
parsed.hostname = "huggingface.co";
|
| 502 |
+
return parsed.href;
|
| 503 |
+
}
|
| 504 |
+
catch {
|
| 505 |
+
return url;
|
| 506 |
+
}
|
| 507 |
+
}
|
| 508 |
+
/** The scheme of files given with the `files` option: `local:///<key>`, the key percent-encoded. */
|
| 509 |
+
export const LOCAL = "local:";
|
| 510 |
+
/** A `files` key as the load spells it: `/` separators, no leading `./` or `/`. */
|
| 511 |
+
export function localKey(key) {
|
| 512 |
+
return key.replace(/\\/g, "/").replace(/^(?:\.?\/)+/, "");
|
| 513 |
+
}
|
| 514 |
+
/** The URL a `files` key loads as; relative asset paths in the file resolve against it. */
|
| 515 |
+
export function localUrl(key) {
|
| 516 |
+
return `${LOCAL}///${localKey(key).split("/").map(encodeURIComponent).join("/")}`;
|
| 517 |
+
}
|
| 518 |
+
/** The `files` key a `local:` URL names. */
|
| 519 |
+
export function keyOfLocalUrl(url) {
|
| 520 |
+
return decodeURIComponent(new URL(url).pathname.slice(1));
|
| 521 |
+
}
|
| 522 |
+
/**
|
| 523 |
+
* How a load rooted at `rootUrl` may request `url`: `{ refused }` with the
|
| 524 |
+
* reason, or the fetch options to use. Every request a load makes goes
|
| 525 |
+
* through this first, then through {@link fetchWithPolicy}. Only the
|
| 526 |
+
* requested URL is checked: fetches follow redirects (a Hub `resolve` URL
|
| 527 |
+
* redirects to its CDN, which the Hub controls), but never with the caller's
|
| 528 |
+
* headers off the Hub.
|
| 529 |
+
*
|
| 530 |
+
* - hf.co URLs are checked as the huggingface.co URLs they redirect to.
|
| 531 |
+
* - The root URL itself, as the caller gave it, is always allowed.
|
| 532 |
+
* - A `local:` root (the `files` option) may read other `local:` URLs, which
|
| 533 |
+
* are looked up in its files and never fetched; no other root may.
|
| 534 |
+
* - Only http(s), with no user name or password in the URL.
|
| 535 |
+
* - Origins: the root's, those in `allowedOrigins` (`'*'` for any) and, for a
|
| 536 |
+
* root on the Hugging Face Hub, the Hub and its CDN hosts.
|
| 537 |
+
* - On huggingface.co and hf.co, only repo files (`…/resolve/…`) and tree
|
| 538 |
+
* listings, under a user or organization name (not `/api/…`, `/oauth/…`
|
| 539 |
+
* and other Hub pages), with no encoded slashes outside the revision (a
|
| 540 |
+
* pull request's is `refs%2Fpr%2F1`).
|
| 541 |
+
* - Credentials (cookies and the caller's headers) go only to the root's own
|
| 542 |
+
* origin or, for a Hub root, only to the root's own repo.
|
| 543 |
+
*/
|
| 544 |
+
export function requestPolicy(url, rootUrl, allowedOrigins = []) {
|
| 545 |
+
const refused = refusal(canonicalUrl(url), canonicalUrl(rootUrl), allowedOrigins);
|
| 546 |
+
if (refused) {
|
| 547 |
+
return { refused };
|
| 548 |
+
}
|
| 549 |
+
return {
|
| 550 |
+
credentials: credentialed(new URL(canonicalUrl(url)), new URL(canonicalUrl(rootUrl))) ? "same-origin" : "omit",
|
| 551 |
+
referrerPolicy: "no-referrer",
|
| 552 |
+
};
|
| 553 |
+
}
|
| 554 |
+
function refusal(url, rootUrl, allowedOrigins) {
|
| 555 |
+
if (url === rootUrl) {
|
| 556 |
+
return null;
|
| 557 |
+
}
|
| 558 |
+
let target;
|
| 559 |
+
try {
|
| 560 |
+
target = new URL(url);
|
| 561 |
+
}
|
| 562 |
+
catch {
|
| 563 |
+
return `not a URL: ${url}`;
|
| 564 |
+
}
|
| 565 |
+
const root = new URL(rootUrl);
|
| 566 |
+
if (root.protocol === LOCAL && target.protocol === LOCAL) {
|
| 567 |
+
return null;
|
| 568 |
+
}
|
| 569 |
+
if (target.protocol !== "http:" && target.protocol !== "https:") {
|
| 570 |
+
return `only http(s) URLs are fetched: ${url}`;
|
| 571 |
+
}
|
| 572 |
+
if (target.username || target.password) {
|
| 573 |
+
return `URLs with credentials are not fetched: ${url}`;
|
| 574 |
+
}
|
| 575 |
+
const hub = HUB_HOST.test(target.hostname);
|
| 576 |
+
if (hub && !hubFile(target)) {
|
| 577 |
+
return `only Hub repo files are fetched from ${target.host}: ${url}`;
|
| 578 |
+
}
|
| 579 |
+
const fromHub = HUB_HOST.test(root.hostname) && (hub || HUB_CDN.test(target.hostname)) && target.protocol === "https:";
|
| 580 |
+
if (target.origin === root.origin ||
|
| 581 |
+
fromHub ||
|
| 582 |
+
allowedOrigins.includes("*") ||
|
| 583 |
+
allowedOrigins.includes(target.origin)) {
|
| 584 |
+
return null;
|
| 585 |
+
}
|
| 586 |
+
return `its origin is not in allowedOrigins: ${url}`;
|
| 587 |
+
}
|
| 588 |
+
/** A Hub repo file or tree listing with no encoded slash or backslash, but for a `%2F` in its revision. */
|
| 589 |
+
function hubFile(url) {
|
| 590 |
+
const match = hubMatch(url);
|
| 591 |
+
if (!match) {
|
| 592 |
+
return false;
|
| 593 |
+
}
|
| 594 |
+
const revisionStart = match[0].length - match[4].length;
|
| 595 |
+
const outside = url.pathname.slice(0, revisionStart) + url.pathname.slice(match[0].length);
|
| 596 |
+
return !/%2f|%5c/i.test(outside) && !/%5c/i.test(match[4]);
|
| 597 |
+
}
|
| 598 |
+
function credentialed(target, root) {
|
| 599 |
+
// Every `local:` URL's origin is the string "null", which would match any other's.
|
| 600 |
+
if (root.protocol === LOCAL) {
|
| 601 |
+
return false;
|
| 602 |
+
}
|
| 603 |
+
if (target.origin !== root.origin) {
|
| 604 |
+
return false;
|
| 605 |
+
}
|
| 606 |
+
const repo = hubRepo(root);
|
| 607 |
+
return HUB_HOST.test(root.hostname) ? !!repo && hubRepo(target) === repo : true;
|
| 608 |
+
}
|
| 609 |
+
/**
|
| 610 |
+
* Fetches `url` under `policy` (see {@link requestPolicy}), sending `headers`
|
| 611 |
+
* only where credentials may go. A request carrying them does not follow a
|
| 612 |
+
* redirect with them: unless it is on the Hub (whose redirects stay on its own
|
| 613 |
+
* hosts), it is not followed, and the URL is fetched again without headers or
|
| 614 |
+
* cookies, for the browser to follow.
|
| 615 |
+
*/
|
| 616 |
+
export async function fetchWithPolicy(url, policy, headers) {
|
| 617 |
+
const sendHeaders = policy.credentials === "same-origin" && !!headers && Object.keys(headers).length > 0;
|
| 618 |
+
if (!sendHeaders) {
|
| 619 |
+
return fetch(url, policy);
|
| 620 |
+
}
|
| 621 |
+
if (HUB_HOST.test(new URL(url).hostname)) {
|
| 622 |
+
return fetch(url, { ...policy, headers });
|
| 623 |
+
}
|
| 624 |
+
const response = await fetch(url, { ...policy, headers, redirect: "manual" });
|
| 625 |
+
if (response.type !== "opaqueredirect" && !(response.status >= 300 && response.status < 400)) {
|
| 626 |
+
return response;
|
| 627 |
+
}
|
| 628 |
+
response.body?.cancel().catch(() => { });
|
| 629 |
+
return fetch(url, { ...policy, credentials: "omit" });
|
| 630 |
+
}
|
| 631 |
+
/**
|
| 632 |
+
* Reads each geometry out of WASM in turn, so only one mesh's arrays are in
|
| 633 |
+
* WASM memory at a time, and calls `onGeometry(index, meta, arrays)` with
|
| 634 |
+
* JS-owned typed arrays (`meta` and `arrays` are null for a mesh with nothing
|
| 635 |
+
* drawable, or left out). Triangles count as drawn, once per instance:
|
| 636 |
+
* meshes that would take them past `maxTriangles` are left out unread.
|
| 637 |
+
* Releases the stage afterwards. Returns warnings: `triangle-limit` for
|
| 638 |
+
* meshes left out, `nothing-drawable` when no mesh had anything to draw.
|
| 639 |
+
*/
|
| 640 |
+
export function readGeometries(scene, meta, onGeometry, { maxTriangles = DEFAULTS.maxTriangles } = {}) {
|
| 641 |
+
const instances = Array.from({ length: meta.geometryCount }, () => 0);
|
| 642 |
+
for (const { geometry } of meta.instances) {
|
| 643 |
+
instances[geometry]++;
|
| 644 |
+
}
|
| 645 |
+
let drawn = 0;
|
| 646 |
+
let left = maxTriangles;
|
| 647 |
+
const skipped = [];
|
| 648 |
+
for (let i = 0; i < meta.geometryCount; i++) {
|
| 649 |
+
// Not drawn anywhere (e.g. all its instances past maxInstances).
|
| 650 |
+
if (!instances[i]) {
|
| 651 |
+
onGeometry(i, null, null);
|
| 652 |
+
continue;
|
| 653 |
+
}
|
| 654 |
+
const json = scene.read(i, Math.min(Math.floor(left / instances[i]), 2 ** 32 - 1));
|
| 655 |
+
const g = json && JSON.parse(json);
|
| 656 |
+
if (!g || "overBudget" in g) {
|
| 657 |
+
if (g) {
|
| 658 |
+
skipped.push(g.path);
|
| 659 |
+
}
|
| 660 |
+
onGeometry(i, null, null);
|
| 661 |
+
continue;
|
| 662 |
+
}
|
| 663 |
+
drawn++;
|
| 664 |
+
left = Math.max(0, left - instances[i] * g.groups.reduce((n, [, count]) => n + count / 3, 0));
|
| 665 |
+
onGeometry(i, g, {
|
| 666 |
+
positions: scene.positions(),
|
| 667 |
+
normals: scene.normals(),
|
| 668 |
+
uvs: g.uvSets.map((_, k) => scene.uvs(k)),
|
| 669 |
+
colors: g.hasColors ? scene.colors() : null,
|
| 670 |
+
indices: g.maxIndex < 65536 ? scene.indices16() : scene.indices(),
|
| 671 |
+
});
|
| 672 |
+
}
|
| 673 |
+
scene.finish();
|
| 674 |
+
const warnings = [];
|
| 675 |
+
if (skipped.length) {
|
| 676 |
+
warnings.push({
|
| 677 |
+
code: "triangle-limit",
|
| 678 |
+
message: `${skipped.length} meshes left out: past maxTriangles (${maxTriangles}) drawn`,
|
| 679 |
+
path: skipped[0],
|
| 680 |
+
});
|
| 681 |
+
}
|
| 682 |
+
if (!drawn) {
|
| 683 |
+
warnings.push({
|
| 684 |
+
code: "nothing-drawable",
|
| 685 |
+
message: "nothing to draw: the stage has no visible meshes with geometry",
|
| 686 |
+
});
|
| 687 |
+
}
|
| 688 |
+
return warnings;
|
| 689 |
+
}
|
| 690 |
+
/**
|
| 691 |
+
* Reads the colliders of a scene composed with `physics` (`SceneMeta.physics.colliderCount`), one at a time, and calls
|
| 692 |
+
* `onCollider(index, meta, arrays)` with JS-owned typed arrays: its points as authored and its faces fan-triangulated.
|
| 693 |
+
* Reads nothing for a scene composed without it. Call it before `scene.free()`; each collider reads once.
|
| 694 |
+
*/
|
| 695 |
+
export function readColliders(scene, onCollider) {
|
| 696 |
+
const count = scene.colliderCount();
|
| 697 |
+
for (let i = 0; i < count; i++) {
|
| 698 |
+
const meta = JSON.parse(scene.readCollider(i));
|
| 699 |
+
onCollider(i, meta, { points: scene.positions(), indices: scene.indices() });
|
| 700 |
+
}
|
| 701 |
+
return count;
|
| 702 |
+
}
|
| 703 |
+
/**
|
| 704 |
+
* Images stored inside a USDZ package (they cannot be fetched by URL) among
|
| 705 |
+
* the texture `jobs` (see {@link textureJobs}), each read once, by path, all
|
| 706 |
+
* together at most `maxBytes`. One that cannot be read maps to its error, so
|
| 707 |
+
* it fails as that texture rather than the whole load.
|
| 708 |
+
*/
|
| 709 |
+
export function takePackagedTextures(scene, jobs, { maxBytes = Infinity } = {}) {
|
| 710 |
+
const out = new Map();
|
| 711 |
+
let left = maxBytes;
|
| 712 |
+
for (const { path } of jobs) {
|
| 713 |
+
if (!path.includes("[")) {
|
| 714 |
+
continue;
|
| 715 |
+
}
|
| 716 |
+
try {
|
| 717 |
+
const bytes = scene.packagedFile(path, left);
|
| 718 |
+
if (bytes) {
|
| 719 |
+
out.set(path, bytes);
|
| 720 |
+
}
|
| 721 |
+
left -= bytes?.byteLength ?? 0;
|
| 722 |
+
}
|
| 723 |
+
catch (error) {
|
| 724 |
+
out.set(path, error);
|
| 725 |
+
}
|
| 726 |
+
}
|
| 727 |
+
return out;
|
| 728 |
+
}
|
| 729 |
+
/** Long-side cap for data maps (roughness, metallic, occlusion, ...) in `preview` mode. */
|
| 730 |
+
const PREVIEW_DATA_SIZE = 512;
|
| 731 |
+
/**
|
| 732 |
+
* The texture files to load and the size to decode each to, base colors first.
|
| 733 |
+
* `preview`: base color up to `maxSize`, other maps up to 512 px, no normal
|
| 734 |
+
* maps. `full`: every map, including normals, up to `maxSize`. `none`: nothing.
|
| 735 |
+
*/
|
| 736 |
+
export function textureJobs(meta, { textures, maxSize }) {
|
| 737 |
+
if (textures === "none") {
|
| 738 |
+
return [];
|
| 739 |
+
}
|
| 740 |
+
const full = textures === "full";
|
| 741 |
+
const dataSize = full ? maxSize : Math.min(maxSize, PREVIEW_DATA_SIZE);
|
| 742 |
+
const tiers = [
|
| 743 |
+
[["diffuseColor"], maxSize],
|
| 744 |
+
[["opacity", "emissiveColor", "roughness", "metallic", "occlusion"], dataSize],
|
| 745 |
+
[full ? ["normal"] : [], maxSize],
|
| 746 |
+
];
|
| 747 |
+
const jobs = new Map();
|
| 748 |
+
for (const [inputs, size] of tiers) {
|
| 749 |
+
for (const m of meta.materials) {
|
| 750 |
+
for (const input of inputs) {
|
| 751 |
+
const path = m.maps[input]?.path;
|
| 752 |
+
// A file shared by several inputs is decoded once, at the largest size asked.
|
| 753 |
+
if (path) {
|
| 754 |
+
jobs.set(path, Math.max(jobs.get(path) ?? 0, size));
|
| 755 |
+
}
|
| 756 |
+
}
|
| 757 |
+
}
|
| 758 |
+
}
|
| 759 |
+
return [...jobs].map(([path, size]) => ({ path, size }));
|
| 760 |
+
}
|
services/explorer/dist/static/usd-reader/00c663a/esm/load-core.js.br
ADDED
|
Binary file (8.51 kB). View file
|
|
|
services/explorer/dist/static/usd-reader/00c663a/esm/worker.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Loads, composes and extracts a USD stage off the main thread, then streams
|
| 2 |
+
// textures as downscaled ImageBitmaps. One worker per load: the page
|
| 3 |
+
// terminates it when done, disposed or aborted, which releases all WASM memory.
|
| 4 |
+
import init, { lastPanic, UsdLoader } from "../wasm/usd_wasm.js";
|
| 5 |
+
import { hubPackageLayers, pinHubRevision } from "./hub-prefetch.js";
|
| 6 |
+
import { DEFAULTS, LOCAL, canonicalUrl, composeStage, fetchLimited, fetchWithPolicy, imageInfo, keyOfLocalUrl, limiter, loadFailure, readColliders, readGeometries, requestPolicy, takePackagedTextures, textureJobs, } from "./load-core.js";
|
| 7 |
+
// Textures in flight at once (fetch and decode): decoding a large image
|
| 8 |
+
// briefly holds it at full size, so wide parallelism spikes memory.
|
| 9 |
+
const TEXTURE_CONCURRENCY = 4;
|
| 10 |
+
// Longest side of an image read at all: larger ones are refused from their
|
| 11 |
+
// header, before decoding (WebGL's own limit is commonly 16384 too).
|
| 12 |
+
const MAX_IMAGE_SIZE = DEFAULTS.maxImageSize;
|
| 13 |
+
self.onmessage = async ({ data }) => {
|
| 14 |
+
const { url, wasmModule, maxTextureSize = DEFAULTS.maxTextureSize, textures = DEFAULTS.textures, maxConcurrentFetches = DEFAULTS.maxConcurrentFetches, maxLayerBytes, maxTextureBytes = DEFAULTS.maxTextureBytes, maxLayers, maxInstances, maxTriangles, allowedOrigins, headers, files, physics, } = data;
|
| 15 |
+
// Every request (layer, texture, Hub listing) goes through here, and
|
| 16 |
+
// through the request policy first. The caller's headers go only where
|
| 17 |
+
// cookies may, and never through a redirect off the Hub.
|
| 18 |
+
const request = async (target) => {
|
| 19 |
+
target = canonicalUrl(target);
|
| 20 |
+
const policy = requestPolicy(target, url, allowedOrigins);
|
| 21 |
+
// Reads like a network failure: a missing layer or a failed texture.
|
| 22 |
+
if (policy.refused !== undefined) {
|
| 23 |
+
throw new TypeError(`request refused: ${policy.refused}`);
|
| 24 |
+
}
|
| 25 |
+
if (target.startsWith(LOCAL)) {
|
| 26 |
+
const file = files?.get(keyOfLocalUrl(target));
|
| 27 |
+
return file ? new Response(file) : new Response(null, { status: 404 });
|
| 28 |
+
}
|
| 29 |
+
return fetchWithPolicy(target, policy, headers);
|
| 30 |
+
};
|
| 31 |
+
const fetchBytes = (target, budget) => fetchLimited(target, budget, { fetchFn: request });
|
| 32 |
+
// One budget for every texture, packaged ones first, then each fetched
|
| 33 |
+
// body as its bytes arrive. Bytes of a body cut short stay charged: they
|
| 34 |
+
// were downloaded.
|
| 35 |
+
let textureBytes = 0;
|
| 36 |
+
const chargeTexture = (bytes) => {
|
| 37 |
+
textureBytes += bytes;
|
| 38 |
+
if (textureBytes > maxTextureBytes) {
|
| 39 |
+
throw new Error(`textures exceed maxTextureBytes (${maxTextureBytes} bytes)`);
|
| 40 |
+
}
|
| 41 |
+
};
|
| 42 |
+
const progress = (p) => self.postMessage({ type: "progress", progress: p });
|
| 43 |
+
let wasmMemory;
|
| 44 |
+
try {
|
| 45 |
+
const t0 = performance.now();
|
| 46 |
+
// Looked up while the WASM module initializes.
|
| 47 |
+
const rootUrl = pinHubRevision(url, request);
|
| 48 |
+
const preload = rootUrl.then((root) => hubPackageLayers(root, request));
|
| 49 |
+
const wasm = await init({ module_or_path: wasmModule });
|
| 50 |
+
wasmMemory = wasm.memory;
|
| 51 |
+
const tInit = performance.now();
|
| 52 |
+
const { scene, meta, stats } = await composeStage({
|
| 53 |
+
UsdLoader,
|
| 54 |
+
fetchBytes,
|
| 55 |
+
rootUrl: await rootUrl,
|
| 56 |
+
maxConcurrentFetches,
|
| 57 |
+
maxLayerBytes,
|
| 58 |
+
maxLayers,
|
| 59 |
+
maxInstances,
|
| 60 |
+
allowedOrigins,
|
| 61 |
+
preload,
|
| 62 |
+
onProgress: progress,
|
| 63 |
+
physics: physics?.namespaces,
|
| 64 |
+
});
|
| 65 |
+
stats.initMs = tInit - t0;
|
| 66 |
+
self.postMessage({ type: "meta", meta });
|
| 67 |
+
// One mesh at a time: each is transferred (not copied) as soon as it is read.
|
| 68 |
+
const onGeometry = (index, g, arrays) => {
|
| 69 |
+
const transfer = arrays
|
| 70 |
+
? [arrays.positions, arrays.normals, arrays.colors, arrays.indices, ...arrays.uvs]
|
| 71 |
+
.filter((a) => !!a)
|
| 72 |
+
.map((a) => a.buffer)
|
| 73 |
+
: [];
|
| 74 |
+
self.postMessage({ type: "geometry", index, meta: g, arrays }, transfer);
|
| 75 |
+
progress({ stage: "geometry", loaded: index + 1, total: meta.geometryCount });
|
| 76 |
+
};
|
| 77 |
+
const warnings = readGeometries(scene, meta, onGeometry, { maxTriangles });
|
| 78 |
+
// Then the colliders (only when asked for), each transferred as it is read.
|
| 79 |
+
readColliders(scene, (index, c, arrays) => self.postMessage({ type: "collider", index, meta: c, arrays }, [arrays.points.buffer, arrays.indices.buffer]));
|
| 80 |
+
const jobs = textureJobs(meta, { textures, maxSize: maxTextureSize });
|
| 81 |
+
const packaged = takePackagedTextures(scene, jobs, { maxBytes: maxTextureBytes });
|
| 82 |
+
for (const entry of packaged.values()) {
|
| 83 |
+
if (!(entry instanceof Error)) {
|
| 84 |
+
textureBytes += entry.byteLength;
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
scene.free();
|
| 88 |
+
stats.warnings.push(...warnings);
|
| 89 |
+
stats.totalMs = performance.now() - t0;
|
| 90 |
+
stats.wasmMemoryBytes = wasm.memory.buffer.byteLength;
|
| 91 |
+
self.postMessage({ type: "scene", stats: stats });
|
| 92 |
+
let loaded = 0;
|
| 93 |
+
let bytes = 0;
|
| 94 |
+
progress({ stage: "textures", loaded, total: jobs.length, bytes });
|
| 95 |
+
// The limiter runs jobs in order, so base colors come first.
|
| 96 |
+
const throttle = limiter(Math.min(maxConcurrentFetches, TEXTURE_CONCURRENCY));
|
| 97 |
+
await Promise.all(jobs.map(({ path, size }) => throttle(async () => {
|
| 98 |
+
try {
|
| 99 |
+
const entry = packaged.get(path);
|
| 100 |
+
if (entry instanceof Error) {
|
| 101 |
+
throw entry;
|
| 102 |
+
}
|
| 103 |
+
// A packaged path is never a URL to fetch.
|
| 104 |
+
if (!entry && path.includes("[")) {
|
| 105 |
+
throw new Error(`not found in its package: ${path}`);
|
| 106 |
+
}
|
| 107 |
+
const image = entry ?? (await fetchBytes(path, chargeTexture));
|
| 108 |
+
bytes += image.byteLength;
|
| 109 |
+
const { bitmap, color } = await decodeTexture(image, size);
|
| 110 |
+
self.postMessage({ type: "texture", path, bitmap, color }, [bitmap]);
|
| 111 |
+
}
|
| 112 |
+
catch (error) {
|
| 113 |
+
self.postMessage({ type: "texture", path, error: String(error?.message || error) });
|
| 114 |
+
}
|
| 115 |
+
progress({ stage: "textures", loaded: ++loaded, total: jobs.length, bytes });
|
| 116 |
+
})));
|
| 117 |
+
self.postMessage({ type: "done" });
|
| 118 |
+
}
|
| 119 |
+
catch (error) {
|
| 120 |
+
self.postMessage({ type: "error", ...loadFailure(error, wasmMemory?.buffer.byteLength ?? 0, lastPanic) });
|
| 121 |
+
}
|
| 122 |
+
};
|
| 123 |
+
/**
|
| 124 |
+
* Decodes a PNG, JPEG or WebP straight to at most `maxSize` px on its long
|
| 125 |
+
* side, and tells whether it holds color (what `sourceColorSpace = "auto"`
|
| 126 |
+
* decodes as sRGB). Images whose size the header does not give, or that are
|
| 127 |
+
* too large, are refused before decoding.
|
| 128 |
+
*/
|
| 129 |
+
async function decodeTexture(bytes, maxSize) {
|
| 130 |
+
const info = imageInfo(bytes);
|
| 131 |
+
if (!info) {
|
| 132 |
+
throw new Error("unsupported image format: only PNG, JPEG and WebP are read");
|
| 133 |
+
}
|
| 134 |
+
if (Math.max(info.width, info.height) > MAX_IMAGE_SIZE) {
|
| 135 |
+
throw new Error(`image too large: ${info.width}x${info.height} (at most ${MAX_IMAGE_SIZE} px a side)`);
|
| 136 |
+
}
|
| 137 |
+
// USD texture coordinates put (0,0) at the bottom-left, three.js's default.
|
| 138 |
+
const options = {
|
| 139 |
+
imageOrientation: "flipY",
|
| 140 |
+
premultiplyAlpha: "none",
|
| 141 |
+
colorSpaceConversion: "none",
|
| 142 |
+
};
|
| 143 |
+
const scale = Math.min(1, maxSize / Math.max(info.width, info.height));
|
| 144 |
+
if (scale < 1) {
|
| 145 |
+
options.resizeWidth = Math.max(1, Math.round(info.width * scale));
|
| 146 |
+
options.resizeHeight = Math.max(1, Math.round(info.height * scale));
|
| 147 |
+
options.resizeQuality = "high";
|
| 148 |
+
}
|
| 149 |
+
return { bitmap: await createImageBitmap(new Blob([bytes]), options), color: info.color };
|
| 150 |
+
}
|
services/explorer/dist/static/usd-reader/00c663a/esm/worker.js.br
ADDED
|
Binary file (2.49 kB). View file
|
|
|
services/explorer/dist/static/usd-reader/00c663a/wasm/usd_wasm.js
ADDED
|
@@ -0,0 +1,760 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* @ts-self-types="./usd_wasm.d.ts" */
|
| 2 |
+
|
| 3 |
+
export class UsdLoader {
|
| 4 |
+
__destroy_into_raw() {
|
| 5 |
+
const ptr = this.__wbg_ptr;
|
| 6 |
+
this.__wbg_ptr = 0;
|
| 7 |
+
UsdLoaderFinalization.unregister(this);
|
| 8 |
+
return ptr;
|
| 9 |
+
}
|
| 10 |
+
free() {
|
| 11 |
+
const ptr = this.__destroy_into_raw();
|
| 12 |
+
wasm.__wbg_usdloader_free(ptr, 0);
|
| 13 |
+
}
|
| 14 |
+
/**
|
| 15 |
+
* Stores a layer and returns the layers it names outside unselected
|
| 16 |
+
* variants (see [`Loader::add_layer`]).
|
| 17 |
+
* @param {string} path
|
| 18 |
+
* @param {Uint8Array} bytes
|
| 19 |
+
* @returns {string[]}
|
| 20 |
+
*/
|
| 21 |
+
addLayer(path, bytes) {
|
| 22 |
+
try {
|
| 23 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 24 |
+
const ptr0 = passStringToWasm0(path, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
| 25 |
+
const len0 = WASM_VECTOR_LEN;
|
| 26 |
+
const ptr1 = passArray8ToWasm0(bytes, wasm.__wbindgen_export);
|
| 27 |
+
const len1 = WASM_VECTOR_LEN;
|
| 28 |
+
wasm.usdloader_addLayer(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
|
| 29 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 30 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 31 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 32 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 33 |
+
if (r3) {
|
| 34 |
+
throw takeObject(r2);
|
| 35 |
+
}
|
| 36 |
+
var v3 = getArrayJsValueFromWasm0(r0, r1);
|
| 37 |
+
wasm.__wbindgen_export3(r0, r1 * 4, 4);
|
| 38 |
+
return v3;
|
| 39 |
+
} finally {
|
| 40 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
/**
|
| 44 |
+
* Composes the stage at `root`. Returns the layers still missing; when
|
| 45 |
+
* that is empty the scene is ready for [`take_scene`](Self::take_scene).
|
| 46 |
+
* The scene draws at most `max_instances` mesh instances.
|
| 47 |
+
* @param {string} root
|
| 48 |
+
* @param {number} max_instances
|
| 49 |
+
* @returns {string[]}
|
| 50 |
+
*/
|
| 51 |
+
compose(root, max_instances) {
|
| 52 |
+
try {
|
| 53 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 54 |
+
const ptr0 = passStringToWasm0(root, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
| 55 |
+
const len0 = WASM_VECTOR_LEN;
|
| 56 |
+
wasm.usdloader_compose(retptr, this.__wbg_ptr, ptr0, len0, max_instances);
|
| 57 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 58 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 59 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 60 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 61 |
+
if (r3) {
|
| 62 |
+
throw takeObject(r2);
|
| 63 |
+
}
|
| 64 |
+
var v2 = getArrayJsValueFromWasm0(r0, r1);
|
| 65 |
+
wasm.__wbindgen_export3(r0, r1 * 4, 4);
|
| 66 |
+
return v2;
|
| 67 |
+
} finally {
|
| 68 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
/**
|
| 72 |
+
* @param {string} path
|
| 73 |
+
* @returns {boolean}
|
| 74 |
+
*/
|
| 75 |
+
has(path) {
|
| 76 |
+
const ptr0 = passStringToWasm0(path, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
| 77 |
+
const len0 = WASM_VECTOR_LEN;
|
| 78 |
+
const ret = wasm.usdloader_has(this.__wbg_ptr, ptr0, len0);
|
| 79 |
+
return ret !== 0;
|
| 80 |
+
}
|
| 81 |
+
/**
|
| 82 |
+
* @param {string} path
|
| 83 |
+
*/
|
| 84 |
+
markUnavailable(path) {
|
| 85 |
+
const ptr0 = passStringToWasm0(path, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
| 86 |
+
const len0 = WASM_VECTOR_LEN;
|
| 87 |
+
wasm.usdloader_markUnavailable(this.__wbg_ptr, ptr0, len0);
|
| 88 |
+
}
|
| 89 |
+
constructor() {
|
| 90 |
+
const ret = wasm.usdloader_new();
|
| 91 |
+
this.__wbg_ptr = ret;
|
| 92 |
+
UsdLoaderFinalization.register(this, this.__wbg_ptr, this);
|
| 93 |
+
return this;
|
| 94 |
+
}
|
| 95 |
+
/**
|
| 96 |
+
* Also reads the stage's physics when composing (see
|
| 97 |
+
* [`Loader::set_physics`]); `namespaces` are the host's own attribute
|
| 98 |
+
* namespaces (`["simready"]`). The scene's meta then carries `physics`,
|
| 99 |
+
* and [`UsdScene::read_collider`] reads its colliders.
|
| 100 |
+
* @param {string[]} namespaces
|
| 101 |
+
*/
|
| 102 |
+
setPhysics(namespaces) {
|
| 103 |
+
const ptr0 = passArrayJsValueToWasm0(namespaces, wasm.__wbindgen_export);
|
| 104 |
+
const len0 = WASM_VECTOR_LEN;
|
| 105 |
+
wasm.usdloader_setPhysics(this.__wbg_ptr, ptr0, len0);
|
| 106 |
+
}
|
| 107 |
+
/**
|
| 108 |
+
* Hands over the extracted scene and drops every stored layer.
|
| 109 |
+
* @returns {UsdScene}
|
| 110 |
+
*/
|
| 111 |
+
takeScene() {
|
| 112 |
+
try {
|
| 113 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 114 |
+
wasm.usdloader_takeScene(retptr, this.__wbg_ptr);
|
| 115 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 116 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 117 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 118 |
+
if (r2) {
|
| 119 |
+
throw takeObject(r1);
|
| 120 |
+
}
|
| 121 |
+
return UsdScene.__wrap(r0);
|
| 122 |
+
} finally {
|
| 123 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
}
|
| 127 |
+
if (Symbol.dispose) UsdLoader.prototype[Symbol.dispose] = UsdLoader.prototype.free;
|
| 128 |
+
|
| 129 |
+
/**
|
| 130 |
+
* A composed scene whose meshes are read one at a time: `read(i)` makes
|
| 131 |
+
* geometry `i` current, and the array getters move its data out (each once).
|
| 132 |
+
* Only the current mesh's arrays live in WASM memory at any time.
|
| 133 |
+
*/
|
| 134 |
+
export class UsdScene {
|
| 135 |
+
static __wrap(ptr) {
|
| 136 |
+
const obj = Object.create(UsdScene.prototype);
|
| 137 |
+
obj.__wbg_ptr = ptr;
|
| 138 |
+
UsdSceneFinalization.register(obj, obj.__wbg_ptr, obj);
|
| 139 |
+
return obj;
|
| 140 |
+
}
|
| 141 |
+
__destroy_into_raw() {
|
| 142 |
+
const ptr = this.__wbg_ptr;
|
| 143 |
+
this.__wbg_ptr = 0;
|
| 144 |
+
UsdSceneFinalization.unregister(this);
|
| 145 |
+
return ptr;
|
| 146 |
+
}
|
| 147 |
+
free() {
|
| 148 |
+
const ptr = this.__destroy_into_raw();
|
| 149 |
+
wasm.__wbg_usdscene_free(ptr, 0);
|
| 150 |
+
}
|
| 151 |
+
/**
|
| 152 |
+
* How many colliders the scene's physics holds (0 when it was not read).
|
| 153 |
+
* @returns {number}
|
| 154 |
+
*/
|
| 155 |
+
colliderCount() {
|
| 156 |
+
const ret = wasm.usdscene_colliderCount(this.__wbg_ptr);
|
| 157 |
+
return ret >>> 0;
|
| 158 |
+
}
|
| 159 |
+
/**
|
| 160 |
+
* @returns {Float32Array}
|
| 161 |
+
*/
|
| 162 |
+
colors() {
|
| 163 |
+
try {
|
| 164 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 165 |
+
wasm.usdscene_colors(retptr, this.__wbg_ptr);
|
| 166 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 167 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 168 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 169 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 170 |
+
if (r3) {
|
| 171 |
+
throw takeObject(r2);
|
| 172 |
+
}
|
| 173 |
+
var v1 = getArrayF32FromWasm0(r0, r1).slice();
|
| 174 |
+
wasm.__wbindgen_export3(r0, r1 * 4, 4);
|
| 175 |
+
return v1;
|
| 176 |
+
} finally {
|
| 177 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 178 |
+
}
|
| 179 |
+
}
|
| 180 |
+
/**
|
| 181 |
+
* Releases the stage once every geometry has been read.
|
| 182 |
+
*/
|
| 183 |
+
finish() {
|
| 184 |
+
wasm.usdscene_finish(this.__wbg_ptr);
|
| 185 |
+
}
|
| 186 |
+
/**
|
| 187 |
+
* Indices as 16-bit, for geometries with fewer than 65536 vertices.
|
| 188 |
+
* @returns {Uint16Array}
|
| 189 |
+
*/
|
| 190 |
+
indices16() {
|
| 191 |
+
try {
|
| 192 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 193 |
+
wasm.usdscene_indices16(retptr, this.__wbg_ptr);
|
| 194 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 195 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 196 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 197 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 198 |
+
if (r3) {
|
| 199 |
+
throw takeObject(r2);
|
| 200 |
+
}
|
| 201 |
+
var v1 = getArrayU16FromWasm0(r0, r1).slice();
|
| 202 |
+
wasm.__wbindgen_export3(r0, r1 * 2, 2);
|
| 203 |
+
return v1;
|
| 204 |
+
} finally {
|
| 205 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 206 |
+
}
|
| 207 |
+
}
|
| 208 |
+
/**
|
| 209 |
+
* @returns {Uint32Array}
|
| 210 |
+
*/
|
| 211 |
+
indices() {
|
| 212 |
+
try {
|
| 213 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 214 |
+
wasm.usdscene_indices(retptr, this.__wbg_ptr);
|
| 215 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 216 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 217 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 218 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 219 |
+
if (r3) {
|
| 220 |
+
throw takeObject(r2);
|
| 221 |
+
}
|
| 222 |
+
var v1 = getArrayU32FromWasm0(r0, r1).slice();
|
| 223 |
+
wasm.__wbindgen_export3(r0, r1 * 4, 4);
|
| 224 |
+
return v1;
|
| 225 |
+
} finally {
|
| 226 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 227 |
+
}
|
| 228 |
+
}
|
| 229 |
+
/**
|
| 230 |
+
* Everything but the triangle data, as JSON.
|
| 231 |
+
* @returns {string}
|
| 232 |
+
*/
|
| 233 |
+
meta() {
|
| 234 |
+
let deferred1_0;
|
| 235 |
+
let deferred1_1;
|
| 236 |
+
try {
|
| 237 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 238 |
+
wasm.usdscene_meta(retptr, this.__wbg_ptr);
|
| 239 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 240 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 241 |
+
deferred1_0 = r0;
|
| 242 |
+
deferred1_1 = r1;
|
| 243 |
+
return getStringFromWasm0(r0, r1);
|
| 244 |
+
} finally {
|
| 245 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 246 |
+
wasm.__wbindgen_export3(deferred1_0, deferred1_1, 1);
|
| 247 |
+
}
|
| 248 |
+
}
|
| 249 |
+
/**
|
| 250 |
+
* @returns {Float32Array}
|
| 251 |
+
*/
|
| 252 |
+
normals() {
|
| 253 |
+
try {
|
| 254 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 255 |
+
wasm.usdscene_normals(retptr, this.__wbg_ptr);
|
| 256 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 257 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 258 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 259 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 260 |
+
if (r3) {
|
| 261 |
+
throw takeObject(r2);
|
| 262 |
+
}
|
| 263 |
+
var v1 = getArrayF32FromWasm0(r0, r1).slice();
|
| 264 |
+
wasm.__wbindgen_export3(r0, r1 * 4, 4);
|
| 265 |
+
return v1;
|
| 266 |
+
} finally {
|
| 267 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 268 |
+
}
|
| 269 |
+
}
|
| 270 |
+
/**
|
| 271 |
+
* A texture that lives inside a USDZ package, if `path` names one there.
|
| 272 |
+
* Fails rather than expand it past `limit` bytes.
|
| 273 |
+
* @param {string} path
|
| 274 |
+
* @param {number} limit
|
| 275 |
+
* @returns {Uint8Array | undefined}
|
| 276 |
+
*/
|
| 277 |
+
packagedFile(path, limit) {
|
| 278 |
+
try {
|
| 279 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 280 |
+
const ptr0 = passStringToWasm0(path, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
| 281 |
+
const len0 = WASM_VECTOR_LEN;
|
| 282 |
+
wasm.usdscene_packagedFile(retptr, this.__wbg_ptr, ptr0, len0, limit);
|
| 283 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 284 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 285 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 286 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 287 |
+
if (r3) {
|
| 288 |
+
throw takeObject(r2);
|
| 289 |
+
}
|
| 290 |
+
let v2;
|
| 291 |
+
if (r0 !== 0) {
|
| 292 |
+
v2 = getArrayU8FromWasm0(r0, r1).slice();
|
| 293 |
+
wasm.__wbindgen_export3(r0, r1 * 1, 1);
|
| 294 |
+
}
|
| 295 |
+
return v2;
|
| 296 |
+
} finally {
|
| 297 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 298 |
+
}
|
| 299 |
+
}
|
| 300 |
+
/**
|
| 301 |
+
* @returns {Float32Array}
|
| 302 |
+
*/
|
| 303 |
+
positions() {
|
| 304 |
+
try {
|
| 305 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 306 |
+
wasm.usdscene_positions(retptr, this.__wbg_ptr);
|
| 307 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 308 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 309 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 310 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 311 |
+
if (r3) {
|
| 312 |
+
throw takeObject(r2);
|
| 313 |
+
}
|
| 314 |
+
var v1 = getArrayF32FromWasm0(r0, r1).slice();
|
| 315 |
+
wasm.__wbindgen_export3(r0, r1 * 4, 4);
|
| 316 |
+
return v1;
|
| 317 |
+
} finally {
|
| 318 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 319 |
+
}
|
| 320 |
+
}
|
| 321 |
+
/**
|
| 322 |
+
* Reads collider `index`: returns its metadata as JSON (`path`, `body`,
|
| 323 |
+
* `approximation`, `enabled`, `purpose`, `vertices`, `triangles`) and makes
|
| 324 |
+
* its points and triangle indices current for [`positions`](Self::positions)
|
| 325 |
+
* and [`indices`](Self::indices) (each once).
|
| 326 |
+
* @param {number} index
|
| 327 |
+
* @returns {string}
|
| 328 |
+
*/
|
| 329 |
+
readCollider(index) {
|
| 330 |
+
let deferred2_0;
|
| 331 |
+
let deferred2_1;
|
| 332 |
+
try {
|
| 333 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 334 |
+
wasm.usdscene_readCollider(retptr, this.__wbg_ptr, index);
|
| 335 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 336 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 337 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 338 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 339 |
+
var ptr1 = r0;
|
| 340 |
+
var len1 = r1;
|
| 341 |
+
if (r3) {
|
| 342 |
+
ptr1 = 0; len1 = 0;
|
| 343 |
+
throw takeObject(r2);
|
| 344 |
+
}
|
| 345 |
+
deferred2_0 = ptr1;
|
| 346 |
+
deferred2_1 = len1;
|
| 347 |
+
return getStringFromWasm0(ptr1, len1);
|
| 348 |
+
} finally {
|
| 349 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 350 |
+
wasm.__wbindgen_export3(deferred2_0, deferred2_1, 1);
|
| 351 |
+
}
|
| 352 |
+
}
|
| 353 |
+
/**
|
| 354 |
+
* Reads geometry `index` and returns its metadata as JSON, or `None` when
|
| 355 |
+
* the mesh has nothing drawable. A mesh with more than `max_triangles` is
|
| 356 |
+
* left unread: `{"overBudget": triangles, "path": prim path}`.
|
| 357 |
+
* @param {number} index
|
| 358 |
+
* @param {number} max_triangles
|
| 359 |
+
* @returns {string | undefined}
|
| 360 |
+
*/
|
| 361 |
+
read(index, max_triangles) {
|
| 362 |
+
try {
|
| 363 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 364 |
+
wasm.usdscene_read(retptr, this.__wbg_ptr, index, max_triangles);
|
| 365 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 366 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 367 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 368 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 369 |
+
if (r3) {
|
| 370 |
+
throw takeObject(r2);
|
| 371 |
+
}
|
| 372 |
+
let v1;
|
| 373 |
+
if (r0 !== 0) {
|
| 374 |
+
v1 = getStringFromWasm0(r0, r1);
|
| 375 |
+
wasm.__wbindgen_export3(r0, r1 * 1, 1);
|
| 376 |
+
}
|
| 377 |
+
return v1;
|
| 378 |
+
} finally {
|
| 379 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 380 |
+
}
|
| 381 |
+
}
|
| 382 |
+
/**
|
| 383 |
+
* UV set `set` (in the order of the geometry's `uvSets`).
|
| 384 |
+
* @param {number} set
|
| 385 |
+
* @returns {Float32Array}
|
| 386 |
+
*/
|
| 387 |
+
uvs(set) {
|
| 388 |
+
try {
|
| 389 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 390 |
+
wasm.usdscene_uvs(retptr, this.__wbg_ptr, set);
|
| 391 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 392 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 393 |
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
| 394 |
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
| 395 |
+
if (r3) {
|
| 396 |
+
throw takeObject(r2);
|
| 397 |
+
}
|
| 398 |
+
var v1 = getArrayF32FromWasm0(r0, r1).slice();
|
| 399 |
+
wasm.__wbindgen_export3(r0, r1 * 4, 4);
|
| 400 |
+
return v1;
|
| 401 |
+
} finally {
|
| 402 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 403 |
+
}
|
| 404 |
+
}
|
| 405 |
+
}
|
| 406 |
+
if (Symbol.dispose) UsdScene.prototype[Symbol.dispose] = UsdScene.prototype.free;
|
| 407 |
+
|
| 408 |
+
/**
|
| 409 |
+
* Takes the message of the last panic, if any.
|
| 410 |
+
* @returns {string | undefined}
|
| 411 |
+
*/
|
| 412 |
+
export function lastPanic() {
|
| 413 |
+
try {
|
| 414 |
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
| 415 |
+
wasm.lastPanic(retptr);
|
| 416 |
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
| 417 |
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
| 418 |
+
let v1;
|
| 419 |
+
if (r0 !== 0) {
|
| 420 |
+
v1 = getStringFromWasm0(r0, r1);
|
| 421 |
+
wasm.__wbindgen_export3(r0, r1 * 1, 1);
|
| 422 |
+
}
|
| 423 |
+
return v1;
|
| 424 |
+
} finally {
|
| 425 |
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
| 426 |
+
}
|
| 427 |
+
}
|
| 428 |
+
|
| 429 |
+
export function start() {
|
| 430 |
+
wasm.start();
|
| 431 |
+
}
|
| 432 |
+
function __wbg_get_imports() {
|
| 433 |
+
const import0 = {
|
| 434 |
+
__proto__: null,
|
| 435 |
+
__wbg_Error_30c8987f7c2ed4e2: function(arg0, arg1) {
|
| 436 |
+
const ret = Error(getStringFromWasm0(arg0, arg1));
|
| 437 |
+
return addHeapObject(ret);
|
| 438 |
+
},
|
| 439 |
+
__wbg___wbindgen_string_get_0380ccaa2f57f0d9: function(arg0, arg1) {
|
| 440 |
+
const obj = getObject(arg1);
|
| 441 |
+
const ret = typeof(obj) === 'string' ? obj : undefined;
|
| 442 |
+
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
| 443 |
+
var len1 = WASM_VECTOR_LEN;
|
| 444 |
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
| 445 |
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
| 446 |
+
},
|
| 447 |
+
__wbg___wbindgen_throw_41e9ee4f547fc59a: function(arg0, arg1) {
|
| 448 |
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
| 449 |
+
},
|
| 450 |
+
__wbindgen_generic_0000000000000001: function(arg0, arg1) {
|
| 451 |
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
| 452 |
+
const ret = getStringFromWasm0(arg0, arg1);
|
| 453 |
+
return addHeapObject(ret);
|
| 454 |
+
},
|
| 455 |
+
__wbindgen_object_drop_ref: function(arg0) {
|
| 456 |
+
takeObject(arg0);
|
| 457 |
+
},
|
| 458 |
+
};
|
| 459 |
+
return {
|
| 460 |
+
__proto__: null,
|
| 461 |
+
"./usd_wasm_bg.js": import0,
|
| 462 |
+
};
|
| 463 |
+
}
|
| 464 |
+
|
| 465 |
+
const UsdLoaderFinalization = (typeof FinalizationRegistry === 'undefined')
|
| 466 |
+
? { register: () => {}, unregister: () => {} }
|
| 467 |
+
: new FinalizationRegistry(ptr => wasm.__wbg_usdloader_free(ptr, 1));
|
| 468 |
+
const UsdSceneFinalization = (typeof FinalizationRegistry === 'undefined')
|
| 469 |
+
? { register: () => {}, unregister: () => {} }
|
| 470 |
+
: new FinalizationRegistry(ptr => wasm.__wbg_usdscene_free(ptr, 1));
|
| 471 |
+
|
| 472 |
+
function addHeapObject(obj) {
|
| 473 |
+
if (heap_next === heap.length) heap.push(heap.length + 1);
|
| 474 |
+
const idx = heap_next;
|
| 475 |
+
heap_next = heap[idx];
|
| 476 |
+
|
| 477 |
+
heap[idx] = obj;
|
| 478 |
+
return idx;
|
| 479 |
+
}
|
| 480 |
+
|
| 481 |
+
function dropObject(idx) {
|
| 482 |
+
if (idx < 1028) return;
|
| 483 |
+
heap[idx] = heap_next;
|
| 484 |
+
heap_next = idx;
|
| 485 |
+
}
|
| 486 |
+
|
| 487 |
+
function getArrayF32FromWasm0(ptr, len) {
|
| 488 |
+
ptr = ptr >>> 0;
|
| 489 |
+
return getFloat32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
|
| 490 |
+
}
|
| 491 |
+
|
| 492 |
+
function getArrayJsValueFromWasm0(ptr, len) {
|
| 493 |
+
ptr = ptr >>> 0;
|
| 494 |
+
const mem = getDataViewMemory0();
|
| 495 |
+
const result = [];
|
| 496 |
+
for (let i = ptr; i < ptr + 4 * len; i += 4) {
|
| 497 |
+
result.push(takeObject(mem.getUint32(i, true)));
|
| 498 |
+
}
|
| 499 |
+
return result;
|
| 500 |
+
}
|
| 501 |
+
|
| 502 |
+
function getArrayU16FromWasm0(ptr, len) {
|
| 503 |
+
ptr = ptr >>> 0;
|
| 504 |
+
return getUint16ArrayMemory0().subarray(ptr / 2, ptr / 2 + len);
|
| 505 |
+
}
|
| 506 |
+
|
| 507 |
+
function getArrayU32FromWasm0(ptr, len) {
|
| 508 |
+
ptr = ptr >>> 0;
|
| 509 |
+
return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
|
| 510 |
+
}
|
| 511 |
+
|
| 512 |
+
function getArrayU8FromWasm0(ptr, len) {
|
| 513 |
+
ptr = ptr >>> 0;
|
| 514 |
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
| 515 |
+
}
|
| 516 |
+
|
| 517 |
+
let cachedDataViewMemory0 = null;
|
| 518 |
+
function getDataViewMemory0() {
|
| 519 |
+
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
|
| 520 |
+
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
| 521 |
+
}
|
| 522 |
+
return cachedDataViewMemory0;
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
+
let cachedFloat32ArrayMemory0 = null;
|
| 526 |
+
function getFloat32ArrayMemory0() {
|
| 527 |
+
if (cachedFloat32ArrayMemory0 === null || cachedFloat32ArrayMemory0.byteLength === 0) {
|
| 528 |
+
cachedFloat32ArrayMemory0 = new Float32Array(wasm.memory.buffer);
|
| 529 |
+
}
|
| 530 |
+
return cachedFloat32ArrayMemory0;
|
| 531 |
+
}
|
| 532 |
+
|
| 533 |
+
function getStringFromWasm0(ptr, len) {
|
| 534 |
+
return decodeText(ptr >>> 0, len);
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
let cachedUint16ArrayMemory0 = null;
|
| 538 |
+
function getUint16ArrayMemory0() {
|
| 539 |
+
if (cachedUint16ArrayMemory0 === null || cachedUint16ArrayMemory0.byteLength === 0) {
|
| 540 |
+
cachedUint16ArrayMemory0 = new Uint16Array(wasm.memory.buffer);
|
| 541 |
+
}
|
| 542 |
+
return cachedUint16ArrayMemory0;
|
| 543 |
+
}
|
| 544 |
+
|
| 545 |
+
let cachedUint32ArrayMemory0 = null;
|
| 546 |
+
function getUint32ArrayMemory0() {
|
| 547 |
+
if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {
|
| 548 |
+
cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);
|
| 549 |
+
}
|
| 550 |
+
return cachedUint32ArrayMemory0;
|
| 551 |
+
}
|
| 552 |
+
|
| 553 |
+
let cachedUint8ArrayMemory0 = null;
|
| 554 |
+
function getUint8ArrayMemory0() {
|
| 555 |
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
| 556 |
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
| 557 |
+
}
|
| 558 |
+
return cachedUint8ArrayMemory0;
|
| 559 |
+
}
|
| 560 |
+
|
| 561 |
+
function getObject(idx) { return heap[idx]; }
|
| 562 |
+
|
| 563 |
+
let heap = new Array(1024).fill(undefined);
|
| 564 |
+
heap.push(undefined, null, true, false);
|
| 565 |
+
|
| 566 |
+
let heap_next = heap.length;
|
| 567 |
+
|
| 568 |
+
function isLikeNone(x) {
|
| 569 |
+
return x === undefined || x === null;
|
| 570 |
+
}
|
| 571 |
+
|
| 572 |
+
function passArray8ToWasm0(arg, malloc) {
|
| 573 |
+
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
| 574 |
+
getUint8ArrayMemory0().set(arg, ptr / 1);
|
| 575 |
+
WASM_VECTOR_LEN = arg.length;
|
| 576 |
+
return ptr;
|
| 577 |
+
}
|
| 578 |
+
|
| 579 |
+
function passArrayJsValueToWasm0(array, malloc) {
|
| 580 |
+
const ptr = malloc(array.length * 4, 4) >>> 0;
|
| 581 |
+
const mem = getDataViewMemory0();
|
| 582 |
+
for (let i = 0; i < array.length; i++) {
|
| 583 |
+
mem.setUint32(ptr + 4 * i, addHeapObject(array[i]), true);
|
| 584 |
+
}
|
| 585 |
+
WASM_VECTOR_LEN = array.length;
|
| 586 |
+
return ptr;
|
| 587 |
+
}
|
| 588 |
+
|
| 589 |
+
function passStringToWasm0(arg, malloc, realloc) {
|
| 590 |
+
if (realloc === undefined) {
|
| 591 |
+
const buf = cachedTextEncoder.encode(arg);
|
| 592 |
+
const ptr = malloc(buf.length, 1) >>> 0;
|
| 593 |
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
| 594 |
+
WASM_VECTOR_LEN = buf.length;
|
| 595 |
+
return ptr;
|
| 596 |
+
}
|
| 597 |
+
|
| 598 |
+
let len = arg.length;
|
| 599 |
+
let ptr = malloc(len, 1) >>> 0;
|
| 600 |
+
|
| 601 |
+
const mem = getUint8ArrayMemory0();
|
| 602 |
+
|
| 603 |
+
let offset = 0;
|
| 604 |
+
|
| 605 |
+
for (; offset < len; offset++) {
|
| 606 |
+
const code = arg.charCodeAt(offset);
|
| 607 |
+
if (code > 0x7F) break;
|
| 608 |
+
mem[ptr + offset] = code;
|
| 609 |
+
}
|
| 610 |
+
if (offset !== len) {
|
| 611 |
+
if (offset !== 0) {
|
| 612 |
+
arg = arg.slice(offset);
|
| 613 |
+
}
|
| 614 |
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
| 615 |
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
| 616 |
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
| 617 |
+
|
| 618 |
+
offset += ret.written;
|
| 619 |
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
| 620 |
+
}
|
| 621 |
+
|
| 622 |
+
WASM_VECTOR_LEN = offset;
|
| 623 |
+
return ptr;
|
| 624 |
+
}
|
| 625 |
+
|
| 626 |
+
function takeObject(idx) {
|
| 627 |
+
const ret = getObject(idx);
|
| 628 |
+
dropObject(idx);
|
| 629 |
+
return ret;
|
| 630 |
+
}
|
| 631 |
+
|
| 632 |
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
| 633 |
+
cachedTextDecoder.decode();
|
| 634 |
+
const MAX_SAFARI_DECODE_BYTES = 2146435072;
|
| 635 |
+
let numBytesDecoded = 0;
|
| 636 |
+
function decodeText(ptr, len) {
|
| 637 |
+
numBytesDecoded += len;
|
| 638 |
+
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
|
| 639 |
+
cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
| 640 |
+
cachedTextDecoder.decode();
|
| 641 |
+
numBytesDecoded = len;
|
| 642 |
+
}
|
| 643 |
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
| 644 |
+
}
|
| 645 |
+
|
| 646 |
+
const cachedTextEncoder = new TextEncoder();
|
| 647 |
+
|
| 648 |
+
if (!('encodeInto' in cachedTextEncoder)) {
|
| 649 |
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
| 650 |
+
const buf = cachedTextEncoder.encode(arg);
|
| 651 |
+
view.set(buf);
|
| 652 |
+
return {
|
| 653 |
+
read: arg.length,
|
| 654 |
+
written: buf.length
|
| 655 |
+
};
|
| 656 |
+
};
|
| 657 |
+
}
|
| 658 |
+
|
| 659 |
+
let WASM_VECTOR_LEN = 0;
|
| 660 |
+
|
| 661 |
+
let wasmModule, wasmInstance, wasm;
|
| 662 |
+
function __wbg_finalize_init(instance, module) {
|
| 663 |
+
wasmInstance = instance;
|
| 664 |
+
wasm = instance.exports;
|
| 665 |
+
wasmModule = module;
|
| 666 |
+
cachedDataViewMemory0 = null;
|
| 667 |
+
cachedFloat32ArrayMemory0 = null;
|
| 668 |
+
cachedUint16ArrayMemory0 = null;
|
| 669 |
+
cachedUint32ArrayMemory0 = null;
|
| 670 |
+
cachedUint8ArrayMemory0 = null;
|
| 671 |
+
wasm.__wbindgen_start();
|
| 672 |
+
return wasm;
|
| 673 |
+
}
|
| 674 |
+
|
| 675 |
+
async function __wbg_load(module, imports) {
|
| 676 |
+
if (typeof Response === 'function' && module instanceof Response) {
|
| 677 |
+
if (!module.ok) {
|
| 678 |
+
throw new Error(`failed to fetch Wasm: ${module.status} ${module.statusText} fetching '${module.url}'`);
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
| 682 |
+
try {
|
| 683 |
+
return await WebAssembly.instantiateStreaming(module, imports);
|
| 684 |
+
} catch (e) {
|
| 685 |
+
const validResponse = expectedResponseType(module.type);
|
| 686 |
+
|
| 687 |
+
if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
|
| 688 |
+
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
| 689 |
+
|
| 690 |
+
} else { throw e; }
|
| 691 |
+
}
|
| 692 |
+
}
|
| 693 |
+
|
| 694 |
+
const bytes = await module.arrayBuffer();
|
| 695 |
+
return await WebAssembly.instantiate(bytes, imports);
|
| 696 |
+
} else {
|
| 697 |
+
const instance = await WebAssembly.instantiate(module, imports);
|
| 698 |
+
|
| 699 |
+
if (instance instanceof WebAssembly.Instance) {
|
| 700 |
+
return { instance, module };
|
| 701 |
+
} else {
|
| 702 |
+
return instance;
|
| 703 |
+
}
|
| 704 |
+
}
|
| 705 |
+
|
| 706 |
+
function expectedResponseType(type) {
|
| 707 |
+
switch (type) {
|
| 708 |
+
case 'basic': case 'cors': case 'default': return true;
|
| 709 |
+
}
|
| 710 |
+
return false;
|
| 711 |
+
}
|
| 712 |
+
}
|
| 713 |
+
|
| 714 |
+
function initSync(module) {
|
| 715 |
+
if (wasm !== undefined) return wasm;
|
| 716 |
+
|
| 717 |
+
|
| 718 |
+
if (module !== undefined) {
|
| 719 |
+
if (Object.getPrototypeOf(module) === Object.prototype) {
|
| 720 |
+
({module} = module)
|
| 721 |
+
} else {
|
| 722 |
+
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
|
| 723 |
+
}
|
| 724 |
+
}
|
| 725 |
+
|
| 726 |
+
const imports = __wbg_get_imports();
|
| 727 |
+
if (!(module instanceof WebAssembly.Module)) {
|
| 728 |
+
module = new WebAssembly.Module(module);
|
| 729 |
+
}
|
| 730 |
+
const instance = new WebAssembly.Instance(module, imports);
|
| 731 |
+
return __wbg_finalize_init(instance, module);
|
| 732 |
+
}
|
| 733 |
+
|
| 734 |
+
async function __wbg_init(module_or_path) {
|
| 735 |
+
if (wasm !== undefined) return wasm;
|
| 736 |
+
|
| 737 |
+
|
| 738 |
+
if (module_or_path !== undefined) {
|
| 739 |
+
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
|
| 740 |
+
({module_or_path} = module_or_path)
|
| 741 |
+
} else {
|
| 742 |
+
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
|
| 743 |
+
}
|
| 744 |
+
}
|
| 745 |
+
|
| 746 |
+
if (module_or_path === undefined) {
|
| 747 |
+
module_or_path = new URL('usd_wasm_bg.wasm', import.meta.url);
|
| 748 |
+
}
|
| 749 |
+
const imports = __wbg_get_imports();
|
| 750 |
+
|
| 751 |
+
if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
|
| 752 |
+
module_or_path = fetch(module_or_path);
|
| 753 |
+
}
|
| 754 |
+
|
| 755 |
+
const { instance, module } = await __wbg_load(await module_or_path, imports);
|
| 756 |
+
|
| 757 |
+
return __wbg_finalize_init(instance, module);
|
| 758 |
+
}
|
| 759 |
+
|
| 760 |
+
export { initSync, __wbg_init as default };
|
services/explorer/dist/static/usd-reader/00c663a/wasm/usd_wasm.js.br
ADDED
|
Binary file (4.39 kB). View file
|
|
|
services/explorer/dist/static/usd-reader/00c663a/wasm/usd_wasm_bg.wasm
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:6eac411e5266dbfbf3157e560a85a9f156aa8a13a07f4bbc99b0e320e1495bb9
|
| 3 |
+
size 2280023
|
services/explorer/dist/static/usd-reader/00c663a/wasm/usd_wasm_bg.wasm.br
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:414418179b11d65a996b50eb9837a5bdf2b1254e46546a57f89f02d1ead8bb82
|
| 3 |
+
size 625241
|
services/explorer/dist/third-party-notices.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
Third-party notices — SimReady Central Explorer slim-ui-
|
| 2 |
|
| 3 |
The software in this web application's browser bundle includes the packages below, each under its own
|
| 4 |
license. Each entry gives the package, its version, its license and the license / notice text it ships.
|
|
|
|
| 1 |
+
Third-party notices — SimReady Central Explorer slim-ui-e06d4a92
|
| 2 |
|
| 3 |
The software in this web application's browser bundle includes the packages below, each under its own
|
| 4 |
license. Each entry gives the package, its version, its license and the license / notice text it ships.
|