diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index 58222c1..b78d4d8 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -62,7 +62,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: results-${{ matrix.fixture }}-${{ matrix.variation }} - path: ./results/${{ matrix.fixture }}/${{ matrix.variation }}/ + path: ./${{ matrix.fixture }}/${{ matrix.variation }}/ retention-days: 7 process: name: 'Process Results' @@ -78,11 +78,13 @@ jobs: - name: Download Results uses: actions/download-artifact@v4 with: - path: results - pattern: results-* + path: ./ - name: Process Results run: | bash ./scripts/process-results.sh + - name: Build Charts View + run: | + vlr build - name: Upload Processed Results uses: actions/upload-artifact@v4 with: diff --git a/.gitignore b/.gitignore index 38726d6..6e3f9f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,14 @@ +# system .DS_Store -results + +# deps +node_modules + +# build .nx/installation .nx/cache -.nx/workspace-data \ No newline at end of file +.nx/workspace-data + +results +dist +chart diff --git a/README.md b/README.md index 2b91466..611ebbb 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ package-manager: X.XXs (stddev: X.XXs) ### Generated Results -Results are organized by date in the `chart/results/YYYY-MM-DD/` directory: +Results are organized by date in the `charts/YYYY-MM-DD/` directory: - `-.json`: Cold cache installation results - `--package-count.json`: The count of packages installed for each package manager for a given fixture and variation - `index.html`: Interactive visualization diff --git a/chart/index.html b/chart/index.html deleted file mode 100644 index 10241c2..0000000 --- a/chart/index.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - Benchmark - - - -
- -
- - - - diff --git a/chart/styles.css b/chart/styles.css deleted file mode 100644 index 620434d..0000000 --- a/chart/styles.css +++ /dev/null @@ -1,32 +0,0 @@ -body { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; - line-height: 1.6; - margin: 0; - padding: 20px; - background-color: #f5f5f5; -} - -.container { - max-width: 1200px; - margin: 0 auto; - background-color: white; - padding: 20px; - border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} - -h1 { - margin: 0 0 10px 0; - color: #333; -} - -.date { - color: #666; - margin-bottom: 20px; -} - -.chart-container { - position: relative; - height: 600px; - width: 100%; -} \ No newline at end of file diff --git a/charts/assets/GeistMono-VariableFont_wght-BlNDD6KS.ttf b/charts/assets/GeistMono-VariableFont_wght-BlNDD6KS.ttf new file mode 100644 index 0000000..f86f195 Binary files /dev/null and b/charts/assets/GeistMono-VariableFont_wght-BlNDD6KS.ttf differ diff --git a/charts/assets/Inter-Italic-VariableFont_opsz_wght-B-9PvMw6.ttf b/charts/assets/Inter-Italic-VariableFont_opsz_wght-B-9PvMw6.ttf new file mode 100644 index 0000000..43ed4f5 Binary files /dev/null and b/charts/assets/Inter-Italic-VariableFont_opsz_wght-B-9PvMw6.ttf differ diff --git a/charts/assets/Inter-VariableFont_opsz_wght-c8O0ljhh.ttf b/charts/assets/Inter-VariableFont_opsz_wght-c8O0ljhh.ttf new file mode 100644 index 0000000..e31b51e Binary files /dev/null and b/charts/assets/Inter-VariableFont_opsz_wght-c8O0ljhh.ttf differ diff --git a/charts/assets/index-BILFLdu-.js b/charts/assets/index-BILFLdu-.js new file mode 100644 index 0000000..830a750 --- /dev/null +++ b/charts/assets/index-BILFLdu-.js @@ -0,0 +1,256 @@ +function KL(e,t){for(var n=0;nr[i]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const l of i)if(l.type==="childList")for(const s of l.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&r(s)}).observe(document,{childList:!0,subtree:!0});function n(i){const l={};return i.integrity&&(l.integrity=i.integrity),i.referrerPolicy&&(l.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?l.credentials="include":i.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function r(i){if(i.ep)return;i.ep=!0;const l=n(i);fetch(i.href,l)}})();function zr(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var av={exports:{}},ls={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var AE;function YL(){if(AE)return ls;AE=1;var e=Symbol.for("react.transitional.element"),t=Symbol.for("react.fragment");function n(r,i,l){var s=null;if(l!==void 0&&(s=""+l),i.key!==void 0&&(s=""+i.key),"key"in i){l={};for(var c in i)c!=="key"&&(l[c]=i[c])}else l=i;return i=l.ref,{$$typeof:e,type:r,key:s,ref:i!==void 0?i:null,props:l}}return ls.Fragment=t,ls.jsx=n,ls.jsxs=n,ls}var CE;function XL(){return CE||(CE=1,av.exports=YL()),av.exports}var D=XL(),iv={exports:{}},Be={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var _E;function WL(){if(_E)return Be;_E=1;var e=Symbol.for("react.transitional.element"),t=Symbol.for("react.portal"),n=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),l=Symbol.for("react.consumer"),s=Symbol.for("react.context"),c=Symbol.for("react.forward_ref"),f=Symbol.for("react.suspense"),h=Symbol.for("react.memo"),g=Symbol.for("react.lazy"),m=Symbol.iterator;function p(j){return j===null||typeof j!="object"?null:(j=m&&j[m]||j["@@iterator"],typeof j=="function"?j:null)}var y={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},x=Object.assign,w={};function E(j,X,Z){this.props=j,this.context=X,this.refs=w,this.updater=Z||y}E.prototype.isReactComponent={},E.prototype.setState=function(j,X){if(typeof j!="object"&&typeof j!="function"&&j!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,j,X,"setState")},E.prototype.forceUpdate=function(j){this.updater.enqueueForceUpdate(this,j,"forceUpdate")};function O(){}O.prototype=E.prototype;function _(j,X,Z){this.props=j,this.context=X,this.refs=w,this.updater=Z||y}var A=_.prototype=new O;A.constructor=_,x(A,E.prototype),A.isPureReactComponent=!0;var P=Array.isArray,T={H:null,A:null,T:null,S:null,V:null},M=Object.prototype.hasOwnProperty;function N(j,X,Z,te,de,Ae){return Z=Ae.ref,{$$typeof:e,type:j,key:X,ref:Z!==void 0?Z:null,props:Ae}}function $(j,X){return N(j.type,X,void 0,void 0,void 0,j.props)}function G(j){return typeof j=="object"&&j!==null&&j.$$typeof===e}function ue(j){var X={"=":"=0",":":"=2"};return"$"+j.replace(/[=:]/g,function(Z){return X[Z]})}var Q=/\/+/g;function ae(j,X){return typeof j=="object"&&j!==null&&j.key!=null?ue(""+j.key):X.toString(36)}function se(){}function ce(j){switch(j.status){case"fulfilled":return j.value;case"rejected":throw j.reason;default:switch(typeof j.status=="string"?j.then(se,se):(j.status="pending",j.then(function(X){j.status==="pending"&&(j.status="fulfilled",j.value=X)},function(X){j.status==="pending"&&(j.status="rejected",j.reason=X)})),j.status){case"fulfilled":return j.value;case"rejected":throw j.reason}}throw j}function he(j,X,Z,te,de){var Ae=typeof j;(Ae==="undefined"||Ae==="boolean")&&(j=null);var xe=!1;if(j===null)xe=!0;else switch(Ae){case"bigint":case"string":case"number":xe=!0;break;case"object":switch(j.$$typeof){case e:case t:xe=!0;break;case g:return xe=j._init,he(xe(j._payload),X,Z,te,de)}}if(xe)return de=de(j),xe=te===""?"."+ae(j,0):te,P(de)?(Z="",xe!=null&&(Z=xe.replace(Q,"$&/")+"/"),he(de,X,Z,"",function(ge){return ge})):de!=null&&(G(de)&&(de=$(de,Z+(de.key==null||j&&j.key===de.key?"":(""+de.key).replace(Q,"$&/")+"/")+xe)),X.push(de)),1;xe=0;var Re=te===""?".":te+":";if(P(j))for(var Ke=0;Ke>>1,j=z[ne];if(0>>1;nei(te,U))dei(Ae,te)?(z[ne]=Ae,z[de]=U,ne=de):(z[ne]=te,z[Z]=U,ne=Z);else if(dei(Ae,U))z[ne]=Ae,z[de]=U,ne=de;else break e}}return W}function i(z,W){var U=z.sortIndex-W.sortIndex;return U!==0?U:z.id-W.id}if(e.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var l=performance;e.unstable_now=function(){return l.now()}}else{var s=Date,c=s.now();e.unstable_now=function(){return s.now()-c}}var f=[],h=[],g=1,m=null,p=3,y=!1,x=!1,w=!1,E=!1,O=typeof setTimeout=="function"?setTimeout:null,_=typeof clearTimeout=="function"?clearTimeout:null,A=typeof setImmediate<"u"?setImmediate:null;function P(z){for(var W=n(h);W!==null;){if(W.callback===null)r(h);else if(W.startTime<=z)r(h),W.sortIndex=W.expirationTime,t(f,W);else break;W=n(h)}}function T(z){if(w=!1,P(z),!x)if(n(f)!==null)x=!0,M||(M=!0,ae());else{var W=n(h);W!==null&&he(T,W.startTime-z)}}var M=!1,N=-1,$=5,G=-1;function ue(){return E?!0:!(e.unstable_now()-G<$)}function Q(){if(E=!1,M){var z=e.unstable_now();G=z;var W=!0;try{e:{x=!1,w&&(w=!1,_(N),N=-1),y=!0;var U=p;try{t:{for(P(z),m=n(f);m!==null&&!(m.expirationTime>z&&ue());){var ne=m.callback;if(typeof ne=="function"){m.callback=null,p=m.priorityLevel;var j=ne(m.expirationTime<=z);if(z=e.unstable_now(),typeof j=="function"){m.callback=j,P(z),W=!0;break t}m===n(f)&&r(f),P(z)}else r(f);m=n(f)}if(m!==null)W=!0;else{var X=n(h);X!==null&&he(T,X.startTime-z),W=!1}}break e}finally{m=null,p=U,y=!1}W=void 0}}finally{W?ae():M=!1}}}var ae;if(typeof A=="function")ae=function(){A(Q)};else if(typeof MessageChannel<"u"){var se=new MessageChannel,ce=se.port2;se.port1.onmessage=Q,ae=function(){ce.postMessage(null)}}else ae=function(){O(Q,0)};function he(z,W){N=O(function(){z(e.unstable_now())},W)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(z){z.callback=null},e.unstable_forceFrameRate=function(z){0>z||125ne?(z.sortIndex=U,t(h,z),n(f)===null&&z===n(h)&&(w?(_(N),N=-1):w=!0,he(T,U-ne))):(z.sortIndex=j,t(f,z),x||y||(x=!0,M||(M=!0,ae()))),z},e.unstable_shouldYield=ue,e.unstable_wrapCallback=function(z){var W=p;return function(){var U=p;p=W;try{return z.apply(this,arguments)}finally{p=U}}}}(uv)),uv}var TE;function QL(){return TE||(TE=1,lv.exports=ZL()),lv.exports}var sv={exports:{}},dn={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var PE;function JL(){if(PE)return dn;PE=1;var e=eu();function t(f){var h="https://react.dev/errors/"+f;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}return e(),sv.exports=JL(),sv.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var jE;function ez(){if(jE)return us;jE=1;var e=QL(),t=eu(),n=FM();function r(a){var o="https://react.dev/errors/"+a;if(1j||(a.current=ne[j],ne[j]=null,j--)}function te(a,o){j++,ne[j]=a.current,a.current=o}var de=X(null),Ae=X(null),xe=X(null),Re=X(null);function Ke(a,o){switch(te(xe,o),te(Ae,a),te(de,null),o.nodeType){case 9:case 11:a=(a=o.documentElement)&&(a=a.namespaceURI)?J1(a):0;break;default:if(a=o.tagName,o=o.namespaceURI)o=J1(o),a=eE(o,a);else switch(a){case"svg":a=1;break;case"math":a=2;break;default:a=0}}Z(de),te(de,a)}function ge(){Z(de),Z(Ae),Z(xe)}function ve(a){a.memoizedState!==null&&te(Re,a);var o=de.current,u=eE(o,a.type);o!==u&&(te(Ae,a),te(de,u))}function Ne(a){Ae.current===a&&(Z(de),Z(Ae)),Re.current===a&&(Z(Re),ns._currentValue=U)}var le=Object.prototype.hasOwnProperty,pt=e.unstable_scheduleCallback,qe=e.unstable_cancelCallback,en=e.unstable_shouldYield,tn=e.unstable_requestPaint,Rt=e.unstable_now,Uo=e.unstable_getCurrentPriorityLevel,pc=e.unstable_ImmediatePriority,yc=e.unstable_UserBlockingPriority,Ho=e.unstable_NormalPriority,oa=e.unstable_LowPriority,Ka=e.unstable_IdlePriority,bc=e.log,du=e.unstable_setDisableYieldValue,Sn=null,St=null;function _r(a){if(typeof bc=="function"&&du(a),St&&typeof St.setStrictMode=="function")try{St.setStrictMode(Sn,a)}catch{}}var nn=Math.clz32?Math.clz32:wc,eg=Math.log,Br=Math.LN2;function wc(a){return a>>>=0,a===0?32:31-(eg(a)/Br|0)|0}var Ui=256,Hi=4194304;function la(a){var o=a&42;if(o!==0)return o;switch(a&-a){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a&4194048;case 4194304:case 8388608:case 16777216:case 33554432:return a&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return a}}function Fi(a,o,u){var d=a.pendingLanes;if(d===0)return 0;var v=0,b=a.suspendedLanes,C=a.pingedLanes;a=a.warmLanes;var R=d&134217727;return R!==0?(d=R&~b,d!==0?v=la(d):(C&=R,C!==0?v=la(C):u||(u=R&~a,u!==0&&(v=la(u))))):(R=d&~b,R!==0?v=la(R):C!==0?v=la(C):u||(u=d&~a,u!==0&&(v=la(u)))),v===0?0:o!==0&&o!==v&&(o&b)===0&&(b=v&-v,u=o&-o,b>=u||b===32&&(u&4194048)!==0)?o:v}function Ur(a,o){return(a.pendingLanes&~(a.suspendedLanes&~a.pingedLanes)&o)===0}function xc(a,o){switch(a){case 1:case 2:case 4:case 8:case 64:return o+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return o+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Fo(){var a=Ui;return Ui<<=1,(Ui&4194048)===0&&(Ui=256),a}function Sc(){var a=Hi;return Hi<<=1,(Hi&62914560)===0&&(Hi=4194304),a}function qo(a){for(var o=[],u=0;31>u;u++)o.push(a);return o}function qi(a,o){a.pendingLanes|=o,o!==268435456&&(a.suspendedLanes=0,a.pingedLanes=0,a.warmLanes=0)}function Ec(a,o,u,d,v,b){var C=a.pendingLanes;a.pendingLanes=u,a.suspendedLanes=0,a.pingedLanes=0,a.warmLanes=0,a.expiredLanes&=u,a.entangledLanes&=u,a.errorRecoveryDisabledLanes&=u,a.shellSuspendCounter=0;var R=a.entanglements,k=a.expirationTimes,q=a.hiddenUpdates;for(u=C&~u;0)":-1v||k[d]!==q[v]){var ee=` +`+k[d].replace(" at new "," at ");return a.displayName&&ee.includes("")&&(ee=ee.replace("",a.displayName)),ee}while(1<=d&&0<=v);break}}}finally{Et=!1,Error.prepareStackTrace=u}return(u=a?a.displayName||a.name:"")?ar(u):""}function Oc(a){switch(a.tag){case 26:case 27:case 5:return ar(a.type);case 16:return ar("Lazy");case 13:return ar("Suspense");case 19:return ar("SuspenseList");case 0:case 15:return Xa(a.type,!1);case 11:return Xa(a.type.render,!1);case 1:return Xa(a.type,!0);case 31:return ar("Activity");default:return""}}function Ac(a){try{var o="";do o+=Oc(a),a=a.return;while(a);return o}catch(u){return` +Error generating stack: `+u.message+` +`+u.stack}}function ir(a){switch(typeof a){case"bigint":case"boolean":case"number":case"string":case"undefined":return a;case"object":return a;default:return""}}function Yw(a){var o=a.type;return(a=a.nodeName)&&a.toLowerCase()==="input"&&(o==="checkbox"||o==="radio")}function HN(a){var o=Yw(a)?"checked":"value",u=Object.getOwnPropertyDescriptor(a.constructor.prototype,o),d=""+a[o];if(!a.hasOwnProperty(o)&&typeof u<"u"&&typeof u.get=="function"&&typeof u.set=="function"){var v=u.get,b=u.set;return Object.defineProperty(a,o,{configurable:!0,get:function(){return v.call(this)},set:function(C){d=""+C,b.call(this,C)}}),Object.defineProperty(a,o,{enumerable:u.enumerable}),{getValue:function(){return d},setValue:function(C){d=""+C},stopTracking:function(){a._valueTracker=null,delete a[o]}}}}function Cc(a){a._valueTracker||(a._valueTracker=HN(a))}function Xw(a){if(!a)return!1;var o=a._valueTracker;if(!o)return!0;var u=o.getValue(),d="";return a&&(d=Yw(a)?a.checked?"true":"false":a.value),a=d,a!==u?(o.setValue(a),!0):!1}function _c(a){if(a=a||(typeof document<"u"?document:void 0),typeof a>"u")return null;try{return a.activeElement||a.body}catch{return a.body}}var FN=/[\n"\\]/g;function or(a){return a.replace(FN,function(o){return"\\"+o.charCodeAt(0).toString(16)+" "})}function tg(a,o,u,d,v,b,C,R){a.name="",C!=null&&typeof C!="function"&&typeof C!="symbol"&&typeof C!="boolean"?a.type=C:a.removeAttribute("type"),o!=null?C==="number"?(o===0&&a.value===""||a.value!=o)&&(a.value=""+ir(o)):a.value!==""+ir(o)&&(a.value=""+ir(o)):C!=="submit"&&C!=="reset"||a.removeAttribute("value"),o!=null?ng(a,C,ir(o)):u!=null?ng(a,C,ir(u)):d!=null&&a.removeAttribute("value"),v==null&&b!=null&&(a.defaultChecked=!!b),v!=null&&(a.checked=v&&typeof v!="function"&&typeof v!="symbol"),R!=null&&typeof R!="function"&&typeof R!="symbol"&&typeof R!="boolean"?a.name=""+ir(R):a.removeAttribute("name")}function Ww(a,o,u,d,v,b,C,R){if(b!=null&&typeof b!="function"&&typeof b!="symbol"&&typeof b!="boolean"&&(a.type=b),o!=null||u!=null){if(!(b!=="submit"&&b!=="reset"||o!=null))return;u=u!=null?""+ir(u):"",o=o!=null?""+ir(o):u,R||o===a.value||(a.value=o),a.defaultValue=o}d=d??v,d=typeof d!="function"&&typeof d!="symbol"&&!!d,a.checked=R?a.checked:!!d,a.defaultChecked=!!d,C!=null&&typeof C!="function"&&typeof C!="symbol"&&typeof C!="boolean"&&(a.name=C)}function ng(a,o,u){o==="number"&&_c(a.ownerDocument)===a||a.defaultValue===""+u||(a.defaultValue=""+u)}function Go(a,o,u,d){if(a=a.options,o){o={};for(var v=0;v"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),lg=!1;if(fa)try{var vu={};Object.defineProperty(vu,"passive",{get:function(){lg=!0}}),window.addEventListener("test",vu,vu),window.removeEventListener("test",vu,vu)}catch{lg=!1}var Wa=null,ug=null,Rc=null;function rx(){if(Rc)return Rc;var a,o=ug,u=o.length,d,v="value"in Wa?Wa.value:Wa.textContent,b=v.length;for(a=0;a=bu),sx=" ",cx=!1;function fx(a,o){switch(a){case"keyup":return pk.indexOf(o.keyCode)!==-1;case"keydown":return o.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function dx(a){return a=a.detail,typeof a=="object"&&"data"in a?a.data:null}var Wo=!1;function bk(a,o){switch(a){case"compositionend":return dx(o);case"keypress":return o.which!==32?null:(cx=!0,sx);case"textInput":return a=o.data,a===sx&&cx?null:a;default:return null}}function wk(a,o){if(Wo)return a==="compositionend"||!hg&&fx(a,o)?(a=rx(),Rc=ug=Wa=null,Wo=!1,a):null;switch(a){case"paste":return null;case"keypress":if(!(o.ctrlKey||o.altKey||o.metaKey)||o.ctrlKey&&o.altKey){if(o.char&&1=o)return{node:u,offset:o-a};a=d}e:{for(;u;){if(u.nextSibling){u=u.nextSibling;break e}u=u.parentNode}u=void 0}u=wx(u)}}function Sx(a,o){return a&&o?a===o?!0:a&&a.nodeType===3?!1:o&&o.nodeType===3?Sx(a,o.parentNode):"contains"in a?a.contains(o):a.compareDocumentPosition?!!(a.compareDocumentPosition(o)&16):!1:!1}function Ex(a){a=a!=null&&a.ownerDocument!=null&&a.ownerDocument.defaultView!=null?a.ownerDocument.defaultView:window;for(var o=_c(a.document);o instanceof a.HTMLIFrameElement;){try{var u=typeof o.contentWindow.location.href=="string"}catch{u=!1}if(u)a=o.contentWindow;else break;o=_c(a.document)}return o}function vg(a){var o=a&&a.nodeName&&a.nodeName.toLowerCase();return o&&(o==="input"&&(a.type==="text"||a.type==="search"||a.type==="tel"||a.type==="url"||a.type==="password")||o==="textarea"||a.contentEditable==="true")}var Mk=fa&&"documentMode"in document&&11>=document.documentMode,Zo=null,pg=null,Eu=null,yg=!1;function Ox(a,o,u){var d=u.window===u?u.document:u.nodeType===9?u:u.ownerDocument;yg||Zo==null||Zo!==_c(d)||(d=Zo,"selectionStart"in d&&vg(d)?d={start:d.selectionStart,end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(),d={anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),Eu&&Su(Eu,d)||(Eu=d,d=wf(pg,"onSelect"),0>=C,v-=C,ha=1<<32-nn(o)+v|u<b?b:8;var C=z.T,R={};z.T=R,rm(a,!1,o,u);try{var k=v(),q=z.S;if(q!==null&&q(R,k),k!==null&&typeof k=="object"&&typeof k.then=="function"){var ee=zk(k,d);$u(a,o,ee,Bn(a))}else $u(a,o,d,Bn(a))}catch(ie){$u(a,o,{then:function(){},status:"rejected",reason:ie},Bn())}finally{W.p=b,z.T=C}}function Hk(){}function tm(a,o,u,d){if(a.tag!==5)throw Error(r(476));var v=AS(a).queue;OS(a,v,o,U,u===null?Hk:function(){return CS(a),u(d)})}function AS(a){var o=a.memoizedState;if(o!==null)return o;o={memoizedState:U,baseState:U,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:pa,lastRenderedState:U},next:null};var u={};return o.next={memoizedState:u,baseState:u,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:pa,lastRenderedState:u},next:null},a.memoizedState=o,a=a.alternate,a!==null&&(a.memoizedState=o),o}function CS(a){var o=AS(a).next.queue;$u(a,o,{},Bn())}function nm(){return fn(ns)}function _S(){return kt().memoizedState}function MS(){return kt().memoizedState}function Fk(a){for(var o=a.return;o!==null;){switch(o.tag){case 24:case 3:var u=Bn();a=Ja(u);var d=ei(o,a,u);d!==null&&(Un(d,o,u),Du(d,o,u)),o={cache:Dg()},a.payload=o;return}o=o.return}}function qk(a,o,u){var d=Bn();u={lane:d,revertLane:0,action:u,hasEagerState:!1,eagerState:null,next:null},Jc(a)?TS(o,u):(u=Sg(a,o,u,d),u!==null&&(Un(u,a,d),PS(u,o,d)))}function RS(a,o,u){var d=Bn();$u(a,o,u,d)}function $u(a,o,u,d){var v={lane:d,revertLane:0,action:u,hasEagerState:!1,eagerState:null,next:null};if(Jc(a))TS(o,v);else{var b=a.alternate;if(a.lanes===0&&(b===null||b.lanes===0)&&(b=o.lastRenderedReducer,b!==null))try{var C=o.lastRenderedState,R=b(C,u);if(v.hasEagerState=!0,v.eagerState=R,kn(R,C))return Lc(a,o,v,0),mt===null&&kc(),!1}catch{}finally{}if(u=Sg(a,o,v,d),u!==null)return Un(u,a,d),PS(u,o,d),!0}return!1}function rm(a,o,u,d){if(d={lane:2,revertLane:km(),action:d,hasEagerState:!1,eagerState:null,next:null},Jc(a)){if(o)throw Error(r(479))}else o=Sg(a,u,d,2),o!==null&&Un(o,a,2)}function Jc(a){var o=a.alternate;return a===He||o!==null&&o===He}function TS(a,o){ll=Kc=!0;var u=a.pending;u===null?o.next=o:(o.next=u.next,u.next=o),a.pending=o}function PS(a,o,u){if((u&4194048)!==0){var d=o.lanes;d&=a.pendingLanes,u|=d,o.lanes=u,Gi(a,u)}}var ef={readContext:fn,use:Xc,useCallback:Tt,useContext:Tt,useEffect:Tt,useImperativeHandle:Tt,useLayoutEffect:Tt,useInsertionEffect:Tt,useMemo:Tt,useReducer:Tt,useRef:Tt,useState:Tt,useDebugValue:Tt,useDeferredValue:Tt,useTransition:Tt,useSyncExternalStore:Tt,useId:Tt,useHostTransitionStatus:Tt,useFormState:Tt,useActionState:Tt,useOptimistic:Tt,useMemoCache:Tt,useCacheRefresh:Tt},DS={readContext:fn,use:Xc,useCallback:function(a,o){return On().memoizedState=[a,o===void 0?null:o],a},useContext:fn,useEffect:mS,useImperativeHandle:function(a,o,u){u=u!=null?u.concat([a]):null,Qc(4194308,4,bS.bind(null,o,a),u)},useLayoutEffect:function(a,o){return Qc(4194308,4,a,o)},useInsertionEffect:function(a,o){Qc(4,2,a,o)},useMemo:function(a,o){var u=On();o=o===void 0?null:o;var d=a();if(io){_r(!0);try{a()}finally{_r(!1)}}return u.memoizedState=[d,o],d},useReducer:function(a,o,u){var d=On();if(u!==void 0){var v=u(o);if(io){_r(!0);try{u(o)}finally{_r(!1)}}}else v=o;return d.memoizedState=d.baseState=v,a={pending:null,lanes:0,dispatch:null,lastRenderedReducer:a,lastRenderedState:v},d.queue=a,a=a.dispatch=qk.bind(null,He,a),[d.memoizedState,a]},useRef:function(a){var o=On();return a={current:a},o.memoizedState=a},useState:function(a){a=Zg(a);var o=a.queue,u=RS.bind(null,He,o);return o.dispatch=u,[a.memoizedState,u]},useDebugValue:Jg,useDeferredValue:function(a,o){var u=On();return em(u,a,o)},useTransition:function(){var a=Zg(!1);return a=OS.bind(null,He,a.queue,!0,!1),On().memoizedState=a,[!1,a]},useSyncExternalStore:function(a,o,u){var d=He,v=On();if(tt){if(u===void 0)throw Error(r(407));u=u()}else{if(u=o(),mt===null)throw Error(r(349));(Ze&124)!==0||Jx(d,o,u)}v.memoizedState=u;var b={value:u,getSnapshot:o};return v.queue=b,mS(tS.bind(null,d,b,a),[a]),d.flags|=2048,sl(9,Zc(),eS.bind(null,d,b,u,o),null),u},useId:function(){var a=On(),o=mt.identifierPrefix;if(tt){var u=ga,d=ha;u=(d&~(1<<32-nn(d)-1)).toString(32)+u,o="«"+o+"R"+u,u=Yc++,0ke?(Kt=Me,Me=null):Kt=Me.sibling;var Je=V(B,Me,F[ke],re);if(Je===null){Me===null&&(Me=Kt);break}a&&Me&&Je.alternate===null&&o(B,Me),I=b(Je,I,ke),Ge===null?pe=Je:Ge.sibling=Je,Ge=Je,Me=Kt}if(ke===F.length)return u(B,Me),tt&&Ji(B,ke),pe;if(Me===null){for(;keke?(Kt=Me,Me=null):Kt=Me.sibling;var pi=V(B,Me,Je.value,re);if(pi===null){Me===null&&(Me=Kt);break}a&&Me&&pi.alternate===null&&o(B,Me),I=b(pi,I,ke),Ge===null?pe=pi:Ge.sibling=pi,Ge=pi,Me=Kt}if(Je.done)return u(B,Me),tt&&Ji(B,ke),pe;if(Me===null){for(;!Je.done;ke++,Je=F.next())Je=ie(B,Je.value,re),Je!==null&&(I=b(Je,I,ke),Ge===null?pe=Je:Ge.sibling=Je,Ge=Je);return tt&&Ji(B,ke),pe}for(Me=d(Me);!Je.done;ke++,Je=F.next())Je=K(Me,B,ke,Je.value,re),Je!==null&&(a&&Je.alternate!==null&&Me.delete(Je.key===null?ke:Je.key),I=b(Je,I,ke),Ge===null?pe=Je:Ge.sibling=Je,Ge=Je);return a&&Me.forEach(function(GL){return o(B,GL)}),tt&&Ji(B,ke),pe}function st(B,I,F,re){if(typeof F=="object"&&F!==null&&F.type===x&&F.key===null&&(F=F.props.children),typeof F=="object"&&F!==null){switch(F.$$typeof){case p:e:{for(var pe=F.key;I!==null;){if(I.key===pe){if(pe=F.type,pe===x){if(I.tag===7){u(B,I.sibling),re=v(I,F.props.children),re.return=B,B=re;break e}}else if(I.elementType===pe||typeof pe=="object"&&pe!==null&&pe.$$typeof===$&&NS(pe)===I.type){u(B,I.sibling),re=v(I,F.props),Bu(re,F),re.return=B,B=re;break e}u(B,I);break}else o(B,I);I=I.sibling}F.type===x?(re=Zi(F.props.children,B.mode,re,F.key),re.return=B,B=re):(re=$c(F.type,F.key,F.props,null,B.mode,re),Bu(re,F),re.return=B,B=re)}return C(B);case y:e:{for(pe=F.key;I!==null;){if(I.key===pe)if(I.tag===4&&I.stateNode.containerInfo===F.containerInfo&&I.stateNode.implementation===F.implementation){u(B,I.sibling),re=v(I,F.children||[]),re.return=B,B=re;break e}else{u(B,I);break}else o(B,I);I=I.sibling}re=Ag(F,B.mode,re),re.return=B,B=re}return C(B);case $:return pe=F._init,F=pe(F._payload),st(B,I,F,re)}if(he(F))return $e(B,I,F,re);if(ae(F)){if(pe=ae(F),typeof pe!="function")throw Error(r(150));return F=pe.call(F),je(B,I,F,re)}if(typeof F.then=="function")return st(B,I,tf(F),re);if(F.$$typeof===A)return st(B,I,Hc(B,F),re);nf(B,F)}return typeof F=="string"&&F!==""||typeof F=="number"||typeof F=="bigint"?(F=""+F,I!==null&&I.tag===6?(u(B,I.sibling),re=v(I,F),re.return=B,B=re):(u(B,I),re=Og(F,B.mode,re),re.return=B,B=re),C(B)):u(B,I)}return function(B,I,F,re){try{Iu=0;var pe=st(B,I,F,re);return cl=null,pe}catch(Me){if(Me===Tu||Me===qc)throw Me;var Ge=Ln(29,Me,null,B.mode);return Ge.lanes=re,Ge.return=B,Ge}finally{}}}var fl=kS(!0),LS=kS(!1),fr=X(null),qr=null;function ni(a){var o=a.alternate;te(Ut,Ut.current&1),te(fr,a),qr===null&&(o===null||ol.current!==null||o.memoizedState!==null)&&(qr=a)}function zS(a){if(a.tag===22){if(te(Ut,Ut.current),te(fr,a),qr===null){var o=a.alternate;o!==null&&o.memoizedState!==null&&(qr=a)}}else ri()}function ri(){te(Ut,Ut.current),te(fr,fr.current)}function ya(a){Z(fr),qr===a&&(qr=null),Z(Ut)}var Ut=X(0);function rf(a){for(var o=a;o!==null;){if(o.tag===13){var u=o.memoizedState;if(u!==null&&(u=u.dehydrated,u===null||u.data==="$?"||Km(u)))return o}else if(o.tag===19&&o.memoizedProps.revealOrder!==void 0){if((o.flags&128)!==0)return o}else if(o.child!==null){o.child.return=o,o=o.child;continue}if(o===a)break;for(;o.sibling===null;){if(o.return===null||o.return===a)return null;o=o.return}o.sibling.return=o.return,o=o.sibling}return null}function am(a,o,u,d){o=a.memoizedState,u=u(d,o),u=u==null?o:g({},o,u),a.memoizedState=u,a.lanes===0&&(a.updateQueue.baseState=u)}var im={enqueueSetState:function(a,o,u){a=a._reactInternals;var d=Bn(),v=Ja(d);v.payload=o,u!=null&&(v.callback=u),o=ei(a,v,d),o!==null&&(Un(o,a,d),Du(o,a,d))},enqueueReplaceState:function(a,o,u){a=a._reactInternals;var d=Bn(),v=Ja(d);v.tag=1,v.payload=o,u!=null&&(v.callback=u),o=ei(a,v,d),o!==null&&(Un(o,a,d),Du(o,a,d))},enqueueForceUpdate:function(a,o){a=a._reactInternals;var u=Bn(),d=Ja(u);d.tag=2,o!=null&&(d.callback=o),o=ei(a,d,u),o!==null&&(Un(o,a,u),Du(o,a,u))}};function $S(a,o,u,d,v,b,C){return a=a.stateNode,typeof a.shouldComponentUpdate=="function"?a.shouldComponentUpdate(d,b,C):o.prototype&&o.prototype.isPureReactComponent?!Su(u,d)||!Su(v,b):!0}function IS(a,o,u,d){a=o.state,typeof o.componentWillReceiveProps=="function"&&o.componentWillReceiveProps(u,d),typeof o.UNSAFE_componentWillReceiveProps=="function"&&o.UNSAFE_componentWillReceiveProps(u,d),o.state!==a&&im.enqueueReplaceState(o,o.state,null)}function oo(a,o){var u=o;if("ref"in o){u={};for(var d in o)d!=="ref"&&(u[d]=o[d])}if(a=a.defaultProps){u===o&&(u=g({},u));for(var v in a)u[v]===void 0&&(u[v]=a[v])}return u}var af=typeof reportError=="function"?reportError:function(a){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var o=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof a=="object"&&a!==null&&typeof a.message=="string"?String(a.message):String(a),error:a});if(!window.dispatchEvent(o))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",a);return}console.error(a)};function BS(a){af(a)}function US(a){console.error(a)}function HS(a){af(a)}function of(a,o){try{var u=a.onUncaughtError;u(o.value,{componentStack:o.stack})}catch(d){setTimeout(function(){throw d})}}function FS(a,o,u){try{var d=a.onCaughtError;d(u.value,{componentStack:u.stack,errorBoundary:o.tag===1?o.stateNode:null})}catch(v){setTimeout(function(){throw v})}}function om(a,o,u){return u=Ja(u),u.tag=3,u.payload={element:null},u.callback=function(){of(a,o)},u}function qS(a){return a=Ja(a),a.tag=3,a}function VS(a,o,u,d){var v=u.type.getDerivedStateFromError;if(typeof v=="function"){var b=d.value;a.payload=function(){return v(b)},a.callback=function(){FS(o,u,d)}}var C=u.stateNode;C!==null&&typeof C.componentDidCatch=="function"&&(a.callback=function(){FS(o,u,d),typeof v!="function"&&(si===null?si=new Set([this]):si.add(this));var R=d.stack;this.componentDidCatch(d.value,{componentStack:R!==null?R:""})})}function Gk(a,o,u,d,v){if(u.flags|=32768,d!==null&&typeof d=="object"&&typeof d.then=="function"){if(o=u.alternate,o!==null&&_u(o,u,v,!0),u=fr.current,u!==null){switch(u.tag){case 13:return qr===null?Tm():u.alternate===null&&Mt===0&&(Mt=3),u.flags&=-257,u.flags|=65536,u.lanes=v,d===kg?u.flags|=16384:(o=u.updateQueue,o===null?u.updateQueue=new Set([d]):o.add(d),Dm(a,d,v)),!1;case 22:return u.flags|=65536,d===kg?u.flags|=16384:(o=u.updateQueue,o===null?(o={transitions:null,markerInstances:null,retryQueue:new Set([d])},u.updateQueue=o):(u=o.retryQueue,u===null?o.retryQueue=new Set([d]):u.add(d)),Dm(a,d,v)),!1}throw Error(r(435,u.tag))}return Dm(a,d,v),Tm(),!1}if(tt)return o=fr.current,o!==null?((o.flags&65536)===0&&(o.flags|=256),o.flags|=65536,o.lanes=v,d!==Mg&&(a=Error(r(422),{cause:d}),Cu(lr(a,u)))):(d!==Mg&&(o=Error(r(423),{cause:d}),Cu(lr(o,u))),a=a.current.alternate,a.flags|=65536,v&=-v,a.lanes|=v,d=lr(d,u),v=om(a.stateNode,d,v),$g(a,v),Mt!==4&&(Mt=2)),!1;var b=Error(r(520),{cause:d});if(b=lr(b,u),Ku===null?Ku=[b]:Ku.push(b),Mt!==4&&(Mt=2),o===null)return!0;d=lr(d,u),u=o;do{switch(u.tag){case 3:return u.flags|=65536,a=v&-v,u.lanes|=a,a=om(u.stateNode,d,a),$g(u,a),!1;case 1:if(o=u.type,b=u.stateNode,(u.flags&128)===0&&(typeof o.getDerivedStateFromError=="function"||b!==null&&typeof b.componentDidCatch=="function"&&(si===null||!si.has(b))))return u.flags|=65536,v&=-v,u.lanes|=v,v=qS(v),VS(v,a,u,d),$g(u,v),!1}u=u.return}while(u!==null);return!1}var GS=Error(r(461)),Vt=!1;function rn(a,o,u,d){o.child=a===null?LS(o,null,u,d):fl(o,a.child,u,d)}function KS(a,o,u,d,v){u=u.render;var b=o.ref;if("ref"in d){var C={};for(var R in d)R!=="ref"&&(C[R]=d[R])}else C=d;return ro(o),d=Fg(a,o,u,C,b,v),R=qg(),a!==null&&!Vt?(Vg(a,o,v),ba(a,o,v)):(tt&&R&&Cg(o),o.flags|=1,rn(a,o,d,v),o.child)}function YS(a,o,u,d,v){if(a===null){var b=u.type;return typeof b=="function"&&!Eg(b)&&b.defaultProps===void 0&&u.compare===null?(o.tag=15,o.type=b,XS(a,o,b,d,v)):(a=$c(u.type,null,d,o,o.mode,v),a.ref=o.ref,a.return=o,o.child=a)}if(b=a.child,!gm(a,v)){var C=b.memoizedProps;if(u=u.compare,u=u!==null?u:Su,u(C,d)&&a.ref===o.ref)return ba(a,o,v)}return o.flags|=1,a=da(b,d),a.ref=o.ref,a.return=o,o.child=a}function XS(a,o,u,d,v){if(a!==null){var b=a.memoizedProps;if(Su(b,d)&&a.ref===o.ref)if(Vt=!1,o.pendingProps=d=b,gm(a,v))(a.flags&131072)!==0&&(Vt=!0);else return o.lanes=a.lanes,ba(a,o,v)}return lm(a,o,u,d,v)}function WS(a,o,u){var d=o.pendingProps,v=d.children,b=a!==null?a.memoizedState:null;if(d.mode==="hidden"){if((o.flags&128)!==0){if(d=b!==null?b.baseLanes|u:u,a!==null){for(v=o.child=a.child,b=0;v!==null;)b=b|v.lanes|v.childLanes,v=v.sibling;o.childLanes=b&~d}else o.childLanes=0,o.child=null;return ZS(a,o,d,u)}if((u&536870912)!==0)o.memoizedState={baseLanes:0,cachePool:null},a!==null&&Fc(o,b!==null?b.cachePool:null),b!==null?Xx(o,b):Bg(),zS(o);else return o.lanes=o.childLanes=536870912,ZS(a,o,b!==null?b.baseLanes|u:u,u)}else b!==null?(Fc(o,b.cachePool),Xx(o,b),ri(),o.memoizedState=null):(a!==null&&Fc(o,null),Bg(),ri());return rn(a,o,v,u),o.child}function ZS(a,o,u,d){var v=Ng();return v=v===null?null:{parent:Bt._currentValue,pool:v},o.memoizedState={baseLanes:u,cachePool:v},a!==null&&Fc(o,null),Bg(),zS(o),a!==null&&_u(a,o,d,!0),null}function lf(a,o){var u=o.ref;if(u===null)a!==null&&a.ref!==null&&(o.flags|=4194816);else{if(typeof u!="function"&&typeof u!="object")throw Error(r(284));(a===null||a.ref!==u)&&(o.flags|=4194816)}}function lm(a,o,u,d,v){return ro(o),u=Fg(a,o,u,d,void 0,v),d=qg(),a!==null&&!Vt?(Vg(a,o,v),ba(a,o,v)):(tt&&d&&Cg(o),o.flags|=1,rn(a,o,u,v),o.child)}function QS(a,o,u,d,v,b){return ro(o),o.updateQueue=null,u=Zx(o,d,u,v),Wx(a),d=qg(),a!==null&&!Vt?(Vg(a,o,b),ba(a,o,b)):(tt&&d&&Cg(o),o.flags|=1,rn(a,o,u,b),o.child)}function JS(a,o,u,d,v){if(ro(o),o.stateNode===null){var b=tl,C=u.contextType;typeof C=="object"&&C!==null&&(b=fn(C)),b=new u(d,b),o.memoizedState=b.state!==null&&b.state!==void 0?b.state:null,b.updater=im,o.stateNode=b,b._reactInternals=o,b=o.stateNode,b.props=d,b.state=o.memoizedState,b.refs={},Lg(o),C=u.contextType,b.context=typeof C=="object"&&C!==null?fn(C):tl,b.state=o.memoizedState,C=u.getDerivedStateFromProps,typeof C=="function"&&(am(o,u,C,d),b.state=o.memoizedState),typeof u.getDerivedStateFromProps=="function"||typeof b.getSnapshotBeforeUpdate=="function"||typeof b.UNSAFE_componentWillMount!="function"&&typeof b.componentWillMount!="function"||(C=b.state,typeof b.componentWillMount=="function"&&b.componentWillMount(),typeof b.UNSAFE_componentWillMount=="function"&&b.UNSAFE_componentWillMount(),C!==b.state&&im.enqueueReplaceState(b,b.state,null),Nu(o,d,b,v),ju(),b.state=o.memoizedState),typeof b.componentDidMount=="function"&&(o.flags|=4194308),d=!0}else if(a===null){b=o.stateNode;var R=o.memoizedProps,k=oo(u,R);b.props=k;var q=b.context,ee=u.contextType;C=tl,typeof ee=="object"&&ee!==null&&(C=fn(ee));var ie=u.getDerivedStateFromProps;ee=typeof ie=="function"||typeof b.getSnapshotBeforeUpdate=="function",R=o.pendingProps!==R,ee||typeof b.UNSAFE_componentWillReceiveProps!="function"&&typeof b.componentWillReceiveProps!="function"||(R||q!==C)&&IS(o,b,d,C),Qa=!1;var V=o.memoizedState;b.state=V,Nu(o,d,b,v),ju(),q=o.memoizedState,R||V!==q||Qa?(typeof ie=="function"&&(am(o,u,ie,d),q=o.memoizedState),(k=Qa||$S(o,u,k,d,V,q,C))?(ee||typeof b.UNSAFE_componentWillMount!="function"&&typeof b.componentWillMount!="function"||(typeof b.componentWillMount=="function"&&b.componentWillMount(),typeof b.UNSAFE_componentWillMount=="function"&&b.UNSAFE_componentWillMount()),typeof b.componentDidMount=="function"&&(o.flags|=4194308)):(typeof b.componentDidMount=="function"&&(o.flags|=4194308),o.memoizedProps=d,o.memoizedState=q),b.props=d,b.state=q,b.context=C,d=k):(typeof b.componentDidMount=="function"&&(o.flags|=4194308),d=!1)}else{b=o.stateNode,zg(a,o),C=o.memoizedProps,ee=oo(u,C),b.props=ee,ie=o.pendingProps,V=b.context,q=u.contextType,k=tl,typeof q=="object"&&q!==null&&(k=fn(q)),R=u.getDerivedStateFromProps,(q=typeof R=="function"||typeof b.getSnapshotBeforeUpdate=="function")||typeof b.UNSAFE_componentWillReceiveProps!="function"&&typeof b.componentWillReceiveProps!="function"||(C!==ie||V!==k)&&IS(o,b,d,k),Qa=!1,V=o.memoizedState,b.state=V,Nu(o,d,b,v),ju();var K=o.memoizedState;C!==ie||V!==K||Qa||a!==null&&a.dependencies!==null&&Uc(a.dependencies)?(typeof R=="function"&&(am(o,u,R,d),K=o.memoizedState),(ee=Qa||$S(o,u,ee,d,V,K,k)||a!==null&&a.dependencies!==null&&Uc(a.dependencies))?(q||typeof b.UNSAFE_componentWillUpdate!="function"&&typeof b.componentWillUpdate!="function"||(typeof b.componentWillUpdate=="function"&&b.componentWillUpdate(d,K,k),typeof b.UNSAFE_componentWillUpdate=="function"&&b.UNSAFE_componentWillUpdate(d,K,k)),typeof b.componentDidUpdate=="function"&&(o.flags|=4),typeof b.getSnapshotBeforeUpdate=="function"&&(o.flags|=1024)):(typeof b.componentDidUpdate!="function"||C===a.memoizedProps&&V===a.memoizedState||(o.flags|=4),typeof b.getSnapshotBeforeUpdate!="function"||C===a.memoizedProps&&V===a.memoizedState||(o.flags|=1024),o.memoizedProps=d,o.memoizedState=K),b.props=d,b.state=K,b.context=k,d=ee):(typeof b.componentDidUpdate!="function"||C===a.memoizedProps&&V===a.memoizedState||(o.flags|=4),typeof b.getSnapshotBeforeUpdate!="function"||C===a.memoizedProps&&V===a.memoizedState||(o.flags|=1024),d=!1)}return b=d,lf(a,o),d=(o.flags&128)!==0,b||d?(b=o.stateNode,u=d&&typeof u.getDerivedStateFromError!="function"?null:b.render(),o.flags|=1,a!==null&&d?(o.child=fl(o,a.child,null,v),o.child=fl(o,null,u,v)):rn(a,o,u,v),o.memoizedState=b.state,a=o.child):a=ba(a,o,v),a}function e1(a,o,u,d){return Au(),o.flags|=256,rn(a,o,u,d),o.child}var um={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function sm(a){return{baseLanes:a,cachePool:Ux()}}function cm(a,o,u){return a=a!==null?a.childLanes&~u:0,o&&(a|=dr),a}function t1(a,o,u){var d=o.pendingProps,v=!1,b=(o.flags&128)!==0,C;if((C=b)||(C=a!==null&&a.memoizedState===null?!1:(Ut.current&2)!==0),C&&(v=!0,o.flags&=-129),C=(o.flags&32)!==0,o.flags&=-33,a===null){if(tt){if(v?ni(o):ri(),tt){var R=_t,k;if(k=R){e:{for(k=R,R=Fr;k.nodeType!==8;){if(!R){R=null;break e}if(k=Tr(k.nextSibling),k===null){R=null;break e}}R=k}R!==null?(o.memoizedState={dehydrated:R,treeContext:Qi!==null?{id:ha,overflow:ga}:null,retryLane:536870912,hydrationErrors:null},k=Ln(18,null,null,0),k.stateNode=R,k.return=o,o.child=k,yn=o,_t=null,k=!0):k=!1}k||to(o)}if(R=o.memoizedState,R!==null&&(R=R.dehydrated,R!==null))return Km(R)?o.lanes=32:o.lanes=536870912,null;ya(o)}return R=d.children,d=d.fallback,v?(ri(),v=o.mode,R=uf({mode:"hidden",children:R},v),d=Zi(d,v,u,null),R.return=o,d.return=o,R.sibling=d,o.child=R,v=o.child,v.memoizedState=sm(u),v.childLanes=cm(a,C,u),o.memoizedState=um,d):(ni(o),fm(o,R))}if(k=a.memoizedState,k!==null&&(R=k.dehydrated,R!==null)){if(b)o.flags&256?(ni(o),o.flags&=-257,o=dm(a,o,u)):o.memoizedState!==null?(ri(),o.child=a.child,o.flags|=128,o=null):(ri(),v=d.fallback,R=o.mode,d=uf({mode:"visible",children:d.children},R),v=Zi(v,R,u,null),v.flags|=2,d.return=o,v.return=o,d.sibling=v,o.child=d,fl(o,a.child,null,u),d=o.child,d.memoizedState=sm(u),d.childLanes=cm(a,C,u),o.memoizedState=um,o=v);else if(ni(o),Km(R)){if(C=R.nextSibling&&R.nextSibling.dataset,C)var q=C.dgst;C=q,d=Error(r(419)),d.stack="",d.digest=C,Cu({value:d,source:null,stack:null}),o=dm(a,o,u)}else if(Vt||_u(a,o,u,!1),C=(u&a.childLanes)!==0,Vt||C){if(C=mt,C!==null&&(d=u&-u,d=(d&42)!==0?1:hu(d),d=(d&(C.suspendedLanes|u))!==0?0:d,d!==0&&d!==k.retryLane))throw k.retryLane=d,el(a,d),Un(C,a,d),GS;R.data==="$?"||Tm(),o=dm(a,o,u)}else R.data==="$?"?(o.flags|=192,o.child=a.child,o=null):(a=k.treeContext,_t=Tr(R.nextSibling),yn=o,tt=!0,eo=null,Fr=!1,a!==null&&(sr[cr++]=ha,sr[cr++]=ga,sr[cr++]=Qi,ha=a.id,ga=a.overflow,Qi=o),o=fm(o,d.children),o.flags|=4096);return o}return v?(ri(),v=d.fallback,R=o.mode,k=a.child,q=k.sibling,d=da(k,{mode:"hidden",children:d.children}),d.subtreeFlags=k.subtreeFlags&65011712,q!==null?v=da(q,v):(v=Zi(v,R,u,null),v.flags|=2),v.return=o,d.return=o,d.sibling=v,o.child=d,d=v,v=o.child,R=a.child.memoizedState,R===null?R=sm(u):(k=R.cachePool,k!==null?(q=Bt._currentValue,k=k.parent!==q?{parent:q,pool:q}:k):k=Ux(),R={baseLanes:R.baseLanes|u,cachePool:k}),v.memoizedState=R,v.childLanes=cm(a,C,u),o.memoizedState=um,d):(ni(o),u=a.child,a=u.sibling,u=da(u,{mode:"visible",children:d.children}),u.return=o,u.sibling=null,a!==null&&(C=o.deletions,C===null?(o.deletions=[a],o.flags|=16):C.push(a)),o.child=u,o.memoizedState=null,u)}function fm(a,o){return o=uf({mode:"visible",children:o},a.mode),o.return=a,a.child=o}function uf(a,o){return a=Ln(22,a,null,o),a.lanes=0,a.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null},a}function dm(a,o,u){return fl(o,a.child,null,u),a=fm(o,o.pendingProps.children),a.flags|=2,o.memoizedState=null,a}function n1(a,o,u){a.lanes|=o;var d=a.alternate;d!==null&&(d.lanes|=o),Tg(a.return,o,u)}function hm(a,o,u,d,v){var b=a.memoizedState;b===null?a.memoizedState={isBackwards:o,rendering:null,renderingStartTime:0,last:d,tail:u,tailMode:v}:(b.isBackwards=o,b.rendering=null,b.renderingStartTime=0,b.last=d,b.tail=u,b.tailMode=v)}function r1(a,o,u){var d=o.pendingProps,v=d.revealOrder,b=d.tail;if(rn(a,o,d.children,u),d=Ut.current,(d&2)!==0)d=d&1|2,o.flags|=128;else{if(a!==null&&(a.flags&128)!==0)e:for(a=o.child;a!==null;){if(a.tag===13)a.memoizedState!==null&&n1(a,u,o);else if(a.tag===19)n1(a,u,o);else if(a.child!==null){a.child.return=a,a=a.child;continue}if(a===o)break e;for(;a.sibling===null;){if(a.return===null||a.return===o)break e;a=a.return}a.sibling.return=a.return,a=a.sibling}d&=1}switch(te(Ut,d),v){case"forwards":for(u=o.child,v=null;u!==null;)a=u.alternate,a!==null&&rf(a)===null&&(v=u),u=u.sibling;u=v,u===null?(v=o.child,o.child=null):(v=u.sibling,u.sibling=null),hm(o,!1,v,u,b);break;case"backwards":for(u=null,v=o.child,o.child=null;v!==null;){if(a=v.alternate,a!==null&&rf(a)===null){o.child=v;break}a=v.sibling,v.sibling=u,u=v,v=a}hm(o,!0,u,null,b);break;case"together":hm(o,!1,null,null,void 0);break;default:o.memoizedState=null}return o.child}function ba(a,o,u){if(a!==null&&(o.dependencies=a.dependencies),ui|=o.lanes,(u&o.childLanes)===0)if(a!==null){if(_u(a,o,u,!1),(u&o.childLanes)===0)return null}else return null;if(a!==null&&o.child!==a.child)throw Error(r(153));if(o.child!==null){for(a=o.child,u=da(a,a.pendingProps),o.child=u,u.return=o;a.sibling!==null;)a=a.sibling,u=u.sibling=da(a,a.pendingProps),u.return=o;u.sibling=null}return o.child}function gm(a,o){return(a.lanes&o)!==0?!0:(a=a.dependencies,!!(a!==null&&Uc(a)))}function Kk(a,o,u){switch(o.tag){case 3:Ke(o,o.stateNode.containerInfo),Za(o,Bt,a.memoizedState.cache),Au();break;case 27:case 5:ve(o);break;case 4:Ke(o,o.stateNode.containerInfo);break;case 10:Za(o,o.type,o.memoizedProps.value);break;case 13:var d=o.memoizedState;if(d!==null)return d.dehydrated!==null?(ni(o),o.flags|=128,null):(u&o.child.childLanes)!==0?t1(a,o,u):(ni(o),a=ba(a,o,u),a!==null?a.sibling:null);ni(o);break;case 19:var v=(a.flags&128)!==0;if(d=(u&o.childLanes)!==0,d||(_u(a,o,u,!1),d=(u&o.childLanes)!==0),v){if(d)return r1(a,o,u);o.flags|=128}if(v=o.memoizedState,v!==null&&(v.rendering=null,v.tail=null,v.lastEffect=null),te(Ut,Ut.current),d)break;return null;case 22:case 23:return o.lanes=0,WS(a,o,u);case 24:Za(o,Bt,a.memoizedState.cache)}return ba(a,o,u)}function a1(a,o,u){if(a!==null)if(a.memoizedProps!==o.pendingProps)Vt=!0;else{if(!gm(a,u)&&(o.flags&128)===0)return Vt=!1,Kk(a,o,u);Vt=(a.flags&131072)!==0}else Vt=!1,tt&&(o.flags&1048576)!==0&&Nx(o,Bc,o.index);switch(o.lanes=0,o.tag){case 16:e:{a=o.pendingProps;var d=o.elementType,v=d._init;if(d=v(d._payload),o.type=d,typeof d=="function")Eg(d)?(a=oo(d,a),o.tag=1,o=JS(null,o,d,a,u)):(o.tag=0,o=lm(null,o,d,a,u));else{if(d!=null){if(v=d.$$typeof,v===P){o.tag=11,o=KS(null,o,d,a,u);break e}else if(v===N){o.tag=14,o=YS(null,o,d,a,u);break e}}throw o=ce(d)||d,Error(r(306,o,""))}}return o;case 0:return lm(a,o,o.type,o.pendingProps,u);case 1:return d=o.type,v=oo(d,o.pendingProps),JS(a,o,d,v,u);case 3:e:{if(Ke(o,o.stateNode.containerInfo),a===null)throw Error(r(387));d=o.pendingProps;var b=o.memoizedState;v=b.element,zg(a,o),Nu(o,d,null,u);var C=o.memoizedState;if(d=C.cache,Za(o,Bt,d),d!==b.cache&&Pg(o,[Bt],u,!0),ju(),d=C.element,b.isDehydrated)if(b={element:d,isDehydrated:!1,cache:C.cache},o.updateQueue.baseState=b,o.memoizedState=b,o.flags&256){o=e1(a,o,d,u);break e}else if(d!==v){v=lr(Error(r(424)),o),Cu(v),o=e1(a,o,d,u);break e}else{switch(a=o.stateNode.containerInfo,a.nodeType){case 9:a=a.body;break;default:a=a.nodeName==="HTML"?a.ownerDocument.body:a}for(_t=Tr(a.firstChild),yn=o,tt=!0,eo=null,Fr=!0,u=LS(o,null,d,u),o.child=u;u;)u.flags=u.flags&-3|4096,u=u.sibling}else{if(Au(),d===v){o=ba(a,o,u);break e}rn(a,o,d,u)}o=o.child}return o;case 26:return lf(a,o),a===null?(u=uE(o.type,null,o.pendingProps,null))?o.memoizedState=u:tt||(u=o.type,a=o.pendingProps,d=Sf(xe.current).createElement(u),d[oe]=o,d[fe]=a,on(d,u,a),Ie(d),o.stateNode=d):o.memoizedState=uE(o.type,a.memoizedProps,o.pendingProps,a.memoizedState),null;case 27:return ve(o),a===null&&tt&&(d=o.stateNode=iE(o.type,o.pendingProps,xe.current),yn=o,Fr=!0,v=_t,di(o.type)?(Ym=v,_t=Tr(d.firstChild)):_t=v),rn(a,o,o.pendingProps.children,u),lf(a,o),a===null&&(o.flags|=4194304),o.child;case 5:return a===null&&tt&&((v=d=_t)&&(d=xL(d,o.type,o.pendingProps,Fr),d!==null?(o.stateNode=d,yn=o,_t=Tr(d.firstChild),Fr=!1,v=!0):v=!1),v||to(o)),ve(o),v=o.type,b=o.pendingProps,C=a!==null?a.memoizedProps:null,d=b.children,qm(v,b)?d=null:C!==null&&qm(v,C)&&(o.flags|=32),o.memoizedState!==null&&(v=Fg(a,o,Ik,null,null,u),ns._currentValue=v),lf(a,o),rn(a,o,d,u),o.child;case 6:return a===null&&tt&&((a=u=_t)&&(u=SL(u,o.pendingProps,Fr),u!==null?(o.stateNode=u,yn=o,_t=null,a=!0):a=!1),a||to(o)),null;case 13:return t1(a,o,u);case 4:return Ke(o,o.stateNode.containerInfo),d=o.pendingProps,a===null?o.child=fl(o,null,d,u):rn(a,o,d,u),o.child;case 11:return KS(a,o,o.type,o.pendingProps,u);case 7:return rn(a,o,o.pendingProps,u),o.child;case 8:return rn(a,o,o.pendingProps.children,u),o.child;case 12:return rn(a,o,o.pendingProps.children,u),o.child;case 10:return d=o.pendingProps,Za(o,o.type,d.value),rn(a,o,d.children,u),o.child;case 9:return v=o.type._context,d=o.pendingProps.children,ro(o),v=fn(v),d=d(v),o.flags|=1,rn(a,o,d,u),o.child;case 14:return YS(a,o,o.type,o.pendingProps,u);case 15:return XS(a,o,o.type,o.pendingProps,u);case 19:return r1(a,o,u);case 31:return d=o.pendingProps,u=o.mode,d={mode:d.mode,children:d.children},a===null?(u=uf(d,u),u.ref=o.ref,o.child=u,u.return=o,o=u):(u=da(a.child,d),u.ref=o.ref,o.child=u,u.return=o,o=u),o;case 22:return WS(a,o,u);case 24:return ro(o),d=fn(Bt),a===null?(v=Ng(),v===null&&(v=mt,b=Dg(),v.pooledCache=b,b.refCount++,b!==null&&(v.pooledCacheLanes|=u),v=b),o.memoizedState={parent:d,cache:v},Lg(o),Za(o,Bt,v)):((a.lanes&u)!==0&&(zg(a,o),Nu(o,null,null,u),ju()),v=a.memoizedState,b=o.memoizedState,v.parent!==d?(v={parent:d,cache:d},o.memoizedState=v,o.lanes===0&&(o.memoizedState=o.updateQueue.baseState=v),Za(o,Bt,d)):(d=b.cache,Za(o,Bt,d),d!==v.cache&&Pg(o,[Bt],u,!0))),rn(a,o,o.pendingProps.children,u),o.child;case 29:throw o.pendingProps}throw Error(r(156,o.tag))}function wa(a){a.flags|=4}function i1(a,o){if(o.type!=="stylesheet"||(o.state.loading&4)!==0)a.flags&=-16777217;else if(a.flags|=16777216,!hE(o)){if(o=fr.current,o!==null&&((Ze&4194048)===Ze?qr!==null:(Ze&62914560)!==Ze&&(Ze&536870912)===0||o!==qr))throw Pu=kg,Hx;a.flags|=8192}}function sf(a,o){o!==null&&(a.flags|=4),a.flags&16384&&(o=a.tag!==22?Sc():536870912,a.lanes|=o,ml|=o)}function Uu(a,o){if(!tt)switch(a.tailMode){case"hidden":o=a.tail;for(var u=null;o!==null;)o.alternate!==null&&(u=o),o=o.sibling;u===null?a.tail=null:u.sibling=null;break;case"collapsed":u=a.tail;for(var d=null;u!==null;)u.alternate!==null&&(d=u),u=u.sibling;d===null?o||a.tail===null?a.tail=null:a.tail.sibling=null:d.sibling=null}}function Ot(a){var o=a.alternate!==null&&a.alternate.child===a.child,u=0,d=0;if(o)for(var v=a.child;v!==null;)u|=v.lanes|v.childLanes,d|=v.subtreeFlags&65011712,d|=v.flags&65011712,v.return=a,v=v.sibling;else for(v=a.child;v!==null;)u|=v.lanes|v.childLanes,d|=v.subtreeFlags,d|=v.flags,v.return=a,v=v.sibling;return a.subtreeFlags|=d,a.childLanes=u,o}function Yk(a,o,u){var d=o.pendingProps;switch(_g(o),o.tag){case 31:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Ot(o),null;case 1:return Ot(o),null;case 3:return u=o.stateNode,d=null,a!==null&&(d=a.memoizedState.cache),o.memoizedState.cache!==d&&(o.flags|=2048),va(Bt),ge(),u.pendingContext&&(u.context=u.pendingContext,u.pendingContext=null),(a===null||a.child===null)&&(Ou(o)?wa(o):a===null||a.memoizedState.isDehydrated&&(o.flags&256)===0||(o.flags|=1024,zx())),Ot(o),null;case 26:return u=o.memoizedState,a===null?(wa(o),u!==null?(Ot(o),i1(o,u)):(Ot(o),o.flags&=-16777217)):u?u!==a.memoizedState?(wa(o),Ot(o),i1(o,u)):(Ot(o),o.flags&=-16777217):(a.memoizedProps!==d&&wa(o),Ot(o),o.flags&=-16777217),null;case 27:Ne(o),u=xe.current;var v=o.type;if(a!==null&&o.stateNode!=null)a.memoizedProps!==d&&wa(o);else{if(!d){if(o.stateNode===null)throw Error(r(166));return Ot(o),null}a=de.current,Ou(o)?kx(o):(a=iE(v,d,u),o.stateNode=a,wa(o))}return Ot(o),null;case 5:if(Ne(o),u=o.type,a!==null&&o.stateNode!=null)a.memoizedProps!==d&&wa(o);else{if(!d){if(o.stateNode===null)throw Error(r(166));return Ot(o),null}if(a=de.current,Ou(o))kx(o);else{switch(v=Sf(xe.current),a){case 1:a=v.createElementNS("http://www.w3.org/2000/svg",u);break;case 2:a=v.createElementNS("http://www.w3.org/1998/Math/MathML",u);break;default:switch(u){case"svg":a=v.createElementNS("http://www.w3.org/2000/svg",u);break;case"math":a=v.createElementNS("http://www.w3.org/1998/Math/MathML",u);break;case"script":a=v.createElement("div"),a.innerHTML=" + + + + +
+ + + diff --git a/components.json b/components.json new file mode 100644 index 0000000..189a6a4 --- /dev/null +++ b/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/global.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..f5ecdbc --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,27 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; +import { globalIgnores } from "eslint/config"; + +export default tseslint.config([ + globalIgnores(["dist"]), + { + files: ["**/*.{ts,tsx}"], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs["recommended-latest"], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + rules: { + "react-refresh/only-export-components": "off", + "react-hooks/exhaustive-deps": "off", + }, + }, +]); diff --git a/index.html b/index.html new file mode 100644 index 0000000..6aac735 --- /dev/null +++ b/index.html @@ -0,0 +1,21 @@ + + + + + + + vlt benchmarks + + + + + + + + + +
+ + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..cce7ad3 --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "vltpkg-benchmarks", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@radix-ui/react-dropdown-menu": "^2.1.15", + "@radix-ui/react-slot": "^1.2.3", + "@tailwindcss/vite": "^4.1.11", + "@tanstack/react-table": "^8.21.3", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-react": "^0.534.0", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "react-router": "^7.7.1", + "recharts": "^3.1.0", + "tailwind-merge": "^3.3.1", + "tailwindcss": "^4.1.11" + }, + "devDependencies": { + "@eslint/js": "^9.30.1", + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", + "eslint": "^9.30.1", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^16.3.0", + "tw-animate-css": "^1.3.6", + "typescript": "~5.8.3", + "typescript-eslint": "^8.35.1", + "vite": "^7.0.4" + } +} diff --git a/public/favicon/apple-touch-icon.png b/public/favicon/apple-touch-icon.png new file mode 100644 index 0000000..4409d3a Binary files /dev/null and b/public/favicon/apple-touch-icon.png differ diff --git a/public/favicon/favicon-96x96.png b/public/favicon/favicon-96x96.png new file mode 100644 index 0000000..287ebf9 Binary files /dev/null and b/public/favicon/favicon-96x96.png differ diff --git a/public/favicon/favicon.ico b/public/favicon/favicon.ico new file mode 100644 index 0000000..d5330e4 Binary files /dev/null and b/public/favicon/favicon.ico differ diff --git a/public/favicon/favicon.svg b/public/favicon/favicon.svg new file mode 100644 index 0000000..523a069 --- /dev/null +++ b/public/favicon/favicon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/favicon/site.webmanifest b/public/favicon/site.webmanifest new file mode 100644 index 0000000..ccf313a --- /dev/null +++ b/public/favicon/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "MyWebSite", + "short_name": "MySite", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/public/favicon/web-app-manifest-192x192.png b/public/favicon/web-app-manifest-192x192.png new file mode 100644 index 0000000..f24d7aa Binary files /dev/null and b/public/favicon/web-app-manifest-192x192.png differ diff --git a/public/favicon/web-app-manifest-512x512.png b/public/favicon/web-app-manifest-512x512.png new file mode 100644 index 0000000..d97eb79 Binary files /dev/null and b/public/favicon/web-app-manifest-512x512.png differ diff --git a/scripts/benchmark.sh b/scripts/benchmark.sh index 950534d..9172c9b 100644 --- a/scripts/benchmark.sh +++ b/scripts/benchmark.sh @@ -21,31 +21,31 @@ pushd "./fixtures/$1" # Run the install variation case "$2" in cache) - bash ../../scripts/variations/cache.sh "../../scripts" "../../results" "$1" "$2" + bash ../../scripts/variations/cache.sh "../../scripts" "../" "$1" "$2" ;; cache+lockfile) - bash ../../scripts/variations/cache+lockfile.sh "../../scripts" "../../results" "$1" "$2" + bash ../../scripts/variations/cache+lockfile.sh "../../scripts" "../" "$1" "$2" ;; cache+node_modules) - bash ../../scripts/variations/cache+node_modules.sh "../../scripts" "../../results" "$1" "$2" + bash ../../scripts/variations/cache+node_modules.sh "../../scripts" "../" "$1" "$2" ;; cache+lockfile+node_modules) - bash ../../scripts/variations/cache+lockfile+node_modules.sh "../../scripts" "../../results" "$1" "$2" + bash ../../scripts/variations/cache+lockfile+node_modules.sh "../../scripts" "../" "$1" "$2" ;; lockfile) - bash ../../scripts/variations/lockfile.sh "../../scripts" "../../results" "$1" "$2" + bash ../../scripts/variations/lockfile.sh "../../scripts" "../" "$1" "$2" ;; lockfile+node_modules) - bash ../../scripts/variations/lockfile+node_modules.sh "../../scripts" "../../results" "$1" "$2" + bash ../../scripts/variations/lockfile+node_modules.sh "../../scripts" "../" "$1" "$2" ;; node_modules) - bash ../../scripts/variations/node_modules.sh "../../scripts" "../../results" "$1" "$2" + bash ../../scripts/variations/node_modules.sh "../../scripts" "../" "$1" "$2" ;; clean) - bash ../../scripts/variations/clean.sh "../../scripts" "../../results" "$1" "$2" + bash ../../scripts/variations/clean.sh "../../scripts" "../" "$1" "$2" ;; run) - bash ../../scripts/variations/run.sh "../../scripts" "../../results" "run" "run" + bash ../../scripts/variations/run.sh "../../scripts" "../" "run" "run" ;; *) echo "Error: Unknown install variation '$2'" diff --git a/scripts/generate-chart.js b/scripts/generate-chart.js index a948299..d6e3c68 100644 --- a/scripts/generate-chart.js +++ b/scripts/generate-chart.js @@ -1,13 +1,13 @@ -const fs = require('fs'); -const path = require('path'); +import fs from "fs"; +import path from "path"; const DATE = process.argv[2]; if (!DATE) { - console.error('Error: Date argument is required'); + console.error("Error: Date argument is required"); process.exit(1); } -const RESULTS_DIR = path.resolve('chart', 'results', DATE); +const RESULTS_DIR = path.resolve("charts", DATE); if (!fs.existsSync(RESULTS_DIR)) { console.error(`Error: Results directory ${RESULTS_DIR} does not exist`); process.exit(1); @@ -15,64 +15,67 @@ if (!fs.existsSync(RESULTS_DIR)) { // Colors for different package managers const COLORS = { - npm: '#cb0606', - yarn: '#117cad', - pnpm: '#f9ad00', - berry: '#9555bb', - deno: '#70ffaf', - bun: '#f472b6', - vlt: '#000000', - nx: '#3b82f6', - turbo: '#ff1e56', - node: '#84ba64' + npm: "#cb0606", + yarn: "#117cad", + pnpm: "#f9ad00", + berry: "#9555bb", + deno: "#70ffaf", + bun: "#f472b6", + vlt: "#000000", + nx: "#3b82f6", + turbo: "#ff1e56", + node: "#84ba64", }; // Read and process results function readResults(file) { try { - const data = JSON.parse(fs.readFileSync(file, 'utf8')); + const data = JSON.parse(fs.readFileSync(file, "utf8")); if (!data.results || !Array.isArray(data.results)) { console.warn(`Warning: Invalid results format in ${file}`); return []; } - return data.results.map(r => ({ + return data.results.map((r) => ({ command: r.command, mean: parseFloat(r.mean) || 0, - stddev: parseFloat(r.stddev) || 0 + stddev: parseFloat(r.stddev) || 0, })); } catch (error) { - console.warn(`Warning: Could not read results from ${file}:`, error.message); + console.warn( + `Warning: Could not read results from ${file}:`, + error.message, + ); return []; } } -// Generate chart data +// Generate chart data for Recharts function generateChartData(option = {}) { - const fixtures = ['next', 'astro', 'svelte', 'vue', 'run']; + const fixtures = ["next", "astro", "svelte", "vue", "run"]; const variations = [ - 'cache', - 'cache+lockfile', - 'cache+lockfile+node_modules', - 'cache+node_modules', - 'clean', - 'lockfile', - 'lockfile+node_modules', - 'node_modules', - 'run' + "cache", + "cache+lockfile", + "cache+lockfile+node_modules", + "cache+node_modules", + "clean", + "lockfile", + "lockfile+node_modules", + "node_modules", + "run", ]; const result = {}; // Process each variation - variations.forEach(variation => { - const datasets = []; + variations.forEach((variation) => { + const fixtureData = {}; const seenFixtures = new Set(); - Object.keys(COLORS).forEach(pm => { - const data = []; - const stddev = []; - let countData = undefined; + // First pass: collect all data for each fixture + fixtures.forEach((fixture) => { + const fixtureResults = {}; + let hasData = false; - fixtures.forEach(fixture => { + Object.keys(COLORS).forEach((pm) => { const file = path.resolve(RESULTS_DIR, `${fixture}-${variation}.json`); let count = undefined; @@ -80,16 +83,16 @@ function generateChartData(option = {}) { if (option.perPackageCount) { const countFile = path.resolve( RESULTS_DIR, - `${fixture}-${variation}-package-count.json` + `${fixture}-${variation}-package-count.json`, ); if (fs.existsSync(countFile)) { try { - countData = JSON.parse(fs.readFileSync(countFile, 'utf8')); + const countData = JSON.parse(fs.readFileSync(countFile, "utf8")); if ( countData && - typeof countData === 'object' && + typeof countData === "object" && countData[pm] && - typeof countData[pm].count === 'number' + typeof countData[pm].count === "number" ) { count = countData[pm].count; } @@ -101,352 +104,87 @@ function generateChartData(option = {}) { if (fs.existsSync(file)) { const results = readResults(file); - const pmResult = results.find(r => r.command === pm); - if (!pmResult?.mean) { - return; - } - seenFixtures.add(fixture); + const pmResult = results.find((r) => r.command === pm); + if (pmResult?.mean) { + let value = pmResult.mean; + if ( + option.perPackageCount && + typeof count === "number" && + count > 0 + ) { + value = (value / count) * 1000; + } - let value = pmResult.mean; - if (option.perPackageCount && typeof count === 'number' && count > 0) { - value = (value / count) * 1000; + fixtureResults[pm] = value; + fixtureResults[`${pm}_stddev`] = pmResult.stddev; + fixtureResults[`${pm}_fill`] = COLORS[pm]; + + if (count !== undefined) { + fixtureResults[`${pm}_count`] = count; + } + + hasData = true; } - data.push(value); - stddev.push(pmResult.stddev); } }); - if (data.length > 0) { - datasets.push({ - ...((countData) ? { count: countData[pm].count } : {}), - label: pm, - data: data, - stddev: stddev, - backgroundColor: COLORS[pm], - borderColor: COLORS[pm], - borderWidth: 1 - }); + if (hasData) { + fixtureResults.fixture = fixture; + fixtureData[fixture] = fixtureResults; + seenFixtures.add(fixture); } }); - if (datasets.length > 0) { - // Store chart data for this variation - result[variation] = { - labels: Array.from(seenFixtures), - datasets: datasets - }; + if (Object.keys(fixtureData).length > 0) { + // Convert to array format for Recharts + result[variation] = Array.from(seenFixtures).map( + (fixture) => fixtureData[fixture], + ); } }); return { - labels: Object.keys(result), - result: result + variations: Object.keys(result), + data: result, + packageManagers: Object.keys(COLORS), + colors: COLORS, }; } -// Generate HTML with chart -function generateHtml(chartData, perPackageCountChartData) { - return ` - - - Package Manager Benchmarks - ${DATE} - - - - -
-

