slimsdk 0.2.0 → 0.2.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/config/global.ts","../../src/config/index.ts","../../src/svchub/oauth/index.ts","../../src/lib/cookie.ts","../../src/svchub/oauth/template.ts","../../src/lib/utility.ts","../../src/svchub/api/auth/index.ts","../../src/svchub/oauth/midware.ts","../../src/svchub/api/index.ts","../../src/svchub/wss/index.ts","../../src/mod/dialog/index.ts","../../src/lib/dateTime.ts","../../src/page/index.ts","../../src/svchub/hwlink/template.ts","../../src/svchub/hwlink/index.ts"],"sourcesContent":["/* global */\n/*------------------------------------------------------------*/\nimport { version } from '../../package.json';\nexport const info = () => `sdk ${version}`;\n/*------------------------------------------------------------*/\ntype InitParams = {\n svcWorker?: string,\n webNotify?: boolean,\n wakeLock?: boolean,\n btnToTop?: boolean,\n hideTabbar?: boolean,\n};\nexport const init = (params?: InitParams) => {\n if (params?.svcWorker) svcWorker(params.svcWorker);\n if (params?.webNotify) webNotify();\n if (params?.wakeLock) wakeLock();\n if (params?.btnToTop) btnToTop();\n if (params?.hideTabbar) hideTabbar();\n};\n/*------------------------------------------------------------*/\nconst svcWorker = (worker: string) => {\n if (!('serviceWorker' in navigator)) return;\n navigator.serviceWorker.register(worker, {\n type: 'module'\n }).catch(err => console.warn(err));\n};\n/*------------------------------------------------------------*/\nconst webNotify = () => {\n if (!('Notification' in window)) return;\n Notification.requestPermission()\n .catch(err => console.warn(err));\n};\n/*------------------------------------------------------------*/\nconst wakeLock = () => {\n if (document.hidden) return;\n navigator.wakeLock.request('screen')\n .catch(err => console.warn(err));\n};\n/*------------------------------------------------------------*/\nconst hideTabbar = () => {\n const winHeight = window.innerHeight;\n window.visualViewport?.addEventListener('resize', () => {\n const tabbar = document.querySelector<HTMLElement>('#tabbar');\n if (!tabbar) return;\n if (winHeight != window.innerHeight) {\n tabbar.classList.add('hide');\n } else {\n tabbar.classList.remove('hide');\n }\n });\n};\n/*------------------------------------------------------------*/\nconst app = document.querySelector<HTMLElement>('#app');\nconst btnToTop = () => {\n if (!app) return;\n // create item\n const totop = document.createElement('div');\n totop.id = 'totop';\n totop.innerHTML = /* html */ `\n <button id=\"btn-totop\" class=\"circle purple\" shadow=\"true\"\n title=\"กลับด้านบน\">&#xf341;</button>\n `;\n document.body.appendChild(totop);\n // add event\n totop.querySelector<HTMLButtonElement>('#btn-totop')!.onclick = () => {\n app.scrollTo({ top: 0, behavior: 'smooth' });\n };\n app.addEventListener('scroll', () => {\n if (app.scrollTop > 1000) {\n totop.style.display = 'block';\n if (app.classList.contains('tabbar')) {\n app.style.paddingBottom = '116px';\n } else {\n app.style.paddingBottom = '60px';\n }\n } else {\n totop.style.display = '';\n app.style.paddingBottom = '';\n }\n // tabs mobile shadow\n const tabsMobile = app.querySelector<HTMLElement>('.slim-tabs.mobile .tabs-header');\n if (!tabsMobile) return;\n if (app.scrollTop > 10) {\n tabsMobile.style.boxShadow = `rgba(0, 0, 0, 0.16) 0px 1px 4px`;\n } else {\n tabsMobile.style.boxShadow = '';\n }\n });\n};\n/*------------------------------------------------------------*/","/* config */\nexport { init, info } from './global';\n/*------------------------------------------------------------*/\nexport const cfg: Config = {\n UNIX_TIME: 0,\n app: {\n UUID: '',\n NAME: '',\n SECRET: '',\n VERSION: '',\n RELEASE: '',\n CALLBACK: '',\n },\n api: {\n URL: '',\n TOKEN: '',\n },\n hub: {\n LOGIN: 'https://wkrh.info/oauth/v1/authorize',\n OAUTH: 'https://wkrh.info:8850/oauth/v1',\n API: 'https://wkrh.info:8850/api/v1',\n WSS: 'wss://wkrh.info:8855/ws',\n UUID: '',\n },\n hwl: {\n HOST: 'ws://localhost:8844/ws',\n FILE: 'https://wkrh.info/app/hwlink/hwlink_setup.exe',\n },\n user: {\n sub: 0,\n name: '',\n utyp: '',\n unit: '',\n unit_id: 0,\n role_id: 0,\n metadata: {\n emp_type: '',\n emp_level: '',\n position: '',\n },\n picture: '',\n }\n};\n/*------------------------------------------------------------*/\ntype Config = {\n UNIX_TIME: number;\n app: AppCfg;\n api: ApiCfg;\n hub: HubCfg;\n hwl: HwlCfg;\n user: UserCfg;\n};\ntype AppCfg = {\n UUID: string;\n NAME: string;\n SECRET: string;\n VERSION: string;\n RELEASE: string;\n CALLBACK: string;\n};\ntype ApiCfg = {\n URL: string;\n TOKEN: string;\n HEADERS?: Headers;\n};\ntype HubCfg = {\n LOGIN: string;\n OAUTH: string;\n API: string;\n WSS: string;\n UUID: string;\n TASK?: Worker;\n};\ntype HwlCfg = {\n HOST: string;\n FILE: string;\n};\ntype UserCfg = {\n sub: number;\n name: string;\n utyp: string;\n unit: string;\n unit_id: number;\n role_id: number;\n metadata: {\n emp_type: string;\n emp_level: string;\n position: string;\n };\n picture: string;\n};","/* oauth */\n/*--------------------------------------------------------------------------------*/\nimport { cfg } from '../../config';\nimport * as cookie from '../../lib/cookie';\nimport { tempLogout } from './template';\nconst app = document.querySelector<HTMLElement>('#app');\nexport { authMW } from './midware';\n/*--------------------------------------------------------------------------------*/\nexport const login = () => {\n clearCache();\n // set params\n const state = Math.random().toString(36).slice(-8);\n sessionStorage.setItem('OAUTH_STATE', state);\n const query = new URLSearchParams({\n response_type: 'token',\n client_id: cfg.app.UUID,\n redirect_uri: cfg.app.CALLBACK,\n state: state,\n }).toString();\n const url = `${cfg.hub.LOGIN}?${query}`;\n window.location.replace(url);\n};\n/*--------------------------------------------------------------------------------*/\nexport const logout = () => {\n clearCache();\n // template\n if (!app) return;\n app.innerHTML = tempLogout;\n app.classList.add('full-page');\n const content = app.querySelector<HTMLElement>('#content')!;\n const loader = app.querySelector<HTMLElement>('#loader')!;\n new Promise(r => setTimeout(r, 400)).then(() => {\n content.style.display = 'block';\n loader.style.display = 'none';\n });\n app.querySelector<HTMLButtonElement>('#btn-login')!.onclick = () => {\n window.location.replace('/login');\n };\n};\n/*--------------------------------------------------------------------------------*/\nexport const callback = () => {\n const search = window.location.search;\n const query = new URLSearchParams(search);\n const state = query.get('state');\n const session = sessionStorage.getItem('OAUTH_STATE');\n if (state !== session) {\n window.location.replace('/login');\n }\n clearCache();\n // response_type\n const code = query.get('code');\n const token = query.get('token');\n if (code) { /*code*/ }\n if (token) {\n localStorage.setItem('ACCESS_TOKEN', token);\n }\n window.location.replace('/');\n};\n/*--------------------------------------------------------------------------------*/\nconst clearCache = () => {\n cookie.clear();\n localStorage.clear();\n sessionStorage.clear();\n};\n/*--------------------------------------------------------------------------------*/\n","/* cookie */\n/*--------------------------------------------------------------------------------*/\nexport const setItem = (key: string, val: string, exp: number) => {\n const d = new Date();\n d.setTime(d.getTime() + (1000 * exp)); // seconds\n const expires = \"expires=\" + d.toUTCString();\n document.cookie = `${key}=${val};${expires};path=/`;\n};\n/*--------------------------------------------------------------------------------*/\nexport const getItem = (key: string): string => {\n const pair = document.cookie.split('; ').find(x => x.startsWith(key + '='));\n if (pair) return pair.split('=')[1];\n else return '';\n};\n/*--------------------------------------------------------------------------------*/\nexport const removeItem = (key: string) => {\n document.cookie = `${key}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/;`;\n};\n/*--------------------------------------------------------------------------------*/\nexport const clear = () => {\n document.cookie.split(';').forEach(cookie => {\n const eqPos = cookie.indexOf('=');\n const name = eqPos > -1 ? cookie.substring(0, eqPos) : cookie;\n removeItem(name);\n });\n};\n/*--------------------------------------------------------------------------------*/\n","/* template */\nexport const tempLogout = /*html*/ `\n<div id=\"page-logout\">\n <div id=\"content\">\n <div class=\"logo\">\n <img src=\"https://cdn.jsdelivr.net/npm/slimsdk/dist/assets/icon/icon-02.png\">\n </div>\n <button id=\"btn-login\" class=\"lg\">เข้าระบบอีกครั้ง</button>\n </div>\n <!-- loader -->\n <div id=\"loader\"></div>\n</div>\n<style>\n#app:has(#page-logout) {\n padding: 0;\n}\n#page-logout {\n width: 100%;\n height: 100%;\n position: fixed;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n background-position: center;\n background-repeat: no-repeat;\n background-size: cover;\n background-image: url('https://cdn.jsdelivr.net/npm/slimsdk/dist/assets/bg/bg-01.jpg');\n}\n#page-logout #content {\n display: none;\n text-align: center;\n animation: fadeIn 0.4s;\n}\n#page-logout #content .logo {\n margin: auto;\n width: 150px;\n height: 150px;\n margin-bottom: 20px;\n border-radius: 50%;\n background-color: rgba(255, 255, 255, 0.2);\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2),\n 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n}\n#page-logout #content .logo img {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n}\n#page-logout #content #btn-login {\n box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px,\n rgba(0, 0, 0, 0.23) 0px 3px 6px;\n}\n#page-logout #loader {\n width: 110px;\n height: 110px;\n border-radius: 50%;\n border: 11px solid #E5E7EB;\n border-color: #E5E7EB #06B6D4 #E5E7EB #06B6D4;\n animation: spin 2s linear infinite;\n}\n</style>\n`;","/* utility */\nexport const THAI_DIGIT = ['๐', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙'];\n/*--------------------------------------------------------------------------------*/\nexport const thaiDigit = (input: number | string): string => {\n return input.toString()\n .replace(/\\d/g, (digit: string) => THAI_DIGIT[parseInt(digit)]);\n};\n/*--------------------------------------------------------------------------------*/\nexport const cidCheck = (cid: string): boolean => {\n if (!Number(cid)) return false;\n if (cid.substring(0, 1) == '0') return false;\n if (cid.length !== 13) return false;\n let sum = 0;\n for (let i = 0; i < 12; i++) {\n sum += parseFloat(cid.charAt(i)) * (13 - i);\n }\n return (11 - sum % 11) % 10 === parseFloat(cid.charAt(12));\n};\n/*--------------------------------------------------------------------------------*/\nexport const winPopup = (\n width: number,\n height: number,\n name: string,\n url: string,\n) => {\n const left = (screen.width - width) / 2;\n const top = (screen.height - height) / 2;\n let opt = `width=${width}, height=${height},`;\n opt += `left=${left}, top=${top}`;\n return window.open(url, name, opt);\n};\n/*--------------------------------------------------------------------------------*/\nexport const strCheck = (str: string): string => {\n let out = String(str);\n out = out.replaceAll(\"'\", \"\\\\'\");\n out = out.replaceAll('\"', '\\\\\"');\n out = out.trim();\n return out;\n};\n/*--------------------------------------------------------------------------------*/\nexport const zeroFill = (\n num: number,\n opts?: {\n min?: number;\n max?: number;\n char?: string;\n }\n): string => {\n const n = Number(num);\n const min = opts?.min ? Number(opts.min) : 0;\n const max = opts?.max ? Number(opts.max) : 0;\n const char = opts?.char || opts?.char == '' ? opts.char : '-';\n if (n > 0) {\n return n.toLocaleString(undefined, {\n minimumFractionDigits: min,\n maximumFractionDigits: max,\n });\n } else return char;\n};\n/*--------------------------------------------------------------------------------*/\nexport const numFormat = (num: number, fixed = 0): string => {\n const n = Number(num);\n const f = Number(fixed);\n let out: string = '';\n if (n >= 10 ** 3 && n < 10 ** 6) {\n out = (n / 1000).toFixed(f) + ' K';\n } else if (n >= 10 ** 6) {\n out = (n / 1000000).toFixed(f) + ' M';\n }\n return out;\n};\n/*--------------------------------------------------------------------------------*/\nexport const strFormat = (value: string, pattern: string): string => {\n let i = 0;\n const v = value.toString();\n return pattern.replace(/#/g, () => {\n const out = v[i] ? v[i] : '#';\n i++;\n return out;\n });\n};\n/*--------------------------------------------------------------------------------*/\nexport const toBase64 = (file: File) => new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = err => reject(err);\n});\n/*--------------------------------------------------------------------------------*/\nexport type JwtClaims = {\n iss: string;\n aud: string;\n iat: number;\n exp: number;\n sub: number;\n};\nexport const jwtParse = (token: string): JwtClaims | null => {\n try { return JSON.parse(atob(token.split('.')[1])); }\n catch { return null; }\n};\n/*--------------------------------------------------------------------------------*/\n","/* auth */\nimport type { ApiRsp } from '..';\nimport { cfg } from '../../../config';\n/*--------------------------------------------------------------------------------*/\nexport const getToken = (params: ReqToken) => new Promise<ApiRsp>((resolve, reject) => {\n fetch(cfg.hub.OAUTH + '/token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json; charset=utf-8' },\n body: JSON.stringify(params),\n }).then(resp => {\n if (!resp.ok) throw resp;\n return resp.json();\n }).then(json => {\n resolve(json);\n }).catch(err => reject(err));\n});\n/*--------------------------------------------------------------------------------*/\nexport const getUserInfo = (token?: string) => new Promise<ApiRsp>((resolve, reject) => {\n let headers = cfg.api.HEADERS;\n if (token) headers = new Headers({\n 'Content-Type': 'application/json; charset=utf-8',\n 'Authorization': `Bearer ${token}`,\n });\n fetch(cfg.hub.OAUTH + '/userinfo', {\n method: 'GET',\n headers: headers,\n }).then(resp => {\n if (!resp.ok) throw resp;\n return resp.json();\n }).then(json => {\n resolve(json);\n }).catch(err => reject(err));\n});\n/*--------------------------------------------------------------------------------*/\nexport type ReqToken = {\n grant_type: string;\n client_id: string;\n client_secret?: string;\n username?: string;\n password?: string;\n refresh_token?: string;\n uuid?: string;\n};\nexport type RspToken = {\n access_token: string;\n token_type: string;\n expires_in: number;\n refresh_token?: string;\n redirect_uri?: string;\n};\nexport type UserInfo = {\n sub: number;\n name: string;\n utyp: string;\n unit: string;\n unit_id: number;\n role_id: number;\n metadata?: {\n emp_type: string;\n emp_level: string;\n position: string;\n },\n picture?: string;\n updated_at: number;\n};","/* middleware */\n/*--------------------------------------------------------------------------------*/\nimport { cfg } from '../../config';\nimport { jwtParse } from '../../lib/utility';\nimport * as cookie from '../../lib/cookie';\nimport { getUserInfo, type UserInfo } from '../api/auth';\nconst IGNORE: string[] = ['__NOT_FOUND__', 'login', 'logout', 'callback'];\n/*--------------------------------------------------------------------------------*/\nexport const authMW = async (route: string, ignore?: string[]) => {\n // ignore\n ignore?.forEach(val => IGNORE.push(val));\n if (IGNORE.includes(route)) {\n console.log('ignore :', route);\n return;\n }\n // token exist\n const token = localStorage.getItem('ACCESS_TOKEN');\n if (!token) {\n gotoLogin();\n throw 'token not exist';\n }\n // token expire\n try {\n const jwt = jwtParse(token);\n const exp = Number(jwt?.exp) * 1000;\n if (isNaN(exp)) throw 'err';\n const now = Date.now();\n if (now >= exp) throw 'err';\n } catch { gotoLogin(); }\n // set api header\n cfg.api.TOKEN = token;\n cfg.api.HEADERS = new Headers({\n 'Content-Type': 'application/json; charset=utf-8',\n 'Authorization': `Bearer ${cfg.api.TOKEN}`,\n });\n // session exist\n const session = sessionStorage.getItem('ACCESS_SESSION');\n if (!session) {\n await getUserInfo().then(resp => {\n const data = resp.data as UserInfo;\n setProfile(data);\n sessionStorage.setItem('ACCESS_SESSION', JSON.stringify(data));\n }).catch(() => gotoLogin());\n } else {\n const data = JSON.parse(session) as UserInfo;\n setProfile(data);\n }\n};\n/*--------------------------------------------------------------------------------*/\nconst setProfile = (user: UserInfo) => {\n cfg.user.sub = user.sub;\n cfg.user.name = user.name;\n cfg.user.utyp = user.utyp;\n cfg.user.unit = user.unit;\n cfg.user.unit_id = user.unit_id;\n cfg.user.role_id = user.role_id;\n cfg.user.picture = user.picture ? user.picture : '';\n if (user.metadata) cfg.user.metadata = user.metadata;\n};\n/*--------------------------------------------------------------------------------*/\nconst gotoLogin = () => {\n cookie.clear();\n localStorage.clear();\n sessionStorage.clear();\n window.location.replace('/login');\n throw 'not logged in';\n};\n/*--------------------------------------------------------------------------------*/\n","/* api */\nexport * as auth from './auth';\n// api response\nexport interface ApiRsp {\n status: {\n code: number;\n message: string;\n };\n rows: {\n total: number;\n limit: number;\n offset: number;\n };\n data: unknown;\n}","/* wsshub */\n/*--------------------------------------------------------------------------------*/\nimport { cfg } from '../../config';\nimport { toast } from '../../mod/dialog';\nimport { timeToStr, thaiDate } from '../../lib/dateTime';\n/*--------------------------------------------------------------------------------*/\nexport const newTask = (worker: new () => Worker) => {\n if (!window.Worker) return;\n cfg.hub.TASK = new worker();\n cfg.hub.TASK.postMessage({\n head: 'INIT',\n data: {\n url: cfg.hub.WSS,\n app: cfg.app.NAME,\n uid: cfg.app.UUID,\n ver: cfg.app.VERSION,\n }\n });\n cfg.hub.TASK.addEventListener('message', (e) => {\n const json = e.data;\n const head = json.head ? json.head : '';\n const data = json.data ? json.data : '';\n if (head == 'ACCEPT') {\n rspAccept(data);\n cfg.hub.TASK?.postMessage({\n head: 'VERIFY',\n data: cfg.api.TOKEN,\n });\n }\n if (head == 'DISCON') rspDiscon();\n if (head == 'LATEST') rspLatest(data);\n if (head == 'BRDMSG') rspBrdMsg(data);\n if (head == 'VERIFY' && data != '200 OK') {\n console.log(head, data);\n }\n });\n};\n/*--------------------------------------------------------------------------------*/\nexport const checkUpdate = (min = 10) => {\n return setInterval(() => {\n cfg.hub.TASK?.postMessage({\n head: 'LATEST',\n data: {\n app: cfg.app.NAME,\n uid: cfg.app.UUID,\n }\n });\n }, 1000 * 60 * min); // defult 10 min\n};\n/*--------------------------------------------------------------------------------*/\ntype BrdPack = {\n from: string;\n to: string;\n cmd: string;\n msg: unknown;\n};\nconst rspBrdMsg = (brd: BrdPack) => {\n if (brd.cmd == \"LOGS\") console.log(brd.msg);\n if (brd.cmd == \"TIME\") setTime(brd.msg as { unix: number; });\n if (brd.cmd == 'RESULT' && brd.to == cfg.hub.UUID) {\n console.log(brd.cmd, 'From:', brd.from);\n console.log(brd.msg);\n }\n if (brd.cmd == 'CONRST' && (brd.to == cfg.hub.UUID || brd.to == '@all')) {\n sessionStorage.clear();\n window.location.reload();\n }\n if (brd.cmd == 'LOGOUT' && (brd.to == cfg.hub.UUID || brd.to == '@all')) {\n localStorage.clear();\n sessionStorage.clear();\n window.location.reload();\n }\n if (brd.cmd == 'NOTIFY' && (brd.to == cfg.hub.UUID || brd.to == '@all')) {\n brdNotify(brd.msg as NotifyPack);\n }\n if (brd.cmd == '') console.log(brd.msg);\n};\n/*--------------------------------------------------------------------------------*/\nconst rspAccept = (data: { uuid: string; }) => {\n cfg.hub.UUID = data.uuid ? data.uuid : '';\n console.log('hub-uuid:', cfg.hub.UUID);\n const boxTime = document.querySelector<HTMLElement>('#topbar #box-time');\n if (boxTime) boxTime.classList.remove('offline');\n toast('เชื่อมต่อ Server สำเร็จ.!', { type: 'success' });\n};\n/*--------------------------------------------------------------------------------*/\nconst rspDiscon = () => {\n const boxTime = document.querySelector<HTMLElement>('#topbar #box-time');\n if (boxTime) {\n boxTime.classList.add('offline');\n const svTime = boxTime.querySelector<HTMLElement>('#sv-time');\n const svDate = boxTime.querySelector<HTMLElement>('#sv-date');\n if (svTime) svTime.innerText = 'server';\n if (svDate) svDate.innerText = 'OFFLINE';\n }\n toast('ขาดการเชื่อมต่อ Server.!', { type: 'failure' });\n};\n/*--------------------------------------------------------------------------------*/\nconst rspLatest = (data: {\n appname: string;\n appuuid: string;\n version: string;\n release: string;\n}) => {\n if (cfg.app.UUID == data.appuuid && cfg.app.NAME == data.appname) {\n const path = window.location.pathname;\n if (path != '/changelog' && cfg.app.RELEASE != data.release) {\n window.location.replace('/changelog');\n }\n }\n};\n/*--------------------------------------------------------------------------------*/\nconst setTime = (data: { unix: number; }) => {\n if (typeof data.unix != 'number') return;\n cfg.UNIX_TIME = Number(data.unix);\n const svTime = document.querySelector<HTMLElement>('#topbar #box-time #sv-time');\n const svDate = document.querySelector<HTMLElement>('#topbar #box-time #sv-date');\n if (svTime && svDate) {\n const [date, time] = timeToStr(cfg.UNIX_TIME).split(' ');\n svTime.innerText = time;\n svDate.innerText = thaiDate(date, 11);\n }\n};\n/*--------------------------------------------------------------------------------*/\ntype NotifyPack = {\n title?: string;\n icon?: string;\n body: string;\n};\nconst brdNotify = (data: NotifyPack) => {\n const title = data.title ? data.title : 'Hub Notify';\n const icon = data.icon ? data.icon : 'https://cdn.jsdelivr.net/npm/slimsdk/dist/assets/icon/icon-06.png';\n const body = data.body ? data.body : '';\n if (!body) return;\n Notification.requestPermission().then(res => {\n if (res == 'granted') {\n new Notification(title, { body: body, icon: icon });\n }\n }).catch(err => console.error(err));\n};\n/*--------------------------------------------------------------------------------*/\n","/* dialog */\nconst app = document.querySelector<HTMLElement>('#app');\n/*--------------------------------------------------------------------------------*/\nexport const confirm = (\n message: string,\n params?: {\n color?: string;\n target?: HTMLElement;\n }\n) => new Promise<boolean>((resolve) => {\n if (!app) return;\n const doc = params && params?.target ? params.target : app;\n const color = params && params?.color ? params.color : 'green';\n // create\n const dialog = document.createElement('div');\n dialog.className = 'overlay slim-dialog';\n dialog.innerHTML = /*html*/ `\n <div class=\"confirm ${color}\">\n <div class=\"header\">\n <i class=\"icon solid\">&#xf058;</i> Slim Confirm\n </div>\n <div class=\"message\">${message}</div>\n <div class=\"footer\">\n <button class=\"lg gray left\" id=\"btn-no\">\n <i>&#xf057;</i>ยกเลิก\n </button>\n <button class=\"lg ${color} right\" id=\"btn-yes\">\n <i>&#xf058;</i>ตกลง\n </button>\n </div>\n </div>\n `;\n doc.appendChild(dialog);\n // button\n dialog.querySelector<HTMLButtonElement>('#btn-yes')!.focus();\n dialog.querySelector<HTMLButtonElement>('#btn-yes')!.onclick = () => {\n dialog.remove();\n resolve(true);\n };\n dialog.querySelector<HTMLButtonElement>('#btn-no')!.onclick = () => {\n dialog.remove();\n resolve(false);\n };\n});\n/*--------------------------------------------------------------------------------*/\nexport const alert = (\n message: string,\n params?: {\n type?: string;\n target?: HTMLElement;\n }\n) => new Promise<void>((resolve) => {\n if (!app) return;\n const doc = params && params?.target ? params.target : app;\n const type = params && params?.type ? params.type : 'success';\n // type\n let color = '';\n let icon = '';\n if (type == 'success') { color = 'green'; icon = '&#xf058;'; }\n if (type == 'failure') { color = 'red'; icon = '&#xf057;'; }\n if (type == 'warning') { color = 'orange'; icon = '&#xf06a;'; }\n if (type == 'info') { color = 'blue'; icon = '&#xf05a;'; }\n // create\n const dialog = document.createElement('div');\n dialog.className = 'overlay slim-dialog';\n dialog.innerHTML = /*html*/ `\n <div class=\"alert ${color}\">\n <div class=\"icon solid\">${icon}</div>\n <div class=\"message\">${message}</div>\n <div class=\"footer\">\n <button class=\"lg ${color}\" id=\"btn-yes\">ตกลง</button>\n </div>\n </div>\n `;\n doc.appendChild(dialog);\n // button\n dialog.querySelector<HTMLButtonElement>('#btn-yes')!.focus();\n dialog.querySelector<HTMLButtonElement>('#btn-yes')!.onclick = () => {\n dialog.remove();\n resolve();\n };\n});\n/*--------------------------------------------------------------------------------*/\nexport const toast = (\n message: string,\n params?: {\n type?: string;\n target?: HTMLElement;\n }\n) => new Promise<void>((resolve) => {\n if (!app) return;\n const doc = params && params?.target ? params.target : app;\n const type = params && params?.type ? params.type : 'success';\n // type\n let color = '';\n let icon = '';\n if (type == 'success') { color = 'green'; icon = '&#xf058;'; }\n if (type == 'failure') { color = 'red'; icon = '&#xf057;'; }\n if (type == 'warning') { color = 'orange'; icon = '&#xf06a;'; }\n if (type == 'info') { color = 'blue'; icon = '&#xf05a;'; }\n // create\n const toast = document.createElement('div');\n toast.className = `slim-toast ${color}`;\n toast.innerHTML = /*html*/ `\n <i class=\"icon\">${icon}</i>\n <span class=\"text\">${message}</span>\n `;\n doc.appendChild(toast);\n // animation\n toast.classList.add('show');\n let count = 0;\n toast.onanimationend = () => {\n count++;\n if (count == 2) {\n toast.remove();\n resolve();\n }\n };\n});\n/*--------------------------------------------------------------------------------*/\n","/* dateTime */\n/*--------------------------------------------------------------------------------*/\nexport const TH_MONTH: string[] = [\n 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน',\n 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม',\n];\nexport const TH_MONTH_SHORT: string[] = [\n 'ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.',\n 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.',\n];\nexport const FY_MONTH: string[] = [\n 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม', 'มกราคม', 'กุมภาพันธ์', 'มีนาคม',\n 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน',\n];\nexport const FY_MONTH_SHORT: string[] = [\n 'ต.ค.', 'พ.ย.', 'ธ.ค.', 'ม.ค.', 'ก.พ.', 'มี.ค.',\n 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.',\n];\nexport const PERIOD_TEXT: string[] = ['', 'เวรดึก', 'เวรเช้า', 'เวรบ่าย'];\n// time unix now\nexport const curTime = (): number => new Date().getTime();\n/*--------------------------------------------------------------------------------*/\nexport const curDate = (): string => {\n const dt = new Date();\n const yy = dt.getFullYear();\n const mm = String(dt.getMonth() + 1).padStart(2, '0');\n const dd = String(dt.getDate()).padStart(2, '0');\n return `${yy}-${mm}-${dd}`;\n};\n/*--------------------------------------------------------------------------------*/\nexport const curMonth = (): string => {\n const dt = new Date();\n const yy = dt.getFullYear();\n const mm = String(dt.getMonth() + 1).padStart(2, '0');\n return `${yy}-${mm}`;\n};\n/*--------------------------------------------------------------------------------*/\nexport const curYear = (yearType = ''): number => {\n const dt = new Date();\n const mm = dt.getMonth() + 1;\n if ((yearType == 'fyear' || yearType == 'fy') && mm > 9) {\n return dt.getFullYear() + 1; // ปีงบประมาณ\n }\n return dt.getFullYear(); // ปีปฏิทิน\n};\n/*--------------------------------------------------------------------------------*/\nexport const timeToStr = (unixtime: number, format = ''): string => {\n if (typeof unixtime != 'number') {\n return '';\n }\n const unix = new Date(Number(unixtime));\n const yy = unix.getFullYear();\n const mm = String(unix.getMonth() + 1).padStart(2, '0');\n const dd = String(unix.getDate()).padStart(2, '0');\n const H = String(unix.getHours()).padStart(2, '0');\n const M = String(unix.getMinutes()).padStart(2, '0');\n const S = String(unix.getSeconds()).padStart(2, '0');\n if (format == 'date') {\n return `${yy}-${mm}-${dd}`;\n }\n if (format == 'time') {\n return `${H}:${M}:${S}`;\n }\n return `${yy}-${mm}-${dd} ${H}:${M}:${S}`;\n};\n/*--------------------------------------------------------------------------------*/\nexport const shiftIndex = (unixtime = 0) => {\n if (typeof unixtime != 'number') {\n return { num: 0, text: '' };\n }\n const unix = unixtime ? new Date(unixtime) : new Date();\n const H = unix.getHours();\n if (H >= 0 && H < 8) return { num: 1, text: PERIOD_TEXT[1] };\n if (H >= 8 && H < 16) return { num: 2, text: PERIOD_TEXT[2] };\n if (H >= 16) return { num: 3, text: PERIOD_TEXT[3] };\n return { num: 0, text: '' };\n};\n/*--------------------------------------------------------------------------------*/\nexport const setYear = (el: HTMLSelectElement, min = 2020, txt = '') => {\n const dt = new Date();\n let year = dt.getFullYear();\n const month = dt.getMonth() + 1;\n if (month > 6 && month <= 12) {\n year++;\n }\n el.innerHTML = '<option value=\"\">- เลือก -</option>';\n for (let y = min; y <= year; y++) {\n const option = document.createElement('option');\n option.value = `${y}`;\n option.text = `${txt} ${y + 543}`;\n el.appendChild(option);\n }\n};\n/*--------------------------------------------------------------------------------*/\nexport const thaiDate = (date: number | string, format = 0): string => {\n if (typeof date == 'string' && date.indexOf('0000-00-00') >= 0) {\n return '';\n }\n if (typeof date == 'string') {\n date = date.trim();\n date = date.replace(' ', 'T');\n }\n\n const dt = new Date(date);\n if (isNaN(dt.getTime())) return '';\n\n const yy = dt.getFullYear() + 543;\n const mm = String(dt.getMonth() + 1).padStart(2, '0');\n const dd = String(dt.getDate()).padStart(2, '0');\n const H = String(dt.getHours()).padStart(2, '0');\n const M = String(dt.getMinutes()).padStart(2, '0');\n const S = String(dt.getSeconds()).padStart(2, '0');\n\n // 01/01/2500\n if (format == 0) return `${dd}/${mm}/${yy}`;\n // 01/01/2500 00:00\n if (format == 1) return `${dd}/${mm}/${yy} ${H}:${M}`;\n // 01/01/2500 00:00:00\n if (format == 2) return `${dd}/${mm}/${yy} ${H}:${M}:${S}`;\n\n // 01 มกราคม 2500\n if (format == 10) return `${dd} ${TH_MONTH[Number(mm) - 1]} ${yy}`;\n // 01 ม.ค. 65\n if (format == 11) return `${dd} ${TH_MONTH_SHORT[Number(mm) - 1]} ${String(yy).slice(-2)}`;\n // 01 มกราคม 2500 เวลา 00:00 น.\n if (format == 12) return `${dd} ${TH_MONTH[Number(mm) - 1]} ${yy} เวลา ${H}:${M} น.`;\n // 01 ม.ค. 65 00:00\n if (format == 13) return `${dd} ${TH_MONTH_SHORT[Number(mm) - 1]} ${String(yy).slice(-2)} ${H}:${M}`;\n\n // มกราคม 2500\n if (format == 20) return `${TH_MONTH[Number(mm) - 1]} ${yy}`;\n // ม.ค. 2500\n if (format == 21) return `${TH_MONTH_SHORT[Number(mm) - 1]} ${yy}`;\n // ม.ค. 65\n if (format == 22) return `${TH_MONTH_SHORT[Number(mm) - 1]} ${String(yy).slice(-2)}`;\n\n return '';\n};\n/*--------------------------------------------------------------------------------*/\nexport const dateDiff = (start: string, stop: string): number => {\n if (!start || start.indexOf('0000-00-00') >= 0) {\n return 0;\n }\n if (!stop || stop.indexOf('0000-00-00') >= 0) {\n return 0;\n }\n const [y1, m1, d1] = start.split('-');\n const [y2, m2, d2] = stop.split('-');\n const date1 = new Date(Number(y1), Number(m1) - 1, Number(d1)).getTime();\n const date2 = new Date(Number(y2), Number(m2) - 1, Number(d2)).getTime();\n return Math.round((date2 - date1) / (1000 * 60 * 60 * 24));\n};\n/*--------------------------------------------------------------------------------*/\nexport const timeDiff = (start: string, stop: string) => {\n if (!start || start.indexOf('0000-00-00') >= 0) {\n return { h: 0, m: 0, s: 0 };\n }\n if (!stop || stop.indexOf('0000-00-00') >= 0) {\n return { h: 0, m: 0, s: 0 };\n }\n start = start.replace(' ', 'T');\n stop = stop.replace(' ', 'T');\n const date1 = new Date(start);\n const date2 = new Date(stop);\n let msec = date2.getTime() - date1.getTime();\n\n const hh = Math.floor(msec / 1000 / 60 / 60);\n msec -= hh * 1000 * 60 * 60;\n const mm = Math.floor(msec / 1000 / 60);\n msec -= mm * 1000 * 60;\n const ss = Math.floor(msec / 1000);\n msec -= ss * 1000;\n return { h: hh, m: mm, s: ss };\n};\n/*--------------------------------------------------------------------------------*/\nexport const getAge = (date: string) => {\n if (!date || date.indexOf('0000-00-00') >= 0) {\n return { years: 0, months: 0, days: 0 };\n }\n const now = new Date();\n const nowYear = now.getFullYear();\n const nowMonth = now.getMonth();\n const nowDate = now.getDate();\n\n const [yy, mm, dd] = date.split('-');\n const birth = new Date(Number(yy), Number(mm) - 1, Number(dd));\n const birthYear = birth.getFullYear();\n const birthMonth = birth.getMonth();\n const birthDate = birth.getDate();\n\n let yearAge = nowYear - birthYear;\n let monthAge = 0;\n let dateAge = 0;\n\n if (nowMonth >= birthMonth) {\n monthAge = nowMonth - birthMonth;\n } else {\n yearAge--;\n monthAge = 12 + nowMonth - birthMonth;\n }\n\n if (nowDate >= birthDate) {\n dateAge = nowDate - birthDate;\n } else {\n monthAge--;\n dateAge = 31 + nowDate - birthDate;\n if (monthAge < 0) {\n monthAge = 11;\n yearAge--;\n }\n }\n\n return {\n years: yearAge,\n months: monthAge,\n days: dateAge,\n };\n};\n/*--------------------------------------------------------------------------------*/\nexport const ageToBirth = (year: number, month: number, day: number): string => {\n const y = Number(year);\n const m = Number(month);\n const d = Number(day);\n const dt = new Date(\n new Date().getFullYear() - y,\n new Date().getMonth() - m,\n new Date().getDate() - d,\n );\n const yy = dt.getFullYear();\n const mm = String(dt.getMonth() + 1).padStart(2, '0');\n const dd = String(dt.getDate()).padStart(2, '0');\n return `${yy}-${mm}-${dd}`; // 1957-10-10\n};\n/*--------------------------------------------------------------------------------*/\nexport const toDbDate = (date: string): string => {\n if ((!date) || (date.indexOf('0000-00-00') >= 0)) {\n return '';\n }\n const dt = new Date(date);\n const yy = dt.getFullYear() - 543;\n const mm = String(dt.getMonth() + 1).padStart(2, '0');\n const dd = String(dt.getDate()).padStart(2, '0');\n return `${yy}-${mm}-${dd}`;\n};\n/*--------------------------------------------------------------------------------*/\nexport const toThaiDate = (date: string): string => {\n if ((!date) || (date.indexOf('0000-00-00') >= 0)) {\n return '';\n }\n const dt = new Date(date);\n const yy = dt.getFullYear() + 543;\n const mm = String(dt.getMonth() + 1).padStart(2, '0');\n const dd = String(dt.getDate()).padStart(2, '0');\n return `${yy}-${mm}-${dd}`;\n};\n/*--------------------------------------------------------------------------------*/\nexport const isToday = (date: string): boolean => {\n const input = new Date(date);\n const today = new Date();\n if (input.setHours(0, 0, 0, 0) == today.setHours(0, 0, 0, 0)) {\n return true;\n }\n return false;\n};\n/*--------------------------------------------------------------------------------*/\n","/* page */\n/*--------------------------------------------------------------------------------*/\nconst app = document.querySelector<HTMLElement>('#app');\nconst pageSpin: string = /*html*/ `\n<div class=\"lds-spinner\">\n <div></div><div></div><div></div><div></div>\n <div></div><div></div><div></div><div></div>\n <div></div><div></div><div></div><div></div>\n</div>\n`;\nconst smallSpin: string = `<div class=\"spinner s32\"></div>`;\n/*--------------------------------------------------------------------------------*/\nexport const loading = (size = 'default') => {\n if (!app) return;\n // page-loader\n if (!app.querySelector('#page-loader')) {\n const loader = document.createElement('div');\n loader.id = 'page-loader';\n loader.className = 'overlay center';\n loader.innerHTML = size == 'default' ? pageSpin : smallSpin;\n app.appendChild(loader);\n }\n // app-content\n const content = app.querySelector<HTMLElement>('#app-content');\n if (content) content.style.display = 'none';\n};\n/*--------------------------------------------------------------------------------*/\nexport const ready = (delay = 400) => {\n new Promise(r => setTimeout(r, delay)).then(() => {\n clearLoader(true);\n });\n};\n/*--------------------------------------------------------------------------------*/\nexport const error = (err: Error) => {\n clearLoader(false);\n if (!app) return;\n // create\n const box = document.createElement('div');\n box.className = 'page-error';\n box.innerHTML = /*html*/ `\n <i class=\"icon red\">&#xf188;</i>\n <div class=\"topic\">&#x2726; เกิดข้อผิดพลาด &#x2726;</div>\n <div class=\"text\">${err}</div>\n `;\n app.prepend(box);\n throw err;\n};\n/*--------------------------------------------------------------------------------*/\nexport const notFound = () => {\n if (!app) return;\n app.innerHTML = /*html*/ `\n <div class=\"page-not-found\">\n <h1>4<i class=\"fas fa-ghost\"></i>4</h1>\n <h2>Error 404 Page Not Found</h2>\n <p>Sorry, the page cannot be accessed</p>\n </div>\n `;\n};\n/*--------------------------------------------------------------------------------*/\nexport const fullLoad = () => {\n clearNavbar();\n if (!app) return;\n app.classList.add('full-page');\n app.innerHTML = /*html*/ `\n <div class=\"page-full-load\">\n <div class=\"spinner\"></div>\n <div class=\"text\">Slim<br>Loading</div>\n </div>\n `;\n};\n/*--------------------------------------------------------------------------------*/\nexport const inform = (params: {\n icon: string;\n msg: string;\n btnTxt: string;\n btnUrl: string;\n color?: string;\n}) => {\n clearNavbar();\n if (!app) return;\n app.classList.add('full-page');\n app.innerHTML = /*html*/ `\n <div class=\"page-inform ${params.color}\">\n <div class=\"icon solid\">${params.icon}</div>\n <div class=\"msg\">${params.msg}</div>\n <button class=\"lg ${params.color}\" shadow=\"true\">\n ${params.btnTxt}\n </button>\n </div>\n `;\n const btn = app.querySelector<HTMLButtonElement>('button')!;\n btn.onclick = () => window.location.replace(params.btnUrl);\n};\n/*--------------------------------------------------------------------------------*/\n//export const Maintain = () => { };\n//export const Construct = () => { };\n/*--------------------------------------------------------------------------------*/\nconst clearNavbar = () => {\n const topbar = document.querySelector<HTMLElement>('#topbar');\n const tabbar = document.querySelector<HTMLElement>('#tabbar');\n const sidebar = document.querySelector<HTMLElement>('#sidebar');\n if (topbar) topbar.remove();\n if (tabbar) tabbar.remove();\n if (sidebar) sidebar.remove();\n if (app) app.className = '';\n};\nconst clearLoader = (showContent: boolean) => {\n if (!app) return;\n const loader = app.querySelector<HTMLElement>('#page-loader');\n if (loader) {\n loader.style.animation = 'fade-out 0.4s forwards';\n loader.onanimationend = () => loader.remove();\n }\n const content = app.querySelector<HTMLElement>('#app-content');\n if (content) content.style.display = showContent ? 'block' : 'none';\n};\n/*--------------------------------------------------------------------------------*/\n","/* template */\nexport const template: string = /*html*/ `\n<div id=\"page-svchub\" class=\"cover\">\n <div class=\"cover-bar\">Hardware Link</div>\n <div class=\"cover-body border\">\n <!-- svcinfo -->\n <div id=\"svcinfo\">\n <div class=\"box-tb\">\n <div class=\"topic\">HwLink</div>\n <div class=\"text\" id=\"hwlink\">:</div>\n </div>\n <div class=\"box-tb\">\n <div class=\"topic\">AutoUp</div>\n <div class=\"text\" id=\"autoup\">:</div>\n </div>\n <div class=\"box-tb\">\n <div class=\"topic\">CSUUID</div>\n <div class=\"text\" id=\"csuuid\">:</div>\n </div>\n </div>\n <hr>\n <!-- device -->\n <div id=\"device\">\n <div class=\"box-tb\">\n <div class=\"topic\">หน่วยงาน</div>\n <div class=\"text\" id=\"\">:</div>\n </div>\n <div class=\"box-tb\">\n <div class=\"topic\">กลุ่มงาน</div>\n <div class=\"text\" id=\"\">:</div>\n </div>\n <div class=\"box-tb\">\n <div class=\"topic\">ชื่ออุปกรณ์</div>\n <div class=\"text\" id=\"\">:</div>\n </div>\n <div class=\"box-tb\">\n <div class=\"topic\">เลขทรัพย์สิน</div>\n <div class=\"text\" id=\"\">:</div>\n </div>\n <button id=\"btn-edit\" class=\"circle sm blue\"\n shadow=\"true\">&#xf5ae;</button>\n </div>\n <hr>\n <!-- hwinfo -->\n <div id=\"hwinfo\">\n <div class=\"box-tb\">\n <div class=\"topic\">Hostname</div>\n <div class=\"text\" id=\"host\">:</div>\n </div>\n <div class=\"box-tb\">\n <div class=\"topic\">Platform</div>\n <div class=\"text\" id=\"os\">:</div>\n </div>\n <div class=\"box-tb\">\n <div class=\"topic\">CpuModel</div>\n <div class=\"text\" id=\"cpu\">:</div>\n </div>\n <div class=\"box-tb\">\n <div class=\"topic\">Memory</div>\n <div class=\"text\" id=\"mem\">:</div>\n </div>\n <div class=\"box-tb\">\n <div class=\"topic\">Uptime</div>\n <div class=\"text\" id=\"uptime\">:</div>\n </div>\n </div>\n <hr>\n <!-- x -->\n <div id=\"\">\n <div class=\"box-tb\">\n <div class=\"topic\">SmartCard</div>\n <div class=\"text\" id=\"\">:</div>\n </div>\n <div class=\"box-tb\">\n <div class=\"topic\">Biometric</div>\n <div class=\"text\" id=\"\">:</div>\n </div>\n </div>\n </div>\n</div>\n<style>\n #page-svchub {\n margin: auto;\n max-width: 600px;\n min-width: 480px;\n line-height: 1.5;\n }\n #page-svchub .topic {\n float: left;\n width: 100px;\n font-weight: 600;\n }\n #page-svchub .text {\n float: left;\n width: calc(100% - 100px);\n }\n #page-svchub #device {\n position: relative;\n }\n #page-svchub #btn-edit {\n position: absolute;\n top: 0;\n right: 0;\n }\n</style>\n`;","/* hwlink */\n/*--------------------------------------------------------------------------------*/\nimport { cfg } from '../../config';\nimport { loading, ready } from '../../page';\nimport { template } from './template';\nconst app = document.querySelector<HTMLElement>('#app');\nlet isREADY: boolean;\nlet WSSVC: WebSocket;\n/*--------------------------------------------------------------------------------*/\nexport const hwLink = () => {\n if (!app) return;\n // template\n const content = document.createElement('div');\n content.id = 'app-content';\n content.innerHTML = template;\n app.classList.add('full-page');\n app.appendChild(content);\n // wait socket\n isREADY = false;\n loading();\n wsSvc();\n};\n/*--------------------------------------------------------------------------------*/\nconst wsSvc = () => {\n WSSVC = new WebSocket(cfg.hwl.HOST);\n WSSVC.onopen = () => {\n hwinfo();\n T_hwinfo = setInterval(hwinfo, 1000 * 10);\n };\n WSSVC.onclose = () => {\n clearInterval(T_hwinfo);\n setTimeout(wsSvc, 1000 * 10);\n };\n WSSVC.onmessage = (e) => {\n const resp = JSON.parse(e.data);\n const head = resp.head ? resp.head : '';\n const data = resp.data ? resp.data : '';\n if (head == 'CSUUID') {\n if (!isREADY) {\n isREADY = true;\n ready();\n }\n }\n if (head == 'HWINFO') setHwInfo(data);\n };\n let T_hwinfo: NodeJS.Timeout;\n const hwinfo = () => WSSVC.send('{\"head\": \"HWINFO\"}');\n};\n/*--------------------------------------------------------------------------------*/\nconst setHwInfo = (data: HwInfo) => {\n if (!app) return;\n // svcinfo\n const svc = data.svc;\n app.querySelector<HTMLElement>('#hwlink')!.innerText = `: ${svc.hwlink}`;\n app.querySelector<HTMLElement>('#autoup')!.innerText = `: ${svc.autoup}`;\n app.querySelector<HTMLElement>('#csuuid')!.innerText = `: ${data.csuuid}`;\n // hwinfo\n const cpu = data.cpu;\n const mem = data.mem;\n const hwinfo = app.querySelector<HTMLElement>('#hwinfo')!;\n const uptime = Number(data.uptime);\n const hh = Math.floor(uptime / 3600);\n const mm = Math.floor((uptime % 3600) / 60);\n const memUsed = (Number(mem.used) / 1024 / 1024 / 1024).toFixed(1);\n const memTotal = (Number(mem.total) / 1024 / 1024 / 1024).toFixed(1);\n const mem_text = `${memUsed}/${memTotal} GB (${mem.percent}%)`;\n hwinfo.querySelector<HTMLElement>('#host')!.innerText = `: ${data.hostname}`;\n hwinfo.querySelector<HTMLElement>('#os')!.innerText = `: ${data.platform}`;\n hwinfo.querySelector<HTMLElement>('#cpu')!.innerText = `: ${cpu.model}`;\n app.querySelector<HTMLElement>('#mem')!.innerText = `: ${mem_text}`;\n app.querySelector<HTMLElement>('#uptime')!.innerText = `: ${hh} h ${mm} m`;\n};\n/*--------------------------------------------------------------------------------*/\ntype HwInfo = {\n csuuid: string;\n hostname: string;\n platform: string;\n uptime: number;\n svc: {\n hwlink: string;\n autoup: string;\n };\n cpu: {\n model: string;\n percent: number;\n };\n mem: {\n total: number;\n used: number;\n percent: number;\n };\n};"],"mappings":"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","names":["app","app","app","toast","app","app","app"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slimsdk",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "WebApp SDK",
5
5
  "type": "module",
6
6
  "exports": {
@@ -10,6 +10,7 @@
10
10
  "./mobile": "./dist/mobile/index.js",
11
11
  "./mobile/": "./dist/mobile/",
12
12
  "./lib": "./dist/lib/index.js",
13
+ "./svchub": "./dist/svchub/index.js",
13
14
  "./worker/": "./dist/worker/*.js",
14
15
  "./page": "./dist/page/index.js",
15
16
  "./page/*": "./dist/page/*/index.js",
@@ -1,52 +0,0 @@
1
- export { i as info, a as init } from '../../index-BMqjxP9I.js';
2
-
3
- declare const cfg: Config;
4
- type Config = {
5
- UNIX_TIME: number;
6
- app: AppCfg;
7
- api: ApiCfg;
8
- hub: HubCfg;
9
- hwl: HwlCfg;
10
- user: UserCfg;
11
- };
12
- type AppCfg = {
13
- UUID: string;
14
- NAME: string;
15
- SECRET: string;
16
- VERSION: string;
17
- RELEASE: string;
18
- CALLBACK: string;
19
- };
20
- type ApiCfg = {
21
- URL: string;
22
- TOKEN: string;
23
- HEADERS?: Headers;
24
- };
25
- type HubCfg = {
26
- LOGIN: string;
27
- OAUTH: string;
28
- API: string;
29
- WSS: string;
30
- UUID: string;
31
- TASK?: Worker;
32
- };
33
- type HwlCfg = {
34
- HOST: string;
35
- FILE: string;
36
- };
37
- type UserCfg = {
38
- sub: number;
39
- name: string;
40
- utyp: string;
41
- unit: string;
42
- unit_id: number;
43
- role_id: number;
44
- metadata: {
45
- emp_type: string;
46
- emp_level: string;
47
- position: string;
48
- };
49
- picture: string;
50
- };
51
-
52
- export { cfg };
@@ -1,121 +0,0 @@
1
- // package.json
2
- var version = "0.2.0";
3
-
4
- // src/config/global.ts
5
- var info = () => `sdk ${version}`;
6
- var init = (params) => {
7
- if (params?.svcWorker) svcWorker(params.svcWorker);
8
- if (params?.webNotify) webNotify();
9
- if (params?.wakeLock) wakeLock();
10
- if (params?.btnToTop) btnToTop();
11
- if (params?.hideTabbar) hideTabbar();
12
- };
13
- var svcWorker = (worker) => {
14
- if (!("serviceWorker" in navigator)) return;
15
- navigator.serviceWorker.register(worker, {
16
- type: "module"
17
- }).catch((err) => console.warn(err));
18
- };
19
- var webNotify = () => {
20
- if (!("Notification" in window)) return;
21
- Notification.requestPermission().catch((err) => console.warn(err));
22
- };
23
- var wakeLock = () => {
24
- if (document.hidden) return;
25
- navigator.wakeLock.request("screen").catch((err) => console.warn(err));
26
- };
27
- var hideTabbar = () => {
28
- const winHeight = window.innerHeight;
29
- window.visualViewport?.addEventListener("resize", () => {
30
- const tabbar = document.querySelector("#tabbar");
31
- if (!tabbar) return;
32
- if (winHeight != window.innerHeight) {
33
- tabbar.classList.add("hide");
34
- } else {
35
- tabbar.classList.remove("hide");
36
- }
37
- });
38
- };
39
- var app = document.querySelector("#app");
40
- var btnToTop = () => {
41
- if (!app) return;
42
- const totop = document.createElement("div");
43
- totop.id = "totop";
44
- totop.innerHTML = /* html */
45
- `
46
- <button id="btn-totop" class="circle purple" shadow="true"
47
- title="\u0E01\u0E25\u0E31\u0E1A\u0E14\u0E49\u0E32\u0E19\u0E1A\u0E19">&#xf341;</button>
48
- `;
49
- document.body.appendChild(totop);
50
- totop.querySelector("#btn-totop").onclick = () => {
51
- app.scrollTo({ top: 0, behavior: "smooth" });
52
- };
53
- app.addEventListener("scroll", () => {
54
- if (app.scrollTop > 1e3) {
55
- totop.style.display = "block";
56
- if (app.classList.contains("tabbar")) {
57
- app.style.paddingBottom = "116px";
58
- } else {
59
- app.style.paddingBottom = "60px";
60
- }
61
- } else {
62
- totop.style.display = "";
63
- app.style.paddingBottom = "";
64
- }
65
- const tabsMobile = app.querySelector(".slim-tabs.mobile .tabs-header");
66
- if (!tabsMobile) return;
67
- if (app.scrollTop > 10) {
68
- tabsMobile.style.boxShadow = `rgba(0, 0, 0, 0.16) 0px 1px 4px`;
69
- } else {
70
- tabsMobile.style.boxShadow = "";
71
- }
72
- });
73
- };
74
-
75
- // src/config/index.ts
76
- var cfg = {
77
- UNIX_TIME: 0,
78
- app: {
79
- UUID: "",
80
- NAME: "",
81
- SECRET: "",
82
- VERSION: "",
83
- RELEASE: "",
84
- CALLBACK: ""
85
- },
86
- api: {
87
- URL: "",
88
- TOKEN: ""
89
- },
90
- hub: {
91
- LOGIN: "https://wkrh.info/oauth/v1/authorize",
92
- OAUTH: "https://wkrh.info:8850/oauth/v1",
93
- API: "https://wkrh.info:8850/api/v1",
94
- WSS: "wss://wkrh.info:8855/ws",
95
- UUID: ""
96
- },
97
- hwl: {
98
- HOST: "ws://localhost:8844/ws",
99
- FILE: "https://wkrh.info/app/hwlink/hwlink_setup.exe"
100
- },
101
- user: {
102
- sub: 0,
103
- name: "",
104
- utyp: "",
105
- unit: "",
106
- unit_id: 0,
107
- role_id: 0,
108
- metadata: {
109
- emp_type: "",
110
- emp_level: "",
111
- position: ""
112
- },
113
- picture: ""
114
- }
115
- };
116
- export {
117
- cfg,
118
- info,
119
- init
120
- };
121
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../package.json","../../../src/config/global.ts","../../../src/config/index.ts"],"sourcesContent":["{\n \"name\": \"slimsdk\",\n \"version\": \"0.2.0\",\n \"description\": \"WebApp SDK\",\n \"type\": \"module\",\n \"exports\": {\n \".\": \"./dist/index.js\",\n \"./desktop\": \"./dist/desktop/index.js\",\n \"./desktop/\": \"./dist/desktop/\",\n \"./mobile\": \"./dist/mobile/index.js\",\n \"./mobile/\": \"./dist/mobile/\",\n \"./lib\": \"./dist/lib/index.js\",\n \"./worker/\": \"./dist/worker/*.js\",\n \"./page\": \"./dist/page/index.js\",\n \"./page/*\": \"./dist/page/*/index.js\",\n \"./page/*.css\": \"./dist/page/*.css\",\n \"./mod\": \"./dist/mod/index.js\",\n \"./mod/*\": \"./dist/mod/*/index.js\",\n \"./mod/*.css\": \"./dist/mod/*.css\",\n \"./css/\": \"./dist/css/\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"dev\": \"tsup --watch\",\n \"build\": \"tsup && sh ./clean.sh\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.39.1\",\n \"@types/node\": \"^25.2.0\",\n \"eslint\": \"^9.39.2\",\n \"globals\": \"^17.3.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.54.0\"\n },\n \"license\": \"MIT\",\n \"author\": \"hs3lcs@gmail.com\"\n}","/* global */\n/*------------------------------------------------------------*/\nimport { version } from '../../package.json';\nexport const info = () => `sdk ${version}`;\n/*------------------------------------------------------------*/\ntype InitParams = {\n svcWorker?: string,\n webNotify?: boolean,\n wakeLock?: boolean,\n btnToTop?: boolean,\n hideTabbar?: boolean,\n};\nexport const init = (params?: InitParams) => {\n if (params?.svcWorker) svcWorker(params.svcWorker);\n if (params?.webNotify) webNotify();\n if (params?.wakeLock) wakeLock();\n if (params?.btnToTop) btnToTop();\n if (params?.hideTabbar) hideTabbar();\n};\n/*------------------------------------------------------------*/\nconst svcWorker = (worker: string) => {\n if (!('serviceWorker' in navigator)) return;\n navigator.serviceWorker.register(worker, {\n type: 'module'\n }).catch(err => console.warn(err));\n};\n/*------------------------------------------------------------*/\nconst webNotify = () => {\n if (!('Notification' in window)) return;\n Notification.requestPermission()\n .catch(err => console.warn(err));\n};\n/*------------------------------------------------------------*/\nconst wakeLock = () => {\n if (document.hidden) return;\n navigator.wakeLock.request('screen')\n .catch(err => console.warn(err));\n};\n/*------------------------------------------------------------*/\nconst hideTabbar = () => {\n const winHeight = window.innerHeight;\n window.visualViewport?.addEventListener('resize', () => {\n const tabbar = document.querySelector<HTMLElement>('#tabbar');\n if (!tabbar) return;\n if (winHeight != window.innerHeight) {\n tabbar.classList.add('hide');\n } else {\n tabbar.classList.remove('hide');\n }\n });\n};\n/*------------------------------------------------------------*/\nconst app = document.querySelector<HTMLElement>('#app');\nconst btnToTop = () => {\n if (!app) return;\n // create item\n const totop = document.createElement('div');\n totop.id = 'totop';\n totop.innerHTML = /* html */ `\n <button id=\"btn-totop\" class=\"circle purple\" shadow=\"true\"\n title=\"กลับด้านบน\">&#xf341;</button>\n `;\n document.body.appendChild(totop);\n // add event\n totop.querySelector<HTMLButtonElement>('#btn-totop')!.onclick = () => {\n app.scrollTo({ top: 0, behavior: 'smooth' });\n };\n app.addEventListener('scroll', () => {\n if (app.scrollTop > 1000) {\n totop.style.display = 'block';\n if (app.classList.contains('tabbar')) {\n app.style.paddingBottom = '116px';\n } else {\n app.style.paddingBottom = '60px';\n }\n } else {\n totop.style.display = '';\n app.style.paddingBottom = '';\n }\n // tabs mobile shadow\n const tabsMobile = app.querySelector<HTMLElement>('.slim-tabs.mobile .tabs-header');\n if (!tabsMobile) return;\n if (app.scrollTop > 10) {\n tabsMobile.style.boxShadow = `rgba(0, 0, 0, 0.16) 0px 1px 4px`;\n } else {\n tabsMobile.style.boxShadow = '';\n }\n });\n};\n/*------------------------------------------------------------*/","/* config */\nexport { init, info } from './global';\n/*------------------------------------------------------------*/\nexport const cfg: Config = {\n UNIX_TIME: 0,\n app: {\n UUID: '',\n NAME: '',\n SECRET: '',\n VERSION: '',\n RELEASE: '',\n CALLBACK: '',\n },\n api: {\n URL: '',\n TOKEN: '',\n },\n hub: {\n LOGIN: 'https://wkrh.info/oauth/v1/authorize',\n OAUTH: 'https://wkrh.info:8850/oauth/v1',\n API: 'https://wkrh.info:8850/api/v1',\n WSS: 'wss://wkrh.info:8855/ws',\n UUID: '',\n },\n hwl: {\n HOST: 'ws://localhost:8844/ws',\n FILE: 'https://wkrh.info/app/hwlink/hwlink_setup.exe',\n },\n user: {\n sub: 0,\n name: '',\n utyp: '',\n unit: '',\n unit_id: 0,\n role_id: 0,\n metadata: {\n emp_type: '',\n emp_level: '',\n position: '',\n },\n picture: '',\n }\n};\n/*------------------------------------------------------------*/\ntype Config = {\n UNIX_TIME: number;\n app: AppCfg;\n api: ApiCfg;\n hub: HubCfg;\n hwl: HwlCfg;\n user: UserCfg;\n};\ntype AppCfg = {\n UUID: string;\n NAME: string;\n SECRET: string;\n VERSION: string;\n RELEASE: string;\n CALLBACK: string;\n};\ntype ApiCfg = {\n URL: string;\n TOKEN: string;\n HEADERS?: Headers;\n};\ntype HubCfg = {\n LOGIN: string;\n OAUTH: string;\n API: string;\n WSS: string;\n UUID: string;\n TASK?: Worker;\n};\ntype HwlCfg = {\n HOST: string;\n FILE: string;\n};\ntype UserCfg = {\n sub: number;\n name: string;\n utyp: string;\n unit: string;\n unit_id: number;\n role_id: number;\n metadata: {\n emp_type: string;\n emp_level: string;\n position: string;\n };\n picture: string;\n};"],"mappings":";AAEI,cAAW;;;ACCR,IAAM,OAAO,MAAM,OAAO,OAAO;AASjC,IAAM,OAAO,CAAC,WAAwB;AACzC,MAAI,QAAQ,UAAW,WAAU,OAAO,SAAS;AACjD,MAAI,QAAQ,UAAW,WAAU;AACjC,MAAI,QAAQ,SAAU,UAAS;AAC/B,MAAI,QAAQ,SAAU,UAAS;AAC/B,MAAI,QAAQ,WAAY,YAAW;AACvC;AAEA,IAAM,YAAY,CAAC,WAAmB;AAClC,MAAI,EAAE,mBAAmB,WAAY;AACrC,YAAU,cAAc,SAAS,QAAQ;AAAA,IACrC,MAAM;AAAA,EACV,CAAC,EAAE,MAAM,SAAO,QAAQ,KAAK,GAAG,CAAC;AACrC;AAEA,IAAM,YAAY,MAAM;AACpB,MAAI,EAAE,kBAAkB,QAAS;AACjC,eAAa,kBAAkB,EAC1B,MAAM,SAAO,QAAQ,KAAK,GAAG,CAAC;AACvC;AAEA,IAAM,WAAW,MAAM;AACnB,MAAI,SAAS,OAAQ;AACrB,YAAU,SAAS,QAAQ,QAAQ,EAC9B,MAAM,SAAO,QAAQ,KAAK,GAAG,CAAC;AACvC;AAEA,IAAM,aAAa,MAAM;AACrB,QAAM,YAAY,OAAO;AACzB,SAAO,gBAAgB,iBAAiB,UAAU,MAAM;AACpD,UAAM,SAAS,SAAS,cAA2B,SAAS;AAC5D,QAAI,CAAC,OAAQ;AACb,QAAI,aAAa,OAAO,aAAa;AACjC,aAAO,UAAU,IAAI,MAAM;AAAA,IAC/B,OAAO;AACH,aAAO,UAAU,OAAO,MAAM;AAAA,IAClC;AAAA,EACJ,CAAC;AACL;AAEA,IAAM,MAAM,SAAS,cAA2B,MAAM;AACtD,IAAM,WAAW,MAAM;AACnB,MAAI,CAAC,IAAK;AAEV,QAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,QAAM,KAAK;AACX,QAAM;AAAA,EAAuB;AAAA;AAAA;AAAA;AAI7B,WAAS,KAAK,YAAY,KAAK;AAE/B,QAAM,cAAiC,YAAY,EAAG,UAAU,MAAM;AAClE,QAAI,SAAS,EAAE,KAAK,GAAG,UAAU,SAAS,CAAC;AAAA,EAC/C;AACA,MAAI,iBAAiB,UAAU,MAAM;AACjC,QAAI,IAAI,YAAY,KAAM;AACtB,YAAM,MAAM,UAAU;AACtB,UAAI,IAAI,UAAU,SAAS,QAAQ,GAAG;AAClC,YAAI,MAAM,gBAAgB;AAAA,MAC9B,OAAO;AACH,YAAI,MAAM,gBAAgB;AAAA,MAC9B;AAAA,IACJ,OAAO;AACH,YAAM,MAAM,UAAU;AACtB,UAAI,MAAM,gBAAgB;AAAA,IAC9B;AAEA,UAAM,aAAa,IAAI,cAA2B,gCAAgC;AAClF,QAAI,CAAC,WAAY;AACjB,QAAI,IAAI,YAAY,IAAI;AACpB,iBAAW,MAAM,YAAY;AAAA,IACjC,OAAO;AACH,iBAAW,MAAM,YAAY;AAAA,IACjC;AAAA,EACJ,CAAC;AACL;;;ACrFO,IAAM,MAAc;AAAA,EACvB,WAAW;AAAA,EACX,KAAK;AAAA,IACD,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU;AAAA,EACd;AAAA,EACA,KAAK;AAAA,IACD,KAAK;AAAA,IACL,OAAO;AAAA,EACX;AAAA,EACA,KAAK;AAAA,IACD,OAAO;AAAA,IACP,OAAO;AAAA,IACP,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACV;AAAA,EACA,KAAK;AAAA,IACD,MAAM;AAAA,IACN,MAAM;AAAA,EACV;AAAA,EACA,MAAM;AAAA,IACF,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU;AAAA,MACN,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,IACd;AAAA,IACA,SAAS;AAAA,EACb;AACJ;","names":[]}
@@ -1,261 +0,0 @@
1
- // src/config/global.ts
2
- var app = document.querySelector("#app");
3
-
4
- // src/config/index.ts
5
- var cfg = {
6
- UNIX_TIME: 0,
7
- app: {
8
- UUID: "",
9
- NAME: "",
10
- SECRET: "",
11
- VERSION: "",
12
- RELEASE: "",
13
- CALLBACK: ""
14
- },
15
- api: {
16
- URL: "",
17
- TOKEN: ""
18
- },
19
- hub: {
20
- LOGIN: "https://wkrh.info/oauth/v1/authorize",
21
- OAUTH: "https://wkrh.info:8850/oauth/v1",
22
- API: "https://wkrh.info:8850/api/v1",
23
- WSS: "wss://wkrh.info:8855/ws",
24
- UUID: ""
25
- },
26
- hwl: {
27
- HOST: "ws://localhost:8844/ws",
28
- FILE: "https://wkrh.info/app/hwlink/hwlink_setup.exe"
29
- },
30
- user: {
31
- sub: 0,
32
- name: "",
33
- utyp: "",
34
- unit: "",
35
- unit_id: 0,
36
- role_id: 0,
37
- metadata: {
38
- emp_type: "",
39
- emp_level: "",
40
- position: ""
41
- },
42
- picture: ""
43
- }
44
- };
45
-
46
- // src/page/index.ts
47
- var app2 = document.querySelector("#app");
48
- var pageSpin = (
49
- /*html*/
50
- `
51
- <div class="lds-spinner">
52
- <div></div><div></div><div></div><div></div>
53
- <div></div><div></div><div></div><div></div>
54
- <div></div><div></div><div></div><div></div>
55
- </div>
56
- `
57
- );
58
- var smallSpin = `<div class="spinner s32"></div>`;
59
- var loading = (size = "default") => {
60
- if (!app2) return;
61
- if (!app2.querySelector("#page-loader")) {
62
- const loader = document.createElement("div");
63
- loader.id = "page-loader";
64
- loader.className = "overlay center";
65
- loader.innerHTML = size == "default" ? pageSpin : smallSpin;
66
- app2.appendChild(loader);
67
- }
68
- const content = app2.querySelector("#app-content");
69
- if (content) content.style.display = "none";
70
- };
71
- var ready = (delay = 400) => {
72
- new Promise((r) => setTimeout(r, delay)).then(() => {
73
- clearLoader(true);
74
- });
75
- };
76
- var clearLoader = (showContent) => {
77
- if (!app2) return;
78
- const loader = app2.querySelector("#page-loader");
79
- if (loader) {
80
- loader.style.animation = "fade-out 0.4s forwards";
81
- loader.onanimationend = () => loader.remove();
82
- }
83
- const content = app2.querySelector("#app-content");
84
- if (content) content.style.display = showContent ? "block" : "none";
85
- };
86
-
87
- // src/svchub/hwlink/template.ts
88
- var template = (
89
- /*html*/
90
- `
91
- <div id="page-svchub" class="cover">
92
- <div class="cover-bar">Hardware Link</div>
93
- <div class="cover-body border">
94
- <!-- svcinfo -->
95
- <div id="svcinfo">
96
- <div class="box-tb">
97
- <div class="topic">HwLink</div>
98
- <div class="text" id="hwlink">:</div>
99
- </div>
100
- <div class="box-tb">
101
- <div class="topic">AutoUp</div>
102
- <div class="text" id="autoup">:</div>
103
- </div>
104
- <div class="box-tb">
105
- <div class="topic">CSUUID</div>
106
- <div class="text" id="csuuid">:</div>
107
- </div>
108
- </div>
109
- <hr>
110
- <!-- device -->
111
- <div id="device">
112
- <div class="box-tb">
113
- <div class="topic">\u0E2B\u0E19\u0E48\u0E27\u0E22\u0E07\u0E32\u0E19</div>
114
- <div class="text" id="">:</div>
115
- </div>
116
- <div class="box-tb">
117
- <div class="topic">\u0E01\u0E25\u0E38\u0E48\u0E21\u0E07\u0E32\u0E19</div>
118
- <div class="text" id="">:</div>
119
- </div>
120
- <div class="box-tb">
121
- <div class="topic">\u0E0A\u0E37\u0E48\u0E2D\u0E2D\u0E38\u0E1B\u0E01\u0E23\u0E13\u0E4C</div>
122
- <div class="text" id="">:</div>
123
- </div>
124
- <div class="box-tb">
125
- <div class="topic">\u0E40\u0E25\u0E02\u0E17\u0E23\u0E31\u0E1E\u0E22\u0E4C\u0E2A\u0E34\u0E19</div>
126
- <div class="text" id="">:</div>
127
- </div>
128
- <button id="btn-edit" class="circle sm blue"
129
- shadow="true">&#xf5ae;</button>
130
- </div>
131
- <hr>
132
- <!-- hwinfo -->
133
- <div id="hwinfo">
134
- <div class="box-tb">
135
- <div class="topic">Hostname</div>
136
- <div class="text" id="host">:</div>
137
- </div>
138
- <div class="box-tb">
139
- <div class="topic">Platform</div>
140
- <div class="text" id="os">:</div>
141
- </div>
142
- <div class="box-tb">
143
- <div class="topic">CpuModel</div>
144
- <div class="text" id="cpu">:</div>
145
- </div>
146
- <div class="box-tb">
147
- <div class="topic">Memory</div>
148
- <div class="text" id="mem">:</div>
149
- </div>
150
- <div class="box-tb">
151
- <div class="topic">Uptime</div>
152
- <div class="text" id="uptime">:</div>
153
- </div>
154
- </div>
155
- <hr>
156
- <!-- x -->
157
- <div id="">
158
- <div class="box-tb">
159
- <div class="topic">SmartCard</div>
160
- <div class="text" id="">:</div>
161
- </div>
162
- <div class="box-tb">
163
- <div class="topic">Biometric</div>
164
- <div class="text" id="">:</div>
165
- </div>
166
- </div>
167
- </div>
168
- </div>
169
- <style>
170
- #page-svchub {
171
- margin: auto;
172
- max-width: 600px;
173
- min-width: 480px;
174
- line-height: 1.5;
175
- }
176
- #page-svchub .topic {
177
- float: left;
178
- width: 100px;
179
- font-weight: 600;
180
- }
181
- #page-svchub .text {
182
- float: left;
183
- width: calc(100% - 100px);
184
- }
185
- #page-svchub #device {
186
- position: relative;
187
- }
188
- #page-svchub #btn-edit {
189
- position: absolute;
190
- top: 0;
191
- right: 0;
192
- }
193
- </style>
194
- `
195
- );
196
-
197
- // src/svchub/hwlink/index.ts
198
- var app3 = document.querySelector("#app");
199
- var isREADY;
200
- var WSSVC;
201
- var hwLink = () => {
202
- if (!app3) return;
203
- const content = document.createElement("div");
204
- content.id = "app-content";
205
- content.innerHTML = template;
206
- app3.classList.add("full-page");
207
- app3.appendChild(content);
208
- isREADY = false;
209
- loading();
210
- wsSvc();
211
- };
212
- var wsSvc = () => {
213
- WSSVC = new WebSocket(cfg.hwl.HOST);
214
- WSSVC.onopen = () => {
215
- hwinfo();
216
- T_hwinfo = setInterval(hwinfo, 1e3 * 10);
217
- };
218
- WSSVC.onclose = () => {
219
- clearInterval(T_hwinfo);
220
- setTimeout(wsSvc, 1e3 * 10);
221
- };
222
- WSSVC.onmessage = (e) => {
223
- const resp = JSON.parse(e.data);
224
- const head = resp.head ? resp.head : "";
225
- const data = resp.data ? resp.data : "";
226
- if (head == "CSUUID") {
227
- if (!isREADY) {
228
- isREADY = true;
229
- ready();
230
- }
231
- }
232
- if (head == "HWINFO") setHwInfo(data);
233
- };
234
- let T_hwinfo;
235
- const hwinfo = () => WSSVC.send('{"head": "HWINFO"}');
236
- };
237
- var setHwInfo = (data) => {
238
- if (!app3) return;
239
- const svc = data.svc;
240
- app3.querySelector("#hwlink").innerText = `: ${svc.hwlink}`;
241
- app3.querySelector("#autoup").innerText = `: ${svc.autoup}`;
242
- app3.querySelector("#csuuid").innerText = `: ${data.csuuid}`;
243
- const cpu = data.cpu;
244
- const mem = data.mem;
245
- const hwinfo = app3.querySelector("#hwinfo");
246
- const uptime = Number(data.uptime);
247
- const hh = Math.floor(uptime / 3600);
248
- const mm = Math.floor(uptime % 3600 / 60);
249
- const memUsed = (Number(mem.used) / 1024 / 1024 / 1024).toFixed(1);
250
- const memTotal = (Number(mem.total) / 1024 / 1024 / 1024).toFixed(1);
251
- const mem_text = `${memUsed}/${memTotal} GB (${mem.percent}%)`;
252
- hwinfo.querySelector("#host").innerText = `: ${data.hostname}`;
253
- hwinfo.querySelector("#os").innerText = `: ${data.platform}`;
254
- hwinfo.querySelector("#cpu").innerText = `: ${cpu.model}`;
255
- app3.querySelector("#mem").innerText = `: ${mem_text}`;
256
- app3.querySelector("#uptime").innerText = `: ${hh} h ${mm} m`;
257
- };
258
- export {
259
- hwLink
260
- };
261
- //# sourceMappingURL=index.js.map