mirror of
https://github.com/Wx-2025/ST-Amily2-Chat-Optimisation.git
synced 2026-06-06 04:35:51 +00:00
ci: auto build & obfuscate [2026-05-16 19:16:28] (Jenkins #21)
This commit is contained in:
@@ -35,6 +35,7 @@ import { extension_settings } from "/scripts/extensions.js";
|
||||
import { saveSettingsDebounced } from "/script.js";
|
||||
import { extensionName } from "../settings.js";
|
||||
import { apiKeyStore } from "./api-key-store/ApiKeyStore.js";
|
||||
import { configManager } from "./ConfigManager.js";
|
||||
|
||||
// ── 类型与功能槽定义 ──────────────────────────────────────────────────────────
|
||||
|
||||
@@ -71,6 +72,7 @@ export const SLOTS = {
|
||||
cwb: { label: '角色世界书', type: 'chat' },
|
||||
autoCharCard: { label: '一键生卡', type: 'chat' },
|
||||
sybd: { label: '术语表填写', type: 'chat' },
|
||||
tableFilling: { label: '表格填表 / 重整', type: 'chat' },
|
||||
// Embedding 槽
|
||||
ragEmbed: { label: 'RAG 向量化', type: 'embedding' },
|
||||
// Rerank 槽
|
||||
@@ -252,6 +254,11 @@ class ApiProfileManager {
|
||||
...base,
|
||||
maxTokens: data.maxTokens ?? 65500,
|
||||
temperature: data.temperature ?? 1.0,
|
||||
// 自定义参数:透传到 LLM 请求 body 的额外 key/value(top_p、frequency_penalty 等)
|
||||
// 由 utils/api-vendor.js 提供 vendor 标准参数提示,但不强校验。
|
||||
customParams: (typeof data.customParams === 'object' && data.customParams !== null)
|
||||
? data.customParams
|
||||
: {},
|
||||
};
|
||||
}
|
||||
if (type === 'embedding') {
|
||||
@@ -295,6 +302,278 @@ export const apiProfileManager = new ApiProfileManager();
|
||||
}
|
||||
})();
|
||||
|
||||
// ── Profile.provider 迁移 ────────────────────────────────────────────────────
|
||||
// Phase B 改造:旧 'openai' 是"OpenAI 兼容总称",现在拆为 6 个具体 vendor + 'custom_oai'。
|
||||
// 按 URL substring 推断真实 vendor;推断不出来 → 改成 'custom_oai';URL 为空 → 保持 'openai'。
|
||||
// 仅迁移 provider==='openai' 的旧 profile,新值(anthropic/openrouter/deepseek/xai/custom_oai/google/...)一概不动。
|
||||
function _detectVendorFromUrlSync(url) {
|
||||
if (!url) return null;
|
||||
const lower = String(url).toLowerCase();
|
||||
if (lower.includes('anthropic.com')) return 'anthropic';
|
||||
if (lower.includes('openrouter.ai')) return 'openrouter';
|
||||
if (lower.includes('googleapis.com') || lower.includes('aistudio.google.com')) return 'google';
|
||||
if (lower.includes('deepseek.com')) return 'deepseek';
|
||||
if (lower.includes('x.ai') || lower.includes('xai.com')) return 'xai';
|
||||
if (lower.includes('openai.com')) return 'openai';
|
||||
return null;
|
||||
}
|
||||
|
||||
;(() => {
|
||||
try {
|
||||
const s = extension_settings[extensionName];
|
||||
if (!s || !Array.isArray(s[EXT_PROFILES])) return;
|
||||
let migratedCount = 0;
|
||||
for (const profile of s[EXT_PROFILES]) {
|
||||
if (profile?.provider !== 'openai') continue; // 已是新值或非 chat profile
|
||||
const detected = _detectVendorFromUrlSync(profile.apiUrl);
|
||||
if (detected && detected !== 'openai') {
|
||||
profile.provider = detected;
|
||||
migratedCount++;
|
||||
} else if (profile.apiUrl && !detected) {
|
||||
// URL 填了但不匹配任何已知厂商 → 标记为 custom_oai
|
||||
profile.provider = 'custom_oai';
|
||||
migratedCount++;
|
||||
}
|
||||
// URL 为空(新建中)或确实是 openai.com → 保持 'openai'
|
||||
}
|
||||
if (migratedCount > 0) {
|
||||
console.info(`[ApiProfiles] 迁移: ${migratedCount} 个 profile 的 provider 字段已按 URL 重分类。`);
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[ApiProfiles] provider 迁移失败:', e);
|
||||
}
|
||||
})();
|
||||
|
||||
// ── Legacy → Profile 自动迁移(v2.1.x)─────────────────────────────────────
|
||||
// 对每个 chat slot:若没分配 profile 且旧字段(apiUrl + model 都填了)存在,
|
||||
// 自动建一个 profile + 迁移 API Key + 分配给该 slot。
|
||||
// 幂等:通过 _legacyProfileMigrationDone 标记,只在首次 ship 后跑一次。
|
||||
// 旧字段保留不动,由"清除旧配置残留"按钮显式清理。
|
||||
|
||||
/**
|
||||
* 每个 slot 的 legacy 字段映射。jqyh 已合并到 plotOpt 不单独迁移。
|
||||
* cwb / autoCharCard / ragEmbed / ragRerank 字段结构差异较大,留作后续。
|
||||
*/
|
||||
const LEGACY_PROFILE_MIGRATION_MAP = [
|
||||
{
|
||||
slot: 'main',
|
||||
urlKey: 'apiUrl',
|
||||
modelKey: 'model',
|
||||
keyName: 'apiKey',
|
||||
maxTokensKey: 'maxTokens',
|
||||
temperatureKey: 'temperature',
|
||||
name: '主面板 旧配置',
|
||||
},
|
||||
{
|
||||
slot: 'plotOpt',
|
||||
urlKey: 'plotOpt_apiUrl',
|
||||
modelKey: 'plotOpt_model',
|
||||
keyName: 'plotOpt_apiKey',
|
||||
maxTokensKey: 'plotOpt_max_tokens',
|
||||
temperatureKey: 'plotOpt_temperature',
|
||||
name: '剧情优化 旧配置',
|
||||
},
|
||||
{
|
||||
slot: 'plotOptConc',
|
||||
urlKey: 'plotOpt_concurrentApiUrl',
|
||||
modelKey: 'plotOpt_concurrentModel',
|
||||
keyName: 'plotOpt_concurrentApiKey',
|
||||
maxTokensKey: 'plotOpt_concurrentMaxTokens',
|
||||
temperatureKey: null, // 并发优化无独立 temperature 旧字段
|
||||
name: '并发剧情优化 旧配置',
|
||||
},
|
||||
{
|
||||
slot: 'ngms',
|
||||
urlKey: 'ngmsApiUrl',
|
||||
modelKey: 'ngmsModel',
|
||||
keyName: 'ngmsApiKey',
|
||||
maxTokensKey: 'ngmsMaxTokens',
|
||||
temperatureKey: 'ngmsTemperature',
|
||||
name: 'NGMS 旧配置',
|
||||
},
|
||||
{
|
||||
slot: 'nccs',
|
||||
urlKey: 'nccsApiUrl',
|
||||
modelKey: 'nccsModel',
|
||||
keyName: 'nccsApiKey',
|
||||
maxTokensKey: 'nccsMaxTokens',
|
||||
temperatureKey: 'nccsTemperature',
|
||||
name: 'NCCS 旧配置',
|
||||
},
|
||||
{
|
||||
slot: 'sybd',
|
||||
urlKey: 'sybdApiUrl',
|
||||
modelKey: 'sybdModel',
|
||||
keyName: 'sybdApiKey',
|
||||
maxTokensKey: 'sybdMaxTokens',
|
||||
temperatureKey: 'sybdTemperature',
|
||||
name: 'SYBD 旧配置',
|
||||
},
|
||||
];
|
||||
|
||||
;(async () => {
|
||||
try {
|
||||
const s = extension_settings[extensionName];
|
||||
if (!s) return;
|
||||
if (s._legacyProfileMigrationDone) return; // 幂等
|
||||
|
||||
const migrated = [];
|
||||
for (const m of LEGACY_PROFILE_MIGRATION_MAP) {
|
||||
// 已分配 profile 的 slot 跳过
|
||||
if (apiProfileManager.getAssignment(m.slot)) continue;
|
||||
|
||||
const url = String(s[m.urlKey] ?? '').trim();
|
||||
const model = String(s[m.modelKey] ?? '').trim();
|
||||
if (!url || !model) continue; // 旧配置不完整,跳过
|
||||
|
||||
const provider = _detectVendorFromUrlSync(url) || 'custom_oai';
|
||||
|
||||
const profileId = apiProfileManager.createProfile({
|
||||
type: 'chat',
|
||||
name: m.name,
|
||||
provider,
|
||||
apiUrl: url,
|
||||
model,
|
||||
maxTokens: s[m.maxTokensKey] ?? undefined,
|
||||
temperature: m.temperatureKey ? s[m.temperatureKey] : undefined,
|
||||
});
|
||||
|
||||
// 旧 API Key 从 configManager(localStorage)读出,写入 ApiKeyStore
|
||||
try {
|
||||
const legacyKey = configManager.get(m.keyName);
|
||||
if (legacyKey) await apiProfileManager.setKey(profileId, legacyKey);
|
||||
} catch (keyErr) {
|
||||
console.warn(`[ApiProfiles] ${m.slot} Key 迁移失败:`, keyErr);
|
||||
}
|
||||
|
||||
apiProfileManager.setAssignment(m.slot, profileId);
|
||||
migrated.push(`${m.slot} → ${profileId}`);
|
||||
}
|
||||
|
||||
// 新引入的 slot(无 legacy 字段可迁移)默认借用其他 slot 的 profile,
|
||||
// 让升级用户的功能不至于因为没主动分配而中断。用户可以随后改成专属 profile。
|
||||
const SLOT_INHERITANCE = {
|
||||
tableFilling: 'main', // 表格填表历史上默认走主 API,升级后默认沿用 main 的 profile
|
||||
};
|
||||
const linked = [];
|
||||
for (const [newSlot, sourceSlot] of Object.entries(SLOT_INHERITANCE)) {
|
||||
if (apiProfileManager.getAssignment(newSlot)) continue;
|
||||
const sourceId = apiProfileManager.getAssignment(sourceSlot);
|
||||
if (sourceId) {
|
||||
apiProfileManager.setAssignment(newSlot, sourceId);
|
||||
linked.push(`${newSlot} ← ${sourceSlot} (${sourceId})`);
|
||||
}
|
||||
}
|
||||
|
||||
s._legacyProfileMigrationDone = true;
|
||||
saveSettingsDebounced();
|
||||
|
||||
if (migrated.length > 0 || linked.length > 0) {
|
||||
if (migrated.length > 0) {
|
||||
console.info(`[ApiProfiles] 自动迁移 ${migrated.length} 个旧配置 → profile:`, migrated);
|
||||
}
|
||||
if (linked.length > 0) {
|
||||
console.info(`[ApiProfiles] 自动 link ${linked.length} 个新 slot 借用现有 profile:`, linked);
|
||||
}
|
||||
// 延迟提示,等 toastr 就绪
|
||||
setTimeout(() => {
|
||||
if (typeof toastr !== 'undefined' && migrated.length > 0) {
|
||||
toastr.success(
|
||||
`已自动迁移 ${migrated.length} 个旧 API 配置到新连接配置${linked.length > 0 ? `(含 ${linked.length} 个新槽位借用)` : ''}。请检查"API 连接配置"面板,确认无误后可点"清除旧配置残留"。`,
|
||||
'Amily2 配置迁移',
|
||||
{ timeOut: 8000 }
|
||||
);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[ApiProfiles] Legacy → profile 自动迁移失败:', e);
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* 清除旧配置残留 —— 用户在 UI 点击按钮时调用。
|
||||
*
|
||||
* 行为:
|
||||
* 1. 校验所有有 legacy 字段的 slot 都已分配 profile(防止误删导致功能没配置)
|
||||
* 2. 删除 extension_settings 里的 legacy URL / model / maxTokens / temperature / apiMode / tavernProfile / fakeStream 字段
|
||||
* 3. 删除 configManager(localStorage)里的 legacy API Key
|
||||
* 4. 不删 _legacyProfileMigrationDone 标记(避免再次运行迁移)
|
||||
*
|
||||
* @returns {{ ok: boolean, error?: string, clearedFields: number, clearedKeys: number }}
|
||||
*/
|
||||
export function clearLegacyConfig() {
|
||||
const s = extension_settings[extensionName];
|
||||
if (!s) return { ok: false, error: 'extension_settings 不存在', clearedFields: 0, clearedKeys: 0 };
|
||||
|
||||
// 前置校验:每个有 legacy 数据的 slot 必须已分配 profile
|
||||
for (const m of LEGACY_PROFILE_MIGRATION_MAP) {
|
||||
const url = String(s[m.urlKey] ?? '').trim();
|
||||
const model = String(s[m.modelKey] ?? '').trim();
|
||||
const hasLegacy = url || model;
|
||||
if (!hasLegacy) continue;
|
||||
if (!apiProfileManager.getAssignment(m.slot)) {
|
||||
return {
|
||||
ok: false,
|
||||
error: `槽位 "${m.slot}" 仍有旧配置但未分配 profile,清除会导致该模块不可用。请先在 API 连接配置面板为它分配 profile。`,
|
||||
clearedFields: 0,
|
||||
clearedKeys: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 全套 legacy 字段(含 maxTokens / temperature / apiMode / tavernProfile / fakeStream / enabled 等)
|
||||
const ALL_LEGACY_FIELDS = {
|
||||
main: ['apiUrl', 'model', 'maxTokens', 'temperature', 'apiProvider', 'tavernProfile'],
|
||||
plotOpt: ['plotOpt_apiUrl', 'plotOpt_model', 'plotOpt_apiMode', 'plotOpt_tavernProfile', 'plotOpt_max_tokens', 'plotOpt_temperature', 'plotOpt_top_p', 'plotOpt_presence_penalty', 'plotOpt_frequency_penalty'],
|
||||
plotOptConc: ['plotOpt_concurrentApiUrl', 'plotOpt_concurrentModel', 'plotOpt_concurrentApiProvider', 'plotOpt_concurrentMaxTokens'],
|
||||
ngms: ['ngmsApiUrl', 'ngmsModel', 'ngmsApiMode', 'ngmsTavernProfile', 'ngmsMaxTokens', 'ngmsTemperature', 'ngmsFakeStreamEnabled'],
|
||||
nccs: ['nccsApiUrl', 'nccsModel', 'nccsApiMode', 'nccsTavernProfile', 'nccsMaxTokens', 'nccsTemperature', 'nccsFakeStreamEnabled'],
|
||||
sybd: ['sybdApiUrl', 'sybdModel', 'sybdApiMode', 'sybdTavernProfile', 'sybdMaxTokens', 'sybdTemperature'],
|
||||
// jqyh 字段也清掉(已合并到 plotOpt 但残留可能还在)
|
||||
jqyh: ['jqyhApiUrl', 'jqyhModel', 'jqyhApiMode', 'jqyhTavernProfile', 'jqyhMaxTokens', 'jqyhTemperature', 'jqyhEnabled'],
|
||||
};
|
||||
|
||||
const LEGACY_KEY_NAMES = {
|
||||
main: 'apiKey',
|
||||
plotOpt: 'plotOpt_apiKey',
|
||||
plotOptConc: 'plotOpt_concurrentApiKey',
|
||||
ngms: 'ngmsApiKey',
|
||||
nccs: 'nccsApiKey',
|
||||
sybd: 'sybdApiKey',
|
||||
jqyh: 'jqyhApiKey',
|
||||
};
|
||||
|
||||
let clearedFields = 0;
|
||||
let clearedKeys = 0;
|
||||
|
||||
for (const slot of Object.keys(ALL_LEGACY_FIELDS)) {
|
||||
for (const field of ALL_LEGACY_FIELDS[slot]) {
|
||||
if (field in s) {
|
||||
delete s[field];
|
||||
clearedFields++;
|
||||
}
|
||||
}
|
||||
const keyName = LEGACY_KEY_NAMES[slot];
|
||||
if (keyName) {
|
||||
try {
|
||||
if (configManager.get(keyName)) {
|
||||
// configManager.set(key, '') 对敏感字段会同时清除 localStorage + extension_settings
|
||||
configManager.set(keyName, '');
|
||||
clearedKeys++;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(`[ApiProfiles] 清除旧 Key ${keyName} 失败:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saveSettingsDebounced();
|
||||
console.info(`[ApiProfiles] 清除旧配置残留:${clearedFields} 个字段 + ${clearedKeys} 个 Key。`);
|
||||
return { ok: true, clearedFields, clearedKeys };
|
||||
}
|
||||
|
||||
// ── Bus 注册 ──────────────────────────────────────────────────────────────────
|
||||
setTimeout(() => {
|
||||
try {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
const a0_0x35000d=a0_0x1b59;(function(_0x8816cc,_0x1c96f6){const _0x2f2108=a0_0x1b59,_0x49609b=_0x8816cc();while(!![]){try{const _0x2b3831=parseInt(_0x2f2108(0xb7,'OzQe'))/0x1*(-parseInt(_0x2f2108(0xcc,'0*sw'))/0x2)+parseInt(_0x2f2108(0xc6,'OzQe'))/0x3*(parseInt(_0x2f2108(0xba,'iX]J'))/0x4)+parseInt(_0x2f2108(0xc5,'QNX)'))/0x5+-parseInt(_0x2f2108(0xbf,'8nV('))/0x6+parseInt(_0x2f2108(0xc1,'OzQe'))/0x7*(-parseInt(_0x2f2108(0xd3,'xLmU'))/0x8)+-parseInt(_0x2f2108(0xca,'Nl[p'))/0x9*(parseInt(_0x2f2108(0xcb,'dkeB'))/0xa)+parseInt(_0x2f2108(0xc8,'p(lm'))/0xb*(parseInt(_0x2f2108(0xb9,'rEVf'))/0xc);if(_0x2b3831===_0x1c96f6)break;else _0x49609b['push'](_0x49609b['shift']());}catch(_0x541579){_0x49609b['push'](_0x49609b['shift']());}}}(a0_0xf533,0x96d6c));function a0_0x1b59(_0x2dc26a,_0x522808){_0x2dc26a=_0x2dc26a-0xb5;const _0xf533aa=a0_0xf533();let _0x1b59cd=_0xf533aa[_0x2dc26a];if(a0_0x1b59['bSZPtK']===undefined){var _0x86ad60=function(_0x10c615){const _0x36e03e='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x46d791='',_0x307618='';for(let _0x44fca7=0x0,_0x2c4b07,_0xf87044,_0x764e61=0x0;_0xf87044=_0x10c615['charAt'](_0x764e61++);~_0xf87044&&(_0x2c4b07=_0x44fca7%0x4?_0x2c4b07*0x40+_0xf87044:_0xf87044,_0x44fca7++%0x4)?_0x46d791+=String['fromCharCode'](0xff&_0x2c4b07>>(-0x2*_0x44fca7&0x6)):0x0){_0xf87044=_0x36e03e['indexOf'](_0xf87044);}for(let _0x371e12=0x0,_0x577985=_0x46d791['length'];_0x371e12<_0x577985;_0x371e12++){_0x307618+='%'+('00'+_0x46d791['charCodeAt'](_0x371e12)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x307618);};const _0x31dfda=function(_0x487176,_0x31fa2c){let _0x229feb=[],_0x236a9d=0x0,_0x547838,_0x463afc='';_0x487176=_0x86ad60(_0x487176);let _0x5e369a;for(_0x5e369a=0x0;_0x5e369a<0x100;_0x5e369a++){_0x229feb[_0x5e369a]=_0x5e369a;}for(_0x5e369a=0x0;_0x5e369a<0x100;_0x5e369a++){_0x236a9d=(_0x236a9d+_0x229feb[_0x5e369a]+_0x31fa2c['charCodeAt'](_0x5e369a%_0x31fa2c['length']))%0x100,_0x547838=_0x229feb[_0x5e369a],_0x229feb[_0x5e369a]=_0x229feb[_0x236a9d],_0x229feb[_0x236a9d]=_0x547838;}_0x5e369a=0x0,_0x236a9d=0x0;for(let _0xda8512=0x0;_0xda8512<_0x487176['length'];_0xda8512++){_0x5e369a=(_0x5e369a+0x1)%0x100,_0x236a9d=(_0x236a9d+_0x229feb[_0x5e369a])%0x100,_0x547838=_0x229feb[_0x5e369a],_0x229feb[_0x5e369a]=_0x229feb[_0x236a9d],_0x229feb[_0x236a9d]=_0x547838,_0x463afc+=String['fromCharCode'](_0x487176['charCodeAt'](_0xda8512)^_0x229feb[(_0x229feb[_0x5e369a]+_0x229feb[_0x236a9d])%0x100]);}return _0x463afc;};a0_0x1b59['mVPKyC']=_0x31dfda,a0_0x1b59['ivbaBy']={},a0_0x1b59['bSZPtK']=!![];}const _0x10ff19=_0xf533aa[0x0],_0x11c8c3=_0x2dc26a+_0x10ff19,_0x556a35=a0_0x1b59['ivbaBy'][_0x11c8c3];return!_0x556a35?(a0_0x1b59['JnJwVm']===undefined&&(a0_0x1b59['JnJwVm']=!![]),_0x1b59cd=a0_0x1b59['mVPKyC'](_0x1b59cd,_0x522808),a0_0x1b59['ivbaBy'][_0x11c8c3]=_0x1b59cd):_0x1b59cd=_0x556a35,_0x1b59cd;}function a0_0xf533(){const _0x14f1e0=['WRlcTCkLewuoWOyU','rSkLtIGPbdJdMHewW40jwa','W4FcPCohW7pdP3RcQX5cW5mm','ddNdVCkbWR4FW6u9WOPZx359W4WdWR7dTM7cIItcRdVdUCkh','BSkSBXBcN8kACSoSd8kenc3dQq','W6pdOSohWPxcKCo2WPRdHMFcSSkHBmoT','omoPn2xdJmoB','dCoHW4NcJCoSqWpcHHdcVCoVW5G','kSoPrmkjESoSdmkr','W7ddP8kKr8oLW5GpfW','tCoZe1FcG0BcSrTAdCoBC8oU','tqibW6zujgxdMCkQW7K','xCogoWq3W74mW4dcTmkxoCos','kCkUmaKfW5/dICkjWOzDWOxcKY8','W7tcHCkKCCobW7us','W43cOSodW7VdQdldRWX+W5KXWQJdOW','kmoRCmkhESo6kSkK','WOVcLdTPWRimm8o1WRtcOq','WPlcKdrFmmouW65EaCosWRVdH8kU','a2rPtY3dNmohCG','aCojBdhdHduc','W6fYW78mkmoOj8oEWRvcqmkXtaO','W45nFY7dLCkLnqbPhrNcIa','hCoFuSkgWRpcVgJdIG','t8kyzSkBWPRcQwpdOCkJWOJdVa','W4aqjSo4WQRcT8oSe8oyWQ1U','qSofjL5Yv30','sMxcPmoeW4LBW6eRWPnqzK0','WRZdJmkpbmoqWO3cLa','gSkNrXZdTaBdQsjgiG','chvKW6D/W5dcT1xcPr8','W7BdOCopdSkDWQLsiw3cVCoBF8km'];a0_0xf533=function(){return _0x14f1e0;};return a0_0xf533();}export const SENSITIVE_KEYS=new Set([a0_0x35000d(0xbe,'O@8d'),a0_0x35000d(0xcd,'PG2$'),a0_0x35000d(0xbb,'xLmU'),a0_0x35000d(0xb5,'^tpD'),a0_0x35000d(0xc9,'i]&Q'),a0_0x35000d(0xb6,'&5[]'),a0_0x35000d(0xd0,'AzPH'),a0_0x35000d(0xc3,'NR@e')]);
|
||||
const a0_0x12bdd0=a0_0x2c8a;function a0_0xe868(){const _0x2310ad=['jSoxW7VdQX1uySkcWO/cPG','jSkQh8kKW4hcMZxdGmkHjHRdLxvo','CSoCyvpdS8okW5RcNSkmW7u','kLCYxNjdWRRcNfFdKq','AqFdOaBdPH3cL0pcKwq','DeGZWOnGxdNcSSozy8odW4ma','haeZWRRcOCkRW7pcRmktWPtdS300WPi','e8kQeCoVWONdJCkpfSkTWOW','DbNdRXhdPH3cL0pcKwq','W5OUDaWNW5BcPmkxW47dG0q','W5GPFXGJW58','ke/cTLpcKt/cShZcVuNdRa','W7WtW6JcQJrKW4qDW6NdLG','W4PWW7LpWPC7cCkvW4v4W6RdLwpcImkmDgiAW57dS2KrWQOh','eSkUrSkBWQtdTCk+eG','W4f9emk7vSkhW4i1Emkoca7cOue','lmo8WRbjyHTpW5pcLXm0d0G','WOSRWQmkW6b5tmo6W4b5W6BdNgZcVW','W6ldVmkWpSoWtCo9','vg4TW7f1tqO','a8oeWOvRWR/dOgbFsSoo','W70tW6JcQqLJW6a/W5ZdLG','WR1KWQddVdqlbxHhW4Wswq','sCoqmCo3AbG8t8ojcfzgW50','W77cUmoBmqFdJmk6uCkovW9AWPC','WR5QWQZdVZGbEcrLW4yCrtjY','smkfbCoNrbZcUY9CkLtcTG','A2/cRba+WOhcKZXZns0','WO18W5aWWOvaiq/dUCks','ymolW6WGcCkxhmkg'];a0_0xe868=function(){return _0x2310ad;};return a0_0xe868();}function a0_0x2c8a(_0x304b6c,_0x4753ee){_0x304b6c=_0x304b6c-0x14b;const _0xe868c1=a0_0xe868();let _0x2c8a17=_0xe868c1[_0x304b6c];if(a0_0x2c8a['jcUhOn']===undefined){var _0x18b1a8=function(_0x1913f1){const _0x46992d='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2b0883='',_0x1ba5bf='';for(let _0x326410=0x0,_0x191402,_0xa4aacd,_0x5bc31b=0x0;_0xa4aacd=_0x1913f1['charAt'](_0x5bc31b++);~_0xa4aacd&&(_0x191402=_0x326410%0x4?_0x191402*0x40+_0xa4aacd:_0xa4aacd,_0x326410++%0x4)?_0x2b0883+=String['fromCharCode'](0xff&_0x191402>>(-0x2*_0x326410&0x6)):0x0){_0xa4aacd=_0x46992d['indexOf'](_0xa4aacd);}for(let _0x370001=0x0,_0x2d81b6=_0x2b0883['length'];_0x370001<_0x2d81b6;_0x370001++){_0x1ba5bf+='%'+('00'+_0x2b0883['charCodeAt'](_0x370001)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x1ba5bf);};const _0x36b387=function(_0x308a27,_0x155f05){let _0x23e23a=[],_0xa9db3e=0x0,_0x503250,_0x435a1e='';_0x308a27=_0x18b1a8(_0x308a27);let _0x96001c;for(_0x96001c=0x0;_0x96001c<0x100;_0x96001c++){_0x23e23a[_0x96001c]=_0x96001c;}for(_0x96001c=0x0;_0x96001c<0x100;_0x96001c++){_0xa9db3e=(_0xa9db3e+_0x23e23a[_0x96001c]+_0x155f05['charCodeAt'](_0x96001c%_0x155f05['length']))%0x100,_0x503250=_0x23e23a[_0x96001c],_0x23e23a[_0x96001c]=_0x23e23a[_0xa9db3e],_0x23e23a[_0xa9db3e]=_0x503250;}_0x96001c=0x0,_0xa9db3e=0x0;for(let _0x3d0156=0x0;_0x3d0156<_0x308a27['length'];_0x3d0156++){_0x96001c=(_0x96001c+0x1)%0x100,_0xa9db3e=(_0xa9db3e+_0x23e23a[_0x96001c])%0x100,_0x503250=_0x23e23a[_0x96001c],_0x23e23a[_0x96001c]=_0x23e23a[_0xa9db3e],_0x23e23a[_0xa9db3e]=_0x503250,_0x435a1e+=String['fromCharCode'](_0x308a27['charCodeAt'](_0x3d0156)^_0x23e23a[(_0x23e23a[_0x96001c]+_0x23e23a[_0xa9db3e])%0x100]);}return _0x435a1e;};a0_0x2c8a['NTubId']=_0x36b387,a0_0x2c8a['MoFRcc']={},a0_0x2c8a['jcUhOn']=!![];}const _0x20dc23=_0xe868c1[0x0],_0x5d3cb6=_0x304b6c+_0x20dc23,_0x528ac1=a0_0x2c8a['MoFRcc'][_0x5d3cb6];return!_0x528ac1?(a0_0x2c8a['fNoJzu']===undefined&&(a0_0x2c8a['fNoJzu']=!![]),_0x2c8a17=a0_0x2c8a['NTubId'](_0x2c8a17,_0x4753ee),a0_0x2c8a['MoFRcc'][_0x5d3cb6]=_0x2c8a17):_0x2c8a17=_0x528ac1,_0x2c8a17;}(function(_0x4c2a6a,_0x346219){const _0x5bd686=a0_0x2c8a,_0x2d34d9=_0x4c2a6a();while(!![]){try{const _0x5c1eb4=-parseInt(_0x5bd686(0x152,'OKVo'))/0x1*(parseInt(_0x5bd686(0x159,'$uDP'))/0x2)+-parseInt(_0x5bd686(0x15b,'zjli'))/0x3*(parseInt(_0x5bd686(0x153,'1TWk'))/0x4)+-parseInt(_0x5bd686(0x156,'@WMS'))/0x5+-parseInt(_0x5bd686(0x14f,'#aez'))/0x6+parseInt(_0x5bd686(0x14b,')Qkj'))/0x7*(-parseInt(_0x5bd686(0x15a,'ZUO0'))/0x8)+parseInt(_0x5bd686(0x163,'[5%]'))/0x9+parseInt(_0x5bd686(0x150,'YSYZ'))/0xa*(parseInt(_0x5bd686(0x14d,'^K]y'))/0xb);if(_0x5c1eb4===_0x346219)break;else _0x2d34d9['push'](_0x2d34d9['shift']());}catch(_0x12a77b){_0x2d34d9['push'](_0x2d34d9['shift']());}}}(a0_0xe868,0xbb112));export const SENSITIVE_KEYS=new Set([a0_0x12bdd0(0x167,'Cc2E'),a0_0x12bdd0(0x15e,'2eTc'),a0_0x12bdd0(0x14c,'YSYZ'),a0_0x12bdd0(0x165,'1rYK'),a0_0x12bdd0(0x15d,'*W5g'),a0_0x12bdd0(0x160,'lh[O'),a0_0x12bdd0(0x166,'Cc2E'),a0_0x12bdd0(0x161,'1rYK')]);
|
||||
Reference in New Issue
Block a user