@privacyscrubber/mcp-server 2.4.0 → 2.4.2
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/README.md +1 -1
- package/index.js +186 -80
- package/install.js +66 -3
- package/manifest.json +1 -1
- package/package.json +5 -1
- package/pii-masking-run.js +90 -40
- package/ps-license-manager.cjs +261 -11
- package/ps-license-manager.js +261 -11
- package/ps-pii-engine.cjs +3611 -8
- package/ps-pii-engine.js +3611 -8
- package/scrubber-core.cjs +1801 -8
- package/server.json +3 -3
- package/.well-known/mcp/server-card.json +0 -78
- package/LICENSE +0 -23
package/pii-masking-run.js
CHANGED
|
@@ -27,7 +27,7 @@ const cmdIndex = args.indexOf("--");
|
|
|
27
27
|
|
|
28
28
|
if (args.includes("--version") || args.includes("-v")) {
|
|
29
29
|
const pkgPath = path.resolve(__dirname, './package.json');
|
|
30
|
-
let version = '2.2
|
|
30
|
+
let version = '2.4.2';
|
|
31
31
|
try { version = JSON.parse(fs.readFileSync(pkgPath, 'utf8')).version; } catch (_) {}
|
|
32
32
|
console.log(`ps-guard / pii-masking-run v${version} (PrivacyScrubber MCP)`);
|
|
33
33
|
process.exit(0);
|
|
@@ -89,35 +89,35 @@ const colors = {
|
|
|
89
89
|
};
|
|
90
90
|
|
|
91
91
|
const DEVOPS_SECRETS_DETECTOR = [
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
92
|
+
{ name: 'AWS Credentials', regex: /\b(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA)[A-Z0-9]{12,28}\b/g, label: 'AWS_KEY' },
|
|
93
|
+
{ name: 'Google Cloud / Gemini API Key', regex: /\bAIza[0-9A-Za-z_-]{35}\b/g, label: 'API_TOKEN' },
|
|
94
|
+
{ name: 'Anthropic API Key', regex: /\bsk-ant-(?:api\d{2}|admin\d{2}|sid\d{2})-[a-zA-Z0-9_-]{16,128}\b/g, label: 'API_TOKEN' },
|
|
95
|
+
{ name: 'HuggingFace / Perplexity API Key', regex: /\b(?:hf_[a-zA-Z0-9]{20,64}|pplx-[a-zA-Z0-9]{24,64})\b/g, label: 'API_TOKEN' },
|
|
96
|
+
{ name: 'SendGrid API Key', regex: /\bSG\.[a-zA-Z0-9_-]{16,32}\.[a-zA-Z0-9_-]{32,64}\b/g, label: 'API_TOKEN' },
|
|
97
|
+
{ name: 'Postman API Key', regex: /\bPMAK-[a-fA-F0-9]{24}-[a-fA-F0-9]{34}\b/g, label: 'API_TOKEN' },
|
|
98
|
+
{ name: 'GitHub Fine-Grained PAT', regex: /\bgithub_pat_[a-zA-Z0-9]{20,30}_[a-zA-Z0-9]{40,80}\b/g, label: 'API_TOKEN' },
|
|
99
|
+
{ name: 'Slack Enterprise / Refresh Token', regex: /\bxoxe\.xox[baprs]-\d-[a-zA-Z0-9-]{10,}\b|\bxox[eapbrs]-[a-zA-Z0-9-]{10,}\b/g, label: 'API_TOKEN' },
|
|
100
|
+
{ name: 'Telegram Bot API Token', regex: /\b\d{8,10}:AA[A-Za-z0-9_-]{33}\b/g, label: 'API_TOKEN' },
|
|
101
|
+
{ name: 'Age Encryption Secret Key', regex: /\bAGE-SECRET-KEY-1[A-Z0-9]{58}\b/g, label: 'SECRET' },
|
|
102
|
+
{ name: 'Modern Cloud & AI Platform Key', regex: /\b(?:sbp_[a-fA-F0-9]{40}|dop_v1_[a-fA-F0-9]{64}|doo_v1_[a-fA-F0-9]{64}|dp\.(?:st|pt|ct|sa)\.[a-zA-Z0-9_-]{20,}|lin_api_[a-zA-Z0-9]{32,64}|ntn_[a-zA-Z0-9]{32,64}|secret_[a-zA-Z0-9]{32,64}|gsk_[a-zA-Z0-9]{32,64}|r8_[a-zA-Z0-9]{24,64}|tvly-[a-zA-Z0-9_-]{20,64}|fc-[a-fA-F0-9]{32}|dapi[a-fA-F0-9]{32}(?:-\d)?|re_[a-zA-Z0-9_]{20,64}|napi_[a-zA-Z0-9]{32,64}|[a-zA-Z0-9]{14}\.atlasv1\.[a-zA-Z0-9]{50,80}|pypi-[A-Za-z0-9_-]{16,128}|whsec_[A-Za-z0-9+/=_-]{24,128}|shpat_[a-fA-F0-9]{32}|shpss_[a-fA-F0-9]{32}|shpca_[a-fA-F0-9]{32}|shppa_[a-fA-F0-9]{32}|hvs\.[A-Za-z0-9_-]{24,128}|hvb\.[A-Za-z0-9_-]{24,128}|glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8}|glc_[A-Za-z0-9+/=_-]{20,128}|pscale_tkn_[A-Za-z0-9_.-]{20,64}|pscale_pw_[A-Za-z0-9_.-]{20,64}|pat[A-Za-z0-9]{14}\.[a-fA-F0-9]{64}|pat-(?:na1|eu1)-[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}|sq0atp-[A-Za-z0-9_-]{22,64}|sq0csp-[A-Za-z0-9_-]{32,64}|NRAK-[A-Z0-9]{27}|v1\.0-[a-fA-F0-9]{24}-[a-fA-F0-9]{16,160}|ATATT3xFfGF0[A-Za-z0-9+/=_-]{24,128}|tskey-(?:auth|api|client)-[A-Za-z0-9_-]{20,96}|sntry[su]_[A-Za-z0-9+/=_-]{32,160}|(?:pk|sk)\.eyJ1[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{16,}|key-[a-f0-9]{32}|[a-f0-9]{32}-us\d{1,2})\b/g, label: 'API_TOKEN' },
|
|
103
|
+
{ name: 'Twilio Account SID / API Key', regex: /\b(?:AC|SK)[a-fA-F0-9]{32}\b/g, label: 'API_TOKEN' },
|
|
104
|
+
{ name: 'Bcrypt / Argon2 Password Hash', regex: /(?<![A-Za-z0-9])(?:\$2[aby]\$\d{2}\$[./A-Za-z0-9=]{20,60}|\$argon2(?:id|i|d)\$[^\s"']{15,120})/g, label: 'SECRET' },
|
|
105
|
+
{ name: 'JSON Web Token (JWT)', regex: /\beyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+\b/g, label: 'JWT_TOKEN' },
|
|
106
|
+
{ name: 'API Token/Key (GitHub/Slack/NPM)', regex: /\b(?:ghp|gho|ghu|ghs|ghr|glpat|npm|xox[baprs])[-_][A-Za-z0-9_-]{10,}\b/g, label: 'API_TOKEN' },
|
|
107
|
+
{ name: 'Stripe API Key', regex: /\b(?:[rs]k)_(?:test|live)_[a-zA-Z0-9]{10,}\b/g, label: 'STRIPE_KEY' },
|
|
108
|
+
{ name: 'OpenAI Project API Key', regex: /\b(?:sk|pk)-(?:proj-)?[a-zA-Z0-9_-]{16,}\b/gi, label: 'OPENAI_KEY' },
|
|
109
|
+
{ name: 'Slack / Discord Incoming Webhook URL', regex: /\bhttps:\/\/(?:hooks\.slack\.com\/services\/T[A-Z0-9_]+\/B[A-Z0-9_]+\/[A-Za-z0-9_-]+|(?:ptb\.|canary\.)?discord(?:app)?\.com\/api\/webhooks\/\d{17,20}\/[A-Za-z0-9_-]{60,70})\b/gi, label: 'SECRET' },
|
|
110
|
+
{ name: 'Azure Connection String / SAS Token', regex: /(?:DefaultEndpointsProtocol=https?;AccountName=[^;\s"']+;AccountKey=[A-Za-z0-9+/=]{20,}(?:;EndpointSuffix=[^;\s"']+)?|Endpoint=sb:\/\/[^;\s"']+;SharedAccessKeyName=[^;\s"']+;SharedAccessKey=[A-Za-z0-9+/=]{16,}|\bSharedAccessSignature=sr=[^\s"']+&sig=[A-Za-z0-9%/+=]{16,}|\bAccountKey=[A-Za-z0-9+/=]{40,88}==)/gi, label: 'SECRET' },
|
|
111
|
+
{ name: 'Database Connection URI', regex: /\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis|amqp|mssql):\/\/[^\s"']+/gi, label: 'DB_URI' },
|
|
112
|
+
{ name: 'Embedded Credentials URI', regex: /\b(?:https?|hxxps?|s?ftp|fxp|wss?):\/\/[a-zA-Z0-9_.%+-]+:[^\s/@:"']+@[a-zA-Z0-9_.-]+(?:\[\.\][a-zA-Z0-9_.-]+|\(\.\)[a-zA-Z0-9_.-]+)*(?::\d+)?(?:\/[^\s"']*)?/gi, label: 'SECRET' },
|
|
113
|
+
{ name: 'URL Query Parameter Secret', regex: /(?<=[?&](?:api_key|apikey|access_token|client_secret|auth_token|token|secret|password|private_key)=)[^\s"'\x26#)>]{8,}/gi, label: 'SECRET' },
|
|
114
|
+
{ name: 'CLI Credential Flag / Curl User Auth', regex: /(?:\bcurl\b[^\r\n]*?\s(?:-u|--user)\s+["']?[A-Za-z0-9_.+-]+:[^\s"']+|\b(?:--password|--api-key|--apikey|--access-token|--auth-token|--client-secret|--secret-key|--private-key)(?:=|\s+)["']?[^\s"']{6,}["']?)/gi, label: 'SECRET' },
|
|
115
|
+
{ name: 'HTTP API Key Header', regex: /\b(?:X-API-Key|X-Amz-Security-Token|X-Functions-Key|X-Shopify-Access-Token|X-Auth-Token|Api-Key)\s*:\s*["']?[A-Za-z0-9_.\-~+/=]{12,}["']?/gi, label: 'SECRET' },
|
|
116
|
+
{ name: 'Docker Registry Auth / K8s Secret Base64', regex: /(?<=["']?(?:auth|identitytoken|registrytoken|\.dockerconfigjson)["']?\s*:\s*["'])[A-Za-z0-9+/=]{16,}(?=["'])/gi, label: 'SECRET' },
|
|
117
|
+
{ name: 'Bearer / Auth Header Token', regex: /(?<=\b(?:Bearer|Token)\s+)[a-zA-Z0-9_\-\.~+/=]{16,}\b/gi, label: 'SECRET' },
|
|
118
|
+
{ name: 'Database/API Secret', regex: /\b(DB|POSTGRES|REDIS|MYSQL|AWS|SECRET|PASSWORD|TOKEN|API|KEY)[A-Z0-9_]*\s*[:=]\s*[^ \t\r\n"']{8,}/gi, label: 'SECRET' },
|
|
119
|
+
{ name: 'Private Cryptographic Key (PEM Block)', regex: /-----BEGIN (?:RSA |EC |PGP |DSA |OPENSSH |ENCRYPTED )?PRIVATE KEY(?: BLOCK)?-----[\s\S]{10,8192}?-----END (?:RSA |EC |PGP |DSA |OPENSSH |ENCRYPTED )?PRIVATE KEY(?: BLOCK)?-----/g, label: 'SECRET' },
|
|
120
|
+
{ name: 'Private Cryptographic Key (Header)', regex: /-----BEGIN (?:RSA |EC |PGP |DSA |OPENSSH |ENCRYPTED )?PRIVATE KEY(?: BLOCK)?-----/g, label: 'SECRET' }
|
|
121
121
|
];
|
|
122
122
|
|
|
123
123
|
let LicenseManager;
|
|
@@ -327,7 +327,7 @@ function buildCisoAuditTelemetry(currentTokenMap = {}) {
|
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
const ipHoldings = {
|
|
330
|
-
standard: 'IETF draft-sibiryakov-ztds-protocol-
|
|
330
|
+
standard: 'IETF draft-sibiryakov-ztds-protocol-01',
|
|
331
331
|
standardUrl: 'https://datatracker.ietf.org/doc/draft-sibiryakov-ztds-protocol/',
|
|
332
332
|
patent: "U.S. & Int'l Patents Pending (Paris Convention Priority)",
|
|
333
333
|
trademark: 'ZTDS™ Reg. #182655957 (ILPO Cl 9 & 42)'
|
|
@@ -337,27 +337,27 @@ function buildCisoAuditTelemetry(currentTokenMap = {}) {
|
|
|
337
337
|
{
|
|
338
338
|
statute: 'EU AI Act (Art. 50)',
|
|
339
339
|
scope: 'AI Transparency & Data Minimization',
|
|
340
|
-
rule: '
|
|
340
|
+
rule: 'Sanitization runs locally by design; reduces the content sent to external AI models. Informational mapping, not a compliance determination.'
|
|
341
341
|
},
|
|
342
342
|
{
|
|
343
343
|
statute: 'GDPR (Art. 4, 25, 28, 32)',
|
|
344
344
|
scope: 'Pseudonymization & Processor Liability',
|
|
345
|
-
rule: '
|
|
345
|
+
rule: 'Client-side pseudonymization is a technical measure supporting Art. 25 and 32. It does not by itself remove controller or processor obligations.'
|
|
346
346
|
},
|
|
347
347
|
{
|
|
348
348
|
statute: 'HIPAA 45 CFR § 164.514(b)',
|
|
349
349
|
scope: 'Safe Harbor De-Identification',
|
|
350
|
-
rule: '
|
|
350
|
+
rule: 'Pattern-based masking of direct identifiers supports Safe Harbor de-identification workflows. Review output for residual identifiers before sharing.'
|
|
351
351
|
},
|
|
352
352
|
{
|
|
353
353
|
statute: 'IRC § 7216 & IRS Pub. 1075',
|
|
354
354
|
scope: 'Tax Return Information Confidentiality',
|
|
355
|
-
rule: '
|
|
355
|
+
rule: 'Masking identifiers before AI use can reduce exposure of tax return information. Informational mapping, not legal advice.'
|
|
356
356
|
},
|
|
357
357
|
{
|
|
358
358
|
statute: 'FRE 502',
|
|
359
359
|
scope: 'Attorney-Client Privilege Preservation',
|
|
360
|
-
rule: '
|
|
360
|
+
rule: 'In-memory redaction can reduce disclosure of privileged details in AI workflows. Privilege determinations remain a legal judgment.'
|
|
361
361
|
}
|
|
362
362
|
];
|
|
363
363
|
|
|
@@ -373,6 +373,54 @@ function buildCisoAuditTelemetry(currentTokenMap = {}) {
|
|
|
373
373
|
};
|
|
374
374
|
}
|
|
375
375
|
|
|
376
|
+
// ── PSR-2 Receipt Integrity (real SHA-256; parity with src/modules/receipt-integrity.js) ──
|
|
377
|
+
const PSR2_VERSION = 'PSR-2';
|
|
378
|
+
const PSR2_STATEMENTS = {
|
|
379
|
+
measured: [
|
|
380
|
+
'Token Manifest SHA-256: digest of the sorted token labels held in this session (original values are never hashed or exported).',
|
|
381
|
+
'Entity counts per type.',
|
|
382
|
+
'Receipt SHA-256: digest of the canonical field string, so edits to this receipt are detectable.'
|
|
383
|
+
],
|
|
384
|
+
byDesign: [
|
|
385
|
+
'The sanitization engine runs locally in process memory and does not transmit prompt content. This is an architectural property and is not measured by this receipt.',
|
|
386
|
+
'Token-to-original mappings are held in volatile memory for the session. This receipt does not record their contents.'
|
|
387
|
+
],
|
|
388
|
+
limits: [
|
|
389
|
+
'This receipt is not a digital signature and does not prove who generated it or when.',
|
|
390
|
+
'No final output digest is recorded by this export (Output SHA-256: not recorded).',
|
|
391
|
+
'Detection is pattern-based. Free-text narrative can contain indirect identifiers that remain after sanitization; review output before sharing.',
|
|
392
|
+
'Regulatory references are informational technical-safeguard mappings, not a legal determination of compliance.'
|
|
393
|
+
]
|
|
394
|
+
};
|
|
395
|
+
function psr2Sha256(input) {
|
|
396
|
+
return crypto.createHash('sha256').update(String(input == null ? '' : input), 'utf8').digest('hex');
|
|
397
|
+
}
|
|
398
|
+
function buildPsr2Receipt(tokenMap, timestamp = new Date().toISOString()) {
|
|
399
|
+
const labels = (tokenMap && typeof tokenMap === 'object' ? Object.keys(tokenMap) : []).slice().sort();
|
|
400
|
+
const counts = {};
|
|
401
|
+
for (const t of labels) {
|
|
402
|
+
const m = t.match(/\[([A-Z_]+)_\d+\]/);
|
|
403
|
+
const type = m ? m[1] : 'CUSTOM';
|
|
404
|
+
counts[type] = (counts[type] || 0) + 1;
|
|
405
|
+
}
|
|
406
|
+
const entityCounts = Object.keys(counts).sort().map(k => `${k}=${counts[k]}`).join(',') || 'none';
|
|
407
|
+
const manifestSha256 = psr2Sha256(labels.join('\n'));
|
|
408
|
+
const canonical = [PSR2_VERSION, timestamp, 'none', manifestSha256, entityCounts, 'na'].join('|');
|
|
409
|
+
return { version: PSR2_VERSION, timestamp, outputSha256: null, manifestSha256, entityCounts, tokensTotal: labels.length, tokensPresentInOutput: null, canonical, receiptSha256: psr2Sha256(canonical) };
|
|
410
|
+
}
|
|
411
|
+
function psr2Lines(r) {
|
|
412
|
+
return [
|
|
413
|
+
`Receipt Version: ${r.version}`,
|
|
414
|
+
`Timestamp (UTC): ${r.timestamp}`,
|
|
415
|
+
`Output SHA-256: not recorded`,
|
|
416
|
+
`Token Manifest SHA-256: ${r.manifestSha256}`,
|
|
417
|
+
`Entity Counts: ${r.entityCounts}`,
|
|
418
|
+
`Tokens In Final Output: not recorded`,
|
|
419
|
+
`Canonical: ${r.canonical}`,
|
|
420
|
+
`Receipt SHA-256: ${r.receiptSha256}`
|
|
421
|
+
];
|
|
422
|
+
}
|
|
423
|
+
|
|
376
424
|
function emitProofFeedback() {
|
|
377
425
|
const isQuiet = args.includes("--quiet") || args.includes("-q");
|
|
378
426
|
if (isQuiet) return;
|
|
@@ -388,7 +436,7 @@ function emitProofFeedback() {
|
|
|
388
436
|
const hasSecrets = (telemetry.types || []).some(t => ['API_KEY', 'SECRET', 'PASSWORD', 'TOKEN', 'KEY', 'CREDIT_CARD', 'BANK', 'ID', 'SSN'].includes(t));
|
|
389
437
|
if (hasSecrets || totalMasked >= 3) {
|
|
390
438
|
process.stderr.write(`\x1b[33m[ps-guard] Saved credentials/PII from model egress. Star the project: https://github.com/moxno/privacyscrubber-mcp\x1b[0m\n`);
|
|
391
|
-
process.stderr.write(`\x1b[90m One-click CLI: gh repo star moxno/privacyscrubber-mcp |
|
|
439
|
+
process.stderr.write(`\x1b[90m One-click CLI: gh repo star moxno/privacyscrubber-mcp | Feedback: https://privacyscrubber.com/uninstall/?mode=feedback&src=cli\x1b[0m\n`);
|
|
392
440
|
}
|
|
393
441
|
} else if (args.includes("--verbose")) {
|
|
394
442
|
process.stderr.write(`\x1b[36m[ps-guard] 0 item(s) masked · 0 bytes egress · Zero-Trust RAM verified\x1b[0m\n`);
|
|
@@ -531,7 +579,7 @@ if (isDiffMode) {
|
|
|
531
579
|
}
|
|
532
580
|
if (!diffOutput.trim()) {
|
|
533
581
|
if (isJsonMode) {
|
|
534
|
-
console.log(JSON.stringify({ isDiff: true, empty: true, diff: "", count: 0, telemetry: buildCisoAuditTelemetry({}) }, null, 2));
|
|
582
|
+
console.log(JSON.stringify({ isDiff: true, empty: true, diff: "", count: 0, telemetry: buildCisoAuditTelemetry({}), receipt: buildPsr2Receipt({}) }, null, 2));
|
|
535
583
|
} else {
|
|
536
584
|
console.log(`[Zero-Trust Agentic Guard: Git Diff]\nNo git diff changes detected (${isStaged ? 'staged' : 'unstaged'}).`);
|
|
537
585
|
}
|
|
@@ -545,7 +593,8 @@ if (isDiffMode) {
|
|
|
545
593
|
sanitizedDiff: sanitizedDiff,
|
|
546
594
|
tokenMap: localSessionMap,
|
|
547
595
|
count: Object.keys(localSessionMap).length,
|
|
548
|
-
telemetry: telemetry
|
|
596
|
+
telemetry: telemetry,
|
|
597
|
+
receipt: buildPsr2Receipt(localSessionMap)
|
|
549
598
|
}, null, 2));
|
|
550
599
|
} else {
|
|
551
600
|
process.stdout.write(sanitizedDiff.endsWith('\n') ? sanitizedDiff : sanitizedDiff + '\n');
|
|
@@ -571,7 +620,8 @@ if (hasStdin && !hasCommand && !isRestoreMode && !isDiffMode && !isRulesMode) {
|
|
|
571
620
|
scrubbedText: sanitized,
|
|
572
621
|
tokenMap: localSessionMap,
|
|
573
622
|
count: Object.keys(localSessionMap).length,
|
|
574
|
-
telemetry: telemetry
|
|
623
|
+
telemetry: telemetry,
|
|
624
|
+
receipt: buildPsr2Receipt(localSessionMap)
|
|
575
625
|
}, null, 2) + '\n');
|
|
576
626
|
emitProofFeedback();
|
|
577
627
|
process.exit(0);
|
package/ps-license-manager.cjs
CHANGED
|
@@ -1,11 +1,261 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
function _0x31be(_0x29754c,_0x346462){_0x29754c=_0x29754c-0x188;const _0x3f7cbe=_0x3f7c();let _0x31be84=_0x3f7cbe[_0x29754c];if(_0x31be['dOswYu']===undefined){var _0x72e0e3=function(_0x5c0cad){const _0x2740cd='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x291f06='',_0x124f34='';for(let _0x58829f=0x0,_0x51abd8,_0x474e70,_0x325f42=0x0;_0x474e70=_0x5c0cad['charAt'](_0x325f42++);~_0x474e70&&(_0x51abd8=_0x58829f%0x4?_0x51abd8*0x40+_0x474e70:_0x474e70,_0x58829f++%0x4)?_0x291f06+=String['fromCharCode'](0xff&_0x51abd8>>(-0x2*_0x58829f&0x6)):0x0){_0x474e70=_0x2740cd['indexOf'](_0x474e70);}for(let _0x272002=0x0,_0x3c9aa0=_0x291f06['length'];_0x272002<_0x3c9aa0;_0x272002++){_0x124f34+='%'+('00'+_0x291f06['charCodeAt'](_0x272002)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x124f34);};_0x31be['dVwNjP']=_0x72e0e3,_0x31be['XRijcb']={},_0x31be['dOswYu']=!![];}const _0x3c1788=_0x3f7cbe[0x0],_0x360dd6=_0x29754c+_0x3c1788,_0x2c001e=_0x31be['XRijcb'][_0x360dd6];return!_0x2c001e?(_0x31be84=_0x31be['dVwNjP'](_0x31be84),_0x31be['XRijcb'][_0x360dd6]=_0x31be84):_0x31be84=_0x2c001e,_0x31be84;}function _0x3f7c(){const _0x2958fa=['nta4nG','DhjPBG','mtyWmG','ntu4nW','Dg9AAW','DgvT','CMvK','yMfZzq','ufmTuG','mZiXoq','mZyWoa','C3rVCG','mdmXmq','nZaYmG','mJK2ma','r1DLwa','zw5KCW','C3rHCG','nZK3oq','nta0na','mtqYmq','mdu5mq','ndC3mJi1nvPwwfLAzG','mZy5ma','zgvK','ndC3mG','m25ZtNL6ta','nde0oq','ndeYoq','mtiWmq','A2v5ia','mJCXmq','ndu2mG','nJG4na','mteZmdG4nerUCfnQzq','nZyWmW','mZuYmq','Cg93','mZGXmW','nZCWnG','odK3oq','BgvUzW','y3j5Ca','ntG4na','sLDuia','vfv4CW','nJi0mG','zxKGCa','oteYnq','nte1oa','tgLJzq','mJC2nW','ntC0oq','odeWnq','nJm0nW','B25bBG','A3LMuq','ywLSzq','ntaZna','BhKGza','odmXnW','EuX5DG','mJC2oq','rNDStG','mdmYma','Aw5JBa','ndy3oa','mdq4nq','zw5Hva','otKWma','y2fqAW','Avb4Ba','ufjp','zxLk','otm5nq','nJiXmq','nti0mG','otaYmG','mJCZna','CMLUzW','zM9YBq','nJq5oq','Ehboza','ntGXoa','mtuYoda5mJL6DgHZseu','u3Hxwa','zgf0Aq','wLreuW','u0rl','odu1oq','nJy4mq','zMLUzq','tM8GAW','mdy0nW','DhrzAq','Exb0Aq','nJG5oq','AuTotG','otG2oa','vef6rq','wfj1Ea','z3zWtq','nJC4mq','mZG4nG','DcbLEa','BxziqG','u0eT','sw52yq','DLvYvG','mtyYnG','v2L0Aa','yxn0xW','vM9SvW','DgvK','nJKZmG','mta5nW','y2SGyq','mJzFiq','nZm1oa','nZmXmG','ody2mG','otm3oq','oda1nW','q2HHCG','vgLTzq','D2nNAq','nZqYmtC4nfH6yMvwCW','nZyXna','nJmWmW','nty3ma','nde1mW','nZu5nq','ote4mG','nteXoq','BgvK','mJuYnW','mdy5na','BM9Tyq','zxHWAq','nJi2ma','odiXmG','CM92Aq','DgLVBG','Dg9vCa','mteZnJe3mgDmzg1SsW','C2v0sq','DMfSAq','mJa2nG','uLnbia','shbkrW','nta1oa','ote2oq','ndi1mW','mJm4oq','Dw5Kzq','ntC0nG','nJa4mW','otyWoq','q29Kzq','Ae52tG','B21HBa','ndKXnq','vevbtq','mtKWnq','odyYoa','ntmXoq','swLKDa','mJeYnW','Bw9JAW','nZq2mq','mJe4oa','AYbYBW','qvbuwG','ywDL','ntu0nW','nZa4nW','mtqXmq','mdG1nW','B25fEa','odq5nW','luXjqW','mtmZnG','zxHW','C2XPyW','ndy4ma','v1rTEG','DwTArW','mZiYma','z2z2ta','CNrZ','q2XVyW','uLnb','otaZnW','ntaZnG','mta0ma','ndG4mG','nZqYna','nZG2oq','zxrLyW','qKjfvG','mJu4mq','suXpva','x1nbta','tw5eyq','nZq3ma','ndaWnW','ndyWoa','ChnFBa','ntaXoq','mdG2nq','ntK2na','mdGYoq','odqYoq','nJKXmG','mJmZna','B24GzG','ota4ma','z2v0sq','odyXmG','vf8Yma','r2PLsa','x3rPBq','oti5na','DhnxAq','nZCXnW','ndC5nG','mJy4ma','odiZnW','ugLSBW','nZa2mq','yNDhDa','mtK3na','mte0oq','ywnL','mdC1na','DcbKzq','mJG1mG','ody1mG','nJu1na','nJqYma','CMvWBa','nty5mG','BNnLtq','mZu0ma','mZC2ma','nJa1nG','odKYnq','mZGWmW','mZq4nG','ufmTua','CgfKuW','yxnL','CgLYzq','ntaXnW','teXrvG','mJeZmq','mJa2nq','BgLKia','CgvYqW','mZa5nG','AfHXsG','nZmWoa','mty0oa','BM93','zgvJCG','mtu0oq','DhjPBq','ode0mG','mtqZodm0ogP3C3jQuW','tKnyyq','lvbjta','C3vICW','zNjVBq','y2HHCG','t0vn','nZyWnq','sLDu','ndq3nW','mZq5na','C3bSAq','igzHAq','DuDRqW','CgfYCW','mtCYoq','nNvYDxfJzG','y29UyW','BgXIyq','C2vLBG','yMLUyq','zxHWBW','uLbssq','DgLLCG','Dg9tDa','DgfYDa','mte3mq','ndyZnW','DwrLCW','ru5urq','mtbTr0XJC0G','t1qT','odCYoq','mJyZnq','yw5HzW','mJqYoa','mteXndGWm1ntz2rxBa','odG1nW'];_0x3f7c=function(){return _0x2958fa;};return _0x3f7c();}const _0x3c19f9=_0x31be,_0x43b883=_0x31be;(function(_0x2652f6,_0x151fbc){const _0x4915b7={_0x2177c0:0x1b8,_0x4bf6db:0x2a2,_0x1c72e4:0x2b2,_0x40fb5e:0x226,_0x5eb2b7:0x214,_0x5704e2:0x1ea},_0x257c14=_0x31be,_0x180053=_0x31be,_0xe6ee48=_0x2652f6();while(!![]){try{const _0x485021=parseInt(_0x257c14(0x194))/0x1+parseInt(_0x180053(_0x4915b7._0x2177c0))/0x2+-parseInt(_0x257c14(0x1b0))/0x3*(parseInt(_0x257c14(_0x4915b7._0x4bf6db))/0x4)+-parseInt(_0x180053(0x1ac))/0x5*(parseInt(_0x180053(_0x4915b7._0x1c72e4))/0x6)+-parseInt(_0x180053(_0x4915b7._0x40fb5e))/0x7+-parseInt(_0x180053(_0x4915b7._0x5eb2b7))/0x8+-parseInt(_0x180053(_0x4915b7._0x5704e2))/0x9*(-parseInt(_0x257c14(0x18e))/0xa);if(_0x485021===_0x151fbc)break;else _0xe6ee48['push'](_0xe6ee48['shift']());}catch(_0x2ff4dc){_0xe6ee48['push'](_0xe6ee48['shift']());}}}(_0x3f7c,0xedce7),function(_0x19bda1){const _0x5bf439={_0x98d228:0x1ed,_0x454f88:0x2a4,_0x48c113:0x18f,_0x51abc8:0x1ed,_0x57e034:0x271,_0x1a1eee:0x20b,_0x2236b4:0x1df,_0x700f30:0x1de,_0x53ab65:0x1c2,_0x355aca:0x26d,_0x1036df:0x1cf,_0x24b3f7:0x230,_0x537b59:0x1f1,_0x990e00:0x295,_0x2c0a0e:0x1a8,_0x52faa5:0x258,_0x1fadc3:0x1d0,_0x5019f6:0x1d8,_0xb1e04a:0x1e2,_0x5597ff:0x28d,_0x5191ab:0x278,_0x491599:0x218,_0x380bc0:0x210,_0x4553f6:0x219,_0x32a9fe:0x1a0,_0xb5a39d:0x233,_0x44c11d:0x287,_0x13f409:0x240,_0x3dadfe:0x1cb,_0x58b3b6:0x284,_0x182d80:0x1b3,_0x340750:0x19f,_0x3916eb:0x18b,_0x1bca6d:0x195,_0x273b3a:0x239,_0x5a2b6e:0x23b,_0x54fd5b:0x232,_0x2b9738:0x1e7,_0x35898e:0x280,_0x3274ee:0x20f,_0x52cf1d:0x1c6,_0x1c8556:0x264,_0x2dae3f:0x1b5,_0xd680f9:0x1e4,_0x36b944:0x2ab,_0x43cf9c:0x259,_0x4aa5f3:0x25b,_0x3ceca4:0x1a2,_0x10a3f4:0x22e,_0x3d46b9:0x1a9,_0x477a51:0x299,_0x411874:0x27e,_0x2a8dd2:0x1b2,_0x421b13:0x29f,_0x1253e7:0x20c,_0x30c5b8:0x203,_0x7c546c:0x270,_0x5d1c3e:0x25e,_0x455345:0x269,_0x137b6a:0x1fc,_0x19527b:0x28c,_0xb03a7f:0x1d2,_0x4d108a:0x1aa,_0x907898:0x28b,_0x4c836b:0x1f6,_0x1aa385:0x1f3,_0x4f3f45:0x279,_0x59f990:0x251,_0x568b2b:0x276,_0x59034a:0x1e3,_0x50f0ef:0x1e9,_0x5a8759:0x249,_0x38e7d5:0x1c4,_0x56407a:0x27b,_0x455070:0x289,_0x139b92:0x285,_0x1a717c:0x25a,_0x15e97e:0x28e,_0x56861e:0x1ef,_0x1918c1:0x20e,_0x24e466:0x18a,_0x312f4f:0x1cc,_0x3b7230:0x24b,_0x3fbbbd:0x2a1,_0x3125eb:0x1e0,_0x5e08bb:0x217,_0x2a11a8:0x231,_0x51930a:0x1d4,_0x14990a:0x221,_0x5cb681:0x1ca,_0x5a73e6:0x268,_0x593e9a:0x296,_0x1575fa:0x274,_0x398783:0x1e1,_0x106322:0x1b1,_0x569c05:0x1a4,_0x17f337:0x1f0,_0x6a3fd6:0x21d,_0x3bd12e:0x28a,_0x26ac0a:0x222,_0x45b81b:0x29b,_0x30be56:0x262,_0x5954f3:0x237,_0xe89086:0x1ba,_0x19f979:0x27d,_0x373387:0x1a3,_0x2403f7:0x21a,_0x447479:0x277,_0x436bd5:0x1fd,_0x59ca2e:0x216,_0x5587c2:0x257,_0x3da315:0x21b,_0x5ec0f3:0x229,_0x23b8ed:0x1c9,_0x20b3ff:0x1ab,_0x1fec53:0x282,_0x370188:0x1bc,_0x2124c0:0x23f,_0x1cabad:0x190,_0x56bcbe:0x1c1,_0x1b9df5:0x245,_0x15bf36:0x26b,_0x4da1e4:0x1ad,_0x440345:0x1db,_0x3c36f0:0x293,_0x281595:0x198,_0x37b7c5:0x21e,_0x52a52f:0x29c,_0x5e5e34:0x191,_0x27d28b:0x246,_0x45d4d6:0x1bd,_0x3f8de0:0x199,_0x44c5c9:0x1c8,_0x1e2a0f:0x288,_0x5ac6a0:0x250,_0x1b09a3:0x1c8,_0x2cb862:0x192,_0x2bde18:0x1f7,_0x4a6d1c:0x202,_0x112768:0x2b7,_0x10a4ba:0x253},_0x3b1685={_0x5949a6:0x1c5,_0x3947b9:0x223,_0x5138b1:0x1ae,_0x42b551:0x2a0,_0x128bfa:0x225,_0x1f82ba:0x291,_0x1b4c42:0x2ad,_0x1bd9e7:0x23e,_0x401543:0x212,_0x44a9ff:0x1f7,_0x724f0d:0x23e,_0x19a0af:0x23e,_0x173cc6:0x252,_0x10de14:0x19b,_0x28bea5:0x265,_0x297900:0x205,_0x62565c:0x2b5,_0x34b970:0x25d,_0x142e8d:0x23e,_0x510384:0x23e,_0x53aef6:0x1a1,_0x5851ac:0x243,_0x2ef587:0x227,_0xa47e82:0x19b,_0x16cef4:0x265,_0x266ce1:0x2b5,_0x20622:0x273,_0x4e35b2:0x188,_0x55d2a9:0x1e5,_0xa4d890:0x23e,_0x3b3fc6:0x25d,_0x14e676:0x1cd,_0x5e0ee9:0x236,_0x77e64e:0x1cd,_0x16690b:0x236,_0x5430a1:0x254,_0x20e8f5:0x2b4,_0x1bb05a:0x21f,_0x2961d2:0x1d1,_0x1ebbac:0x207,_0x2a2696:0x230,_0x4e2153:0x1a7,_0x2c06fd:0x28f,_0x3fb034:0x25f,_0x281057:0x2a5,_0x3d98d5:0x197,_0x2508b1:0x1bf,_0x27265f:0x1bf,_0x5ab3eb:0x234,_0x2372a4:0x213,_0x43018f:0x290,_0x51455a:0x189,_0x299f1a:0x1eb,_0x41802b:0x1dc,_0x318047:0x275,_0x567cdd:0x1dd,_0x5be2c9:0x206,_0x109ec8:0x248,_0x3bd7ae:0x292,_0x2e0857:0x27a,_0x1b4cc4:0x27a,_0x3d49fc:0x1fe,_0x22803f:0x27a,_0x522ac9:0x281,_0x4764a3:0x1c0,_0x574e55:0x224,_0x267070:0x2ae,_0x3f1461:0x275,_0x3e4d60:0x200,_0x2f5cfc:0x2af,_0x558a99:0x1bf,_0x32f771:0x1bf,_0x3524a5:0x188,_0x1ee717:0x1ff,_0x474218:0x1eb,_0x4b8fb7:0x1a7,_0x316324:0x1ed,_0x34b06:0x24a,_0x527d4a:0x2ad,_0x2b932a:0x292,_0x5128db:0x255,_0x426d97:0x22a,_0x30e3c5:0x1b4,_0x5b9cd3:0x220,_0x31fda7:0x19c,_0x822c3e:0x22a,_0x44e0a3:0x29e,_0x835cec:0x1f5,_0x54a418:0x1cf,_0x32bb65:0x238,_0x3977a0:0x1ee,_0x40782c:0x2a8,_0x327c95:0x18d,_0x4becb1:0x1d7,_0x1f866b:0x18c,_0x3a9f1e:0x1f9,_0x4b5dbd:0x1bf,_0x1050ae:0x2a7,_0x28978b:0x234,_0x45ee7a:0x1d3,_0x48088f:0x275,_0x9a3c8d:0x1ce,_0x572c60:0x286,_0x2e0bf5:0x27f,_0x2aa692:0x1bf,_0x1bd326:0x2a7,_0x5c269d:0x1e5,_0x5c8870:0x188,_0x2d0913:0x1e5,_0x1d46ff:0x1bf,_0x39c204:0x1a6,_0x5503a0:0x204,_0x511cd7:0x2b0,_0x376667:0x24c,_0xdd7b92:0x242,_0x3fa2f3:0x24c,_0x5e1fcb:0x1a5,_0x101290:0x292,_0x466dd2:0x2aa,_0x12eaf2:0x1c2,_0x25931a:0x220,_0x1488a6:0x19c,_0x415e61:0x201,_0x1ce002:0x297,_0x4be483:0x1e6},_0x4fadcb={_0x14daf0:0x1bb,_0x4deba2:0x252,_0x7a2127:0x1bf,_0x5f4eef:0x272,_0x32655e:0x252,_0x4d2f69:0x2a7,_0x532083:0x234,_0x45e71e:0x1fa,_0x349d75:0x1d3,_0x2073e1:0x24d,_0x512169:0x272,_0x3da9a9:0x1c3,_0x4e1cf8:0x252,_0x2f062b:0x252,_0x5ee348:0x29a,_0x1ce114:0x1fb,_0x447c6f:0x22b,_0x1f1c70:0x252,_0x4bd85d:0x29a,_0x3911d4:0x27c,_0x2b20de:0x272,_0x38dcff:0x272,_0x2a8512:0x188,_0x1a80bf:0x1e5},_0x2f418e={_0x59c148:0x1bf,_0xc093c9:0x2a7,_0x10dfdd:0x234,_0x224a7f:0x188,_0x3afba7:0x1e5,_0x46a4b7:0x290,_0x3771aa:0x189,_0x3f1a3a:0x1da},_0x394da5={_0x1f74d1:0x188,_0x33cd87:0x1e5,_0x13b0c2:0x1bf,_0x1815e2:0x2a6,_0x428ae1:0x211,_0x48ee7b:0x234,_0x412f7c:0x2a5},_0x1f1bfb=_0x31be,_0x1a27ba=_0x31be,_0x52c2e7={'Iidtr':function(_0x1e788a,_0x15855c){return _0x1e788a%_0x15855c;},'hNvNC':function(_0x5df98f,_0x4a396e){return _0x5df98f%_0x4a396e;},'WTmzw':function(_0x526882,_0x3471eb){return _0x526882*_0x3471eb;},'enaTs':function(_0x23df61,_0x115eb2){return _0x23df61+_0x115eb2;},'gfvLG':function(_0xa3cead,_0x1c268a,_0x504639){return _0xa3cead(_0x1c268a,_0x504639);},'GjeHQ':function(_0x5939fd,_0x124d64){return _0x5939fd<_0x124d64;},'XRuxI':function(_0xaf5321,_0x5ba5a2){return _0xaf5321>>_0x5ba5a2;},'yLyvC':function(_0x2e81d0,_0x4099ff){return _0x2e81d0%_0x4099ff;},'bwGtP':function(_0x3b81b7,_0xf99d23){return _0x3b81b7|_0xf99d23;},'TUxsv':function(_0x316d21,_0x229524){return _0x316d21-_0x229524;},'hXqJp':function(_0x7a117b,_0x45a3be){return _0x7a117b^_0x45a3be;},'NCXaP':function(_0x16070e,_0x1bcb6a){return _0x16070e<_0x1bcb6a;},'gvpMs':function(_0x368ffc,_0x45a02a){return _0x368ffc-_0x45a02a;},'HpJGq':function(_0x189091,_0x28264c){return _0x189091^_0x28264c;},'LLQVR':function(_0x1b7c2c,_0x2447ea){return _0x1b7c2c-_0x2447ea;},'FwlNz':function(_0x590b5b,_0x2f0fab){return _0x590b5b+_0x2f0fab;},'iKNNU':function(_0x4d59e7,_0x3a75b3){return _0x4d59e7!==_0x3a75b3;},'BBEVF':function(_0x1dce2c,_0x2e300b){return _0x1dce2c===_0x2e300b;},'MnDaQ':function(_0x5459a1,_0xf6391d){return _0x5459a1===_0xf6391d;},'wcgiK':function(_0x21d1d6,_0x379fdd){return _0x21d1d6<_0x379fdd;},'SxWXi':function(_0x1b540b,_0x57115f){return _0x1b540b(_0x57115f);},'caPkM':function(_0x420655,_0x269473,_0x186f75,_0x1e0110){return _0x420655(_0x269473,_0x186f75,_0x1e0110);},'iPxlY':_0x1f1bfb(_0x5bf439._0x98d228)+_0x1f1bfb(_0x5bf439._0x454f88)+_0x1f1bfb(_0x5bf439._0x48c113),'toZkT':function(_0x1e109f,_0x28a1f4,_0xc9e5a5){return _0x1e109f(_0x28a1f4,_0xc9e5a5);},'VolWH':_0x1f1bfb(0x238)+'S','uGkCw':function(_0x7405d3,_0x65dc7b){return _0x7405d3(_0x65dc7b);},'mvHBO':function(_0x4aeabf,_0xc5ee4c,_0x3ef2ae,_0x586a10){return _0x4aeabf(_0xc5ee4c,_0x3ef2ae,_0x586a10);},'xpNda':function(_0x376e5d,_0x193e9f){return _0x376e5d===_0x193e9f;},'TAzEV':_0x1f1bfb(_0x5bf439._0x51abc8)+_0x1a27ba(0x260)+_0x1f1bfb(_0x5bf439._0x57e034)+_0x1a27ba(_0x5bf439._0x1a1eee)+'@#','kyfQZ':_0x1a27ba(_0x5bf439._0x2236b4),'APTZX':function(_0x39806b,_0x1649a6){return _0x39806b/_0x1649a6;},'GWeXw':_0x1f1bfb(_0x5bf439._0x700f30),'ttYiq':_0x1f1bfb(_0x5bf439._0x53ab65)+_0x1f1bfb(0x228)+_0x1f1bfb(0x1ec)+_0x1f1bfb(_0x5bf439._0x355aca)+_0x1f1bfb(_0x5bf439._0x1036df)+'d','ukZGZ':_0x1a27ba(_0x5bf439._0x24b3f7)+_0x1f1bfb(_0x5bf439._0x537b59)+'d','vUrVb':function(_0x219166,_0x4a5bf0){return _0x219166!==_0x4a5bf0;}},_0x2ea186=BigInt(_0x1a27ba(_0x5bf439._0x990e00)+_0x1a27ba(_0x5bf439._0x2c0a0e)+_0x1f1bfb(_0x5bf439._0x52faa5)+_0x1a27ba(_0x5bf439._0x1fadc3)+_0x1f1bfb(_0x5bf439._0x5019f6)+_0x1a27ba(0x26c)+_0x1f1bfb(_0x5bf439._0xb1e04a)+_0x1a27ba(_0x5bf439._0x5597ff)+_0x1a27ba(0x1f8)+_0x1a27ba(0x1b7)+_0x1f1bfb(_0x5bf439._0x5191ab)+_0x1a27ba(0x266)+_0x1f1bfb(_0x5bf439._0x491599)+_0x1f1bfb(_0x5bf439._0x380bc0)+_0x1f1bfb(_0x5bf439._0x4553f6)+_0x1f1bfb(_0x5bf439._0x32a9fe)+_0x1f1bfb(_0x5bf439._0xb5a39d)+_0x1a27ba(0x26e)+_0x1a27ba(0x193)+_0x1a27ba(0x2b1)+_0x1f1bfb(0x2a9)+_0x1a27ba(_0x5bf439._0x44c11d)+_0x1f1bfb(_0x5bf439._0x13f409)+_0x1f1bfb(_0x5bf439._0x3dadfe)+_0x1a27ba(_0x5bf439._0x58b3b6)+_0x1a27ba(_0x5bf439._0x182d80)+_0x1a27ba(_0x5bf439._0x340750)+_0x1f1bfb(0x256)+_0x1a27ba(_0x5bf439._0x3916eb)+_0x1f1bfb(0x23d)+_0x1a27ba(0x215)+_0x1a27ba(_0x5bf439._0x1bca6d)+_0x1a27ba(_0x5bf439._0x273b3a)+_0x1a27ba(_0x5bf439._0x5a2b6e)+_0x1f1bfb(0x22f)+_0x1a27ba(_0x5bf439._0x54fd5b)+_0x1f1bfb(_0x5bf439._0x2b9738)+_0x1a27ba(_0x5bf439._0x35898e)+_0x1f1bfb(_0x5bf439._0x3274ee)+_0x1a27ba(_0x5bf439._0x52cf1d)+_0x1a27ba(_0x5bf439._0x1c8556)+_0x1f1bfb(0x209)+_0x1a27ba(_0x5bf439._0x2dae3f)+_0x1a27ba(_0x5bf439._0xd680f9)+_0x1a27ba(_0x5bf439._0x36b944)+_0x1a27ba(0x1d9)+_0x1a27ba(_0x5bf439._0x43cf9c)+_0x1f1bfb(_0x5bf439._0x4aa5f3)+_0x1a27ba(0x24e)+_0x1f1bfb(0x244)+_0x1f1bfb(_0x5bf439._0x3ceca4)+_0x1f1bfb(_0x5bf439._0x10a3f4)+_0x1f1bfb(0x267)+_0x1a27ba(_0x5bf439._0x3d46b9)+_0x1f1bfb(_0x5bf439._0x477a51)+_0x1f1bfb(0x23a)+_0x1a27ba(0x1b9)+_0x1f1bfb(_0x5bf439._0x411874)+_0x1f1bfb(_0x5bf439._0x2a8dd2)+_0x1a27ba(_0x5bf439._0x421b13)+_0x1a27ba(0x196)+_0x1a27ba(0x1c7)+_0x1f1bfb(_0x5bf439._0x1253e7)+_0x1f1bfb(_0x5bf439._0x30c5b8)+_0x1f1bfb(_0x5bf439._0x7c546c)+_0x1a27ba(_0x5bf439._0x5d1c3e)+_0x1a27ba(_0x5bf439._0x455345)+_0x1f1bfb(_0x5bf439._0x137b6a)+_0x1a27ba(_0x5bf439._0x19527b)+_0x1f1bfb(_0x5bf439._0xb03a7f)+_0x1f1bfb(_0x5bf439._0x4d108a)+_0x1f1bfb(_0x5bf439._0x907898)+_0x1f1bfb(_0x5bf439._0x4c836b)+_0x1f1bfb(0x1be)+_0x1f1bfb(_0x5bf439._0x1aa385)+_0x1a27ba(_0x5bf439._0x4f3f45)+_0x1f1bfb(0x190)+_0x1a27ba(_0x5bf439._0x59f990)+_0x1a27ba(_0x5bf439._0x568b2b)+_0x1f1bfb(_0x5bf439._0x59034a)+_0x1f1bfb(_0x5bf439._0x50f0ef)+_0x1f1bfb(_0x5bf439._0x5a8759)+_0x1f1bfb(_0x5bf439._0x38e7d5)+_0x1f1bfb(_0x5bf439._0x56407a)+_0x1f1bfb(0x208)+_0x1a27ba(_0x5bf439._0x455070)+_0x1f1bfb(0x1b6)+_0x1a27ba(0x283)+_0x1a27ba(_0x5bf439._0x139b92)+_0x1a27ba(_0x5bf439._0x1a717c)+_0x1f1bfb(_0x5bf439._0x15e97e)+_0x1a27ba(_0x5bf439._0x56861e)+_0x1a27ba(_0x5bf439._0x1918c1)+_0x1f1bfb(_0x5bf439._0x24e466)+_0x1a27ba(_0x5bf439._0x312f4f)+_0x1f1bfb(_0x5bf439._0x3b7230)+_0x1a27ba(_0x5bf439._0x3fbbbd)+_0x1a27ba(_0x5bf439._0x3125eb)+_0x1a27ba(0x1af)+_0x1a27ba(_0x5bf439._0x5e08bb)+_0x1a27ba(_0x5bf439._0x2a11a8)+_0x1f1bfb(_0x5bf439._0x51930a)+_0x1a27ba(_0x5bf439._0x14990a)+_0x1f1bfb(0x20d)+_0x1a27ba(_0x5bf439._0x5cb681)+_0x1a27ba(_0x5bf439._0x5a73e6)+_0x1f1bfb(_0x5bf439._0x593e9a)+_0x1a27ba(_0x5bf439._0x1575fa)+_0x1a27ba(_0x5bf439._0x398783)+_0x1a27ba(_0x5bf439._0x106322)+_0x1a27ba(_0x5bf439._0x569c05)+_0x1a27ba(_0x5bf439._0x17f337)+_0x1a27ba(_0x5bf439._0x6a3fd6)+_0x1a27ba(0x22c)+_0x1a27ba(_0x5bf439._0x3bd12e)+_0x1f1bfb(_0x5bf439._0x26ac0a)+_0x1a27ba(_0x5bf439._0x45b81b)+_0x1a27ba(_0x5bf439._0x30be56)+_0x1f1bfb(_0x5bf439._0x5954f3)+_0x1f1bfb(_0x5bf439._0xe89086)+_0x1f1bfb(_0x5bf439._0x19f979)+_0x1a27ba(_0x5bf439._0x373387)+_0x1a27ba(_0x5bf439._0x2403f7)+_0x1a27ba(_0x5bf439._0x447479)+_0x1a27ba(_0x5bf439._0x436bd5)+_0x1a27ba(_0x5bf439._0x59ca2e)+_0x1f1bfb(_0x5bf439._0x5587c2)+_0x1f1bfb(_0x5bf439._0x3da315)+_0x1a27ba(_0x5bf439._0x5ec0f3)+_0x1a27ba(_0x5bf439._0x23b8ed)+_0x1f1bfb(_0x5bf439._0x20b3ff)+_0x1f1bfb(0x263)+_0x1f1bfb(_0x5bf439._0x1fec53)+_0x1f1bfb(_0x5bf439._0x370188)+_0x1a27ba(_0x5bf439._0x2124c0)+_0x1a27ba(0x26a)+_0x1a27ba(0x247)+_0x1a27ba(_0x5bf439._0x1cabad)+_0x1a27ba(_0x5bf439._0x56bcbe)+_0x1a27ba(_0x5bf439._0x1b9df5)+_0x1f1bfb(_0x5bf439._0x15bf36)+_0x1f1bfb(_0x5bf439._0x4da1e4)+_0x1f1bfb(_0x5bf439._0x440345)+_0x1a27ba(_0x5bf439._0x3c36f0)+_0x1a27ba(0x1d6)+_0x1f1bfb(0x2ac)+_0x1a27ba(_0x5bf439._0x281595)+_0x1f1bfb(_0x5bf439._0x37b7c5)+_0x1a27ba(_0x5bf439._0x52a52f)+_0x1a27ba(_0x5bf439._0x5e5e34)+_0x1f1bfb(_0x5bf439._0x27d28b)+_0x1f1bfb(_0x5bf439._0x45d4d6)+_0x1f1bfb(_0x5bf439._0x3f8de0)+_0x1a27ba(0x22d)+'1'),_0x42b66a=0x10001n;function _0x2dd270(_0x128e02,_0x4f2cd5,_0x4e5d04){const _0x147620=_0x1a27ba,_0x51b4b5=_0x1a27ba;let _0x50a7ee=0x1n;_0x128e02=_0x52c2e7[_0x147620(0x23c)+'r'](_0x128e02,_0x4e5d04);while(_0x4f2cd5>0x0n){if(_0x4f2cd5%0x2n===0x1n)_0x50a7ee=_0x52c2e7[_0x147620(0x235)+'C'](_0x50a7ee*_0x128e02,_0x4e5d04);_0x4f2cd5=_0x4f2cd5/0x2n,_0x128e02=_0x52c2e7[_0x147620(0x24f)+'w'](_0x128e02,_0x128e02)%_0x4e5d04;}return _0x50a7ee;}function _0x46bbfc(_0x127557){const _0x2de0e1=_0x1f1bfb,_0x5593a7=_0x1f1bfb;let _0x2af96c=_0x127557[_0x2de0e1(_0x394da5._0x1f74d1)+_0x5593a7(_0x394da5._0x33cd87)](0x10);if(_0x2af96c[_0x2de0e1(_0x394da5._0x13b0c2)+'th']%0x2!==0x0)_0x2af96c='0'+_0x2af96c;let _0x3f1b14='';for(let _0x35c9a4=0x0;_0x35c9a4<_0x2af96c[_0x5593a7(_0x394da5._0x13b0c2)+'th'];_0x35c9a4+=0x2){_0x3f1b14+=String[_0x2de0e1(_0x394da5._0x1815e2)+_0x2de0e1(_0x394da5._0x428ae1)+_0x2de0e1(_0x394da5._0x48ee7b)](parseInt(_0x2af96c[_0x2de0e1(_0x394da5._0x412f7c)+'tr'](_0x35c9a4,0x2),0x10));}return _0x3f1b14;}function _0x43a7a7(_0x34a3a7){const _0x32df3b=_0x1a27ba,_0x3789ab=_0x1a27ba;let _0x1ff27d='';for(let _0xf4d376=0x0;_0xf4d376<_0x34a3a7[_0x32df3b(_0x2f418e._0x59c148)+'th'];_0xf4d376++){_0x1ff27d+=_0x34a3a7[_0x3789ab(_0x2f418e._0xc093c9)+_0x32df3b(_0x2f418e._0x10dfdd)+'At'](_0xf4d376)[_0x3789ab(_0x2f418e._0x224a7f)+_0x32df3b(_0x2f418e._0x3afba7)](0x10)[_0x32df3b(_0x2f418e._0x46a4b7)+_0x3789ab(_0x2f418e._0x3771aa)](0x2,'0');}return BigInt(_0x52c2e7[_0x3789ab(_0x2f418e._0x3f1a3a)+'s']('0x',_0x1ff27d));}function _0x36d753(_0x44099b){const _0x549754=_0x1a27ba,_0x2139b2=_0x1a27ba;function _0x3ab292(_0x4eece5,_0x13e29b){return _0x4eece5>>>_0x13e29b|_0x4eece5<<0x20-_0x13e29b;}var _0x483bfb=Math[_0x549754(_0x4fadcb._0x14daf0)],_0x15f069=_0x52c2e7[_0x549754(_0x4fadcb._0x4deba2)+'G'](_0x483bfb,0x2,0x20),_0x1e1a35=_0x2139b2(_0x4fadcb._0x7a2127)+'th',_0x2403f8,_0x3b565a,_0x5d0c70='',_0x32338d=[],_0x22029e=_0x44099b[_0x1e1a35]*0x8,_0x217eb1=_0x36d753['h']=_0x36d753['h']||[],_0x22c622=_0x36d753['k']=_0x36d753['k']||[],_0x265d54=_0x22c622[_0x1e1a35],_0x3a6f86={};for(var _0x35122f=0x2;_0x265d54<0x40;_0x35122f++){if(!_0x3a6f86[_0x35122f]){for(_0x2403f8=0x0;_0x52c2e7[_0x549754(_0x4fadcb._0x5f4eef)+'Q'](_0x2403f8,0x139);_0x2403f8+=_0x35122f){_0x3a6f86[_0x2403f8]=_0x35122f;}_0x217eb1[_0x265d54]=_0x483bfb(_0x35122f,0.5)*_0x15f069|0x0,_0x22c622[_0x265d54++]=_0x52c2e7[_0x549754(_0x4fadcb._0x32655e)+'G'](_0x483bfb,_0x35122f,0x1/0x3)*_0x15f069|0x0;}}_0x44099b+='\u0080';while(_0x44099b[_0x1e1a35]%0x40-0x38)_0x44099b+='\x00';for(_0x2403f8=0x0;_0x2403f8<_0x44099b[_0x1e1a35];_0x2403f8++){_0x3b565a=_0x44099b[_0x2139b2(_0x4fadcb._0x4d2f69)+_0x2139b2(_0x4fadcb._0x532083)+'At'](_0x2403f8);if(_0x52c2e7[_0x2139b2(_0x4fadcb._0x45e71e)+'I'](_0x3b565a,0x8))return;_0x32338d[_0x2403f8>>0x2]|=_0x3b565a<<_0x52c2e7[_0x2139b2(_0x4fadcb._0x349d75)+'C'](0x3-_0x2403f8,0x4)*0x8;}_0x32338d[_0x32338d[_0x1e1a35]]=_0x52c2e7[_0x2139b2(0x27c)+'P'](_0x22029e/_0x15f069,0x0),_0x32338d[_0x32338d[_0x1e1a35]]=_0x22029e;for(_0x3b565a=0x0;_0x3b565a<_0x32338d[_0x1e1a35];){var _0x357ae7=_0x32338d[_0x2139b2(_0x4fadcb._0x2073e1)+'e'](_0x3b565a,_0x3b565a+=0x10),_0x4a4d56=_0x217eb1;_0x217eb1=_0x217eb1[_0x2139b2(0x24d)+'e'](0x0,0x8);for(_0x2403f8=0x0;_0x52c2e7[_0x2139b2(_0x4fadcb._0x512169)+'Q'](_0x2403f8,0x40);_0x2403f8++){var _0x5bd626=_0x357ae7[_0x2403f8-0xf],_0xfa76eb=_0x357ae7[_0x52c2e7[_0x549754(_0x4fadcb._0x3da9a9)+'v'](_0x2403f8,0x2)],_0x540aab=_0x217eb1[0x0],_0x1e17a7=_0x217eb1[0x4],_0xa351a5=_0x217eb1[0x7]+(_0x3ab292(_0x1e17a7,0x6)^_0x52c2e7[_0x549754(_0x4fadcb._0x4e1cf8)+'G'](_0x3ab292,_0x1e17a7,0xb)^_0x52c2e7[_0x549754(_0x4fadcb._0x2f062b)+'G'](_0x3ab292,_0x1e17a7,0x19))+_0x52c2e7[_0x2139b2(_0x4fadcb._0x5ee348)+'p'](_0x1e17a7&_0x217eb1[0x5],~_0x1e17a7&_0x217eb1[0x6])+_0x22c622[_0x2403f8]+(_0x357ae7[_0x2403f8]=_0x52c2e7[_0x549754(0x2a3)+'P'](_0x2403f8,0x10)?_0x357ae7[_0x2403f8]:_0x357ae7[_0x52c2e7[_0x2139b2(_0x4fadcb._0x1ce114)+'s'](_0x2403f8,0x10)]+(_0x52c2e7[_0x549754(_0x4fadcb._0x447c6f)+'q'](_0x3ab292(_0x5bd626,0x7),_0x52c2e7[_0x2139b2(_0x4fadcb._0x1f1c70)+'G'](_0x3ab292,_0x5bd626,0x12))^_0x5bd626>>>0x3)+_0x357ae7[_0x52c2e7[_0x549754(0x294)+'R'](_0x2403f8,0x7)]+(_0x3ab292(_0xfa76eb,0x11)^_0x3ab292(_0xfa76eb,0x13)^_0xfa76eb>>>0xa)|0x0),_0x3ec3ab=(_0x52c2e7[_0x2139b2(_0x4fadcb._0x4bd85d)+'p'](_0x3ab292(_0x540aab,0x2),_0x3ab292(_0x540aab,0xd))^_0x3ab292(_0x540aab,0x16))+(_0x540aab&_0x217eb1[0x1]^_0x540aab&_0x217eb1[0x2]^_0x217eb1[0x1]&_0x217eb1[0x2]);_0x217eb1=[_0xa351a5+_0x3ec3ab|0x0][_0x2139b2(0x2b3)+'at'](_0x217eb1),_0x217eb1[0x4]=_0x52c2e7[_0x549754(0x1d5)+'z'](_0x217eb1[0x4],_0xa351a5)|0x0;}for(_0x2403f8=0x0;_0x52c2e7[_0x549754(_0x4fadcb._0x5f4eef)+'Q'](_0x2403f8,0x8);_0x2403f8++){_0x217eb1[_0x2403f8]=_0x52c2e7[_0x549754(_0x4fadcb._0x3911d4)+'P'](_0x217eb1[_0x2403f8]+_0x4a4d56[_0x2403f8],0x0);}}for(_0x2403f8=0x0;_0x52c2e7[_0x2139b2(_0x4fadcb._0x2b20de)+'Q'](_0x2403f8,0x8);_0x2403f8++){for(_0x3b565a=0x3;_0x3b565a+0x1;_0x3b565a--){var _0x3450bc=_0x217eb1[_0x2403f8]>>_0x3b565a*0x8&0xff;_0x5d0c70+=(_0x52c2e7[_0x549754(_0x4fadcb._0x38dcff)+'Q'](_0x3450bc,0x10)?0x0:'')+_0x3450bc[_0x549754(_0x4fadcb._0x2a8512)+_0x549754(_0x4fadcb._0x1a80bf)](0x10);}}return _0x5d0c70;}class LicenseManager{static validate(_0x588699,_0x28a664={}){const _0x562b0a=_0x1a27ba,_0x4b335b=_0x1a27ba;if(!_0x588699)return{'valid':![],'tier':null,'reason':_0x562b0a(0x1f2)+_0x562b0a(_0x3b1685._0x5949a6)+_0x4b335b(_0x3b1685._0x3947b9)+_0x562b0a(_0x3b1685._0x5138b1)};const _0x32bc05=_0x588699[_0x562b0a(_0x3b1685._0x42b551)](),_0x3c8c2f=_0x32bc05[_0x4b335b(_0x3b1685._0x128bfa)+_0x562b0a(0x298)+_0x562b0a(_0x3b1685._0x1f82ba)](),_0x4a1076=_0x3c8c2f[_0x562b0a(_0x3b1685._0x1b4c42)+'t']('-'),_0x431f06=_0x28a664[_0x562b0a(_0x3b1685._0x1bd9e7)+_0x562b0a(_0x3b1685._0x401543)]!==undefined&&_0x52c2e7[_0x4b335b(_0x3b1685._0x44a9ff)+'U'](_0x28a664[_0x4b335b(_0x3b1685._0x724f0d)+_0x4b335b(_0x3b1685._0x401543)],null)?_0x28a664[_0x4b335b(_0x3b1685._0x19a0af)+_0x562b0a(0x212)]:Date[_0x4b335b(0x29d)]();let _0x2f7eeb=0x0;_0x28a664[_0x4b335b(0x1a1)+_0x562b0a(0x243)]&&(_0x2f7eeb=_0x52c2e7[_0x562b0a(_0x3b1685._0x173cc6)+'G'](parseInt,_0x28a664[_0x562b0a(0x1a1)+_0x4b335b(0x243)][_0x562b0a(0x26f)+_0x562b0a(_0x3b1685._0x10de14)](_0x4b335b(_0x3b1685._0x28bea5)+_0x562b0a(_0x3b1685._0x297900)+_0x562b0a(_0x3b1685._0x62565c)+_0x4b335b(0x273)+'e')||'0',0xa),(_0x52c2e7[_0x4b335b(_0x3b1685._0x34b970)+'F'](_0x28a664[_0x562b0a(_0x3b1685._0x142e8d)+_0x562b0a(0x212)],undefined)||_0x52c2e7[_0x4b335b(0x261)+'Q'](_0x28a664[_0x4b335b(_0x3b1685._0x510384)+_0x4b335b(_0x3b1685._0x401543)],null))&&_0x28a664[_0x562b0a(_0x3b1685._0x53aef6)+_0x562b0a(_0x3b1685._0x5851ac)][_0x562b0a(_0x3b1685._0x2ef587)+_0x4b335b(_0x3b1685._0xa47e82)](_0x562b0a(_0x3b1685._0x16cef4)+_0x562b0a(_0x3b1685._0x297900)+_0x562b0a(_0x3b1685._0x266ce1)+_0x562b0a(_0x3b1685._0x20622)+'e',_0x431f06[_0x4b335b(_0x3b1685._0x4e35b2)+_0x4b335b(_0x3b1685._0x55d2a9)]()));if((_0x28a664[_0x562b0a(_0x3b1685._0xa4d890)+_0x562b0a(_0x3b1685._0x401543)]===undefined||_0x52c2e7[_0x4b335b(_0x3b1685._0x3b3fc6)+'F'](_0x28a664[_0x562b0a(0x23e)+_0x562b0a(0x212)],null))&&_0x431f06<_0x2f7eeb){if(_0x28a664[_0x562b0a(_0x3b1685._0x14e676)+_0x562b0a(_0x3b1685._0x5e0ee9)+'y'])_0x28a664[_0x4b335b(_0x3b1685._0x77e64e)+_0x562b0a(_0x3b1685._0x16690b)+'y']();return{'valid':![],'tier':null,'reason':_0x562b0a(_0x3b1685._0x5430a1)+_0x562b0a(0x241)+_0x562b0a(_0x3b1685._0x20e8f5)+_0x562b0a(0x20a)+_0x562b0a(_0x3b1685._0x1bb05a)+_0x4b335b(_0x3b1685._0x2961d2)+_0x4b335b(0x25c)+_0x4b335b(_0x3b1685._0x1ebbac)};}const _0xf9b4cf=typeof atob!==_0x562b0a(_0x3b1685._0x2a2696)+_0x562b0a(0x1f1)+'d'?atob:_0x18888e=>Buffer[_0x562b0a(0x2a6)](_0x18888e,_0x562b0a(0x19d)+'64')[_0x562b0a(0x188)+_0x4b335b(0x1e5)](_0x562b0a(0x2b6)+'ry');if(_0x3c8c2f[_0x4b335b(_0x3b1685._0x4e2153)+_0x562b0a(0x275)+'th'](_0x562b0a(_0x3b1685._0x2c06fd)+_0x562b0a(_0x3b1685._0x3fb034)+'-'))try{const _0x2c227c=_0x32bc05[_0x562b0a(_0x3b1685._0x281057)+_0x562b0a(_0x3b1685._0x3d98d5)+'g'](0x9),_0x1983d3=_0xf9b4cf(_0x2c227c),_0x4f69bb=new Uint8Array(_0x1983d3[_0x4b335b(_0x3b1685._0x2508b1)+'th']);for(let _0x2cc9a8=0x0;_0x2cc9a8<_0x1983d3[_0x562b0a(_0x3b1685._0x27265f)+'th'];_0x2cc9a8++){_0x4f69bb[_0x2cc9a8]=_0x1983d3[_0x4b335b(0x2a7)+_0x4b335b(_0x3b1685._0x5ab3eb)+'At'](_0x2cc9a8);}let _0x3aa092='';for(let _0x48284b=0x0;_0x52c2e7[_0x562b0a(_0x3b1685._0x2372a4)+'K'](_0x48284b,_0x4f69bb[_0x562b0a(0x1bf)+'th']);_0x48284b++){_0x3aa092+=_0x4f69bb[_0x48284b][_0x4b335b(0x188)+_0x4b335b(0x1e5)](0x10)[_0x4b335b(_0x3b1685._0x43018f)+_0x4b335b(_0x3b1685._0x51455a)](0x2,'0');}const _0x26ce3a=_0x52c2e7[_0x562b0a(_0x3b1685._0x299f1a)+'i'](BigInt,'0x'+_0x3aa092),_0x3006fb=_0x52c2e7[_0x562b0a(_0x3b1685._0x41802b)+'M'](_0x2dd270,_0x26ce3a,_0x42b66a,_0x2ea186),_0x27a7ed=_0x46bbfc(_0x3006fb);if(_0x27a7ed[_0x562b0a(0x1a7)+_0x562b0a(_0x3b1685._0x318047)+'th'](_0x52c2e7[_0x4b335b(_0x3b1685._0x567cdd)+'Y'])){const _0x3c85cc=_0x52c2e7[_0x4b335b(0x19a)+'T'](parseInt,_0x27a7ed[_0x4b335b(_0x3b1685._0x281057)+_0x4b335b(_0x3b1685._0x3d98d5)+'g'](0xb),0xa);if(!isNaN(_0x3c85cc)){if(_0x431f06<_0x3c85cc)return{'valid':!![],'tier':_0x52c2e7[_0x562b0a(_0x3b1685._0x5be2c9)+'H'],'expires':_0x3c85cc};if(_0x28a664[_0x562b0a(_0x3b1685._0x109ec8)+_0x4b335b(0x292)+'d'])_0x28a664[_0x4b335b(_0x3b1685._0x109ec8)+_0x4b335b(_0x3b1685._0x3bd7ae)+'d'](_0x562b0a(_0x3b1685._0x2e0857)+'t');return{'valid':![],'tier':null,'reason':_0x4b335b(_0x3b1685._0x1b4cc4)+_0x562b0a(_0x3b1685._0x3d49fc)+_0x4b335b(_0x3b1685._0x3bd7ae)+'d'};}}}catch(_0x3e6e0d){return{'valid':![],'tier':null,'reason':_0x4b335b(_0x3b1685._0x22803f)+_0x4b335b(_0x3b1685._0x522ac9)+_0x4b335b(_0x3b1685._0x4764a3)+_0x562b0a(_0x3b1685._0x574e55)+_0x4b335b(_0x3b1685._0x267070)+_0x562b0a(0x21c)};}if(_0x3c8c2f[_0x4b335b(0x1a7)+_0x4b335b(_0x3b1685._0x3f1461)+'th'](_0x562b0a(0x19e)+_0x4b335b(_0x3b1685._0x3e4d60)))try{const _0x266e0b=_0x32bc05[_0x4b335b(0x2a5)+_0x562b0a(0x197)+'g'](0x7),_0x2012ba=_0x52c2e7[_0x562b0a(_0x3b1685._0x2f5cfc)+'w'](_0xf9b4cf,_0x266e0b),_0x3eb3d1=new Uint8Array(_0x2012ba[_0x4b335b(_0x3b1685._0x27265f)+'th']);for(let _0xada787=0x0;_0xada787<_0x2012ba[_0x562b0a(_0x3b1685._0x558a99)+'th'];_0xada787++){_0x3eb3d1[_0xada787]=_0x2012ba[_0x562b0a(0x2a7)+_0x4b335b(_0x3b1685._0x5ab3eb)+'At'](_0xada787);}let _0x3a83ff='';for(let _0x13489c=0x0;_0x13489c<_0x3eb3d1[_0x562b0a(_0x3b1685._0x32f771)+'th'];_0x13489c++){_0x3a83ff+=_0x3eb3d1[_0x13489c][_0x562b0a(_0x3b1685._0x3524a5)+_0x4b335b(0x1e5)](0x10)[_0x4b335b(_0x3b1685._0x43018f)+_0x562b0a(0x189)](0x2,'0');}const _0x57d18f=BigInt('0x'+_0x3a83ff),_0x41b31a=_0x52c2e7[_0x562b0a(_0x3b1685._0x1ee717)+'O'](_0x2dd270,_0x57d18f,_0x42b66a,_0x2ea186),_0x33cfb3=_0x52c2e7[_0x4b335b(_0x3b1685._0x474218)+'i'](_0x46bbfc,_0x41b31a);if(_0x33cfb3[_0x562b0a(_0x3b1685._0x4b8fb7)+_0x4b335b(_0x3b1685._0x318047)+'th'](_0x562b0a(_0x3b1685._0x316324)+_0x562b0a(_0x3b1685._0x34b06)+'-')){const _0x53edb1=_0x33cfb3[_0x4b335b(_0x3b1685._0x527d4a)+'t']('-');if(_0x53edb1[_0x562b0a(_0x3b1685._0x27265f)+'th']>=0x5){const _0xe08c75=_0x53edb1[0x2],_0x240989=parseInt(_0x53edb1[0x4],0xa);if(!isNaN(_0x240989)){if(_0x431f06<_0x240989)return{'valid':!![],'tier':_0xe08c75,'expires':_0x240989};if(_0x28a664[_0x562b0a(0x248)+_0x4b335b(0x292)+'d'])_0x28a664[_0x4b335b(_0x3b1685._0x109ec8)+_0x4b335b(_0x3b1685._0x2b932a)+'d'](_0x562b0a(_0x3b1685._0x5128db));return{'valid':![],'tier':null,'reason':_0x4b335b(_0x3b1685._0x426d97)+_0x562b0a(_0x3b1685._0x30e3c5)+_0x4b335b(_0x3b1685._0x5b9cd3)+_0x4b335b(_0x3b1685._0x31fda7)};}}}}catch(_0x17b763){return{'valid':![],'tier':null,'reason':_0x4b335b(_0x3b1685._0x822c3e)+_0x562b0a(_0x3b1685._0x44e0a3)+_0x562b0a(_0x3b1685._0x835cec)+_0x4b335b(0x26d)+_0x562b0a(_0x3b1685._0x54a418)+'d'};}if(_0x52c2e7[_0x562b0a(0x1e8)+'a'](_0x4a1076[_0x4b335b(0x1bf)+'th'],0x4)&&_0x4a1076[0x0]==='PS'&&[_0x4b335b(0x1de),_0x4b335b(_0x3b1685._0x32bb65)+'S',_0x562b0a(_0x3b1685._0x3977a0),_0x4b335b(_0x3b1685._0x40782c),_0x4b335b(_0x3b1685._0x327c95)+_0x4b335b(0x2b8)+'SE'][_0x562b0a(_0x3b1685._0x4becb1)+_0x4b335b(_0x3b1685._0x1f866b)](_0x4a1076[0x1])){const _0x1f1165=_0x4a1076[0x1],_0x29b1fe=_0x4a1076[0x2],_0x44ffb3=_0x4a1076[0x3],_0x32f6fc=_0x52c2e7[_0x4b335b(_0x3b1685._0x3a9f1e)+'V'],_0xaec198=_0x29b1fe+_0x32f6fc+_0x1f1165;let _0x49e57e=0x0;for(let _0x111375=0x0;_0x111375<_0xaec198[_0x4b335b(_0x3b1685._0x4b5dbd)+'th'];_0x111375++){_0x49e57e+=_0xaec198[_0x4b335b(_0x3b1685._0x1050ae)+_0x562b0a(_0x3b1685._0x28978b)+'At'](_0x111375)*(_0x111375+0x1);}const _0x451ed2=_0x52c2e7[_0x4b335b(_0x3b1685._0x45ee7a)+'C'](_0x49e57e,0x270f)[_0x4b335b(_0x3b1685._0x4e35b2)+_0x4b335b(0x1e5)]()[_0x4b335b(_0x3b1685._0x43018f)+_0x562b0a(0x189)](0x4,'0');if(_0x44ffb3===_0x451ed2)return{'valid':!![],'tier':_0x1f1165};}if(_0x32bc05[_0x4b335b(_0x3b1685._0x4b8fb7)+_0x562b0a(_0x3b1685._0x48088f)+'th'](_0x52c2e7[_0x4b335b(_0x3b1685._0x9a3c8d)+'Z'])&&_0x32bc05[_0x562b0a(_0x3b1685._0x527d4a)+'t']('.')[_0x4b335b(0x1bf)+'th']===0x3)try{const [_0xc188e7,_0x153054,_0x254189]=_0x32bc05[_0x4b335b(0x2ad)+'t']('.');let _0x59f1fb=_0x254189[_0x4b335b(_0x3b1685._0x572c60)+_0x4b335b(0x27f)](/-/g,'+')[_0x4b335b(_0x3b1685._0x572c60)+_0x562b0a(_0x3b1685._0x2e0bf5)](/_/g,'/');while(_0x59f1fb[_0x562b0a(_0x3b1685._0x2aa692)+'th']%0x4)_0x59f1fb+='=';const _0x19ddf3=_0xf9b4cf(_0x59f1fb);let _0x770037='';for(let _0x412f91=0x0;_0x412f91<_0x19ddf3[_0x4b335b(_0x3b1685._0x2508b1)+'th'];_0x412f91++){_0x770037+=_0x19ddf3[_0x4b335b(_0x3b1685._0x1bd326)+_0x4b335b(_0x3b1685._0x5ab3eb)+'At'](_0x412f91)[_0x4b335b(_0x3b1685._0x3524a5)+_0x562b0a(_0x3b1685._0x5c269d)](0x10)[_0x4b335b(_0x3b1685._0x43018f)+_0x4b335b(_0x3b1685._0x51455a)](0x2,'0');}const _0x2017e3=BigInt('0x'+_0x770037),_0x4ba77d=_0x2dd270(_0x2017e3,_0x42b66a,_0x2ea186);let _0x197cf=_0x4ba77d[_0x562b0a(_0x3b1685._0x5c8870)+_0x562b0a(_0x3b1685._0x2d0913)](0x10);if(_0x197cf[_0x562b0a(_0x3b1685._0x1d46ff)+'th']%0x2!==0x0)_0x197cf='0'+_0x197cf;const _0x367180=_0x36d753(_0xc188e7+'.'+_0x153054);if(_0x197cf[_0x4b335b(_0x3b1685._0x39c204)+_0x562b0a(_0x3b1685._0x5503a0)](_0x367180)){const _0x38cbe1=_0xf9b4cf(_0x153054[_0x562b0a(_0x3b1685._0x572c60)+_0x562b0a(_0x3b1685._0x2e0bf5)](/-/g,'+')[_0x4b335b(_0x3b1685._0x572c60)+_0x4b335b(_0x3b1685._0x2e0bf5)](/_/g,'/')),_0x4436f0=JSON[_0x562b0a(_0x3b1685._0x511cd7)+'e'](_0x38cbe1);if(_0x4436f0[_0x4b335b(_0x3b1685._0x376667)]&&_0x52c2e7[_0x4b335b(_0x3b1685._0xdd7b92)+'X'](_0x431f06,0x3e8)<_0x4436f0[_0x4b335b(_0x3b1685._0x3fa2f3)])return{'valid':!![],'tier':_0x4436f0[_0x562b0a(0x2b9)]||_0x52c2e7[_0x562b0a(_0x3b1685._0x5e1fcb)+'w'],'expires':_0x4436f0[_0x4b335b(_0x3b1685._0x376667)]*0x3e8};else{if(_0x28a664[_0x4b335b(_0x3b1685._0x109ec8)+_0x562b0a(_0x3b1685._0x101290)+'d'])_0x28a664[_0x562b0a(_0x3b1685._0x109ec8)+_0x562b0a(_0x3b1685._0x3bd7ae)+'d'](_0x562b0a(_0x3b1685._0x466dd2));return{'valid':![],'tier':null,'reason':_0x4b335b(_0x3b1685._0x12eaf2)+_0x562b0a(_0x3b1685._0x25931a)+_0x4b335b(_0x3b1685._0x1488a6)};}}}catch(_0x17ec22){return{'valid':![],'tier':null,'reason':_0x52c2e7[_0x562b0a(0x1f4)+'q']};}return{'valid':![],'tier':null,'reason':_0x562b0a(_0x3b1685._0x415e61)+_0x4b335b(_0x3b1685._0x1ce002)+_0x4b335b(_0x3b1685._0x4be483)+'at'};}}typeof globalThis!==_0x1f1bfb(0x230)+_0x1a27ba(_0x5bf439._0x537b59)+'d'&&(globalThis[_0x1a27ba(_0x5bf439._0x44c5c9)+_0x1f1bfb(_0x5bf439._0x1e2a0f)+_0x1a27ba(0x192)+'er']=LicenseManager),typeof _0x19bda1!==_0x52c2e7[_0x1f1bfb(_0x5bf439._0x5ac6a0)+'Z']&&(_0x19bda1[_0x1a27ba(_0x5bf439._0x1b09a3)+_0x1a27ba(_0x5bf439._0x1e2a0f)+_0x1a27ba(_0x5bf439._0x2cb862)+'er']=LicenseManager),_0x52c2e7[_0x1f1bfb(_0x5bf439._0x2bde18)+'U'](typeof window,_0x52c2e7[_0x1f1bfb(_0x5bf439._0x5ac6a0)+'Z'])&&(window[_0x1f1bfb(_0x5bf439._0x44c5c9)+_0x1a27ba(0x288)+_0x1f1bfb(0x192)+'er']=LicenseManager),_0x52c2e7[_0x1f1bfb(_0x5bf439._0x4a6d1c)+'b'](typeof exports,_0x1f1bfb(_0x5bf439._0x24b3f7)+_0x1f1bfb(_0x5bf439._0x537b59)+'d')&&(typeof module!==_0x1a27ba(_0x5bf439._0x24b3f7)+_0x1a27ba(0x1f1)+'d'&&module[_0x1f1bfb(_0x5bf439._0x112768)+_0x1f1bfb(_0x5bf439._0x10a4ba)]&&(module[_0x1f1bfb(0x2b7)+_0x1f1bfb(_0x5bf439._0x10a4ba)]=LicenseManager),exports[_0x1a27ba(0x1c8)+_0x1a27ba(0x288)+_0x1a27ba(_0x5bf439._0x2cb862)+'er']=LicenseManager);}(typeof globalThis!==_0x3c19f9(0x230)+_0x43b883(0x1f1)+'d'?globalThis:typeof window!==_0x3c19f9(0x230)+_0x3c19f9(0x1f1)+'d'?window:this));
|
|
1
|
+
(function(global) {
|
|
2
|
+
// ── START LICENSE CRYPTO ──
|
|
3
|
+
const PUBLIC_KEY_N = BigInt("21317979104050344678233452423803986868842680501941538057759536089609908024281729760556922188810565541201321990374637212776148857190553192389608364990754937991254608109727112734447704854882786946805547031142530865504430968628760311494129154950865158735816268612258108296781892583171421605668998979064782378729322077179022581884976242706169323540456286526420742434868559866211716347133681429395477256705746276962607312574959642065929462114149296066812527505837608212730874704915352119747022918247963886630350365119206627670591400728523813746184290857872958847087691236909900501703203494160206941648263514117706558791691");
|
|
4
|
+
const PUBLIC_KEY_E = 65537n;
|
|
5
|
+
|
|
6
|
+
function modPow(base, exp, mod) {
|
|
7
|
+
let res = 1n;
|
|
8
|
+
base = base % mod;
|
|
9
|
+
while (exp > 0n) {
|
|
10
|
+
if (exp % 2n === 1n) res = (res * base) % mod;
|
|
11
|
+
exp = exp / 2n;
|
|
12
|
+
base = (base * base) % mod;
|
|
13
|
+
}
|
|
14
|
+
return res;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function bigIntToString(bi) {
|
|
18
|
+
let hex = bi.toString(16);
|
|
19
|
+
if (hex.length % 2 !== 0) hex = '0' + hex;
|
|
20
|
+
let str = '';
|
|
21
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
22
|
+
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
|
|
23
|
+
}
|
|
24
|
+
return str;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function stringToBigInt(str) {
|
|
28
|
+
let hex = '';
|
|
29
|
+
for (let i = 0; i < str.length; i++) {
|
|
30
|
+
hex += str.charCodeAt(i).toString(16).padStart(2, '0');
|
|
31
|
+
}
|
|
32
|
+
return BigInt('0x' + hex);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function sha256(ascii) {
|
|
36
|
+
function rightRotate(value, amount) { return (value>>>amount) | (value<<(32 - amount)); }
|
|
37
|
+
var mathPow = Math.pow; var maxWord = mathPow(2, 32);
|
|
38
|
+
var lengthProperty = 'length'; var i, j;
|
|
39
|
+
var result = ''; var words = []; var asciiBitLength = ascii[lengthProperty]*8;
|
|
40
|
+
var hash = sha256.h = sha256.h || [];
|
|
41
|
+
var k = sha256.k = sha256.k || [];
|
|
42
|
+
var primeCounter = k[lengthProperty];
|
|
43
|
+
var isComposite = {};
|
|
44
|
+
for (var candidate = 2; primeCounter < 64; candidate++) {
|
|
45
|
+
if (!isComposite[candidate]) {
|
|
46
|
+
for (i = 0; i < 313; i += candidate) { isComposite[i] = candidate; }
|
|
47
|
+
hash[primeCounter] = (mathPow(candidate, .5)*maxWord)|0;
|
|
48
|
+
k[primeCounter++] = (mathPow(candidate, 1/3)*maxWord)|0;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
ascii += '\x80';
|
|
52
|
+
while (ascii[lengthProperty]%64 - 56) ascii += '\x00';
|
|
53
|
+
for (i = 0; i < ascii[lengthProperty]; i++) {
|
|
54
|
+
j = ascii.charCodeAt(i);
|
|
55
|
+
if (j>>8) return;
|
|
56
|
+
words[i>>2] |= j << ((3 - i)%4)*8;
|
|
57
|
+
}
|
|
58
|
+
words[words[lengthProperty]] = ((asciiBitLength/maxWord)|0);
|
|
59
|
+
words[words[lengthProperty]] = (asciiBitLength)
|
|
60
|
+
for (j = 0; j < words[lengthProperty];) {
|
|
61
|
+
var w = words.slice(j, j += 16);
|
|
62
|
+
var oldHash = hash;
|
|
63
|
+
hash = hash.slice(0, 8);
|
|
64
|
+
for (i = 0; i < 64; i++) {
|
|
65
|
+
var w15 = w[i - 15], w2 = w[i - 2];
|
|
66
|
+
var a = hash[0], e = hash[4];
|
|
67
|
+
var temp1 = hash[7] + (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25)) + ((e&hash[5])^((~e)&hash[6])) + k[i] + (w[i] = (i < 16) ? w[i] : (w[i - 16] + (rightRotate(w15, 7) ^ rightRotate(w15, 18) ^ (w15>>>3)) + w[i - 7] + (rightRotate(w2, 17) ^ rightRotate(w2, 19) ^ (w2>>>10)))|0);
|
|
68
|
+
var temp2 = (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22)) + ((a&hash[1])^(a&hash[2])^(hash[1]&hash[2]));
|
|
69
|
+
hash = [(temp1 + temp2)|0].concat(hash);
|
|
70
|
+
hash[4] = (hash[4] + temp1)|0;
|
|
71
|
+
}
|
|
72
|
+
for (i = 0; i < 8; i++) { hash[i] = (hash[i] + oldHash[i])|0; }
|
|
73
|
+
}
|
|
74
|
+
for (i = 0; i < 8; i++) {
|
|
75
|
+
for (j = 3; j + 1; j--) {
|
|
76
|
+
var b = (hash[i]>>(j*8))&255;
|
|
77
|
+
result += ((b < 16) ? 0 : '') + b.toString(16);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
// ── END LICENSE CRYPTO ──
|
|
83
|
+
|
|
84
|
+
class LicenseManager {
|
|
85
|
+
/**
|
|
86
|
+
* Validates a license key universally across all environments.
|
|
87
|
+
* @param {string} key - The license key.
|
|
88
|
+
* @param {object} options - Options mapping to environment specifics.
|
|
89
|
+
* @returns {object} { valid: boolean, tier: string|null, reason?: string, expires?: number }
|
|
90
|
+
*/
|
|
91
|
+
static validate(key, options = {}) {
|
|
92
|
+
if (!key) return { valid: false, tier: null, reason: "No key provided" };
|
|
93
|
+
const rawKey = key.trim();
|
|
94
|
+
const k = rawKey.toUpperCase();
|
|
95
|
+
const parts = k.split('-');
|
|
96
|
+
|
|
97
|
+
const now = options.mockTime !== undefined && options.mockTime !== null ? options.mockTime : Date.now();
|
|
98
|
+
let lastSeen = 0;
|
|
99
|
+
|
|
100
|
+
if (options.storage) {
|
|
101
|
+
lastSeen = parseInt(options.storage.getItem('ps_last_seen_time') || '0', 10);
|
|
102
|
+
if (options.mockTime === undefined || options.mockTime === null) {
|
|
103
|
+
options.storage.setItem('ps_last_seen_time', now.toString());
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Clock rollback guard
|
|
108
|
+
if ((options.mockTime === undefined || options.mockTime === null) && now < lastSeen) {
|
|
109
|
+
if (options.onAnomaly) options.onAnomaly();
|
|
110
|
+
return { valid: false, tier: null, reason: "Clock rollback anomaly detected" };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const _atob = typeof atob !== 'undefined' ? atob : (str) => Buffer.from(str, 'base64').toString('binary');
|
|
114
|
+
|
|
115
|
+
// 1. Process Pilot Keys (RSA-1024 Encrypted Timestamps)
|
|
116
|
+
if (k.startsWith('PS-PILOT-')) {
|
|
117
|
+
try {
|
|
118
|
+
const payload = rawKey.substring(9);
|
|
119
|
+
const binary = _atob(payload);
|
|
120
|
+
const bytes = new Uint8Array(binary.length);
|
|
121
|
+
for (let i = 0; i < binary.length; i++) {
|
|
122
|
+
bytes[i] = binary.charCodeAt(i);
|
|
123
|
+
}
|
|
124
|
+
let hex = '';
|
|
125
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
126
|
+
hex += bytes[i].toString(16).padStart(2, '0');
|
|
127
|
+
}
|
|
128
|
+
const S = BigInt('0x' + hex);
|
|
129
|
+
|
|
130
|
+
const M = modPow(S, PUBLIC_KEY_E, PUBLIC_KEY_N);
|
|
131
|
+
const decryptedStr = bigIntToString(M);
|
|
132
|
+
|
|
133
|
+
if (decryptedStr.startsWith('ZTDS-PILOT-')) {
|
|
134
|
+
const expDate = parseInt(decryptedStr.substring(11), 10);
|
|
135
|
+
if (!isNaN(expDate)) {
|
|
136
|
+
if (now < expDate) return { valid: true, tier: 'TEAMS', expires: expDate };
|
|
137
|
+
|
|
138
|
+
if (options.onExpired) options.onExpired('Pilot');
|
|
139
|
+
return { valid: false, tier: null, reason: "Pilot expired" };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
} catch(e) {
|
|
143
|
+
return { valid: false, tier: null, reason: "Pilot decryption failed" };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 1.5. Process RSA Signed Keys (PS-RSA-...)
|
|
148
|
+
if (k.startsWith('PS-RSA-')) {
|
|
149
|
+
try {
|
|
150
|
+
const payload = rawKey.substring(7);
|
|
151
|
+
const binary = _atob(payload);
|
|
152
|
+
const bytes = new Uint8Array(binary.length);
|
|
153
|
+
for (let i = 0; i < binary.length; i++) {
|
|
154
|
+
bytes[i] = binary.charCodeAt(i);
|
|
155
|
+
}
|
|
156
|
+
let hex = '';
|
|
157
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
158
|
+
hex += bytes[i].toString(16).padStart(2, '0');
|
|
159
|
+
}
|
|
160
|
+
const S = BigInt('0x' + hex);
|
|
161
|
+
|
|
162
|
+
const M = modPow(S, PUBLIC_KEY_E, PUBLIC_KEY_N);
|
|
163
|
+
const decryptedStr = bigIntToString(M);
|
|
164
|
+
|
|
165
|
+
if (decryptedStr.startsWith('ZTDS-LIC-')) {
|
|
166
|
+
const pieces = decryptedStr.split('-');
|
|
167
|
+
if (pieces.length >= 5) {
|
|
168
|
+
const tier = pieces[2];
|
|
169
|
+
const expires = parseInt(pieces[4], 10);
|
|
170
|
+
if (!isNaN(expires)) {
|
|
171
|
+
if (now < expires) return { valid: true, tier: tier, expires: expires };
|
|
172
|
+
|
|
173
|
+
if (options.onExpired) options.onExpired('RSA');
|
|
174
|
+
return { valid: false, tier: null, reason: "RSA key expired" };
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
} catch(e) {
|
|
179
|
+
return { valid: false, tier: null, reason: "RSA decryption failed" };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// 2. Process Modern Prefixed Keys (v1.4.2+ Salted Checksum)
|
|
184
|
+
if (parts.length === 4 && parts[0] === 'PS' && ['PRO', 'TEAMS', 'SDK', 'OEM', 'ENTERPRISE'].includes(parts[1])) {
|
|
185
|
+
const tier = parts[1];
|
|
186
|
+
const core = parts[2];
|
|
187
|
+
const checksum = parts[3];
|
|
188
|
+
const salt = "ZTDS_SALT_2026_!@#";
|
|
189
|
+
const input = core + salt + tier;
|
|
190
|
+
let sum = 0;
|
|
191
|
+
for (let i = 0; i < input.length; i++) {
|
|
192
|
+
sum += input.charCodeAt(i) * (i + 1);
|
|
193
|
+
}
|
|
194
|
+
const expectedChecksum = (sum % 9999).toString().padStart(4, '0');
|
|
195
|
+
if (checksum === expectedChecksum) {
|
|
196
|
+
return { valid: true, tier: tier };
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// 3. Process Standard RS256 JWTs (eyJ...)
|
|
201
|
+
if (rawKey.startsWith('eyJ') && rawKey.split('.').length === 3) {
|
|
202
|
+
try {
|
|
203
|
+
const [b64Header, b64Payload, b64Signature] = rawKey.split('.');
|
|
204
|
+
|
|
205
|
+
let sigStr = b64Signature.replace(/-/g, '+').replace(/_/g, '/');
|
|
206
|
+
while (sigStr.length % 4) sigStr += '=';
|
|
207
|
+
const binarySig = _atob(sigStr);
|
|
208
|
+
let hexSig = '';
|
|
209
|
+
for (let i = 0; i < binarySig.length; i++) {
|
|
210
|
+
hexSig += binarySig.charCodeAt(i).toString(16).padStart(2, '0');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const S = BigInt('0x' + hexSig);
|
|
214
|
+
const M = modPow(S, PUBLIC_KEY_E, PUBLIC_KEY_N);
|
|
215
|
+
|
|
216
|
+
let mHex = M.toString(16);
|
|
217
|
+
if (mHex.length % 2 !== 0) mHex = '0' + mHex;
|
|
218
|
+
|
|
219
|
+
const expectedHash = sha256(b64Header + '.' + b64Payload);
|
|
220
|
+
|
|
221
|
+
if (mHex.endsWith(expectedHash)) {
|
|
222
|
+
const payloadJson = _atob(b64Payload.replace(/-/g, '+').replace(/_/g, '/'));
|
|
223
|
+
const payload = JSON.parse(payloadJson);
|
|
224
|
+
|
|
225
|
+
if (payload.exp && (now / 1000) < payload.exp) {
|
|
226
|
+
return { valid: true, tier: payload.tier || 'PRO', expires: payload.exp * 1000 };
|
|
227
|
+
} else {
|
|
228
|
+
if (options.onExpired) options.onExpired('JWT');
|
|
229
|
+
return { valid: false, tier: null, reason: "JWT expired" };
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
} catch(e) {
|
|
233
|
+
return { valid: false, tier: null, reason: "JWT validation failed" };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return { valid: false, tier: null, reason: "Invalid format" };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
LicenseManager.PUBLIC_KEY_N = PUBLIC_KEY_N;
|
|
242
|
+
LicenseManager.PUBLIC_KEY_E = PUBLIC_KEY_E;
|
|
243
|
+
LicenseManager.OFFLINE_KEY_SALT = "ZTDS_SALT_2026_!@#";
|
|
244
|
+
|
|
245
|
+
// Export module for ES modules, CommonJS, and Browser Global
|
|
246
|
+
if (typeof globalThis !== 'undefined') {
|
|
247
|
+
globalThis.LicenseManager = LicenseManager;
|
|
248
|
+
}
|
|
249
|
+
if (typeof global !== 'undefined') {
|
|
250
|
+
global.LicenseManager = LicenseManager;
|
|
251
|
+
}
|
|
252
|
+
if (typeof window !== 'undefined') {
|
|
253
|
+
window.LicenseManager = LicenseManager;
|
|
254
|
+
}
|
|
255
|
+
if (typeof exports !== 'undefined') {
|
|
256
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
257
|
+
module.exports = LicenseManager;
|
|
258
|
+
}
|
|
259
|
+
exports.LicenseManager = LicenseManager;
|
|
260
|
+
}
|
|
261
|
+
})(typeof globalThis !== 'undefined' ? globalThis : (typeof window !== 'undefined' ? window : this));
|