@gkd-kit/inspect 0.0.1784022139716 → 0.0.1784556894874

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.
Files changed (25) hide show
  1. package/dist/404.html +14 -14
  2. package/dist/assets/{ActionCard-DX4l_WJe.js → ActionCard-eQYOgHVh.js} +2 -2
  3. package/dist/assets/{ActionCard-DX4l_WJe.js.map → ActionCard-eQYOgHVh.js.map} +1 -1
  4. package/dist/assets/{DevicePage-pwsi0ARH.js → DevicePage-A7gjew_b.js} +2 -2
  5. package/dist/assets/{DevicePage-pwsi0ARH.js.map → DevicePage-A7gjew_b.js.map} +1 -1
  6. package/dist/assets/{HomePage-Cm0eK4jK.js → HomePage-CK1sVwzl.js} +2 -2
  7. package/dist/assets/{HomePage-Cm0eK4jK.js.map → HomePage-CK1sVwzl.js.map} +1 -1
  8. package/dist/assets/{SelectorPage-DuSW-Og-.js → SelectorPage-DT_fr6B2.js} +2 -2
  9. package/dist/assets/{SelectorPage-DuSW-Og-.js.map → SelectorPage-DT_fr6B2.js.map} +1 -1
  10. package/dist/assets/{SnapshotPage-BHG417bW.js → SnapshotPage-DyhoQqAA.js} +4 -4
  11. package/dist/assets/{SnapshotPage-BHG417bW.js.map → SnapshotPage-DyhoQqAA.js.map} +1 -1
  12. package/dist/assets/{TrackGraph-7abwJYiU.js → TrackGraph-Z1aFO1AL.js} +2 -2
  13. package/dist/assets/{TrackGraph-7abwJYiU.js.map → TrackGraph-Z1aFO1AL.js.map} +1 -1
  14. package/dist/assets/chunk-CrgKN-f1.js +1 -1
  15. package/dist/assets/{dist-Ed4nv7XA.js → dist-sa2Ots6K.js} +2 -2
  16. package/dist/assets/{dist-Ed4nv7XA.js.map → dist-sa2Ots6K.js.map} +1 -1
  17. package/dist/assets/{index-Kh9cOBUf.js → index-ClJbN9CD.js} +7 -7
  18. package/dist/assets/{index-Kh9cOBUf.js.map → index-ClJbN9CD.js.map} +1 -1
  19. package/dist/assets/{index-8cyrRZl0.css → index-DSoTs45N.css} +1 -1
  20. package/dist/assets/{selector-D4x6mV72.js → selector-DY-RG6gh.js} +2 -2
  21. package/dist/assets/{selector-D4x6mV72.js.map → selector-DY-RG6gh.js.map} +1 -1
  22. package/dist/assets/{useBatchActions-DdbI6fAV.js → useBatchActions-fKVQDVTI.js} +2 -2
  23. package/dist/assets/{useBatchActions-DdbI6fAV.js.map → useBatchActions-fKVQDVTI.js.map} +1 -1
  24. package/dist/index.html +14 -14
  25. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import{i as e}from"./chunk-62oNxeRG.js";import{ln as t,r as n,u as r,v as i,x as a}from"./discrete-CByWVgF2.js";import{n as o}from"./Icon-ByFRPJzF.js";import{d as s,f as c,m as l,t as u,w as ee}from"./ActionCard-DX4l_WJe.js";import{Et as te,F as d,G as f,K as p,M as m,Q as h,f as g,g as _,h as v,i as y,it as b,l as x,ot as S,p as C,q as w,rt as T,u as E,ut as D,v as O,z as k}from"./runtime-core.esm-bundler-BDo_QXnq.js";import{a as ne,i as re,n as ie,o as ae,t as oe}from"./useBatchActions-DdbI6fAV.js";import{t as se}from"./Input-C3St80tx.js";import{t as ce}from"./Checkbox-CA6sAZH-.js";import{a as le}from"./vue-router-rzTi5fkZ.js";import{x as ue}from"./storage-BFHw9nz6.js";import{t as de}from"./check-DMevxUTa.js";import{c as A,i as j,r as fe,s as M}from"./chunk-CrgKN-f1.js";import{r as N,t as P}from"./dist-DZjMMDTK.js";var pe=e=>{let t=S(e),r=S(),i=async(e,r,i)=>{var a;if(!t.value)throw Error(`origin must exist`);let o=await A(new URL(`/api/`+e,t.value),r,i).catch(t=>{throw n.error(`网络错误:`+e),t});if(!o.ok)throw n.error(`接口错误:`+e+`:`+o.status),o;if((a=o.headers.get(`Content-Type`))!=null&&a.includes(`application/json`)){let e=await o.clone().json();if(e.__error)throw n.error(e.message),o}return o},a=async(e,t={},n)=>i(e,{method:`post`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)},n),o=async(e,t={})=>a(e,t).then(e=>e.json()),s=async(e,t={})=>a(e,t,e=>(e.responseType=`arraybuffer`,e)).then(e=>e.arrayBuffer());return{origin:t,api:{getServerInfo:async()=>o(`getServerInfo`),getSnapshot:async e=>{var t;return((t=r.value)==null||(t=t.gkdAppInfo)==null?void 0:t.versionName)===`1.10.4`?i(`snapshot?id=`+e.id).then(e=>e.json()):o(`getSnapshot`,e)},getScreenshot:async e=>s(`getScreenshot`,e),captureSnapshot:async()=>o(`captureSnapshot`),getSnapshots:async()=>o(`getSnapshots`),updateSubscription:async e=>o(`updateSubscription`,{...e,id:-1,name:`内存订阅`,version:0}),execSelector:async e=>(e=structuredClone(e),e.action||=void 0,o(`execSelector`,e)),deleteSnapshot:async e=>o(`deleteSnapshot`,e)},serverInfo:r}},me=e(P(),1),he={flex:``,"gap-10px":``,"flex-items-center":``},ge={"page-size":``,flex:``,"flex-col":``,"p-10px":``,"gap-10px":``},F={flex:``,"items-center":``,"gap-24px":``},I={key:0,gkd_code:``,"pl-16px":``,"whitespace-nowrap":``,flex:``,"items-center":``},L=O({__name:`DevicePage`,setup(e){let O=le(),{api:A,origin:P,serverInfo:L}=pe(),R=r(`device_link`,``),z=c(async()=>{R.value&&(P.value=N(()=>new URL(R.value.trim()),()=>`非法设备地址`).origin,R.value=P.value,L.value=await A.getServerInfo())}),B=x(()=>{if(!L.value)return`未连接设备`;let e=L.value.device,t=L.value.gkdAppInfo;return`${e.manufacturer} Android${e.release} - GKD${t.versionName}`});m(async()=>{await ue(500),de(R.value)&&z.invoke()});let V=S([]);p(async()=>{if(!L.value)return;document.title=B.value;let e=await A.getSnapshots();e.sort((e,t)=>t.id-e.id),V.value=e,Y.value=``});let H=c(async()=>{let e=await A.captureSnapshot(),t=await A.getScreenshot({id:e.id});await M.setItem(e.id,e),await j.setItem(e.id,t),n.success(`捕获并保存快照成功`);let r=await A.getSnapshots();r.sort((e,t)=>t.id-e.id),V.value=r}),U=c(async()=>{let e=(await A.getSnapshots()).map(e=>e.id),t=new Set((await j.keys()).map(e=>parseInt(e))),r=e.filter(e=>!t.has(e));if(r.length==0){n.success(`没有新记录可导入`);return}let i=0,a=fe(3);await Promise.all(r.map(e=>a(async()=>{let[t,n]=await Promise.all([A.getSnapshot({id:e}),A.getScreenshot({id:e})]);t.nodes&&(await Promise.all([M.setItem(e,t),j.setItem(e,n)]),i++)}))),n.success(`导入${i}条新记录`)}),{activityIdCol:_e,appIdCol:ve,appNameCol:ye,ctimeCol:W,appVersionCodeCol:be,appVersionNameCol:xe,resetColWidth:Se}=re(),Ce=e=>{e.columnKey==W.key&&(W.sortOrder=e.order)},G=s(async e=>{if(!await M.hasItem(e.id)){let t=await A.getSnapshot({id:e.id});await M.setItem(e.id,t)}if(!await j.hasItem(e.id)){let t=await A.getScreenshot({id:e.id});await j.setItem(e.id,t)}window.open(O.resolve({name:`snapshot`,params:{snapshotId:e.id}}).href)},e=>e.id),we=[{type:`selection`},W,ye,ve,be,xe,_e,{key:`actions`,title:`操作`,fixed:`right`,width:`160px`,render(e){return _(u,{snapshot:e,showExport:!1,showShare:!1,deleteConfirmText:`是否确认删除? 此操作不可恢复!\n快照ID:${e.id}`,onPreview:()=>G.invoke(e),previewLoading:G.loading[e.id],onBeforeDelete:async()=>await A.deleteSnapshot({id:e.id}),onDelete:()=>{V.value=V.value.filter(t=>t.id!==e.id)}},null)}}],K=T([]),{batchDelete:Te}=oe(K,{beforeDeleteItem:async e=>await A.deleteSnapshot({id:e}),onAfterDelete:async()=>{let e=await A.getSnapshots();e.sort((e,t)=>t.id-e.id),V.value=e}}),q=b({page:1,pageSize:50,showSizePicker:!0,pageSizes:[50,100],onChange:e=>{q.page=e},onUpdatePageSize:e=>{q.pageSize=e,q.page=1}});f(q,Se);let J=S(!1),Y=S(``),X=c(async()=>{let e=N(()=>me.default.parse(Y.value.trim()));if(e){if(e.categories||e.globalGroups||e.apps)await A.updateSubscription(e);else if(typeof e.id==`string`)await A.updateSubscription({apps:[e]});else if(Array.isArray(e)&&typeof e[0].id==`string`)await A.updateSubscription({apps:e});else if(typeof e.key==`number`)await A.updateSubscription({globalGroups:[e]});else if(Array.isArray(e)&&typeof e[0].key==`number`)await A.updateSubscription({globalGroups:e});else{n.error(`无法识别的订阅文本`);return}n.success(`修改成功`)}}),Z=S(!1),Ee=[{label:`仅查询`,value:``},{value:`click`,label:`click`},{value:`clickNode`,label:`clickNode`},{value:`clickCenter`,label:`clickCenter`},{value:`back`,label:`back`},{value:`longClick`,label:`longClick`},{value:`longClickNode`,label:`longClickNode`},{value:`longClickCenter`,label:`longClickCenter`}],Q=b({selector:``,action:`click`,quickFind:!1}),$=c(async()=>{let e=await A.execSelector({...Q,fastQuery:Q.quickFind});if(e.message){n.success(`操作成功:`+e.message);return}e.action?n.success((e.result?`操作成功:`:`操作失败`)+e.action):!e.action&&e.result&&n.success(`查询成功`)});return(e,n)=>{let r=se,s=i,c=ce,u=l,f=ae,p=k(`SvgIcon`),m=a,b=k(`RouterLink`),x=o,S=ee,T=ne;return d(),C(y,null,[_(s,{show:D(J),"onUpdate:show":n[1]||=e=>h(J)?J.value=e:null,preset:`dialog`,style:{width:`800px`},title:`修改内存订阅`,positiveText:`确认`,positiveButtonProps:{loading:D(X).loading,onClick(){D(X).invoke()}}},{default:w(()=>[_(r,{value:D(Y),"onUpdate:value":n[0]||=e=>h(Y)?Y.value=e:null,disabled:D(X).loading,type:`textarea`,class:`gkd_code`,autosize:{minRows:20,maxRows:25},placeholder:D(`请输入订阅文本(JSON5语法):
1
+ import{i as e}from"./chunk-62oNxeRG.js";import{ln as t,r as n,u as r,v as i,x as a}from"./discrete-CByWVgF2.js";import{n as o}from"./Icon-ByFRPJzF.js";import{d as s,f as c,m as l,t as u,w as ee}from"./ActionCard-eQYOgHVh.js";import{Et as te,F as d,G as f,K as p,M as m,Q as h,f as g,g as _,h as v,i as y,it as b,l as x,ot as S,p as C,q as w,rt as T,u as E,ut as D,v as O,z as k}from"./runtime-core.esm-bundler-BDo_QXnq.js";import{a as ne,i as re,n as ie,o as ae,t as oe}from"./useBatchActions-fKVQDVTI.js";import{t as se}from"./Input-C3St80tx.js";import{t as ce}from"./Checkbox-CA6sAZH-.js";import{a as le}from"./vue-router-rzTi5fkZ.js";import{x as ue}from"./storage-BFHw9nz6.js";import{t as de}from"./check-DMevxUTa.js";import{c as A,i as j,r as fe,s as M}from"./chunk-CrgKN-f1.js";import{r as N,t as P}from"./dist-DZjMMDTK.js";var pe=e=>{let t=S(e),r=S(),i=async(e,r,i)=>{var a;if(!t.value)throw Error(`origin must exist`);let o=await A(new URL(`/api/`+e,t.value),r,i).catch(t=>{throw n.error(`网络错误:`+e),t});if(!o.ok)throw n.error(`接口错误:`+e+`:`+o.status),o;if((a=o.headers.get(`Content-Type`))!=null&&a.includes(`application/json`)){let e=await o.clone().json();if(e.__error)throw n.error(e.message),o}return o},a=async(e,t={},n)=>i(e,{method:`post`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)},n),o=async(e,t={})=>a(e,t).then(e=>e.json()),s=async(e,t={})=>a(e,t,e=>(e.responseType=`arraybuffer`,e)).then(e=>e.arrayBuffer());return{origin:t,api:{getServerInfo:async()=>o(`getServerInfo`),getSnapshot:async e=>{var t;return((t=r.value)==null||(t=t.gkdAppInfo)==null?void 0:t.versionName)===`1.10.4`?i(`snapshot?id=`+e.id).then(e=>e.json()):o(`getSnapshot`,e)},getScreenshot:async e=>s(`getScreenshot`,e),captureSnapshot:async()=>o(`captureSnapshot`),getSnapshots:async()=>o(`getSnapshots`),updateSubscription:async e=>o(`updateSubscription`,{...e,id:-1,name:`内存订阅`,version:0}),execSelector:async e=>(e=structuredClone(e),e.action||=void 0,o(`execSelector`,e)),deleteSnapshot:async e=>o(`deleteSnapshot`,e)},serverInfo:r}},me=e(P(),1),he={flex:``,"gap-10px":``,"flex-items-center":``},ge={"page-size":``,flex:``,"flex-col":``,"p-10px":``,"gap-10px":``},F={flex:``,"items-center":``,"gap-24px":``},I={key:0,gkd_code:``,"pl-16px":``,"whitespace-nowrap":``,flex:``,"items-center":``},L=O({__name:`DevicePage`,setup(e){let O=le(),{api:A,origin:P,serverInfo:L}=pe(),R=r(`device_link`,``),z=c(async()=>{R.value&&(P.value=N(()=>new URL(R.value.trim()),()=>`非法设备地址`).origin,R.value=P.value,L.value=await A.getServerInfo())}),B=x(()=>{if(!L.value)return`未连接设备`;let e=L.value.device,t=L.value.gkdAppInfo;return`${e.manufacturer} Android${e.release} - GKD${t.versionName}`});m(async()=>{await ue(500),de(R.value)&&z.invoke()});let V=S([]);p(async()=>{if(!L.value)return;document.title=B.value;let e=await A.getSnapshots();e.sort((e,t)=>t.id-e.id),V.value=e,Y.value=``});let H=c(async()=>{let e=await A.captureSnapshot(),t=await A.getScreenshot({id:e.id});await M.setItem(e.id,e),await j.setItem(e.id,t),n.success(`捕获并保存快照成功`);let r=await A.getSnapshots();r.sort((e,t)=>t.id-e.id),V.value=r}),U=c(async()=>{let e=(await A.getSnapshots()).map(e=>e.id),t=new Set((await j.keys()).map(e=>parseInt(e))),r=e.filter(e=>!t.has(e));if(r.length==0){n.success(`没有新记录可导入`);return}let i=0,a=fe(3);await Promise.all(r.map(e=>a(async()=>{let[t,n]=await Promise.all([A.getSnapshot({id:e}),A.getScreenshot({id:e})]);t.nodes&&(await Promise.all([M.setItem(e,t),j.setItem(e,n)]),i++)}))),n.success(`导入${i}条新记录`)}),{activityIdCol:_e,appIdCol:ve,appNameCol:ye,ctimeCol:W,appVersionCodeCol:be,appVersionNameCol:xe,resetColWidth:Se}=re(),Ce=e=>{e.columnKey==W.key&&(W.sortOrder=e.order)},G=s(async e=>{if(!await M.hasItem(e.id)){let t=await A.getSnapshot({id:e.id});await M.setItem(e.id,t)}if(!await j.hasItem(e.id)){let t=await A.getScreenshot({id:e.id});await j.setItem(e.id,t)}window.open(O.resolve({name:`snapshot`,params:{snapshotId:e.id}}).href)},e=>e.id),we=[{type:`selection`},W,ye,ve,be,xe,_e,{key:`actions`,title:`操作`,fixed:`right`,width:`160px`,render(e){return _(u,{snapshot:e,showExport:!1,showShare:!1,deleteConfirmText:`是否确认删除? 此操作不可恢复!\n快照ID:${e.id}`,onPreview:()=>G.invoke(e),previewLoading:G.loading[e.id],onBeforeDelete:async()=>await A.deleteSnapshot({id:e.id}),onDelete:()=>{V.value=V.value.filter(t=>t.id!==e.id)}},null)}}],K=T([]),{batchDelete:Te}=oe(K,{beforeDeleteItem:async e=>await A.deleteSnapshot({id:e}),onAfterDelete:async()=>{let e=await A.getSnapshots();e.sort((e,t)=>t.id-e.id),V.value=e}}),q=b({page:1,pageSize:50,showSizePicker:!0,pageSizes:[50,100],onChange:e=>{q.page=e},onUpdatePageSize:e=>{q.pageSize=e,q.page=1}});f(q,Se);let J=S(!1),Y=S(``),X=c(async()=>{let e=N(()=>me.default.parse(Y.value.trim()));if(e){if(e.categories||e.globalGroups||e.apps)await A.updateSubscription(e);else if(typeof e.id==`string`)await A.updateSubscription({apps:[e]});else if(Array.isArray(e)&&typeof e[0].id==`string`)await A.updateSubscription({apps:e});else if(typeof e.key==`number`)await A.updateSubscription({globalGroups:[e]});else if(Array.isArray(e)&&typeof e[0].key==`number`)await A.updateSubscription({globalGroups:e});else{n.error(`无法识别的订阅文本`);return}n.success(`修改成功`)}}),Z=S(!1),Ee=[{label:`仅查询`,value:``},{value:`click`,label:`click`},{value:`clickNode`,label:`clickNode`},{value:`clickCenter`,label:`clickCenter`},{value:`back`,label:`back`},{value:`longClick`,label:`longClick`},{value:`longClickNode`,label:`longClickNode`},{value:`longClickCenter`,label:`longClickCenter`}],Q=b({selector:``,action:`click`,quickFind:!1}),$=c(async()=>{let e=await A.execSelector({...Q,fastQuery:Q.quickFind});if(e.message){n.success(`操作成功:`+e.message);return}e.action?n.success((e.result?`操作成功:`:`操作失败`)+e.action):!e.action&&e.result&&n.success(`查询成功`)});return(e,n)=>{let r=se,s=i,c=ce,u=l,f=ae,p=k(`SvgIcon`),m=a,b=k(`RouterLink`),x=o,S=ee,T=ne;return d(),C(y,null,[_(s,{show:D(J),"onUpdate:show":n[1]||=e=>h(J)?J.value=e:null,preset:`dialog`,style:{width:`800px`},title:`修改内存订阅`,positiveText:`确认`,positiveButtonProps:{loading:D(X).loading,onClick(){D(X).invoke()}}},{default:w(()=>[_(r,{value:D(Y),"onUpdate:value":n[0]||=e=>h(Y)?Y.value=e:null,disabled:D(X).loading,type:`textarea`,class:`gkd_code`,autosize:{minRows:20,maxRows:25},placeholder:D(`请输入订阅文本(JSON5语法):
2
2
  示例1-更新单个应用的规则:
3
3
  {
4
4
  id: 'appId',
@@ -44,4 +44,4 @@ import{i as e}from"./chunk-62oNxeRG.js";import{ln as t,r as n,u as r,v as i,x as
44
44
  globalGroups: [],
45
45
  categories: [],
46
46
  }`)},null,8,[`value`,`disabled`,`placeholder`])]),_:1},8,[`show`,`positiveButtonProps`]),_(s,{show:D(Z),"onUpdate:show":n[5]||=e=>h(Z)?Z.value=e:null,preset:`dialog`,style:{width:`800px`},title:`执行选择器`,positiveText:`确认`,positiveButtonProps:{loading:D($).loading,onClick(){D($).invoke()}}},{default:w(()=>[_(r,{value:D(Q).selector,"onUpdate:value":n[2]||=e=>D(Q).selector=e,disabled:D($).loading,type:`textarea`,class:`gkd_code`,autosize:{minRows:4,maxRows:10},placeholder:`请输入合法的选择器`},null,8,[`value`,`disabled`]),n[13]||=E(`div`,{"h-15px":``},null,-1),_(u,null,{default:w(()=>[_(c,{checked:D(Q).quickFind,"onUpdate:checked":n[3]||=e=>D(Q).quickFind=e},{default:w(()=>[...n[10]||=[v(` 快速查找 `,-1)]]),_:1},8,[`checked`]),n[11]||=E(`a`,{href:`https://gkd.li/api/interfaces/RawCommonProps.html#quickfind`,target:`_blank`,rel:`noopener noreferrer`},` 查找说明 `,-1)]),_:1}),n[14]||=E(`div`,{"h-10px":``},null,-1),E(`div`,he,[_(f,{value:D(Q).action,"onUpdate:value":n[4]||=e=>D(Q).action=e,options:Ee,class:`w-150px`},null,8,[`value`]),n[12]||=E(`a`,{href:`https://gkd.li/api/interfaces/RawRuleProps#action`,target:`_blank`,rel:`noopener noreferrer`},` 操作说明 `,-1)])]),_:1},8,[`show`,`positiveButtonProps`]),E(`div`,ge,[E(`div`,F,[_(b,{to:`/`,class:`flex ml-12px`,title:`首页`},{default:w(()=>[_(m,{text:``,style:{"--n-icon-size":`24px`}},{icon:w(()=>[_(p,{name:`home`})]),_:1})]),_:1}),_(S,null,{default:w(()=>[_(r,{value:D(R),"onUpdate:value":n[6]||=e=>h(R)?R.value=e:null,placeholder:`请输入设备地址`,class:`gkd_code`,style:{width:`240px`},onKeyup:t(D(z).invoke,[`enter`])},{suffix:w(()=>[_(x,null,{trigger:w(()=>[_(m,{text:``,style:{"--n-icon-size":`20px`},loading:D(z).loading,onClick:D(z).invoke},{icon:w(()=>[_(p,{name:`refresh`})]),_:1},8,[`loading`,`onClick`])]),default:w(()=>[n[15]||=v(` 刷新连接 `,-1)]),_:1})]),_:1},8,[`value`,`onKeyup`]),D(L)?(d(),C(`div`,I,te(D(B)),1)):g(``,!0)]),_:1}),D(L)?(d(),C(y,{key:0},[_(ie,{checkedCount:D(K).length,batchDelete:D(Te)},null,8,[`checkedCount`,`batchDelete`]),_(x,null,{trigger:w(()=>[_(m,{text:``,style:{"--n-icon-size":`24px`},loading:D(H).loading,onClick:D(H).invoke},{icon:w(()=>[_(p,{name:`Snapshot`})]),_:1},8,[`loading`,`onClick`])]),default:w(()=>[n[16]||=v(` 捕获快照 `,-1)]),_:1}),_(x,null,{trigger:w(()=>[_(m,{text:``,style:{"--n-icon-size":`24px`},loading:D(U).loading,onClick:D(U).invoke},{icon:w(()=>[_(p,{name:`Down-all`})]),_:1},8,[`loading`,`onClick`])]),default:w(()=>[n[17]||=v(` 下载所有快照 `,-1)]),_:1}),_(x,null,{trigger:w(()=>[_(m,{text:``,style:{"--n-icon-size":`24px`},onClick:n[7]||=e=>J.value=!0},{icon:w(()=>[_(p,{name:`CacheSub`})]),_:1})]),default:w(()=>[n[18]||=v(` 修改内存订阅 `,-1)]),_:1}),_(x,null,{trigger:w(()=>[_(m,{text:``,style:{"--n-icon-size":`24px`},onClick:n[8]||=e=>Z.value=!0},{icon:w(()=>[_(p,{name:`Exe-Sel`})]),_:1})]),default:w(()=>[n[19]||=v(` 执行选择器 `,-1)]),_:1})],64)):g(``,!0)]),_(T,{checkedRowKeys:D(K),"onUpdate:checkedRowKeys":n[9]||=e=>h(K)?K.value=e:null,striped:``,"flex-height":``,data:D(V),columns:we,pagination:D(q),rowKey:e=>e.id,size:`small`,class:`flex-1`,scrollX:1200,"onUpdate:sorter":Ce},null,8,[`checkedRowKeys`,`data`,`pagination`,`rowKey`])])],64)}}});export{L as default};
47
- //# sourceMappingURL=DevicePage-pwsi0ARH.js.map
47
+ //# sourceMappingURL=DevicePage-A7gjew_b.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevicePage-pwsi0ARH.js","names":[],"sources":["../../src/utils/api.ts","../../src/views/DevicePage.vue","../../src/views/DevicePage.vue"],"sourcesContent":["import { message } from './discrete';\nimport { enhanceFetch } from './fetch';\nimport type { GmXhrOptions } from './gm';\n\ninterface Reqid {\n id: number;\n}\n\nexport const useDeviceApi = (initOrigin?: string) => {\n const origin = shallowRef(initOrigin);\n const serverInfo = shallowRef<ServerInfo>();\n const request = async (\n name: string,\n init?: RequestInit,\n xhrDetails?: (arg: GmXhrOptions) => GmXhrOptions,\n ) => {\n if (!origin.value) {\n throw new Error(`origin must exist`);\n }\n const u = new URL(`/api/` + name, origin.value);\n const response = await enhanceFetch(u, init, xhrDetails).catch((e) => {\n message.error(`网络错误:` + name);\n throw e;\n });\n if (!response.ok) {\n message.error(`接口错误:` + name + `:` + response.status);\n throw response;\n }\n if (response.headers.get(`Content-Type`)?.includes(`application/json`)) {\n const error = (await response.clone().json()) as RpcError;\n if (error.__error) {\n message.error(error.message);\n throw response;\n }\n }\n return response;\n };\n const baseRpc = async (\n name: string,\n data: object = {},\n xhrDetails?: (arg: GmXhrOptions) => GmXhrOptions,\n ) => {\n return request(\n name,\n {\n method: 'post',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n },\n xhrDetails,\n );\n };\n const jsonRpc = async <T>(name: string, data: object = {}): Promise<T> => {\n return baseRpc(name, data).then((r) => r.json());\n };\n const bfRpc = async (\n name: string,\n data: object = {},\n ): Promise<ArrayBuffer> => {\n return baseRpc(name, data, (v) => {\n // must set responseType to get binary data\n v.responseType = 'arraybuffer';\n return v;\n }).then((r) => r.arrayBuffer());\n };\n const api = {\n getServerInfo: async () => jsonRpc<ServerInfo>(`getServerInfo`),\n getSnapshot: async (data: Reqid): Promise<Snapshot> => {\n if (serverInfo.value?.gkdAppInfo?.versionName === '1.10.4') {\n // 兼容旧版本 BUG\n // https://github.com/gkd-kit/gkd/blob/v1.10.4/app/src/main/kotlin/li/songe/gkd/debug/HttpService.kt#L198\n return request('snapshot?id=' + data.id).then((r) => r.json());\n }\n return jsonRpc(`getSnapshot`, data);\n },\n getScreenshot: async (data: Reqid) => {\n return bfRpc(`getScreenshot`, data);\n },\n captureSnapshot: async () => jsonRpc<Snapshot>(`captureSnapshot`),\n getSnapshots: async () => jsonRpc<Snapshot[]>(`getSnapshots`),\n updateSubscription: async (data: any) => {\n return jsonRpc(`updateSubscription`, {\n ...data,\n id: -1,\n name: '内存订阅',\n version: 0,\n });\n },\n execSelector: async (data: {\n selector: string;\n action?: string;\n fastQuery?: boolean;\n }) => {\n data = structuredClone(data);\n data.action ||= undefined;\n return jsonRpc<{ message: string; action: string; result: boolean }>(\n `execSelector`,\n data,\n );\n },\n deleteSnapshot: async (data: Reqid) => {\n return jsonRpc<{ message: string }>(`deleteSnapshot`, data);\n },\n };\n return { origin, api, serverInfo };\n};\n","<script setup lang=\"tsx\">\nimport { useDeviceApi } from '@/utils/api';\nimport { toValidURL } from '@/utils/check';\nimport { message } from '@/utils/discrete';\nimport { errorWrap } from '@/utils/error';\nimport { delay } from '@/utils/others';\nimport { screenshotStorage, snapshotStorage } from '@/utils/snapshot';\nimport { useSnapshotColumns } from '@/utils/table';\nimport { useBatchTask, useTask } from '@/utils/task';\nimport type { DataTableColumns, PaginationProps } from 'naive-ui';\nimport type { SortState } from 'naive-ui/es/data-table/src/interface';\nimport pLimit from 'p-limit';\nimport JSON5 from 'json5';\nimport ActionCard from '@/components/ActionCard.vue';\nimport BatchActionsBar from '@/components/BatchActionsBar.vue';\nimport { useBatchActions } from '@/composables/useBatchActions';\n\nconst router = useRouter();\nconst { api, origin, serverInfo } = useDeviceApi();\nconst link = useStorage(`device_link`, ``);\nconst connect = useTask(async () => {\n if (!link.value) return;\n origin.value = errorWrap(\n () => new URL(link.value.trim()),\n () => `非法设备地址`,\n ).origin;\n link.value = origin.value;\n serverInfo.value = await api.getServerInfo();\n});\n\nconst serverTitle = computed(() => {\n if (!serverInfo.value) return '未连接设备';\n const d = serverInfo.value.device;\n const g = serverInfo.value.gkdAppInfo;\n return `${d.manufacturer} Android${d.release} - GKD${g.versionName}`;\n});\n\nonMounted(async () => {\n await delay(500);\n if (toValidURL(link.value)) {\n connect.invoke();\n }\n});\n\nconst snapshots = shallowRef<Snapshot[]>([]);\nwatchEffect(async () => {\n if (!serverInfo.value) return;\n document.title = serverTitle.value;\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n subsText.value = '';\n});\n\nconst captureSnapshot = useTask(async () => {\n const snapshot = await api.captureSnapshot();\n const screenshot = await api.getScreenshot({ id: snapshot.id });\n await snapshotStorage.setItem(snapshot.id, snapshot);\n await screenshotStorage.setItem(snapshot.id, screenshot);\n message.success(`捕获并保存快照成功`);\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n});\nconst downloadAllSnapshot = useTask(async () => {\n const snapshotIds = (await api.getSnapshots()).map((s) => s.id);\n const existSnapshotIds = new Set(\n (await screenshotStorage.keys()).map((s) => parseInt(s)),\n );\n const unimportSnapshotIds = snapshotIds.filter(\n (k) => !existSnapshotIds.has(k),\n );\n if (unimportSnapshotIds.length == 0) {\n message.success(`没有新记录可导入`);\n return;\n }\n let r = 0;\n const limit = pLimit(3);\n await Promise.all(\n unimportSnapshotIds.map((snapshotId) =>\n limit(async () => {\n const [newSnapshot, newScreenshot] = await Promise.all([\n api.getSnapshot({ id: snapshotId }),\n api.getScreenshot({ id: snapshotId }),\n ] as const);\n if (!newSnapshot.nodes) return;\n await Promise.all([\n snapshotStorage.setItem(snapshotId, newSnapshot),\n screenshotStorage.setItem(snapshotId, newScreenshot),\n ]);\n r++;\n }),\n ),\n );\n message.success(`导入${r}条新记录`);\n});\n\nconst {\n activityIdCol,\n appIdCol,\n appNameCol,\n ctimeCol,\n appVersionCodeCol,\n appVersionNameCol,\n resetColWidth,\n} = useSnapshotColumns();\nconst handleSorterChange = (sorter: SortState) => {\n if (sorter.columnKey == ctimeCol.key) {\n ctimeCol.sortOrder = sorter.order;\n }\n};\nconst previewSnapshot = useBatchTask(\n async (row: Snapshot) => {\n if (!(await snapshotStorage.hasItem(row.id))) {\n const obj = await api.getSnapshot({ id: row.id });\n await snapshotStorage.setItem(row.id, obj);\n }\n if (!(await screenshotStorage.hasItem(row.id))) {\n const bf = await api.getScreenshot({ id: row.id });\n await screenshotStorage.setItem(row.id, bf);\n }\n window.open(\n router.resolve({\n name: 'snapshot',\n params: { snapshotId: row.id },\n }).href,\n );\n },\n (r) => r.id,\n);\n\nconst columns: DataTableColumns<Snapshot> = [\n {\n type: 'selection',\n },\n ctimeCol,\n appNameCol,\n appIdCol,\n appVersionCodeCol,\n appVersionNameCol,\n activityIdCol,\n {\n key: `actions`,\n title: `操作`,\n fixed: 'right',\n width: `160px`,\n render(row) {\n return (\n <ActionCard\n snapshot={row}\n showExport={false}\n showShare={false}\n deleteConfirmText={`是否确认删除? 此操作不可恢复!\\n快照ID:${row.id}`}\n onPreview={() => previewSnapshot.invoke(row)}\n previewLoading={previewSnapshot.loading[row.id]}\n onBeforeDelete={async () => await api.deleteSnapshot({ id: row.id })}\n onDelete={() => {\n snapshots.value = snapshots.value.filter((s) => s.id !== row.id);\n }}\n />\n );\n },\n },\n];\n\nconst checkedRowKeys = ref<number[]>([]);\nconst { batchDelete } = useBatchActions(checkedRowKeys, {\n beforeDeleteItem: async (id) => await api.deleteSnapshot({ id }),\n onAfterDelete: async () => {\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n },\n});\n\nconst pagination = shallowReactive<PaginationProps>({\n page: 1,\n pageSize: 50,\n showSizePicker: true,\n pageSizes: [50, 100],\n onChange: (page: number) => {\n pagination.page = page;\n },\n onUpdatePageSize: (pageSize: number) => {\n pagination.pageSize = pageSize;\n pagination.page = 1;\n },\n});\nwatch(pagination, resetColWidth);\n\nconst showSubsModel = shallowRef(false);\nconst subsText = shallowRef(``);\nconst updateSubs = useTask(async () => {\n const data = errorWrap(() => JSON5.parse(subsText.value.trim()));\n if (!data) return;\n if (data.categories || data.globalGroups || data.apps) {\n await api.updateSubscription(data);\n } else if (typeof data.id == 'string') {\n await api.updateSubscription({\n apps: [data],\n });\n } else if (Array.isArray(data) && typeof data[0].id == 'string') {\n await api.updateSubscription({\n apps: data,\n });\n } else if (typeof data.key == 'number') {\n await api.updateSubscription({\n globalGroups: [data],\n });\n } else if (Array.isArray(data) && typeof data[0].key == 'number') {\n await api.updateSubscription({\n globalGroups: data,\n });\n } else {\n message.error(`无法识别的订阅文本`);\n return;\n }\n message.success(`修改成功`);\n});\n\nconst showSelectorModel = shallowRef(false);\n\nconst actionOptions: {\n value?: string;\n label: string;\n}[] = [\n {\n label: '仅查询',\n value: ``,\n },\n {\n value: 'click',\n label: 'click',\n },\n {\n value: 'clickNode',\n label: 'clickNode',\n },\n {\n value: 'clickCenter',\n label: 'clickCenter',\n },\n {\n value: 'back',\n label: 'back',\n },\n {\n value: 'longClick',\n label: 'longClick',\n },\n {\n value: 'longClickNode',\n label: 'longClickNode',\n },\n {\n value: 'longClickCenter',\n label: 'longClickCenter',\n },\n];\nconst clickAction = shallowReactive({\n selector: ``,\n action: 'click',\n quickFind: false,\n});\nconst execSelector = useTask(async () => {\n const result = await api.execSelector({\n ...clickAction,\n fastQuery: clickAction.quickFind,\n });\n if (result.message) {\n message.success(`操作成功:` + result.message);\n return;\n }\n if (result.action) {\n message.success((result.result ? `操作成功:` : `操作失败`) + result.action);\n } else if (!result.action && result.result) {\n message.success(`查询成功`);\n }\n});\n\nconst placeholder = `\n请输入订阅文本(JSON5语法):\n示例1-更新单个应用的规则:\n{\n id: 'appId',\n groups: []\n}\n\n示例2-更新多个应用的规则:\n[\n {\n id: 'appId1',\n groups: []\n },\n {\n id: 'appId2',\n groups: []\n }\n]\n\n示例3-更新全局规则(1.7.0):\n{\n name: '全局规则-1',\n key: 0,\n rules: []\n}\n\n示例3-更新多个全局规则(1.7.0):\n[\n {\n name: '全局规则-1',\n key: 0,\n rules: []\n },\n {\n name: '全局规则-2',\n key: 1,\n rules: []\n }\n]\n\n示例4-更新整个订阅(1.7.0):\n{\n apps: [],\n globalGroups: [],\n categories: [],\n}\n`.trim();\n</script>\n<template>\n <NModal\n v-model:show=\"showSubsModel\"\n preset=\"dialog\"\n style=\"width: 800px\"\n title=\"修改内存订阅\"\n positiveText=\"确认\"\n :positiveButtonProps=\"{\n loading: updateSubs.loading,\n onClick() {\n updateSubs.invoke();\n },\n }\"\n >\n <NInput\n v-model:value=\"subsText\"\n :disabled=\"updateSubs.loading\"\n type=\"textarea\"\n class=\"gkd_code\"\n :autosize=\"{\n minRows: 20,\n maxRows: 25,\n }\"\n :placeholder=\"placeholder\"\n />\n </NModal>\n <NModal\n v-model:show=\"showSelectorModel\"\n preset=\"dialog\"\n style=\"width: 800px\"\n title=\"执行选择器\"\n positiveText=\"确认\"\n :positiveButtonProps=\"{\n loading: execSelector.loading,\n onClick() {\n execSelector.invoke();\n },\n }\"\n >\n <NInput\n v-model:value=\"clickAction.selector\"\n :disabled=\"execSelector.loading\"\n type=\"textarea\"\n class=\"gkd_code\"\n :autosize=\"{\n minRows: 4,\n maxRows: 10,\n }\"\n placeholder=\"请输入合法的选择器\"\n />\n <div h-15px />\n <NSpace>\n <NCheckbox v-model:checked=\"clickAction.quickFind\"> 快速查找 </NCheckbox>\n <a\n href=\"https://gkd.li/api/interfaces/RawCommonProps.html#quickfind\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n 查找说明\n </a>\n </NSpace>\n <div h-10px />\n <div flex gap-10px flex-items-center>\n <NSelect\n v-model:value=\"clickAction.action\"\n :options=\"actionOptions\"\n class=\"w-150px\"\n />\n <a\n href=\"https://gkd.li/api/interfaces/RawRuleProps#action\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n 操作说明\n </a>\n </div>\n </NModal>\n <div page-size flex flex-col p-10px gap-10px>\n <div flex items-center gap-24px>\n <RouterLink to=\"/\" class=\"flex ml-12px\" title=\"首页\">\n <NButton text style=\"--n-icon-size: 24px\">\n <template #icon>\n <SvgIcon name=\"home\" />\n </template>\n </NButton>\n </RouterLink>\n <NInputGroup>\n <NInput\n v-model:value=\"link\"\n placeholder=\"请输入设备地址\"\n class=\"gkd_code\"\n :style=\"{ width: `240px` }\"\n @keyup.enter=\"connect.invoke\"\n >\n <template #suffix>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 20px\"\n :loading=\"connect.loading\"\n @click=\"connect.invoke\"\n >\n <template #icon><SvgIcon name=\"refresh\" /></template>\n </NButton>\n </template>\n 刷新连接\n </NTooltip>\n </template>\n </NInput>\n\n <div\n v-if=\"serverInfo\"\n gkd_code\n pl-16px\n whitespace-nowrap\n flex\n items-center\n >\n {{ serverTitle }}\n </div>\n </NInputGroup>\n <template v-if=\"serverInfo\">\n <BatchActionsBar\n :checkedCount=\"checkedRowKeys.length\"\n :batchDelete=\"batchDelete\"\n />\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n :loading=\"captureSnapshot.loading\"\n @click=\"captureSnapshot.invoke\"\n >\n <template #icon><SvgIcon name=\"Snapshot\" /></template>\n </NButton>\n </template>\n 捕获快照\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n :loading=\"downloadAllSnapshot.loading\"\n @click=\"downloadAllSnapshot.invoke\"\n >\n <template #icon><SvgIcon name=\"Down-all\" /></template>\n </NButton>\n </template>\n 下载所有快照\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n @click=\"showSubsModel = true\"\n >\n <template #icon><SvgIcon name=\"CacheSub\" /></template>\n </NButton>\n </template>\n 修改内存订阅\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n @click=\"showSelectorModel = true\"\n >\n <template #icon><SvgIcon name=\"Exe-Sel\" /></template>\n </NButton>\n </template>\n 执行选择器\n </NTooltip>\n </template>\n </div>\n <NDataTable\n v-model:checkedRowKeys=\"checkedRowKeys\"\n striped\n flex-height\n :data=\"snapshots\"\n :columns=\"columns\"\n :pagination=\"pagination\"\n :rowKey=\"(r:Snapshot)=>r.id\"\n size=\"small\"\n class=\"flex-1\"\n :scrollX=\"1200\"\n @update:sorter=\"handleSorterChange\"\n />\n </div>\n</template>\n","<script setup lang=\"tsx\">\nimport { useDeviceApi } from '@/utils/api';\nimport { toValidURL } from '@/utils/check';\nimport { message } from '@/utils/discrete';\nimport { errorWrap } from '@/utils/error';\nimport { delay } from '@/utils/others';\nimport { screenshotStorage, snapshotStorage } from '@/utils/snapshot';\nimport { useSnapshotColumns } from '@/utils/table';\nimport { useBatchTask, useTask } from '@/utils/task';\nimport type { DataTableColumns, PaginationProps } from 'naive-ui';\nimport type { SortState } from 'naive-ui/es/data-table/src/interface';\nimport pLimit from 'p-limit';\nimport JSON5 from 'json5';\nimport ActionCard from '@/components/ActionCard.vue';\nimport BatchActionsBar from '@/components/BatchActionsBar.vue';\nimport { useBatchActions } from '@/composables/useBatchActions';\n\nconst router = useRouter();\nconst { api, origin, serverInfo } = useDeviceApi();\nconst link = useStorage(`device_link`, ``);\nconst connect = useTask(async () => {\n if (!link.value) return;\n origin.value = errorWrap(\n () => new URL(link.value.trim()),\n () => `非法设备地址`,\n ).origin;\n link.value = origin.value;\n serverInfo.value = await api.getServerInfo();\n});\n\nconst serverTitle = computed(() => {\n if (!serverInfo.value) return '未连接设备';\n const d = serverInfo.value.device;\n const g = serverInfo.value.gkdAppInfo;\n return `${d.manufacturer} Android${d.release} - GKD${g.versionName}`;\n});\n\nonMounted(async () => {\n await delay(500);\n if (toValidURL(link.value)) {\n connect.invoke();\n }\n});\n\nconst snapshots = shallowRef<Snapshot[]>([]);\nwatchEffect(async () => {\n if (!serverInfo.value) return;\n document.title = serverTitle.value;\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n subsText.value = '';\n});\n\nconst captureSnapshot = useTask(async () => {\n const snapshot = await api.captureSnapshot();\n const screenshot = await api.getScreenshot({ id: snapshot.id });\n await snapshotStorage.setItem(snapshot.id, snapshot);\n await screenshotStorage.setItem(snapshot.id, screenshot);\n message.success(`捕获并保存快照成功`);\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n});\nconst downloadAllSnapshot = useTask(async () => {\n const snapshotIds = (await api.getSnapshots()).map((s) => s.id);\n const existSnapshotIds = new Set(\n (await screenshotStorage.keys()).map((s) => parseInt(s)),\n );\n const unimportSnapshotIds = snapshotIds.filter(\n (k) => !existSnapshotIds.has(k),\n );\n if (unimportSnapshotIds.length == 0) {\n message.success(`没有新记录可导入`);\n return;\n }\n let r = 0;\n const limit = pLimit(3);\n await Promise.all(\n unimportSnapshotIds.map((snapshotId) =>\n limit(async () => {\n const [newSnapshot, newScreenshot] = await Promise.all([\n api.getSnapshot({ id: snapshotId }),\n api.getScreenshot({ id: snapshotId }),\n ] as const);\n if (!newSnapshot.nodes) return;\n await Promise.all([\n snapshotStorage.setItem(snapshotId, newSnapshot),\n screenshotStorage.setItem(snapshotId, newScreenshot),\n ]);\n r++;\n }),\n ),\n );\n message.success(`导入${r}条新记录`);\n});\n\nconst {\n activityIdCol,\n appIdCol,\n appNameCol,\n ctimeCol,\n appVersionCodeCol,\n appVersionNameCol,\n resetColWidth,\n} = useSnapshotColumns();\nconst handleSorterChange = (sorter: SortState) => {\n if (sorter.columnKey == ctimeCol.key) {\n ctimeCol.sortOrder = sorter.order;\n }\n};\nconst previewSnapshot = useBatchTask(\n async (row: Snapshot) => {\n if (!(await snapshotStorage.hasItem(row.id))) {\n const obj = await api.getSnapshot({ id: row.id });\n await snapshotStorage.setItem(row.id, obj);\n }\n if (!(await screenshotStorage.hasItem(row.id))) {\n const bf = await api.getScreenshot({ id: row.id });\n await screenshotStorage.setItem(row.id, bf);\n }\n window.open(\n router.resolve({\n name: 'snapshot',\n params: { snapshotId: row.id },\n }).href,\n );\n },\n (r) => r.id,\n);\n\nconst columns: DataTableColumns<Snapshot> = [\n {\n type: 'selection',\n },\n ctimeCol,\n appNameCol,\n appIdCol,\n appVersionCodeCol,\n appVersionNameCol,\n activityIdCol,\n {\n key: `actions`,\n title: `操作`,\n fixed: 'right',\n width: `160px`,\n render(row) {\n return (\n <ActionCard\n snapshot={row}\n showExport={false}\n showShare={false}\n deleteConfirmText={`是否确认删除? 此操作不可恢复!\\n快照ID:${row.id}`}\n onPreview={() => previewSnapshot.invoke(row)}\n previewLoading={previewSnapshot.loading[row.id]}\n onBeforeDelete={async () => await api.deleteSnapshot({ id: row.id })}\n onDelete={() => {\n snapshots.value = snapshots.value.filter((s) => s.id !== row.id);\n }}\n />\n );\n },\n },\n];\n\nconst checkedRowKeys = ref<number[]>([]);\nconst { batchDelete } = useBatchActions(checkedRowKeys, {\n beforeDeleteItem: async (id) => await api.deleteSnapshot({ id }),\n onAfterDelete: async () => {\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n },\n});\n\nconst pagination = shallowReactive<PaginationProps>({\n page: 1,\n pageSize: 50,\n showSizePicker: true,\n pageSizes: [50, 100],\n onChange: (page: number) => {\n pagination.page = page;\n },\n onUpdatePageSize: (pageSize: number) => {\n pagination.pageSize = pageSize;\n pagination.page = 1;\n },\n});\nwatch(pagination, resetColWidth);\n\nconst showSubsModel = shallowRef(false);\nconst subsText = shallowRef(``);\nconst updateSubs = useTask(async () => {\n const data = errorWrap(() => JSON5.parse(subsText.value.trim()));\n if (!data) return;\n if (data.categories || data.globalGroups || data.apps) {\n await api.updateSubscription(data);\n } else if (typeof data.id == 'string') {\n await api.updateSubscription({\n apps: [data],\n });\n } else if (Array.isArray(data) && typeof data[0].id == 'string') {\n await api.updateSubscription({\n apps: data,\n });\n } else if (typeof data.key == 'number') {\n await api.updateSubscription({\n globalGroups: [data],\n });\n } else if (Array.isArray(data) && typeof data[0].key == 'number') {\n await api.updateSubscription({\n globalGroups: data,\n });\n } else {\n message.error(`无法识别的订阅文本`);\n return;\n }\n message.success(`修改成功`);\n});\n\nconst showSelectorModel = shallowRef(false);\n\nconst actionOptions: {\n value?: string;\n label: string;\n}[] = [\n {\n label: '仅查询',\n value: ``,\n },\n {\n value: 'click',\n label: 'click',\n },\n {\n value: 'clickNode',\n label: 'clickNode',\n },\n {\n value: 'clickCenter',\n label: 'clickCenter',\n },\n {\n value: 'back',\n label: 'back',\n },\n {\n value: 'longClick',\n label: 'longClick',\n },\n {\n value: 'longClickNode',\n label: 'longClickNode',\n },\n {\n value: 'longClickCenter',\n label: 'longClickCenter',\n },\n];\nconst clickAction = shallowReactive({\n selector: ``,\n action: 'click',\n quickFind: false,\n});\nconst execSelector = useTask(async () => {\n const result = await api.execSelector({\n ...clickAction,\n fastQuery: clickAction.quickFind,\n });\n if (result.message) {\n message.success(`操作成功:` + result.message);\n return;\n }\n if (result.action) {\n message.success((result.result ? `操作成功:` : `操作失败`) + result.action);\n } else if (!result.action && result.result) {\n message.success(`查询成功`);\n }\n});\n\nconst placeholder = `\n请输入订阅文本(JSON5语法):\n示例1-更新单个应用的规则:\n{\n id: 'appId',\n groups: []\n}\n\n示例2-更新多个应用的规则:\n[\n {\n id: 'appId1',\n groups: []\n },\n {\n id: 'appId2',\n groups: []\n }\n]\n\n示例3-更新全局规则(1.7.0):\n{\n name: '全局规则-1',\n key: 0,\n rules: []\n}\n\n示例3-更新多个全局规则(1.7.0):\n[\n {\n name: '全局规则-1',\n key: 0,\n rules: []\n },\n {\n name: '全局规则-2',\n key: 1,\n rules: []\n }\n]\n\n示例4-更新整个订阅(1.7.0):\n{\n apps: [],\n globalGroups: [],\n categories: [],\n}\n`.trim();\n</script>\n<template>\n <NModal\n v-model:show=\"showSubsModel\"\n preset=\"dialog\"\n style=\"width: 800px\"\n title=\"修改内存订阅\"\n positiveText=\"确认\"\n :positiveButtonProps=\"{\n loading: updateSubs.loading,\n onClick() {\n updateSubs.invoke();\n },\n }\"\n >\n <NInput\n v-model:value=\"subsText\"\n :disabled=\"updateSubs.loading\"\n type=\"textarea\"\n class=\"gkd_code\"\n :autosize=\"{\n minRows: 20,\n maxRows: 25,\n }\"\n :placeholder=\"placeholder\"\n />\n </NModal>\n <NModal\n v-model:show=\"showSelectorModel\"\n preset=\"dialog\"\n style=\"width: 800px\"\n title=\"执行选择器\"\n positiveText=\"确认\"\n :positiveButtonProps=\"{\n loading: execSelector.loading,\n onClick() {\n execSelector.invoke();\n },\n }\"\n >\n <NInput\n v-model:value=\"clickAction.selector\"\n :disabled=\"execSelector.loading\"\n type=\"textarea\"\n class=\"gkd_code\"\n :autosize=\"{\n minRows: 4,\n maxRows: 10,\n }\"\n placeholder=\"请输入合法的选择器\"\n />\n <div h-15px />\n <NSpace>\n <NCheckbox v-model:checked=\"clickAction.quickFind\"> 快速查找 </NCheckbox>\n <a\n href=\"https://gkd.li/api/interfaces/RawCommonProps.html#quickfind\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n 查找说明\n </a>\n </NSpace>\n <div h-10px />\n <div flex gap-10px flex-items-center>\n <NSelect\n v-model:value=\"clickAction.action\"\n :options=\"actionOptions\"\n class=\"w-150px\"\n />\n <a\n href=\"https://gkd.li/api/interfaces/RawRuleProps#action\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n 操作说明\n </a>\n </div>\n </NModal>\n <div page-size flex flex-col p-10px gap-10px>\n <div flex items-center gap-24px>\n <RouterLink to=\"/\" class=\"flex ml-12px\" title=\"首页\">\n <NButton text style=\"--n-icon-size: 24px\">\n <template #icon>\n <SvgIcon name=\"home\" />\n </template>\n </NButton>\n </RouterLink>\n <NInputGroup>\n <NInput\n v-model:value=\"link\"\n placeholder=\"请输入设备地址\"\n class=\"gkd_code\"\n :style=\"{ width: `240px` }\"\n @keyup.enter=\"connect.invoke\"\n >\n <template #suffix>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 20px\"\n :loading=\"connect.loading\"\n @click=\"connect.invoke\"\n >\n <template #icon><SvgIcon name=\"refresh\" /></template>\n </NButton>\n </template>\n 刷新连接\n </NTooltip>\n </template>\n </NInput>\n\n <div\n v-if=\"serverInfo\"\n gkd_code\n pl-16px\n whitespace-nowrap\n flex\n items-center\n >\n {{ serverTitle }}\n </div>\n </NInputGroup>\n <template v-if=\"serverInfo\">\n <BatchActionsBar\n :checkedCount=\"checkedRowKeys.length\"\n :batchDelete=\"batchDelete\"\n />\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n :loading=\"captureSnapshot.loading\"\n @click=\"captureSnapshot.invoke\"\n >\n <template #icon><SvgIcon name=\"Snapshot\" /></template>\n </NButton>\n </template>\n 捕获快照\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n :loading=\"downloadAllSnapshot.loading\"\n @click=\"downloadAllSnapshot.invoke\"\n >\n <template #icon><SvgIcon name=\"Down-all\" /></template>\n </NButton>\n </template>\n 下载所有快照\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n @click=\"showSubsModel = true\"\n >\n <template #icon><SvgIcon name=\"CacheSub\" /></template>\n </NButton>\n </template>\n 修改内存订阅\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n @click=\"showSelectorModel = true\"\n >\n <template #icon><SvgIcon name=\"Exe-Sel\" /></template>\n </NButton>\n </template>\n 执行选择器\n </NTooltip>\n </template>\n </div>\n <NDataTable\n v-model:checkedRowKeys=\"checkedRowKeys\"\n striped\n flex-height\n :data=\"snapshots\"\n :columns=\"columns\"\n :pagination=\"pagination\"\n :rowKey=\"(r:Snapshot)=>r.id\"\n size=\"small\"\n class=\"flex-1\"\n :scrollX=\"1200\"\n @update:sorter=\"handleSorterChange\"\n />\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"DevicePage-A7gjew_b.js","names":[],"sources":["../../src/utils/api.ts","../../src/views/DevicePage.vue","../../src/views/DevicePage.vue"],"sourcesContent":["import { message } from './discrete';\nimport { enhanceFetch } from './fetch';\nimport type { GmXhrOptions } from './gm';\n\ninterface Reqid {\n id: number;\n}\n\nexport const useDeviceApi = (initOrigin?: string) => {\n const origin = shallowRef(initOrigin);\n const serverInfo = shallowRef<ServerInfo>();\n const request = async (\n name: string,\n init?: RequestInit,\n xhrDetails?: (arg: GmXhrOptions) => GmXhrOptions,\n ) => {\n if (!origin.value) {\n throw new Error(`origin must exist`);\n }\n const u = new URL(`/api/` + name, origin.value);\n const response = await enhanceFetch(u, init, xhrDetails).catch((e) => {\n message.error(`网络错误:` + name);\n throw e;\n });\n if (!response.ok) {\n message.error(`接口错误:` + name + `:` + response.status);\n throw response;\n }\n if (response.headers.get(`Content-Type`)?.includes(`application/json`)) {\n const error = (await response.clone().json()) as RpcError;\n if (error.__error) {\n message.error(error.message);\n throw response;\n }\n }\n return response;\n };\n const baseRpc = async (\n name: string,\n data: object = {},\n xhrDetails?: (arg: GmXhrOptions) => GmXhrOptions,\n ) => {\n return request(\n name,\n {\n method: 'post',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n },\n xhrDetails,\n );\n };\n const jsonRpc = async <T>(name: string, data: object = {}): Promise<T> => {\n return baseRpc(name, data).then((r) => r.json());\n };\n const bfRpc = async (\n name: string,\n data: object = {},\n ): Promise<ArrayBuffer> => {\n return baseRpc(name, data, (v) => {\n // must set responseType to get binary data\n v.responseType = 'arraybuffer';\n return v;\n }).then((r) => r.arrayBuffer());\n };\n const api = {\n getServerInfo: async () => jsonRpc<ServerInfo>(`getServerInfo`),\n getSnapshot: async (data: Reqid): Promise<Snapshot> => {\n if (serverInfo.value?.gkdAppInfo?.versionName === '1.10.4') {\n // 兼容旧版本 BUG\n // https://github.com/gkd-kit/gkd/blob/v1.10.4/app/src/main/kotlin/li/songe/gkd/debug/HttpService.kt#L198\n return request('snapshot?id=' + data.id).then((r) => r.json());\n }\n return jsonRpc(`getSnapshot`, data);\n },\n getScreenshot: async (data: Reqid) => {\n return bfRpc(`getScreenshot`, data);\n },\n captureSnapshot: async () => jsonRpc<Snapshot>(`captureSnapshot`),\n getSnapshots: async () => jsonRpc<Snapshot[]>(`getSnapshots`),\n updateSubscription: async (data: any) => {\n return jsonRpc(`updateSubscription`, {\n ...data,\n id: -1,\n name: '内存订阅',\n version: 0,\n });\n },\n execSelector: async (data: {\n selector: string;\n action?: string;\n fastQuery?: boolean;\n }) => {\n data = structuredClone(data);\n data.action ||= undefined;\n return jsonRpc<{ message: string; action: string; result: boolean }>(\n `execSelector`,\n data,\n );\n },\n deleteSnapshot: async (data: Reqid) => {\n return jsonRpc<{ message: string }>(`deleteSnapshot`, data);\n },\n };\n return { origin, api, serverInfo };\n};\n","<script setup lang=\"tsx\">\nimport { useDeviceApi } from '@/utils/api';\nimport { toValidURL } from '@/utils/check';\nimport { message } from '@/utils/discrete';\nimport { errorWrap } from '@/utils/error';\nimport { delay } from '@/utils/others';\nimport { screenshotStorage, snapshotStorage } from '@/utils/snapshot';\nimport { useSnapshotColumns } from '@/utils/table';\nimport { useBatchTask, useTask } from '@/utils/task';\nimport type { DataTableColumns, PaginationProps } from 'naive-ui';\nimport type { SortState } from 'naive-ui/es/data-table/src/interface';\nimport pLimit from 'p-limit';\nimport JSON5 from 'json5';\nimport ActionCard from '@/components/ActionCard.vue';\nimport BatchActionsBar from '@/components/BatchActionsBar.vue';\nimport { useBatchActions } from '@/composables/useBatchActions';\n\nconst router = useRouter();\nconst { api, origin, serverInfo } = useDeviceApi();\nconst link = useStorage(`device_link`, ``);\nconst connect = useTask(async () => {\n if (!link.value) return;\n origin.value = errorWrap(\n () => new URL(link.value.trim()),\n () => `非法设备地址`,\n ).origin;\n link.value = origin.value;\n serverInfo.value = await api.getServerInfo();\n});\n\nconst serverTitle = computed(() => {\n if (!serverInfo.value) return '未连接设备';\n const d = serverInfo.value.device;\n const g = serverInfo.value.gkdAppInfo;\n return `${d.manufacturer} Android${d.release} - GKD${g.versionName}`;\n});\n\nonMounted(async () => {\n await delay(500);\n if (toValidURL(link.value)) {\n connect.invoke();\n }\n});\n\nconst snapshots = shallowRef<Snapshot[]>([]);\nwatchEffect(async () => {\n if (!serverInfo.value) return;\n document.title = serverTitle.value;\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n subsText.value = '';\n});\n\nconst captureSnapshot = useTask(async () => {\n const snapshot = await api.captureSnapshot();\n const screenshot = await api.getScreenshot({ id: snapshot.id });\n await snapshotStorage.setItem(snapshot.id, snapshot);\n await screenshotStorage.setItem(snapshot.id, screenshot);\n message.success(`捕获并保存快照成功`);\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n});\nconst downloadAllSnapshot = useTask(async () => {\n const snapshotIds = (await api.getSnapshots()).map((s) => s.id);\n const existSnapshotIds = new Set(\n (await screenshotStorage.keys()).map((s) => parseInt(s)),\n );\n const unimportSnapshotIds = snapshotIds.filter(\n (k) => !existSnapshotIds.has(k),\n );\n if (unimportSnapshotIds.length == 0) {\n message.success(`没有新记录可导入`);\n return;\n }\n let r = 0;\n const limit = pLimit(3);\n await Promise.all(\n unimportSnapshotIds.map((snapshotId) =>\n limit(async () => {\n const [newSnapshot, newScreenshot] = await Promise.all([\n api.getSnapshot({ id: snapshotId }),\n api.getScreenshot({ id: snapshotId }),\n ] as const);\n if (!newSnapshot.nodes) return;\n await Promise.all([\n snapshotStorage.setItem(snapshotId, newSnapshot),\n screenshotStorage.setItem(snapshotId, newScreenshot),\n ]);\n r++;\n }),\n ),\n );\n message.success(`导入${r}条新记录`);\n});\n\nconst {\n activityIdCol,\n appIdCol,\n appNameCol,\n ctimeCol,\n appVersionCodeCol,\n appVersionNameCol,\n resetColWidth,\n} = useSnapshotColumns();\nconst handleSorterChange = (sorter: SortState) => {\n if (sorter.columnKey == ctimeCol.key) {\n ctimeCol.sortOrder = sorter.order;\n }\n};\nconst previewSnapshot = useBatchTask(\n async (row: Snapshot) => {\n if (!(await snapshotStorage.hasItem(row.id))) {\n const obj = await api.getSnapshot({ id: row.id });\n await snapshotStorage.setItem(row.id, obj);\n }\n if (!(await screenshotStorage.hasItem(row.id))) {\n const bf = await api.getScreenshot({ id: row.id });\n await screenshotStorage.setItem(row.id, bf);\n }\n window.open(\n router.resolve({\n name: 'snapshot',\n params: { snapshotId: row.id },\n }).href,\n );\n },\n (r) => r.id,\n);\n\nconst columns: DataTableColumns<Snapshot> = [\n {\n type: 'selection',\n },\n ctimeCol,\n appNameCol,\n appIdCol,\n appVersionCodeCol,\n appVersionNameCol,\n activityIdCol,\n {\n key: `actions`,\n title: `操作`,\n fixed: 'right',\n width: `160px`,\n render(row) {\n return (\n <ActionCard\n snapshot={row}\n showExport={false}\n showShare={false}\n deleteConfirmText={`是否确认删除? 此操作不可恢复!\\n快照ID:${row.id}`}\n onPreview={() => previewSnapshot.invoke(row)}\n previewLoading={previewSnapshot.loading[row.id]}\n onBeforeDelete={async () => await api.deleteSnapshot({ id: row.id })}\n onDelete={() => {\n snapshots.value = snapshots.value.filter((s) => s.id !== row.id);\n }}\n />\n );\n },\n },\n];\n\nconst checkedRowKeys = ref<number[]>([]);\nconst { batchDelete } = useBatchActions(checkedRowKeys, {\n beforeDeleteItem: async (id) => await api.deleteSnapshot({ id }),\n onAfterDelete: async () => {\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n },\n});\n\nconst pagination = shallowReactive<PaginationProps>({\n page: 1,\n pageSize: 50,\n showSizePicker: true,\n pageSizes: [50, 100],\n onChange: (page: number) => {\n pagination.page = page;\n },\n onUpdatePageSize: (pageSize: number) => {\n pagination.pageSize = pageSize;\n pagination.page = 1;\n },\n});\nwatch(pagination, resetColWidth);\n\nconst showSubsModel = shallowRef(false);\nconst subsText = shallowRef(``);\nconst updateSubs = useTask(async () => {\n const data = errorWrap(() => JSON5.parse(subsText.value.trim()));\n if (!data) return;\n if (data.categories || data.globalGroups || data.apps) {\n await api.updateSubscription(data);\n } else if (typeof data.id == 'string') {\n await api.updateSubscription({\n apps: [data],\n });\n } else if (Array.isArray(data) && typeof data[0].id == 'string') {\n await api.updateSubscription({\n apps: data,\n });\n } else if (typeof data.key == 'number') {\n await api.updateSubscription({\n globalGroups: [data],\n });\n } else if (Array.isArray(data) && typeof data[0].key == 'number') {\n await api.updateSubscription({\n globalGroups: data,\n });\n } else {\n message.error(`无法识别的订阅文本`);\n return;\n }\n message.success(`修改成功`);\n});\n\nconst showSelectorModel = shallowRef(false);\n\nconst actionOptions: {\n value?: string;\n label: string;\n}[] = [\n {\n label: '仅查询',\n value: ``,\n },\n {\n value: 'click',\n label: 'click',\n },\n {\n value: 'clickNode',\n label: 'clickNode',\n },\n {\n value: 'clickCenter',\n label: 'clickCenter',\n },\n {\n value: 'back',\n label: 'back',\n },\n {\n value: 'longClick',\n label: 'longClick',\n },\n {\n value: 'longClickNode',\n label: 'longClickNode',\n },\n {\n value: 'longClickCenter',\n label: 'longClickCenter',\n },\n];\nconst clickAction = shallowReactive({\n selector: ``,\n action: 'click',\n quickFind: false,\n});\nconst execSelector = useTask(async () => {\n const result = await api.execSelector({\n ...clickAction,\n fastQuery: clickAction.quickFind,\n });\n if (result.message) {\n message.success(`操作成功:` + result.message);\n return;\n }\n if (result.action) {\n message.success((result.result ? `操作成功:` : `操作失败`) + result.action);\n } else if (!result.action && result.result) {\n message.success(`查询成功`);\n }\n});\n\nconst placeholder = `\n请输入订阅文本(JSON5语法):\n示例1-更新单个应用的规则:\n{\n id: 'appId',\n groups: []\n}\n\n示例2-更新多个应用的规则:\n[\n {\n id: 'appId1',\n groups: []\n },\n {\n id: 'appId2',\n groups: []\n }\n]\n\n示例3-更新全局规则(1.7.0):\n{\n name: '全局规则-1',\n key: 0,\n rules: []\n}\n\n示例3-更新多个全局规则(1.7.0):\n[\n {\n name: '全局规则-1',\n key: 0,\n rules: []\n },\n {\n name: '全局规则-2',\n key: 1,\n rules: []\n }\n]\n\n示例4-更新整个订阅(1.7.0):\n{\n apps: [],\n globalGroups: [],\n categories: [],\n}\n`.trim();\n</script>\n<template>\n <NModal\n v-model:show=\"showSubsModel\"\n preset=\"dialog\"\n style=\"width: 800px\"\n title=\"修改内存订阅\"\n positiveText=\"确认\"\n :positiveButtonProps=\"{\n loading: updateSubs.loading,\n onClick() {\n updateSubs.invoke();\n },\n }\"\n >\n <NInput\n v-model:value=\"subsText\"\n :disabled=\"updateSubs.loading\"\n type=\"textarea\"\n class=\"gkd_code\"\n :autosize=\"{\n minRows: 20,\n maxRows: 25,\n }\"\n :placeholder=\"placeholder\"\n />\n </NModal>\n <NModal\n v-model:show=\"showSelectorModel\"\n preset=\"dialog\"\n style=\"width: 800px\"\n title=\"执行选择器\"\n positiveText=\"确认\"\n :positiveButtonProps=\"{\n loading: execSelector.loading,\n onClick() {\n execSelector.invoke();\n },\n }\"\n >\n <NInput\n v-model:value=\"clickAction.selector\"\n :disabled=\"execSelector.loading\"\n type=\"textarea\"\n class=\"gkd_code\"\n :autosize=\"{\n minRows: 4,\n maxRows: 10,\n }\"\n placeholder=\"请输入合法的选择器\"\n />\n <div h-15px />\n <NSpace>\n <NCheckbox v-model:checked=\"clickAction.quickFind\"> 快速查找 </NCheckbox>\n <a\n href=\"https://gkd.li/api/interfaces/RawCommonProps.html#quickfind\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n 查找说明\n </a>\n </NSpace>\n <div h-10px />\n <div flex gap-10px flex-items-center>\n <NSelect\n v-model:value=\"clickAction.action\"\n :options=\"actionOptions\"\n class=\"w-150px\"\n />\n <a\n href=\"https://gkd.li/api/interfaces/RawRuleProps#action\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n 操作说明\n </a>\n </div>\n </NModal>\n <div page-size flex flex-col p-10px gap-10px>\n <div flex items-center gap-24px>\n <RouterLink to=\"/\" class=\"flex ml-12px\" title=\"首页\">\n <NButton text style=\"--n-icon-size: 24px\">\n <template #icon>\n <SvgIcon name=\"home\" />\n </template>\n </NButton>\n </RouterLink>\n <NInputGroup>\n <NInput\n v-model:value=\"link\"\n placeholder=\"请输入设备地址\"\n class=\"gkd_code\"\n :style=\"{ width: `240px` }\"\n @keyup.enter=\"connect.invoke\"\n >\n <template #suffix>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 20px\"\n :loading=\"connect.loading\"\n @click=\"connect.invoke\"\n >\n <template #icon><SvgIcon name=\"refresh\" /></template>\n </NButton>\n </template>\n 刷新连接\n </NTooltip>\n </template>\n </NInput>\n\n <div\n v-if=\"serverInfo\"\n gkd_code\n pl-16px\n whitespace-nowrap\n flex\n items-center\n >\n {{ serverTitle }}\n </div>\n </NInputGroup>\n <template v-if=\"serverInfo\">\n <BatchActionsBar\n :checkedCount=\"checkedRowKeys.length\"\n :batchDelete=\"batchDelete\"\n />\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n :loading=\"captureSnapshot.loading\"\n @click=\"captureSnapshot.invoke\"\n >\n <template #icon><SvgIcon name=\"Snapshot\" /></template>\n </NButton>\n </template>\n 捕获快照\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n :loading=\"downloadAllSnapshot.loading\"\n @click=\"downloadAllSnapshot.invoke\"\n >\n <template #icon><SvgIcon name=\"Down-all\" /></template>\n </NButton>\n </template>\n 下载所有快照\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n @click=\"showSubsModel = true\"\n >\n <template #icon><SvgIcon name=\"CacheSub\" /></template>\n </NButton>\n </template>\n 修改内存订阅\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n @click=\"showSelectorModel = true\"\n >\n <template #icon><SvgIcon name=\"Exe-Sel\" /></template>\n </NButton>\n </template>\n 执行选择器\n </NTooltip>\n </template>\n </div>\n <NDataTable\n v-model:checkedRowKeys=\"checkedRowKeys\"\n striped\n flex-height\n :data=\"snapshots\"\n :columns=\"columns\"\n :pagination=\"pagination\"\n :rowKey=\"(r:Snapshot)=>r.id\"\n size=\"small\"\n class=\"flex-1\"\n :scrollX=\"1200\"\n @update:sorter=\"handleSorterChange\"\n />\n </div>\n</template>\n","<script setup lang=\"tsx\">\nimport { useDeviceApi } from '@/utils/api';\nimport { toValidURL } from '@/utils/check';\nimport { message } from '@/utils/discrete';\nimport { errorWrap } from '@/utils/error';\nimport { delay } from '@/utils/others';\nimport { screenshotStorage, snapshotStorage } from '@/utils/snapshot';\nimport { useSnapshotColumns } from '@/utils/table';\nimport { useBatchTask, useTask } from '@/utils/task';\nimport type { DataTableColumns, PaginationProps } from 'naive-ui';\nimport type { SortState } from 'naive-ui/es/data-table/src/interface';\nimport pLimit from 'p-limit';\nimport JSON5 from 'json5';\nimport ActionCard from '@/components/ActionCard.vue';\nimport BatchActionsBar from '@/components/BatchActionsBar.vue';\nimport { useBatchActions } from '@/composables/useBatchActions';\n\nconst router = useRouter();\nconst { api, origin, serverInfo } = useDeviceApi();\nconst link = useStorage(`device_link`, ``);\nconst connect = useTask(async () => {\n if (!link.value) return;\n origin.value = errorWrap(\n () => new URL(link.value.trim()),\n () => `非法设备地址`,\n ).origin;\n link.value = origin.value;\n serverInfo.value = await api.getServerInfo();\n});\n\nconst serverTitle = computed(() => {\n if (!serverInfo.value) return '未连接设备';\n const d = serverInfo.value.device;\n const g = serverInfo.value.gkdAppInfo;\n return `${d.manufacturer} Android${d.release} - GKD${g.versionName}`;\n});\n\nonMounted(async () => {\n await delay(500);\n if (toValidURL(link.value)) {\n connect.invoke();\n }\n});\n\nconst snapshots = shallowRef<Snapshot[]>([]);\nwatchEffect(async () => {\n if (!serverInfo.value) return;\n document.title = serverTitle.value;\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n subsText.value = '';\n});\n\nconst captureSnapshot = useTask(async () => {\n const snapshot = await api.captureSnapshot();\n const screenshot = await api.getScreenshot({ id: snapshot.id });\n await snapshotStorage.setItem(snapshot.id, snapshot);\n await screenshotStorage.setItem(snapshot.id, screenshot);\n message.success(`捕获并保存快照成功`);\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n});\nconst downloadAllSnapshot = useTask(async () => {\n const snapshotIds = (await api.getSnapshots()).map((s) => s.id);\n const existSnapshotIds = new Set(\n (await screenshotStorage.keys()).map((s) => parseInt(s)),\n );\n const unimportSnapshotIds = snapshotIds.filter(\n (k) => !existSnapshotIds.has(k),\n );\n if (unimportSnapshotIds.length == 0) {\n message.success(`没有新记录可导入`);\n return;\n }\n let r = 0;\n const limit = pLimit(3);\n await Promise.all(\n unimportSnapshotIds.map((snapshotId) =>\n limit(async () => {\n const [newSnapshot, newScreenshot] = await Promise.all([\n api.getSnapshot({ id: snapshotId }),\n api.getScreenshot({ id: snapshotId }),\n ] as const);\n if (!newSnapshot.nodes) return;\n await Promise.all([\n snapshotStorage.setItem(snapshotId, newSnapshot),\n screenshotStorage.setItem(snapshotId, newScreenshot),\n ]);\n r++;\n }),\n ),\n );\n message.success(`导入${r}条新记录`);\n});\n\nconst {\n activityIdCol,\n appIdCol,\n appNameCol,\n ctimeCol,\n appVersionCodeCol,\n appVersionNameCol,\n resetColWidth,\n} = useSnapshotColumns();\nconst handleSorterChange = (sorter: SortState) => {\n if (sorter.columnKey == ctimeCol.key) {\n ctimeCol.sortOrder = sorter.order;\n }\n};\nconst previewSnapshot = useBatchTask(\n async (row: Snapshot) => {\n if (!(await snapshotStorage.hasItem(row.id))) {\n const obj = await api.getSnapshot({ id: row.id });\n await snapshotStorage.setItem(row.id, obj);\n }\n if (!(await screenshotStorage.hasItem(row.id))) {\n const bf = await api.getScreenshot({ id: row.id });\n await screenshotStorage.setItem(row.id, bf);\n }\n window.open(\n router.resolve({\n name: 'snapshot',\n params: { snapshotId: row.id },\n }).href,\n );\n },\n (r) => r.id,\n);\n\nconst columns: DataTableColumns<Snapshot> = [\n {\n type: 'selection',\n },\n ctimeCol,\n appNameCol,\n appIdCol,\n appVersionCodeCol,\n appVersionNameCol,\n activityIdCol,\n {\n key: `actions`,\n title: `操作`,\n fixed: 'right',\n width: `160px`,\n render(row) {\n return (\n <ActionCard\n snapshot={row}\n showExport={false}\n showShare={false}\n deleteConfirmText={`是否确认删除? 此操作不可恢复!\\n快照ID:${row.id}`}\n onPreview={() => previewSnapshot.invoke(row)}\n previewLoading={previewSnapshot.loading[row.id]}\n onBeforeDelete={async () => await api.deleteSnapshot({ id: row.id })}\n onDelete={() => {\n snapshots.value = snapshots.value.filter((s) => s.id !== row.id);\n }}\n />\n );\n },\n },\n];\n\nconst checkedRowKeys = ref<number[]>([]);\nconst { batchDelete } = useBatchActions(checkedRowKeys, {\n beforeDeleteItem: async (id) => await api.deleteSnapshot({ id }),\n onAfterDelete: async () => {\n const result = await api.getSnapshots();\n result.sort((a, b) => b.id - a.id);\n snapshots.value = result;\n },\n});\n\nconst pagination = shallowReactive<PaginationProps>({\n page: 1,\n pageSize: 50,\n showSizePicker: true,\n pageSizes: [50, 100],\n onChange: (page: number) => {\n pagination.page = page;\n },\n onUpdatePageSize: (pageSize: number) => {\n pagination.pageSize = pageSize;\n pagination.page = 1;\n },\n});\nwatch(pagination, resetColWidth);\n\nconst showSubsModel = shallowRef(false);\nconst subsText = shallowRef(``);\nconst updateSubs = useTask(async () => {\n const data = errorWrap(() => JSON5.parse(subsText.value.trim()));\n if (!data) return;\n if (data.categories || data.globalGroups || data.apps) {\n await api.updateSubscription(data);\n } else if (typeof data.id == 'string') {\n await api.updateSubscription({\n apps: [data],\n });\n } else if (Array.isArray(data) && typeof data[0].id == 'string') {\n await api.updateSubscription({\n apps: data,\n });\n } else if (typeof data.key == 'number') {\n await api.updateSubscription({\n globalGroups: [data],\n });\n } else if (Array.isArray(data) && typeof data[0].key == 'number') {\n await api.updateSubscription({\n globalGroups: data,\n });\n } else {\n message.error(`无法识别的订阅文本`);\n return;\n }\n message.success(`修改成功`);\n});\n\nconst showSelectorModel = shallowRef(false);\n\nconst actionOptions: {\n value?: string;\n label: string;\n}[] = [\n {\n label: '仅查询',\n value: ``,\n },\n {\n value: 'click',\n label: 'click',\n },\n {\n value: 'clickNode',\n label: 'clickNode',\n },\n {\n value: 'clickCenter',\n label: 'clickCenter',\n },\n {\n value: 'back',\n label: 'back',\n },\n {\n value: 'longClick',\n label: 'longClick',\n },\n {\n value: 'longClickNode',\n label: 'longClickNode',\n },\n {\n value: 'longClickCenter',\n label: 'longClickCenter',\n },\n];\nconst clickAction = shallowReactive({\n selector: ``,\n action: 'click',\n quickFind: false,\n});\nconst execSelector = useTask(async () => {\n const result = await api.execSelector({\n ...clickAction,\n fastQuery: clickAction.quickFind,\n });\n if (result.message) {\n message.success(`操作成功:` + result.message);\n return;\n }\n if (result.action) {\n message.success((result.result ? `操作成功:` : `操作失败`) + result.action);\n } else if (!result.action && result.result) {\n message.success(`查询成功`);\n }\n});\n\nconst placeholder = `\n请输入订阅文本(JSON5语法):\n示例1-更新单个应用的规则:\n{\n id: 'appId',\n groups: []\n}\n\n示例2-更新多个应用的规则:\n[\n {\n id: 'appId1',\n groups: []\n },\n {\n id: 'appId2',\n groups: []\n }\n]\n\n示例3-更新全局规则(1.7.0):\n{\n name: '全局规则-1',\n key: 0,\n rules: []\n}\n\n示例3-更新多个全局规则(1.7.0):\n[\n {\n name: '全局规则-1',\n key: 0,\n rules: []\n },\n {\n name: '全局规则-2',\n key: 1,\n rules: []\n }\n]\n\n示例4-更新整个订阅(1.7.0):\n{\n apps: [],\n globalGroups: [],\n categories: [],\n}\n`.trim();\n</script>\n<template>\n <NModal\n v-model:show=\"showSubsModel\"\n preset=\"dialog\"\n style=\"width: 800px\"\n title=\"修改内存订阅\"\n positiveText=\"确认\"\n :positiveButtonProps=\"{\n loading: updateSubs.loading,\n onClick() {\n updateSubs.invoke();\n },\n }\"\n >\n <NInput\n v-model:value=\"subsText\"\n :disabled=\"updateSubs.loading\"\n type=\"textarea\"\n class=\"gkd_code\"\n :autosize=\"{\n minRows: 20,\n maxRows: 25,\n }\"\n :placeholder=\"placeholder\"\n />\n </NModal>\n <NModal\n v-model:show=\"showSelectorModel\"\n preset=\"dialog\"\n style=\"width: 800px\"\n title=\"执行选择器\"\n positiveText=\"确认\"\n :positiveButtonProps=\"{\n loading: execSelector.loading,\n onClick() {\n execSelector.invoke();\n },\n }\"\n >\n <NInput\n v-model:value=\"clickAction.selector\"\n :disabled=\"execSelector.loading\"\n type=\"textarea\"\n class=\"gkd_code\"\n :autosize=\"{\n minRows: 4,\n maxRows: 10,\n }\"\n placeholder=\"请输入合法的选择器\"\n />\n <div h-15px />\n <NSpace>\n <NCheckbox v-model:checked=\"clickAction.quickFind\"> 快速查找 </NCheckbox>\n <a\n href=\"https://gkd.li/api/interfaces/RawCommonProps.html#quickfind\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n 查找说明\n </a>\n </NSpace>\n <div h-10px />\n <div flex gap-10px flex-items-center>\n <NSelect\n v-model:value=\"clickAction.action\"\n :options=\"actionOptions\"\n class=\"w-150px\"\n />\n <a\n href=\"https://gkd.li/api/interfaces/RawRuleProps#action\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n 操作说明\n </a>\n </div>\n </NModal>\n <div page-size flex flex-col p-10px gap-10px>\n <div flex items-center gap-24px>\n <RouterLink to=\"/\" class=\"flex ml-12px\" title=\"首页\">\n <NButton text style=\"--n-icon-size: 24px\">\n <template #icon>\n <SvgIcon name=\"home\" />\n </template>\n </NButton>\n </RouterLink>\n <NInputGroup>\n <NInput\n v-model:value=\"link\"\n placeholder=\"请输入设备地址\"\n class=\"gkd_code\"\n :style=\"{ width: `240px` }\"\n @keyup.enter=\"connect.invoke\"\n >\n <template #suffix>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 20px\"\n :loading=\"connect.loading\"\n @click=\"connect.invoke\"\n >\n <template #icon><SvgIcon name=\"refresh\" /></template>\n </NButton>\n </template>\n 刷新连接\n </NTooltip>\n </template>\n </NInput>\n\n <div\n v-if=\"serverInfo\"\n gkd_code\n pl-16px\n whitespace-nowrap\n flex\n items-center\n >\n {{ serverTitle }}\n </div>\n </NInputGroup>\n <template v-if=\"serverInfo\">\n <BatchActionsBar\n :checkedCount=\"checkedRowKeys.length\"\n :batchDelete=\"batchDelete\"\n />\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n :loading=\"captureSnapshot.loading\"\n @click=\"captureSnapshot.invoke\"\n >\n <template #icon><SvgIcon name=\"Snapshot\" /></template>\n </NButton>\n </template>\n 捕获快照\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n :loading=\"downloadAllSnapshot.loading\"\n @click=\"downloadAllSnapshot.invoke\"\n >\n <template #icon><SvgIcon name=\"Down-all\" /></template>\n </NButton>\n </template>\n 下载所有快照\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n @click=\"showSubsModel = true\"\n >\n <template #icon><SvgIcon name=\"CacheSub\" /></template>\n </NButton>\n </template>\n 修改内存订阅\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <NButton\n text\n style=\"--n-icon-size: 24px\"\n @click=\"showSelectorModel = true\"\n >\n <template #icon><SvgIcon name=\"Exe-Sel\" /></template>\n </NButton>\n </template>\n 执行选择器\n </NTooltip>\n </template>\n </div>\n <NDataTable\n v-model:checkedRowKeys=\"checkedRowKeys\"\n striped\n flex-height\n :data=\"snapshots\"\n :columns=\"columns\"\n :pagination=\"pagination\"\n :rowKey=\"(r:Snapshot)=>r.id\"\n size=\"small\"\n class=\"flex-1\"\n :scrollX=\"1200\"\n @update:sorter=\"handleSorterChange\"\n />\n </div>\n</template>\n"],"mappings":"6zBAQA,IAAa,GAAgB,GAAwB,CACnD,IAAM,EAAS,EAAW,CAAU,EAC9B,EAAa,EAAuB,EACpC,EAAU,MACd,EACA,EACA,IACG,OACH,GAAI,CAAC,EAAO,MACV,MAAU,MAAM,mBAAmB,EAGrC,IAAM,EAAW,MAAM,EAAa,IADtB,IAAI,QAAU,EAAM,EAAO,KACL,EAAG,EAAM,CAAU,EAAE,MAAO,GAAM,CAEpE,MADA,EAAQ,MAAM,QAAU,CAAI,EACtB,CACR,CAAC,EACD,GAAI,CAAC,EAAS,GAEZ,MADA,EAAQ,MAAM,QAAU,EAAO,IAAM,EAAS,MAAM,EAC9C,EAER,IAAA,EAAI,EAAS,QAAQ,IAAI,cAAc,IAAA,MAAA,EAAG,SAAS,kBAAkB,EAAG,CACtE,IAAM,EAAS,MAAM,EAAS,MAAM,EAAE,KAAK,EAC3C,GAAI,EAAM,QAER,MADA,EAAQ,MAAM,EAAM,OAAO,EACrB,CAEV,CACA,OAAO,CACT,EACM,EAAU,MACd,EACA,EAAe,CAAC,EAChB,IAEO,EACL,EACA,CACE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAClB,EACA,KAAM,KAAK,UAAU,CAAI,CAC3B,EACA,CACF,EAEI,EAAU,MAAU,EAAc,EAAe,CAAC,IAC/C,EAAQ,EAAM,CAAI,EAAE,KAAM,GAAM,EAAE,KAAK,CAAC,EAE3C,EAAQ,MACZ,EACA,EAAe,CAAC,IAET,EAAQ,EAAM,EAAO,IAE1B,EAAE,aAAe,cACV,EACR,EAAE,KAAM,GAAM,EAAE,YAAY,CAAC,EAyChC,MAAO,CAAE,SAAQ,IAAA,CAtCf,cAAe,SAAY,EAAoB,eAAe,EAC9D,YAAa,KAAO,IAAmC,OAMrD,QALA,EAAI,EAAW,QAAA,OAAA,EAAA,EAAO,aAAA,KAAA,IAAA,GAAA,EAAY,eAAgB,SAGzC,EAAQ,eAAiB,EAAK,EAAE,EAAE,KAAM,GAAM,EAAE,KAAK,CAAC,EAExD,EAAQ,cAAe,CAAI,CACpC,EACA,cAAe,KAAO,IACb,EAAM,gBAAiB,CAAI,EAEpC,gBAAiB,SAAY,EAAkB,iBAAiB,EAChE,aAAc,SAAY,EAAoB,cAAc,EAC5D,mBAAoB,KAAO,IAClB,EAAQ,qBAAsB,CACnC,GAAG,EACH,GAAI,GACJ,KAAM,OACN,QAAS,CACX,CAAC,EAEH,aAAc,KAAO,KAKnB,EAAO,gBAAgB,CAAI,EAC3B,EAAK,SAAW,IAAA,GACT,EACL,eACA,CACF,GAEF,eAAgB,KAAO,IACd,EAA6B,iBAAkB,CAAI,CAG7C,EAAK,YAAW,CACnC,sSC1FA,IAAM,EAAS,GAAU,EACnB,CAAE,MAAK,SAAQ,cAAe,GAAa,EAC3C,EAAO,EAAW,cAAe,EAAE,EACnC,EAAU,EAAQ,SAAY,CAC7B,EAAK,QACV,EAAO,MAAQ,MACP,IAAI,IAAI,EAAK,MAAM,KAAK,CAAC,MACzB,QACR,EAAE,OACF,EAAK,MAAQ,EAAO,MACpB,EAAW,MAAQ,MAAM,EAAI,cAAc,EAC7C,CAAC,EAEK,EAAc,MAAe,CACjC,GAAI,CAAC,EAAW,MAAO,MAAO,QAC9B,IAAM,EAAI,EAAW,MAAM,OACrB,EAAI,EAAW,MAAM,WAC3B,MAAO,GAAG,EAAE,aAAY,UAAW,EAAE,QAAO,QAAS,EAAE,aACzD,CAAC,EAED,EAAU,SAAY,CACpB,MAAM,GAAM,GAAG,EACX,GAAW,EAAK,KAAK,GACvB,EAAQ,OAAO,CAEnB,CAAC,EAED,IAAM,EAAY,EAAuB,CAAA,CAAE,EAC3C,EAAY,SAAY,CACtB,GAAI,CAAC,EAAW,MAAO,OACvB,SAAS,MAAQ,EAAY,MAC7B,IAAM,EAAS,MAAM,EAAI,aAAa,EACtC,EAAO,MAAM,EAAG,IAAM,EAAE,GAAK,EAAE,EAAE,EACjC,EAAU,MAAQ,EAClB,EAAS,MAAQ,EACnB,CAAC,EAED,IAAM,EAAkB,EAAQ,SAAY,CAC1C,IAAM,EAAW,MAAM,EAAI,gBAAgB,EACrC,EAAa,MAAM,EAAI,cAAc,CAAE,GAAI,EAAS,EAAG,CAAC,EAC9D,MAAM,EAAgB,QAAQ,EAAS,GAAI,CAAQ,EACnD,MAAM,EAAkB,QAAQ,EAAS,GAAI,CAAU,EACvD,EAAQ,QAAQ,WAAW,EAC3B,IAAM,EAAS,MAAM,EAAI,aAAa,EACtC,EAAO,MAAM,EAAG,IAAM,EAAE,GAAK,EAAE,EAAE,EACjC,EAAU,MAAQ,CACpB,CAAC,EACK,EAAsB,EAAQ,SAAY,CAC9C,IAAM,GAAe,MAAM,EAAI,aAAa,GAAG,IAAK,GAAM,EAAE,EAAE,EACxD,EAAmB,IAAI,KAC1B,MAAM,EAAkB,KAAK,GAAG,IAAK,GAAM,SAAS,CAAC,CAAC,CACzD,EACM,EAAsB,EAAY,OACrC,GAAM,CAAC,EAAiB,IAAI,CAAC,CAChC,EACA,GAAI,EAAoB,QAAU,EAAG,CACnC,EAAQ,QAAQ,UAAU,EAC1B,MACF,CACA,IAAI,EAAI,EACF,EAAQ,GAAO,CAAC,EACtB,MAAM,QAAQ,IACZ,EAAoB,IAAK,GACvB,EAAM,SAAY,CAChB,GAAM,CAAC,EAAa,GAAiB,MAAM,QAAQ,IAAI,CACrD,EAAI,YAAY,CAAE,GAAI,CAAW,CAAC,EAClC,EAAI,cAAc,CAAE,GAAI,CAAW,CAAC,CAAC,CAC7B,EACL,EAAY,QACjB,MAAM,QAAQ,IAAI,CAChB,EAAgB,QAAQ,EAAY,CAAW,EAC/C,EAAkB,QAAQ,EAAY,CAAa,CAAC,CACrD,EACD,IACF,CAAC,CACH,CACF,EACA,EAAQ,QAAQ,KAAK,EAAC,KAAM,CAC9B,CAAC,EAEK,CACJ,iBACA,YACA,cACA,WACA,qBACA,qBACA,kBACE,GAAmB,EACjB,GAAsB,GAAsB,CAC5C,EAAO,WAAa,EAAS,MAC/B,EAAS,UAAY,EAAO,MAEhC,EACM,EAAkB,EACtB,KAAO,IAAkB,CACvB,GAAI,CAAE,MAAM,EAAgB,QAAQ,EAAI,EAAE,EAAI,CAC5C,IAAM,EAAM,MAAM,EAAI,YAAY,CAAE,GAAI,EAAI,EAAG,CAAC,EAChD,MAAM,EAAgB,QAAQ,EAAI,GAAI,CAAG,CAC3C,CACA,GAAI,CAAE,MAAM,EAAkB,QAAQ,EAAI,EAAE,EAAI,CAC9C,IAAM,EAAK,MAAM,EAAI,cAAc,CAAE,GAAI,EAAI,EAAG,CAAC,EACjD,MAAM,EAAkB,QAAQ,EAAI,GAAI,CAAE,CAC5C,CACA,OAAO,KACL,EAAO,QAAQ,CACb,KAAM,WACN,OAAQ,CAAE,WAAY,EAAI,EAAG,CAC/B,CAAC,EAAE,IACL,CACF,EACC,GAAM,EAAE,EACX,EAEM,GAAsC,CAC1C,CACE,KAAM,WACR,EACA,EACA,GACA,GACA,GACA,GACA,GACA,CACE,IAAK,UACL,MAAO,KACP,MAAO,QACP,MAAO,QACP,OAAO,EAAK,CACV,OAAA,EAAA,EAAA,CAAA,SAEc,EAAG,WACD,GAAK,UACN,GAAK,kBACG,0BAA0B,EAAI,KAAI,cACpC,EAAgB,OAAO,CAAG,EAAC,eAC5B,EAAgB,QAAQ,EAAI,IAAG,eAC/B,SAAY,MAAM,EAAI,eAAe,CAAE,GAAI,EAAI,EAAG,CAAC,EAAC,aACpD,CACd,EAAU,MAAQ,EAAU,MAAM,OAAQ,GAAM,EAAE,KAAO,EAAI,EAAE,CACjE,CAAC,EAAA,IAAA,CAGP,CACF,CAAC,EAGG,EAAiB,EAAc,CAAA,CAAE,EACjC,CAAE,gBAAgB,GAAgB,EAAgB,CACtD,iBAAkB,KAAO,IAAO,MAAM,EAAI,eAAe,CAAE,IAAG,CAAC,EAC/D,cAAe,SAAY,CACzB,IAAM,EAAS,MAAM,EAAI,aAAa,EACtC,EAAO,MAAM,EAAG,IAAM,EAAE,GAAK,EAAE,EAAE,EACjC,EAAU,MAAQ,CACpB,CACF,CAAC,EAEK,EAAa,EAAiC,CAClD,KAAM,EACN,SAAU,GACV,eAAgB,GAChB,UAAW,CAAC,GAAI,GAAG,EACnB,SAAW,GAAiB,CAC1B,EAAW,KAAO,CACpB,EACA,iBAAmB,GAAqB,CACtC,EAAW,SAAW,EACtB,EAAW,KAAO,CACpB,CACF,CAAC,EACD,EAAM,EAAY,EAAa,EAE/B,IAAM,EAAgB,EAAW,EAAK,EAChC,EAAW,EAAW,EAAE,EACxB,EAAa,EAAQ,SAAY,CACrC,IAAM,EAAO,MAAgB,GAAA,QAAM,MAAM,EAAS,MAAM,KAAK,CAAC,CAAC,EAC1D,KACL,IAAI,EAAK,YAAc,EAAK,cAAgB,EAAK,KAC/C,MAAM,EAAI,mBAAmB,CAAI,OAC5B,GAAI,OAAO,EAAK,IAAM,SAC3B,MAAM,EAAI,mBAAmB,CAC3B,KAAM,CAAC,CAAI,CACb,CAAC,OACI,GAAI,MAAM,QAAQ,CAAI,GAAK,OAAO,EAAK,GAAG,IAAM,SACrD,MAAM,EAAI,mBAAmB,CAC3B,KAAM,CACR,CAAC,OACI,GAAI,OAAO,EAAK,KAAO,SAC5B,MAAM,EAAI,mBAAmB,CAC3B,aAAc,CAAC,CAAI,CACrB,CAAC,OACI,GAAI,MAAM,QAAQ,CAAI,GAAK,OAAO,EAAK,GAAG,KAAO,SACtD,MAAM,EAAI,mBAAmB,CAC3B,aAAc,CAChB,CAAC,MACI,CACL,EAAQ,MAAM,WAAW,EACzB,MACF,CACA,EAAQ,QAAQ,MAAM,CADtB,CAEF,CAAC,EAEK,EAAoB,EAAW,EAAK,EAEpC,GAGA,CACJ,CACE,MAAO,MACP,MAAO,EACT,EACA,CACE,MAAO,QACP,MAAO,OACT,EACA,CACE,MAAO,YACP,MAAO,WACT,EACA,CACE,MAAO,cACP,MAAO,aACT,EACA,CACE,MAAO,OACP,MAAO,MACT,EACA,CACE,MAAO,YACP,MAAO,WACT,EACA,CACE,MAAO,gBACP,MAAO,eACT,EACA,CACE,MAAO,kBACP,MAAO,iBACT,CAAC,EAEG,EAAc,EAAgB,CAClC,SAAU,GACV,OAAQ,QACR,UAAW,EACb,CAAC,EACK,EAAe,EAAQ,SAAY,CACvC,IAAM,EAAS,MAAM,EAAI,aAAa,CACpC,GAAG,EACH,UAAW,EAAY,SACzB,CAAC,EACD,GAAI,EAAO,QAAS,CAClB,EAAQ,QAAQ,QAAU,EAAO,OAAO,EACxC,MACF,CACI,EAAO,OACT,EAAQ,SAAS,EAAO,OAAS,QAAU,QAAU,EAAO,MAAM,EACzD,CAAC,EAAO,QAAU,EAAO,QAClC,EAAQ,QAAQ,MAAM,CAE1B,CAAC,mHAoDC,EAwBS,EAAA,CAvBC,KAAM,EAAA,CAAA,iCAAA,EAAa,MAAA,EAAA,KAC3B,OAAO,SACP,MAAA,CAAA,MAAA,OAAA,EACA,MAAM,SACN,aAAa,KACZ,oBAAmB,SAAmB,EAAA,CAAA,EAAW,kBAAmC,EAAA,CAAA,EAAW,OAAM,oBAiBpG,CAVF,EAUE,EAAA,CATQ,MAAO,EAAA,CAAA,kCAAA,EAAQ,MAAA,EAAA,KACtB,SAAU,EAAA,CAAA,EAAW,QACtB,KAAK,WACL,MAAM,WACL,SAAU,wBAIV,YAAa,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAA,uFAGlB,EAkDS,EAAA,CAjDC,KAAM,EAAA,CAAA,iCAAA,EAAiB,MAAA,EAAA,KAC/B,OAAO,SACP,MAAA,CAAA,MAAA,OAAA,EACA,MAAM,QACN,aAAa,KACZ,oBAAmB,SAAmB,EAAA,CAAA,EAAa,kBAAmC,EAAA,CAAA,EAAa,OAAM,oBAiBxG,CAVF,EAUE,EAAA,CATQ,MAAO,EAAA,CAAA,EAAY,oCAAZ,EAAA,CAAA,EAAY,SAAQ,EAClC,SAAU,EAAA,CAAA,EAAa,QACxB,KAAK,WACL,MAAM,WACL,SAAU,uBAIX,YAAY,kDAEd,EAAc,MAAA,CAAT,SAAA,EAAM,EAAA,KAAA,EAAA,EACX,EASS,EAAA,KAAA,eAR8D,CAArE,EAAqE,EAAA,CAAlD,QAAS,EAAA,CAAA,EAAY,uCAAZ,EAAA,CAAA,EAAY,UAAS,kBAAQ,CAAA,GAAA,AAAA,EAAA,MAAA,CAAA,EAAN,SAAM,EAAA,CAAA,CAAA,CAAA,8BACzD,EAMI,IAAA,CALF,KAAK,8DACL,OAAO,SACP,IAAI,uBACL,SAED,EAAA,CAAA,CAAA,gBAEF,EAAc,MAAA,CAAT,SAAA,EAAM,EAAA,KAAA,EAAA,EACX,EAaM,MAbN,GAaM,CAZJ,EAIE,EAAA,CAHQ,MAAO,EAAA,CAAA,EAAY,kCAAZ,EAAA,CAAA,EAAY,OAAM,EAChC,QAAS,GACV,MAAM,qCAER,EAMI,IAAA,CALF,KAAK,oDACL,OAAO,SACP,IAAI,uBACL,SAED,EAAA,CAAA,CAAA,2CAGJ,EAmHM,MAnHN,GAmHM,CAlHJ,EAoGM,MApGN,EAoGM,CAnGJ,EAMa,EAAA,CAND,GAAG,IAAI,MAAM,eAAe,MAAM,qBAKlC,CAJV,EAIU,EAAA,CAJD,KAAA,GAAK,MAAA,CAAA,gBAAA,MAAA,IACD,KAAI,MACU,CAAvB,EAAuB,EAAA,CAAd,KAAK,MAAM,CAAA,CAAA,CAAA,gBAI1B,EAmCc,EAAA,KAAA,eAZH,CAtBT,EAsBS,EAAA,CArBC,MAAO,EAAA,CAAA,kCAAA,EAAI,MAAA,EAAA,KACnB,YAAY,UACZ,MAAM,WACL,MAAO,CAAA,MAAA,OAAA,EACP,QAAK,EAAQ,EAAA,CAAA,EAAQ,OAAM,CAAA,OAAA,CAAA,IAEjB,OAAM,MAaJ,CAZX,EAYW,EAAA,KAAA,CAXE,QAAO,MAQN,CAPV,EAOU,EAAA,CANR,KAAA,GACA,MAAA,CAAA,gBAAA,MAAA,EACC,QAAS,EAAA,CAAA,EAAQ,QACjB,QAAO,EAAA,CAAA,EAAQ,SAEL,KAAI,MAA2B,CAA1B,EAA0B,EAAA,CAAjB,KAAK,SAAS,CAAA,CAAA,CAAA,gDAI7C,CAAA,AAAA,EAAA,MAAA,EAFa,SAEb,EAAA,CAAA,CAAA,sCAKI,EAAA,CAAA,GAAA,EAAA,EADR,EASM,MATN,EASM,GADD,EAAA,CAAA,CAAW,EAAA,CAAA,GAAA,EAAA,GAAA,EAAA,CAAA,CAAA,QAGF,EAAA,CAAA,GAAA,EAAA,EAAhB,EAuDW,EAAA,CAAA,IAAA,CAAA,EAAA,CAtDT,EAGE,GAAA,CAFC,aAAc,EAAA,CAAA,EAAe,OAC7B,YAAa,EAAA,EAAA,0CAEhB,EAYW,EAAA,KAAA,CAXE,QAAO,MAQN,CAPV,EAOU,EAAA,CANR,KAAA,GACA,MAAA,CAAA,gBAAA,MAAA,EACC,QAAS,EAAA,CAAA,EAAgB,QACzB,QAAO,EAAA,CAAA,EAAgB,SAEb,KAAI,MAA4B,CAA3B,EAA2B,EAAA,CAAlB,KAAK,UAAU,CAAA,CAAA,CAAA,gDAI9C,CAAA,AAAA,EAAA,MAAA,EAFa,SAEb,EAAA,CAAA,CAAA,QACA,EAYW,EAAA,KAAA,CAXE,QAAO,MAQN,CAPV,EAOU,EAAA,CANR,KAAA,GACA,MAAA,CAAA,gBAAA,MAAA,EACC,QAAS,EAAA,CAAA,EAAoB,QAC7B,QAAO,EAAA,CAAA,EAAoB,SAEjB,KAAI,MAA4B,CAA3B,EAA2B,EAAA,CAAlB,KAAK,UAAU,CAAA,CAAA,CAAA,gDAI9C,CAAA,AAAA,EAAA,MAAA,EAFa,WAEb,EAAA,CAAA,CAAA,QACA,EAWW,EAAA,KAAA,CAVE,QAAO,MAON,CANV,EAMU,EAAA,CALR,KAAA,GACA,MAAA,CAAA,gBAAA,MAAA,EACC,QAAK,AAAA,EAAA,KAAA,GAAE,EAAA,MAAa,KAEV,KAAI,MAA4B,CAA3B,EAA2B,EAAA,CAAlB,KAAK,UAAU,CAAA,CAAA,CAAA,wBAI9C,CAAA,AAAA,EAAA,MAAA,EAFa,WAEb,EAAA,CAAA,CAAA,QACA,EAWW,EAAA,KAAA,CAVE,QAAO,MAON,CANV,EAMU,EAAA,CALR,KAAA,GACA,MAAA,CAAA,gBAAA,MAAA,EACC,QAAK,AAAA,EAAA,KAAA,GAAE,EAAA,MAAiB,KAEd,KAAI,MAA2B,CAA1B,EAA0B,EAAA,CAAjB,KAAK,SAAS,CAAA,CAAA,CAAA,wBAI7C,CAAA,AAAA,EAAA,MAAA,EAFa,UAEb,EAAA,CAAA,CAAA,yBAGJ,EAYE,EAAA,CAXQ,eAAgB,EAAA,CAAA,2CAAA,EAAc,MAAA,EAAA,KACtC,QAAA,GACA,cAAA,GACC,KAAM,EAAA,CAAA,EACG,WACT,WAAY,EAAA,CAAA,EACZ,OAAS,GAAa,EAAE,GACzB,KAAK,QACL,MAAM,SACL,QAAS,KACT,kBAAe"}
@@ -1,4 +1,4 @@
1
- import{A as e,B as t,Cn as n,Ct as r,En as i,Et as a,L as o,P as s,Pt as c,Tn as l,_t as u,bn as d,hn as f,j as p,l as m,ln as h,pn as g,v as _,vn as v,vt as y,wn as b,x,xn as S,yt as C}from"./discrete-CByWVgF2.js";import{i as w,n as T}from"./Icon-ByFRPJzF.js";import{f as E,m as D,t as O,w as k}from"./ActionCard-DX4l_WJe.js";import{F as A,G as j,K as M,M as ee,Q as N,ct as P,g as F,h as I,i as te,it as L,l as R,ot as z,p as ne,q as B,rt as V,tt as re,u as H,ut as U,v as W,x as G,z as K}from"./runtime-core.esm-bundler-BDo_QXnq.js";import{a as q}from"./buildMatchPatternFn-CfYV5d7G.js";import{a as ie,i as ae,n as oe,r as se,t as ce}from"./useBatchActions-DdbI6fAV.js";import{t as le}from"./Input-C3St80tx.js";import{t as ue}from"./Checkbox-CA6sAZH-.js";import{C as de,o as fe}from"./storage-BFHw9nz6.js";import{t as pe}from"./check-DMevxUTa.js";import{n as J}from"./node-CfXtXkv-.js";import{o as me}from"./chunk-CrgKN-f1.js";import{n as he,t as ge}from"./import-ZO-Vqm1r.js";var Y={buttonHeightSmall:`14px`,buttonHeightMedium:`18px`,buttonHeightLarge:`22px`,buttonWidthSmall:`14px`,buttonWidthMedium:`18px`,buttonWidthLarge:`22px`,buttonWidthPressedSmall:`20px`,buttonWidthPressedMedium:`24px`,buttonWidthPressedLarge:`28px`,railHeightSmall:`18px`,railHeightMedium:`22px`,railHeightLarge:`26px`,railWidthSmall:`32px`,railWidthMedium:`40px`,railWidthLarge:`48px`};function X(e){let{primaryColor:t,opacityDisabled:n,borderRadius:r,textColor3:i}=e;return Object.assign(Object.assign({},Y),{iconColor:i,textColor:`white`,loadingColor:t,opacityDisabled:n,railColor:`rgba(0, 0, 0, .14)`,railColorActive:t,buttonBoxShadow:`0 1px 4px 0 rgba(0, 0, 0, 0.3), inset 0 0 1px 0 rgba(0, 0, 0, 0.05)`,buttonColor:`#FFF`,railBorderRadiusSmall:r,railBorderRadiusMedium:r,railBorderRadiusLarge:r,buttonBorderRadiusSmall:r,buttonBorderRadiusMedium:r,buttonBorderRadiusLarge:r,boxShadowFocus:`0 0 0 2px ${g(t,{alpha:.2})}`})}var Z={name:`Switch`,common:e,self:X},_e=S(`switch`,`
1
+ import{A as e,B as t,Cn as n,Ct as r,En as i,Et as a,L as o,P as s,Pt as c,Tn as l,_t as u,bn as d,hn as f,j as p,l as m,ln as h,pn as g,v as _,vn as v,vt as y,wn as b,x,xn as S,yt as C}from"./discrete-CByWVgF2.js";import{i as w,n as T}from"./Icon-ByFRPJzF.js";import{f as E,m as D,t as O,w as k}from"./ActionCard-eQYOgHVh.js";import{F as A,G as j,K as M,M as ee,Q as N,ct as P,g as F,h as I,i as te,it as L,l as R,ot as z,p as ne,q as B,rt as V,tt as re,u as H,ut as U,v as W,x as G,z as K}from"./runtime-core.esm-bundler-BDo_QXnq.js";import{a as q}from"./buildMatchPatternFn-CfYV5d7G.js";import{a as ie,i as ae,n as oe,r as se,t as ce}from"./useBatchActions-fKVQDVTI.js";import{t as le}from"./Input-C3St80tx.js";import{t as ue}from"./Checkbox-CA6sAZH-.js";import{C as de,o as fe}from"./storage-BFHw9nz6.js";import{t as pe}from"./check-DMevxUTa.js";import{n as J}from"./node-CfXtXkv-.js";import{o as me}from"./chunk-CrgKN-f1.js";import{n as he,t as ge}from"./import-ZO-Vqm1r.js";var Y={buttonHeightSmall:`14px`,buttonHeightMedium:`18px`,buttonHeightLarge:`22px`,buttonWidthSmall:`14px`,buttonWidthMedium:`18px`,buttonWidthLarge:`22px`,buttonWidthPressedSmall:`20px`,buttonWidthPressedMedium:`24px`,buttonWidthPressedLarge:`28px`,railHeightSmall:`18px`,railHeightMedium:`22px`,railHeightLarge:`26px`,railWidthSmall:`32px`,railWidthMedium:`40px`,railWidthLarge:`48px`};function X(e){let{primaryColor:t,opacityDisabled:n,borderRadius:r,textColor3:i}=e;return Object.assign(Object.assign({},Y),{iconColor:i,textColor:`white`,loadingColor:t,opacityDisabled:n,railColor:`rgba(0, 0, 0, .14)`,railColorActive:t,buttonBoxShadow:`0 1px 4px 0 rgba(0, 0, 0, 0.3), inset 0 0 1px 0 rgba(0, 0, 0, 0.05)`,buttonColor:`#FFF`,railBorderRadiusSmall:r,railBorderRadiusMedium:r,railBorderRadiusLarge:r,buttonBorderRadiusSmall:r,buttonBorderRadiusMedium:r,buttonBorderRadiusLarge:r,boxShadowFocus:`0 0 0 2px ${g(t,{alpha:.2})}`})}var Z={name:`Switch`,common:e,self:X},_e=S(`switch`,`
2
2
  height: var(--n-height);
3
3
  min-width: var(--n-width);
4
4
  vertical-align: middle;
@@ -105,4 +105,4 @@ import{A as e,B as t,Cn as n,Ct as r,En as i,Et as a,L as o,P as s,Pt as c,Tn as
105
105
  每行一个
106
106
  空白行自动忽略
107
107
  非法链接行自动忽略`,autosize:{minRows:8,maxRows:16},inputProps:{style:`white-space: nowrap;`},"onUpdate:value":n[5]||=e=>{U(G).loading||(W.value=e)}},null,8,[`value`])]),_:1},8,[`show`,`loading`,`onPositiveClick`]),F(v,{show:U(Q),"onUpdate:show":n[14]||=e=>N(Q)?Q.value=e:null,preset:`dialog`,title:`设置`,showIcon:!1,positiveText:`关闭`,style:{width:`600px`},onPositiveClick:n[15]||=e=>Q.value=!1},{default:B(()=>[F(y,{checked:U(t).ignoreUploadWarn,"onUpdate:checked":n[11]||=e=>U(t).ignoreUploadWarn=e},{default:B(()=>[...n[26]||=[I(` 关闭生成分享链接弹窗提醒 `,-1)]]),_:1},8,[`checked`]),n[29]||=H(`div`,{"h-1px":``,"my-10px":``,bg:`#eee`},null,-1),F(y,{checked:U(t).ignoreWasmWarn,"onUpdate:checked":n[12]||=e=>U(t).ignoreWasmWarn=e},{default:B(()=>[...n[27]||=[I(` 关闭浏览器版本正则表达式 WASM(GC) 提醒 `,-1)]]),_:1},8,[`checked`]),n[30]||=H(`div`,{"h-1px":``,"my-10px":``,bg:`#eee`},null,-1),H(`div`,Te,[F(S,{value:U(t).autoUploadImport,"onUpdate:value":n[13]||=e=>U(t).autoUploadImport=e},null,8,[`value`]),n[28]||=H(`div`,null,`打开快照页面自动生成分享链接(请确保不含隐私)`,-1)])]),_:1},8,[`show`])],64)}}});export{$ as default};
108
- //# sourceMappingURL=HomePage-Cm0eK4jK.js.map
108
+ //# sourceMappingURL=HomePage-CK1sVwzl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HomePage-Cm0eK4jK.js","names":["commonVars","commonLight","style","NIconSwitchTransition","NBaseLoading"],"sources":["../../node_modules/.pnpm/naive-ui@2.44.1_vue@3.5.34_typescript@6.0.3_/node_modules/naive-ui/es/switch/styles/_common.mjs","../../node_modules/.pnpm/naive-ui@2.44.1_vue@3.5.34_typescript@6.0.3_/node_modules/naive-ui/es/switch/styles/light.mjs","../../node_modules/.pnpm/naive-ui@2.44.1_vue@3.5.34_typescript@6.0.3_/node_modules/naive-ui/es/switch/src/styles/index.cssr.mjs","../../node_modules/.pnpm/naive-ui@2.44.1_vue@3.5.34_typescript@6.0.3_/node_modules/naive-ui/es/switch/src/Switch.mjs","../../src/views/home/HomePage.vue","../../src/views/home/HomePage.vue"],"sourcesContent":["export default {\n buttonHeightSmall: '14px',\n buttonHeightMedium: '18px',\n buttonHeightLarge: '22px',\n buttonWidthSmall: '14px',\n buttonWidthMedium: '18px',\n buttonWidthLarge: '22px',\n buttonWidthPressedSmall: '20px',\n buttonWidthPressedMedium: '24px',\n buttonWidthPressedLarge: '28px',\n railHeightSmall: '18px',\n railHeightMedium: '22px',\n railHeightLarge: '26px',\n railWidthSmall: '32px',\n railWidthMedium: '40px',\n railWidthLarge: '48px'\n};","import { changeColor } from 'seemly';\nimport { commonLight } from \"../../_styles/common/index.mjs\";\nimport commonVars from \"./_common.mjs\";\nfunction self(vars) {\n const {\n primaryColor,\n opacityDisabled,\n borderRadius,\n textColor3\n } = vars;\n const railOverlayColor = 'rgba(0, 0, 0, .14)';\n return Object.assign(Object.assign({}, commonVars), {\n iconColor: textColor3,\n textColor: 'white',\n loadingColor: primaryColor,\n opacityDisabled,\n railColor: railOverlayColor,\n railColorActive: primaryColor,\n buttonBoxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.3), inset 0 0 1px 0 rgba(0, 0, 0, 0.05)',\n buttonColor: '#FFF',\n railBorderRadiusSmall: borderRadius,\n railBorderRadiusMedium: borderRadius,\n railBorderRadiusLarge: borderRadius,\n buttonBorderRadiusSmall: borderRadius,\n buttonBorderRadiusMedium: borderRadius,\n buttonBorderRadiusLarge: borderRadius,\n boxShadowFocus: `0 0 0 2px ${changeColor(primaryColor, {\n alpha: 0.2\n })}`\n });\n}\nconst switchLight = {\n name: 'Switch',\n common: commonLight,\n self\n};\nexport default switchLight;","import { iconSwitchTransition } from \"../../../_styles/transitions/icon-switch.cssr.mjs\";\nimport { c, cB, cE, cM, cNotM } from \"../../../_utils/cssr/index.mjs\";\n// vars:\n// --n-bezier\n// --n-button-border-radius\n// --n-button-box-shadow\n// --n-button-color\n// --n-button-width\n// --n-button-width-pressed\n// --n-height\n// --n-offset\n// --n-rail-border-radius\n// --n-rail-color\n// --n-rail-color-active\n// --n-rail-height\n// --n-rail-width\n// --n-width\n// --n-box-shadow-focus\n// --n-loading-color\n// --n-text-color\n// --n-icon-color\nexport default cB('switch', `\n height: var(--n-height);\n min-width: var(--n-width);\n vertical-align: middle;\n user-select: none;\n -webkit-user-select: none;\n display: inline-flex;\n outline: none;\n justify-content: center;\n align-items: center;\n`, [cE('children-placeholder', `\n height: var(--n-rail-height);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n pointer-events: none;\n visibility: hidden;\n `), cE('rail-placeholder', `\n display: flex;\n flex-wrap: none;\n `), cE('button-placeholder', `\n width: calc(1.75 * var(--n-rail-height));\n height: var(--n-rail-height);\n `), cB('base-loading', `\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translateX(-50%) translateY(-50%);\n font-size: calc(var(--n-button-width) - 4px);\n color: var(--n-loading-color);\n transition: color .3s var(--n-bezier);\n `, [iconSwitchTransition({\n left: '50%',\n top: '50%',\n originalTransform: 'translateX(-50%) translateY(-50%)'\n})]), cE('checked, unchecked', `\n transition: color .3s var(--n-bezier);\n color: var(--n-text-color);\n box-sizing: border-box;\n position: absolute;\n white-space: nowrap;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n line-height: 1;\n `), cE('checked', `\n right: 0;\n padding-right: calc(1.25 * var(--n-rail-height) - var(--n-offset));\n `), cE('unchecked', `\n left: 0;\n justify-content: flex-end;\n padding-left: calc(1.25 * var(--n-rail-height) - var(--n-offset));\n `), c('&:focus', [cE('rail', `\n box-shadow: var(--n-box-shadow-focus);\n `)]), cM('round', [cE('rail', 'border-radius: calc(var(--n-rail-height) / 2);', [cE('button', 'border-radius: calc(var(--n-button-height) / 2);')])]), cNotM('disabled', [cNotM('icon', [cM('rubber-band', [cM('pressed', [cE('rail', [cE('button', 'max-width: var(--n-button-width-pressed);')])]), cE('rail', [c('&:active', [cE('button', 'max-width: var(--n-button-width-pressed);')])]), cM('active', [cM('pressed', [cE('rail', [cE('button', 'left: calc(100% - var(--n-offset) - var(--n-button-width-pressed));')])]), cE('rail', [c('&:active', [cE('button', 'left: calc(100% - var(--n-offset) - var(--n-button-width-pressed));')])])])])])]), cM('active', [cE('rail', [cE('button', 'left: calc(100% - var(--n-button-width) - var(--n-offset))')])]), cE('rail', `\n overflow: hidden;\n height: var(--n-rail-height);\n min-width: var(--n-rail-width);\n border-radius: var(--n-rail-border-radius);\n cursor: pointer;\n position: relative;\n transition:\n opacity .3s var(--n-bezier),\n background .3s var(--n-bezier),\n box-shadow .3s var(--n-bezier);\n background-color: var(--n-rail-color);\n `, [cE('button-icon', `\n color: var(--n-icon-color);\n transition: color .3s var(--n-bezier);\n font-size: calc(var(--n-button-height) - 4px);\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n line-height: 1;\n `, [iconSwitchTransition()]), cE('button', `\n align-items: center; \n top: var(--n-offset);\n left: var(--n-offset);\n height: var(--n-button-height);\n width: var(--n-button-width-pressed);\n max-width: var(--n-button-width);\n border-radius: var(--n-button-border-radius);\n background-color: var(--n-button-color);\n box-shadow: var(--n-button-box-shadow);\n box-sizing: border-box;\n cursor: inherit;\n content: \"\";\n position: absolute;\n transition:\n background-color .3s var(--n-bezier),\n left .3s var(--n-bezier),\n opacity .3s var(--n-bezier),\n max-width .3s var(--n-bezier),\n box-shadow .3s var(--n-bezier);\n `)]), cM('active', [cE('rail', 'background-color: var(--n-rail-color-active);')]), cM('loading', [cE('rail', `\n cursor: wait;\n `)]), cM('disabled', [cE('rail', `\n cursor: not-allowed;\n opacity: .5;\n `)])]);","import { depx, pxfy } from 'seemly';\nimport { useMergedState } from 'vooks';\nimport { computed, defineComponent, h, ref, toRef, watchEffect } from 'vue';\nimport { NBaseLoading, NIconSwitchTransition } from \"../../_internal/index.mjs\";\nimport { useConfig, useFormItem, useTheme, useThemeClass } from \"../../_mixins/index.mjs\";\nimport { call, createKey, isSlotEmpty, resolveWrappedSlot, warnOnce } from \"../../_utils/index.mjs\";\nimport { switchLight } from \"../styles/index.mjs\";\nimport style from \"./styles/index.cssr.mjs\";\nexport const switchProps = Object.assign(Object.assign({}, useTheme.props), {\n size: String,\n value: {\n type: [String, Number, Boolean],\n default: undefined\n },\n loading: Boolean,\n defaultValue: {\n type: [String, Number, Boolean],\n default: false\n },\n disabled: {\n type: Boolean,\n default: undefined\n },\n round: {\n type: Boolean,\n default: true\n },\n 'onUpdate:value': [Function, Array],\n onUpdateValue: [Function, Array],\n checkedValue: {\n type: [String, Number, Boolean],\n default: true\n },\n uncheckedValue: {\n type: [String, Number, Boolean],\n default: false\n },\n railStyle: Function,\n rubberBand: {\n type: Boolean,\n default: true\n },\n spinProps: Object,\n /** @deprecated */\n onChange: [Function, Array]\n});\nlet supportCssMax;\nexport default defineComponent({\n name: 'Switch',\n props: switchProps,\n slots: Object,\n setup(props) {\n if (process.env.NODE_ENV !== 'production') {\n watchEffect(() => {\n if (props.onChange) {\n warnOnce('switch', '`on-change` is deprecated, please use `on-update:value` instead.');\n }\n });\n }\n if (supportCssMax === undefined) {\n if (typeof CSS !== 'undefined') {\n if (typeof CSS.supports !== 'undefined') {\n supportCssMax = CSS.supports('width', 'max(1px)');\n } else {\n supportCssMax = false;\n }\n } else {\n // If you are using SSR, we assume that you are targeting browsers with\n // recent versions\n supportCssMax = true;\n }\n }\n const {\n mergedClsPrefixRef,\n inlineThemeDisabled,\n mergedComponentPropsRef\n } = useConfig(props);\n const themeRef = useTheme('Switch', '-switch', style, switchLight, props, mergedClsPrefixRef);\n const formItem = useFormItem(props, {\n mergedSize(NFormItem) {\n var _a, _b;\n if (props.size !== undefined) return props.size;\n if (NFormItem) {\n return NFormItem.mergedSize.value;\n }\n const configSize = (_b = (_a = mergedComponentPropsRef === null || mergedComponentPropsRef === void 0 ? void 0 : mergedComponentPropsRef.value) === null || _a === void 0 ? void 0 : _a.Switch) === null || _b === void 0 ? void 0 : _b.size;\n if (configSize) return configSize;\n return 'medium';\n }\n });\n const {\n mergedSizeRef,\n mergedDisabledRef\n } = formItem;\n const uncontrolledValueRef = ref(props.defaultValue);\n const controlledValueRef = toRef(props, 'value');\n const mergedValueRef = useMergedState(controlledValueRef, uncontrolledValueRef);\n const checkedRef = computed(() => {\n return mergedValueRef.value === props.checkedValue;\n });\n const pressedRef = ref(false);\n const focusedRef = ref(false);\n const mergedRailStyleRef = computed(() => {\n const {\n railStyle\n } = props;\n if (!railStyle) return undefined;\n return railStyle({\n focused: focusedRef.value,\n checked: checkedRef.value\n });\n });\n function doUpdateValue(value) {\n const {\n 'onUpdate:value': _onUpdateValue,\n onChange,\n onUpdateValue\n } = props;\n const {\n nTriggerFormInput,\n nTriggerFormChange\n } = formItem;\n if (_onUpdateValue) call(_onUpdateValue, value);\n if (onUpdateValue) call(onUpdateValue, value);\n if (onChange) call(onChange, value);\n uncontrolledValueRef.value = value;\n nTriggerFormInput();\n nTriggerFormChange();\n }\n function doFocus() {\n const {\n nTriggerFormFocus\n } = formItem;\n nTriggerFormFocus();\n }\n function doBlur() {\n const {\n nTriggerFormBlur\n } = formItem;\n nTriggerFormBlur();\n }\n function handleClick() {\n if (props.loading || mergedDisabledRef.value) return;\n if (mergedValueRef.value !== props.checkedValue) {\n doUpdateValue(props.checkedValue);\n } else {\n doUpdateValue(props.uncheckedValue);\n }\n }\n function handleFocus() {\n focusedRef.value = true;\n doFocus();\n }\n function handleBlur() {\n focusedRef.value = false;\n doBlur();\n pressedRef.value = false;\n }\n function handleKeyup(e) {\n if (props.loading || mergedDisabledRef.value) return;\n if (e.key === ' ') {\n if (mergedValueRef.value !== props.checkedValue) {\n doUpdateValue(props.checkedValue);\n } else {\n doUpdateValue(props.uncheckedValue);\n }\n pressedRef.value = false;\n }\n }\n function handleKeydown(e) {\n if (props.loading || mergedDisabledRef.value) return;\n if (e.key === ' ') {\n e.preventDefault();\n pressedRef.value = true;\n }\n }\n const cssVarsRef = computed(() => {\n const {\n value: size\n } = mergedSizeRef;\n const {\n self: {\n opacityDisabled,\n railColor,\n railColorActive,\n buttonBoxShadow,\n buttonColor,\n boxShadowFocus,\n loadingColor,\n textColor,\n iconColor,\n [createKey('buttonHeight', size)]: buttonHeight,\n [createKey('buttonWidth', size)]: buttonWidth,\n [createKey('buttonWidthPressed', size)]: buttonWidthPressed,\n [createKey('railHeight', size)]: railHeight,\n [createKey('railWidth', size)]: railWidth,\n [createKey('railBorderRadius', size)]: railBorderRadius,\n [createKey('buttonBorderRadius', size)]: buttonBorderRadius\n },\n common: {\n cubicBezierEaseInOut\n }\n } = themeRef.value;\n let offset;\n let height;\n let width;\n if (supportCssMax) {\n offset = `calc((${railHeight} - ${buttonHeight}) / 2)`;\n height = `max(${railHeight}, ${buttonHeight})`;\n width = `max(${railWidth}, calc(${railWidth} + ${buttonHeight} - ${railHeight}))`;\n } else {\n offset = pxfy((depx(railHeight) - depx(buttonHeight)) / 2);\n height = pxfy(Math.max(depx(railHeight), depx(buttonHeight)));\n width = depx(railHeight) > depx(buttonHeight) ? railWidth : pxfy(depx(railWidth) + depx(buttonHeight) - depx(railHeight));\n }\n return {\n '--n-bezier': cubicBezierEaseInOut,\n '--n-button-border-radius': buttonBorderRadius,\n '--n-button-box-shadow': buttonBoxShadow,\n '--n-button-color': buttonColor,\n '--n-button-width': buttonWidth,\n '--n-button-width-pressed': buttonWidthPressed,\n '--n-button-height': buttonHeight,\n '--n-height': height,\n '--n-offset': offset,\n '--n-opacity-disabled': opacityDisabled,\n '--n-rail-border-radius': railBorderRadius,\n '--n-rail-color': railColor,\n '--n-rail-color-active': railColorActive,\n '--n-rail-height': railHeight,\n '--n-rail-width': railWidth,\n '--n-width': width,\n '--n-box-shadow-focus': boxShadowFocus,\n '--n-loading-color': loadingColor,\n '--n-text-color': textColor,\n '--n-icon-color': iconColor\n };\n });\n const themeClassHandle = inlineThemeDisabled ? useThemeClass('switch', computed(() => {\n return mergedSizeRef.value[0];\n }), cssVarsRef, props) : undefined;\n return {\n handleClick,\n handleBlur,\n handleFocus,\n handleKeyup,\n handleKeydown,\n mergedRailStyle: mergedRailStyleRef,\n pressed: pressedRef,\n mergedClsPrefix: mergedClsPrefixRef,\n mergedValue: mergedValueRef,\n checked: checkedRef,\n mergedDisabled: mergedDisabledRef,\n cssVars: inlineThemeDisabled ? undefined : cssVarsRef,\n themeClass: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.themeClass,\n onRender: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.onRender\n };\n },\n render() {\n const {\n mergedClsPrefix,\n mergedDisabled,\n checked,\n mergedRailStyle,\n onRender,\n $slots\n } = this;\n onRender === null || onRender === void 0 ? void 0 : onRender();\n const {\n checked: checkedSlot,\n unchecked: uncheckedSlot,\n icon: iconSlot,\n 'checked-icon': checkedIconSlot,\n 'unchecked-icon': uncheckedIconSlot\n } = $slots;\n const hasIcon = !(isSlotEmpty(iconSlot) && isSlotEmpty(checkedIconSlot) && isSlotEmpty(uncheckedIconSlot));\n return h(\"div\", {\n role: \"switch\",\n \"aria-checked\": checked,\n class: [`${mergedClsPrefix}-switch`, this.themeClass, hasIcon && `${mergedClsPrefix}-switch--icon`, checked && `${mergedClsPrefix}-switch--active`, mergedDisabled && `${mergedClsPrefix}-switch--disabled`, this.round && `${mergedClsPrefix}-switch--round`, this.loading && `${mergedClsPrefix}-switch--loading`, this.pressed && `${mergedClsPrefix}-switch--pressed`, this.rubberBand && `${mergedClsPrefix}-switch--rubber-band`],\n tabindex: !this.mergedDisabled ? 0 : undefined,\n style: this.cssVars,\n onClick: this.handleClick,\n onFocus: this.handleFocus,\n onBlur: this.handleBlur,\n onKeyup: this.handleKeyup,\n onKeydown: this.handleKeydown\n }, h(\"div\", {\n class: `${mergedClsPrefix}-switch__rail`,\n \"aria-hidden\": \"true\",\n style: mergedRailStyle\n }, resolveWrappedSlot(checkedSlot, checkedSlotChildren => resolveWrappedSlot(uncheckedSlot, uncheckedSlotChildren => {\n if (checkedSlotChildren || uncheckedSlotChildren) {\n return h(\"div\", {\n \"aria-hidden\": true,\n class: `${mergedClsPrefix}-switch__children-placeholder`\n }, h(\"div\", {\n class: `${mergedClsPrefix}-switch__rail-placeholder`\n }, h(\"div\", {\n class: `${mergedClsPrefix}-switch__button-placeholder`\n }), checkedSlotChildren), h(\"div\", {\n class: `${mergedClsPrefix}-switch__rail-placeholder`\n }, h(\"div\", {\n class: `${mergedClsPrefix}-switch__button-placeholder`\n }), uncheckedSlotChildren));\n }\n return null;\n })), h(\"div\", {\n class: `${mergedClsPrefix}-switch__button`\n }, resolveWrappedSlot(iconSlot, icon => resolveWrappedSlot(checkedIconSlot, checkedIcon => resolveWrappedSlot(uncheckedIconSlot, uncheckedIcon => {\n return h(NIconSwitchTransition, null, {\n default: () => this.loading ? h(NBaseLoading, Object.assign({\n key: \"loading\",\n clsPrefix: mergedClsPrefix,\n strokeWidth: 20\n }, this.spinProps)) : this.checked && (checkedIcon || icon) ? h(\"div\", {\n class: `${mergedClsPrefix}-switch__button-icon`,\n key: checkedIcon ? 'checked-icon' : 'icon'\n }, checkedIcon || icon) : !this.checked && (uncheckedIcon || icon) ? h(\"div\", {\n class: `${mergedClsPrefix}-switch__button-icon`,\n key: uncheckedIcon ? 'unchecked-icon' : 'icon'\n }, uncheckedIcon || icon) : null\n });\n }))), resolveWrappedSlot(checkedSlot, children => children && h(\"div\", {\n key: \"checked\",\n class: `${mergedClsPrefix}-switch__checked`\n }, children)), resolveWrappedSlot(uncheckedSlot, children => children && h(\"div\", {\n key: \"unchecked\",\n class: `${mergedClsPrefix}-switch__unchecked`\n }, children)))));\n }\n});","<script lang=\"tsx\" setup>\nimport ActionCard from '@/components/ActionCard.vue';\nimport BatchActionsBar from '@/components/BatchActionsBar.vue';\nimport { toValidURL } from '@/utils/check';\nimport { importFromLocal, importFromNetwork } from '@/utils/import';\nimport { getAppInfo } from '@/utils/node';\nimport { getDragEventFiles } from '@/utils/others';\nimport { shallowSnapshotStorage } from '@/utils/snapshot';\nimport { renderDevice, useSnapshotColumns } from '@/utils/table';\nimport { useTask } from '@/utils/task';\nimport type { DataTableColumns, PaginationProps } from 'naive-ui';\nimport type { SortState } from 'naive-ui/es/data-table/src/interface';\nimport { useBatchActions } from '@/composables/useBatchActions';\n\nconst { settingsStore } = useStorageStore();\n\nconst snapshots = shallowRef<Snapshot[]>([]);\nconst loading = shallowRef(true);\nconst updateSnapshots = async () => {\n loading.value = true;\n snapshots.value = (await shallowSnapshotStorage.getAllItems()).reverse();\n checkedRowKeys.value = [];\n loading.value = false;\n};\nonMounted(updateSnapshots);\nconst filterOption = shallowReactive({\n query: ``,\n actualQuery: ``,\n updateQuery: () => {\n filterOption.actualQuery = filterOption.query.trim();\n checkedRowKeys.value = [];\n },\n});\nconst filterSnapshots = computed(() => {\n const actualQuery = filterOption.actualQuery;\n if (!actualQuery) return snapshots.value;\n return snapshots.value.filter((s) => {\n return (\n (getAppInfo(s).name || ``).includes(actualQuery) ||\n (s.appId || ``).includes(actualQuery) ||\n (s.activityId || ``).includes(actualQuery)\n );\n });\n});\n\nconst importLocal = useTask(async (_files?: File[]) => {\n if (await importFromLocal(_files)) {\n await updateSnapshots();\n }\n});\n\nuseEventListener(document.body, 'drop', async (e) => {\n e.preventDefault();\n await importLocal.invoke(getDragEventFiles(e));\n});\nuseEventListener(document.body, 'dragover', (e) => {\n e.preventDefault();\n});\n\nconst {\n activityIdCol,\n appIdCol,\n appNameCol,\n ctimeCol,\n mtimeCol,\n deviceCol,\n appVersionCodeCol,\n appVersionNameCol,\n resetColWidth,\n} = useSnapshotColumns();\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(renderDevice(c)), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n deviceCol.filterOptions = undefined;\n return;\n }\n deviceCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(getAppInfo(c).name), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n appNameCol.filterOptions = undefined;\n return;\n }\n appNameCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(c.activityId), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n activityIdCol.filterOptions = undefined;\n return;\n }\n activityIdCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nconst columns: DataTableColumns<Snapshot> = reactive([\n {\n type: 'selection',\n },\n ctimeCol,\n mtimeCol,\n deviceCol,\n appNameCol,\n appIdCol,\n appVersionCodeCol,\n appVersionNameCol,\n activityIdCol,\n {\n key: `actions`,\n title: `操作`,\n fixed: 'right',\n width: `160px`,\n render(row) {\n return <ActionCard snapshot={row} onDelete={updateSnapshots} />;\n },\n },\n]);\n\nconst pagination = shallowReactive<PaginationProps>({\n page: 1,\n pageSize: 50,\n showSizePicker: true,\n pageSizes: [50, 100],\n onChange: (page: number) => {\n pagination.page = page;\n },\n onUpdatePageSize: (pageSize: number) => {\n pagination.pageSize = pageSize;\n pagination.page = 1;\n },\n});\nwatch(pagination, resetColWidth);\n\nconst handleSorterChange = (sorter: SortState) => {\n [ctimeCol, mtimeCol].forEach((c) => {\n if (sorter.columnKey != c.key) {\n c.sortOrder = undefined;\n } else {\n c.sortOrder = sorter.order;\n }\n });\n};\nmtimeCol.sortOrder = `descend`;\nconst showImportModal = shallowRef(false);\nconst textImportValue = shallowRef(``);\nconst importNetwork = useTask(async () => {\n const urls = textImportValue.value\n .trim()\n .split(`\\n`)\n .map((u) => u.trim())\n .filter((u) => toValidURL(u));\n if (urls.length == 0) return;\n const r = await importFromNetwork(urls);\n if (!r) return;\n await updateSnapshots();\n textImportValue.value = ``;\n});\n\nuseEventListener(document.body, 'paste', (e) => {\n if (showImportModal.value) return;\n const target = e.target as HTMLElement;\n if (\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n (target.className || '').includes('input')\n ) {\n return;\n }\n const dataTransfer = e.clipboardData;\n if (!dataTransfer) return;\n const text = (dataTransfer.getData('text') || '').trim();\n if (text.startsWith('https://') || text.startsWith('http://')) {\n showImportModal.value = true;\n setTimeout(() => {\n textImportValue.value = text;\n });\n }\n});\n\nconst checkedRowKeys = ref<number[]>([]);\nconst {\n batchDelete,\n batchDownloadImage,\n batchDownloadZip,\n batchShareImageUrl,\n batchShareZipUrl,\n} = useBatchActions(checkedRowKeys, {\n onAfterDelete: updateSnapshots,\n});\n\nconst settingsDlgShow = shallowRef(false);\n\nconst inputImportRef = shallowRef();\n</script>\n<template>\n <div flex flex-col p-10px gap-10px page-size>\n <div flex>\n <NSpace>\n <NInputGroup>\n <NInput\n v-model:value=\"filterOption.query\"\n placeholder=\"请输入应用名称/应用ID/界面ID\"\n clearable\n class=\"min-w-320px\"\n @keyup.enter=\"filterOption.updateQuery\"\n @change=\"filterOption.updateQuery\"\n />\n <NButton @click=\"filterOption.updateQuery\">\n <template #icon>\n <SvgIcon name=\"search\" />\n </template>\n </NButton>\n </NInputGroup>\n <BatchActionsBar\n :checkedCount=\"checkedRowKeys.length\"\n :batchDelete=\"batchDelete\"\n :batchDownloadImage=\"batchDownloadImage\"\n :batchDownloadZip=\"batchDownloadZip\"\n :batchShareImageUrl=\"batchShareImageUrl\"\n :batchShareZipUrl=\"batchShareZipUrl\"\n />\n </NSpace>\n <div flex-1 />\n <div flex gap-24px items-center pr-8px class=\"[--svg-h:24px]\">\n <NTooltip>\n <template #trigger>\n <NButton text @click=\"settingsDlgShow = true\">\n <SvgIcon name=\"settings\" />\n </NButton>\n </template>\n 设置\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <RouterLink flex to=\"/selector\">\n <NButton text>\n <SvgIcon name=\"terminal\" />\n </NButton>\n </RouterLink>\n </template>\n 测试选择器\n </NTooltip>\n <NPopover>\n <template #trigger>\n <NButton text>\n <SvgIcon name=\"import\" />\n </NButton>\n </template>\n <NSpace vertical>\n <NTooltip placement=\"left\">\n <template #trigger>\n <NButton\n :loading=\"importLocal.loading\"\n @click=\"importLocal.invoke()\"\n >\n 导入本地文件\n </NButton>\n </template>\n <div class=\"whitespace-nowrap\">支持拖拽文件到页面任意位置</div>\n </NTooltip>\n <NTooltip placement=\"left\">\n <template #trigger>\n <NButton\n :loading=\"importNetwork.loading\"\n @click=\"showImportModal = true\"\n >\n 导入网络文件\n </NButton>\n </template>\n <div class=\"whitespace-nowrap\">\n 支持任意位置粘贴(Ctrl+V)文本触发导入\n </div>\n </NTooltip>\n </NSpace>\n </NPopover>\n <NTooltip>\n <template #trigger>\n <RouterLink flex to=\"/device\">\n <NButton text>\n <SvgIcon name=\"device\" />\n </NButton>\n </RouterLink>\n </template>\n 连接设备\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <a\n flex\n href=\"https://github.com/orgs/gkd-kit/discussions\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <NButton text>\n <SvgIcon name=\"discussion\" />\n </NButton>\n </a>\n </template>\n 讨论交流\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <a\n flex\n href=\"https://github.com/gkd-kit/inspect\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <NButton text>\n <SvgIcon name=\"github\" />\n </NButton>\n </a>\n </template>\n Github\n </NTooltip>\n </div>\n </div>\n <NDataTable\n v-model:checkedRowKeys=\"checkedRowKeys\"\n striped\n virtualScroll\n :data=\"filterSnapshots\"\n :columns=\"columns\"\n :scrollX=\"1800\"\n :rowKey=\"(r:Snapshot)=>r.id\"\n size=\"small\"\n class=\"flex-1\"\n flex-height\n :loading=\"loading\"\n @update:sorter=\"handleSorterChange\"\n />\n </div>\n <NModal\n :show=\"showImportModal\"\n preset=\"dialog\"\n title=\"导入网络文件\"\n :showIcon=\"false\"\n positiveText=\"确认\"\n negativeText=\"取消\"\n style=\"width: 800px\"\n :loading=\"importNetwork.loading\"\n @positiveClick=\"importNetwork.invoke\"\n @negativeClick=\"showImportModal = false\"\n @close=\"showImportModal = false\"\n @esc=\"showImportModal = false\"\n @afterEnter=\"inputImportRef?.focus()\"\n @afterLeave=\"textImportValue = ``\"\n >\n <NInput\n ref=\"inputImportRef\"\n :value=\"textImportValue\"\n type=\"textarea\"\n :placeholder=\"`1.支持ZIP文件链接\\n2.支持快照链接\\n每行一个\\n空白行自动忽略\\n非法链接行自动忽略`\"\n :autosize=\"{\n minRows: 8,\n maxRows: 16,\n }\"\n :inputProps=\"{\n style: `white-space: nowrap;`,\n }\"\n @update:value=\"\n if (!importNetwork.loading) {\n textImportValue = $event;\n }\n \"\n />\n </NModal>\n\n <NModal\n v-model:show=\"settingsDlgShow\"\n preset=\"dialog\"\n title=\"设置\"\n :showIcon=\"false\"\n positiveText=\"关闭\"\n style=\"width: 600px\"\n @positiveClick=\"settingsDlgShow = false\"\n >\n <NCheckbox v-model:checked=\"settingsStore.ignoreUploadWarn\">\n 关闭生成分享链接弹窗提醒\n </NCheckbox>\n <div h-1px my-10px bg=\"#eee\" />\n <NCheckbox v-model:checked=\"settingsStore.ignoreWasmWarn\">\n 关闭浏览器版本正则表达式 WASM(GC) 提醒\n </NCheckbox>\n <div h-1px my-10px bg=\"#eee\" />\n <div flex gap-10px>\n <NSwitch v-model:value=\"settingsStore.autoUploadImport\" />\n <div>打开快照页面自动生成分享链接(请确保不含隐私)</div>\n </div>\n </NModal>\n</template>\n","<script lang=\"tsx\" setup>\nimport ActionCard from '@/components/ActionCard.vue';\nimport BatchActionsBar from '@/components/BatchActionsBar.vue';\nimport { toValidURL } from '@/utils/check';\nimport { importFromLocal, importFromNetwork } from '@/utils/import';\nimport { getAppInfo } from '@/utils/node';\nimport { getDragEventFiles } from '@/utils/others';\nimport { shallowSnapshotStorage } from '@/utils/snapshot';\nimport { renderDevice, useSnapshotColumns } from '@/utils/table';\nimport { useTask } from '@/utils/task';\nimport type { DataTableColumns, PaginationProps } from 'naive-ui';\nimport type { SortState } from 'naive-ui/es/data-table/src/interface';\nimport { useBatchActions } from '@/composables/useBatchActions';\n\nconst { settingsStore } = useStorageStore();\n\nconst snapshots = shallowRef<Snapshot[]>([]);\nconst loading = shallowRef(true);\nconst updateSnapshots = async () => {\n loading.value = true;\n snapshots.value = (await shallowSnapshotStorage.getAllItems()).reverse();\n checkedRowKeys.value = [];\n loading.value = false;\n};\nonMounted(updateSnapshots);\nconst filterOption = shallowReactive({\n query: ``,\n actualQuery: ``,\n updateQuery: () => {\n filterOption.actualQuery = filterOption.query.trim();\n checkedRowKeys.value = [];\n },\n});\nconst filterSnapshots = computed(() => {\n const actualQuery = filterOption.actualQuery;\n if (!actualQuery) return snapshots.value;\n return snapshots.value.filter((s) => {\n return (\n (getAppInfo(s).name || ``).includes(actualQuery) ||\n (s.appId || ``).includes(actualQuery) ||\n (s.activityId || ``).includes(actualQuery)\n );\n });\n});\n\nconst importLocal = useTask(async (_files?: File[]) => {\n if (await importFromLocal(_files)) {\n await updateSnapshots();\n }\n});\n\nuseEventListener(document.body, 'drop', async (e) => {\n e.preventDefault();\n await importLocal.invoke(getDragEventFiles(e));\n});\nuseEventListener(document.body, 'dragover', (e) => {\n e.preventDefault();\n});\n\nconst {\n activityIdCol,\n appIdCol,\n appNameCol,\n ctimeCol,\n mtimeCol,\n deviceCol,\n appVersionCodeCol,\n appVersionNameCol,\n resetColWidth,\n} = useSnapshotColumns();\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(renderDevice(c)), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n deviceCol.filterOptions = undefined;\n return;\n }\n deviceCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(getAppInfo(c).name), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n appNameCol.filterOptions = undefined;\n return;\n }\n appNameCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(c.activityId), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n activityIdCol.filterOptions = undefined;\n return;\n }\n activityIdCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nconst columns: DataTableColumns<Snapshot> = reactive([\n {\n type: 'selection',\n },\n ctimeCol,\n mtimeCol,\n deviceCol,\n appNameCol,\n appIdCol,\n appVersionCodeCol,\n appVersionNameCol,\n activityIdCol,\n {\n key: `actions`,\n title: `操作`,\n fixed: 'right',\n width: `160px`,\n render(row) {\n return <ActionCard snapshot={row} onDelete={updateSnapshots} />;\n },\n },\n]);\n\nconst pagination = shallowReactive<PaginationProps>({\n page: 1,\n pageSize: 50,\n showSizePicker: true,\n pageSizes: [50, 100],\n onChange: (page: number) => {\n pagination.page = page;\n },\n onUpdatePageSize: (pageSize: number) => {\n pagination.pageSize = pageSize;\n pagination.page = 1;\n },\n});\nwatch(pagination, resetColWidth);\n\nconst handleSorterChange = (sorter: SortState) => {\n [ctimeCol, mtimeCol].forEach((c) => {\n if (sorter.columnKey != c.key) {\n c.sortOrder = undefined;\n } else {\n c.sortOrder = sorter.order;\n }\n });\n};\nmtimeCol.sortOrder = `descend`;\nconst showImportModal = shallowRef(false);\nconst textImportValue = shallowRef(``);\nconst importNetwork = useTask(async () => {\n const urls = textImportValue.value\n .trim()\n .split(`\\n`)\n .map((u) => u.trim())\n .filter((u) => toValidURL(u));\n if (urls.length == 0) return;\n const r = await importFromNetwork(urls);\n if (!r) return;\n await updateSnapshots();\n textImportValue.value = ``;\n});\n\nuseEventListener(document.body, 'paste', (e) => {\n if (showImportModal.value) return;\n const target = e.target as HTMLElement;\n if (\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n (target.className || '').includes('input')\n ) {\n return;\n }\n const dataTransfer = e.clipboardData;\n if (!dataTransfer) return;\n const text = (dataTransfer.getData('text') || '').trim();\n if (text.startsWith('https://') || text.startsWith('http://')) {\n showImportModal.value = true;\n setTimeout(() => {\n textImportValue.value = text;\n });\n }\n});\n\nconst checkedRowKeys = ref<number[]>([]);\nconst {\n batchDelete,\n batchDownloadImage,\n batchDownloadZip,\n batchShareImageUrl,\n batchShareZipUrl,\n} = useBatchActions(checkedRowKeys, {\n onAfterDelete: updateSnapshots,\n});\n\nconst settingsDlgShow = shallowRef(false);\n\nconst inputImportRef = shallowRef();\n</script>\n<template>\n <div flex flex-col p-10px gap-10px page-size>\n <div flex>\n <NSpace>\n <NInputGroup>\n <NInput\n v-model:value=\"filterOption.query\"\n placeholder=\"请输入应用名称/应用ID/界面ID\"\n clearable\n class=\"min-w-320px\"\n @keyup.enter=\"filterOption.updateQuery\"\n @change=\"filterOption.updateQuery\"\n />\n <NButton @click=\"filterOption.updateQuery\">\n <template #icon>\n <SvgIcon name=\"search\" />\n </template>\n </NButton>\n </NInputGroup>\n <BatchActionsBar\n :checkedCount=\"checkedRowKeys.length\"\n :batchDelete=\"batchDelete\"\n :batchDownloadImage=\"batchDownloadImage\"\n :batchDownloadZip=\"batchDownloadZip\"\n :batchShareImageUrl=\"batchShareImageUrl\"\n :batchShareZipUrl=\"batchShareZipUrl\"\n />\n </NSpace>\n <div flex-1 />\n <div flex gap-24px items-center pr-8px class=\"[--svg-h:24px]\">\n <NTooltip>\n <template #trigger>\n <NButton text @click=\"settingsDlgShow = true\">\n <SvgIcon name=\"settings\" />\n </NButton>\n </template>\n 设置\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <RouterLink flex to=\"/selector\">\n <NButton text>\n <SvgIcon name=\"terminal\" />\n </NButton>\n </RouterLink>\n </template>\n 测试选择器\n </NTooltip>\n <NPopover>\n <template #trigger>\n <NButton text>\n <SvgIcon name=\"import\" />\n </NButton>\n </template>\n <NSpace vertical>\n <NTooltip placement=\"left\">\n <template #trigger>\n <NButton\n :loading=\"importLocal.loading\"\n @click=\"importLocal.invoke()\"\n >\n 导入本地文件\n </NButton>\n </template>\n <div class=\"whitespace-nowrap\">支持拖拽文件到页面任意位置</div>\n </NTooltip>\n <NTooltip placement=\"left\">\n <template #trigger>\n <NButton\n :loading=\"importNetwork.loading\"\n @click=\"showImportModal = true\"\n >\n 导入网络文件\n </NButton>\n </template>\n <div class=\"whitespace-nowrap\">\n 支持任意位置粘贴(Ctrl+V)文本触发导入\n </div>\n </NTooltip>\n </NSpace>\n </NPopover>\n <NTooltip>\n <template #trigger>\n <RouterLink flex to=\"/device\">\n <NButton text>\n <SvgIcon name=\"device\" />\n </NButton>\n </RouterLink>\n </template>\n 连接设备\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <a\n flex\n href=\"https://github.com/orgs/gkd-kit/discussions\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <NButton text>\n <SvgIcon name=\"discussion\" />\n </NButton>\n </a>\n </template>\n 讨论交流\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <a\n flex\n href=\"https://github.com/gkd-kit/inspect\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <NButton text>\n <SvgIcon name=\"github\" />\n </NButton>\n </a>\n </template>\n Github\n </NTooltip>\n </div>\n </div>\n <NDataTable\n v-model:checkedRowKeys=\"checkedRowKeys\"\n striped\n virtualScroll\n :data=\"filterSnapshots\"\n :columns=\"columns\"\n :scrollX=\"1800\"\n :rowKey=\"(r:Snapshot)=>r.id\"\n size=\"small\"\n class=\"flex-1\"\n flex-height\n :loading=\"loading\"\n @update:sorter=\"handleSorterChange\"\n />\n </div>\n <NModal\n :show=\"showImportModal\"\n preset=\"dialog\"\n title=\"导入网络文件\"\n :showIcon=\"false\"\n positiveText=\"确认\"\n negativeText=\"取消\"\n style=\"width: 800px\"\n :loading=\"importNetwork.loading\"\n @positiveClick=\"importNetwork.invoke\"\n @negativeClick=\"showImportModal = false\"\n @close=\"showImportModal = false\"\n @esc=\"showImportModal = false\"\n @afterEnter=\"inputImportRef?.focus()\"\n @afterLeave=\"textImportValue = ``\"\n >\n <NInput\n ref=\"inputImportRef\"\n :value=\"textImportValue\"\n type=\"textarea\"\n :placeholder=\"`1.支持ZIP文件链接\\n2.支持快照链接\\n每行一个\\n空白行自动忽略\\n非法链接行自动忽略`\"\n :autosize=\"{\n minRows: 8,\n maxRows: 16,\n }\"\n :inputProps=\"{\n style: `white-space: nowrap;`,\n }\"\n @update:value=\"\n if (!importNetwork.loading) {\n textImportValue = $event;\n }\n \"\n />\n </NModal>\n\n <NModal\n v-model:show=\"settingsDlgShow\"\n preset=\"dialog\"\n title=\"设置\"\n :showIcon=\"false\"\n positiveText=\"关闭\"\n style=\"width: 600px\"\n @positiveClick=\"settingsDlgShow = false\"\n >\n <NCheckbox v-model:checked=\"settingsStore.ignoreUploadWarn\">\n 关闭生成分享链接弹窗提醒\n </NCheckbox>\n <div h-1px my-10px bg=\"#eee\" />\n <NCheckbox v-model:checked=\"settingsStore.ignoreWasmWarn\">\n 关闭浏览器版本正则表达式 WASM(GC) 提醒\n </NCheckbox>\n <div h-1px my-10px bg=\"#eee\" />\n <div flex gap-10px>\n <NSwitch v-model:value=\"settingsStore.autoUploadImport\" />\n <div>打开快照页面自动生成分享链接(请确保不含隐私)</div>\n </div>\n </NModal>\n</template>\n"],"x_google_ignoreList":[0,1,2,3],"mappings":"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"}
1
+ {"version":3,"file":"HomePage-CK1sVwzl.js","names":["commonVars","commonLight","style","NIconSwitchTransition","NBaseLoading"],"sources":["../../node_modules/.pnpm/naive-ui@2.44.1_vue@3.5.34_typescript@6.0.3_/node_modules/naive-ui/es/switch/styles/_common.mjs","../../node_modules/.pnpm/naive-ui@2.44.1_vue@3.5.34_typescript@6.0.3_/node_modules/naive-ui/es/switch/styles/light.mjs","../../node_modules/.pnpm/naive-ui@2.44.1_vue@3.5.34_typescript@6.0.3_/node_modules/naive-ui/es/switch/src/styles/index.cssr.mjs","../../node_modules/.pnpm/naive-ui@2.44.1_vue@3.5.34_typescript@6.0.3_/node_modules/naive-ui/es/switch/src/Switch.mjs","../../src/views/home/HomePage.vue","../../src/views/home/HomePage.vue"],"sourcesContent":["export default {\n buttonHeightSmall: '14px',\n buttonHeightMedium: '18px',\n buttonHeightLarge: '22px',\n buttonWidthSmall: '14px',\n buttonWidthMedium: '18px',\n buttonWidthLarge: '22px',\n buttonWidthPressedSmall: '20px',\n buttonWidthPressedMedium: '24px',\n buttonWidthPressedLarge: '28px',\n railHeightSmall: '18px',\n railHeightMedium: '22px',\n railHeightLarge: '26px',\n railWidthSmall: '32px',\n railWidthMedium: '40px',\n railWidthLarge: '48px'\n};","import { changeColor } from 'seemly';\nimport { commonLight } from \"../../_styles/common/index.mjs\";\nimport commonVars from \"./_common.mjs\";\nfunction self(vars) {\n const {\n primaryColor,\n opacityDisabled,\n borderRadius,\n textColor3\n } = vars;\n const railOverlayColor = 'rgba(0, 0, 0, .14)';\n return Object.assign(Object.assign({}, commonVars), {\n iconColor: textColor3,\n textColor: 'white',\n loadingColor: primaryColor,\n opacityDisabled,\n railColor: railOverlayColor,\n railColorActive: primaryColor,\n buttonBoxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.3), inset 0 0 1px 0 rgba(0, 0, 0, 0.05)',\n buttonColor: '#FFF',\n railBorderRadiusSmall: borderRadius,\n railBorderRadiusMedium: borderRadius,\n railBorderRadiusLarge: borderRadius,\n buttonBorderRadiusSmall: borderRadius,\n buttonBorderRadiusMedium: borderRadius,\n buttonBorderRadiusLarge: borderRadius,\n boxShadowFocus: `0 0 0 2px ${changeColor(primaryColor, {\n alpha: 0.2\n })}`\n });\n}\nconst switchLight = {\n name: 'Switch',\n common: commonLight,\n self\n};\nexport default switchLight;","import { iconSwitchTransition } from \"../../../_styles/transitions/icon-switch.cssr.mjs\";\nimport { c, cB, cE, cM, cNotM } from \"../../../_utils/cssr/index.mjs\";\n// vars:\n// --n-bezier\n// --n-button-border-radius\n// --n-button-box-shadow\n// --n-button-color\n// --n-button-width\n// --n-button-width-pressed\n// --n-height\n// --n-offset\n// --n-rail-border-radius\n// --n-rail-color\n// --n-rail-color-active\n// --n-rail-height\n// --n-rail-width\n// --n-width\n// --n-box-shadow-focus\n// --n-loading-color\n// --n-text-color\n// --n-icon-color\nexport default cB('switch', `\n height: var(--n-height);\n min-width: var(--n-width);\n vertical-align: middle;\n user-select: none;\n -webkit-user-select: none;\n display: inline-flex;\n outline: none;\n justify-content: center;\n align-items: center;\n`, [cE('children-placeholder', `\n height: var(--n-rail-height);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n pointer-events: none;\n visibility: hidden;\n `), cE('rail-placeholder', `\n display: flex;\n flex-wrap: none;\n `), cE('button-placeholder', `\n width: calc(1.75 * var(--n-rail-height));\n height: var(--n-rail-height);\n `), cB('base-loading', `\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translateX(-50%) translateY(-50%);\n font-size: calc(var(--n-button-width) - 4px);\n color: var(--n-loading-color);\n transition: color .3s var(--n-bezier);\n `, [iconSwitchTransition({\n left: '50%',\n top: '50%',\n originalTransform: 'translateX(-50%) translateY(-50%)'\n})]), cE('checked, unchecked', `\n transition: color .3s var(--n-bezier);\n color: var(--n-text-color);\n box-sizing: border-box;\n position: absolute;\n white-space: nowrap;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n line-height: 1;\n `), cE('checked', `\n right: 0;\n padding-right: calc(1.25 * var(--n-rail-height) - var(--n-offset));\n `), cE('unchecked', `\n left: 0;\n justify-content: flex-end;\n padding-left: calc(1.25 * var(--n-rail-height) - var(--n-offset));\n `), c('&:focus', [cE('rail', `\n box-shadow: var(--n-box-shadow-focus);\n `)]), cM('round', [cE('rail', 'border-radius: calc(var(--n-rail-height) / 2);', [cE('button', 'border-radius: calc(var(--n-button-height) / 2);')])]), cNotM('disabled', [cNotM('icon', [cM('rubber-band', [cM('pressed', [cE('rail', [cE('button', 'max-width: var(--n-button-width-pressed);')])]), cE('rail', [c('&:active', [cE('button', 'max-width: var(--n-button-width-pressed);')])]), cM('active', [cM('pressed', [cE('rail', [cE('button', 'left: calc(100% - var(--n-offset) - var(--n-button-width-pressed));')])]), cE('rail', [c('&:active', [cE('button', 'left: calc(100% - var(--n-offset) - var(--n-button-width-pressed));')])])])])])]), cM('active', [cE('rail', [cE('button', 'left: calc(100% - var(--n-button-width) - var(--n-offset))')])]), cE('rail', `\n overflow: hidden;\n height: var(--n-rail-height);\n min-width: var(--n-rail-width);\n border-radius: var(--n-rail-border-radius);\n cursor: pointer;\n position: relative;\n transition:\n opacity .3s var(--n-bezier),\n background .3s var(--n-bezier),\n box-shadow .3s var(--n-bezier);\n background-color: var(--n-rail-color);\n `, [cE('button-icon', `\n color: var(--n-icon-color);\n transition: color .3s var(--n-bezier);\n font-size: calc(var(--n-button-height) - 4px);\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n line-height: 1;\n `, [iconSwitchTransition()]), cE('button', `\n align-items: center; \n top: var(--n-offset);\n left: var(--n-offset);\n height: var(--n-button-height);\n width: var(--n-button-width-pressed);\n max-width: var(--n-button-width);\n border-radius: var(--n-button-border-radius);\n background-color: var(--n-button-color);\n box-shadow: var(--n-button-box-shadow);\n box-sizing: border-box;\n cursor: inherit;\n content: \"\";\n position: absolute;\n transition:\n background-color .3s var(--n-bezier),\n left .3s var(--n-bezier),\n opacity .3s var(--n-bezier),\n max-width .3s var(--n-bezier),\n box-shadow .3s var(--n-bezier);\n `)]), cM('active', [cE('rail', 'background-color: var(--n-rail-color-active);')]), cM('loading', [cE('rail', `\n cursor: wait;\n `)]), cM('disabled', [cE('rail', `\n cursor: not-allowed;\n opacity: .5;\n `)])]);","import { depx, pxfy } from 'seemly';\nimport { useMergedState } from 'vooks';\nimport { computed, defineComponent, h, ref, toRef, watchEffect } from 'vue';\nimport { NBaseLoading, NIconSwitchTransition } from \"../../_internal/index.mjs\";\nimport { useConfig, useFormItem, useTheme, useThemeClass } from \"../../_mixins/index.mjs\";\nimport { call, createKey, isSlotEmpty, resolveWrappedSlot, warnOnce } from \"../../_utils/index.mjs\";\nimport { switchLight } from \"../styles/index.mjs\";\nimport style from \"./styles/index.cssr.mjs\";\nexport const switchProps = Object.assign(Object.assign({}, useTheme.props), {\n size: String,\n value: {\n type: [String, Number, Boolean],\n default: undefined\n },\n loading: Boolean,\n defaultValue: {\n type: [String, Number, Boolean],\n default: false\n },\n disabled: {\n type: Boolean,\n default: undefined\n },\n round: {\n type: Boolean,\n default: true\n },\n 'onUpdate:value': [Function, Array],\n onUpdateValue: [Function, Array],\n checkedValue: {\n type: [String, Number, Boolean],\n default: true\n },\n uncheckedValue: {\n type: [String, Number, Boolean],\n default: false\n },\n railStyle: Function,\n rubberBand: {\n type: Boolean,\n default: true\n },\n spinProps: Object,\n /** @deprecated */\n onChange: [Function, Array]\n});\nlet supportCssMax;\nexport default defineComponent({\n name: 'Switch',\n props: switchProps,\n slots: Object,\n setup(props) {\n if (process.env.NODE_ENV !== 'production') {\n watchEffect(() => {\n if (props.onChange) {\n warnOnce('switch', '`on-change` is deprecated, please use `on-update:value` instead.');\n }\n });\n }\n if (supportCssMax === undefined) {\n if (typeof CSS !== 'undefined') {\n if (typeof CSS.supports !== 'undefined') {\n supportCssMax = CSS.supports('width', 'max(1px)');\n } else {\n supportCssMax = false;\n }\n } else {\n // If you are using SSR, we assume that you are targeting browsers with\n // recent versions\n supportCssMax = true;\n }\n }\n const {\n mergedClsPrefixRef,\n inlineThemeDisabled,\n mergedComponentPropsRef\n } = useConfig(props);\n const themeRef = useTheme('Switch', '-switch', style, switchLight, props, mergedClsPrefixRef);\n const formItem = useFormItem(props, {\n mergedSize(NFormItem) {\n var _a, _b;\n if (props.size !== undefined) return props.size;\n if (NFormItem) {\n return NFormItem.mergedSize.value;\n }\n const configSize = (_b = (_a = mergedComponentPropsRef === null || mergedComponentPropsRef === void 0 ? void 0 : mergedComponentPropsRef.value) === null || _a === void 0 ? void 0 : _a.Switch) === null || _b === void 0 ? void 0 : _b.size;\n if (configSize) return configSize;\n return 'medium';\n }\n });\n const {\n mergedSizeRef,\n mergedDisabledRef\n } = formItem;\n const uncontrolledValueRef = ref(props.defaultValue);\n const controlledValueRef = toRef(props, 'value');\n const mergedValueRef = useMergedState(controlledValueRef, uncontrolledValueRef);\n const checkedRef = computed(() => {\n return mergedValueRef.value === props.checkedValue;\n });\n const pressedRef = ref(false);\n const focusedRef = ref(false);\n const mergedRailStyleRef = computed(() => {\n const {\n railStyle\n } = props;\n if (!railStyle) return undefined;\n return railStyle({\n focused: focusedRef.value,\n checked: checkedRef.value\n });\n });\n function doUpdateValue(value) {\n const {\n 'onUpdate:value': _onUpdateValue,\n onChange,\n onUpdateValue\n } = props;\n const {\n nTriggerFormInput,\n nTriggerFormChange\n } = formItem;\n if (_onUpdateValue) call(_onUpdateValue, value);\n if (onUpdateValue) call(onUpdateValue, value);\n if (onChange) call(onChange, value);\n uncontrolledValueRef.value = value;\n nTriggerFormInput();\n nTriggerFormChange();\n }\n function doFocus() {\n const {\n nTriggerFormFocus\n } = formItem;\n nTriggerFormFocus();\n }\n function doBlur() {\n const {\n nTriggerFormBlur\n } = formItem;\n nTriggerFormBlur();\n }\n function handleClick() {\n if (props.loading || mergedDisabledRef.value) return;\n if (mergedValueRef.value !== props.checkedValue) {\n doUpdateValue(props.checkedValue);\n } else {\n doUpdateValue(props.uncheckedValue);\n }\n }\n function handleFocus() {\n focusedRef.value = true;\n doFocus();\n }\n function handleBlur() {\n focusedRef.value = false;\n doBlur();\n pressedRef.value = false;\n }\n function handleKeyup(e) {\n if (props.loading || mergedDisabledRef.value) return;\n if (e.key === ' ') {\n if (mergedValueRef.value !== props.checkedValue) {\n doUpdateValue(props.checkedValue);\n } else {\n doUpdateValue(props.uncheckedValue);\n }\n pressedRef.value = false;\n }\n }\n function handleKeydown(e) {\n if (props.loading || mergedDisabledRef.value) return;\n if (e.key === ' ') {\n e.preventDefault();\n pressedRef.value = true;\n }\n }\n const cssVarsRef = computed(() => {\n const {\n value: size\n } = mergedSizeRef;\n const {\n self: {\n opacityDisabled,\n railColor,\n railColorActive,\n buttonBoxShadow,\n buttonColor,\n boxShadowFocus,\n loadingColor,\n textColor,\n iconColor,\n [createKey('buttonHeight', size)]: buttonHeight,\n [createKey('buttonWidth', size)]: buttonWidth,\n [createKey('buttonWidthPressed', size)]: buttonWidthPressed,\n [createKey('railHeight', size)]: railHeight,\n [createKey('railWidth', size)]: railWidth,\n [createKey('railBorderRadius', size)]: railBorderRadius,\n [createKey('buttonBorderRadius', size)]: buttonBorderRadius\n },\n common: {\n cubicBezierEaseInOut\n }\n } = themeRef.value;\n let offset;\n let height;\n let width;\n if (supportCssMax) {\n offset = `calc((${railHeight} - ${buttonHeight}) / 2)`;\n height = `max(${railHeight}, ${buttonHeight})`;\n width = `max(${railWidth}, calc(${railWidth} + ${buttonHeight} - ${railHeight}))`;\n } else {\n offset = pxfy((depx(railHeight) - depx(buttonHeight)) / 2);\n height = pxfy(Math.max(depx(railHeight), depx(buttonHeight)));\n width = depx(railHeight) > depx(buttonHeight) ? railWidth : pxfy(depx(railWidth) + depx(buttonHeight) - depx(railHeight));\n }\n return {\n '--n-bezier': cubicBezierEaseInOut,\n '--n-button-border-radius': buttonBorderRadius,\n '--n-button-box-shadow': buttonBoxShadow,\n '--n-button-color': buttonColor,\n '--n-button-width': buttonWidth,\n '--n-button-width-pressed': buttonWidthPressed,\n '--n-button-height': buttonHeight,\n '--n-height': height,\n '--n-offset': offset,\n '--n-opacity-disabled': opacityDisabled,\n '--n-rail-border-radius': railBorderRadius,\n '--n-rail-color': railColor,\n '--n-rail-color-active': railColorActive,\n '--n-rail-height': railHeight,\n '--n-rail-width': railWidth,\n '--n-width': width,\n '--n-box-shadow-focus': boxShadowFocus,\n '--n-loading-color': loadingColor,\n '--n-text-color': textColor,\n '--n-icon-color': iconColor\n };\n });\n const themeClassHandle = inlineThemeDisabled ? useThemeClass('switch', computed(() => {\n return mergedSizeRef.value[0];\n }), cssVarsRef, props) : undefined;\n return {\n handleClick,\n handleBlur,\n handleFocus,\n handleKeyup,\n handleKeydown,\n mergedRailStyle: mergedRailStyleRef,\n pressed: pressedRef,\n mergedClsPrefix: mergedClsPrefixRef,\n mergedValue: mergedValueRef,\n checked: checkedRef,\n mergedDisabled: mergedDisabledRef,\n cssVars: inlineThemeDisabled ? undefined : cssVarsRef,\n themeClass: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.themeClass,\n onRender: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.onRender\n };\n },\n render() {\n const {\n mergedClsPrefix,\n mergedDisabled,\n checked,\n mergedRailStyle,\n onRender,\n $slots\n } = this;\n onRender === null || onRender === void 0 ? void 0 : onRender();\n const {\n checked: checkedSlot,\n unchecked: uncheckedSlot,\n icon: iconSlot,\n 'checked-icon': checkedIconSlot,\n 'unchecked-icon': uncheckedIconSlot\n } = $slots;\n const hasIcon = !(isSlotEmpty(iconSlot) && isSlotEmpty(checkedIconSlot) && isSlotEmpty(uncheckedIconSlot));\n return h(\"div\", {\n role: \"switch\",\n \"aria-checked\": checked,\n class: [`${mergedClsPrefix}-switch`, this.themeClass, hasIcon && `${mergedClsPrefix}-switch--icon`, checked && `${mergedClsPrefix}-switch--active`, mergedDisabled && `${mergedClsPrefix}-switch--disabled`, this.round && `${mergedClsPrefix}-switch--round`, this.loading && `${mergedClsPrefix}-switch--loading`, this.pressed && `${mergedClsPrefix}-switch--pressed`, this.rubberBand && `${mergedClsPrefix}-switch--rubber-band`],\n tabindex: !this.mergedDisabled ? 0 : undefined,\n style: this.cssVars,\n onClick: this.handleClick,\n onFocus: this.handleFocus,\n onBlur: this.handleBlur,\n onKeyup: this.handleKeyup,\n onKeydown: this.handleKeydown\n }, h(\"div\", {\n class: `${mergedClsPrefix}-switch__rail`,\n \"aria-hidden\": \"true\",\n style: mergedRailStyle\n }, resolveWrappedSlot(checkedSlot, checkedSlotChildren => resolveWrappedSlot(uncheckedSlot, uncheckedSlotChildren => {\n if (checkedSlotChildren || uncheckedSlotChildren) {\n return h(\"div\", {\n \"aria-hidden\": true,\n class: `${mergedClsPrefix}-switch__children-placeholder`\n }, h(\"div\", {\n class: `${mergedClsPrefix}-switch__rail-placeholder`\n }, h(\"div\", {\n class: `${mergedClsPrefix}-switch__button-placeholder`\n }), checkedSlotChildren), h(\"div\", {\n class: `${mergedClsPrefix}-switch__rail-placeholder`\n }, h(\"div\", {\n class: `${mergedClsPrefix}-switch__button-placeholder`\n }), uncheckedSlotChildren));\n }\n return null;\n })), h(\"div\", {\n class: `${mergedClsPrefix}-switch__button`\n }, resolveWrappedSlot(iconSlot, icon => resolveWrappedSlot(checkedIconSlot, checkedIcon => resolveWrappedSlot(uncheckedIconSlot, uncheckedIcon => {\n return h(NIconSwitchTransition, null, {\n default: () => this.loading ? h(NBaseLoading, Object.assign({\n key: \"loading\",\n clsPrefix: mergedClsPrefix,\n strokeWidth: 20\n }, this.spinProps)) : this.checked && (checkedIcon || icon) ? h(\"div\", {\n class: `${mergedClsPrefix}-switch__button-icon`,\n key: checkedIcon ? 'checked-icon' : 'icon'\n }, checkedIcon || icon) : !this.checked && (uncheckedIcon || icon) ? h(\"div\", {\n class: `${mergedClsPrefix}-switch__button-icon`,\n key: uncheckedIcon ? 'unchecked-icon' : 'icon'\n }, uncheckedIcon || icon) : null\n });\n }))), resolveWrappedSlot(checkedSlot, children => children && h(\"div\", {\n key: \"checked\",\n class: `${mergedClsPrefix}-switch__checked`\n }, children)), resolveWrappedSlot(uncheckedSlot, children => children && h(\"div\", {\n key: \"unchecked\",\n class: `${mergedClsPrefix}-switch__unchecked`\n }, children)))));\n }\n});","<script lang=\"tsx\" setup>\nimport ActionCard from '@/components/ActionCard.vue';\nimport BatchActionsBar from '@/components/BatchActionsBar.vue';\nimport { toValidURL } from '@/utils/check';\nimport { importFromLocal, importFromNetwork } from '@/utils/import';\nimport { getAppInfo } from '@/utils/node';\nimport { getDragEventFiles } from '@/utils/others';\nimport { shallowSnapshotStorage } from '@/utils/snapshot';\nimport { renderDevice, useSnapshotColumns } from '@/utils/table';\nimport { useTask } from '@/utils/task';\nimport type { DataTableColumns, PaginationProps } from 'naive-ui';\nimport type { SortState } from 'naive-ui/es/data-table/src/interface';\nimport { useBatchActions } from '@/composables/useBatchActions';\n\nconst { settingsStore } = useStorageStore();\n\nconst snapshots = shallowRef<Snapshot[]>([]);\nconst loading = shallowRef(true);\nconst updateSnapshots = async () => {\n loading.value = true;\n snapshots.value = (await shallowSnapshotStorage.getAllItems()).reverse();\n checkedRowKeys.value = [];\n loading.value = false;\n};\nonMounted(updateSnapshots);\nconst filterOption = shallowReactive({\n query: ``,\n actualQuery: ``,\n updateQuery: () => {\n filterOption.actualQuery = filterOption.query.trim();\n checkedRowKeys.value = [];\n },\n});\nconst filterSnapshots = computed(() => {\n const actualQuery = filterOption.actualQuery;\n if (!actualQuery) return snapshots.value;\n return snapshots.value.filter((s) => {\n return (\n (getAppInfo(s).name || ``).includes(actualQuery) ||\n (s.appId || ``).includes(actualQuery) ||\n (s.activityId || ``).includes(actualQuery)\n );\n });\n});\n\nconst importLocal = useTask(async (_files?: File[]) => {\n if (await importFromLocal(_files)) {\n await updateSnapshots();\n }\n});\n\nuseEventListener(document.body, 'drop', async (e) => {\n e.preventDefault();\n await importLocal.invoke(getDragEventFiles(e));\n});\nuseEventListener(document.body, 'dragover', (e) => {\n e.preventDefault();\n});\n\nconst {\n activityIdCol,\n appIdCol,\n appNameCol,\n ctimeCol,\n mtimeCol,\n deviceCol,\n appVersionCodeCol,\n appVersionNameCol,\n resetColWidth,\n} = useSnapshotColumns();\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(renderDevice(c)), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n deviceCol.filterOptions = undefined;\n return;\n }\n deviceCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(getAppInfo(c).name), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n appNameCol.filterOptions = undefined;\n return;\n }\n appNameCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(c.activityId), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n activityIdCol.filterOptions = undefined;\n return;\n }\n activityIdCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nconst columns: DataTableColumns<Snapshot> = reactive([\n {\n type: 'selection',\n },\n ctimeCol,\n mtimeCol,\n deviceCol,\n appNameCol,\n appIdCol,\n appVersionCodeCol,\n appVersionNameCol,\n activityIdCol,\n {\n key: `actions`,\n title: `操作`,\n fixed: 'right',\n width: `160px`,\n render(row) {\n return <ActionCard snapshot={row} onDelete={updateSnapshots} />;\n },\n },\n]);\n\nconst pagination = shallowReactive<PaginationProps>({\n page: 1,\n pageSize: 50,\n showSizePicker: true,\n pageSizes: [50, 100],\n onChange: (page: number) => {\n pagination.page = page;\n },\n onUpdatePageSize: (pageSize: number) => {\n pagination.pageSize = pageSize;\n pagination.page = 1;\n },\n});\nwatch(pagination, resetColWidth);\n\nconst handleSorterChange = (sorter: SortState) => {\n [ctimeCol, mtimeCol].forEach((c) => {\n if (sorter.columnKey != c.key) {\n c.sortOrder = undefined;\n } else {\n c.sortOrder = sorter.order;\n }\n });\n};\nmtimeCol.sortOrder = `descend`;\nconst showImportModal = shallowRef(false);\nconst textImportValue = shallowRef(``);\nconst importNetwork = useTask(async () => {\n const urls = textImportValue.value\n .trim()\n .split(`\\n`)\n .map((u) => u.trim())\n .filter((u) => toValidURL(u));\n if (urls.length == 0) return;\n const r = await importFromNetwork(urls);\n if (!r) return;\n await updateSnapshots();\n textImportValue.value = ``;\n});\n\nuseEventListener(document.body, 'paste', (e) => {\n if (showImportModal.value) return;\n const target = e.target as HTMLElement;\n if (\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n (target.className || '').includes('input')\n ) {\n return;\n }\n const dataTransfer = e.clipboardData;\n if (!dataTransfer) return;\n const text = (dataTransfer.getData('text') || '').trim();\n if (text.startsWith('https://') || text.startsWith('http://')) {\n showImportModal.value = true;\n setTimeout(() => {\n textImportValue.value = text;\n });\n }\n});\n\nconst checkedRowKeys = ref<number[]>([]);\nconst {\n batchDelete,\n batchDownloadImage,\n batchDownloadZip,\n batchShareImageUrl,\n batchShareZipUrl,\n} = useBatchActions(checkedRowKeys, {\n onAfterDelete: updateSnapshots,\n});\n\nconst settingsDlgShow = shallowRef(false);\n\nconst inputImportRef = shallowRef();\n</script>\n<template>\n <div flex flex-col p-10px gap-10px page-size>\n <div flex>\n <NSpace>\n <NInputGroup>\n <NInput\n v-model:value=\"filterOption.query\"\n placeholder=\"请输入应用名称/应用ID/界面ID\"\n clearable\n class=\"min-w-320px\"\n @keyup.enter=\"filterOption.updateQuery\"\n @change=\"filterOption.updateQuery\"\n />\n <NButton @click=\"filterOption.updateQuery\">\n <template #icon>\n <SvgIcon name=\"search\" />\n </template>\n </NButton>\n </NInputGroup>\n <BatchActionsBar\n :checkedCount=\"checkedRowKeys.length\"\n :batchDelete=\"batchDelete\"\n :batchDownloadImage=\"batchDownloadImage\"\n :batchDownloadZip=\"batchDownloadZip\"\n :batchShareImageUrl=\"batchShareImageUrl\"\n :batchShareZipUrl=\"batchShareZipUrl\"\n />\n </NSpace>\n <div flex-1 />\n <div flex gap-24px items-center pr-8px class=\"[--svg-h:24px]\">\n <NTooltip>\n <template #trigger>\n <NButton text @click=\"settingsDlgShow = true\">\n <SvgIcon name=\"settings\" />\n </NButton>\n </template>\n 设置\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <RouterLink flex to=\"/selector\">\n <NButton text>\n <SvgIcon name=\"terminal\" />\n </NButton>\n </RouterLink>\n </template>\n 测试选择器\n </NTooltip>\n <NPopover>\n <template #trigger>\n <NButton text>\n <SvgIcon name=\"import\" />\n </NButton>\n </template>\n <NSpace vertical>\n <NTooltip placement=\"left\">\n <template #trigger>\n <NButton\n :loading=\"importLocal.loading\"\n @click=\"importLocal.invoke()\"\n >\n 导入本地文件\n </NButton>\n </template>\n <div class=\"whitespace-nowrap\">支持拖拽文件到页面任意位置</div>\n </NTooltip>\n <NTooltip placement=\"left\">\n <template #trigger>\n <NButton\n :loading=\"importNetwork.loading\"\n @click=\"showImportModal = true\"\n >\n 导入网络文件\n </NButton>\n </template>\n <div class=\"whitespace-nowrap\">\n 支持任意位置粘贴(Ctrl+V)文本触发导入\n </div>\n </NTooltip>\n </NSpace>\n </NPopover>\n <NTooltip>\n <template #trigger>\n <RouterLink flex to=\"/device\">\n <NButton text>\n <SvgIcon name=\"device\" />\n </NButton>\n </RouterLink>\n </template>\n 连接设备\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <a\n flex\n href=\"https://github.com/orgs/gkd-kit/discussions\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <NButton text>\n <SvgIcon name=\"discussion\" />\n </NButton>\n </a>\n </template>\n 讨论交流\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <a\n flex\n href=\"https://github.com/gkd-kit/inspect\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <NButton text>\n <SvgIcon name=\"github\" />\n </NButton>\n </a>\n </template>\n Github\n </NTooltip>\n </div>\n </div>\n <NDataTable\n v-model:checkedRowKeys=\"checkedRowKeys\"\n striped\n virtualScroll\n :data=\"filterSnapshots\"\n :columns=\"columns\"\n :scrollX=\"1800\"\n :rowKey=\"(r:Snapshot)=>r.id\"\n size=\"small\"\n class=\"flex-1\"\n flex-height\n :loading=\"loading\"\n @update:sorter=\"handleSorterChange\"\n />\n </div>\n <NModal\n :show=\"showImportModal\"\n preset=\"dialog\"\n title=\"导入网络文件\"\n :showIcon=\"false\"\n positiveText=\"确认\"\n negativeText=\"取消\"\n style=\"width: 800px\"\n :loading=\"importNetwork.loading\"\n @positiveClick=\"importNetwork.invoke\"\n @negativeClick=\"showImportModal = false\"\n @close=\"showImportModal = false\"\n @esc=\"showImportModal = false\"\n @afterEnter=\"inputImportRef?.focus()\"\n @afterLeave=\"textImportValue = ``\"\n >\n <NInput\n ref=\"inputImportRef\"\n :value=\"textImportValue\"\n type=\"textarea\"\n :placeholder=\"`1.支持ZIP文件链接\\n2.支持快照链接\\n每行一个\\n空白行自动忽略\\n非法链接行自动忽略`\"\n :autosize=\"{\n minRows: 8,\n maxRows: 16,\n }\"\n :inputProps=\"{\n style: `white-space: nowrap;`,\n }\"\n @update:value=\"\n if (!importNetwork.loading) {\n textImportValue = $event;\n }\n \"\n />\n </NModal>\n\n <NModal\n v-model:show=\"settingsDlgShow\"\n preset=\"dialog\"\n title=\"设置\"\n :showIcon=\"false\"\n positiveText=\"关闭\"\n style=\"width: 600px\"\n @positiveClick=\"settingsDlgShow = false\"\n >\n <NCheckbox v-model:checked=\"settingsStore.ignoreUploadWarn\">\n 关闭生成分享链接弹窗提醒\n </NCheckbox>\n <div h-1px my-10px bg=\"#eee\" />\n <NCheckbox v-model:checked=\"settingsStore.ignoreWasmWarn\">\n 关闭浏览器版本正则表达式 WASM(GC) 提醒\n </NCheckbox>\n <div h-1px my-10px bg=\"#eee\" />\n <div flex gap-10px>\n <NSwitch v-model:value=\"settingsStore.autoUploadImport\" />\n <div>打开快照页面自动生成分享链接(请确保不含隐私)</div>\n </div>\n </NModal>\n</template>\n","<script lang=\"tsx\" setup>\nimport ActionCard from '@/components/ActionCard.vue';\nimport BatchActionsBar from '@/components/BatchActionsBar.vue';\nimport { toValidURL } from '@/utils/check';\nimport { importFromLocal, importFromNetwork } from '@/utils/import';\nimport { getAppInfo } from '@/utils/node';\nimport { getDragEventFiles } from '@/utils/others';\nimport { shallowSnapshotStorage } from '@/utils/snapshot';\nimport { renderDevice, useSnapshotColumns } from '@/utils/table';\nimport { useTask } from '@/utils/task';\nimport type { DataTableColumns, PaginationProps } from 'naive-ui';\nimport type { SortState } from 'naive-ui/es/data-table/src/interface';\nimport { useBatchActions } from '@/composables/useBatchActions';\n\nconst { settingsStore } = useStorageStore();\n\nconst snapshots = shallowRef<Snapshot[]>([]);\nconst loading = shallowRef(true);\nconst updateSnapshots = async () => {\n loading.value = true;\n snapshots.value = (await shallowSnapshotStorage.getAllItems()).reverse();\n checkedRowKeys.value = [];\n loading.value = false;\n};\nonMounted(updateSnapshots);\nconst filterOption = shallowReactive({\n query: ``,\n actualQuery: ``,\n updateQuery: () => {\n filterOption.actualQuery = filterOption.query.trim();\n checkedRowKeys.value = [];\n },\n});\nconst filterSnapshots = computed(() => {\n const actualQuery = filterOption.actualQuery;\n if (!actualQuery) return snapshots.value;\n return snapshots.value.filter((s) => {\n return (\n (getAppInfo(s).name || ``).includes(actualQuery) ||\n (s.appId || ``).includes(actualQuery) ||\n (s.activityId || ``).includes(actualQuery)\n );\n });\n});\n\nconst importLocal = useTask(async (_files?: File[]) => {\n if (await importFromLocal(_files)) {\n await updateSnapshots();\n }\n});\n\nuseEventListener(document.body, 'drop', async (e) => {\n e.preventDefault();\n await importLocal.invoke(getDragEventFiles(e));\n});\nuseEventListener(document.body, 'dragover', (e) => {\n e.preventDefault();\n});\n\nconst {\n activityIdCol,\n appIdCol,\n appNameCol,\n ctimeCol,\n mtimeCol,\n deviceCol,\n appVersionCodeCol,\n appVersionNameCol,\n resetColWidth,\n} = useSnapshotColumns();\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(renderDevice(c)), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n deviceCol.filterOptions = undefined;\n return;\n }\n deviceCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(getAppInfo(c).name), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n appNameCol.filterOptions = undefined;\n return;\n }\n appNameCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nwatchEffect(() => {\n const set = filterSnapshots.value.reduce(\n (p, c) => (p.add(c.activityId), p),\n new Set<string>(),\n );\n if (set.size <= 1) {\n activityIdCol.filterOptions = undefined;\n return;\n }\n activityIdCol.filterOptions = [...set.values()].map((s) => ({\n value: s,\n label: s,\n }));\n});\n\nconst columns: DataTableColumns<Snapshot> = reactive([\n {\n type: 'selection',\n },\n ctimeCol,\n mtimeCol,\n deviceCol,\n appNameCol,\n appIdCol,\n appVersionCodeCol,\n appVersionNameCol,\n activityIdCol,\n {\n key: `actions`,\n title: `操作`,\n fixed: 'right',\n width: `160px`,\n render(row) {\n return <ActionCard snapshot={row} onDelete={updateSnapshots} />;\n },\n },\n]);\n\nconst pagination = shallowReactive<PaginationProps>({\n page: 1,\n pageSize: 50,\n showSizePicker: true,\n pageSizes: [50, 100],\n onChange: (page: number) => {\n pagination.page = page;\n },\n onUpdatePageSize: (pageSize: number) => {\n pagination.pageSize = pageSize;\n pagination.page = 1;\n },\n});\nwatch(pagination, resetColWidth);\n\nconst handleSorterChange = (sorter: SortState) => {\n [ctimeCol, mtimeCol].forEach((c) => {\n if (sorter.columnKey != c.key) {\n c.sortOrder = undefined;\n } else {\n c.sortOrder = sorter.order;\n }\n });\n};\nmtimeCol.sortOrder = `descend`;\nconst showImportModal = shallowRef(false);\nconst textImportValue = shallowRef(``);\nconst importNetwork = useTask(async () => {\n const urls = textImportValue.value\n .trim()\n .split(`\\n`)\n .map((u) => u.trim())\n .filter((u) => toValidURL(u));\n if (urls.length == 0) return;\n const r = await importFromNetwork(urls);\n if (!r) return;\n await updateSnapshots();\n textImportValue.value = ``;\n});\n\nuseEventListener(document.body, 'paste', (e) => {\n if (showImportModal.value) return;\n const target = e.target as HTMLElement;\n if (\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n (target.className || '').includes('input')\n ) {\n return;\n }\n const dataTransfer = e.clipboardData;\n if (!dataTransfer) return;\n const text = (dataTransfer.getData('text') || '').trim();\n if (text.startsWith('https://') || text.startsWith('http://')) {\n showImportModal.value = true;\n setTimeout(() => {\n textImportValue.value = text;\n });\n }\n});\n\nconst checkedRowKeys = ref<number[]>([]);\nconst {\n batchDelete,\n batchDownloadImage,\n batchDownloadZip,\n batchShareImageUrl,\n batchShareZipUrl,\n} = useBatchActions(checkedRowKeys, {\n onAfterDelete: updateSnapshots,\n});\n\nconst settingsDlgShow = shallowRef(false);\n\nconst inputImportRef = shallowRef();\n</script>\n<template>\n <div flex flex-col p-10px gap-10px page-size>\n <div flex>\n <NSpace>\n <NInputGroup>\n <NInput\n v-model:value=\"filterOption.query\"\n placeholder=\"请输入应用名称/应用ID/界面ID\"\n clearable\n class=\"min-w-320px\"\n @keyup.enter=\"filterOption.updateQuery\"\n @change=\"filterOption.updateQuery\"\n />\n <NButton @click=\"filterOption.updateQuery\">\n <template #icon>\n <SvgIcon name=\"search\" />\n </template>\n </NButton>\n </NInputGroup>\n <BatchActionsBar\n :checkedCount=\"checkedRowKeys.length\"\n :batchDelete=\"batchDelete\"\n :batchDownloadImage=\"batchDownloadImage\"\n :batchDownloadZip=\"batchDownloadZip\"\n :batchShareImageUrl=\"batchShareImageUrl\"\n :batchShareZipUrl=\"batchShareZipUrl\"\n />\n </NSpace>\n <div flex-1 />\n <div flex gap-24px items-center pr-8px class=\"[--svg-h:24px]\">\n <NTooltip>\n <template #trigger>\n <NButton text @click=\"settingsDlgShow = true\">\n <SvgIcon name=\"settings\" />\n </NButton>\n </template>\n 设置\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <RouterLink flex to=\"/selector\">\n <NButton text>\n <SvgIcon name=\"terminal\" />\n </NButton>\n </RouterLink>\n </template>\n 测试选择器\n </NTooltip>\n <NPopover>\n <template #trigger>\n <NButton text>\n <SvgIcon name=\"import\" />\n </NButton>\n </template>\n <NSpace vertical>\n <NTooltip placement=\"left\">\n <template #trigger>\n <NButton\n :loading=\"importLocal.loading\"\n @click=\"importLocal.invoke()\"\n >\n 导入本地文件\n </NButton>\n </template>\n <div class=\"whitespace-nowrap\">支持拖拽文件到页面任意位置</div>\n </NTooltip>\n <NTooltip placement=\"left\">\n <template #trigger>\n <NButton\n :loading=\"importNetwork.loading\"\n @click=\"showImportModal = true\"\n >\n 导入网络文件\n </NButton>\n </template>\n <div class=\"whitespace-nowrap\">\n 支持任意位置粘贴(Ctrl+V)文本触发导入\n </div>\n </NTooltip>\n </NSpace>\n </NPopover>\n <NTooltip>\n <template #trigger>\n <RouterLink flex to=\"/device\">\n <NButton text>\n <SvgIcon name=\"device\" />\n </NButton>\n </RouterLink>\n </template>\n 连接设备\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <a\n flex\n href=\"https://github.com/orgs/gkd-kit/discussions\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <NButton text>\n <SvgIcon name=\"discussion\" />\n </NButton>\n </a>\n </template>\n 讨论交流\n </NTooltip>\n <NTooltip>\n <template #trigger>\n <a\n flex\n href=\"https://github.com/gkd-kit/inspect\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <NButton text>\n <SvgIcon name=\"github\" />\n </NButton>\n </a>\n </template>\n Github\n </NTooltip>\n </div>\n </div>\n <NDataTable\n v-model:checkedRowKeys=\"checkedRowKeys\"\n striped\n virtualScroll\n :data=\"filterSnapshots\"\n :columns=\"columns\"\n :scrollX=\"1800\"\n :rowKey=\"(r:Snapshot)=>r.id\"\n size=\"small\"\n class=\"flex-1\"\n flex-height\n :loading=\"loading\"\n @update:sorter=\"handleSorterChange\"\n />\n </div>\n <NModal\n :show=\"showImportModal\"\n preset=\"dialog\"\n title=\"导入网络文件\"\n :showIcon=\"false\"\n positiveText=\"确认\"\n negativeText=\"取消\"\n style=\"width: 800px\"\n :loading=\"importNetwork.loading\"\n @positiveClick=\"importNetwork.invoke\"\n @negativeClick=\"showImportModal = false\"\n @close=\"showImportModal = false\"\n @esc=\"showImportModal = false\"\n @afterEnter=\"inputImportRef?.focus()\"\n @afterLeave=\"textImportValue = ``\"\n >\n <NInput\n ref=\"inputImportRef\"\n :value=\"textImportValue\"\n type=\"textarea\"\n :placeholder=\"`1.支持ZIP文件链接\\n2.支持快照链接\\n每行一个\\n空白行自动忽略\\n非法链接行自动忽略`\"\n :autosize=\"{\n minRows: 8,\n maxRows: 16,\n }\"\n :inputProps=\"{\n style: `white-space: nowrap;`,\n }\"\n @update:value=\"\n if (!importNetwork.loading) {\n textImportValue = $event;\n }\n \"\n />\n </NModal>\n\n <NModal\n v-model:show=\"settingsDlgShow\"\n preset=\"dialog\"\n title=\"设置\"\n :showIcon=\"false\"\n positiveText=\"关闭\"\n style=\"width: 600px\"\n @positiveClick=\"settingsDlgShow = false\"\n >\n <NCheckbox v-model:checked=\"settingsStore.ignoreUploadWarn\">\n 关闭生成分享链接弹窗提醒\n </NCheckbox>\n <div h-1px my-10px bg=\"#eee\" />\n <NCheckbox v-model:checked=\"settingsStore.ignoreWasmWarn\">\n 关闭浏览器版本正则表达式 WASM(GC) 提醒\n </NCheckbox>\n <div h-1px my-10px bg=\"#eee\" />\n <div flex gap-10px>\n <NSwitch v-model:value=\"settingsStore.autoUploadImport\" />\n <div>打开快照页面自动生成分享链接(请确保不含隐私)</div>\n </div>\n </NModal>\n</template>\n"],"x_google_ignoreList":[0,1,2,3],"mappings":"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"}