@xcpcio/board-app 0.51.1 → 0.52.0

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 (53) hide show
  1. package/dist/404.html +1 -1
  2. package/dist/assets/Board-04b0589d.js +1 -0
  3. package/dist/assets/{Board-3491f2da.css → Board-f05c0366.css} +1 -1
  4. package/dist/assets/DataSourceInput.vue_vue_type_script_setup_true_lang-11e5a08c.js +1 -0
  5. package/dist/assets/TheInput.vue_vue_type_script_setup_true_lang-f91fd6e0.js +1 -0
  6. package/dist/assets/{_...all_-e1b5a370.js → _...all_-85910c2a.js} +2 -2
  7. package/dist/assets/_...all_-905784b3.js +1 -0
  8. package/dist/assets/{_name_-1f4a93f9.js → _name_-203db09f.js} +1 -1
  9. package/dist/assets/{about-02a4c19e.js → about-d9d865e0.js} +1 -1
  10. package/dist/assets/board-3f91f491.js +1 -0
  11. package/dist/assets/{board-layout-636d6236.js → board-layout-967802f4.js} +1 -1
  12. package/dist/assets/{headless-aefb4c04.js → headless-f3f3253c.js} +1 -1
  13. package/dist/assets/{home-64be240a.js → home-3d9e3102.js} +1 -1
  14. package/dist/assets/index-0095f855.js +1 -0
  15. package/dist/assets/{index-c3e5f0aa.js → index-1e2a1259.js} +133 -133
  16. package/dist/assets/{index-9dd86d68.css → index-43f8e0d3.css} +1 -1
  17. package/dist/assets/index-86ef642b.js +1 -0
  18. package/dist/assets/index-accb347c.css +1 -0
  19. package/dist/assets/index-b97b2d45.js +1 -0
  20. package/dist/assets/index-c827bc8f.css +1 -0
  21. package/dist/assets/index-d51c6c02.js +1 -0
  22. package/dist/assets/{index-layout-899fd379.js → index-layout-5a67cc99.js} +1 -1
  23. package/dist/assets/{pagination-659cc442.js → pagination-6eac914a.js} +1 -1
  24. package/dist/assets/query-ff21040c.js +1 -0
  25. package/dist/assets/{test-daafb635.js → test-5dd32cac.js} +1 -1
  26. package/dist/assets/{user-cf30e1f8.js → user-cd9a56f6.js} +1 -1
  27. package/dist/assets/{virtual_pwa-register-876d5948.js → virtual_pwa-register-ff5720d1.js} +1 -1
  28. package/dist/index.html +1 -1
  29. package/dist/sw.js +1 -1
  30. package/package.json +4 -5
  31. package/src/components/Balloon.vue +3 -3
  32. package/src/components/BalloonBlock.vue +1 -1
  33. package/src/components/Countdown.vue +3 -8
  34. package/src/components/CustomResolver.vue +25 -0
  35. package/src/components/Resolver.vue +131 -0
  36. package/src/components/ResolverTeamRow.vue +127 -0
  37. package/src/components/board/Board.vue +1 -1
  38. package/src/components/board/StandingsAnnotate.vue +4 -2
  39. package/src/components/board/Utility.vue +7 -12
  40. package/src/components.d.ts +3 -0
  41. package/src/composables/useQueryBoardData.ts +11 -5
  42. package/src/pages/resolver/index.vue +10 -0
  43. package/uno.config.ts +2 -0
  44. package/dist/assets/Board-b8d1453a.js +0 -1
  45. package/dist/assets/DataSourceInput.vue_vue_type_script_setup_true_lang-c5f15c22.js +0 -1
  46. package/dist/assets/TheInput.vue_vue_type_script_setup_true_lang-8a64558b.js +0 -1
  47. package/dist/assets/_...all_-c9f36ec5.js +0 -1
  48. package/dist/assets/board-59a350bb.js +0 -1
  49. package/dist/assets/index-3f6dac34.js +0 -1
  50. package/dist/assets/index-67b2a8c5.css +0 -1
  51. package/dist/assets/index-6a41153b.js +0 -1
  52. package/dist/assets/index-bcded75b.js +0 -1
  53. package/dist/assets/query-ae7df373.js +0 -1
