@needle-tools/engine 6.0.0-alpha.4 → 6.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +11 -1
- package/dist/{gltf-progressive-CcSfG2Ja.js → gltf-progressive-B7lOWdLe.js} +117 -115
- package/dist/gltf-progressive-BpT9M5Mt.umd.cjs +10 -0
- package/dist/gltf-progressive-D0rzvhNG.min.js +10 -0
- package/dist/{materialx-B3qY8vPU.js → materialx-Bd9BE6LR.js} +1 -1
- package/dist/{materialx-BwYvA-4x.umd.cjs → materialx-CzRx9AGf.umd.cjs} +2 -2
- package/dist/{materialx-CTPhpPxI.min.js → materialx-x1m4IJd1.min.js} +1 -1
- package/dist/{needle-engine.bundle-Bmcb5t3w.min.js → needle-engine.bundle-D6mZl1dR.min.js} +29 -29
- package/dist/{needle-engine.bundle-BuUj9B4K.umd.cjs → needle-engine.bundle-DOHf03pR.umd.cjs} +14 -14
- package/dist/{needle-engine.bundle-0tD9EcNs.js → needle-engine.bundle-Hu7ZAxEI.js} +75 -69
- package/dist/needle-engine.d.ts +5 -5
- package/dist/needle-engine.js +192 -192
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{vendor-BQUQwut5.js → vendor-BatPc34p.js} +50 -41
- package/dist/{vendor-BJviq-Oq.umd.cjs → vendor-CDN1hirK.umd.cjs} +1 -1
- package/dist/{vendor-CdNldo8c.min.js → vendor-T07c_9f_.min.js} +1 -1
- package/lib/engine/api.d.ts +1 -1
- package/lib/engine/api.js +1 -1
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/engine_init.js +2 -2
- package/lib/engine/engine_init.js.map +1 -1
- package/lib/engine/engine_license.d.ts +7 -7
- package/lib/engine/engine_license.js +98 -78
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_networking_blob.js +3 -3
- package/lib/engine/engine_networking_blob.js.map +1 -1
- package/lib/engine/engine_utils_qrcode.js +2 -2
- package/lib/engine/engine_utils_qrcode.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js +5 -5
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.js +2 -2
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.loading.js +2 -2
- package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
- package/lib/engine/xr/TempXRContext.js +2 -2
- package/lib/engine/xr/TempXRContext.js.map +1 -1
- package/lib/engine-components/Renderer.d.ts +1 -1
- package/lib/engine-components/Renderer.js +2 -11
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.js +4 -4
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/package.json +6 -3
- package/plugins/common/license.js +4 -4
- package/plugins/license/README.md +38 -0
- package/plugins/license/cli.js +46 -0
- package/plugins/license/index.js +24 -0
- package/plugins/vite/license.js +4 -4
- package/src/engine/api.ts +1 -1
- package/src/engine/engine_init.ts +2 -2
- package/src/engine/engine_license.ts +93 -76
- package/src/engine/engine_networking_blob.ts +3 -3
- package/src/engine/engine_utils_qrcode.ts +2 -2
- package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -2
- package/src/engine/webcomponents/needle menu/needle-menu.ts +5 -5
- package/src/engine/webcomponents/needle-engine.loading.ts +2 -2
- package/src/engine/webcomponents/needle-engine.ts +2 -2
- package/src/engine/xr/TempXRContext.ts +2 -2
- package/src/engine-components/Renderer.ts +4 -13
- package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
- package/dist/gltf-progressive-BYG9UH7O.min.js +0 -10
- package/dist/gltf-progressive-sK--FWg7.umd.cjs +0 -10
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { getMeta } from "../common/config.cjs";
|
|
5
|
+
import { resolveLicense } from "../common/license.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Write a signed license file for a site that does not use a Needle build plugin.
|
|
9
|
+
* The file contains only the public, signed JWT. Never write the Cloud access token.
|
|
10
|
+
* @param {{ out?: string, team?: string, accessToken?: string }} [options]
|
|
11
|
+
* @returns {Promise<{ output: string, signed: boolean }>}
|
|
12
|
+
*/
|
|
13
|
+
export async function generateLicenseFile(options = {}) {
|
|
14
|
+
const output = resolve(options.out ?? "public/needle-license.json");
|
|
15
|
+
mkdirSync(dirname(output), { recursive: true });
|
|
16
|
+
// Clear a previous license before resolving, including when resolution throws.
|
|
17
|
+
writeFileSync(output, '{"jwt":""}\n');
|
|
18
|
+
const team = options.team ?? getMeta()?.license?.team;
|
|
19
|
+
const license = /** @type {{ jwt: string | null } | null} */ (
|
|
20
|
+
/** @type {unknown} */ (await resolveLicense({ team, accessToken: options.accessToken }))
|
|
21
|
+
);
|
|
22
|
+
if (license?.jwt) writeFileSync(output, JSON.stringify({ jwt: license.jwt }) + "\n");
|
|
23
|
+
return { output, signed: Boolean(license?.jwt) };
|
|
24
|
+
}
|
package/plugins/vite/license.js
CHANGED
|
@@ -49,12 +49,12 @@ export function needleLicense(command, config, userSettings) {
|
|
|
49
49
|
let modified = false;
|
|
50
50
|
|
|
51
51
|
// Replace license type
|
|
52
|
-
const index = src.indexOf("
|
|
52
|
+
const index = src.indexOf("__deG");
|
|
53
53
|
if (index >= 0) {
|
|
54
54
|
const end = src.indexOf(";", index);
|
|
55
55
|
if (end >= 0) {
|
|
56
56
|
const line = src.substring(index, end);
|
|
57
|
-
const replaced = "
|
|
57
|
+
const replaced = "__deG = \"" + licenseResult.type + "\"";
|
|
58
58
|
src = src.replace(line, replaced);
|
|
59
59
|
modified = true;
|
|
60
60
|
}
|
|
@@ -62,12 +62,12 @@ export function needleLicense(command, config, userSettings) {
|
|
|
62
62
|
|
|
63
63
|
// Replace license JWT (same pattern)
|
|
64
64
|
if (licenseResult.jwt) {
|
|
65
|
-
const jwtIndex = src.indexOf("
|
|
65
|
+
const jwtIndex = src.indexOf("yDKPfo");
|
|
66
66
|
if (jwtIndex >= 0) {
|
|
67
67
|
const jwtEnd = src.indexOf(";", jwtIndex);
|
|
68
68
|
if (jwtEnd >= 0) {
|
|
69
69
|
const jwtLine = src.substring(jwtIndex, jwtEnd);
|
|
70
|
-
const jwtReplaced = "
|
|
70
|
+
const jwtReplaced = "yDKPfo = \"" + licenseResult.jwt + "\"";
|
|
71
71
|
src = src.replace(jwtLine, jwtReplaced);
|
|
72
72
|
modified = true;
|
|
73
73
|
}
|
package/src/engine/api.ts
CHANGED
|
@@ -237,7 +237,7 @@ export * from "./engine_input.js";
|
|
|
237
237
|
export { InstancingUtil } from "./engine_instancing.js";
|
|
238
238
|
|
|
239
239
|
/** License checking utilities */
|
|
240
|
-
export {
|
|
240
|
+
export { KLnyx, _$sHuA, $jVksoCHS } from "./engine_license.js";
|
|
241
241
|
|
|
242
242
|
|
|
243
243
|
// ============================================================================
|
|
@@ -8,7 +8,7 @@ import { initBuiltinTypes } from "./codegen/register_types.js";
|
|
|
8
8
|
import { initSpatialConsole } from "./debug/debug_spatial_console.js";
|
|
9
9
|
import { initAddressableSerializers } from "./engine_addressables.js";
|
|
10
10
|
import { ensureAudioContextIsResumed } from "./engine_audio.js";
|
|
11
|
-
import {
|
|
11
|
+
import { $bqSkkSKJ } from "./engine_license.js";
|
|
12
12
|
import { initNeedleLoader } from "./engine_loaders.js";
|
|
13
13
|
import { initPhysics } from "./engine_physics_rapier.js";
|
|
14
14
|
import { initBuiltinSerializers } from "./engine_serialization_builtin_serializer.js";
|
|
@@ -59,7 +59,7 @@ export function initEngine() {
|
|
|
59
59
|
initPhysics();
|
|
60
60
|
initXR();
|
|
61
61
|
initSpatialConsole();
|
|
62
|
-
|
|
62
|
+
$bqSkkSKJ();
|
|
63
63
|
|
|
64
64
|
// Must be last. customElements.define() upgrades existing <needle-engine>
|
|
65
65
|
// elements synchronously, which can trigger context.create() and dispatch
|
|
@@ -42,19 +42,19 @@ function setLicenseTimeout(ctx: IContext, callback: () => void, delay: number) {
|
|
|
42
42
|
return timer;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const _$
|
|
45
|
+
const _$hziI: ((result: boolean) => void)[] = [];
|
|
46
46
|
|
|
47
47
|
// DO NOT EDIT MANUALLY
|
|
48
|
-
let
|
|
48
|
+
let __deG: string = "";
|
|
49
49
|
// eslint-disable-next-line prefer-const
|
|
50
|
-
let
|
|
50
|
+
let yDKPfo: string = "";
|
|
51
51
|
|
|
52
52
|
if (debug) {
|
|
53
|
-
console.log("License Type: " +
|
|
54
|
-
if (
|
|
55
|
-
console.log("License JWT: " +
|
|
53
|
+
console.log("License Type: " + __deG);
|
|
54
|
+
if (yDKPfo) {
|
|
55
|
+
console.log("License JWT: " + yDKPfo);
|
|
56
56
|
try {
|
|
57
|
-
const payload = JSON.parse(atob(
|
|
57
|
+
const payload = JSON.parse(atob(yDKPfo.split(".")[1].replace(/-/g, '+').replace(/_/g, '/')));
|
|
58
58
|
console.log("License JWT payload:", payload);
|
|
59
59
|
}
|
|
60
60
|
catch { console.log("License JWT payload: (failed to decode)"); }
|
|
@@ -65,8 +65,8 @@ if (debug) {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/** @internal */
|
|
68
|
-
export function $
|
|
69
|
-
switch (
|
|
68
|
+
export function $jVksoCHS() {
|
|
69
|
+
switch (__deG) {
|
|
70
70
|
case "pro":
|
|
71
71
|
case "enterprise":
|
|
72
72
|
return true;
|
|
@@ -75,8 +75,8 @@ export function $vnStLM() {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
/** @internal */
|
|
78
|
-
export function $
|
|
79
|
-
switch (
|
|
78
|
+
export function _$sHuA() {
|
|
79
|
+
switch (__deG) {
|
|
80
80
|
case "indie":
|
|
81
81
|
return true;
|
|
82
82
|
}
|
|
@@ -84,8 +84,8 @@ export function $TNE() {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
/** @internal */
|
|
87
|
-
export function $
|
|
88
|
-
switch (
|
|
87
|
+
export function $BZiUJx() {
|
|
88
|
+
switch (__deG) {
|
|
89
89
|
case "edu":
|
|
90
90
|
return true;
|
|
91
91
|
}
|
|
@@ -93,26 +93,26 @@ export function $wyQnLr() {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/** @internal */
|
|
96
|
-
export function
|
|
97
|
-
return $
|
|
96
|
+
export function KLnyx() {
|
|
97
|
+
return $jVksoCHS() || _$sHuA() || $BZiUJx();
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
/** @internal */
|
|
102
|
-
export function
|
|
103
|
-
if ($
|
|
102
|
+
export function _$jODX(cb: (result: boolean) => void) {
|
|
103
|
+
if ($jVksoCHS() || _$sHuA() || $BZiUJx()) {
|
|
104
104
|
cb(true);
|
|
105
105
|
return () => {};
|
|
106
106
|
}
|
|
107
|
-
_$
|
|
107
|
+
_$hziI.push(cb);
|
|
108
108
|
return () => {
|
|
109
|
-
const index = _$
|
|
110
|
-
if (index >= 0) _$
|
|
109
|
+
const index = _$hziI.indexOf(cb);
|
|
110
|
+
if (index >= 0) _$hziI.splice(index, 1);
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
function
|
|
115
|
-
for (const cb of _$
|
|
114
|
+
function __QVQhCm(result: boolean) {
|
|
115
|
+
for (const cb of _$hziI) {
|
|
116
116
|
try {
|
|
117
117
|
cb(result);
|
|
118
118
|
}
|
|
@@ -127,7 +127,7 @@ function SpVw(result: boolean) {
|
|
|
127
127
|
|
|
128
128
|
// ECDSA P-256 public key for verifying license JWTs (verification-only, safe to ship)
|
|
129
129
|
/* eslint-disable no-secrets/no-secrets -- public key, not a secret */
|
|
130
|
-
const
|
|
130
|
+
const _UHT = {
|
|
131
131
|
kty: "EC",
|
|
132
132
|
crv: "P-256",
|
|
133
133
|
x: "A34nyKMjhQYVgzeE4tyLUYdx34TAKogDa7v7PRaO9Lg",
|
|
@@ -151,7 +151,7 @@ function base64urlDecode(str: string): Uint8Array {
|
|
|
151
151
|
* Verify a JWT license token and return the `type` claim if valid.
|
|
152
152
|
* Returns null if the JWT is missing, malformed, or has an invalid signature.
|
|
153
153
|
*/
|
|
154
|
-
async function
|
|
154
|
+
async function _$IUNmiHVF(jwt: string): Promise<string | null> {
|
|
155
155
|
if (!jwt) return null;
|
|
156
156
|
try {
|
|
157
157
|
const parts = jwt.split(".");
|
|
@@ -161,7 +161,7 @@ async function QyCIa(jwt: string): Promise<string | null> {
|
|
|
161
161
|
|
|
162
162
|
const key = await crypto.subtle.importKey(
|
|
163
163
|
"jwk",
|
|
164
|
-
|
|
164
|
+
_UHT,
|
|
165
165
|
{ name: "ECDSA", namedCurve: "P-256" },
|
|
166
166
|
false,
|
|
167
167
|
["verify"]
|
|
@@ -221,24 +221,40 @@ async function QyCIa(jwt: string): Promise<string | null> {
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
/** Verify the injected JWT and update the license type if valid.
|
|
224
|
-
* The engine ONLY trusts the JWT — the plain
|
|
224
|
+
* The engine ONLY trusts the JWT — the plain __deG string is ignored. */
|
|
225
225
|
let _jwtVerificationPromise: Promise<void> | undefined = undefined;
|
|
226
|
-
async function
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
//
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
//
|
|
233
|
-
|
|
234
|
-
|
|
226
|
+
async function wJwFeUbX(): Promise<void> {
|
|
227
|
+
// The bundled JWT may be empty when a build supplies a signed license file.
|
|
228
|
+
// Do not return early: the meta tag below may provide the JWT instead.
|
|
229
|
+
// Keep the bundled binding mutable so Vite's esbuild pre-bundling does not
|
|
230
|
+
// treat its initial empty value as constant and remove JWT verification.
|
|
231
|
+
let jwt = yDKPfo;
|
|
232
|
+
// Clear the bundled JWT after reading it; this assignment keeps the binding mutable.
|
|
233
|
+
yDKPfo = "";
|
|
234
|
+
if (!jwt && typeof document !== "undefined") {
|
|
235
|
+
const licenseFile = document.querySelector('meta[name="needle-license"]')?.getAttribute("content");
|
|
236
|
+
if (licenseFile) {
|
|
237
|
+
try {
|
|
238
|
+
const url = new URL(licenseFile, document.baseURI);
|
|
239
|
+
const response = await fetch(url, { cache: "no-store" });
|
|
240
|
+
if (response.ok) {
|
|
241
|
+
const data = await response.json();
|
|
242
|
+
if (typeof data?.jwt === "string") jwt = data.jwt;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
if (debug) console.warn("Could not load signed license file", err);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const verifiedType = await _$IUNmiHVF(jwt);
|
|
235
251
|
if (verifiedType) {
|
|
236
|
-
|
|
252
|
+
__deG = verifiedType;
|
|
237
253
|
if (debug) console.log("License type set from verified JWT: " + verifiedType);
|
|
238
|
-
|
|
254
|
+
__QVQhCm(KLnyx());
|
|
239
255
|
}
|
|
240
256
|
else {
|
|
241
|
-
|
|
257
|
+
__deG = "basic";
|
|
242
258
|
if (debug && jwt) console.warn("JWT verification failed — license reset to basic");
|
|
243
259
|
}
|
|
244
260
|
}
|
|
@@ -361,7 +377,7 @@ export namespace Telemetry {
|
|
|
361
377
|
// NOTE: this does NOT affect license enforcement — the /check call, the "forbidden"
|
|
362
378
|
// overlay and the watermark/logo run on separate, ungated code paths.
|
|
363
379
|
const attribute = domElement?.getAttribute("no-telemetry");
|
|
364
|
-
if ($
|
|
380
|
+
if ($jVksoCHS() && (attribute === "" || attribute === "true" || attribute === "1")) {
|
|
365
381
|
if (debug) console.debug("Telemetry is disabled via no-telemetry attribute");
|
|
366
382
|
return false;
|
|
367
383
|
}
|
|
@@ -689,18 +705,21 @@ export namespace Telemetry {
|
|
|
689
705
|
}
|
|
690
706
|
|
|
691
707
|
|
|
692
|
-
export function
|
|
708
|
+
export function $bqSkkSKJ() {
|
|
693
709
|
|
|
694
|
-
if(
|
|
710
|
+
if(__deG === "") __deG = "basic";
|
|
695
711
|
|
|
696
712
|
// Start JWT verification — must be here (not top-level) to avoid tree-shaking
|
|
697
|
-
_jwtVerificationPromise =
|
|
713
|
+
_jwtVerificationPromise = wJwFeUbX();
|
|
714
|
+
// Start after setting the initial type. At module scope the type was still "",
|
|
715
|
+
// so Basic builds skipped the runtime check entirely.
|
|
716
|
+
_$cThps = __zwPG();
|
|
698
717
|
|
|
699
718
|
Telemetry.init();
|
|
700
719
|
ContextRegistry.registerCallback(ContextEvent.ContextRegistered, evt => {
|
|
701
|
-
|
|
702
|
-
$
|
|
703
|
-
setLicenseTimeout(evt.context, () =>
|
|
720
|
+
pTWobY(evt.context);
|
|
721
|
+
_$XfWxk(evt.context);
|
|
722
|
+
setLicenseTimeout(evt.context, () => _YuMDhu(evt.context), 2000);
|
|
704
723
|
});
|
|
705
724
|
// ContextCreated fires after the renderer exists, so the canvas is available for context-loss monitoring
|
|
706
725
|
ContextRegistry.registerCallback(ContextEvent.ContextCreated, evt => {
|
|
@@ -709,17 +728,17 @@ export function FiUWO() {
|
|
|
709
728
|
});
|
|
710
729
|
}
|
|
711
730
|
|
|
712
|
-
export let
|
|
731
|
+
export let _$cThps: Promise<void> | undefined = undefined;
|
|
713
732
|
let applicationIsForbidden = false;
|
|
714
733
|
let applicationForbiddenText = "";
|
|
715
|
-
async function
|
|
734
|
+
async function __zwPG() {
|
|
716
735
|
// Only perform the runtime license check once
|
|
717
|
-
if (
|
|
736
|
+
if (_$cThps) return _$cThps;
|
|
718
737
|
// Wait for JWT verification to complete first (if running)
|
|
719
738
|
if (_jwtVerificationPromise) {
|
|
720
739
|
await _jwtVerificationPromise;
|
|
721
740
|
}
|
|
722
|
-
if (
|
|
741
|
+
if (__deG === "basic") {
|
|
723
742
|
try {
|
|
724
743
|
const licenseUrl = "https://needle.tools/api/v1/needle-engine/check?location=" + encodeURIComponent(window.location.href) + "&version=" + VERSION + "&generator=" + encodeURIComponent(GENERATOR);
|
|
725
744
|
const res = await fetch(licenseUrl, {
|
|
@@ -731,29 +750,27 @@ async function _$CByS() {
|
|
|
731
750
|
if (res?.status === 200) {
|
|
732
751
|
applicationIsForbidden = false;
|
|
733
752
|
if (debug) console.log("License check succeeded");
|
|
734
|
-
|
|
735
|
-
|
|
753
|
+
__deG = "pro";
|
|
754
|
+
__QVQhCm(true);
|
|
736
755
|
}
|
|
737
756
|
else if (res?.status === 403) {
|
|
738
|
-
|
|
757
|
+
__QVQhCm(false);
|
|
739
758
|
applicationIsForbidden = true;
|
|
740
759
|
applicationForbiddenText = await res.text();
|
|
741
760
|
}
|
|
742
761
|
else {
|
|
743
|
-
|
|
762
|
+
__QVQhCm(false);
|
|
744
763
|
if (debug) console.log("License check failed with status " + res?.status);
|
|
745
764
|
}
|
|
746
765
|
}
|
|
747
766
|
catch (err) {
|
|
748
|
-
|
|
767
|
+
__QVQhCm(false);
|
|
749
768
|
if (debug) console.error("License check failed", err);
|
|
750
769
|
}
|
|
751
770
|
}
|
|
752
|
-
else if (debug) console.log("Runtime license check is skipped because license is already applied as \"" +
|
|
771
|
+
else if (debug) console.log("Runtime license check is skipped because license is already applied as \"" + __deG + "\"");
|
|
753
772
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
async function $FUD(ctx: IContext) {
|
|
773
|
+
async function _$XfWxk(ctx: IContext) {
|
|
757
774
|
function createForbiddenElement() {
|
|
758
775
|
const div = document.createElement("div");
|
|
759
776
|
div.className = "needle-forbidden";
|
|
@@ -818,40 +835,40 @@ async function $FUD(ctx: IContext) {
|
|
|
818
835
|
}, 500)
|
|
819
836
|
}
|
|
820
837
|
|
|
821
|
-
async function
|
|
838
|
+
async function pTWobY(ctx: IContext) {
|
|
822
839
|
try {
|
|
823
|
-
if (!$
|
|
824
|
-
return
|
|
840
|
+
if (!$jVksoCHS() && !_$sHuA()) {
|
|
841
|
+
return $KXTmgnjE(ctx);
|
|
825
842
|
}
|
|
826
843
|
}
|
|
827
844
|
catch (err) {
|
|
828
845
|
if (debug) console.log("License check failed", err)
|
|
829
|
-
return
|
|
846
|
+
return $KXTmgnjE(ctx)
|
|
830
847
|
}
|
|
831
|
-
if (debug)
|
|
848
|
+
if (debug) $KXTmgnjE(ctx)
|
|
832
849
|
}
|
|
833
850
|
|
|
834
851
|
|
|
835
852
|
|
|
836
|
-
async function
|
|
853
|
+
async function $KXTmgnjE(ctx: IContext) {
|
|
837
854
|
|
|
838
855
|
// if the engine loads faster than the license check, we need to capture the ready event here
|
|
839
856
|
let isReady = false;
|
|
840
857
|
ctx.domElement.addEventListener("ready", () => isReady = true);
|
|
841
858
|
|
|
842
|
-
await
|
|
859
|
+
await _$cThps?.catch(() => { });
|
|
843
860
|
|
|
844
861
|
|
|
845
|
-
if ($
|
|
846
|
-
if (
|
|
862
|
+
if ($jVksoCHS() || _$sHuA()) return;
|
|
863
|
+
if (KLnyx() === false) $vKd();
|
|
847
864
|
|
|
848
865
|
// check if the engine is already ready (meaning has finished loading)
|
|
849
866
|
if (isReady) {
|
|
850
|
-
|
|
867
|
+
__OzoZ(ctx);
|
|
851
868
|
}
|
|
852
869
|
else {
|
|
853
870
|
ctx.domElement.addEventListener("ready", () => {
|
|
854
|
-
|
|
871
|
+
__OzoZ(ctx);
|
|
855
872
|
});
|
|
856
873
|
}
|
|
857
874
|
}
|
|
@@ -859,7 +876,7 @@ async function fFIu(ctx: IContext) {
|
|
|
859
876
|
// const licenseElementIdentifier = "needle-license-element";
|
|
860
877
|
// const licenseDuration = 10000;
|
|
861
878
|
// const licenseDelay = 1200;
|
|
862
|
-
function
|
|
879
|
+
function __OzoZ(ctx: IContext) {
|
|
863
880
|
|
|
864
881
|
const style = `
|
|
865
882
|
position: relative;
|
|
@@ -872,7 +889,7 @@ function fWqZoV(ctx: IContext) {
|
|
|
872
889
|
padding: 10px;
|
|
873
890
|
padding-left: 30px;
|
|
874
891
|
`;
|
|
875
|
-
if (
|
|
892
|
+
if (__deG === "edu") {
|
|
876
893
|
if (navigator.webdriver) {
|
|
877
894
|
console.log("This project is supported by Needle for Education – https://needle.tools");
|
|
878
895
|
}
|
|
@@ -929,7 +946,7 @@ function fWqZoV(ctx: IContext) {
|
|
|
929
946
|
}
|
|
930
947
|
}, 1000);
|
|
931
948
|
|
|
932
|
-
if ($
|
|
949
|
+
if ($BZiUJx()) {
|
|
933
950
|
const removeDelay = 20_000;
|
|
934
951
|
setLicenseTimeout(ctx, () => {
|
|
935
952
|
clearInterval(interval);
|
|
@@ -938,7 +955,7 @@ function fWqZoV(ctx: IContext) {
|
|
|
938
955
|
const intervalInMinutes = 5;
|
|
939
956
|
setLicenseTimeout(ctx, () => {
|
|
940
957
|
if (ctx.domElement.parentNode)
|
|
941
|
-
|
|
958
|
+
__OzoZ(ctx);
|
|
942
959
|
}, 1000 * 60 * intervalInMinutes)
|
|
943
960
|
}, removeDelay);
|
|
944
961
|
}
|
|
@@ -949,7 +966,7 @@ function fWqZoV(ctx: IContext) {
|
|
|
949
966
|
const base64Logo = "data:image/webp;base64,UklGRrABAABXRUJQVlA4WAoAAAAQAAAAHwAAHwAAQUxQSKEAAAARN6CmbSM4WR7vdARON11EBDq3fLiNbVtVzpMCPlKAEzsx0Y/x+Ovuv4dn0EFE/ydAvz6YggXzgh5sVgXM/zOC/4sii7qgGvB5N7hmuQYwkvazWAu1JPW41FXSHq6pnaQWvqYH18Fc0j1hO/BFTtIeSBlJi5w6qIIO7IOrwhFsB2Yxukif0FTRLpXswHR8MxbslKe9VZsn/Ub5C7YFOpqSTABWUDgg6AAAAFAGAJ0BKiAAIAA+7VyoTqmkpCI3+qgBMB2JbACdMt69DwMIQBLhkTO6XwY00UEDK6cNIDnuNibPf0EgAP7Y1myuiQHLDsF/0h5unrGh6WAbv7aegg2ZMd3uRKfT/3SJztcaujYfTvMXspfCTmYcoO6a+vhC3ss4M8uM58t4siiu59I4aOl59e9Sr6xoxYlHf2v+NnBNpJYeJf8jABQAId/PXuBkLEFkiCucgSGEcfhvajql/j3reCGl0M5/9gQWy7ayNPs+wlvIxFnNfSlfuND4CZOCyxOHhRqOmHN4ULHo3tCSrUNvgAA=";
|
|
950
967
|
|
|
951
968
|
let lastLogTime = 0;
|
|
952
|
-
async function
|
|
969
|
+
async function $vKd(_logo?: string) {
|
|
953
970
|
const now = Date.now();
|
|
954
971
|
if (now - lastLogTime < 2000) return;
|
|
955
972
|
lastLogTime = now;
|
|
@@ -982,7 +999,7 @@ async function Yjj(_logo?: string) {
|
|
|
982
999
|
}
|
|
983
1000
|
|
|
984
1001
|
|
|
985
|
-
async function
|
|
1002
|
+
async function _YuMDhu(context: IContext) {
|
|
986
1003
|
// isAllowed() now also covers cross-origin-isolated pages (where beacons can't be sent)
|
|
987
1004
|
// and Do Not Track / GPC.
|
|
988
1005
|
if (!Telemetry.isAllowed(context)) {
|
|
@@ -996,7 +1013,7 @@ async function __jDHSHz(context: IContext) {
|
|
|
996
1013
|
|
|
997
1014
|
// current url without query parameters
|
|
998
1015
|
const currentUrl = window.location.href.split("?")[0];
|
|
999
|
-
const license =
|
|
1016
|
+
const license = __deG;
|
|
1000
1017
|
|
|
1001
1018
|
const beaconData = {
|
|
1002
1019
|
license,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FileLoader } from "three";
|
|
2
2
|
|
|
3
3
|
import { showBalloonWarning } from "./debug/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { KLnyx } from "./engine_license.js";
|
|
5
5
|
import { delay } from "./engine_utils.js";
|
|
6
6
|
import { md5AsBytes, md5Hex, sha256Base64 } from "./engine_utils_hash.js";
|
|
7
7
|
|
|
@@ -45,7 +45,7 @@ export namespace BlobStorage {
|
|
|
45
45
|
*/
|
|
46
46
|
export function canUpload(info: { filesize: number }) {
|
|
47
47
|
const sizeInMB = info.filesize / 1024 / 1024;
|
|
48
|
-
if (
|
|
48
|
+
if (KLnyx()) {
|
|
49
49
|
return sizeInMB < maxSizeInMB;
|
|
50
50
|
}
|
|
51
51
|
return sizeInMB < maxFreeSizeInMB;
|
|
@@ -100,7 +100,7 @@ export namespace BlobStorage {
|
|
|
100
100
|
console.warn(`Your file is too large for uploading (${filesizeInMB.toFixed(1)}MB). Max allowed size is ${maxSizeInMB}MB`);
|
|
101
101
|
return null;
|
|
102
102
|
}
|
|
103
|
-
else if (!
|
|
103
|
+
else if (!KLnyx() && filesizeInMB > maxFreeSizeInMB) {
|
|
104
104
|
if (opts?.silent !== true) showBalloonWarning(`File is too large for uploading. Please get a <a href=\"https://needle.tools/pricing\" target=\"_blank\">commercial license</a> to upload files larger than 5MB`);
|
|
105
105
|
console.warn(`Your file is too large for uploading (${filesizeInMB.toFixed(1)}MB). Max size is 5MB for non-commercial users. Please get a commercial license at https://needle.tools/pricing for larger files (up to 50MB)`);
|
|
106
106
|
return null;
|
|
@@ -4,7 +4,7 @@ import { Quaternion, Vector2, Vector3, Vector4 } from "three";
|
|
|
4
4
|
|
|
5
5
|
import { needleLogoOnlySVG } from "./assets/index.js";
|
|
6
6
|
import { isDevEnvironment } from "./debug/debug.js";
|
|
7
|
-
import {
|
|
7
|
+
import { KLnyx } from "./engine_license.js";
|
|
8
8
|
import { InternalAttributeUtils } from "./engine_utils_attributes.js";
|
|
9
9
|
import type { NeedleEngineWebComponent } from "./webcomponents/needle-engine.js";
|
|
10
10
|
|
|
@@ -135,7 +135,7 @@ async function internalRenderQRCodeOverlays(canvas: HTMLCanvasElement, args: { s
|
|
|
135
135
|
console.debug("[QR Code] No web component found")
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
const canUseCustomLogo =
|
|
138
|
+
const canUseCustomLogo = KLnyx();
|
|
139
139
|
|
|
140
140
|
// Query logo src from needle-engine attribute.
|
|
141
141
|
// For any supported attribute it's possible to use "falsey" values (e.g. "0" or "false" to disable the logo in the QR code)
|
|
@@ -2,7 +2,7 @@ import { Mesh, Object3D, TextureLoader, Vector4 } from "three";
|
|
|
2
2
|
import ThreeMeshUI from "three-mesh-ui";
|
|
3
3
|
|
|
4
4
|
import { addNewComponent } from "../../engine_components.js";
|
|
5
|
-
import {
|
|
5
|
+
import { KLnyx } from "../../engine_license.js";
|
|
6
6
|
import { OneEuroFilterXYZ } from "../../engine_math.js";
|
|
7
7
|
import type { Context } from "../../engine_setup.js";
|
|
8
8
|
import { lookAtObject } from "../../engine_three_utils.js";
|
|
@@ -321,7 +321,7 @@ export class NeedleSpatialMenu {
|
|
|
321
321
|
}
|
|
322
322
|
if (this.menu) {
|
|
323
323
|
const index = this.menu.children.indexOf(this._poweredByNeedleElement as any);
|
|
324
|
-
if (!this._showNeedleLogo &&
|
|
324
|
+
if (!this._showNeedleLogo && KLnyx()) {
|
|
325
325
|
if (index >= 0) {
|
|
326
326
|
this._poweredByNeedleElement.removeFromParent();
|
|
327
327
|
this.markDirty();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { showBalloonMessage } from "../../debug/debug.js";
|
|
2
2
|
import type { Context } from "../../engine_context.js";
|
|
3
|
-
import { _$
|
|
3
|
+
import { KLnyx, _$jODX, Telemetry } from "../../engine_license.js";
|
|
4
4
|
import { isLocalNetwork } from "../../engine_networking_utils.js";
|
|
5
5
|
import { HTMLElementBase } from "../../engine_ssr.js";
|
|
6
6
|
import { DeviceUtilities, getParam } from "../../engine_utils.js";
|
|
@@ -801,8 +801,8 @@ export class NeedleMenuElement extends HTMLElementBase {
|
|
|
801
801
|
// calling this method immediately will cause an issue with vite bundling tho
|
|
802
802
|
this._licenseFrame = window.requestAnimationFrame(() => {
|
|
803
803
|
this._licenseFrame = undefined;
|
|
804
|
-
this._unsubscribeLicense =
|
|
805
|
-
if (res == true &&
|
|
804
|
+
this._unsubscribeLicense = _$jODX(res => {
|
|
805
|
+
if (res == true && KLnyx() && !debugNonCommercial) {
|
|
806
806
|
let visible = this._userRequestedLogoVisible;
|
|
807
807
|
if (visible === undefined) visible = false;
|
|
808
808
|
this.___onSetLogoVisible(visible);
|
|
@@ -854,7 +854,7 @@ export class NeedleMenuElement extends HTMLElementBase {
|
|
|
854
854
|
// ensure the menu is not hidden or removed
|
|
855
855
|
const requiredParent = this?.parentNode;
|
|
856
856
|
if (this.style.display != "flex" || this.style.visibility != "visible" || this.style.opacity != "1" || requiredParent != this._domElement?.shadowRoot) {
|
|
857
|
-
if (!
|
|
857
|
+
if (!KLnyx()) {
|
|
858
858
|
const change = changeEventCounter++;
|
|
859
859
|
// if a user doesn't have a local pro license *but* for development the menu is hidden then we show a warning
|
|
860
860
|
if (isLocalNetwork() && this._userRequestedMenuVisible === false) {
|
|
@@ -950,7 +950,7 @@ export class NeedleMenuElement extends HTMLElementBase {
|
|
|
950
950
|
showNeedleLogo(visible: boolean) {
|
|
951
951
|
this._userRequestedLogoVisible = visible;
|
|
952
952
|
if (!visible) {
|
|
953
|
-
if (!
|
|
953
|
+
if (!KLnyx() || debugNonCommercial) {
|
|
954
954
|
console.warn("[Needle Engine] You need a commercial license to hide the Needle Engine logo in production.");
|
|
955
955
|
const localNetwork = isLocalNetwork()
|
|
956
956
|
if (!localNetwork) return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { needleLogoOnlySVG } from "../assets/index.js"
|
|
2
2
|
import { showBalloonWarning } from "../debug/index.js";
|
|
3
|
-
import { $
|
|
3
|
+
import { $jVksoCHS } from "../engine_license.js";
|
|
4
4
|
import { Mathf } from "../engine_math.js";
|
|
5
5
|
import { LoadingProgressArgs } from "../engine_setup.js";
|
|
6
6
|
import { getParam } from "../engine_utils.js";
|
|
@@ -402,7 +402,7 @@ export class EngineLoadingView implements ILoadingViewHandler {
|
|
|
402
402
|
const logoToggle = InternalAttributeUtils.getAttributeAndCheckFalsey(this._element, "loading-logo");
|
|
403
403
|
const showLogo = logoToggle !== null && logoToggle !== false;
|
|
404
404
|
|
|
405
|
-
const hasLicense = $
|
|
405
|
+
const hasLicense = $jVksoCHS();
|
|
406
406
|
|
|
407
407
|
const className = this._loadingElementOptions?.className ?? EngineLoadingView.LoadingContainerClassName;
|
|
408
408
|
el.classList.add(className);
|
|
@@ -3,7 +3,7 @@ import type { Texture } from "three";
|
|
|
3
3
|
import { isDevEnvironment, showBalloonWarning } from "../debug/index.js";
|
|
4
4
|
import { PUBLIC_KEY, VERSION } from "../engine_constants.js";
|
|
5
5
|
import { ContextEvent, ContextRegistry } from "../engine_context_registry.js";
|
|
6
|
-
import {
|
|
6
|
+
import { KLnyx, Telemetry } from "../engine_license.js";
|
|
7
7
|
import { onStart } from "../engine_lifecycle_api.js";
|
|
8
8
|
import { setDracoDecoderPath, setDracoDecoderType, setKtx2TranscoderPath } from "../engine_loaders.gltf.js";
|
|
9
9
|
import { Context, ContextCreateArgs } from "../engine_setup.js";
|
|
@@ -617,7 +617,7 @@ export class NeedleEngineWebComponent extends HTMLElementBase implements INeedle
|
|
|
617
617
|
|
|
618
618
|
|
|
619
619
|
// Loading start events
|
|
620
|
-
const allowOverridingDefaultLoading =
|
|
620
|
+
const allowOverridingDefaultLoading = KLnyx();
|
|
621
621
|
// default loading can be overriden by calling preventDefault in the onload start event
|
|
622
622
|
this.ensureLoadStartIsRegistered();
|
|
623
623
|
let useDefaultLoading = this.dispatchEvent(new CustomEvent("loadstart", {
|
|
@@ -3,7 +3,7 @@ import { ArrayCamera, AxesHelper, Camera, Color, DirectionalLight, Fog, GridHelp
|
|
|
3
3
|
import { needleLogoOnlySVG } from "../assets/index.js";
|
|
4
4
|
import { isDevEnvironment } from "../debug/index.js";
|
|
5
5
|
import { ObjectUtils, PrimitiveType } from "../engine_create_objects.js";
|
|
6
|
-
import {
|
|
6
|
+
import { KLnyx } from "../engine_license.js";
|
|
7
7
|
import { Mathf } from "../engine_math.js";
|
|
8
8
|
import { delay, DeviceUtilities } from "../engine_utils.js";
|
|
9
9
|
|
|
@@ -215,7 +215,7 @@ export class TemporaryXRContext {
|
|
|
215
215
|
this._scene.background = new Color(0x000000);
|
|
216
216
|
|
|
217
217
|
let logoSrc = needleLogoOnlySVG;
|
|
218
|
-
if (
|
|
218
|
+
if (KLnyx()) {
|
|
219
219
|
const htmlComponent = document.querySelector("needle-engine");
|
|
220
220
|
if (htmlComponent) {
|
|
221
221
|
const licenseLogo = htmlComponent.getAttribute("logo-src");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getRaycastMesh } from "@needle-tools/gltf-progressive";
|
|
2
|
-
import { AxesHelper, Material, Mesh,
|
|
2
|
+
import { AxesHelper, Material, Mesh, MeshPhysicalMaterial, MeshStandardMaterial, Object3D, RawShaderMaterial, ShaderMaterial, SkinnedMesh, Texture, Vector4 } from "three";
|
|
3
3
|
|
|
4
4
|
import { showBalloonWarning } from "../engine/debug/index.js";
|
|
5
5
|
import { getComponent, getOrAddComponent } from "../engine/engine_components.js";
|
|
@@ -305,21 +305,12 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
305
305
|
// private _materialProperties: Array<MaterialProperties> | undefined = undefined;
|
|
306
306
|
private _lightmaps?: RendererLightmap[];
|
|
307
307
|
|
|
308
|
-
/** Get the mesh Object3D for this renderer
|
|
309
|
-
* Warn: if this is a multimaterial object it will return the first
|
|
308
|
+
/** Get the mesh Object3D for this renderer
|
|
309
|
+
* Warn: if this is a multimaterial object it will return the first submesh only (same as `sharedMeshes[0]`), use {@link sharedMeshes} to get all of them
|
|
310
310
|
* @returns a mesh object3D.
|
|
311
311
|
* */
|
|
312
312
|
get sharedMesh(): Mesh | SkinnedMesh | undefined {
|
|
313
|
-
|
|
314
|
-
return this.gameObject as unknown as Mesh
|
|
315
|
-
}
|
|
316
|
-
else if (this.gameObject.type === "SkinnesMesh") {
|
|
317
|
-
return this.gameObject as unknown as SkinnedMesh;
|
|
318
|
-
}
|
|
319
|
-
else if (this.gameObject.type === "Group") {
|
|
320
|
-
return this.gameObject.children[0] as unknown as Mesh;
|
|
321
|
-
}
|
|
322
|
-
return undefined;
|
|
313
|
+
return this.sharedMeshes[0];
|
|
323
314
|
}
|
|
324
315
|
|
|
325
316
|
private readonly _sharedMeshes: Mesh[] = [];
|