(function () { 'use strict'; var HISTORY_KEY = 'soondesign_history'; var VERSION = typeof __APP_VERSION__ !== 'undefined' ? __APP_VERSION__ : '3.2.101'; function getAppBasePathname() { var p = (typeof window !== 'undefined' && window.location && window.location.pathname) ? window.location.pathname : '/'; while (p.length > 1 && p.endsWith('/')) { p = p.slice(0, -1); } if (/\.web\.html$/i.test(p) || /\.html$/i.test(p)) { p = p.replace(/[^/]+$/, ''); } if (!p.endsWith('/')) p += '/'; return p; } var SERVER_API_BASE = (function () { var cfg = (typeof window !== 'undefined' && window.SOON_DEPLOY_CONFIG && window.SOON_DEPLOY_CONFIG.api_v1_base); if (cfg) return String(cfg).replace(/\/+$/, '') + '/'; if (typeof window === 'undefined' || !window.location) return '/api/v1/'; return window.location.origin + getAppBasePathname() + 'api/v1/'; })(); function getAccessToken() { if (typeof window.soonGetAccessToken === 'function') return window.soonGetAccessToken(); try { return localStorage.getItem('soon_access') || ''; } catch (e) { return ''; } } function authedFetch(path, opts) { var url = SERVER_API_BASE + String(path).replace(/^\/+/, ''); if (typeof window.soonAuthedFetch === 'function') { return window.soonAuthedFetch(url, opts); } opts = opts || {}; opts.headers = Object.assign({}, opts.headers || {}); if (!opts.headers['Authorization'] && !opts.headers['authorization']) { var t = getAccessToken(); if (t) opts.headers['Authorization'] = 'Bearer ' + t; } return fetch(url, opts); } var JSON_HEADERS = { 'Content-Type': 'application/json; charset=utf-8', 'Accept': 'application/json' }; function parseCloudRef(p) { return typeof window.soonParseFileKey === 'function' ? window.soonParseFileKey(p) : null; } function normalizeSoonName(p) { return typeof window.soonNormalizeSoonName === 'function' ? window.soonNormalizeSoonName(p) : String(p || 'design.soon'); } function packCloudResult(j) { if (!j || !j.ok || !j.data) { return Promise.reject(new Error('cloud_empty_response')); } var fileKey = typeof window.soonApplyCloudMeta === 'function' ? window.soonApplyCloudMeta(j.data) : null; if (!fileKey) { var d = j.data; window._soonFileMeta = { id: d.id, version: d.version, name: d.name }; fileKey = 'soondesign_file:' + d.id + ':v' + d.version; } return { fileId: j.data.id, version: j.data.version, fileKey: fileKey, name: j.data.name }; } function handleCloudResponse(response, bodyText) { if (response.ok) { try { return Promise.resolve(JSON.parse(bodyText)); } catch (e) { return Promise.resolve(null); } } var info = typeof window.soonParseApiError === 'function' ? window.soonParseApiError(response, bodyText) : { status: response.status, message: '操作失败' }; if (typeof window.soonShowApiError === 'function') window.soonShowApiError(info); var err = new Error(info.message || 'cloud_error'); err.status = info.status; err.code = info.code; return Promise.reject(err); } function requireCloudAuth(actionLabel) { if (getAccessToken()) return true; if (typeof window.soonRequireLogin === 'function') return window.soonRequireLogin(actionLabel); return false; } function navigateToPage(pathWithQuery) { try { location.href = new URL(pathWithQuery, window.location.href).href; } catch (e) { location.href = pathWithQuery; } } function getLocale() { var lang = typeof navigator !== 'undefined' ? (navigator.language || navigator.browserLanguage || '') : ''; if (lang.indexOf('zh') === 0) return lang.indexOf('TW') >= 0 ? 'ozh' : 'zh'; return 'en'; } function getSystemFonts() { var list = [ 'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New', 'Georgia', 'Impact', 'Microsoft YaHei', 'SimHei', 'SimSun', 'KaiTi', 'FangSong', 'Times New Roman', 'Trebuchet MS', 'Verdana', 'PingFang SC', 'Hiragino Sans GB' ]; if (typeof document !== 'undefined' && document.fonts && document.fonts.forEach) { var set = {}; document.fonts.forEach(function (f) { var name = (f.family || '').replace(/^["']|["']$/g, ''); if (name) set[name] = 1; }); list = Object.keys(set).length ? Object.keys(set).sort() : list; } return Promise.resolve(list); } function listCloudFiles(pageOrLimit, sizeOrOffset) { if (!getAccessToken()) { var empty = { items: [], total: 0 }; if (typeof pageOrLimit === 'object' && pageOrLimit) { empty.page = pageOrLimit.page || 1; empty.size = pageOrLimit.size || 12; } return Promise.resolve(empty); } var url; var fallback = { items: [], total: 0 }; if (typeof pageOrLimit === 'object' && pageOrLimit) { var page = pageOrLimit.page || 1; var size = pageOrLimit.size || 12; url = 'files?page=' + page + '&size=' + size; fallback = { items: [], total: 0, page: page, size: size }; } else { var lim = pageOrLimit || 50; var off = sizeOrOffset || 0; url = 'files?limit=' + lim + '&offset=' + off; fallback = { items: [], limit: lim, offset: off, total: 0 }; } return authedFetch(url, { headers: { Accept: 'application/json' } }) .then(function (r) { return r.text().then(function (t) { return handleCloudResponse(r, t); }); }) .then(function (j) { return (j && j.ok && j.data) ? j.data : fallback; }); } function createCloudFile(name, jsonStr) { if (!requireCloudAuth('保存')) return Promise.reject(new Error('unauthorized')); return authedFetch('files', { method: 'POST', headers: JSON_HEADERS, body: JSON.stringify({ name: normalizeSoonName(name), json: jsonStr }) }) .then(function (r) { return r.text().then(function (t) { return handleCloudResponse(r, t); }); }) .then(packCloudResult); } function syncCloudFileAfterConflict(id) { var oldKey = (typeof window !== 'undefined' && window.openAs && window.openAs.name) ? window.openAs.name : ''; return authedFetch('files/' + id, { headers: { Accept: 'application/json' } }) .then(function (response) { if (!response.ok) return null; return response.json(); }) .then(function (payload) { if (!payload || !payload.ok || !payload.data) return null; var d = payload.data; var newKey = typeof window.soonApplyCloudMeta === 'function' ? window.soonApplyCloudMeta(d) : ('soondesign_file:' + d.id + ':v' + d.version); if (oldKey && oldKey !== newKey && typeof window.soonLocalRemove === 'function') { window.soonLocalRemove(oldKey); } if (typeof window.soonRecentOnCloudSave === 'function') { window.soonRecentOnCloudSave({ fileKey: newKey, fileId: d.id, name: d.name, version: d.version }, oldKey, null); } if (typeof window !== 'undefined' && window.openAs && newKey) { window.openAs.name = newKey; } if (typeof window.soonToast === 'function') { window.soonToast('文件已在其他端更新,已同步版本,请再次保存', 'warn'); } return newKey; }); } function updateCloudFile(id, name, jsonStr, version) { if (!requireCloudAuth('保存')) return Promise.reject(new Error('unauthorized')); var body = { name: normalizeSoonName(name), json: jsonStr }; if (version != null) body.version = version; return authedFetch('files/' + id, { method: 'PUT', headers: JSON_HEADERS, body: JSON.stringify(body) }) .then(function (r) { return r.text().then(function (t) { if (r.status === 409) { return syncCloudFileAfterConflict(id).then(function () { var err = new Error('version_conflict'); err.status = 409; err.conflictSynced = true; return Promise.reject(err); }); } return handleCloudResponse(r, t); }); }) .then(packCloudResult); } function deleteCloudFile(id) { if (!requireCloudAuth('删除')) return Promise.reject(new Error('unauthorized')); return authedFetch('files/' + id, { method: 'DELETE', headers: { Accept: 'application/json' } }) .then(function (r) { return r.text().then(function (t) { return handleCloudResponse(r, t); }); }); } function importSoonFile(name, jsonObj) { var jsonStr = typeof jsonObj === 'string' ? jsonObj : JSON.stringify(jsonObj); return createCloudFile(name, jsonStr); } function downloadCloudFile(id, fileName) { if (!getAccessToken()) { return Promise.reject(new Error('unauthorized')); } return authedFetch('files/' + id + '/download', { headers: { Accept: 'application/octet-stream' } }) .then(function (response) { if (!response.ok) { return response.text().then(function (t) { return handleCloudResponse(response, t); }); } return response.blob().then(function (blob) { var a = document.createElement('a'); a.download = normalizeSoonName(fileName || 'design.soon'); a.href = URL.createObjectURL(blob); a.click(); URL.revokeObjectURL(a.href); }); }); } function isSoonSaveDialog(options) { if (options && options.soonFile === true) return true; if (options && options.soonFile === false) return false; var raw = (options && options.defaultPath) ? String(options.defaultPath) : ''; if (!raw) return true; if (typeof window.soonIsTemplateKey === 'function' && window.soonIsTemplateKey(raw)) return true; if (raw.indexOf('soondesign_file:') === 0 || raw.indexOf('soondesign_session:') === 0) return true; var filters = options && options.filters; if (filters && Array.isArray(filters)) { for (var i = 0; i < filters.length; i++) { var exts = filters[i].extensions; if (exts && exts.indexOf('soon') >= 0) return true; } return false; } return /\.soon$/i.test(raw.split(/[/\\]/).pop() || ''); } function genericSaveDialogName(raw) { var n = String(raw || 'file').trim(); return n.split(/[/\\]/).pop() || n || 'file'; } function resolveSaveDialogName(name, options, isSoon) { var n = String(name || '').trim(); if (!n) n = isSoon ? 'design.soon' : 'file'; if (isSoon) { return typeof window.soonEnsureSoonExt === 'function' ? window.soonEnsureSoonExt(n) : normalizeSoonName(n); } return genericSaveDialogName(n); } function defaultSoonSaveDialogName(raw) { if (!raw || (typeof window.soonIsTemplateKey === 'function' && window.soonIsTemplateKey(raw))) { return typeof window.soonDefaultNewSoonName === 'function' ? window.soonDefaultNewSoonName() : normalizeSoonName('design.soon'); } if (raw.indexOf('soondesign_file:') === 0 && typeof window.soonDisplayFileName === 'function') { return window.soonDisplayFileName(raw); } return normalizeSoonName(raw); } var bridge = { readHistory: function () { try { var raw = localStorage.getItem(HISTORY_KEY); return Promise.resolve(raw ? JSON.parse(raw) : { history: [] }); } catch (e) { return Promise.resolve({ history: [] }); } }, writeHistory: function (data) { try { localStorage.setItem(HISTORY_KEY, JSON.stringify(data)); return Promise.resolve({ success: true }); } catch (e) { return Promise.resolve({ success: false, error: e.message }); } }, listCloudFiles: listCloudFiles, createCloudFile: createCloudFile, updateCloudFile: updateCloudFile, deleteCloudFile: deleteCloudFile, importSoonFile: importSoonFile, downloadCloudFile: downloadCloudFile, requireCloudAuth: requireCloudAuth, readJsonFile: function (pathOrHandle) { if (!pathOrHandle) return Promise.resolve(null); if (typeof pathOrHandle === 'object' && pathOrHandle.text) { return pathOrHandle.text().then(function (t) { try { return JSON.parse(t); } catch (e) { return null; } }); } var key = typeof pathOrHandle === 'string' ? pathOrHandle : ''; var cacheKey = key; function cacheHitThen(hit) { if (!hit || !hit.json) return null; if (typeof window.soonLocalIsTemplateStale === 'function' && window.soonLocalIsTemplateStale(cacheKey, hit.meta)) { if (typeof window.soonLocalRemove === 'function') { return window.soonLocalRemove(cacheKey).then(function () { return null; }); } return Promise.resolve(null); } if (cacheKey.indexOf('soondesign_file:') === 0 && hit.meta && hit.meta.name && typeof window.soonBindFileMeta === 'function') { window.soonBindFileMeta(cacheKey, { name: hit.meta.name }); } return Promise.resolve(hit.json); } function afterNetworkJson(json, meta) { if (!json) return null; if (typeof window.soonLocalCacheAndThumb === 'function') { return window.soonLocalCacheAndThumb(cacheKey, json, meta || {}).then(function () { return json; }); } return json; } if (key && typeof window.soonLocalGet === 'function') { return window.soonLocalGet(cacheKey).then(function (hit) { return cacheHitThen(hit).then(function (cached) { if (cached) return cached; return fetchFromNetwork(key, cacheKey); }); }).catch(function () { return fetchFromNetwork(key, cacheKey); }); } return fetchFromNetwork(key, cacheKey); function fetchFromNetwork(key, cacheKey) { if (key.indexOf('soondesign_session:') === 0) { if (typeof window.soonLocalGet === 'function') { return window.soonLocalGet(cacheKey).then(function (hit) { if (hit && hit.json) return hit.json; try { var j = sessionStorage.getItem(key); if (!j && typeof localStorage !== 'undefined') j = localStorage.getItem(key); if (!j || j === 'idb') return null; var parsed = JSON.parse(j); return afterNetworkJson(parsed, { source: 'session', name: key }); } catch (e) { return null; } }); } try { var j = sessionStorage.getItem(key); if (!j && typeof localStorage !== 'undefined') j = localStorage.getItem(key); if (!j || j === 'idb') return Promise.resolve(null); return Promise.resolve(JSON.parse(j)); } catch (e) { return Promise.resolve(null); } } if (key && key.indexOf('soondesign_file:') === 0 && typeof fetch !== 'undefined') { var fileMatch = key.match(/^soondesign_file:(\d+)/); if (fileMatch && getAccessToken()) { return authedFetch('files/' + fileMatch[1], { headers: { Accept: 'application/json' } }) .then(function (response) { if (!response.ok) return null; return response.json(); }) .then(function (payload) { if (!payload || !payload.ok || !payload.data) return null; var raw = payload.data.json; var parsed; if (typeof raw === 'string') { try { parsed = JSON.parse(raw); } catch (e) { return null; } } else { parsed = raw && typeof raw === 'object' ? raw : null; } if (!parsed) return null; if (typeof window.soonApplyCloudMeta === 'function') { window.soonApplyCloudMeta(payload.data); } return afterNetworkJson(parsed, { source: 'cloud', name: payload.data.name || '', type: parsed.soonType || 1, updatedAt: payload.data.updated_at || '' }); }) .catch(function () { return null; }); } } if (key && key.indexOf('soondesign_template:') === 0 && typeof fetch !== 'undefined') { var tplMatch = key.match(/^soondesign_template:(\d+)/); if (tplMatch) { var apiBase = (window.SOON_DEPLOY_CONFIG && window.SOON_DEPLOY_CONFIG.api_v1_base) || ''; if (!apiBase) return Promise.resolve(null); return fetch(apiBase + '/templates/' + tplMatch[1] + '/file', { headers: { Accept: 'application/json' } }) .then(function (response) { if (!response.ok) return null; return response.text(); }) .then(function (text) { if (!text) return null; var parsed; try { parsed = JSON.parse(text); } catch (e) { return null; } var tplMeta = window._soonTemplateMeta || {}; return afterNetworkJson(parsed, { source: 'template', name: tplMeta.name || '', type: tplMeta.type || (parsed.soonType || 1), updatedAt: tplMeta.updated_at || '' }); }) .catch(function () { return null; }); } } return Promise.resolve(null); } }, showOpenDialog: function (options) { return new Promise(function (resolve) { var input = document.createElement('input'); input.type = 'file'; if (options && options.filters && Array.isArray(options.filters) && options.filters.length > 0) { var acceptList = []; options.filters.forEach(function (filter) { if (filter.extensions && Array.isArray(filter.extensions)) { filter.extensions.forEach(function (ext) { var cleanExt = ext.replace(/^\./, ''); if (['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'svg'].indexOf(cleanExt.toLowerCase()) >= 0) { var mimeType = 'image/' + (cleanExt.toLowerCase() === 'jpg' ? 'jpeg' : cleanExt.toLowerCase()); if (acceptList.indexOf(mimeType) < 0) acceptList.push(mimeType); } else { var extWithDot = '.' + cleanExt; if (acceptList.indexOf(extWithDot) < 0) acceptList.push(extWithDot); } }); } }); input.accept = acceptList.length > 0 ? acceptList.join(',') : ''; } else { input.accept = '.soon,application/json'; } input.style.display = 'none'; input.onchange = function () { var f = input.files && input.files[0]; document.body.removeChild(input); if (!f) resolve({ canceled: true }); else resolve({ canceled: false, filePaths: [], files: [f], file: f }); }; document.body.appendChild(input); input.click(); }); }, showSaveDialog: function (options) { var raw = (options && options.defaultPath) ? options.defaultPath : ''; var isSoon = isSoonSaveDialog(options); var defaultName = isSoon ? defaultSoonSaveDialogName(raw) : genericSaveDialogName(raw); var title = (options && options.title) ? options.title : (isSoon ? '保存到云端' : '保存文件'); return new Promise(function (resolve) { if (typeof layer === 'undefined' || !layer.open) { resolve({ canceled: false, filePath: defaultName, useCloud: !!isSoon }); return; } var esc = function (s) { return String(s || '').replace(/&/g, '&').replace(/文件名' + '' + ''; layer.open({ type: 1, skin: 'soon-layer', title: title, area: ['360px', 'auto'], shadeClose: false, content: html, btn: ['确定', '取消'], btnAlign: 'r', yes: function (index) { var input = document.getElementById('soonSaveDialogInput'); var name = input && input.value ? String(input.value).trim() : defaultName; name = resolveSaveDialogName(name, options, isSoon); layer.close(index); resolve({ canceled: false, filePath: name, useCloud: !!isSoon }); }, btn2: function (index) { layer.close(index); resolve({ canceled: true }); }, cancel: function (index) { layer.close(index); resolve({ canceled: true }); } }); }); }, writeFile: function (pathOrHandle, content) { var isBlob = content instanceof Blob; var str = typeof content === 'string' ? content : (isBlob ? null : (content && content.toString ? content.toString() : '')); if (isBlob) { var blobName = typeof pathOrHandle === 'string' ? pathOrHandle : 'output.bin'; var a = document.createElement('a'); a.download = blobName; a.href = URL.createObjectURL(content); a.click(); URL.revokeObjectURL(a.href); return Promise.resolve(); } if (pathOrHandle && pathOrHandle.createWritable) { pathOrHandle = typeof pathOrHandle.name === 'string' ? pathOrHandle.name : 'design.soon'; } var name = typeof pathOrHandle === 'string' ? pathOrHandle : 'design.soon'; var cloudRef = parseCloudRef(name); var fileName = normalizeSoonName(name); var parsedJson; try { parsedJson = JSON.parse(str); } catch (e) { parsedJson = null; } function cacheWriteForKey(targetKey, meta) { if (!parsedJson || typeof window.soonLocalCacheAndThumb !== 'function') return Promise.resolve(); return window.soonLocalCacheAndThumb(targetKey, parsedJson, meta || {}); } function afterCloudSave(res, prevKey) { if (!res || !res.fileKey || !parsedJson) return res; var meta = { source: 'cloud', name: res.name || fileName, type: parsedJson.soonType || 1 }; if (prevKey && prevKey !== res.fileKey && typeof window.soonLocalRenameKey === 'function') { return window.soonLocalRenameKey(prevKey, res.fileKey, meta).then(function () { return res; }); } return cacheWriteForKey(res.fileKey, meta).then(function () { return res; }); } if (!getAccessToken()) { if (cloudRef && cloudRef.id) { requireCloudAuth('保存'); return Promise.reject(new Error('unauthorized')); } var sessionKey = typeof window.soonMakeSessionKey === 'function' ? window.soonMakeSessionKey(name) : (name.indexOf('soondesign_session:') === 0 ? name : 'soondesign_session:' + fileName.replace(/\.soon$/i, '')); var prevSessionKey = name.indexOf('soondesign_session:') === 0 ? name : ''; function finishSessionSave() { try { sessionStorage.setItem(sessionKey, 'idb'); } catch (e) { /* ignore */ } return { fileKey: sessionKey, name: fileName, version: 0 }; } if (prevSessionKey && prevSessionKey !== sessionKey && typeof window.soonLocalRenameKey === 'function') { return cacheWriteForKey(sessionKey, { source: 'session', name: fileName }).then(function () { return window.soonLocalRenameKey(prevSessionKey, sessionKey, { source: 'session', name: fileName }) .then(finishSessionSave); }).catch(function () { return Promise.reject(new Error('save_failed')); }); } return cacheWriteForKey(sessionKey, { source: 'session', name: fileName }).then(function () { return finishSessionSave(); }).catch(function () { return Promise.reject(new Error('save_failed')); }); } if (!requireCloudAuth('保存')) { return Promise.reject(new Error('unauthorized')); } if (cloudRef && cloudRef.id) { var ver = cloudRef.version; if (ver == null && window._soonFileMeta && window._soonFileMeta.id === cloudRef.id) { ver = window._soonFileMeta.version; } if (typeof window.soonResolveCloudFileName === 'function') { var cloudSaveName = window.soonResolveCloudFileName(name); if (cloudSaveName) fileName = cloudSaveName; } var prevCloudKey = name; return updateCloudFile(cloudRef.id, fileName, str, ver).then(function (res) { return afterCloudSave(res, prevCloudKey); }); } var prevKey = name.indexOf('soondesign_session:') === 0 ? name : ''; return createCloudFile(fileName, str).then(function (res) { return afterCloudSave(res, prevKey); }); }, readFile: function (pathOrHandle) { if (pathOrHandle && pathOrHandle.getFile) { return pathOrHandle.getFile().then(function (f) { return new Promise(function (res, rej) { var r = new FileReader(); r.onload = function () { res(r.result); }; r.onerror = rej; r.readAsArrayBuffer(f); }); }); } if (pathOrHandle && pathOrHandle.arrayBuffer) { return pathOrHandle.arrayBuffer(); } return Promise.reject(new Error('No file')); }, getAppVersion: function () { return Promise.resolve(VERSION); }, getLocale: getLocale, getUserDataPath: function () { return ''; }, getSystemFonts: getSystemFonts, openDesignPage: function (file, type) { var t = type || 1; var key = file || ''; if (typeof window.soonSyncOpenNavigation === 'function') { window.soonSyncOpenNavigation(key, t); } var fileParam = key ? encodeURIComponent(key) : ''; navigateToPage('design' + t + '.web.html?file=' + fileParam + '&type=' + t); }, openFirstPage: function () { navigateToPage('index.web.html'); }, onClose: function (callback) { if (typeof window !== 'undefined') { window.addEventListener('beforeunload', callback); } }, runClose: function () { if (typeof window !== 'undefined' && window.close) window.close(); }, openHelp: function () { try { window.open(new URL('../assets/help/User Manual.pdf', window.location.href).href, '_blank'); } catch (e) { window.open('../assets/help/User Manual.pdf', '_blank'); } }, printPdf: function (urlOrBlob) { var url = urlOrBlob; if (urlOrBlob && typeof urlOrBlob === 'object' && !(urlOrBlob instanceof String)) { url = URL.createObjectURL(urlOrBlob); } var w = window.open(url, '_blank'); if (w) w.onload = function () { w.print(); }; }, getScaleRate: function () { return typeof window !== 'undefined' && window.devicePixelRatio ? window.devicePixelRatio : 1; }, clipboard: { readText: function () { return navigator.clipboard && navigator.clipboard.readText ? navigator.clipboard.readText() : Promise.resolve(''); }, writeText: function (text) { if (navigator.clipboard && navigator.clipboard.writeText) { return navigator.clipboard.writeText(text); } return Promise.resolve(); } } }; window.platformBridge = bridge; var pathStub = { join: function () { return [].slice.call(arguments).join('/').replace(/\/+/g, '/'); } }; window.sysAPI = { readHistory: bridge.readHistory, writeHistory: bridge.writeHistory, readJsonFile: bridge.readJsonFile, getAppVersion: bridge.getAppVersion }; window.dialog = { showOpenDialog: bridge.showOpenDialog, showSaveDialog: bridge.showSaveDialog }; window.soonShowSaveDialog = bridge.showSaveDialog; window.path = pathStub; window.fs = null; window.remote = null; var loc = getLocale(); window.ipcRenderer = { send: function (ch, a1, a2) { if (ch === 'get-sys-language') { window._sysLanPending = true; setTimeout(function () { if (window._sysLanCb && window._sysLanPending) { window._sysLanCb(null, loc); window._sysLanPending = false; } }, 0); } if (ch === 'open-first-page' && bridge.openFirstPage) { bridge.openFirstPage(); } if (ch === 'open-design-page' && bridge.openDesignPage && (a1 !== undefined || a2 !== undefined)) { bridge.openDesignPage(a1 || '', a2 || 1); } if (ch === 'open-help-file' && bridge.openHelp) { bridge.openHelp(); } if (ch === 'run-close' && bridge.runClose) { bridge.runClose(); } }, on: function (ch, cb) { if (ch === 'sys-lan') { window._sysLanCb = cb; if (window._sysLanPending) setTimeout(function () { if (window._sysLanCb) { window._sysLanCb(null, loc); window._sysLanPending = false; } }, 0); } if (ch === 'close') window._closeCb = cb; } }; window.clipboard = bridge.clipboard; window.exePath = ''; window.fullPath = ''; })();