@@ -0,0 +1 @@
1
+ var q=(i,t,e)=>{if(!t.has(i))throw TypeError("Cannot "+e)};var s=(i,t,e)=>(q(i,t,"read from private field"),e?e.call(i):t.get(i)),u=(i,t,e)=>{if(t.has(i))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(i):t.set(i,e)},l=(i,t,e,n)=>(q(i,t,"write to private field"),n?n.call(i,e):t.set(i,e),e);var f=(i,t,e)=>(q(i,t,"access private method"),e);import{ax as It,ay as O,az as tt,aA as Y,aB as Qt,aC as ft,aD as pt,aE as Et,aF as Dt,aG as Ft,aH as bt,aI as Tt,aJ as Ut,aK as jt,aL as xt,h as Ot,aM as Pt,aN as Mt,v as H,aO as yt,aP as At,aQ as vt,aR as Lt,aS as $t,al as St}from"./index-1e2a1259.js";var y,a,N,b,E,P,g,W,M,A,D,F,w,L,T,$,_,et,B,st,k,it,V,nt,z,at,K,rt,G,ot,J,Ct,gt,Nt=(gt=class extends It{constructor(t,e){super();u(this,T);u(this,_);u(this,B);u(this,k);u(this,V);u(this,z);u(this,K);u(this,G);u(this,J);u(this,y,void 0);u(this,a,void 0);u(this,N,void 0);u(this,b,void 0);u(this,E,void 0);u(this,P,void 0);u(this,g,void 0);u(this,W,void 0);u(this,M,void 0);u(this,A,void 0);u(this,D,void 0);u(this,F,void 0);u(this,w,void 0);u(this,L,new Set);this.options=e,l(this,y,t),l(this,g,null),this.bindMethods(),this.setOptions(e)}bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(s(this,a).addObserver(this),mt(s(this,a),this.options)?f(this,T,$).call(this):this.updateResult(),f(this,V,nt).call(this))}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return ht(s(this,a),this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return ht(s(this,a),this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,f(this,z,at).call(this),f(this,K,rt).call(this),s(this,a).removeObserver(this)}setOptions(t,e){const n=this.options,o=s(this,a);if(this.options=s(this,y).defaultQueryOptions(t),this.options.enabled!==void 0&&typeof this.options.enabled!="boolean"&&typeof this.options.enabled!="function"&&typeof O(this.options.enabled,s(this,a))!="boolean")throw new Error("Expected enabled to be a boolean or a callback that returns a boolean");f(this,G,ot).call(this),s(this,a).setOptions(this.options),n._defaulted&&!tt(this.options,n)&&s(this,y).getQueryCache().notify({type:"observerOptionsUpdated",query:s(this,a),observer:this});const r=this.hasListeners();r&&Rt(s(this,a),o,this.options,n)&&f(this,T,$).call(this),this.updateResult(e),r&&(s(this,a)!==o||O(this.options.enabled,s(this,a))!==O(n.enabled,s(this,a))||Y(this.options.staleTime,s(this,a))!==Y(n.staleTime,s(this,a)))&&f(this,_,et).call(this);const c=f(this,B,st).call(this);r&&(s(this,a)!==o||O(this.options.enabled,s(this,a))!==O(n.enabled,s(this,a))||c!==s(this,w))&&f(this,k,it).call(this,c)}getOptimisticResult(t){const e=s(this,y).getQueryCache().build(s(this,y),t),n=this.createResult(e,t);return _t(this,n)&&(l(this,b,n),l(this,P,this.options),l(this,E,s(this,a).state)),n}getCurrentResult(){return s(this,b)}trackResult(t,e){const n={};return Object.keys(t).forEach(o=>{Object.defineProperty(n,o,{configurable:!1,enumerable:!0,get:()=>(this.trackProp(o),e==null||e(o),t[o])})}),n}trackProp(t){s(this,L).add(t)}getCurrentQuery(){return s(this,a)}refetch({...t}={}){return this.fetch({...t})}fetchOptimistic(t){const e=s(this,y).defaultQueryOptions(t),n=s(this,y).getQueryCache().build(s(this,y),e);return n.isFetchingOptimistic=!0,n.fetch().then(()=>this.createResult(n,e))}fetch(t){return f(this,T,$).call(this,{...t,cancelRefetch:t.cancelRefetch??!0}).then(()=>(this.updateResult(),s(this,b)))}createResult(t,e){var dt;const n=s(this,a),o=this.options,r=s(this,b),c=s(this,E),p=s(this,P),I=t!==n?t.state:s(this,N),{state:v}=t;let d={...v},Q=!1,h;if(e._optimisticResults){const m=this.hasListeners(),Z=!m&&mt(t,e),wt=m&&Rt(t,n,e,o);(Z||wt)&&(d={...d,...Ft(v.data,t.options)}),e._optimisticResults==="isRestoring"&&(d.fetchStatus="idle")}let{error:S,errorUpdatedAt:U,status:R}=d;if(e.select&&d.data!==void 0)if(r&&d.data===(c==null?void 0:c.data)&&e.select===s(this,W))h=s(this,M);else try{l(this,W,e.select),h=e.select(d.data),h=bt(r==null?void 0:r.data,h,e),l(this,M,h),l(this,g,null)}catch(m){l(this,g,m)}else h=d.data;if(e.placeholderData!==void 0&&h===void 0&&R==="pending"){let m;if(r!=null&&r.isPlaceholderData&&e.placeholderData===(p==null?void 0:p.placeholderData))m=r.data;else if(m=typeof e.placeholderData=="function"?e.placeholderData((dt=s(this,A))==null?void 0:dt.state.data,s(this,A)):e.placeholderData,e.select&&m!==void 0)try{m=e.select(m),l(this,g,null)}catch(Z){l(this,g,Z)}m!==void 0&&(R="success",h=bt(r==null?void 0:r.data,m,e),Q=!0)}s(this,g)&&(S=s(this,g),h=s(this,M),U=Date.now(),R="error");const j=d.fetchStatus==="fetching",x=R==="pending",X=R==="error",ct=x&&j,lt=h!==void 0;return{status:R,fetchStatus:d.fetchStatus,isPending:x,isSuccess:R==="success",isError:X,isInitialLoading:ct,isLoading:ct,data:h,dataUpdatedAt:d.dataUpdatedAt,error:S,errorUpdatedAt:U,failureCount:d.fetchFailureCount,failureReason:d.fetchFailureReason,errorUpdateCount:d.errorUpdateCount,isFetched:d.dataUpdateCount>0||d.errorUpdateCount>0,isFetchedAfterMount:d.dataUpdateCount>I.dataUpdateCount||d.errorUpdateCount>I.errorUpdateCount,isFetching:j,isRefetching:j&&!x,isLoadingError:X&&!lt,isPaused:d.fetchStatus==="paused",isPlaceholderData:Q,isRefetchError:X&&lt,isStale:ut(t,e),refetch:this.refetch}}updateResult(t){const e=s(this,b),n=this.createResult(s(this,a),this.options);if(l(this,E,s(this,a).state),l(this,P,this.options),s(this,E).data!==void 0&&l(this,A,s(this,a)),tt(n,e))return;l(this,b,n);const o={},r=()=>{if(!e)return!0;const{notifyOnChangeProps:c}=this.options,p=typeof c=="function"?c():c;if(p==="all"||!p&&!s(this,L).size)return!0;const C=new Set(p??s(this,L));return this.options.throwOnError&&C.add("error"),Object.keys(s(this,b)).some(I=>{const v=I;return s(this,b)[v]!==e[v]&&C.has(v)})};(t==null?void 0:t.listeners)!==!1&&r()&&(o.listeners=!0),f(this,J,Ct).call(this,{...o,...t})}onQueryUpdate(){this.updateResult(),this.hasListeners()&&f(this,V,nt).call(this)}},y=new WeakMap,a=new WeakMap,N=new WeakMap,b=new WeakMap,E=new WeakMap,P=new WeakMap,g=new WeakMap,W=new WeakMap,M=new WeakMap,A=new WeakMap,D=new WeakMap,F=new WeakMap,w=new WeakMap,L=new WeakMap,T=new WeakSet,$=function(t){f(this,G,ot).call(this);let e=s(this,a).fetch(this.options,t);return t!=null&&t.throwOnError||(e=e.catch(Qt)),e},_=new WeakSet,et=function(){f(this,z,at).call(this);const t=Y(this.options.staleTime,s(this,a));if(ft||s(this,b).isStale||!pt(t))return;const n=Et(s(this,b).dataUpdatedAt,t)+1;l(this,D,setTimeout(()=>{s(this,b).isStale||this.updateResult()},n))},B=new WeakSet,st=function(){return(typeof this.options.refetchInterval=="function"?this.options.refetchInterval(s(this,a)):this.options.refetchInterval)??!1},k=new WeakSet,it=function(t){f(this,K,rt).call(this),l(this,w,t),!(ft||O(this.options.enabled,s(this,a))===!1||!pt(s(this,w))||s(this,w)===0)&&l(this,F,setInterval(()=>{(this.options.refetchIntervalInBackground||Dt.isFocused())&&f(this,T,$).call(this)},s(this,w)))},V=new WeakSet,nt=function(){f(this,_,et).call(this),f(this,k,it).call(this,f(this,B,st).call(this))},z=new WeakSet,at=function(){s(this,D)&&(clearTimeout(s(this,D)),l(this,D,void 0))},K=new WeakSet,rt=function(){s(this,F)&&(clearInterval(s(this,F)),l(this,F,void 0))},G=new WeakSet,ot=function(){const t=s(this,y).getQueryCache().build(s(this,y),this.options);if(t===s(this,a))return;const e=s(this,a);l(this,a,t),l(this,N,t.state),this.hasListeners()&&(e==null||e.removeObserver(this),t.addObserver(this))},J=new WeakSet,Ct=function(t){Tt.batch(()=>{t.listeners&&this.listeners.forEach(e=>{e(s(this,b))}),s(this,y).getQueryCache().notify({query:s(this,a),type:"observerResultsUpdated"})})},gt);function Wt(i,t){return O(t.enabled,i)!==!1&&i.state.data===void 0&&!(i.state.status==="error"&&t.retryOnMount===!1)}function mt(i,t){return Wt(i,t)||i.state.data!==void 0&&ht(i,t,t.refetchOnMount)}function ht(i,t,e){if(O(t.enabled,i)!==!1){const n=typeof e=="function"?e(i):e;return n==="always"||n!==!1&&ut(i,t)}return!1}function Rt(i,t,e,n){return(i!==t||O(n.enabled,i)===!1)&&(!e.suspense||i.state.status!=="error")&&ut(i,e)}function ut(i,t){return O(t.enabled,i)!==!1&&i.isStaleByTime(Y(t.staleTime,i))}function _t(i,t){return!tt(i.getCurrentResult(),t)}function Bt(i=""){if(!Ut())throw new Error("vue-query hooks can only be used inside setup() function or functions that support injection context.");const t=xt(i),e=jt(t);if(!e)throw new Error("No 'queryClient' found in Vue context, use 'VueQueryPlugin' to properly initialize the library.");return e}function kt(i,t,e){const n=e||Bt(),o=Ot(()=>{const h=Pt(t);typeof h.enabled=="function"&&(h.enabled=h.enabled());const S=n.defaultQueryOptions(h);return S._optimisticResults=n.isRestoring.value?"isRestoring":"optimistic",S}),r=new i(n,o.value),c=Mt(r.getCurrentResult());let p=()=>{};H(n.isRestoring,h=>{h||(p(),p=r.subscribe(S=>{yt(c,S)}))},{immediate:!0});const C=()=>{r.setOptions(o.value),yt(c,r.getCurrentResult())};H(o,C),At(()=>{p()});const I=(...h)=>(C(),c.refetch(...h)),v=()=>new Promise((h,S)=>{let U=()=>{};const R=()=>{if(o.value.enabled!==!1){r.setOptions(o.value);const j=r.getOptimisticResult(o.value);j.isStale?(U(),r.fetchOptimistic(o.value).then(h,x=>{vt(o.value.throwOnError,[x,r.getCurrentQuery()])?S(x):h(r.getCurrentResult())})):(U(),h(j))}};R(),U=H(o,R)});H(()=>c.error,h=>{if(c.isError&&!c.isFetching&&vt(o.value.throwOnError,[h,r.getCurrentQuery()]))throw h});const Q=Lt(c);for(const h in c)typeof c[h]=="function"&&(Q[h]=c[h]);return Q.suspense=v,Q.refetch=I,Q}function Vt(i,t){return kt(Nt,i,t)}const zt=3;async function Kt(i,t){const e=i.startsWith("/")?i.slice(1):i;let n=`${window.DATA_HOST}${e}`;i.startsWith("http")&&(n=i),n.endsWith("/")&&(n=n.slice(0,-1));const o=await fetch(`${n}/config.json?t=${t??0}`),r=await fetch(`${n}/team.json?t=${t??0}`),c=await fetch(`${n}/run.json?t=${t??0}`),{status:p,statusText:C}=o;if(p>=300||p<200)throw new Error(`fetch data failed. [status=${p}] [statusText=${C}]`);return Promise.all([o.json(),r.json(),c.json()]).then(v=>({contest:v[0],teams:v[1],submissions:v[2]}))}function Jt(i,t,e=!1){let n=3e4,o=n;const r=Ot(()=>Math.floor(t.value.getTime()/1e3/10));return $t.value==="I18N"&&(n=10*1e3,o=n),e&&(n=Number.POSITIVE_INFINITY,o=!1),Vt({queryKey:[i,r.value],queryFn:()=>Kt(i,r.value),retry:zt,staleTime:n,refetchInterval:o})}function Xt(){return St("data-source","",{transform:String})}function Zt(){return St("battle-of-giants","",{transform:String})}export{Zt as a,Xt as g,Jt as u};
@@ -1 +1 @@
1
- import{_ as p}from"./TheInput.vue_vue_type_script_setup_true_lang-8a64558b.js";import{g as c,i as f,M as _,n as b,o as v,c as h,d as e,t as a,j as s,b as y,N as x,O as g,y as i}from"./index-c3e5f0aa.js";import{u as V}from"./user-cf30e1f8.js";const k={flex:"","flex-col":"","justify-center":"","items-center":""},w={"text-sm":"","opacity-75":""},I={"w-48":""},N={class:"hidden",for:"input"},B=["disabled"],C=c({name:"IndexPage",__name:"test",setup(R){const r=V(),o=f(r.savedName),u=_();function l(){o.value&&u.push(`/hi/${encodeURIComponent(o.value)}`)}const{t:n}=b();return(U,t)=>{const d=p;return v(),h("div",k,[t[1]||(t[1]=e("div",{"text-4xl":""},[e("div",{"i-carbon-campsite":""})],-1)),t[2]||(t[2]=e("p",null,[e("a",{rel:"noreferrer",href:"https://github.com/antfu/vitesse",target:"_blank"}," Vitesse ")],-1)),e("p",null,[e("em",w,a(s(n)("intro.desc")),1)]),t[3]||(t[3]=e("div",{"py-4":""},null,-1)),e("div",I,[y(d,{modelValue:s(o),"onUpdate:modelValue":t[0]||(t[0]=m=>x(o)?o.value=m:null),placeholder:s(n)("intro.whats-your-name"),autocomplete:"false",onKeydown:g(l,["enter"])},null,8,["modelValue","placeholder"]),e("label",N,a(s(n)("intro.whats-your-name")),1)]),e("div",null,[e("button",{"m-3":"","text-sm":"",btn:"",disabled:!s(o),onClick:l},a(s(n)("button.go")),9,B)])])}}});typeof i=="function"&&i(C);export{C as default};
1
+ import{_ as p}from"./TheInput.vue_vue_type_script_setup_true_lang-f91fd6e0.js";import{g as c,i as f,S as _,q as b,o as v,c as h,d as e,t as a,u as s,b as x,U as y,V as g,D as i}from"./index-1e2a1259.js";import{u as V}from"./user-cd9a56f6.js";const k={flex:"","flex-col":"","justify-center":"","items-center":""},w={"text-sm":"","opacity-75":""},I={"w-48":""},U={class:"hidden",for:"input"},B=["disabled"],C=c({name:"IndexPage",__name:"test",setup(N){const r=V(),o=f(r.savedName),u=_();function l(){o.value&&u.push(`/hi/${encodeURIComponent(o.value)}`)}const{t:n}=b();return(R,t)=>{const d=p;return v(),h("div",k,[t[1]||(t[1]=e("div",{"text-4xl":""},[e("div",{"i-carbon-campsite":""})],-1)),t[2]||(t[2]=e("p",null,[e("a",{rel:"noreferrer",href:"https://github.com/antfu/vitesse",target:"_blank"}," Vitesse ")],-1)),e("p",null,[e("em",w,a(s(n)("intro.desc")),1)]),t[3]||(t[3]=e("div",{"py-4":""},null,-1)),e("div",I,[x(d,{modelValue:s(o),"onUpdate:modelValue":t[0]||(t[0]=m=>y(o)?o.value=m:null),placeholder:s(n)("intro.whats-your-name"),autocomplete:"false",onKeydown:g(l,["enter"])},null,8,["modelValue","placeholder"]),e("label",U,a(s(n)("intro.whats-your-name")),1)]),e("div",null,[e("button",{"m-3":"","text-sm":"",btn:"",disabled:!s(o),onClick:l},a(s(n)("button.go")),9,B)])])}}});typeof i=="function"&&i(C);export{C as default};
@@ -1 +1 @@
1
- import{aT as m,i as r,h as t}from"./index-c3e5f0aa.js";const l=m("user",()=>{const e=r(""),s=r(new Set),o=t(()=>Array.from(s.value)),u=t(()=>o.value.filter(a=>a!==e.value));function n(a){e.value&&s.value.add(e.value),e.value=a}return{setNewName:n,otherNames:u,savedName:e}});export{l as u};
1
+ import{aW as m,i as r,h as t}from"./index-1e2a1259.js";const l=m("user",()=>{const e=r(""),s=r(new Set),o=t(()=>Array.from(s.value)),u=t(()=>o.value.filter(a=>a!==e.value));function n(a){e.value&&s.value.add(e.value),e.value=a}return{setNewName:n,otherNames:u,savedName:e}});export{l as u};
@@ -1 +1 @@
1
- import{_}from"./index-c3e5f0aa.js";function f(c={}){const{immediate:d=!1,onNeedRefresh:m,onOfflineReady:i,onRegistered:r,onRegisteredSW:s,onRegisterError:a}=c;let t,o;const l=async(n=!0)=>{await o};async function p(){if("serviceWorker"in navigator){const{Workbox:n}=await _(()=>import("./workbox-window.prod.es5-c46a1faa.js"),[],import.meta.url);t=new n("/sw.js",{scope:"/",type:"classic"}),t.addEventListener("activated",e=>{(e.isUpdate||e.isExternal)&&window.location.reload()}),t.addEventListener("installed",e=>{e.isUpdate||i==null||i()}),t.register({immediate:d}).then(e=>{s?s("/sw.js",e):r==null||r(e)}).catch(e=>{a==null||a(e)})}}return o=p(),l}export{f as registerSW};
1
+ import{_}from"./index-1e2a1259.js";function f(c={}){const{immediate:d=!1,onNeedRefresh:m,onOfflineReady:i,onRegistered:r,onRegisteredSW:s,onRegisterError:a}=c;let t,o;const l=async(n=!0)=>{await o};async function p(){if("serviceWorker"in navigator){const{Workbox:n}=await _(()=>import("./workbox-window.prod.es5-c46a1faa.js"),[],import.meta.url);t=new n("/sw.js",{scope:"/",type:"classic"}),t.addEventListener("activated",e=>{(e.isUpdate||e.isExternal)&&window.location.reload()}),t.addEventListener("installed",e=>{e.isUpdate||i==null||i()}),t.register({immediate:d}).then(e=>{s?s("/sw.js",e):r==null||r(e)}).catch(e=>{a==null||a(e)})}}return o=p(),l}export{f as registerSW};
package/dist/index.html CHANGED
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="UTF-8"><link rel="apple-touch-icon" href="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.51.1/dist/balloon-192x192.png"><link rel="mask-icon" href="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.51.1/dist/balloon-512x512.svg" color="#00aba9"><meta name="msapplication-TileColor" content="#00aba9"><script>function normalizePath(_){for(;_.endsWith("/");)_=_.slice(0,-1);return`${_}/`}{let _="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.51.1/dist";_=normalizePath(_),window.CDN_HOST=_}try{let _=__DATA_HOST__;_=normalizePath(_),window.DATA_HOST=_}catch(_){window.DATA_HOST="/data/"}try{let _=__DATA_REGION__;window.DATA_REGION=_}catch(_){window.DATA_REGION="CN"}try{let _=__DEFAULT_LANG__;window.DEFAULT_LANG=_}catch(_){window.DEFAULT_LANG="en"}</script><script>!function(){localStorage.getItem("vueuse-color-scheme")||localStorage.setItem("vueuse-color-scheme","light");const e=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches,o=localStorage.getItem("vueuse-color-scheme")||"auto";("dark"===o||e&&"light"!==o)&&document.documentElement.classList.toggle("dark",!0)}()</script><script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.51.1/dist/assets/index-c3e5f0aa.js"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.51.1/dist/assets/index-9dd86d68.css"><link rel="manifest" href="/manifest.webmanifest"></head><body class="font-sans"><div id="app"></div><noscript>This website requires JavaScript to function properly. Please enable JavaScript to continue.</noscript><script>try{var umamiJSUrl=__UMAMI_JS_URL__,umamiWebsiteId=__UMAMI_WEBSITE_ID__;!function(){var e=document.createElement("script");e.src=umamiJSUrl,e.defer=!0,e.setAttribute("data-website-id",umamiWebsiteId);var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)}()}catch(e){}try{var plausibleJSUrl=__PLAUSIBLE_JS_URL__,plausibleDataDomain=__PLAUSIBLE_DATA_DOMAIN__;!function(){var e=document.createElement("script");e.src=plausibleJSUrl,e.defer=!0,e.setAttribute("data-domain",plausibleDataDomain);var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)}()}catch(e){}try{var baiduAnalyticsId=__BAIDU_ANALYTICS_ID__,_hmt=_hmt||[];!function(){var e=document.createElement("script");e.src=`https://hm.baidu.com/hm.js?${baiduAnalyticsId}`;var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)}()}catch(e){}try{var googleAnalyticsId=__GOOGLE_ANALYTICS_ID__;!function(){var e,t,a,r,c,n;location.port||(e=window,t=document,a="script",r="ga",e.GoogleAnalyticsObject=r,e[r]=e[r]||function(){(e[r].q=e[r].q||[]).push(arguments)},e[r].l=1*new Date,c=t.createElement(a),n=t.getElementsByTagName(a)[0],c.async=1,c.src="//www.google-analytics.com/analytics.js",n.parentNode.insertBefore(c,n),ga("create",`${googleAnalyticsId}`,"auto"),ga("send","pageview"))}()}catch(e){}</script></body></html>
1
+ <!doctype html><html lang="en"><head><meta charset="UTF-8"><link rel="apple-touch-icon" href="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.52.0/dist/balloon-192x192.png"><link rel="mask-icon" href="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.52.0/dist/balloon-512x512.svg" color="#00aba9"><meta name="msapplication-TileColor" content="#00aba9"><script>function normalizePath(_){for(;_.endsWith("/");)_=_.slice(0,-1);return`${_}/`}{let _="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.52.0/dist";_=normalizePath(_),window.CDN_HOST=_}try{let _=__DATA_HOST__;_=normalizePath(_),window.DATA_HOST=_}catch(_){window.DATA_HOST="/data/"}try{let _=__DATA_REGION__;window.DATA_REGION=_}catch(_){window.DATA_REGION="CN"}try{let _=__DEFAULT_LANG__;window.DEFAULT_LANG=_}catch(_){window.DEFAULT_LANG="en"}</script><script>!function(){localStorage.getItem("vueuse-color-scheme")||localStorage.setItem("vueuse-color-scheme","light");const e=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches,o=localStorage.getItem("vueuse-color-scheme")||"auto";("dark"===o||e&&"light"!==o)&&document.documentElement.classList.toggle("dark",!0)}()</script><script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.52.0/dist/assets/index-1e2a1259.js"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.52.0/dist/assets/index-43f8e0d3.css"><link rel="manifest" href="/manifest.webmanifest"></head><body class="font-sans"><div id="app"></div><noscript>This website requires JavaScript to function properly. Please enable JavaScript to continue.</noscript><script>try{var umamiJSUrl=__UMAMI_JS_URL__,umamiWebsiteId=__UMAMI_WEBSITE_ID__;!function(){var e=document.createElement("script");e.src=umamiJSUrl,e.defer=!0,e.setAttribute("data-website-id",umamiWebsiteId);var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)}()}catch(e){}try{var plausibleJSUrl=__PLAUSIBLE_JS_URL__,plausibleDataDomain=__PLAUSIBLE_DATA_DOMAIN__;!function(){var e=document.createElement("script");e.src=plausibleJSUrl,e.defer=!0,e.setAttribute("data-domain",plausibleDataDomain);var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)}()}catch(e){}try{var baiduAnalyticsId=__BAIDU_ANALYTICS_ID__,_hmt=_hmt||[];!function(){var e=document.createElement("script");e.src=`https://hm.baidu.com/hm.js?${baiduAnalyticsId}`;var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)}()}catch(e){}try{var googleAnalyticsId=__GOOGLE_ANALYTICS_ID__;!function(){var e,t,a,r,c,n;location.port||(e=window,t=document,a="script",r="ga",e.GoogleAnalyticsObject=r,e[r]=e[r]||function(){(e[r].q=e[r].q||[]).push(arguments)},e[r].l=1*new Date,c=t.createElement(a),n=t.getElementsByTagName(a)[0],c.async=1,c.src="//www.google-analytics.com/analytics.js",n.parentNode.insertBefore(c,n),ga("create",`${googleAnalyticsId}`,"auto"),ga("send","pageview"))}()}catch(e){}</script></body></html>
package/dist/sw.js CHANGED
@@ -1 +1 @@
1
- if(!self.define){let s,e={};const l=(l,n)=>(l=new URL(l+".js",n).href,e[l]||new Promise((e=>{if("document"in self){const s=document.createElement("script");s.src=l,s.onload=e,document.head.appendChild(s)}else s=l,importScripts(l),e()})).then((()=>{let s=e[l];if(!s)throw new Error(`Module ${l} didn’t register its module`);return s})));self.define=(n,i)=>{const r=s||("document"in self?document.currentScript.src:"")||location.href;if(e[r])return;let u={};const a=s=>l(s,r),t={module:{uri:r},exports:u,require:a};e[r]=Promise.all(n.map((s=>t[s]||a(s)))).then((s=>(i(...s),u)))}}define(["./workbox-86deb690"],(function(s){"use strict";self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"assets/_...all_-c60acc8c.css",revision:null},{url:"assets/_...all_-c9f36ec5.js",revision:null},{url:"assets/_...all_-e1b5a370.js",revision:null},{url:"assets/_name_-1f4a93f9.js",revision:null},{url:"assets/about-02a4c19e.js",revision:null},{url:"assets/Board-3491f2da.css",revision:null},{url:"assets/board-59a350bb.js",revision:null},{url:"assets/Board-b8d1453a.js",revision:null},{url:"assets/board-layout-636d6236.js",revision:null},{url:"assets/DataSourceInput.vue_vue_type_script_setup_true_lang-c5f15c22.js",revision:null},{url:"assets/en-c9a8dbb5.js",revision:null},{url:"assets/headless-aefb4c04.js",revision:null},{url:"assets/home-64be240a.js",revision:null},{url:"assets/index-241beb5a.css",revision:null},{url:"assets/index-3f6dac34.js",revision:null},{url:"assets/index-67b2a8c5.css",revision:null},{url:"assets/index-6a41153b.js",revision:null},{url:"assets/index-9dd86d68.css",revision:null},{url:"assets/index-bcded75b.js",revision:null},{url:"assets/index-c3e5f0aa.js",revision:null},{url:"assets/index-layout-899fd379.js",revision:null},{url:"assets/pagination-659cc442.js",revision:null},{url:"assets/query-ae7df373.js",revision:null},{url:"assets/test-daafb635.js",revision:null},{url:"assets/TheInput.vue_vue_type_script_setup_true_lang-8a64558b.js",revision:null},{url:"assets/user-cf30e1f8.js",revision:null},{url:"assets/virtual_pwa-register-876d5948.js",revision:null},{url:"assets/workbox-window.prod.es5-c46a1faa.js",revision:null},{url:"assets/zh-CN-8e545f66.js",revision:null},{url:"index.html",revision:"d86185ca62b9430ed89dcdd2b638df01"},{url:"favicon.svg",revision:"5a744f4ccbb122d4a0575be779ddcd43"},{url:"safari-pinned-tab.svg",revision:"5eaf74d1c43d30e0af743b68a3f48504"},{url:"balloon2-192x192.png",revision:"c857ae6d9dfae118ab4397d4358422bd"},{url:"balloon2-512x512.png",revision:"065594f4f743fe3884793c03d3fe7d9e"},{url:"manifest.webmanifest",revision:"3082e8d8ebc9619c6c1055ff243a02a8"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html")))}));
1
+ if(!self.define){let s,e={};const l=(l,n)=>(l=new URL(l+".js",n).href,e[l]||new Promise((e=>{if("document"in self){const s=document.createElement("script");s.src=l,s.onload=e,document.head.appendChild(s)}else s=l,importScripts(l),e()})).then((()=>{let s=e[l];if(!s)throw new Error(`Module ${l} didn’t register its module`);return s})));self.define=(n,i)=>{const r=s||("document"in self?document.currentScript.src:"")||location.href;if(e[r])return;let u={};const a=s=>l(s,r),t={module:{uri:r},exports:u,require:a};e[r]=Promise.all(n.map((s=>t[s]||a(s)))).then((s=>(i(...s),u)))}}define(["./workbox-86deb690"],(function(s){"use strict";self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"assets/_...all_-85910c2a.js",revision:null},{url:"assets/_...all_-905784b3.js",revision:null},{url:"assets/_...all_-c60acc8c.css",revision:null},{url:"assets/_name_-203db09f.js",revision:null},{url:"assets/about-d9d865e0.js",revision:null},{url:"assets/Board-04b0589d.js",revision:null},{url:"assets/board-3f91f491.js",revision:null},{url:"assets/Board-f05c0366.css",revision:null},{url:"assets/board-layout-967802f4.js",revision:null},{url:"assets/DataSourceInput.vue_vue_type_script_setup_true_lang-11e5a08c.js",revision:null},{url:"assets/en-c9a8dbb5.js",revision:null},{url:"assets/headless-f3f3253c.js",revision:null},{url:"assets/home-3d9e3102.js",revision:null},{url:"assets/index-0095f855.js",revision:null},{url:"assets/index-1e2a1259.js",revision:null},{url:"assets/index-241beb5a.css",revision:null},{url:"assets/index-43f8e0d3.css",revision:null},{url:"assets/index-86ef642b.js",revision:null},{url:"assets/index-accb347c.css",revision:null},{url:"assets/index-b97b2d45.js",revision:null},{url:"assets/index-c827bc8f.css",revision:null},{url:"assets/index-d51c6c02.js",revision:null},{url:"assets/index-layout-5a67cc99.js",revision:null},{url:"assets/pagination-6eac914a.js",revision:null},{url:"assets/query-ff21040c.js",revision:null},{url:"assets/test-5dd32cac.js",revision:null},{url:"assets/TheInput.vue_vue_type_script_setup_true_lang-f91fd6e0.js",revision:null},{url:"assets/user-cd9a56f6.js",revision:null},{url:"assets/virtual_pwa-register-ff5720d1.js",revision:null},{url:"assets/workbox-window.prod.es5-c46a1faa.js",revision:null},{url:"assets/zh-CN-8e545f66.js",revision:null},{url:"index.html",revision:"671e920b2390887ab04c90fb1b9ce93e"},{url:"favicon.svg",revision:"5a744f4ccbb122d4a0575be779ddcd43"},{url:"safari-pinned-tab.svg",revision:"5eaf74d1c43d30e0af743b68a3f48504"},{url:"balloon2-192x192.png",revision:"c857ae6d9dfae118ab4397d4358422bd"},{url:"balloon2-512x512.png",revision:"065594f4f743fe3884793c03d3fe7d9e"},{url:"manifest.webmanifest",revision:"3082e8d8ebc9619c6c1055ff243a02a8"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html")))}));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xcpcio/board-app",
3
3
  "type": "module",
4
- "version": "0.51.1",
4
+ "version": "0.52.0",
5
5
  "description": "XCPCIO Board App",
6
6
  "author": "Dup4 <lyuzhi.pan@gmail.com>",
7
7
  "license": "MIT",
@@ -53,8 +53,8 @@
53
53
  "vue-router": "^4.4.5",
54
54
  "vue-search-select": "^3.2.0",
55
55
  "vue-toast-notification": "^3.1.3",
56
- "@xcpcio/types": "0.51.1",
57
- "@xcpcio/core": "0.51.1"
56
+ "@xcpcio/core": "0.52.0",
57
+ "@xcpcio/types": "0.52.0"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@antfu/eslint-config": "^0.39.8",
@@ -78,7 +78,6 @@
78
78
  "less": "^4.2.0",
79
79
  "markdown-it-link-attributes": "^4.0.1",
80
80
  "markdown-it-shiki": "^0.9.0",
81
- "pnpm": "^8.15.9",
82
81
  "shiki": "^0.14.7",
83
82
  "taze": "^0.11.4",
84
83
  "typescript": "^5.6.2",
@@ -99,7 +98,7 @@
99
98
  "vite-plugin-webfont-dl": "^3.9.5",
100
99
  "vite-ssg": "^0.23.8",
101
100
  "vite-ssg-sitemap": "^0.5.1",
102
- "vitest": "^0.33.0",
101
+ "vitest": "^2.1.2",
103
102
  "vue-tsc": "^1.8.27",
104
103
  "workbox-build": "^7.1.1",
105
104
  "workbox-window": "^7.1.0"
@@ -40,7 +40,7 @@ watch(data, async () => {
40
40
  reBuildBalloons();
41
41
 
42
42
  firstLoaded.value = true;
43
- });
43
+ }, { immediate: true });
44
44
 
45
45
  const balloons = computed(() => {
46
46
  return rank.value.balloons.sort(Balloon.compare).reverse().slice(0, 256);
@@ -51,13 +51,13 @@ const balloons = computed(() => {
51
51
  <div
52
52
  class="bg-[#323443]"
53
53
  text-gray-200
54
+ w-screen h-screen
54
55
  >
55
56
  <div v-if="!firstLoaded">
56
57
  <div
57
58
  flex flex-col
58
59
  justify-center items-center
59
- w-screen
60
- h-screen
60
+ w-screen h-screen
61
61
  text-xl italic
62
62
  >
63
63
  <div>
@@ -30,7 +30,7 @@ const balloonColor = computed(() => balloon.value.problem.balloonColor);
30
30
  h-24
31
31
  flex flex-row gap-x-4
32
32
  font-mono text-4xl
33
- :class="[index % 2 === 0 ? 'bg-resolver-bg-zero' : 'bg-resolver-bg-one']"
33
+ :class="[index % 2 === 0 ? 'bg-resolver-bg-0' : 'bg-resolver-bg-1']"
34
34
  >
35
35
  <div
36
36
  w-20
@@ -25,15 +25,14 @@ watch(data, async () => {
25
25
  title.value = `${contest.value.name} | ${COUNTDOWN_TITLE_SUFFIX}`;
26
26
 
27
27
  firstLoaded.value = true;
28
- });
28
+ }, { immediate: true });
29
29
  </script>
30
30
 
31
31
  <template>
32
32
  <div
33
- class="background"
33
+ class="bg-[#323443]"
34
34
  text-gray-200
35
- w-screen
36
- h-screen
35
+ w-screen h-screen
37
36
  >
38
37
  <div v-if="!firstLoaded">
39
38
  <div
@@ -91,10 +90,6 @@ watch(data, async () => {
91
90
  </template>
92
91
 
93
92
  <style scoped>
94
- .background {
95
- background-color: #333443;
96
- }
97
-
98
93
  .PENDING {
99
94
  color: #3bb4f2;
100
95
  }
@@ -0,0 +1,25 @@
1
+ <script setup lang="ts">
2
+ import { getDataSourceUrl } from "~/composables/query";
3
+
4
+ const dataSourceUrl = getDataSourceUrl();
5
+ </script>
6
+
7
+ <template>
8
+ <div
9
+ v-if="dataSourceUrl.length === 0"
10
+ >
11
+ <div
12
+ mt-20
13
+ >
14
+ <DataSourceInput />
15
+ </div>
16
+ </div>
17
+
18
+ <div
19
+ v-if="dataSourceUrl.length > 0"
20
+ >
21
+ <Resolver
22
+ :data-source-url="dataSourceUrl"
23
+ />
24
+ </div>
25
+ </template>
@@ -0,0 +1,131 @@
1
+ <script setup lang="ts">
2
+ import { onKeyUp } from "@vueuse/core";
3
+ import { ResolverVue, createContest, createSubmissions, createTeams } from "@xcpcio/core";
4
+ import type { Contest, Submissions, Teams } from "@xcpcio/core";
5
+ import type { Contest as IContest, Submissions as ISubmissions, Teams as ITeams } from "@xcpcio/types";
6
+
7
+ const props = defineProps<{
8
+ dataSourceUrl: string,
9
+ }>();
10
+
11
+ const title = useTitle(RESOLVER_TITLE_SUFFIX);
12
+ const { t } = useI18n();
13
+
14
+ const firstLoaded = ref(false);
15
+ const contest = ref({} as Contest);
16
+ const teams = ref([] as Teams);
17
+ const submissions = ref([] as Submissions);
18
+ const resolver = ref({} as ResolverVue);
19
+ const now = useNow();
20
+
21
+ function reBuildResolver() {
22
+ const newResolver = new ResolverVue(contest.value, teams.value, submissions.value);
23
+ newResolver.buildResolver();
24
+ resolver.value = newResolver;
25
+ }
26
+
27
+ const { data, isError, error } = useQueryBoardData(props.dataSourceUrl, now, /* queryOnce= */true);
28
+ watch(data, async () => {
29
+ if (data.value === null || data.value === undefined) {
30
+ return;
31
+ }
32
+
33
+ contest.value = createContest(data.value?.contest as IContest);
34
+ title.value = `${contest.value.name} | ${RESOLVER_TITLE_SUFFIX}`;
35
+
36
+ teams.value = createTeams(data.value?.teams as ITeams);
37
+ submissions.value = createSubmissions(data.value?.submissions as ISubmissions);
38
+
39
+ reBuildResolver();
40
+
41
+ firstLoaded.value = true;
42
+ }, { immediate: true });
43
+
44
+ onKeyStroke([" "], (e) => {
45
+ e.preventDefault();
46
+ });
47
+
48
+ onKeyUp(["n", " "], () => {
49
+ resolver.value.next();
50
+ }, { dedupe: true });
51
+
52
+ onKeyUp(["r"], () => {
53
+ resolver.value.rewind();
54
+ }, { dedupe: true });
55
+ </script>
56
+
57
+ <template>
58
+ <div
59
+
60
+ text-gray-200
61
+ w-screen h-screen
62
+ >
63
+ <div v-if="!firstLoaded">
64
+ <div
65
+ flex flex-col
66
+ justify-center items-center
67
+ w-screen h-screen
68
+ text-xl italic
69
+ class="bg-[#323443]"
70
+ >
71
+ <div>
72
+ {{ t("common.loading") }}...
73
+ </div>
74
+
75
+ <div v-if="isError">
76
+ {{ error }}
77
+ </div>
78
+ </div>
79
+ </div>
80
+
81
+ <div
82
+ v-else
83
+ >
84
+ <div
85
+ class="bg-resolver-bg-1"
86
+ flex flex-col
87
+ justify-between
88
+ font-mono
89
+ >
90
+ <TransitionGroup
91
+ name="resolver"
92
+ tag="ul"
93
+ >
94
+ <template
95
+ v-for="(team, index) in resolver.teams"
96
+ :key="team.id"
97
+ >
98
+ <div
99
+ position-relative
100
+ :class="[team.id === resolver.currentTeamId ? 'z-999' : 'z-0']"
101
+ >
102
+ <ResolverTeamRow
103
+ :index="index"
104
+ :team="team"
105
+ :resolver="resolver"
106
+ />
107
+ </div>
108
+ </template>
109
+ </TransitionGroup>
110
+ </div>
111
+ </div>
112
+ </div>
113
+ </template>
114
+
115
+ <style scoped>
116
+ .resolver-move,
117
+ .resolver-enter-active,
118
+ .resolver-leave-active {
119
+ transition: all 2s ease;
120
+ }
121
+
122
+ .resolver-enter-from,
123
+ .resolver-leave-to {
124
+ opacity: 0;
125
+ transform: translateX(30px);
126
+ }
127
+
128
+ .resolver-leave-active {
129
+ position: absolute;
130
+ }
131
+ </style>
@@ -0,0 +1,127 @@
1
+ <script setup lang="ts">
2
+ import type { ResolverVue, Team } from "@xcpcio/core";
3
+
4
+ const props = defineProps<{
5
+ index: number;
6
+ team: Team;
7
+ resolver: ResolverVue;
8
+ }>();
9
+
10
+ const index = computed(() => props.index);
11
+ const team = computed(() => props.team);
12
+ const resolver = computed(() => props.resolver);
13
+ const el = ref(null);
14
+
15
+ // TODO(Dup4): Optimizing performance with useElementVisibility
16
+ // const isVisible = useElementVisibility(el);
17
+ const isVisible = true;
18
+
19
+ function showTeamName(team: Team) {
20
+ const sections = [team.organization, team.name];
21
+ return sections.filter(s => s).join(" - ");
22
+ }
23
+ </script>
24
+
25
+ <template>
26
+ <div
27
+ ref="el"
28
+ h-24
29
+ >
30
+ <div
31
+ v-if="isVisible"
32
+ h-24
33
+ flex flex-row gap-x-4
34
+ font-mono text-4xl
35
+ :class="[index % 2 === 0 ? 'bg-resolver-bg-zero' : 'bg-resolver-bg-one',
36
+ resolver.duringAnimation && resolver.currentTeamId === team.id ? 'bg-resolver-selected' : '',
37
+ !resolver.duringAnimation && index === resolver.currentIndex ? 'bg-resolver-selected' : '',
38
+ ]"
39
+ >
40
+ <div
41
+ w-20
42
+ flex flex-shrink-0 justify-center items-center
43
+ >
44
+ <div>
45
+ {{ team.rank }}
46
+ </div>
47
+ </div>
48
+
49
+ <div
50
+ flex flex-1 flex-col justify-center items-start gap-y-3
51
+ >
52
+ <Tooltip>
53
+ <div
54
+ class="resolver-team-name"
55
+ truncate overflow-hidden
56
+ >
57
+ {{ showTeamName(team) }}
58
+ </div>
59
+ <template #popper>
60
+ <div>
61
+ {{ showTeamName(team) }}
62
+ </div>
63
+ </template>
64
+ </Tooltip>
65
+
66
+ <div
67
+ flex flex-row text-sm items-start gap-x-2
68
+ >
69
+ <template
70
+ v-for="(p, pIndex) in team.problemStatistics"
71
+ :key="p.problem.id"
72
+ >
73
+ <div
74
+ class="rounded w-22 h-7 flex justify-center items-center"
75
+ :class="[p.isAccepted ? 'bg-resolver-ac' : '',
76
+ p.isWrongAnswer ? 'bg-resolver-wa' : '',
77
+ p.isPending ? 'bg-resolver-pending' : '',
78
+ p.isUnSubmitted ? 'bg-resolver-untouched' : '',
79
+ resolver.problemFlashingEnded === false
80
+ && index === resolver.currentIndex
81
+ && resolver.currentProblemIndex === pIndex
82
+ ? 'resolver-uncover'
83
+ : '',
84
+ ]"
85
+ >
86
+ <template v-if="p.isAccepted">
87
+ {{ `${p.failedCount + Number(p.isAccepted)}/${Math.floor(p.lastSubmitTimestamp / 60)}` }}
88
+ </template>
89
+ <template v-if="p.isWrongAnswer">
90
+ {{ `${p.failedCount}/${Math.floor(p.lastSubmitTimestamp / 60)}` }}
91
+ </template>
92
+ <template v-if="p.isPending">
93
+ {{ `${p.failedCount} + ${p.pendingCount}` }}
94
+ </template>
95
+ <template v-if="p.isUnSubmitted">
96
+ {{ p.problem.label }}
97
+ </template>
98
+ </div>
99
+ </template>
100
+ </div>
101
+ </div>
102
+
103
+ <div
104
+ w-48
105
+ flex flex-shrink-0 flex-row justify-start items-center
106
+ >
107
+ <div class="w-1/3">
108
+ {{ team.solvedProblemNum }}
109
+ </div>
110
+ <div class="w-2/3">
111
+ {{ team.penaltyToMinute }}
112
+ </div>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ </template>
117
+
118
+ <style scoped>
119
+ .resolver-uncover {
120
+ animation: flashing 300ms infinite;
121
+ -webkit-animation: flashing 30ms infinite; /*Safari and Chrome*/
122
+ }
123
+
124
+ .resolver-team-name {
125
+ max-width: calc(100vw - 80px - 192px - 112px);
126
+ }
127
+ </style>
@@ -113,7 +113,7 @@ watch(data, async () => {
113
113
  reBuildRank();
114
114
 
115
115
  firstLoaded.value = true;
116
- });
116
+ }, { immediate: true });
117
117
 
118
118
  function dynamicReBuildRank() {
119
119
  if (firstLoaded.value === false) {
@@ -1,5 +1,7 @@
1
1
  <template>
2
- <div class="flex items-center justify-center dark:text-black">
2
+ <div
3
+ flex items-center justify-center dark:text-black
4
+ >
3
5
  <table>
4
6
  <tbody>
5
7
  <tr>
@@ -25,7 +27,7 @@
25
27
  Attempted problem
26
28
  </td>
27
29
  <td class="pending">
28
- Pending judgement / Frozen
30
+ Pending judgement/Frozen
29
31
  </td>
30
32
  </tr>
31
33
  </tbody>
@@ -1,16 +1,12 @@
1
1
  <script setup lang="ts">
2
- // const props = defineProps<{
3
- // rank: Rank,
4
- // }>();
5
-
6
2
  const { t } = useI18n();
7
3
 
8
4
  const route = useRoute();
9
5
  const router = useRouter();
10
6
 
11
- const resolverUrl = computed(() => {
12
- return `https://resolver.xcpcio.com/resolver?xcpcio-data-source=${route.path}`;
13
- });
7
+ function goResolver() {
8
+ router.push(`/resolver/?data-source=${route.path}`);
9
+ }
14
10
 
15
11
  function goBalloon() {
16
12
  router.push(`/balloon/?data-source=${route.path}`);
@@ -47,14 +43,13 @@ function goCountdown() {
47
43
  w-full
48
44
  flex mt-4 gap-4
49
45
  >
50
- <a
46
+ <button
51
47
  btn
52
- :href="resolverUrl"
53
- target="_blank"
54
48
  title="Resolver"
49
+ @click="goResolver"
55
50
  >
56
- {{ t("type_menu.resolver") }}
57
- </a>
51
+ {{ t('type_menu.resolver') }}
52
+ </button>
58
53
 
59
54
  <button
60
55
  btn
@@ -21,6 +21,7 @@ declare module 'vue' {
21
21
  CustomBalloon: typeof import('./components/CustomBalloon.vue')['default']
22
22
  CustomBoard: typeof import('./components/CustomBoard.vue')['default']
23
23
  CustomCountdown: typeof import('./components/CustomCountdown.vue')['default']
24
+ CustomResolver: typeof import('./components/CustomResolver.vue')['default']
24
25
  DataSourceInput: typeof import('./components/DataSourceInput.vue')['default']
25
26
  Export: typeof import('./components/board/Export.vue')['default']
26
27
  Footer: typeof import('./components/Footer.vue')['default']
@@ -42,6 +43,8 @@ declare module 'vue' {
42
43
  RatingTable: typeof import('./components/rating/RatingTable.vue')['default']
43
44
  RatingUserUI: typeof import('./components/rating/RatingUserUI.vue')['default']
44
45
  ReactionVideoModal: typeof import('./components/board/ReactionVideoModal.vue')['default']
46
+ Resolver: typeof import('./components/Resolver.vue')['default']
47
+ ResolverTeamRow: typeof import('./components/ResolverTeamRow.vue')['default']
45
48
  RightArrowIcon: typeof import('./components/icon/RightArrowIcon.vue')['default']
46
49
  RouterLink: typeof import('vue-router')['RouterLink']
47
50
  RouterView: typeof import('vue-router')['RouterView']
@@ -45,20 +45,26 @@ async function fetcher(target: string, timestamp?: number): Promise<BoardData> {
45
45
  return p;
46
46
  }
47
47
 
48
- export function useQueryBoardData(target: string, timestamp?: any) {
49
- let refetchInterval = 30 * 1000;
48
+ export function useQueryBoardData(target: string, timestamp?: any, queryOnce = false) {
49
+ let staleTime = 30 * 1000;
50
+ let refetchInterval: number | false = staleTime;
50
51
  const timestampSeconds = computed(() => Math.floor(timestamp.value.getTime() / 1000 / 10));
51
52
 
52
53
  if (DATA_REGION.value === "I18N") {
53
- refetchInterval = 10 * 1000;
54
- // timestampSeconds = computed(() => Math.floor(timestamp.value.getTime() / 1000));
54
+ staleTime = 10 * 1000;
55
+ refetchInterval = staleTime;
56
+ }
57
+
58
+ if (queryOnce) {
59
+ staleTime = Number.POSITIVE_INFINITY;
60
+ refetchInterval = false;
55
61
  }
56
62
 
57
63
  return useQuery({
58
64
  queryKey: [target, timestampSeconds.value],
59
65
  queryFn: () => fetcher(target, timestampSeconds.value),
60
66
  retry: RETRY,
61
- staleTime: refetchInterval,
67
+ staleTime,
62
68
  refetchInterval,
63
69
  });
64
70
  }
@@ -0,0 +1,10 @@
1
+ <template>
2
+ <div>
3
+ <CustomResolver />
4
+ </div>
5
+ </template>
6
+
7
+ <route lang="yaml">
8
+ meta:
9
+ layout: headless
10
+ </route>
package/uno.config.ts CHANGED
@@ -33,7 +33,9 @@ export default defineConfig({
33
33
  selected: "var(--theme-resolver-selected)",
34
34
  bg: {
35
35
  zero: "var(--theme-resolver-bg-0)",
36
+ 0: "var(--theme-resolver-bg-0)",
36
37
  one: "var(--theme-resolver-bg-1)",
38
+ 1: "var(--theme-resolver-bg-1)",
37
39
  },
38
40
  },
39
41
  },