Package Manager Benchmarks

-

Results from ${DATE}

-
- ${chartData.labels.map((label, index) => - `` - ).join('')} -
-

- Per-Package install time (milliseconds) - - with ${chartData.labels[0]} - -

-
- -
-

- Total install time (seconds) - - with ${chartData.labels[0]} - -

-
- -
-

Summary

-
-
- - - -`; -} + fs.writeFileSync( + path.join(RESULTS_DIR, "chart-data.json"), + JSON.stringify(results, null, 2), + ); -// Main execution -try { - const chartData = generateChartData(); - const perPackageCountChartData = generateChartData({ perPackageCount: true }); - console.log(require('util').inspect(chartData, { depth: null })); - - // Check if we have any data to display - if (Object.keys(chartData.result).length === 0) { - console.error('Error: No valid benchmark data found to generate chart'); + if (Object.keys(chartData.data).length === 0) { + console.error("Error: No valid benchmark data found to generate chart"); process.exit(1); } - - const html = generateHtml(chartData, perPackageCountChartData); - - // Write the generated HTML - fs.writeFileSync(path.join(RESULTS_DIR, 'index.html'), html); - - console.log('Chart generation complete!'); +}; + +try { + dumpChartData(); + console.log("Chart generation complete!"); } catch (error) { - console.error('Error generating chart:', error); + console.error("Error generating chart:", error); process.exit(1); -} \ No newline at end of file +} diff --git a/scripts/process-results.sh b/scripts/process-results.sh index 8283fab..b89201a 100644 --- a/scripts/process-results.sh +++ b/scripts/process-results.sh @@ -5,7 +5,7 @@ set -Eeuxo pipefail DATE=$(date +%Y-%m-%d) # Create results directory structure -mkdir -p "chart/results/$DATE" +mkdir -p "charts/$DATE" # Function to print summary of results print_summary() { @@ -50,16 +50,16 @@ echo "Processing results..." # Process variations results for fixture in next astro svelte vue; do for variation in cache cache+lockfile cache+lockfile+node_modules cache+node_modules clean lockfile lockfile+node_modules node_modules run; do - if [ -f "results/results-$fixture-$variation/benchmarks.json" ]; then - print_summary "results/results-$fixture-$variation/benchmarks.json" "$fixture" "$variation" - cp "results/results-$fixture-$variation/benchmarks.json" "chart/results/$DATE/$fixture-$variation.json" + if [ -f "results-$fixture-$variation/benchmarks.json" ]; then + print_summary "results-$fixture-$variation/benchmarks.json" "$fixture" "$variation" + cp "results-$fixture-$variation/benchmarks.json" "charts/$DATE/$fixture-$variation.json" else echo "Warning: No results found for $fixture & $variation" fi - if [ -f "results/results-$fixture-$variation/package-count.json" ]; then - print_package_count "results/results-$fixture-$variation/package-count.json" "$fixture" "$variation" - cp "results/results-$fixture-$variation/package-count.json" "chart/results/$DATE/$fixture-$variation-package-count.json" + if [ -f "results-$fixture-$variation/package-count.json" ]; then + print_package_count "results-$fixture-$variation/package-count.json" "$fixture" "$variation" + cp "results-$fixture-$variation/package-count.json" "charts/$DATE/$fixture-$variation-package-count.json" else echo "Warning: No package count found for $fixture & $variation" fi @@ -67,13 +67,16 @@ for fixture in next astro svelte vue; do done # Process run results -if [ -f "results/results-run-run/benchmarks.json" ]; then - print_summary "results/results-run-run/benchmarks.json" "run" "run" - cp "results/results-run-run/benchmarks.json" "chart/results/$DATE/run-run.json" +if [ -f "results-run-run/benchmarks.json" ]; then + print_summary "results-run-run/benchmarks.json" "run" "run" + cp "results-run-run/benchmarks.json" "charts/$DATE/run-run.json" else echo "Warning: No results found for run" fi +# Create a results directory +mkdir -p charts/$DATE + # Generate visualization echo "Generating visualization..." if ! node scripts/generate-chart.js "$DATE"; then @@ -81,13 +84,5 @@ if ! node scripts/generate-chart.js "$DATE"; then exit 1 fi -# Create a results directory -mkdir -p charts - -# Copy static files -echo "Copying static files..." -cp chart/results/$DATE/index.html charts/index.html -cp chart/results/$DATE/index.html charts/$DATE.html - echo "Results processing complete!" diff --git a/scripts/setup.sh b/scripts/setup.sh index f861790..c11c314 100644 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -41,9 +41,6 @@ corepack enable yarn pnpm # Make npm silent npm config set loglevel silent -# Create Results Directory -mkdir -p ./results/ - # Log Package Manager Versions echo "Logging package manager versions..." NPM_VERSION="$(npm -v)" @@ -81,6 +78,6 @@ echo "{ \"nx\": \"$NX_VERSION\", \"turbo\": \"$TURBO_VERSION\", \"node\": \"$NODE_VERSION\" -}" > ./results/versions.json +}" > ./versions.json echo "Setup completed successfully!" diff --git a/scripts/variations/common.sh b/scripts/variations/common.sh index 23b18af..be26f1f 100644 --- a/scripts/variations/common.sh +++ b/scripts/variations/common.sh @@ -51,7 +51,7 @@ for pm in npm yarn berry pnpm vlt bun deno nx turbo node; do eval "BENCH_INCLUDE_${CHOICE}=" fi done -BENCH_OUTPUT_FOLDER="$BENCH_RESULTS/$BENCH_FIXTURE/$BENCH_VARIATION" +BENCH_OUTPUT_FOLDER="$BENCH_FIXTURE/$BENCH_VARIATION" BENCH_COMMAND_NPM="npm install --no-audit --no-fund --silent >> $BENCH_OUTPUT_FOLDER/npm-output-\${HYPERFINE_ITERATION}.log 2>&1" BENCH_COMMAND_YARN="corepack yarn@1 install --silent > $BENCH_OUTPUT_FOLDER/yarn-output-\${HYPERFINE_ITERATION}.log 2>&1" BENCH_COMMAND_BERRY_PRE=$(cat < { + const { chartData, loading, error } = useChartData(); + const location = useLocation(); + const navigate = useNavigate(); + + useEffect(() => { + if (chartData && location.pathname === "/") { + const firstVariation = chartData.chartData.variations[0]; + navigate(`/${firstVariation}`, { replace: true }); + } + }, [chartData, location.pathname, navigate]); + + return ( + + +
+
+ +
+ {loading && } + {error && } + {chartData && } +
+
+
+
+
+ ); +}; + +export default App; diff --git a/src/assets/fonts/GeistMono-VariableFont_wght.ttf b/src/assets/fonts/GeistMono-VariableFont_wght.ttf new file mode 100644 index 0000000..f86f195 Binary files /dev/null and b/src/assets/fonts/GeistMono-VariableFont_wght.ttf differ diff --git a/src/assets/fonts/Inter-Italic-VariableFont_opsz,wght.ttf b/src/assets/fonts/Inter-Italic-VariableFont_opsz,wght.ttf new file mode 100644 index 0000000..43ed4f5 Binary files /dev/null and b/src/assets/fonts/Inter-Italic-VariableFont_opsz,wght.ttf differ diff --git a/src/assets/fonts/Inter-VariableFont_opsz,wght.ttf b/src/assets/fonts/Inter-VariableFont_opsz,wght.ttf new file mode 100644 index 0000000..e31b51e Binary files /dev/null and b/src/assets/fonts/Inter-VariableFont_opsz,wght.ttf differ diff --git a/src/components/error-boundary.tsx b/src/components/error-boundary.tsx new file mode 100644 index 0000000..29f4a54 --- /dev/null +++ b/src/components/error-boundary.tsx @@ -0,0 +1,78 @@ +import { Component, type ErrorInfo, type ReactNode } from "react"; +import { Button } from "@/components/ui/button"; + +interface ErrorBoundaryProps { + children: ReactNode; + fallback?: ReactNode; +} + +interface ErrorBoundaryState { + hasError: boolean; + error?: Error; +} + +export class ErrorBoundary extends Component< + ErrorBoundaryProps, + ErrorBoundaryState +> { + constructor(props: ErrorBoundaryProps) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError(error: Error): ErrorBoundaryState { + return { hasError: true, error }; + } + + componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error("Error boundary caught an error:", error, errorInfo); + } + + private handleRetry = () => { + this.setState({ hasError: false, error: undefined }); + }; + + render() { + if (this.state.hasError) { + return ( + this.props.fallback || ( +
+
+
+

+ Something went wrong +

+

+ We're sorry, but something unexpected happened. Please try + refreshing the page. +

+ {import.meta.env.DEV && this.state.error && ( +
+ + Error Details (Development) + +
+                      {this.state.error.message}
+                      {this.state.error.stack}
+                    
+
+ )} +
+
+ + +
+
+
+ ) + ); + } + + return this.props.children; + } +} + diff --git a/src/components/error.tsx b/src/components/error.tsx new file mode 100644 index 0000000..085f1ee --- /dev/null +++ b/src/components/error.tsx @@ -0,0 +1,19 @@ +interface ErrorDisplayProps { + message: string; +} + +export const ErrorDisplay = ({ message }: ErrorDisplayProps) => { + return ( +
+
+
+
+
+
+ Error occurred +

{message}

+
+
+
+ ); +}; \ No newline at end of file diff --git a/src/components/footer.tsx b/src/components/footer.tsx new file mode 100644 index 0000000..2d4c62e --- /dev/null +++ b/src/components/footer.tsx @@ -0,0 +1,14 @@ +import { ThemeSwitcher } from "@/components/theme-switcher"; +import { Vlt } from "@/components/icons/vlt"; + +export const Footer = () => { + return ( +
+
+ + +
+
+ ); +}; + diff --git a/src/components/header.tsx b/src/components/header.tsx new file mode 100644 index 0000000..d080d8c --- /dev/null +++ b/src/components/header.tsx @@ -0,0 +1,82 @@ +import { Link, useLocation } from "react-router"; +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, + DropdownMenuItem, +} from "@/components/ui/dropdown-menu"; +import { ChevronDown } from "lucide-react"; +import { cn } from "@/lib/utils"; +import type { BenchmarkChartData, Variation } from "@/types/chart-data"; +import { DATE_YEAR, DATE_MONTH, DATE_DAY } from "@/constants"; + +interface HeaderProps { + chartData: BenchmarkChartData | null; +} + +export const Header = ({ chartData }: HeaderProps) => { + const location = useLocation(); + const currentVariation = + location.pathname.slice(1) || chartData?.chartData.variations[0]; + + return ( +
+
+
+
+

+ Benchmarks + {location.pathname !== "/" && ( + + {" "} + / {location.pathname.slice(1)} + + )} +

+ {chartData && ( +

+ Results from {DATE_YEAR}-{DATE_MONTH}-{DATE_DAY} +

+ )} +
+ + {chartData && ( + + )} +
+
+
+ ); +}; diff --git a/src/components/icons/vlt.tsx b/src/components/icons/vlt.tsx new file mode 100644 index 0000000..36bbdb0 --- /dev/null +++ b/src/components/icons/vlt.tsx @@ -0,0 +1,13 @@ +import { createLucideIcon } from "lucide-react"; + +export const Vlt = createLucideIcon("Vlt", [ + [ + "path", + { + d: "M8.66659 6.33329C8.66659 6.68925 8.61079 7.03216 8.50747 7.35379C8.21694 8.2582 7.99884 9.28798 8.47332 10.1109L10.6593 13.9022C10.9243 14.3618 11.4692 14.5626 11.9997 14.5626C12.5304 14.5626 13.0755 14.3617 13.3406 13.902L15.5265 10.1108C16.001 9.28787 15.7829 8.25813 15.4924 7.35374C15.389 7.03215 15.3333 6.68925 15.3333 6.33332C15.3333 4.49239 16.8257 3.00003 18.6666 3.00003C20.5075 3.00003 21.9999 4.49239 21.9999 6.33332C21.9999 8.17424 20.5075 9.66661 18.6666 9.66661C18.1358 9.66661 17.5906 9.86748 17.3254 10.3273L15.1397 14.1182C14.6652 14.9411 14.8834 15.971 15.1739 16.8754C15.2772 17.197 15.333 17.54 15.333 17.8959C15.333 19.7368 13.8406 21.2292 11.9997 21.2292C10.1588 21.2292 8.66644 19.7368 8.66644 17.8959C8.66644 17.5399 8.72226 17.1969 8.8256 16.8752C9.1162 15.9708 9.33437 14.9409 8.85984 14.1179L6.67422 10.3272C6.40911 9.86744 5.86403 9.66659 5.33329 9.66659C3.49237 9.66659 2 8.17422 2 6.33329C2 4.49237 3.49237 3 5.33329 3C7.17422 3 8.66659 4.49237 8.66659 6.33329Z", + key: "1", + fill: "currentColor", + strokeWidth: "0", + }, + ], +]); diff --git a/src/components/loading.tsx b/src/components/loading.tsx new file mode 100644 index 0000000..4aeb937 --- /dev/null +++ b/src/components/loading.tsx @@ -0,0 +1,18 @@ +import { LOADING_MESSAGES } from "@/constants"; + +interface LoadingProps { + message?: string; +} + +export const Loading = ({ + message = LOADING_MESSAGES.CHART_DATA, +}: LoadingProps) => { + return ( +
+
+
+

{message}

+
+
+ ); +}; diff --git a/src/components/theme-provider.tsx b/src/components/theme-provider.tsx new file mode 100644 index 0000000..e18440d --- /dev/null +++ b/src/components/theme-provider.tsx @@ -0,0 +1,73 @@ +import { createContext, useContext, useEffect, useState } from "react"; + +type Theme = "dark" | "light" | "system"; + +type ThemeProviderProps = { + children: React.ReactNode; + defaultTheme?: Theme; + storageKey?: string; +}; + +type ThemeProviderState = { + theme: Theme; + setTheme: (theme: Theme) => void; +}; + +const initialState: ThemeProviderState = { + theme: "system", + setTheme: () => null, +}; + +const ThemeProviderContext = createContext(initialState); + +export function ThemeProvider({ + children, + defaultTheme = "system", + storageKey = "vite-ui-theme", + ...props +}: ThemeProviderProps) { + const [theme, setTheme] = useState( + () => (localStorage.getItem(storageKey) as Theme) || defaultTheme, + ); + + useEffect(() => { + const root = window.document.documentElement; + + root.classList.remove("light", "dark"); + + if (theme === "system") { + const systemTheme = window.matchMedia("(prefers-color-scheme: dark)") + .matches + ? "dark" + : "light"; + + root.classList.add(systemTheme); + return; + } + + root.classList.add(theme); + }, [theme]); + + const value = { + theme, + setTheme: (theme: Theme) => { + localStorage.setItem(storageKey, theme); + setTheme(theme); + }, + }; + + return ( + + {children} + + ); +} + +export const useTheme = () => { + const context = useContext(ThemeProviderContext); + + if (context === undefined) + throw new Error("useTheme must be used within a ThemeProvider"); + + return context; +}; diff --git a/src/components/theme-switcher.tsx b/src/components/theme-switcher.tsx new file mode 100644 index 0000000..f46a086 --- /dev/null +++ b/src/components/theme-switcher.tsx @@ -0,0 +1,79 @@ +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, + DropdownMenuItem, +} from "@/components/ui/dropdown-menu"; +import { LaptopMinimal, type LucideProps, Moon, Sun } from "lucide-react"; +import { cn } from "@/lib/utils"; +import { useTheme } from "@/components/theme-provider"; + +export type Theme = "system" | "light" | "dark"; + +const ThemeSwitcher = () => { + const { theme, setTheme } = useTheme(); + + const themes: { ariaLabel: Theme; name: Theme }[] = [ + { + ariaLabel: "system", + name: "system", + }, + { + ariaLabel: "light", + name: "light", + }, + { + ariaLabel: "dark", + name: "dark", + }, + ]; + + const renderIcon = (): React.ReactNode => { + const themeProps: LucideProps = { + size: 16, + }; + + return theme === "system" ? ( + + ) : theme === "light" ? ( + + ) : ( + + ); + }; + + return ( + + + + + e.preventDefault()} + > + {themes.map((t) => ( + setTheme(t.name)} + className={cn( + "relative text-sm font-medium capitalize", + t.name === theme + ? "bg-neutral-200/40 dark:bg-neutral-800/80" + : "", + )} + key={t.name} + > + {t.name === "system" && } + {t.name === "light" && } + {t.name === "dark" && } + {t.name} + + ))} + + + ); +}; + +export { ThemeSwitcher }; diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 0000000..b0987f9 --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,59 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive duration-250", + { + variants: { + variant: { + default: + "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", + destructive: + "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", + ghost: + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); + +function Button({ + className, + variant, + size, + asChild = false, + ...props +}: React.ComponentProps<"button"> & + VariantProps & { + asChild?: boolean; + }) { + const Comp = asChild ? Slot : "button"; + + return ( + + ); +} + +export { Button, buttonVariants }; diff --git a/src/components/ui/chart.tsx b/src/components/ui/chart.tsx new file mode 100644 index 0000000..c30877e --- /dev/null +++ b/src/components/ui/chart.tsx @@ -0,0 +1,395 @@ +import * as React from "react"; +import * as RechartsPrimitive from "recharts"; + +import { cn } from "@/lib/utils"; + +// Format: { THEME_NAME: CSS_SELECTOR } +const THEMES = { light: "", dark: ".dark" } as const; + +// Type definitions for Recharts payloads +interface TooltipPayloadItem { + dataKey?: string | number; + name?: string | number; + value?: number | string; + color?: string; + fill?: string; + stroke?: string; + payload?: Record; + [key: string]: unknown; +} + +interface LegendPayloadItem { + value?: string | number; + dataKey?: string | number; + color?: string; + type?: string; + [key: string]: unknown; +} + +type TooltipLabelValue = string | number | React.ReactNode; + +type TooltipFormatterFunction = ( + value: number | string, + name: string | number, + item: TooltipPayloadItem, + index: number, + payload: Record +) => React.ReactNode; + +type LabelFormatterFunction = ( + value: TooltipLabelValue, + payload: TooltipPayloadItem[] +) => React.ReactNode; + +export type ChartConfig = { + [k in string]: { + label?: React.ReactNode; + icon?: React.ComponentType; + } & ( + | { color?: string; theme?: never } + | { color?: never; theme: Record } + ); +}; + +type ChartContextProps = { + config: ChartConfig; +}; + +const ChartContext = React.createContext(null); + +function useChart() { + const context = React.useContext(ChartContext); + + if (!context) { + throw new Error("useChart must be used within a "); + } + + return context; +} + +function ChartContainer({ + id, + className, + children, + config, + ...props +}: React.ComponentProps<"div"> & { + config: ChartConfig; + children: React.ComponentProps< + typeof RechartsPrimitive.ResponsiveContainer + >["children"]; +}) { + const uniqueId = React.useId(); + const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`; + + return ( + +
+ + + {children} + +
+
+ ); +} + +const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => { + const colorConfig = Object.entries(config).filter( + ([, config]) => config.theme || config.color, + ); + + if (!colorConfig.length) { + return null; + } + + return ( +